[Description]

Location = "FLASH\Macronix\MX28F1000P";
Info = " Manufacturer: Macronix",
       " Device: MX29F001T(B)",
       " Memory size: 128 Kbytes (1 MBits)",
       " ",
       "  Note: special adapter are required!",
       " ",
       "  Supported functions:",
       "      Auto erase chip and auto program chip",
       "      Chip protect/unprotect",
       "      Chip read/verify",
       "------------------------------------------------",
       "  Copyright (C) ETL 2006";

Buffer1 = "FLASH",131072 ;
Voltage = 5.0;
Adapter = 1;

[Menu]

Read        = "&Read",ReadButton,"Read chip",F2;
Compare     = "&Verify",CheckButton,"Compare with buffer",F3;
Write       = "&Write",WriteButton,"Write chip",F5;
Div0        = "-";
Erase       = "&Erase",EraseButton,"Erase chip",F9;
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]

define  CHIP_SIZE   0x20000

Proc Read 
{
    var Value,Address,Counter;
    print("");      print("   Reading chip...");
    Address = 0;    PBMax = 131072;
    Run(Read);
    while(Address != CHIP_SIZE) 
    {        
        Value = USB;    FBUF[Address] = Value;
        Address++;      PBPos++;
    }
    if(ForceCloseAfterRead != 0) { return(0x7FFFFFFF); }
    else
    {
        print("   Reading success. %i bytes were read.",Address);
    }
}

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

Proc AutoDetect
{
    var MC,DC;
    Run(Detect);    MC = USB;DC = USB;
    print("   Read signature....");
    print("");
    print("   Next code was readed: %b%b.",MC,DC);      
}

Proc CheckProtect
{
    var Value;
    print("");
    print("   Check protect status...");
    Run(CheckProtect);
    Value = USB;
    if(Value = 1)   {   print("\; Device is protected.");   }
    else            {   print("\; Device is unprotected."); }
}

