Now for the functions that the user interfaces with -
Read from the flash. This function takes an address - 5 digit HEX - from the serial port and then prints out the addres - 5 digit hex - a colon( and then 16 bytes in hex.
This is the cammansd to read from the flash
R00200 to read from address 0x200 - 0x20F
void ReadFlash()
{
unsigned long ctr;
unsigned long ReadAddrL;
char ReadNiblLo, ReadNiblHi;
char ctrPrt, readVal;
char strAddress[8]={'\0','\0','\0','\0','\0','\0','\0','\0'};
do
{
Serial.readBytes(strAddress,5);
}while(strAddress[0]==0);
ReadAddrL = Asc52Long(strAddress);
//Serial.print("Starting address = ");
//PrintHex5(ReadAddrL);
//Serial.println();
for (ctr = ReadAddrL; ctr < (ReadAddrL + 0x10); ctr++)
{
ctrPrt = lowByte(ctr) & 0xf;
if (ctrPrt == 0)
{
PrintHex5(ctr);
Serial.print(":");
}
readVal = DoRead(ctr);
ReadNiblLo = readVal & 0xF;
ReadNiblHi = (readVal >>4) &0xF;
Serial.print(ReadNiblHi,HEX);
Serial.print(ReadNiblLo,HEX);
}
Serial.println();
}
And to Write to the flash you send the programmer a W, followed by 5 hex digits for the start address and 16 bytes in hex.
W00200:C3284915382010A239FF3EAA55012122 will write to addresses 0x200 - 0x20F
Prior to writing the flash, all bytes to be written to must be 0xFF or the results may no be predictable. If necesary the sector (4k block) that you wish to write to must be erased before writing.
To write 1 byte to the flash 4 bytes must be written, The first 3 are to special addresses. The sequence is this -
to address 0x555 write 0xAA, then to address 0x2AAA write 0x55, then to address 0x5555 write 0xA0 (the code to select Program Mode) and then to the desired address write the desired byte. Repeat this sequence for each byte you wish to write.
When the write sequence completes, the 16 bytes just written are read back and sent to the serial port.
void WriteFlash()
{
unsigned long ctr;
unsigned long WriteAddrL;
char ReadNiblLo, ReadNiblHi;
char readVal, writeVal, hexVal[3];
char strAddress[8]={'\0','\0','\0','\0','\0','\0','\0','\0'};
char chkColon[3] ={'\0','\0','\0'};
char WriteData[33] = {'\0','\0','\0','\0','\0','\0',
'\0','\0','\0','\0','\0','\0',
'\0','\0','\0','\0','\0','\0',
'\0','\0','\0','\0','\0','\0',
'\0','\0','\0','\0','\0','\0',
'\0','\0','\0'};
do
{
Serial.readBytes(strAddress,5);
}while(strAddress[0]==0);
WriteAddrL = Asc52Long(strAddress);
//Serial.println(WriteAddrL,HEX);
do
{
Serial.readBytes(chkColon,1);
}while(chkColon[0]==0);
do
{
Serial.readBytes(WriteData,32);
}while(WriteData[0]==0);
for (ctr = 0 ; ctr < 16; ctr++)
{
hexVal[0] = WriteData[ctr *2];
hexVal[1] = WriteData[ctr *2 + 1];
hexVal[3] = 0;
writeVal = Asc22Byte(hexVal);
DoWrite(0x5555L,0xAA); // First output byte of Byte Program
DoWrite(0x2AAAL,0x55); // Second output byte of Byte Program
DoWrite(0x5555L,0xA0); // Third output byte of of Byte Program
DoWrite(WriteAddrL+ctr,writeVal); // Address and Data to store
}
//Serial.println();
PrintHex5(WriteAddrL);
Serial.print(":");
for (ctr = 0 ; ctr < 16; ctr++)
{
readVal = DoRead(WriteAddrL+ctr);
ReadNiblLo = readVal & 0xF;
ReadNiblHi = (readVal >>4) &0xF;
Serial.print(ReadNiblHi,HEX);
Serial.print(ReadNiblLo,HEX);
}
Serial.println();
}
And the Sector Erase command. There are 2 erase commands for this device. The Sector Erase and the Device Erase. I have not implemented the Devie Erase as I am sure I would use it at the worst possible time and erase everything and leave myself very frustrated. The Sector Erase will a 4k block of the flash starting from a 4K page boundry. Pages start at an address ending with 3 zeros - 00000, 01000, 08000, 0f000, 1F000 so the command just requires the first 2 digits. To erase the 4 k sector at 0x0e000 the command is S0E
The Sector Erase command writes a sequence of bytes to specific addresses as follows -
to address 0x5555 write 0xAA,
to address 0x2AAA write 0x55,
to address 0x5555L write 0x80,
to address 0x5555L write0xAA,
to address 0x2AAAL write 0x55,
and then to the to the EraseAddress write 0x30
void SectorErase()
{
unsigned long EraseAddrL;
char Sector[3]={'\0','\0','\0'};
do
{
Serial.readBytesUntil(13,Sector,2);
}while(Sector[0]==0);
Sector[0]= Sector[0] & 0x0F;
Sector[0]= Sector[0] <<4;
Sector[1]= Sector[1] - 0x30;
if (Sector[1] > 0x9)
{
Sector[1] = (Sector[1] & 0xF) + 9;
}
EraseAddrL = Sector[0] | Sector[1];
EraseAddrL = EraseAddrL << 12;
PrintHex5(EraseAddrL);
Serial.println();
DoWrite(0x5555L,0xAA); // First output byte of Sector Erase
DoWrite(0x2AAAL,0x55); // Second output byte of Sector Erase
DoWrite(0x5555L,0x80); // Third output byte of Sector Erase
DoWrite(0x5555L,0xAA); // Fourth output byte of Sector Erase
DoWrite(0x2AAAL,0x55); // Fifth output byte of Sector Erase
DoWrite(EraseAddrL,0x30); // Sector Address and 0x30 Sector Erase Command
}