Los años pasan y por alguna profunda u oscura razones nos siguen gustando juguetes parecidos, a veces quizá algo más caro. Aunque los precios de la electrónica, con el tiempo fueron reduciéndose exponencialmente.
Aquí comento brevemente la construcción -y sobre todo el troubleshooting- de un grabador -diseñado por Mario Keller- de eeprom para aquellas computadoras de 8 bits.
Tiempo atrás, cartuchos como los mencionados solían utilizar EPROMs como la 2764 o 27256. Aquellas EPROMs requerían de exposición a una fuente de luz UV para su borrado. Normalmente se ponía un pequeño tubo UV en una caja estanca y se las exponía por un cierto tiempo, en general 10-15 minutos.Posteriormente se desarrollaron las "Electrically Erasable Programmable Read Only Memory", que ya no tienen en su encapsulado la ventana para el ingreso de luz UV, porque se pueden borrar eléctricamente.
Hay EEPROMs con distinto tipo de buses, pero las de bus paralelo, como la 28C256 presentan un pinout retrocompatibles con las EPROMs de bus paralelo de generaciones previas, como la 27256.
Para que estas EEPROMs/EPROM puedan servir, por ejemplo para algún proyecto con algún microprocesador de 8 bits (z80,6809, etc) o para programar un cartucho para la Commodore 64 por ejemplo, es necesario usar un grabador. Hoy en día, los grabadores para EEPROMs de bus paralelo pueden ser relativamente costosos.
MEEPROMMER
MEEPROMMER es el nombre de un diseño de Mario Keller basado en un Arduino, publicado bajo licencia open source (MIT): https://github.com/mkeller0815/MEEPROMMER. El autor también desarrolló una aplicación Java que sirve para interactuar con el grabador, para grabar o leer datos desde la memoria, comparar la imagen con el contenido de la memoria, etc. El esquemático puede verse a continuación:
Aquí se puede ver el circuito montado, ya funcionando:
Para llegar a esto, fue necesario un troubleshooting bastante laborioso.
Sobre el troubleshooting
En varios aspectos un montaje electrónico se parece a cualquier otra artesanía: en general una vez montado el circuito en un prototipo o no, siempre es necesario dedicar tiempo al troubleshooting. Por errores humanos u otros factores, siempre algo puede fallar, algo habrá que mejorar o depurar. Estas notas son la historia de este troubleshooting, supongo que quizá le sean de utilidad a otros o posiblemente a mí mismo, cuando me haya olvidado de lo que tuve que hacer para detectar la falla.
Además de el proyecto en github, me fue muy útil para el troubleshooting la información disponible en este site en español: https://8bit65.wordpress.com/2014/09/04/programando-la-eeprom/
También los consejos de foros y de mi amigo el Bocha me fueron de gran utilidad.
Como en un troubleshooting de cualquier cosa, la técnica que me resulta más eficaz es dividir el problema en partes más pequeñas, hasta identificar las fallas.
El diseño de Mario se basa en dos shift registers (los chips 74HC595) que sirven para resolver el problema de la cantidad de pines I/O necesarios para el bus de direcciones (15) más el bus de datos (8) y pines de control de la memoria. Por supuesto, los pines de un arduino nano no serían suficientes. El registro de desplazamiento permite controlar 8 salidas al mismo tiempo, mientras solo se utilizan unos pocos pines del microcontrotrolados. Una buena explicación acerca del principio de funcionamiento puede leerse en: https://www.arduino.cc/en/Tutorial/ShiftOut
Luego de que las primeras pruebas indicaran que algo estaba fallando, para el troubleshooting del circuito seguí el siguiente orden:
1) Testeado del cableado en la placa experimental.
2) Se puede utilizar el monitor serie de arduino IDE o cualquier programa de comunicaciones serie, funcionando a 115200 bps para interactuar con el circuito, utilizando el protocolo que el autor implementó. Pasando un caracter 'V' nos mostrará los comandos disponibles y también se pueden ver con más detalle aquí: https://8bit65.wordpress.com/2014/09/04/programando-la-eeprom/
3) Prueba del bus de direcciones (salida de ambos shift registers). El código original de Keller tiene un comando muy útil para el troubleshooting: A,ADDRESS. Pasándole la dirección en hexadecimal, el bus de direcciones tendrá que asumir el valor dado. Así se encuentra documentado en el código:
// Set the address bus to an arbitrary value.
// Useful for debugging shift-register wiring, byte-order.
// e.g. A,00FF
// Useful for debugging shift-register wiring, byte-order.
// e.g. A,00FF
Entonces el comando A,00FF habrá de poner los primeros 8 bits del bus de direcciones en 1.
Con un array de leds probé el bus de direcciones:
Con esto descubrí que había un problema con mi cableado del bus de direcciones que no había detectado en (1) Corregido el cableado ahora el bus de direcciones comenzó a funcionar al 100%, pero por algún otro motivo la grabación de datos continuaba fallando.
4) Prueba de lectura: Para las pruebas también me ayudó bastante haber encontrado guardada una RAM estática, memoria que se graba y accede de una forma muy similar a estas eeproms.
Como puede consultarse en su hoja de datos, para concluir cada ciclo de escritura -ya sea de un byte, o de una página de 64 bytes- se lleva a cabo un proceso de "data polling". Se lee la salida del bus de datos, y una vez que esta coincide con el byte que se quería almacenar, concluye el ciclo de escritura.
Seguí el consejo de mi amigo el Bocha y uní algunas líneas del bus de direcciones con el bus de datos. De esta manera, podría setear una dirección arbitraria y leer un byte del bus. Si los datos coincidían la lectura estaría funcionando correctamente.
Agregué una función corta al código para esas pruebas y los datos concidieron. Las cosas empezaban a mejorar, direcciones y lectura funcionaban ok. Como para escritura se utiliza el mismo bus de datos, tenía certeza de que esas líneas estaban ok. Fue necesario además, poner unas resistencias de unos 10K entre los pines del bus de datos que no se usaban y masa, para evitar que en la lectura dichos pines quedara en estado indefinido.
5) El siguiente paso era intentar escribir apenas un byte en una dirección de la memoria y leerlo para ver si el valor conicidía. Para ello una breve función de tests:
void run_tests(void) {
//void fast_write(unsigned int address, byte data)
Serial.println("\nWriting \'c\' char to addr 0000...");
fast_write(0000,'c');
delay(100);
Serial.println("\nReading from addr 0000. Should get ascii 99 ...");
byte data = read_byte(0000);
Serial.print(" ");
Serial.print(data);
}
//void fast_write(unsigned int address, byte data)
Serial.println("\nWriting \'c\' char to addr 0000...");
fast_write(0000,'c');
delay(100);
Serial.println("\nReading from addr 0000. Should get ascii 99 ...");
byte data = read_byte(0000);
Serial.print(" ");
Serial.print(data);
}
Esta prueba, con la SRAM tenía éxito, pero con la eeprom no. A esas alturas ya estaba bastante claro que el circuito se encontraba funcionando, pero algo fallaba en la interacción con la memoria eeprom.
La falla resultó ser bastante rara. Pero no solo me había ocurrido a mí. La eeprom tiene un código de bloqueo, que si uno desea establecerlo bloquea la eeprom. No se pueden borrar los datos, si no se envía antes el código de desbloqueo que el fabricante especifica.
Aparentemente, la EEPROM 28C256 que tenía (la única por el momento) había venido bloqueada.
Luego de envíar el código de desbloqueo el circuito empezó a funcionar correctamente.
No me queda más que agradecer a Mario Keller por compartir su diseño, a Marcel Van Kervinck https://github.com/kervinck (su versión del código me ayudó para el desbloqueo), otros del foro 6502.org y a mi amigo el Bocha. Ahora solo queda darle algún uso interesante al grabador, para divertirse un rato con retro computing.
Continuar »