[Description]

Location = "FLASH\Winbond\W27F256";
Info = " Manufacturer: Winbond",
       " Device: 27C257,27F256",
       "------------------------------------------",
       " Size: 32768 Bytes (32 KBytes)",
       "------------------------------------------";
Buffer1 = "FLASH",32768;
Voltage = 5.0;
Adapter = 1;

[Menu]

Read    = "&Read",ReadButton,"Read chip",F2;
Compare = "&Verify",CheckButton,"Compare with buffer",F3;
Div0    = "-";
Write   = "&Write",WriteButton,"Write chip",F5;
Div1    = "-";
Erase   = "&Erase",EraseButton,"Erase chip",F8;
Div2    = "-";
Info    = "&About module",ModuleInfoButton,"Show module info",F1;

[Interface]

CheckBox(EraseBeforeWrite,"Erase before write",10,10,1);
CheckBox(VerifyAfterErase,"Checking chip cleanness after erase",10,30,1);

[Host]


Proc Read 
{
    var Value,Address;
    print("");
    print("   Reading chip...");
    Value = 1;
    Address = 0;
    PBMax = 32768;
    Run(Read);
    while(Address != 32768) 
    {
        Value = USB;
        FBUF[Address] = Value;
        Address++;
        PBPos++;
    }
    if(ForceCloseAfterRead != 0) { return(0x7FFFFFFF);}
    print("");
    print("   Reading is done. %i bytes were readed.",Address);      
}


Proc Compare 
{
    var Value,Address,Temp,Mismatch;
    print("");
    print("   Verifying chip...");
    Value = 1;
    Address = 0;
    PBMax = 32768;
    Mismatch = 0;
    Run(Read);
    while(Address != 32768) 
    {
        Value = USB;
        Temp = FBUF[Address];
        if(Temp != Value)
        {
            Mismatch++;
            FSEL[Address] = 0;    
        }
        else
        {
            FSEL[Address] = 1;
        }
        Address++;
        PBPos++;
    }
    if(ForceCloseAfterVerify != 0) { return(0x7FFFFFFF);}
    print("");
    print("   Verifying is done. %i bytes were compared. Mismatch: %i.",Address,Mismatch);
}

Proc Erase
{
    var Temp,NotErase,Address,Value;
    print("");
    print("   Erase chip...");
    Run(Erase);
    Temp = USB;
    print("\; Done");
    if(VerifyAfterErase != 0)
    {
        print("");
        print("   Checking chip cleanness...");
        PBPos = 0;
        PBMax = 32768;
        NotErase = 0;
        Run(Read);
        while(Address != 32768) 
        {   
            Value = USB;
            if(Value != 255) { NotErase++; }
            PBPos++;
            Address++;
        }
        if(NotErase = 0)
        {
            if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
            print("\; Success.");   
        }
        else
        {
            print("\; Error. %i bytes not cleared.",NotErase);
        }        
    }            
}

Proc Write
{
    var Value,Address,Counter,NotErase,Temp,RemAddr;
    
    PBMax = 32768;

    print("");
    if(EraseBeforeWrite != 0)
    {
        //--------- Erase device
        print("   Erase chip...");
        Run(Erase);
        Temp = USB;
        print("\; Done");
        if(VerifyAfterErase != 0)
        {
            print("   Checking chip cleanness...");
            PBPos = 0;
            NotErase = 0;
            Run(Read);
            while(Address != 32768) 
            {   
                Value = USB;
                if(Value != 255) { NotErase++; }
                PBPos++;
                Address++;
            }
            if(NotErase = 0)
            {
                print("\; Success.");   
            }
            else
            {
                print("\; Error. %i bytes not cleared.",NotErase);
                print("   Programming canceled");
                return;
            }
        }
    }
    //-------- Write device
    print("   Writing chip...");
    Address = 0;
    PBPos = 0;
    Run(Write);
    while(Address != 32768)
    {
        Counter = 64;
        BeginBlock;
        while(Counter != 0)
        {
            Value = FBUF[Address];
            USB = Value;
            Counter--;
            Address++;
        }
        EndBlock;
        Value = USB;
        if(Value != 0)
        {
            //--------- Writing error
            Value = Value & 0x7F;
            Address = Address - 64;
            Address = Address + Value;
            print("\; Error. Address: %i",Address);
            Value = 1;
            break;
        }
        PBPos = Address;
    }
    if(Value = 0)
    {
        print("\; Success.");
        if(GlobalVerify != 0)
        {
            // verify chip
            print("   Verifying chip...");
            Address = 0;PBPos = 0;PBMax = 32768;NotErase = 0;
            Run(Read);
            while(Address != 32768) 
            {
                Value = USB;Temp = FBUF[Address];
                if(Temp != Value)   {   NotErase++; FSEL[Address] = 0;      }
                else                {   FSEL[Address] = 1;                  }
                Address++;PBPos++;
            }
            if(NotErase != 0)
            {
                print("\; Error. Number of mismatch %i",NotErase);
            }
            else { print("\ Success.");}  
        }
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF); }
        print("\; %i bytes writed and verified",Address);    
    }
}

