#define SHIFT_DATA 2
#define SHIFT_CLK 3
#define SHIFT_LATCH 4
#define WRITE_EN_16 11
#define WRITE_EN_16_MASK B1000
#define WRITE_EN_256 12
#define WRITE_EN_256_MASK B10000
#define ADDRESS_11 11
#define ADDRESS_13 13
#define VCC 13
#define A6 6
#define A7 5
#define DATA_PIN_COUNT 8
bool is_256 = false;
uint8_t data_pins[DATA_PIN_COUNT] = { A0, A1, A2, A3, A4, A5, A6, A7 };
void set_is_256(bool _is_256) {
is_256 = _is_256;
digitalWrite(VCC, is_256);
delay(500);
}
void pulse_write_enable() {
byte pin_mask = is_256 ? WRITE_EN_256_MASK : WRITE_EN_16_MASK;
PORTB &= ~pin_mask;
__asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
PORTB |= pin_mask;
delay(10);
}
void set_address(uint16_t address, bool outputEnable) {
shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address);
shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, (address >> 8) | (outputEnable ? 0x00 : 0x80));
digitalWrite(SHIFT_LATCH, LOW);
digitalWrite(SHIFT_LATCH, HIGH);
digitalWrite(SHIFT_LATCH, LOW);
if (is_256) {
digitalWrite(ADDRESS_11, (address >> 10) & 0x1);
digitalWrite(ADDRESS_13, (~address >> 12) & 0x1);
}
}
void io_mode(uint8_t mode) {
for (uint8_t pin = 0; pin < DATA_PIN_COUNT; pin++)
pinMode(data_pins[pin], mode);
}
byte read_rom(uint16_t address) {
io_mode(INPUT);
set_address(address, true);
byte data = 0;
for (uint8_t pin = DATA_PIN_COUNT; pin > 0; pin--)
data = (data << 1) + digitalRead(data_pins[pin - 1]);
return data;
}
void write_rom(uint16_t address, byte data) {
set_address(address, false);
io_mode(OUTPUT);
for (uint8_t pin = 0; pin < DATA_PIN_COUNT; pin++) {
digitalWrite(data_pins[pin], data & 1);
data = data >> 1;
}
pulse_write_enable();
}
void print_contents() {
for (uint16_t base = 0; base <= 255; base += 16) {
byte data[16];
for (uint8_t offset = 0; offset <= 15; offset++)
data[offset] = read_rom(base + offset);
char buf[80];
sprintf(buf, "%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
Serial.println(buf);
}
}
byte data[] = { 0x81, 0xcf, 0x92, 0x86, 0xcc, 0xa4, 0xa0, 0x8f, 0x80, 0x84, 0x88, 0xe0, 0xb1, 0xc2, 0xb0, 0xb8 };
void setup() {
pinMode(SHIFT_DATA, OUTPUT);
pinMode(SHIFT_CLK, OUTPUT);
pinMode(SHIFT_LATCH, OUTPUT);
digitalWrite(WRITE_EN_16, HIGH);
digitalWrite(WRITE_EN_256, HIGH);
pinMode(WRITE_EN_16, OUTPUT);
pinMode(WRITE_EN_256, OUTPUT);
pinMode(ADDRESS_11, OUTPUT);
pinMode(ADDRESS_13, OUTPUT);
Serial.begin(57600);
set_is_256(false);
Serial.print("Erasing EEPROM");
for (uint16_t address = 0; address <= 2047; address++) {
write_rom(address, 0xff);
if (address % 64 == 0)
Serial.print(".");
}
Serial.println(" done");
Serial.print("Programming EEPROM");
for (uint16_t address = 0; address < sizeof(data); address++) {
write_rom(address, data[address]);
if (address % 64 == 0)
Serial.print(".");
}
Serial.println(" done");
Serial.println("Reading EEPROM");
print_contents();
}
void loop() {}