[Description]
Location = "Samsung\EEPROM\MW EEPROM\KM93C46";
Info = " Module for programming 3-Wire Serial EEPROMs memory types: KM93C46.",
       " ---------------------------------------------------------- ",
       "    Bus: MicroWire.",
       "    Size: 128 byte (64 words).",
       " ---------------------------------------------------------- ",
       "    Author: fomalex@biz.by (C) 2007";

Buffer1 = "EEPROM",128;
Picture = "KM93C46.bmp";
VCC = 8;
GND = 5;
View1 = 16;

Voltage = 5.0;

[Menu]

Read        = "&Read",ReadButton,"Read chip",F2;
Div10       = "-";
Write       = "&Write",WriteButton,"Write chip",F5;
WriteChanges= "Write &changes",WriteChangesButton,"Write changes",F6;
div1        = "-";
Erase       = "&Erase",EraseButton,"Erase chip",F9;
Compare     = "&Verify",CheckButton,"Compare with buffer",F3;
Divisor     = "-";
Info        = "&About module",ModuleInfoButton,"Show module info",F1;

[Interface]


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

[Host]

define  END_ADR 64

Proc Read {
    
    var Address,Error,Value,Counter;

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


Proc Write  {

    var Address,Error,Value,Counter,CheckValueL,CheckValueH;
    print("");
    print("  Writing chip...");

    Address = 0;PBPos = 0;PBMax = END_ADR;Counter = 0;
    while(Address != END_ADR)
    {
    	Run(WriteWord);
    	BeginBlock;
    	USB = Address;
        Value = FBUF[Counter];USB = Value;CheckValueL = Value;Counter++;
        Value = FBUF[Counter];USB = Value;CheckValueH = Value;Counter++;
        EndBlock;
        Error = USB;
        if(Error != 0) { break; }
        // verify
    	Run(ReadWord);
    	USB = Address;
    	Error = USB;
        if(Error != 0) { break; }
    	Value = USB; if(Value != CheckValueL) { Error++;}
    	Value = USB; if(Value != CheckValueH) { Error++;}
    	if(Error != 0) 
    	{
    		print("  Error. Address %b (HEX)",Address); 
    		break;
    	}
        PBPos++;
        Address++;
    }
    if(Error = 0x8000)
    {
        print("  Writing error: Time out");
    }
    if(Error = 0xFF)
    {
        print("  Wrintig error. Chip not response. Address %i", Address);
    }
    if(Error = 0)
    {           
        if(GlobalVerify != 0) { Compare(); }
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        print("   Writing is done. %i cells were write.",Address);
    }
}

Proc Compare {

    var Address,Error,Value,Value2,Mismatch,Counter;
    print("");
    print("  Verifying chip...");
    Address = 0;PBPos = 0;PBMax = END_ADR;
    Mismatch = 0;Counter = 0;
    while(Address != END_ADR)
    {

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

Proc Erase
{
    var Address,Error;
    print("");
    print("  Erasing chip...");
    Run(Erase);
    Error = USB;
    if(Error = 0)
    {
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        print("  Erasing is done",Address);
    }
    if(Error = 0x8000)
    {
        print("  Erasing error: Time out");
    }
}

Proc WriteChanges
{
    var Address,Temp,Value,Error,Mismatch,Writed,Counter,Value2;
    Address = 0;Temp = 0;
    print("");
    Counter = 0;
    while(Address != END_ADR)
    {
        Value = FSEL[Counter];
        if(Value = 0) {Temp++;}
        Counter++;
        Value = FSEL[Counter];
        if(Value = 0) {Temp++;}
        Counter++;
        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;
        Mismatch = 0;Counter = 0;
        while(Address != END_ADR)
        {
        	Mismatch = FSEL[Counter];
            Value = FBUF[Counter];                    
            Counter++;
            Temp = FSEL[Counter];
            Mismatch = Mismatch + Temp;
            Temp = FBUF[Counter];
            Counter++;
            if(Mismatch < 2)
            {
            	Run(WriteWord);
                USB = Address;
                USB = Value;
                USB = Temp;
                Error = USB;
                if(Error != 0) { break;}
    	
    			Run(ReadWord);
    			USB = Address;
    			Error = USB;
        		if(Error != 0) { break; }
    			Value2 = USB; if(Value2 != Value) { Error++;}
    			Value2 = USB; if(Value2 != Temp) { Error++;}
    			if(Error != 0) 
    			{
    				print("  Error. Address %b (HEX)",Address); 
    				break;
    			}
                Writed++;
            }
            PBPos++;
            Address++;
        }
        if(Error = 0)
        {
            if(GlobalVerify != 0) { Compare(); }
            if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
            print("   Writing is done. %i cells were write",Writed);
        }
        if(Error = 255)
        {
            print("   Writing error. Address %i",Address);
        }
        if(Error = 0x8000)
        {
            print("   Writing error. Time out. Address %i",Address);
        }
    }
}

Proc Info
{
  print("");
  print("  Module for programming 3-Wire eeprom types KM96C46.");
  print("");
  print("  Copyright (C) 2007 fomalex@biz.by.");
}

// ========================================================
//                    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     64    

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


// Variables

var Address,Error,Temp,DataWord,Counter,DataL,DataH,Mode,WordAddress,
    ControlWord;

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

    POUT = 0b01101100;                  // init
                        				// CS=0, SK=0, DI=1, DO=1, ORG=1
	Address = USB;
    DataWord = READINS | Address;

  	CS = 1;                         // Select chip
         
    ShiftOutWord;                   
    DO = 1;DI = 1;  
    if(DOIN != 0)
    {
    	// chip not present
        // send to host error byte (0xFF) and break
    	USB = 0xFF;return;
    }
    USB = 0x00;                    // send to host OK byte (0x00)

    ShiftInWord;                   // get data word from chip
    CS = 0;                        // release chip
    USB = DataWord;                // send to host low byte of data word
    DataWord = DataWord >> 8;
    USB = DataWord;                // send to host high byte of data word
}

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

Proc WriteWord
{
    Error = 0;

    POUT = 0b01101100;                  // init
                                        // CS=0, SK=0, DI=1, DO=1, ORG=1
    Address = USB;
    DataL = USB;
    DataH = USB;
    DataH = DataH << 8;

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

    DataWord = ERASEINS | Address;
    CS = 1; 
    ShiftOutWord;                 
    CS = 0; 

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

    CS = 1; 
    DataWord = WRITEINS | Address;
    ShiftOutWord;                 
    DataWord = DataH | DataL;
    ShiftOutWord;                 
    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--;
    }
}


Proc Erase
{
    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;

    CS = 1;
    DataWord = ERALINS;                 // Send to chip ERASE ALL command
    ShiftOutWord;
    CS = 0;

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

