Compare commits

...

2 Commits

Author SHA1 Message Date
Tom Nisbet 644bfa88b8 remove debug commands by default 2024-04-22 10:19:13 -04:00
Tom Nisbet 1faf66a43e remove debug commands by default 2024-04-22 10:16:36 -04:00
4 changed files with 138 additions and 96 deletions

View File

@ -1,9 +1,9 @@
// Comment this out to remove extra debugging commands and code // Uncomment this to enable extra debugging commands and code
#define ENABLE_DEBUG_COMMANDS //#define ENABLE_DEBUG_COMMANDS
// Uncomment only one of these to choose the PROM device code that will be // Uncomment ONLY ONE of these to choose the PROM device code that will be
// compiled in. // compiled in.
#define PROM_IS_28C #define PROM_IS_28C
@ -13,6 +13,9 @@
//#define PROM_IS_8755A //#define PROM_IS_8755A
//#define PROM_IS_23 //#define PROM_IS_23
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
// Don't change anything below this comment unless you are adding support for a new device type. // Don't change anything below this comment unless you are adding support for a new device type.
#if defined(PROM_IS_28C) #if defined(PROM_IS_28C)
#include "PromDevice28C.h" #include "PromDevice28C.h"

View File

@ -8,12 +8,16 @@
// IO lines for the EPROM device control // IO lines for the EPROM device control
// Pins D2..D9 are used for the data bus. // Pins D2..D9 are used for the data bus.
#define CS3_PIN A0 enum {
#define CS2_PIN A1 CS3_PIN = A0, // WE on 28C schematic
#define CS1_PIN A2 CS2_PIN = A1, // CE on 28C schematic
#define CS3_BIT 0x04 CS1_PIN = A2 // OE on 28C schematic
#define CS2_BIT 0x02 };
#define CS1_BIT 0x01 enum {
CS3_BIT = 0x04,
CS2_BIT = 0x02,
CS1_BIT = 0x01
};
static unsigned csBits; static unsigned csBits;
@ -45,7 +49,7 @@ void PromDevice23::begin()
pinMode(CS1_PIN, OUTPUT); pinMode(CS1_PIN, OUTPUT);
pinMode(CS2_PIN, OUTPUT); pinMode(CS2_PIN, OUTPUT);
pinMode(CS3_PIN, OUTPUT); pinMode(CS3_PIN, OUTPUT);
disableCS1(); disableCS1();
disableCS2(); disableCS2();
disableCS3(); disableCS3();
@ -61,7 +65,7 @@ void PromDevice23::begin()
ERET PromDevice23::disableSoftwareWriteProtect() ERET PromDevice23::disableSoftwareWriteProtect()
{ {
// Finish out the Unlock message printed by the UI code // Finish out the Unlock message printed by the UI code
Serial.println("just kidding!"); Serial.println(F("no unlock needed, scanning chip selects..."));
// Scan a few different addresses in case there are legitimate empty blocks. With // Scan a few different addresses in case there are legitimate empty blocks. With
// the total ROM size of 2K, it is very unlikely that there are several unused // the total ROM size of 2K, it is very unlikely that there are several unused
@ -70,14 +74,14 @@ ERET PromDevice23::disableSoftwareWriteProtect()
{ {
if (scanAddress(addrBase)) if (scanAddress(addrBase))
{ {
Serial.print("Setting CS bits to "); Serial.print(F("Setting CS bits to "));
printCSbits(csBits); printCSbits(csBits);
Serial.println(); Serial.println();
return RET_OK; return RET_OK;
} }
} }
Serial.println("No valid CS settings found"); Serial.println(F("No valid CS settings found"));
return RET_FAIL; return RET_FAIL;
} }
@ -89,11 +93,11 @@ ERET PromDevice23::disableSoftwareWriteProtect()
// Print the current CS bit settings. // Print the current CS bit settings.
void PromDevice23::printCSbits(unsigned bits) void PromDevice23::printCSbits(unsigned bits)
{ {
Serial.print("CS3:"); Serial.print("CS3/WE:");
Serial.print((bits & CS3_BIT) ? 'H':'L'); Serial.print((bits & CS3_BIT) ? 'H':'L');
Serial.print(" CS2:"); Serial.print(" CS2/CE:");
Serial.print((bits & CS2_BIT) ? 'H':'L'); Serial.print((bits & CS2_BIT) ? 'H':'L');
Serial.print(" CS1:"); Serial.print(" CS1/OE:");
Serial.print((bits & CS1_BIT) ? 'H':'L'); Serial.print((bits & CS1_BIT) ? 'H':'L');
} }
@ -104,7 +108,7 @@ bool PromDevice23::scanAddress(uint32_t addrBase)
{ {
unsigned saveBits = 0xff; unsigned saveBits = 0xff;
Serial.print("\nScanning Chip Select combinations starting at address "); Serial.print(F("\nScanning Chip Select combinations starting at address "));
printByte(addrBase >> 8); printByte(addrBase >> 8);
printByte(addrBase & 0xff); printByte(addrBase & 0xff);
Serial.println(); Serial.println();

View File

@ -19,7 +19,7 @@
#include "XModem.h" #include "XModem.h"
static const char * MY_VERSION = "3.5"; static const char * MY_VERSION = "3.6";
// Global status // Global status
@ -106,16 +106,17 @@ enum {
CMD_DUMP, CMD_DUMP,
CMD_ERASE, CMD_ERASE,
CMD_FILL, CMD_FILL,
CMD_INFO,
CMD_LOCK, CMD_LOCK,
CMD_POKE, CMD_POKE,
CMD_READ, CMD_READ,
CMD_UNLOCK, CMD_UNLOCK,
CMD_WRITE, CMD_WRITE,
CMD_ZAP,
CMD_INFO,
CMD_SCAN, CMD_SCAN,
CMD_TEST, CMD_TEST,
CMD_ZAP, CMD_PATTERN32,
CMD_LAST_STATUS CMD_LAST_STATUS
}; };
@ -166,16 +167,17 @@ byte parseCommand(char c)
case 'd': cmd = CMD_DUMP; break; case 'd': cmd = CMD_DUMP; break;
case 'e': cmd = CMD_ERASE; break; case 'e': cmd = CMD_ERASE; break;
case 'f': cmd = CMD_FILL; break; case 'f': cmd = CMD_FILL; break;
case 'i': cmd = CMD_INFO; break;
case 'l': cmd = CMD_LOCK; break; case 'l': cmd = CMD_LOCK; break;
case 'p': cmd = CMD_POKE; break; case 'p': cmd = CMD_POKE; break;
case 'r': cmd = CMD_READ; break; case 'r': cmd = CMD_READ; break;
case 'u': cmd = CMD_UNLOCK; break; case 'u': cmd = CMD_UNLOCK; break;
case 'w': cmd = CMD_WRITE; break; case 'w': cmd = CMD_WRITE; break;
case 'z': cmd = CMD_ZAP; break;
case 'i': cmd = CMD_INFO; break;
case 's': cmd = CMD_SCAN; break; case 's': cmd = CMD_SCAN; break;
case 't': cmd = CMD_TEST; break; case 't': cmd = CMD_TEST; break;
case 'z': cmd = CMD_ZAP; break; case '!': cmd = CMD_PATTERN32; break;
case '/': cmd = CMD_LAST_STATUS;break; case '/': cmd = CMD_LAST_STATUS;break;
default: cmd = CMD_INVALID; break; default: cmd = CMD_INVALID; break;
} }
@ -522,6 +524,56 @@ void pokeBytes(char * pCursor)
cmdStatus.info("Poke successful"); cmdStatus.info("Poke successful");
} }
/**
* Write a 32 byte test pattern to the PROM device and verify it
* by reading back. The pattern includes a walking 1 and a
* walking zero, which may help to detect pins that are tied
* together or swapped.
*
* @param start - start address
*/
void zapTest(uint32_t start)
{
byte testData[] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe,
0x00, 0xff, 0x55, 0xaa, '0', '1', '2', '3'
};
if (!prom.writeData(testData, sizeof(testData), start))
{
cmdStatus.error("Write failed");
return;
}
delay(100);
if (!prom.is_readback_safe()) {
// This chip uses the CE line for write control, so don't do the read because it
// could cause a write operation that would corrupt the data.
cmdStatus.info("Write test complete");
return;
}
for (unsigned ix = 0; ix < sizeof(testData); ix++)
{
byte val = prom.readData(start + ix);
if (val != testData[ix])
{
cmdStatus.error("Verify failed");
cmdStatus.setValueHex(0, "addr", start + ix);
cmdStatus.setValueHex(1, "read", val);
cmdStatus.setValueHex(2, "expected", testData[ix]);
return;
}
}
cmdStatus.info("Write test successful");
}
void printRetStatus(ERET status) void printRetStatus(ERET status)
{ {
switch (status) { switch (status) {
@ -613,51 +665,31 @@ void testAddr(uint32_t addr)
/** /**
* Write a 32 byte test pattern to the PROM device and verify it * Fill a 32K PROM with a test pattern.
* by reading back. The pattern includes a walking 1 and a
* walking zero, which may help to detect pins that are tied
* together or swapped.
*
* @param start - start address
*/ */
void zapTest(uint32_t start) void pattern32()
{ {
byte testData[] = enum { BLOCK_SIZE = 32 };
byte block[BLOCK_SIZE];
for (uint32_t addr = 0; (addr < 0x8000); addr += BLOCK_SIZE)
{ {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', for (int ix = 0; ix < BLOCK_SIZE; ix++)
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe,
0x00, 0xff, 0x55, 0xaa, '0', '1', '2', '3'
};
if (!prom.writeData(testData, sizeof(testData), start))
{
cmdStatus.error("Write failed");
return;
}
delay(100);
if (!prom.is_readback_safe()) {
// This chip uses the CE line for write control, so don't do the read because it
// could cause a write operation that would corrupt the data.
cmdStatus.info("Write test complete");
return;
}
for (unsigned ix = 0; ix < sizeof(testData); ix++)
{
byte val = prom.readData(start + ix);
if (val != testData[ix])
{ {
cmdStatus.error("Verify failed"); // 256 byte pattern is:
cmdStatus.setValueHex(0, "addr", start + ix); // 00 00 00 01 00 02 00 03 .. 00 7f
cmdStatus.setValueHex(1, "read", val); // 01 00 01 01 01 02 01 03 .. 01 7f
cmdStatus.setValueHex(2, "expected", testData[ix]); // ...
// 3f 00 3f 01 3f 02 3f 03 .. 3f 7f
block[ix] = (ix & 1) ? (((addr + ix) >> 1) & 0x7f) : (addr + ix) >> 8;
}
if (!prom.writeData(block, BLOCK_SIZE, addr))
{
cmdStatus.error("Write failed");
return; return;
} }
} }
cmdStatus.info("Write test successful");
} }
#endif /* ENABLE_DEBUG_COMMANDS */ #endif /* ENABLE_DEBUG_COMMANDS */
@ -713,8 +745,8 @@ void loop()
break; break;
case CMD_CHECKSUM: case CMD_CHECKSUM:
start = if_unspec(start, 0); start = if_unspec(start, 0);
end = if_unspec(end, prom.end()); end = if_unspec(end, prom.end());
w = checksumBlock(start, end); w = checksumBlock(start, end);
Serial.print(F("Checksum ")); Serial.print(F("Checksum "));
printWord(start); printWord(start);
@ -726,31 +758,35 @@ void loop()
break; break;
case CMD_DUMP: case CMD_DUMP:
start = if_unspec(start, dump_next); start = if_unspec(start, dump_next);
dump_next = dumpBlock(start, if_unspec(end, start + 0xff)); dump_next = dumpBlock(start, if_unspec(end, start + 0xff));
break; break;
case CMD_ERASE: case CMD_ERASE:
if (start == unspec || end == unspec) if (start == unspec || end == unspec)
{ {
Serial.println(F("Erase requires explicit start, end")); Serial.println(F("Erase requires explicit start, end"));
} }
else else
{ {
printRetStatus(prom.erase(start, end)); printRetStatus(prom.erase(start, end));
} }
break; break;
case CMD_FILL: case CMD_FILL:
if (start == unspec || end == unspec || val == unspec) if (start == unspec || end == unspec || val == unspec)
{ {
Serial.println(F("Fill requires explicit start, end and value")); Serial.println(F("Fill requires explicit start, end and value"));
} }
else else
{ {
prom.resetDebugStats(); prom.resetDebugStats();
fillBlock(start, end, (byte)val); fillBlock(start, end, (byte)val);
} }
break;
case CMD_INFO:
prom.printDebugStats();
break; break;
case CMD_LOCK: case CMD_LOCK:
@ -764,8 +800,8 @@ void loop()
break; break;
case CMD_READ: case CMD_READ:
start = if_unspec(start, 0); start = if_unspec(start, 0);
end = if_unspec(end, prom.end()); end = if_unspec(end, prom.end());
if (xmodem.SendFile(start, end - start + 1)) if (xmodem.SendFile(start, end - start + 1))
{ {
cmdStatus.info("Send complete."); cmdStatus.info("Send complete.");
@ -780,7 +816,7 @@ void loop()
case CMD_WRITE: case CMD_WRITE:
prom.resetDebugStats(); prom.resetDebugStats();
start = if_unspec(start, 0); start = if_unspec(start, 0);
numBytes = xmodem.ReceiveFile(start); numBytes = xmodem.ReceiveFile(start);
if (numBytes) if (numBytes)
{ {
@ -793,11 +829,12 @@ void loop()
} }
break; break;
#ifdef ENABLE_DEBUG_COMMANDS case CMD_ZAP:
case CMD_INFO: prom.resetDebugStats();
prom.printDebugStats(); zapTest(if_unspec(start, 0));
break; break;
#ifdef ENABLE_DEBUG_COMMANDS
case CMD_SCAN: case CMD_SCAN:
scanBlock(if_unspec(start, 0), if_unspec(end, prom.end())); scanBlock(if_unspec(start, 0), if_unspec(end, prom.end()));
break; break;
@ -806,9 +843,8 @@ void loop()
testAddr(if_unspec(start, 0)); testAddr(if_unspec(start, 0));
break; break;
case CMD_ZAP: case CMD_PATTERN32:
prom.resetDebugStats(); pattern32();
zapTest(if_unspec(start, 0));
break; break;
#endif /* ENABLE_DEBUG_COMMANDS */ #endif /* ENABLE_DEBUG_COMMANDS */
@ -824,21 +860,22 @@ void loop()
Serial.println(); Serial.println();
Serial.println(F("Valid commands are:")); Serial.println(F("Valid commands are:"));
Serial.println(F(" Bsssss eeeee - Check to see if device range is Blank/erased (all FF)")); Serial.println(F(" Bsssss eeeee - Check to see if device range is Blank/erased (all FF)"));
Serial.println(F(" Csssss eeeee - Compute checksum from device")); Serial.println(F(" Csssss eeeee - Compute Checksum from device"));
Serial.println(F(" Dsssss eeeee - Dump bytes from device to terminal")); Serial.println(F(" Dsssss eeeee - Dump bytes from device to terminal"));
Serial.println(F(" Esssss eeeee - Erase address range on device (needed for some Flash)")); Serial.println(F(" Esssss eeeee - Erase address range on device (needed for some Flash)"));
Serial.println(F(" Fsssss eeeee dd - Fill block on device with fixed value")); Serial.println(F(" Fsssss eeeee dd - Fill block on device with fixed value"));
Serial.println(F(" I - Print debug Info"));
Serial.println(F(" L - Lock (enable) device Software Data Protection")); Serial.println(F(" L - Lock (enable) device Software Data Protection"));
Serial.println(F(" Psssss dd dd... - Poke (write) values to device (up to 32 values)")); Serial.println(F(" Psssss dd dd... - Poke (write) values to device (up to 32 values)"));
Serial.println(F(" Rsssss eeeee - Read from device and save to XMODEM CRC file")); Serial.println(F(" Rsssss eeeee - Read from device and save to XMODEM CRC file"));
Serial.println(F(" U - Unlock (disable) device Software Data Protection")); Serial.println(F(" U - Unlock (disable) device Software Data Protection"));
Serial.println(F(" Wsssss - Write to device from XMODEM CRC file")); Serial.println(F(" Wsssss - Write to device from XMODEM CRC file"));
Serial.println(F(" Zsssss - Zap (burn) a 32 byte test pattern"));
#ifdef ENABLE_DEBUG_COMMANDS #ifdef ENABLE_DEBUG_COMMANDS
Serial.println(); Serial.println();
Serial.println(F(" I - Print debug Info"));
Serial.println(F(" Ssssss eeeee - Scan addresses (read each 10x)")); Serial.println(F(" Ssssss eeeee - Scan addresses (read each 10x)"));
Serial.println(F(" Tsssss - Test read address (read 100x)")); Serial.println(F(" Tsssss - Test read address (read 100x)"));
Serial.println(F(" Zsssss - Zap (burn) a 32 byte test pattern")); Serial.println(F(" ! - Fill a 32K device with a test pattern"));
#endif /* ENABLE_DEBUG_COMMANDS */ #endif /* ENABLE_DEBUG_COMMANDS */
break; break;
} }

View File

@ -28,7 +28,5 @@ exerpt: "What's New in TommyPROM"
|3.3 |2022-12-14 |Support 29C0x0 flash| |3.3 |2022-12-14 |Support 29C0x0 flash|
| |2022-12-23 |Documentation for TommyPROM32 PCB| | |2022-12-23 |Documentation for TommyPROM32 PCB|
|3.4 |2024-04-09 |Support 2316,2332, and 2364 mask-programmed ROMs| |3.4 |2024-04-09 |Support 2316,2332, and 2364 mask-programmed ROMs|
|3.5 |2024-04-12 |jcranes's updates to CLI for better parameter defaults and additional error checking.| |3.5 |2024-04-12 |jcranes's updates to CLI for better parameter defaults and additional error checking|
|3.6 |2024-04-23 |Remove debug commands by default - can be enabled in Configure.h|