From 08f93deee668d2fb17f8f22f8f3493580ff535f2 Mon Sep 17 00:00:00 2001 From: Tom Nisbet Date: Tue, 9 Apr 2024 13:02:51 -0400 Subject: [PATCH] Automatic detection of 2316 chip selects --- TommyPROM/PromDevice.cpp | 2 + TommyPROM/PromDevice23.cpp | 134 +++++++++++++++++++++++++++++++++---- TommyPROM/PromDevice23.h | 4 ++ TommyPROM/TommyPROM.ino | 4 +- 4 files changed, 128 insertions(+), 16 deletions(-) diff --git a/TommyPROM/PromDevice.cpp b/TommyPROM/PromDevice.cpp index 23d464e..56a84a6 100644 --- a/TommyPROM/PromDevice.cpp +++ b/TommyPROM/PromDevice.cpp @@ -114,6 +114,8 @@ void PromDevice::setDataBusMode(uint8_t mode) { DDRB &= 0xfc; DDRD &= 0x03; + PORTB |= 0x03; // set pullup resistors + PORTD |= 0xfc; } } diff --git a/TommyPROM/PromDevice23.cpp b/TommyPROM/PromDevice23.cpp index 5ba66f3..ac22ec8 100644 --- a/TommyPROM/PromDevice23.cpp +++ b/TommyPROM/PromDevice23.cpp @@ -8,17 +8,25 @@ // IO lines for the EPROM device control // Pins D2..D9 are used for the data bus. -#define CS3 A0 -#define CS1 A1 -#define CS2 A2 +#define CS3_PIN A0 +#define CS2_PIN A1 +#define CS1_PIN A2 +#define CS3_BIT 0x04 +#define CS2_BIT 0x02 +#define CS1_BIT 0x01 + +static unsigned csBits; // Set the status of the device control pins -static void enableCS1() { digitalWrite(CS1, HIGH); } -static void disableCS1() { digitalWrite(CS1, LOW);} -static void enableCS2() { digitalWrite(CS2, HIGH); } -static void disableCS2() { digitalWrite(CS2, LOW);} -static void enableCS3() { digitalWrite(CS3, HIGH); } -static void disableCS3() { digitalWrite(CS3, LOW);} +static void enableCS(unsigned pin, unsigned maskBit) { digitalWrite(pin, (csBits & maskBit) ? HIGH : LOW); } +static void disableCS(unsigned pin, unsigned maskBit) { digitalWrite(pin, (csBits & maskBit) ? LOW : HIGH); } + +static void enableCS1() { enableCS(CS1_PIN, CS1_BIT); } +static void disableCS1() { disableCS(CS1_PIN, CS1_BIT); } +static void enableCS2() { enableCS(CS2_PIN, CS2_BIT); } +static void disableCS2() { disableCS(CS2_PIN, CS2_BIT); } +static void enableCS3() { enableCS(CS3_PIN, CS3_BIT); } +static void disableCS3() { disableCS(CS3_PIN, CS3_BIT); } PromDevice23::PromDevice23(uint32_t size) @@ -31,11 +39,12 @@ void PromDevice23::begin() { // Define the data bus as input initially so that it does not put out a // signal that could collide with output on the data pins of the EEPROM. - setDataBusMode(INPUT); + setDataBusMode(INPUT_PULLUP); - pinMode(CS1, OUTPUT); - pinMode(CS2, OUTPUT); - pinMode(CS3, OUTPUT); + csBits = 0; // Init to CS3, CS2, and CS1 all active LOW + pinMode(CS1_PIN, OUTPUT); + pinMode(CS2_PIN, OUTPUT); + pinMode(CS3_PIN, OUTPUT); disableCS1(); disableCS2(); @@ -46,9 +55,106 @@ void PromDevice23::begin() } +// Override the existing Unlock command to scan the different combinations of CS until +// data is found. If the CS lines are not correctly configured, the chip should not +// assert any signals on the data bus and the Arduino will read back all FF. +ERET PromDevice23::disableSoftwareWriteProtect() +{ + // Finish out the Unlock message printed by the UI code + Serial.println("just kidding!"); + + // 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 + // 16-byte blocks, so a valid set of CS pins should encounter some data. + for (uint32_t addrBase = 0x0000; (addrBase < mSize); addrBase += 0x250) + { + if (scanAddress(addrBase)) + { + Serial.print("Setting CS bits to "); + printCSbits(csBits); + Serial.println(); + return RET_OK; + } + } + + Serial.println("No valid CS settings found"); + + return RET_FAIL; +} + + // BEGIN PRIVATE METHODS // +// Print the current CS bit settings. +void PromDevice23::printCSbits(unsigned bits) +{ + Serial.print("CS3:"); + Serial.print((bits & CS3_BIT) ? 'H':'L'); + Serial.print(" CS2:"); + Serial.print((bits & CS2_BIT) ? 'H':'L'); + Serial.print(" CS1:"); + Serial.print((bits & CS1_BIT) ? 'H':'L'); +} + + +// Try all combinations of the CS bits and read 16 bytes of data from the chip. +// One of the CS settings should read some non-FF data. +bool PromDevice23::scanAddress(uint32_t addrBase) +{ + unsigned saveBits = 0xff; + + Serial.print("\nScanning Chip Select combinations starting at address "); + printByte(addrBase >> 8); + printByte(addrBase & 0xff); + Serial.println(); + + for (csBits = 0; (csBits < 8); csBits++) + { + // Disable all CS bits using the new definition of csBits + disableCS3(); + disableCS2(); + disableCS1(); + + printCSbits(csBits); + Serial.print(" - "); + for (unsigned offset = 0; (offset < 16); offset++) + { + byte data = readByte(addrBase + offset); + printByte(data); + Serial.print(' '); + if (data != 0xff) + { + // this combination of Chip Selects successfully read data + saveBits = csBits; + } + } + Serial.println(); + } + + if (saveBits != 0xff) + { + csBits = saveBits; + return true; + } + return false; +} + + +static const char hex[] = "0123456789abcdef"; + +void PromDevice23::printByte(byte b) +{ + char line[3]; + + line[0] = hex[b >> 4]; + line[1] = hex[b & 0x0f]; + line[2] = '\0'; + + Serial.print(line); +} + + // Use the PromAddressDriver to set a 16 bit address in the two address shift registers. void PromDevice23::setAddress(uint32_t address) { @@ -61,7 +167,7 @@ byte PromDevice23::readByte(uint32_t address) { byte data = 0; setAddress(address); - setDataBusMode(INPUT); + setDataBusMode(INPUT_PULLUP); enableCS1(); enableCS2(); enableCS3(); diff --git a/TommyPROM/PromDevice23.h b/TommyPROM/PromDevice23.h index 335839f..c1d5da9 100644 --- a/TommyPROM/PromDevice23.h +++ b/TommyPROM/PromDevice23.h @@ -24,8 +24,12 @@ class PromDevice23 : public PromDevice PromDevice23(uint32_t size); void begin(); const char *getName() { return "23 series PROM"; } + ERET disableSoftwareWriteProtect(); // use the Unlock command to scan the chip selects protected: + void printCSbits(unsigned bits); + bool scanAddress(uint32_t addrBase); + void printByte(byte b); void setAddress(uint32_t address); byte readByte(uint32_t address); bool burnByte(byte value, uint32_t address) { return false; } diff --git a/TommyPROM/TommyPROM.ino b/TommyPROM/TommyPROM.ino index d50be9b..dfce3f6 100644 --- a/TommyPROM/TommyPROM.ino +++ b/TommyPROM/TommyPROM.ino @@ -19,7 +19,7 @@ #include "XModem.h" -static const char * MY_VERSION = "3.3"; +static const char * MY_VERSION = "3.4"; // Global status @@ -74,7 +74,7 @@ PromDeviceSST28SF prom(512 * 1024L, 40, true); PromDevice8755A prom(2 * 1024L); #elif defined(PROM_IS_23) -PromDevice23 prom(2 * 1024L); // 2316 +PromDevice23 prom(2 * 1024L); // 2316 // Additional device-specific code goes here... //#elif defined(PROM_IS...