Proc Erase
{
    var Value,NotErase,Address;
    print("");
    print("   Erasing chip, wait please...");
    Run(EraseChip);
    while
    {
        USB = 1;
        Value = USB;
        if(Value.7 = 1) { break;}
    }
    USB = 0;
    print("\; Done.");
    if(VerifyAfterErase != 0)
    {
        print("");
        print("   Checking chip cleanness...");
        PBPos = 0;
        PBMax = 131072;
        NotErase = 0;
        Run(Read);
        while(Address != 131072) 
        {   
            Value = USB;
            if(Value != 255) { NotErase++; }
            PBPos++;
            Address++;
        }
        if(NotErase = 0)
        {
            print("\; Success.");   
        }
        else
        {
            print("\; Error. %i bytes not cleared.",NotErase);
        }
    }
}


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

    print("");
    if(EraseBeforeWrite != 0)
    {
        //--------- Erase device
        print("   Erasing chip, wait please...");
        Run(EraseChip);
        while
        {
            USB = 1;
            Value = USB;
            if(Value.7 = 1) { break;}
        }
        USB = 0;
        print("\; Done.");
        if(VerifyAfterErase != 0)
        {
            print("   Checking chip cleanness...");
            PBPos = 0;
            NotErase = 0;
            Run(Read);
            while(Address != 131072) 
            {   
                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 != 131072)
    {
        Counter = 64;
        BeginBlock;
        while(Counter != 0)
        {
            Value = FBUF[Address];
            USB = Value;
            Counter--;
            Address++;
        }
        EndBlock;
        Value = USB;
        if(Value != 0)
        {
            //--------- Writing error
            Value = Value - 65;
            Value = Value + Address;
            print("\; Error. Address: %i",Value);
            Value = 1;
            break;
        }
        PBPos = Address;
    }
    if(Value = 0)
    {
        print("\; Success.");
        if(GlobalVerify != 0)
        {
            // verify chip
            print("   Verifying chip...");
            Address = 0;PBPos = 0;PBMax = 131072;NotErase = 0;
            Run(Read);
            while(Address != 131072) 
            {
                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 Protect
{
    var Counter,Temp;
    print("");
    print("   Protect chip, wait please...");
    Counter = 32;
    Run(LockUnlock);
    while(Counter != 0)
    {
        USB = 1;
        USB = 1;
        Temp = USB;
        if(Temp = 1) { break;}
        Counter--;
    }
    USB = 0;
    if(Temp = 1)
    {
        print("\; Success.");
    }
    else
    {
        print("\; Error. Device failed.");
    }
}

Proc Unprotect
{
    var Counter,Temp;
    print("");
    print("   Unprotect chip, wait please...");
    Counter = 1000;
    Run(LockUnlock);
    while(Counter != 0)
    {
        USB = 1;
        USB = 0;
        Temp = USB;
        if(Temp = 0) { break;}
        Counter--;
    }
    USB = 0;
    if(Temp = 0)
    {
        print("\; Success.");
    }
    else
    {
        print("\; Error. Device failed.");
    }
}

Proc Info
{
    print("  Module for programming CMOS FLASH memory.");
    print("  ---------------------------------------------");
    print("  Note: special adapter are required!");
    print("  ---------------------------------------------");
    print("  Memory type:  MX28F1000P");
    print("  Manufacturer: Macronix");
    print("  Supported functions:");
    print("      Auto erase chip and auto program chip");
    print("      Chip protect/unprotect");
    print("      Chip read/verify");
    print("  ---------------------------------------------");
    print("  Copyright (C) ETL 2006");
}


[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  PAGE_SIZE           128

define  OE  3
define  WE  4
define  CS  5
define  DE  7

var Value,Temp,Control,Byte,Counter,AH,AL,A16;

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

Proc EraseChip
{
    PWRCTRL = 1;                            // VCC on pin 32
    Control = 0b11111000;                   // Chip disable
    CTRL = Control;
    ADRH = 0;ADRL = 0;
    Delay(10000);
    PWRCTRL = 0b10000101;                   // 12V at VPP pin
    Delay(10000);
    DATAOUT = 0x30;                         // Setup erase/erase chip
    WritePulse;
    WritePulse;
    Control = 0b11111000;
    DATAOUT = 255;
    Delay(10000);
    //--------- Wait until erase
    while
    {
        Value = USB;
        if(Value = 0) { break;}
        CTRL = 0b11010000;
        Value = DATAIN;
        CTRL = 0b11111000;
        USB = Value;
    }
    PWRCTRL = 1;                            // disable 12V
    PWRCTRL = 3;                            // power OFF
}

Proc WritePulse
{
    Control.CS = 0;CTRL=Control;
    Control.WE = 0;CTRL=Control;
    Control.WE = 1;CTRL=Control;
    Control.CS = 1;CTRL=Control;
}

Proc Write
{
    PWRCTRL = 1;                            // VCC on pin 32
    Control = 0b11111000;                   // Chip disable
    CTRL = Control;
    ADRH = 0;ADRL = 0;
    AH = 0; AL = 0; A16 = 0; Counter = 0;
    Delay(10000);
    PWRCTRL = 0b00000101;                   // 12V at VPP pin
    Delay(10000);
    while(A16 != 2)
    {
        DATAOUT = 0x40;                     // Setup Auto program
        WritePulse;
        ADRL = AL;
        Value = USB;
        DATAOUT = Value;                    // program
        WritePulse;
        DATAOUT = 255;
        UntilToggle;
        Counter++;
        if(Counter = 64)
        {
            Counter = 0;
            USB = 0;
        }
        AL++;
        if(AL = 256)
        {
            AL = 0;
            AH++;
            ADRH = AH;
            if(AH = 256) 
            {
                AH = 0;
                A16++;
                Control = Control | A16;
            }
        }
    }
    PWRCTRL = 0b00000001;                   // disable 12V at VPP pin
    PWRCTRL = 0b00000011;
}

Proc UntilToggle
{
    CTRL = 0b11010000;                      // CS=0, OE = 0;
    Temp = DATAIN;
    CTRL = 0b11111000;                      // CS=1, OE = 1;
    Temp = Temp & 0x40;
    while 
    {
        CTRL = 0b11010000;                      // CS=0, OE = 0;
        Value = DATAIN;
        CTRL = 0b11111000;                      // CS=1, OE = 1;
        Value = Value & 0x40;
        if(Value != Temp)
        {
            Temp = Value;
        }
        else { break; }
    }
}
