[Description]
Location = "NS\7002MN010";
Info = "  Module for programming 3-Wire Serial EEPROMs",
    "  memory types: 7002MN010",
    "  -----------------------------------------------------------------------",
    "  Bus: MicroWire. Features: National Semiconductor.",
    "  Size: 16 words (32 bytes).",
    "  -----------------------------------------------------------------------",
    "  Author: ETL (C) 2005";

Buffer1 = "EEPROM",32;
Picture = "93CXX.bmp";
VCC = 8;
GND = 5;
Voltage = 5.0;
View1 = 16;

[Menu]

Read    = "&Read",ReadButton,"Read chip",F2;
Div10   = "-";
Write   = "&Write",WriteButton,"Write chip",F5;
WriteChanges= "Write &changes",WriteChangesButton,"Write changes",F6;
Div1    = "-";
Compare = "&Verify",CheckButton,"Compare with buffer",F9;
Div2    = "-";
Info    = "&About",ModuleInfoButton,"About module",F1;

[Interface]


// ==================================================
//                  Host section
// ==================================================

[Host]

define  END_ADR 32

Proc Read {
    
    var Address,Error,Value;
    print("");
    print("  Reading chip...");
    Run(Read);
    Address = 0;PBPos = 0;PBMax = END_ADR / 2;
    while(Address != END_ADR)
    {
        Error = USB;
        if(Error = 0)
        {
            Value = USB;
            FBUF[Address] = Value;
            Address++;
            Value = USB;
            FBUF[Address] = Value;
            Address++;
            PBPos++;
        }
        else { break; }        
    }
    if(Error = 0x8000)
    {
        print("  Reading error: Time out");
    }
    if(Error = 0)
    {
        Address = Address / 2;
        if(ForcecloseAfterRead != 0) { return(0x7FFFFFFF); }
        print("  Reading is done. %i words were read.",Address);
    }
    else
    {
        if(Error = 0xFF)
        {
            print("  Reading error. Chip not response.");
        }
    }
}


Proc Write  {

    var Address,Error,Value;
    print("");
    print("  Writing chip...");
    Run(Write);
    Address = 0;PBPos = 0;PBMax = END_ADR / 2;
    while(Address != END_ADR)
    {
        Value = FBUF[Address];USB = Value;Address++;
        Value = FBUF[Address];USB = Value;Address++;
        Error = USB;
        if(Error != 0) { break; }
        PBPos++;
    }
    if(Error = 0x8000)
    {
        print("  Writing error: Time out");
    }
    if(Error = 0xFF)
    {
        print("  Wrintig error. Address %i", Address);
    }
    if(Error = 0)
    {
        if(GlobalVerify != 0) { Compare(); }
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        print("   Writing is done. %i bytes were write.",Address);
    }
}

Proc Compare {

    var Address,Error,Value,Value2,Mismatch;
    print("");
    print("  Verifying chip...");
    Run(Read);
    Address = 0;PBPos = 0;PBMax = END_ADR / 2;
    Mismatch = 0;
    while(Address != END_ADR)
    {
        Error = USB;
        if(Error = 0)
        {
            Value = USB;
            Value2 = FBUF[Address];
            if(Value != Value2)
            {
                Mismatch++;
                FSEL[Address] = 0;    
            }
            else
            {
                FSEL[Address] = 1;
            }
            Address++;
            Value = USB;
            Value2 = FBUF[Address];
            if(Value != Value2)
            {
                Mismatch++;
                FSEL[Address] = 0;
            }
            else
            {
                FSEL[Address] = 1;
            }
            Address++;
            PBPos++;
        }
    }
    if(Error = 0x8000)
    {
        print("  Verifying error: Time out");
    }
    if(Error = 0)
    {
        Address = Address / 2;
        if(ForceCloseAfterVerify != 0) { return(0x7FFFFFFF); }
        print("  Verifying is done. %i words were read. Number of mismatch: %i",Address,Mismatch);
    }
    if(Error = 0xFF)
    {
        print("  Reading error. Chip not response.");
    }
}

Proc WriteChanges
{
    var Address,Temp,Value,Mismatch,Error,Writed;
    Address = 0;Temp = 0;
    print("");
    while(Address != END_ADR)
    {
        Value = FSEL[Address];
        if(Value = 0) {Temp++;}
        Address++;    
    }
    if(Temp = 0)
    {        
        print("   Any mismatch is not found. Writing is canceled.");
        return;
    }
    else
    {
        print("   Writing changes...");
        PBpos = 0; PBMax = END_ADR;Address = 0;Error = 0;
        while(Address != END_ADR)
        {
            Mismatch = FSEL[Address];
            Value = FBUF[Address];                    
            Address++;
            PBPos++;
            Temp = FSEL[Address];
            Mismatch = Mismatch + Temp;
            Temp = FBUF[Address];
            if(Mismatch < 2)
            {
                Run(WriteCell);
                BeginBlock;
                Error = Address >> 1;
                USB = Error;
                USB = Value;    // low byte
                USB = Temp;     // high byte
                EndBlock;
                Error = USB;
                if(Error != 0) { break;}
                Writed++;
            }
            Address++;
            PBPos++;
        }
    }
    if(Error = 0) 
    { 
        if(GlobalVerify != 0) { Compare(); }
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        Address = Address >> 1;
        print("   Writing is done. %i word were write",Address); 
    }
    if(Error = 0x8000)
    {
        Address = Address >> 1;
        print("Writing error. Time out. Address %i",Address);
    }
}

