# HG changeset patch # User Paul Boddie # Date 1440414039 -7200 # Node ID c44b58a7fc6977f0f5e1431f959b8017db4441ab # Parent cb9fe339c6ed30d1e657c71bb13cdeaae5be4efb Introduced a requirement for 5-digit addresses. Removed the timeout on operations, testing instead the write status, and implementing the algorithm described in the datasheet. Added support for the reset command. Reduced various delays substantially. Added some failure handling to the upload script. diff -r cb9fe339c6ed -r c44b58a7fc69 ArduinoAm29F010.cpp --- a/ArduinoAm29F010.cpp Sun Aug 23 20:02:09 2015 +0200 +++ b/ArduinoAm29F010.cpp Mon Aug 24 13:00:39 2015 +0200 @@ -26,11 +26,14 @@ char inbuffer[BUFSIZE]; int nread = 0; -const char ERASE[][8] = { - "W5555AA", "W2AAA55", "W555580", "W5555AA", "W2AAA55" +const char RESET[][9] = { + "W05555AA", "W02AAA55", "W05555F0" }; -const char PROGRAM[][8] = { - "W5555AA", "W2AAA55", "W5555A0" +const char ERASE[][9] = { + "W05555AA", "W02AAA55", "W0555580", "W05555AA", "W02AAA55" + }; +const char PROGRAM[][9] = { + "W05555AA", "W02AAA55", "W05555A0" }; int fromHex(char c) @@ -88,7 +91,7 @@ int data = 0; setDataIn(); - delay(1); + delayMicroseconds(1); data = sampleData(); setDataOut(); return data; @@ -100,7 +103,7 @@ while (i > 0) { - i--; + i--; digitalWrite(datapins[i], data % 2); data >>= 1; } @@ -135,10 +138,10 @@ digitalWrite(CE, LOW); setAddress(high, low); - delay(1); + delayMicroseconds(1); digitalWrite(OE, LOW); data = readData(); - delay(1); + delayMicroseconds(1); digitalWrite(OE, HIGH); digitalWrite(CE, HIGH); @@ -149,62 +152,51 @@ { digitalWrite(CE, LOW); setAddress(high, low); - delay(1); + delayMicroseconds(1); digitalWrite(WE, LOW); writeData(data); - delay(1); + delayMicroseconds(1); digitalWrite(WE, HIGH); digitalWrite(CE, HIGH); } int readCommand(const char buffer[], int nread) { - int high, low, i; + int high, low; - if (nread > 5) - { - high = fromHex(buffer[1]) << 8; - i = 2; - } - else - { - high = 0; - i = 1; - } - - high |= (fromHex(buffer[i]) << 4) + (fromHex(buffer[i+1])); - low = (fromHex(buffer[i+2]) << 4) + (fromHex(buffer[i+3])); + high = (fromHex(buffer[1]) << 8) + (fromHex(buffer[2]) << 4) + (fromHex(buffer[3])); + low = (fromHex(buffer[4]) << 4) + (fromHex(buffer[5])); return readOp(high, low); } bool writeCommand(const char buffer[], int nread) { - int high, low, data, i; + int high, low, data; - if (nread > 7) - { - high = fromHex(buffer[1]) << 8; - i = 2; - } - else - { - high = 0; - i = 1; - } - - high |= (fromHex(buffer[i]) << 4) + (fromHex(buffer[i+1])); - low = (fromHex(buffer[i+2]) << 4) + (fromHex(buffer[i+3])); - data = (fromHex(buffer[i+4]) << 4) + (fromHex(buffer[i+5])); + high = (fromHex(buffer[1]) << 8) + (fromHex(buffer[2]) << 4) + (fromHex(buffer[3])); + low = (fromHex(buffer[4]) << 4) + (fromHex(buffer[5])); + data = (fromHex(buffer[6]) << 4) + (fromHex(buffer[7])); writeOp(high, low, data); return true; } +bool haveCompletion(int data, int written) +{ + return ((data & 0x80) == (written & 0x80)); +} + +bool haveFault(int data) +{ + return ((data & 0x20) != 0); +} + bool waitForCompletion(int high, int low, int written) { - int data, then = millis(); + int data; + bool match; setDataIn(); digitalWrite(CE, LOW); @@ -212,19 +204,28 @@ do { - delay(10); - data = sampleData(); - } while ( - ((data & 0x80) != (written & 0x80)) && - ((data & 0x20) == 0) && - (millis() - then < 2000) - ); + data = readOp(high, low); + match = haveCompletion(data, written); + } while (!match && !haveFault(data)); + if (!match) + { + data = readOp(high, low); + match = haveCompletion(data, written); + } + + setDataOut(); digitalWrite(OE, HIGH); digitalWrite(CE, HIGH); - setDataOut(); - delay(10); - return readOp(high, low) == written; + return match; +} + +bool reset() +{ + for (int i = 0; i < 3; i++) + { + writeCommand(RESET[i], 7); + } } bool chipErase() @@ -259,22 +260,11 @@ bool program(const char buffer[], int nread) { - int high, low, data, i; + int high, low, data; - if (nread > 7) - { - high = fromHex(buffer[1]) << 8; - i = 2; - } - else - { - high = 0; - i = 1; - } - - high |= (fromHex(buffer[i]) << 4) + (fromHex(buffer[i+1])); - low = (fromHex(buffer[i+2]) << 4) + (fromHex(buffer[i+3])); - data = (fromHex(buffer[i+4]) << 4) + (fromHex(buffer[i+5])); + high = (fromHex(buffer[1]) << 8) + (fromHex(buffer[2]) << 4) + (fromHex(buffer[3])); + low = (fromHex(buffer[4]) << 4) + (fromHex(buffer[5])); + data = (fromHex(buffer[6]) << 4) + (fromHex(buffer[7])); for (int i = 0; i < 3; i++) { @@ -315,12 +305,22 @@ void loop() { + /* Read bytes, obtaining the number read excluding any newline terminator. */ + if (nread += Serial.readBytesUntil('\n', inbuffer + nread, BUFSIZE - nread)) { + /* Handle each command, waiting for the newline. */ + switch (inbuffer[0]) { + case 'r': + reset(); + Serial.println("r"); + nread = 0; + break; + case 'R': - if (nread >= 5) + if (nread >= 6) { Serial.println(readCommand(inbuffer, nread), HEX); nread = 0; @@ -328,7 +328,7 @@ break; case 'W': - if (nread >= 7) + if (nread >= 8) { if (writeCommand(inbuffer, nread)) Serial.println("W"); @@ -358,7 +358,7 @@ break; case 'P': - if (nread >= 7) + if (nread >= 8) { if (program(inbuffer, nread)) Serial.println("P"); diff -r cb9fe339c6ed -r c44b58a7fc69 README.txt --- a/README.txt Sun Aug 23 20:02:09 2015 +0200 +++ b/README.txt Mon Aug 24 13:00:39 2015 +0200 @@ -43,10 +43,8 @@ Issuing read commands permits the testing of addresses in the device: location sector -R0000 0x0000 0 (the first location in the device) -R00000 0x0000 0 (all 17 address bits indicated) -R7fff 0x7fff 1 (the final location in sector 1) -R07fff 0x7fff 1 (all 17 address bits indicated) +R00000 0x0000 0 (the first location in the device) +R07fff 0x7fff 1 (the final location in sector 1) R10000 0x10000 4 (the first location in sector 4) R1ffff 0x1ffff 7 (the final location in the device) diff -r cb9fe339c6ed -r c44b58a7fc69 upload.py --- a/upload.py Sun Aug 23 20:02:09 2015 +0200 +++ b/upload.py Mon Aug 24 13:00:39 2015 +0200 @@ -86,15 +86,23 @@ if not verify_only: writeToPort("P%05x%02x\n" % (addr, value)) resp = readFromPort() - if resp != "P": - print >>sys.stderr, "Program of location %04x failed: %s" % (addr, resp) - return False - else: + if resp == "P": + i += 1 + continue + else: + closePort() + openPort() + + for attempt in "first", "second": writeToPort("R%05x\n" % addr) resp = readFromPort() - if resp != "%02X" % value and resp != "%X" % value: - print >>sys.stderr, "Verify of location %04x failed: %s" % (addr, resp) - return False + if resp == "%02X" % value or resp == "%X" % value: + break + closePort() + openPort() + else: + print >>sys.stderr, "%s of location %05x failed: %s" % (verify_only and "Verify" or "Program", addr, resp) + return False i += 1