Skip to content

Instantly share code, notes, and snippets.

@cogwheel
Last active June 14, 2017 16:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save cogwheel/dcc8789264711e7d6cfb3957164201d5 to your computer and use it in GitHub Desktop.
Revised programmer with unlock
/* Programmer for Xicor X28C256 EEPROM, using Mega2560 for parallel I/O */
/* Address pins */
#define A0 30
#define A1 31
#define A2 32
#define A3 33
#define A4 34
#define A5 35
#define A6 36
#define A7 37
#define A8 38
#define A9 39
#define A10 40
#define A11 41
#define A12 42
#define A13 43
#define A14 44
/* I/O pins */
#define IO0 22
#define IO1 23
#define IO2 24
#define IO3 25
#define IO4 26
#define IO5 27
#define IO6 28
#define IO7 29
/* Control signal pins */
#define CE_LOW 51
#define OE_LOW 52
#define WE_LOW 53
void enableChip() {
digitalWrite(CE_LOW, 0);
}
/* Set a bunch of pins' modes at once */
void pinModes(int pin0, int pinN, int mode) {
for (int i = pin0; i <= pinN; ++i) {
pinMode(i, mode);
}
}
/* Set I/O pin modes to given direction */
void setIO(int direction) {
pinModes(IO0, IO7, direction);
}
/* Like shiftOut but for a range of pins */
void shiftPinsOut(int pin0, int pinN, uint32_t data) {
for (int i = pin0; i <= pinN; ++i) {
uint32_t out = (data >> (i - pin0)) & 1;
digitalWrite(i, out);
}
}
/* Set I/O data */
void setData(char data) {
shiftPinsOut(IO0, IO7, data);
}
/* Set address pins */
void setAddress(short address) {
shiftPinsOut(A0, A14, address);
}
/* Like shiftIn but parallel */
uint32_t shiftPinsIn(int pin0, int pinN) {
uint32_t data = 0;
for (int i = pin0; i <= pinN; ++i) {
uint32_t in = digitalRead(i);
data |= in << (i - pin0);
}
return data;
}
/* Write a byte to ROM - minimal setup & delay */
void writeByteFast(short address, char data) {
setAddress(address);
setData(data);
digitalWrite(WE_LOW, 0);
delayMicroseconds(1);
digitalWrite(WE_LOW, 1);
delayMicroseconds(1);
}
/* Allow EEPROM write cycle to finish before next read/write operation */
void waitForWrite() {
delay(10); /* TODO: poll for completion */
}
/* Write a byte to ROM - set up pins, wait for write to finish */
void writeByte(short address, char data) {
setIO(OUTPUT);
writeByteFast(address, data);
waitForWrite();
}
/* Write bytes to ROM using fast page writes
address must be a multiple of 64 (i.e. low 6 bits should be 0)
size can be any number of bytes (within ROM limits) */
void writeBytes(short address, char const data[], short size) {
setIO(OUTPUT);
for (short i = 0; i < size; ++i) {
writeByteFast(address + i, data[i]);
}
waitForWrite();
}
/* Read a byte from ROM */
uint8_t readByte(short address) {
setAddress(address);
uint32_t data;
digitalWrite(OE_LOW, 0);
delayMicroseconds(1);
data = shiftPinsIn(IO0, IO7);
digitalWrite(OE_LOW, 1);
delayMicroseconds(1);
return data;
}
char const test[] = "This text is a 64 byte string that I'm hoping to write to my ROM";
void testWrite() {
writeBytes(0, test, sizeof(test)/sizeof(test[0]) - 1);
/* TODO: readString */
Serial.begin(115200);
setIO(INPUT);
for (short i = 0; i < 64; ++i) {
char val = readByte(i);
Serial.print(val);
if (val != test[i]) {
digitalWrite(LED_BUILTIN, 1);
}
}
}
/* Magic sequence of writes to disable write protection */
void unlock() {
pinModes(IO0, IO7, OUTPUT);
writeByte(0x5555, 0xaa);
writeByte(0x2aaa, 0x55);
writeByte(0x5555, 0x80);
writeByte(0x5555, 0xaa);
writeByte(0x2aaa, 0x55);
writeByte(0x5555, 0x20);
waitForWrite();
}
void setup() {
shiftPinsOut(CE_LOW, WE_LOW, 0xFF);
pinModes(CE_LOW, WE_LOW, OUTPUT);
enableChip();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, 0);
pinModes(A0, A14, OUTPUT);
unlock();
testWrite();
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment