[Description]
Location = "Siemens\SDE3526";
Info = " Module for programming 2-Wire serial EEPROMs memory types SDE3526.",
    " Manufacturer: SIEMENS.",
    " ------------------------------------------------------------------------------------------------------------------",
    " Bus: I2C.",
    " Size: 256 bytes",
    " ------------------------------------------------------------------------------------------------------------------ ",
    " Supported functions: read, write, verify.",
    " ------------------------------------------------------------------------------------------------------------------  ",
    " Author: ETL (C) 2007";
Buffer1 = "EEPROM",256;
Picture = "SDE2516.bmp";
VCC = 8;
GND = 1;
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        = "-";
Compare = "&Verify",CheckButton,"Compare with buffer",F3;
Div2        = "-";
Info    = "&About module",ModuleInfoButton,"About module",F1;

[Interface]

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

[Host]

define  END_ADR 256

Proc Read {
    
    var Address,Error,Value;
    print("");
    print("  Reading chip...");
    Run(Read);
    Address = 0;PBPos = 0;PBMax = END_ADR;
    Error = USB;
    if(Error = 0)
    {
        while(Address != END_ADR)
        {
            Value = USB;
            FBUF[Address] = Value;
            Address++;
            PBPos++;
        }        
    }
    if(Error = 0x8000)
    {
        print("  Reading error: Time out");
    }
    if(Error = 0)
    {
        if(ForceCloseafterRead != 0) { return(0x7FFFFFFF); }
        print("  Reading is done. %i bytes were read.",Address);
    }
    else
    {
        if(Error != 0x8000)
        {
            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;
    while(Address != END_ADR)
    {
        Value = FBUF[Address];
        USB = Value;
        Error = USB;
        if(Error != 0) { break; }
        Address++;
        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); }
        return(0x7FFFFFFF);
    }
}

Proc Compare {

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

Proc Erase
{
    var Address,Error,Value;
    print("");
    print("  Erase chip...");
    Run(Write);
    Address = 0;PBPos = 0;PBMax = END_ADR;
    while(Address != END_ADR)
    {
        USB = 255;
        Error = USB;
        if(Error != 0) { break; }
        Address++;
        PBPos++;
    }
    if(Error = 0x8000)
    {
        print("  Erasing error: Time out");
    }
    if(Error = 0xFF)
    {
        print("  Erasing error. Address %i", Address);
    }
    if(Error = 0)
    {
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        print("   Erasing is done");
    }
}

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;
        Writed = 0;
        while(Address != END_ADR)
        {
            Temp = FSEL[Address];
            if(Temp = 0)
            {
                Run(WriteByte);
                BeginBlock;
                USB = Address;
                Temp = FBUF[Address];
                USB = Temp;
                EndBlock;
                Error = USB;
                if(Error != 0) { break;}
                Writed++;
            }
            Address++;
            PBPos++;
        }
    }
    if(Error = 0x8000)
    {
        print("  Writing error: Time out. Address: %i",Address);
    }
    if(Error = 0xFF)
    {
        print("  Wrintig error. Device not response. Address %i", Address);
    }
    if(Error = 0)
    {
        if(GlobalVerify != 0) { Compare(); }
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        print("   Writing is done. %i bytes were write.",writed);
    }

}

Proc Info
{
  print("");
  print("  Module for programming 2-Wire(I2C) serial EEPROMs memory types SDE3526.");
  print("");
  print("  Copyright (C) 2007 ETL.");
}

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

[Device]

define      END_ADR     256    
define      SDAOUT      POUT.4
define      SDAIN       PIN.4
define      SCL         POUT.5

// Variables

