diff --git a/eeprom.py b/eeprom.py index 780170b..589d9e8 100755 --- a/eeprom.py +++ b/eeprom.py @@ -60,8 +60,17 @@ class AT28C256(object): To load a local file into the EEPROM: > [l|load] [filename] -Send a reset command: -> reset +To test write/read with random nubers: +> [t]est + +To protect the EEPROM: +> [p]rotect + +To unprotect the EEPROM: +> [u]nprotect + +Quit from program: +> [q]uit Address supports hex (0xFF) and octal (0o7) notation. """ @@ -128,7 +137,6 @@ def fdump(self, f: IO, size=0x8000, console=sys.stdout) -> None: print('\nComplete.', file=console) if size < 0x8000: - self.reset() # consume the remaining packet self._receive(ack=False) @@ -159,9 +167,13 @@ def fload(self, f: IO, size: int, console=sys.stdout) -> None: if console: print('\nComplete.', file=console) - def reset(self) -> None: - """Sends a reset command.""" - self._send(pack('>c', b'r')) + def protect(self) -> None: + """Protect EEPROM.""" + self._send(pack('>c', b'p')) + + def unprotect(self) -> None: + """Unprotect EEPROM.""" + self._send(pack('>c', b'u')) def _rnd(self): """returns a generator producing random ASCII data.""" @@ -223,7 +235,10 @@ def repl(self) -> None: 'load': self.load, 't': self.test, 'test': self.test, - 'reset': self.reset, + 'p': self.protect, + 'protect': self.protect, + 'u': self.unprotect, + 'unprotect': self.unprotect, 'quit': self.quit, 'q': self.quit}[expr[0]](*expr[1:]) @@ -292,4 +307,4 @@ def repl(self) -> None: atexit.register(readline.write_history_file, histfile) eeprom.repl() except (KeyboardInterrupt, BrokenPipeError): - eeprom.reset() + exit(1) diff --git a/src/arduino.cpp b/src/arduino.cpp index 9f3a496..cb2f684 100755 --- a/src/arduino.cpp +++ b/src/arduino.cpp @@ -26,7 +26,7 @@ * A1 | EEPROM OE * A2 | EEPROM CE * ----+-------------- - * 13 | Activity LED + * 10 | Activity LED * ----+-------------- * * Copyright 2019, Erik van Zijst @@ -55,7 +55,7 @@ typedef enum { } error; const unsigned int MAX_PAYLOAD = 63; -const unsigned int DELAY_US = 10; +const unsigned int DELAY_US = 1; // AT28C256 contol lines const unsigned int EEPROM_WE = A0; @@ -115,6 +115,59 @@ void setup() { standbyMode(); } +void quickWrite(unsigned int addr, byte val) { + PORTB &= ~B00001000; + + for (int i = 0; i < 16; ++i) { + if (addr & 0x8000) { + PORTC |= B00010000; + } else { + PORTC &= ~B00010000; + } + PORTB |= B00001000; + delayMicroseconds(3); + PORTB &= ~B00001000; + addr <<= 1; + } + + PORTB = (PORTB & 0xfc) | (val >> 6); + PORTD = (PORTD & 0x03) | (val << 2); + + PORTB &= ~B00010000; + delayMicroseconds(2); + PORTB |= B00010000; + delayMicroseconds(2); + PORTB &= ~B00010000; + + delayMicroseconds(2); + PORTC &= ~B00000001; + delayMicroseconds(2); + PORTC |= B00000001; +} + +void unprotect() { + writeMode(); + + quickWrite(0x5555, 0xAA); + quickWrite(0x2AAA, 0x55); + quickWrite(0x5555, 0x80); + quickWrite(0x5555, 0xAA); + quickWrite(0x2AAA, 0x55); + quickWrite(0x5555, 0x20); + + standbyMode(); +} + +void protect() { + writeMode(); + + quickWrite(0x5555, 0xAA); + quickWrite(0x2AAA, 0x55); + quickWrite(0x5555, 0xA0); + + standbyMode(); +} + /* * Reads the next message from the serial port and copies its payload into * the specified `buf` byte array. @@ -185,12 +238,11 @@ void pulse(int pin) { * Loads the specified 16 bit address into the 595 shift register. */ void loadShiftAddr(unsigned int addr) { + delayMicroseconds(DELAY_US); for (int i = 15; i >= 0; i--) { digitalWrite(SHIFT_SER, ((addr >> i) & 1) ? HIGH : LOW); - delayMicroseconds(DELAY_US); pulse(SHIFT_SCLK); } - delayMicroseconds(DELAY_US); pulse(SHIFT_RCLK); } @@ -299,14 +351,14 @@ int load(unsigned int len) { * Returns 0 on success, or -1 on error. */ int writeMode() { - digitalWrite(EEPROM_CE, LOW); - digitalWrite(EEPROM_OE, HIGH); - digitalWrite(EEPROM_WE, HIGH); - for (unsigned int i = 0; i < 8; i++) { pinMode(dataPins[i], OUTPUT); } + digitalWrite(EEPROM_CE, LOW); + digitalWrite(EEPROM_OE, HIGH); + digitalWrite(EEPROM_WE, HIGH); + delayMicroseconds(DELAY_US); mode = WRITE; return 0; @@ -388,8 +440,11 @@ void loop() { send(NULL, 0, false); // acknowledge cmd message load((buf[1] << 8) + buf[2]); - } else if (buf[0] == 0x72 && len == 1) { - // ignore reset command + } else if (buf[0] == 0x70 && len == 1) { + protect(); + + } else if (buf[0] == 0x75 && len == 1) { + unprotect(); } else { errno = E_UNKNOWN;