mirror of
https://github.com/TomNisbet/TommyPROM.git
synced 2024-06-09 20:29:31 +00:00
190 lines
5.0 KiB
C++
190 lines
5.0 KiB
C++
// NOTE - The 23 series device support is a work in progress. It
|
|
// has not been tested or documented.
|
|
|
|
#include "Configure.h"
|
|
#if defined(PROM_IS_23)
|
|
|
|
#include "PromAddressDriver.h"
|
|
|
|
// IO lines for the EPROM device control
|
|
// Pins D2..D9 are used for the data bus.
|
|
enum {
|
|
CS3_PIN = A0, // WE on 28C schematic
|
|
CS2_PIN = A1, // CE on 28C schematic
|
|
CS1_PIN = A2 // OE on 28C schematic
|
|
};
|
|
enum {
|
|
CS3_BIT = 0x04,
|
|
CS2_BIT = 0x02,
|
|
CS1_BIT = 0x01
|
|
};
|
|
|
|
static unsigned csBits;
|
|
|
|
// Set the status of the device control pins
|
|
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)
|
|
: PromDevice(size, 0, 0, false)
|
|
{
|
|
}
|
|
|
|
|
|
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_PULLUP);
|
|
|
|
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();
|
|
disableCS3();
|
|
|
|
// This chip uses the shift register hardware for addresses, so initialize that.
|
|
PromAddressDriver::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(F("no unlock needed, scanning chip selects..."));
|
|
|
|
// 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(F("Setting CS bits to "));
|
|
printCSbits(csBits);
|
|
Serial.println();
|
|
return RET_OK;
|
|
}
|
|
}
|
|
|
|
Serial.println(F("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/WE:");
|
|
Serial.print((bits & CS3_BIT) ? 'H':'L');
|
|
Serial.print(" CS2/CE:");
|
|
Serial.print((bits & CS2_BIT) ? 'H':'L');
|
|
Serial.print(" CS1/OE:");
|
|
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(F("\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)
|
|
{
|
|
PromAddressDriver::setAddress(address);
|
|
}
|
|
|
|
|
|
// Read a byte from a given address
|
|
byte PromDevice23::readByte(uint32_t address)
|
|
{
|
|
byte data = 0;
|
|
setAddress(address);
|
|
setDataBusMode(INPUT_PULLUP);
|
|
enableCS1();
|
|
enableCS2();
|
|
enableCS3();
|
|
|
|
delayMicroseconds(20);
|
|
data = readDataBus();
|
|
|
|
disableCS3();
|
|
disableCS2();
|
|
disableCS1();
|
|
|
|
return data;
|
|
}
|
|
|
|
#endif // #if defined(PROM_IS_23)
|