forked from Apple-2-HW/TommyPROM
263 lines
6.6 KiB
Arduino
263 lines
6.6 KiB
Arduino
|
/**
|
||
|
* Test hardware for ATMEL 28C series EEPROMs.
|
||
|
*
|
||
|
* The hardware uses two 74LS164 shift registers as the low and
|
||
|
* high address registers.
|
||
|
**/
|
||
|
|
||
|
#include "Configure.h"
|
||
|
|
||
|
#define LED 13
|
||
|
|
||
|
PromDevice28C prom(32 * 1024L, 64, 10, true);
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
/**
|
||
|
* CLI parse functions
|
||
|
*/
|
||
|
const char hex[] = "0123456789abcdef";
|
||
|
|
||
|
|
||
|
// Read a line of data from the serial connection.
|
||
|
char * readLine(char * buffer, int len)
|
||
|
{
|
||
|
for (int ix = 0; (ix < len); ix++)
|
||
|
{
|
||
|
buffer[ix] = 0;
|
||
|
}
|
||
|
|
||
|
// read serial data until linebreak or buffer is full
|
||
|
char c = ' ';
|
||
|
int ix = 0;
|
||
|
do {
|
||
|
if (Serial.available())
|
||
|
{
|
||
|
c = Serial.read();
|
||
|
if ((c == '\b') && (ix > 0))
|
||
|
{
|
||
|
// Backspace, forget last character
|
||
|
--ix;
|
||
|
}
|
||
|
buffer[ix++] = c;
|
||
|
Serial.write(c);
|
||
|
}
|
||
|
} while ((c != '\n') && (ix < len));
|
||
|
|
||
|
buffer[ix - 1] = 0;
|
||
|
return buffer;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* convert a single hex character [0-9a-fA-F] to its value
|
||
|
* @param char c single character (digit)
|
||
|
* @return byte value of the digit (0-15)
|
||
|
************************************************************/
|
||
|
byte hexDigit(char c)
|
||
|
{
|
||
|
if ((c >= '0') && (c <= '9'))
|
||
|
{
|
||
|
return c - '0';
|
||
|
}
|
||
|
else if ((c >= 'a') && (c <= 'f'))
|
||
|
{
|
||
|
return c - 'a' + 10;
|
||
|
}
|
||
|
else if ((c >= 'A') && (c <= 'F'))
|
||
|
{
|
||
|
return c - 'A' + 10;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0xff;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* convert a hex byte (00 - ff) to byte
|
||
|
* @param c-string with the hex value of the byte
|
||
|
* @return byte represented by the digits
|
||
|
************************************************************/
|
||
|
byte hexByte(char * a)
|
||
|
{
|
||
|
return (hexDigit(a[0]) << 4) | hexDigit(a[1]);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* convert a hex word (0000 - ffff) to unsigned int
|
||
|
* @param c-string with the hex value of the word
|
||
|
* @return unsigned int represented by the digits
|
||
|
************************************************************/
|
||
|
unsigned int hexWord(char * data)
|
||
|
{
|
||
|
return (hexDigit(data[0]) << 12) |
|
||
|
(hexDigit(data[1]) << 8) |
|
||
|
(hexDigit(data[2]) << 4) |
|
||
|
(hexDigit(data[3]));
|
||
|
}
|
||
|
|
||
|
|
||
|
void printByte(byte b)
|
||
|
{
|
||
|
char line[3];
|
||
|
|
||
|
line[0] = hex[b >> 4];
|
||
|
line[1] = hex[b & 0x0f];
|
||
|
line[2] = '\0';
|
||
|
|
||
|
Serial.print(line);
|
||
|
}
|
||
|
|
||
|
|
||
|
void printWord(word w)
|
||
|
{
|
||
|
char line[5];
|
||
|
|
||
|
line[0] = hex[(w >> 12) & 0x0f];
|
||
|
line[1] = hex[(w >> 8) & 0x0f];
|
||
|
line[2] = hex[(w >> 4) & 0x0f];
|
||
|
line[3] = hex[(w) & 0x0f];
|
||
|
line[4] = '\0';
|
||
|
|
||
|
Serial.print(line);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************
|
||
|
* MAIN
|
||
|
*************************************************/
|
||
|
word addr = 0;
|
||
|
|
||
|
void setup()
|
||
|
{
|
||
|
// Do this first so that it initializes all of the hardware pins into a
|
||
|
// non-harmful state. The Arduino or the target EEPROM could be damaged
|
||
|
// if both writing to the data bus at the same time.
|
||
|
prom.begin();
|
||
|
|
||
|
Serial.begin(115200);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
word start = 0;
|
||
|
word end = 0xff;
|
||
|
byte val = 0xff;
|
||
|
|
||
|
void loop()
|
||
|
{
|
||
|
byte b;
|
||
|
word w;
|
||
|
bool error = false;
|
||
|
char line[20];
|
||
|
uint32_t numBytes;
|
||
|
|
||
|
Serial.print("\n#");
|
||
|
Serial.flush();
|
||
|
readLine(line, sizeof(line));
|
||
|
byte c = tolower(line[0]);
|
||
|
if ((c >= 'A') && (c <= 'Z')) {
|
||
|
c |= 0x20;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Note that the comamnds here allow for direct writing of the 28C control lines with some exceptions to
|
||
|
* protect the chip and the host arduino:
|
||
|
* 1) When the O command is used to enable chip output, the arduino data bus us set to INPUT
|
||
|
* 2) When the D command is used to write data from the arduino, the chip output is disabled
|
||
|
* 3) The R command sets to output enable (OE) on the chip (but not the chip enable (CE)) */
|
||
|
switch (c)
|
||
|
{
|
||
|
case 'a':
|
||
|
if (hexDigit(line[1]) <= 15)
|
||
|
{
|
||
|
w = hexWord(line + 1);
|
||
|
prom.setAddress(w);
|
||
|
}
|
||
|
else
|
||
|
error = true;
|
||
|
break;
|
||
|
case 'd':
|
||
|
if (hexDigit(line[1]) <= 15)
|
||
|
{
|
||
|
prom.disableOutput();
|
||
|
prom.setDataBusMode(OUTPUT);
|
||
|
b = hexByte(line + 1);
|
||
|
prom.writeDataBus(b);
|
||
|
}
|
||
|
else
|
||
|
error = true;
|
||
|
break;
|
||
|
case 'c':
|
||
|
case 'o':
|
||
|
case 'w':
|
||
|
if ((line[1] == 'd') || (line[1] == 'e')) {
|
||
|
bool enable = line[1] == 'e';
|
||
|
if (c == 'c')
|
||
|
if (enable) prom.enableChip(); else prom.disableChip();
|
||
|
else if (c == 'w')
|
||
|
if (enable) prom.enableWrite(); else prom.disableWrite();
|
||
|
else { // c == 'o'
|
||
|
if (enable)
|
||
|
{
|
||
|
// Don't allow the prom and the data bus to output at the same time
|
||
|
prom.setDataBusMode(INPUT);
|
||
|
prom.enableOutput();
|
||
|
}
|
||
|
else prom.disableOutput();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
error = true;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'r':
|
||
|
prom.setDataBusMode(INPUT);
|
||
|
prom.enableOutput();
|
||
|
b = prom.readDataBus();
|
||
|
printByte(b);
|
||
|
Serial.println();
|
||
|
prom.disableOutput();
|
||
|
break;
|
||
|
|
||
|
case 'l':
|
||
|
Serial.println(F("Writing the lock code to enable Software Write Protect mode."));
|
||
|
prom.enableSoftwareWriteProtect();
|
||
|
break;
|
||
|
|
||
|
case 'u':
|
||
|
Serial.println(F("Writing the unlock code to disable Software Write Protect mode."));
|
||
|
prom.disableSoftwareWriteProtect();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
error = true;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (error) {
|
||
|
Serial.print(F("Hardware Verifier - "));
|
||
|
Serial.println(prom.getName());
|
||
|
Serial.println();
|
||
|
Serial.println(F("Valid commands are:"));
|
||
|
Serial.println(F(" Axxxx - Set address bus to xxxx"));
|
||
|
Serial.println(F(" Dxx - Set Data bus to xx"));
|
||
|
Serial.println(F(" Cs - Set Chip enable to state (e=enable, d=disable)"));
|
||
|
Serial.println(F(" Os - Set Output enable to state (e=enable, d=disable)"));
|
||
|
Serial.println(F(" Ws - Set Write enable to state (e=enable, d=disable)"));
|
||
|
Serial.println(F(" R - Read and print the value on the data bus"));
|
||
|
Serial.println(F(" L - Send Lock sequence to enable device Software Data Protection"));
|
||
|
Serial.println(F(" U - Send Unlock sequence to disable device Software Data Protection"));
|
||
|
}
|
||
|
}
|
||
|
|