Proc Info
{
    print("  Module for programming CMOS FLASH memory.");
    print("  ---------------------------------------------");
    print("  Note: special adapter are required!");
    print("  ---------------------------------------------");
    print("  Memory type:  W27F256");
    print("  Manufacturer: Winbond");
    print("  Supported functions:");
    print("      Erase chip");
    print("      Write chip");
    print("      Verify chip");
    print("  ---------------------------------------------");
    print("  Copyright (C) ETL 2007");
}

[Device]

ereg    ADRL,   0,1
ereg    ADRH,   1,1
ereg    CTRL,   2,1
ereg    DATAIN, 3,0    
ereg    DATAOUT,4,1
ereg    PWRCTRL,5,1

define  CS_AND_OE_LOW       0b11010111
define  CS_AND_OE_HIGH      0b00101000
define  DATA_OUT_ENABLE     0b01111111
define  DATA_OUT_DISABLE    0b10000000

var AL,AH,Value,Temp,Control,Error,Counter25,Counter;

Proc Read
{
    CTRL = 0b11111000;                      // deselect chip
    PWRCTRL = 2;                            // VCC on pin 28
    AH = 0;AL = 0;DATAOUT = 255;
    CTRL = 0b11010000;                      // select chip for read
    while(AH != 128)
    {
        ADRH = AH;AL = 0;
        while(AL != 256)    
        {
            ADRL = AL;Value = DATAIN;USB = Value;AL++;
        }
        AH++;
    }
    CTRL = 0b11111000;                      // deselect chip
    PWRCTRL = 3;                            // power OFF
}

Proc Erase
{
    PWRCTRL = 2;                            // VCC on pin 28
    DATAOUT = 255; 
    CTRL = 0b11111000;                      // Deselect chip
    PWRCTRL = 0b11000010;                   // VPP = 14V
    Delay(10000);
    PWRCTRL = 0b11011010;                   // VPP = 14V on pin A9 and pin 1
    CTRL = 0b11011000;                      // CS = 0;
    Delay(60000);                           // 120 mS
    Delay(60000);
    CTRL = 0b11111000;                      // CS = 1;
    PWRCTRL = 0b00000010;
    PWRCTRL = 3;
    USB = 0;
}

Proc Write
{
    PWRCTRL = 2;                            // VCC on pin 28
    DATAOUT = 255; 
    CTRL = 0b11111000;                      // Deselect chip
    AH =0; AL = 0;
    Counter = 0;
    PWRCTRL = 0b00010010;                   // 12V on VPP pin
    while(AH != 128)
    {
        ADRH = AH;
        AL = 0;
        ADRL = 0;
        while(AL != 256)
        {
            ADRL = AL;Value = USB;
            WriteByte;
            if(Error != 0)
            {
                Value = Counter | 0x80;
                USB = Value;
                while(Counter != 64)
                {
                    Value = USB;
                    Counter++;
                }
                return;
            }
            AL++;
            Counter++;
            if(Counter = 64)
            {
                USB = 0;
                Counter = 0;
            }
        }
        AH++;
    }
}

Proc WriteByte
{
    Error = 0;
    Counter25 = 25;
    while
    {
        DATAOUT = Value;
        CTRL = 0b11011000;              // CS = 0
        Delay(110);                     // 110 uS
        CTRL = 0b11111000;              // CS = 1

        // ------ verify byte
        DATAOUT = 255;
        CTRL = 0b11110000;              // OE = 0;
        Temp = DATAIN;
        CTRL = 0b11111000;              // OE = 1;
        if(Temp = Value) { break;}
        Counter25--;
        if(Counter25 = 0)
        {
            Error = 255;
            break;
        }
    }
}
