# HG changeset patch # User Paul Boddie # Date 1421696616 -3600 # Node ID 22970a6cd9810edbf47fc75d4396293d7b628e8c # Parent 281f052a8a877b54c613c29fc196302ae8ece7b9 Added tentative support for erasure and programming, with an attempt to sample the data pins and detect completion or failure of operations. diff -r 281f052a8a87 -r 22970a6cd981 ArduinoAm29F010.cpp --- a/ArduinoAm29F010.cpp Mon Jan 19 12:27:44 2015 +0100 +++ b/ArduinoAm29F010.cpp Mon Jan 19 20:43:36 2015 +0100 @@ -4,7 +4,11 @@ DQ4 = 10, DQ5 = 11, DQ6 = 12, DQ7 = 13; const int BUFSIZE = 8; -char buffer[BUFSIZE]; +char inbuffer[BUFSIZE]; + +const char CHIP_ERASE[] = "W5555AA\nW2AAA55\nW555580\nW5555AA\nW2AAA55\nW555510\n"; +const char SECTOR_ERASE[] = "W5555AA\nW2AAA55\nW555580\nW5555AA\nW2AAA55\n"; +const char PROGRAM[] = "W5555AA\nW2AAA55\nW5555A0\n"; int fromHex(char c) { @@ -41,14 +45,11 @@ pinMode(DQ7, INPUT); } -int readData() +int sampleData() { int i = DQ7; int data = 0; - setDataIn(); - delay(10); - while (1) { data += digitalRead(i); @@ -58,6 +59,16 @@ data <<= 1; } + return data; +} + +int readData() +{ + int data = 0; + + setDataIn(); + delay(10); + data = sampleData(); setDataOut(); return data; } @@ -90,15 +101,9 @@ digitalWrite(CS1, LOW); } -int readOutput(int nread) +int readOp(int high, int low) { - int high, low, data; - - if (nread < 5) - return 0; - - high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); - low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); + int data; digitalWrite(CE, LOW); setAddress(high, low); @@ -112,7 +117,32 @@ return data; } -bool writeOutput(int nread) +void writeOp(int high, int low, int data) +{ + digitalWrite(CE, LOW); + setAddress(high, low); + delay(10); + digitalWrite(WE, LOW); + writeData(data); + delay(10); + digitalWrite(WE, HIGH); + digitalWrite(CE, HIGH); +} + +int readCommand(int nread, const char buffer[]) +{ + int high, low; + + if (nread < 5) + return 0; + + high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); + low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); + + return readOp(high, low); +} + +bool writeCommand(int nread, const char buffer[]) { int high, low, data; @@ -123,22 +153,86 @@ low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); - digitalWrite(CE, LOW); - setAddress(high, low); - delay(10); - digitalWrite(WE, LOW); - writeData(data); - delay(10); - digitalWrite(WE, HIGH); - digitalWrite(CE, HIGH); + writeOp(high, low, data); return true; } +bool waitForCompletion(int high, int low, int written) +{ + int data; + + setDataIn(); + digitalWrite(CE, LOW); + + do + { + delay(10); + digitalWrite(OE, LOW); + delay(10); + data = sampleData(); + delay(10); + digitalWrite(OE, HIGH); + Serial.println(data, BIN); + } while ( + ((data & 0x80) != (written & 0x80)) && + ((data & 0x20) == 0) + ); + + digitalWrite(CE, HIGH); + setDataOut(); + + return ((data & 0x20) == 0); +} + +bool chipErase() +{ + writeCommand(sizeof(CHIP_ERASE), CHIP_ERASE); + return waitForCompletion(0, 0, 0xff); +} + +bool sectorErase(int nread, const char buffer[]) +{ + int high; + + if (nread < 2) + return false; + + // 3-bit number shifted to A16...A14 with A16 discarded. + // Thus, only sectors from 0 to 3 are supported. + + high = (fromHex(buffer[1]) << 6) & 0xff; + + writeCommand(sizeof(SECTOR_ERASE), SECTOR_ERASE); + writeOp(high, 0, 0x30); + + // Result of erase if 0xff written to all locations. + + return waitForCompletion(high, 0, 0xff); +} + +bool program(int nread, const char buffer[]) +{ + int high, low, data; + + if (nread < 7) + return false; + + // 3-bit number shifted to A16...A14 with A16 discarded. + // Thus, only sectors from 0 to 3 are supported. + + high = (fromHex(buffer[1]) << 6) & 0xff; + low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); + data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); + + writeCommand(sizeof(PROGRAM), PROGRAM); + writeOp(high, low, data); + + return waitForCompletion(high, low, data); +} + void setup() { - int nread = 0; - Serial.begin(115200); pinMode(CE, OUTPUT); pinMode(OE, OUTPUT); @@ -162,33 +256,53 @@ Serial.println("?"); Serial.setTimeout(3600000); // 1 hour +} - while (nread = Serial.readBytesUntil('\n', buffer, BUFSIZE)) +void loop() +{ + int nread = 0; + + if (nread = Serial.readBytesUntil('\n', inbuffer, BUFSIZE)) { - switch (buffer[0]) + switch (inbuffer[0]) { case 'R': - Serial.println(readOutput(nread), HEX); + Serial.println(readCommand(nread, inbuffer), HEX); break; case 'W': - if (writeOutput(nread)) + if (writeCommand(nread, inbuffer)) Serial.println("W"); else Serial.println("C"); break; + case 'E': + if (chipErase()) + Serial.println("E"); + else + Serial.println("C"); + break; + + case 'S': + if (sectorErase(nread, inbuffer)) + Serial.println("S"); + else + Serial.println("C"); + break; + + case 'P': + if (program(nread, inbuffer)) + Serial.println("P"); + else + Serial.println("C"); + break; + default: Serial.println("?"); break; } } - - Serial.println("Done."); -} - -void loop() -{ } extern "C" void __cxa_pure_virtual(void) { diff -r 281f052a8a87 -r 22970a6cd981 README.txt --- a/README.txt Mon Jan 19 12:27:44 2015 +0100 +++ b/README.txt Mon Jan 19 20:43:36 2015 +0100 @@ -1,3 +1,6 @@ +The Am29F010-90PC product has been used to test the software and hardware +design described here. + Pins ==== @@ -51,18 +54,43 @@ Sectors ======= -A[16...14] selects each 16KB sector. +A[16...14] selects each 16KB sector and is referred to as the sector address +or SA in the documentation. Commands ======== Reset (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$F0) -Autoselect (manufacturer) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90); (A=$X00; read) + +Autoselect (manufacturer) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90); + (A=$X00; read) => D=$01 -Autoselect (device) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90); (A=$X01; read) + +Autoselect (device) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90); + (A=$X01; read) => D=$20 -Simple reset (A=$XXX; D=$F0) +Simple reset (A=$XXXX; D=$F0) + +Sector erase (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$80); + (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=SA; D=$30) + +Program (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$A0); + (A=PA; D=PD) + +Progress +-------- + +Programming and erasure commands employ data pins as follows: + + Programming Erasure +DQ7 On completion: DQ7-out On completion: 1 +DQ6 During: toggling value During: toggling value +DQ5 On failure: 1 On failure: 1 +DQ3 Sector erase begun: 1 + +A read operation is required to obtain these outputs, typically with the same +address used to initiate each operation. Arduino Interfacing ===================