All the other examples I've seen have had coding errors where they set a pin LOW in a loop with no delay so that it goes high again right away - but this problem is different, and probably something obvious.
I set up a breadboard memory (EEPROM or similarly-pinned flash) programmer (ala BenEater and many similar sources) using two 74**595s for the first 15 address bits as well as the OE# bit in the MSB spot, and the nano digital outputs for the 8 data bits as well as the WE# (write-enable) bit. The data, address, and OE# pins set correctly every time. The WE# pin, however, stays HIGH forever once it goes HIGH.
I have tried every digital pin for WE#, I have tried every analog pin with an analogWrite. I have tried now three different memory chips and three Arduino Nanos that I've used successfully elsewhere, but still no success.
The only thing I can assume is that the WE# pin on the memory ICs somehow is keeping the line high, but I can't for the life of me figure out how that's possible.
Code and logic analyzer example:
/*
EEPROM Programmer
In this case, programming a SST39SF010A
55ns read access, 22us write time
Software Data Protection to write:
(0x5555, 0xAA)
(0x2AAA, 0x55)
(0x5555, 0xA0)
*/
#define SHIFT_DATA 13
#define SHIFT_CLK 12
#define SHIFT_LATCH 11
#define ROM_D0 2
#define ROM_D1 3
#define ROM_D2 4
#define ROM_D3 5
#define ROM_D4 6
#define ROM_D5 7
#define ROM_D6 8
#define ROM_D7 9
#define WRITE_EN 10
void setAddress(int address, bool outputEnable) {
shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, ((address >> 8) | (outputEnable ? 0x00 : 0x80))); // High bits
shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address); // Low bits
digitalWrite(SHIFT_LATCH, LOW);
digitalWrite(SHIFT_LATCH, HIGH);
digitalWrite(SHIFT_LATCH, LOW);
}
byte readROM(int address) {
for (int pin = ROM_D0; pin <= ROM_D7; pin++) {
pinMode(pin, INPUT);
}
byte data = 0;
setAddress(address, /* outputEnable */ true);
// Read each pin
for (int pin = ROM_D7; pin >= ROM_D0; pin--) {
data = (data << 1) + digitalRead(pin);
}
return data;
}
void printContents() {
for (int base = 0; base < 256; base += 16) {
byte data[16];
char buf[80];
for (int offset = 0; offset < 16; offset++) {
data[offset] = readROM(base + offset);
}
// buffer (string) to hold the formatted data
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);
}
}
void writeROM(int address, byte data) {
for (int pin = ROM_D0; pin <= ROM_D7; pin++) {
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
setAddress(address, /* outputEnable */ false);
for (int pin = ROM_D0; pin <= ROM_D7; pin++) {
digitalWrite(pin, (data & 0x01));
data = (data >> 1);
}
digitalWrite(10, LOW);
delayMicroseconds(10);
digitalWrite(10, HIGH);
delay(1);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(56700);
Serial.flush();
pinMode(SHIFT_DATA, OUTPUT);
pinMode(SHIFT_CLK, OUTPUT);
pinMode(SHIFT_LATCH, OUTPUT);
// Set pull-up resistor
digitalWrite(WRITE_EN, HIGH);
pinMode(WRITE_EN, OUTPUT);
Serial.println();
writeROM(0x5555, 0xAA);
writeROM(0x2AAA, 0x55);
writeROM(0x5555, 0xA0);
for (int i = 0; i < 256; i++)
{
writeROM(i, i % 13);
}
printContents();
}
void loop() {
// put your main code here, to run repeatedly:
}