var Address,Error,Temp,Byte,Counter,Data;

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

    Init;
    StartI2C;

    // -----  Load adress = 0x000 ----

    Byte = 0xa0;ShiftByteToI2C;CheckAck;
    if(Error != 0) { USB = 0xFF;return; }
    Byte = 0x00;ShiftByteToI2C;CheckAck;
    StopI2C;
    if(Error != 0) { USB = 0xFE;return; }

    // -----  Load Read command ------

    StartI2C;Byte = 0xa1;ShiftByteToI2C;CheckAck;
    if(Error != 0) { USB = 0xFD;return; }

    USB = 0;
    // -----  Read loop  -------------
    while
    {
        ShiftByteFromI2C;
        USB = Byte;
        Address++;
        if(Address != END_ADR) { SDAOUT = 0;SCL = 1; SCL = 0;}
        else                   { SDAOUT = 1;SCL = 1; SCL = 0; break;} 
    }

    // ----- Read end ----------------
    SDAOUT = 0;
    StopI2C;
}

Proc Write {

    Init;

    Address = 0;

    // -------- Read operation must be executed before write

    StartI2C;
    Byte = 0xa1;ShiftByteToI2C;CheckAck;
    if(Error != 0) { USB = 0xFD;return; }
    ShiftByteFromI2C;
    SDAOUT = 1;SCL = 1; SCL = 0;
    StopI2C;

    while(Address != END_ADR) 
    {
        
        // -------- Get data byte from host
        Data = USB;

        // -------- Write to chip
        StartI2C;

        // -----  Load adress
        // -----  Command byte 0xA0

        Byte = 0xa0;ShiftByteToI2C;CheckAck;
        if(Error != 0) { USB = 0xFF;return; }

        // ----- Address byte

        Byte = Address;ShiftByteToI2C;CheckAck;
        if(Error != 0) { USB = 0xFF;return; }

        // ----- Data byte

        Byte = DATA;ShiftByteToI2C;CheckAck;
        if(Error != 0) { USB = 0xFF;return; }

        StopI2C;

        // ----- Wait until device is ready

        Counter = 500;
        while(Counter != 0)
        {
            Counter--;
        }

        // ----- Send to host "OK" command

        USB = 0;
        Address++;
    }
}

Proc StartI2C {
    SDAOUT = 1; SCL = 1;
    SDAOUT = 0; SCL = 0;
} 

Proc StopI2C {
    SDAOUT = 0; SCL = 0;
    SCL = 1; SDAOUT = 1;
}

Proc ShiftByteToI2C
{
  Counter = 8;
  while(Counter != 0)
  {
    SDAOUT = Byte.7;SCL = 1;SCL = 0;
    Byte = Byte << 1;
    Counter--;
  }
  SDAOUT = 0;
}

Proc ShiftByteFromI2C
{
  Counter = 8;
  SDAOUT = 1;
  Byte = 0;
  while(Counter != 0)
  {
    Byte = Byte << 1;
    SCL = 1;
    Byte.0 = SDAIN;
    SCL = 0;
    Counter--;
  }
}

Proc CheckAck
{
    SDAOUT = 1;SCL = 1;
    Error.0 = SDAIN;
    SCL = 0;
    SDAOUT = 0;
}

Proc Init {
  POUT = 0;
  SDAOUT = 1;
  SCL = 1; 
}

Proc WriteByte
{
    Init;

    Address = 0;
    // -------- Read operation must be executed before write

    StartI2C;
    Byte = 0xa1;ShiftByteToI2C;CheckAck;
    if(Error != 0) { USB = 0xFD;return; }
    ShiftByteFromI2C;
    SDAOUT = 1;SCL = 1; SCL = 0;
    StopI2C;

        // -------- Get address byte from host

        Address = USB;
         
        // -------- Get data byte from host
        Data = USB;

        // -------- Write to chip
        StartI2C;

        // -----  Load adress
        // -----  Command byte 0xA0

        Byte = 0xa0;ShiftByteToI2C;CheckAck;
        if(Error != 0) { USB = 0xFF;return; }

        // ----- Address byte

        Byte = Address;ShiftByteToI2C;CheckAck;
        if(Error != 0) { USB = 0xFF;return; }

        // ----- Data byte

        Byte = DATA;ShiftByteToI2C;CheckAck;
        if(Error != 0) { USB = 0xFF;return; }

        StopI2C;

        // ----- Wait until device is ready

        Delay(10000);

        // ----- Send to host "OK" command

        USB = 0;

}