diff --git a/TommyPROM/PromDevice.cpp b/TommyPROM/PromDevice.cpp index 5f8a26d..934da65 100644 --- a/TommyPROM/PromDevice.cpp +++ b/TommyPROM/PromDevice.cpp @@ -66,6 +66,22 @@ bool PromDevice::writeData(byte data[], uint32_t len, uint32_t address) return status; } +void PromDevice::resetDebugStats() { + debugBlockWrites = 0; + debugLastAddress = 0; + debugLastExpected = 0; + debugLastReadback = 0; +} +void PromDevice::printDebugStats() { + Serial.print(F("debugBlockWrites: ")); + Serial.println(debugBlockWrites); + Serial.print(F("debugLastAddress: ")); + Serial.println(debugLastAddress, HEX); + Serial.print(F("debugLastExpected: ")); + Serial.println(debugLastExpected, HEX); + Serial.print(F("debugLastReadback: ")); + Serial.println(debugLastReadback, HEX); +} // BEGIN PRIVATE METHODS // @@ -105,5 +121,3 @@ void PromDevice::writeDataBus(byte data) PORTB = (PORTB & 0xfc) | (data >> 6); PORTD = (PORTD & 0x03) | (data << 2); } - - diff --git a/TommyPROM/PromDevice.h b/TommyPROM/PromDevice.h index 862d43c..2a4fbfa 100644 --- a/TommyPROM/PromDevice.h +++ b/TommyPROM/PromDevice.h @@ -20,6 +20,8 @@ class PromDevice PromDevice(uint32_t size, word blockSize, unsigned maxWriteTime, bool polling); bool writeData(byte data[], uint32_t len, uint32_t address); byte readData(uint32_t address) { return readByte(address); } + void resetDebugStats(); + void printDebugStats(); virtual void begin() = 0; virtual const char * getName() = 0; @@ -32,6 +34,11 @@ class PromDevice unsigned int mMaxWriteTime; // Max time (in ms) to wait for write cycle to complete bool mSupportsDataPoll; // End of write detected by data polling + uint32_t debugBlockWrites; // Number of block write operations + uint32_t debugLastAddress; // Last address with an issue + uint8_t debugLastExpected; // Last expected readback value + uint8_t debugLastReadback; // Last actual readback value + void setDataBusMode(uint8_t mode); byte readDataBus(); void writeDataBus(byte data); @@ -45,4 +52,3 @@ class PromDevice #endif // #define INCLUDE_PROM_DEVICE_H - diff --git a/TommyPROM/PromDevice28C.cpp b/TommyPROM/PromDevice28C.cpp index 55c94c0..02c2b2e 100644 --- a/TommyPROM/PromDevice28C.cpp +++ b/TommyPROM/PromDevice28C.cpp @@ -138,9 +138,9 @@ bool PromDevice28C::burnByte(byte value, uint32_t address) bool PromDevice28C::burnBlock(byte data[], uint32_t len, uint32_t address) { bool status = false; - if (len == 0) return true; + ++debugBlockWrites; disableOutput(); disableWrite(); enableChip(); @@ -162,6 +162,9 @@ bool PromDevice28C::burnBlock(byte data[], uint32_t len, uint32_t address) status = waitForWriteCycleEnd(data[len - 1]); disableChip(); + if (!status) { + debugLastAddress = address + len - 1; + } return status; } @@ -174,29 +177,36 @@ bool PromDevice28C::waitForWriteCycleEnd(byte lastValue) // value written twice in a row. The D7 bit will read the inverse of last written // data and the D6 bit will toggle on each read while in programming mode. // - // Note that the max readcount is set to the device's maxReadTime (in uSecs) - // divided by two because there are two 1 uSec delays in the loop. In reality, - // the loop could run for longer because this does not account for the time needed - // to run all of the loop code. In actual practice, the loop will terminate much + // This loop code takes about 18uSec to execute. The max readcount is set to the + // device's maxReadTime (in uSecs) divided by ten rather than eighteen to ensure + // that it runs at least as long as the chip's timeout value, even if some code + // optimizations are made later. In actual practice, the loop will terminate much // earlier because it will detect the end of the write well before the max time. + byte b1=0, b2=0; setDataBusMode(INPUT); delayMicroseconds(1); - for (int readCount = mMaxWriteTime * 1000 / 2; (readCount > 0); readCount--) + for (int readCount = 1; (readCount < (mMaxWriteTime * 100)); readCount++) { + enableChip(); enableOutput(); delayMicroseconds(1); - byte b1 = readDataBus(); + b1 = readDataBus(); disableOutput(); + disableChip(); + enableChip(); enableOutput(); delayMicroseconds(1); - byte b2 = readDataBus(); + b2 = readDataBus(); disableOutput(); + disableChip(); if ((b1 == b2) && (b1 == lastValue)) { return true; } } + debugLastExpected = lastValue; + debugLastReadback = b2; return false; } else @@ -224,4 +234,3 @@ void PromDevice28C::setByte(byte value, uint32_t address) } #endif // #if defined(PROM_IS_28C) - diff --git a/TommyPROM/TommyPROM.ino b/TommyPROM/TommyPROM.ino index 46cb3fd..233bbf1 100644 --- a/TommyPROM/TommyPROM.ino +++ b/TommyPROM/TommyPROM.ino @@ -19,7 +19,7 @@ #include "XModem.h" -static const char * MY_VERSION = "2.3"; +static const char * MY_VERSION = "2.4"; // Global status @@ -84,6 +84,7 @@ enum { CMD_UNLOCK, CMD_WRITE, + CMD_INFO, CMD_SCAN, CMD_TEST, CMD_ZAP, @@ -142,6 +143,7 @@ byte parseCommand(char c) case 'u': cmd = CMD_UNLOCK; break; case 'w': cmd = CMD_WRITE; break; + case 'i': cmd = CMD_INFO; break; case 's': cmd = CMD_SCAN; break; case 't': cmd = CMD_TEST; break; case 'z': cmd = CMD_ZAP; break; @@ -583,7 +585,6 @@ void zapTest(uint32_t start) 0x00, 0xff, 0x55, 0xaa, '0', '1', '2', '3' }; - if (!prom.writeData(testData, sizeof(testData), start)) { cmdStatus.error("Write failed"); @@ -676,6 +677,7 @@ void loop() break; case CMD_FILL: + prom.resetDebugStats(); fillBlock(start, end, val); break; @@ -685,6 +687,7 @@ void loop() break; case CMD_POKE: + prom.resetDebugStats(); pokeBytes(line+1); break; @@ -703,6 +706,7 @@ void loop() break; case CMD_WRITE: + prom.resetDebugStats(); Serial.println(F("Send the image file using XMODEM CRC")); numBytes = xmodem.ReceiveFile(start); if (numBytes) @@ -717,6 +721,10 @@ void loop() break; #ifdef ENABLE_DEBUG_COMMANDS + case CMD_INFO: + prom.printDebugStats(); + break; + case CMD_SCAN: scanBlock(start, end); break; @@ -726,6 +734,7 @@ void loop() break; case CMD_ZAP: + prom.resetDebugStats(); zapTest(start); break; #endif /* ENABLE_DEBUG_COMMANDS */ @@ -752,6 +761,7 @@ void loop() Serial.println(F(" Wsssss - Write to device from XMODEM CRC file")); #ifdef ENABLE_DEBUG_COMMANDS Serial.println(); + Serial.println(F(" I - Print debug Info")); Serial.println(F(" Ssssss eeeee - Scan addresses (read each 10x)")); Serial.println(F(" Tsssss - Test read address (read 100x)")); Serial.println(F(" Zsssss - Zap (burn) a 32 byte test pattern"));