Proc Info
{
  print("");
  print("  Module for programming 3-Wire Serial EEPROMs memory types: 7002MN010.");
  print("");
  print("  Copyright (C) 2006 ETL.");
}

// ========================================================
//                    Device section
// ========================================================

[Device]

define      CS          POUT.0
define      SK          POUT.1
define      DI          POUT.2
define      DO          POUT.3
define      DOIN        PIN.3
define      ORG         POUT.5
define      END_ADR     16    

define      READINS     0b0000000110000000
define      WRITEINS    0b0000000101000000
define      EWENINS     0b0000000100110000                  
define      ERASEINS    0b0000000111000000


// Variables

var Address,Error,Temp,DataWord,Counter,DataL,DataH,DelayCounter;


//***********************************************************
//*       Read                                             **
//***********************************************************
Proc Read {
 
    Error = 0;Address = 0;

    POUT = 0b00101100;                  // init
                                        // CS=0, SK=0, DI=1, DO=1, ORG=1

    while(Address != END_ADR)
    {
        CS = 1;                         // Select chip
        DataWord = READINS | Address;   // Composing Read instruction
                                        // and address field
        ShiftOutWord;                   // Shift result into chip
        DO = 1;DI = 1;                  // release bus
        if(DOIN != 0)
        {
            // chip not present
            // send to host error byte (0xFF) and break
            USB = 0xFF;break;
        }
        ShiftInWord;                    // get data word from chip
        CS = 0;                         // release chip
        USB = 0x00;                    // send to host OK byte (0x00)
        USB = DataWord;                // send to host low byte of data word
        DataWord = DataWord >> 8;
        USB = DataWord;                // send to host high byte of data word
        Address++;                      // next address
    }
}

//************************************************************
//*      Write                                              **
//************************************************************

Proc Write
{
    Error = 0;Address = 0;

    POUT = 0b00101100;                  // init
                                        // CS=0, SK=0, DI=1, DO=1, ORG=1

    CS = 1;
    DataWord = EWENINS;                 // Send to chip WRITE ENABLE command 
    ShiftOutWord;                 
    CS = 0;

    while(Address != END_ADR)
    {
        DataL = USB;
        DataH = USB;


        CS = 1;
        DataWord = ERASEINS | Address;  // Composing WRITE instruction
                                        // and address field
        ShiftOutWord;                   // Shift result into chip
        //DataWord = DataH << 8;          // Composing Data Word
        //DataWord = DataWord | DataL;
        //ShiftOutWord;                   // Shift data word to chip
        CS = 0;

        DelayCounter = 5000;
        while(DelayCounter != 0)
        {
            DelayCounter--;
        }

        CS = 1;
        DataWord = WRITEINS | Address;  // Composing WRITE instruction
                                        // and address field
        ShiftOutWord;                   // Shift result into chip
        DataWord = DataH << 8;          // Composing Data Word
        DataWord = DataWord | DataL;
        ShiftOutWord;                   // Shift data word to chip
        CS = 0;

        //   wait until chip ready
        DO = 1; DI = 1; // release bus
        CS = 1;
        while(DOIN = 0) {}
        CS = 0; 

        DelayCounter = 5000;
        while(DelayCounter != 0)
        {
            DelayCounter--;
        }
        USB = 0;
        Address++;
    }
}

Proc WriteCell
{
    POUT = 0b00101100;                  // init
                                        // CS=0, SK=0, DI=1, DO=1, ORG=1

    CS = 1;
    DataWord = EWENINS;                 // Send to chip WRITE ENABLE command 
    ShiftOutWord;                 
    CS = 0;

    Address = USB;
    DataL = USB;
    DataH = USB;

        CS = 1;
        DataWord = ERASEINS | Address;  // Composing ERASE instruction
                                        // and address field
        ShiftOutWord;                   // Shift result into chip
        CS = 0;

        DelayCounter = 5000;
        while(DelayCounter != 0)
        {
            DelayCounter--;
        }

        CS = 1;
        DataWord = WRITEINS | Address;  // Composing WRITE instruction
                                        // and address field
        ShiftOutWord;                   // Shift into chip Control Word
        DataWord = DataH << 8;          // Composing Data Word
        DataWord = DataWord | DataL;
        ShiftOutWord;                   // Shift data word to chip
        CS = 0;

        //   wait until chip ready
        DO = 1; DI = 1; // release bus
        CS = 1;
        while(DOIN = 0) {}
        CS = 0; 
        USB = 0;

}

Proc ShiftOutWord
{
    Counter = 16;           // bit counter
    while(Counter != 0)
    {
        DI = DataWord.15;           // msb on the input data pin
        SK = 1; SK = 0;             // rising edge SK
        DataWord = DataWord << 1;   // next bit
        Counter--;          
    }    
}


Proc ShiftInWord
{
    Counter = 16;                   // bit counter
    DataWord = 0;
    while(Counter != 0)
    {
        DataWord = DataWord << 1;   // next bit
        SK = 1;                             
        DataWord.0 = DOIN;  // next bit from bus into lowest bit DataWord
        SK = 0;
        Counter--;
    }
}
