//-------------------------------------------------------------------- // EPROM programmer - By Claudio Fin 2012 //-------------------------------------------------------------------- // // +------------+ // 10 --> | SYNC | --> 10 // +------------+ // +------------+ // 11 --> | TEST BLANK | --> 0=OK 1=KO // +------------+ // +------------+ // 12 --> | DUMP | --> // L ADDR --> | | : LEN BYTES // H ADDR --> | | --> // L LEN --> | | // H LEN --> | | // +------------+ // +------------+ // 13 --> | WRITE | --> 0=DONE // L ADDR --> | | // H ADDR --> | | // L LEN --> | | // H LEN --> | | // ---------> | | // LEN BYTES | max 1024 | // : | bytes | // ---------> | | // +------------+ // //-------------------------------------------------------------------- # define SIPO_STROBE 2 # define SIPO_DATA 3 # define SH_CLK 4 # define PISO_LOAD 5 # define PISO_DATA 6 # define IO_RD 7 # define IO_WR 8 # define IO_EN 9 # define IO_A0 10 # define IO_A1 11 # define IO_A2 12 # define LED 13 //-------------------------------------------------------------------- unsigned long ledTime = millis(); byte ledStat = 1; //-------------------------------------------------------------------- void setup() { pinMode(SIPO_STROBE, OUTPUT); digitalWrite(SIPO_STROBE, 0); pinMode(SIPO_DATA, OUTPUT); pinMode(SH_CLK, OUTPUT); digitalWrite(SH_CLK, 0); pinMode(PISO_LOAD, OUTPUT); digitalWrite(PISO_LOAD, 0); pinMode(IO_RD, OUTPUT); digitalWrite(IO_RD, 1); pinMode(IO_WR, OUTPUT); digitalWrite(IO_WR, 1); pinMode(IO_EN, OUTPUT); digitalWrite(IO_EN, 1); pinMode(IO_A0, OUTPUT); pinMode(IO_A1, OUTPUT); pinMode(IO_A2, OUTPUT); pinMode(LED, OUTPUT); busWrite(0, 0); busWrite(1, 0); Serial.begin(38400); Serial.flush(); } //-------------------------------------------------------------------- void loop() { while (Serial.available()==0) blinkLed(); // wait command int cmd = Serial.read(); if (cmd==10 || cmd==11 || cmd==12 || cmd==13) { if (cmd == 10) { Serial.write(byte(10)); return; } // sync if (cmd == 11) { verifCanc(); return; } // test blank while (Serial.available()==0) blinkLed(); // wait low addr word addr = Serial.read() & 255; while (Serial.available()==0) blinkLed(); // wait high addr addr += Serial.read() << 8; while (Serial.available()==0) blinkLed(); // wait low len word len = Serial.read() & 255; while (Serial.available()==0) blinkLed(); // wait high len len += Serial.read() << 8; if (cmd == 12) { dumpEPROM(addr, len); return; } writeEPROM(addr, len); } } //-------------------------------------------------------------------- void blinkLed() { if (millis() > ledTime + 40) { ledTime = millis(); ledStat = !ledStat; digitalWrite(LED, ledStat); } } //-------------------------------------------------------------------- // EPROM programmer functions //-------------------------------------------------------------------- void dumpEPROM(word addr, word len) { setEPROMAddr(addr, 0x80); // 0x80 = riposo lettura while (len > 0) { busWrite(1, 0x80 + ((addr>>12)&7)); Serial.write(byte(busRead(0))); busWrite(1, 0x88); // avanza contatore indirizzo ++addr; --len; } busWrite(0, 0); busWrite(1, 0); } //-------------------------------------------------------------------- void writeEPROM(word addr, word len) { byte dataBuffer[1024]; // buffer dati scrittura for (int i = 0; (i 0) { busWrite(0, dataBuffer[i]); busWrite(1, 0x70+((addr>>12)&7)); busDoubleWrite(1, 0x60+((addr>>12)&7), 0x70+((addr>>12)&7), 1); busWrite(1, 0x78); // avanza contatore indirizzo ++i; ++addr; --len; } Serial.write(byte(0)); busWrite(0, 0); busWrite(1, 0); } //-------------------------------------------------------------------- void verifCanc() { setEPROMAddr(0, 0x80); boolean blank = true; word addr = 0; while (addr < 32768) { busWrite(1, 0x80+((addr>>12)&7)); if (busRead(0) == 255) { ++addr; busWrite(1, 0x88); } else { blank = false; break; } } busWrite(0, 0); busWrite(1, 0); Serial.write(byte(!blank)); } //-------------------------------------------------------------------- void setEPROMAddr(int addr, int n) { busWrite(1, 0); // azzera registro di controllo delay(200); busWrite(1, n); // scrive valore riposo registro controllo delay(200); while (addr > 0) // genera addr impulsi avanzamento indirizzo { busDoubleWrite(1, n|8, n, 0); --addr; } } //-------------------------------------------------------------------- // BUS emulator functions //-------------------------------------------------------------------- byte busRead(int addr) { setBusAddr(addr); digitalWrite(IO_EN, 0); digitalWrite(IO_RD, 0); digitalWrite(SH_CLK, 1); digitalWrite(PISO_LOAD, 1); digitalWrite(PISO_LOAD, 0); byte n = shiftIn(PISO_DATA, SH_CLK, MSBFIRST); digitalWrite(IO_RD, 1); digitalWrite(IO_EN, 1); return n; } //-------------------------------------------------------------------- void busWrite(int addr, int n) { setBusAddr(addr); shiftOut(SIPO_DATA, SH_CLK, MSBFIRST, n); digitalWrite(SIPO_STROBE, 1); digitalWrite(SIPO_STROBE, 0); busWritePulse(); } //-------------------------------------------------------------------- void busDoubleWrite(int addr, int n1, int n2, int t) { setBusAddr(addr); shiftOut(SIPO_DATA, SH_CLK, MSBFIRST, n1); digitalWrite(SIPO_STROBE, 1); digitalWrite(SIPO_STROBE, 0); busWritePulse(); if (t > 0){ delayMicroseconds(830); if (t > 1) delay(t-1); } shiftOut(SIPO_DATA, SH_CLK, MSBFIRST, n2); digitalWrite(SIPO_STROBE, 1); digitalWrite(SIPO_STROBE, 0); busWritePulse(); } //-------------------------------------------------------------------- void busWritePulse() { digitalWrite(IO_EN, 0); digitalWrite(IO_WR, 0); digitalWrite(IO_WR, 1); digitalWrite(IO_EN, 1); } //-------------------------------------------------------------------- void setBusAddr(int addr) { digitalWrite( IO_A0, addr&1); digitalWrite( IO_A1, (addr>>1) &1 ); digitalWrite( IO_A2, (addr>>2)&1 ); } //--------------------------------------------------------------------