En el marco del aún incompleto proyecto de tomar el control de un viejo 8051 me encontré con que tenía que escribir un programita en una EPROM para que la CPU lo leyera. EPROMs tengo de sobra, EEPROM [1] una sola y no tengo la datasheet.
Planes y conceptos
Lectura
Para leer la memoria tengo varias opciones:
FPGA
Tengo el problema de adaptación de voltajes, aunque a baja velocidad no debería traerme problemas, pero se me complica luego interactuar con la memoria de modo arbitrario. No tomaré este camino.
Microcontrolador ATMega328p
Usa 5v igual que la memoria pero no me alcanzan los pines, en el mejor de los casos tiene 23, necesito 8 para datos + 11 para direcciones + 3 o 4 de control y no estoy en el mejor de los casos, luego vemos el número exacto, mientras veamos como lidiar con ello.
Adaptador serie/paralelo
Primero había pensado no hacerlo, pero es algo que entiendo bastante bien desde hace décadas y nunca practiqué, así que lo haré.
Y ahí me preguntarías por qué no usás esta adaptación en los datos así es más simple el programa y yo te contestaría por que necesito leer tambien, adaptación paralelo/serie.
Reducción de direcciones
Puedo no acceder a todas las posiciones de memoria, las lineas altas de direcciones las puedo resolver son switches a mano, no es muy cómodo pero me sirve parcialmente ahora y completamente para resolver lo del 8051, donde sólo necesito ocho bytes, son 3 lineas de direccionamiento.
Acceso secuencial
Este me encanta. Usar un contador y con sólo dos pines, clock y reset, puedo ir direccionando toda la memoria. En mi cajón tengo un 4060 de 14, pero son solo accesibles 10 bits y no contiguos (4-10, 12-14). Un 4020 que son 12 accesibles no contiguos (1, 4-14) estaría mejor.
De un modo u otro, haría algo mixto, la parte alta con contador, la baja con GPIO. Con el 4060 me pude haber arreglado pues el rango 4 a 10 son las siete lineas que necesito, pero para cada incremento tengo que meter ocho ticks. Me he comprado un 4040 que es de 12 bits todos juntos para simplicarme la vida, pero este camino no será tomado.
El borrado
El problema con la EPROM es borrar sin lámpara UV. Para ello pienso usar el sol a ver que pasa. Tengo que leer la EPROM, ponerla al sol, volverla a leer y ver que pasó.La escritura
El acceso es igual que la lectura, pero hay que poner las lineas de control del modo adecuado y darle un pulso, ya veremos.
Problemas con el borrado y reescritura
Si encontrara que hay borrado pero no completo con encontrar 8 direcciones seguidas que tengan FF ya estoy, probablemente al final del espacio de memoria. Esto estaría bueno pues me desbloquea el proyecto del 8051.
FF y no 00 porque:
Initially, and after each erasure, all bits of the 27C16 are in the ‘‘1’’ state. Data is introduced by selectively program- ming ‘‘0s’’ into the desired bit locations. Although only ‘‘0s’’ will be programmed, both ‘‘1s’’ and ‘‘0s’’ can be presented in the data word. The only way to change a ‘‘0’’ to a ‘‘1’’ is by ultraviolet light erasure.
que se reduce a que si hay un cero no lo puedo tocar y si hay un uno puedo dejarlo como está o ponerlo en cero.
Igual no puedo confiar mucho en esa datasheet, pues tambien dice que se programa a 25v.
Si no puedo borrar, usaré el método de la sobreescritura.
Extensiones
Ok, supongamos que el borrado no funciona o lleva mucho tiempo y que la sobreescritura tampoco y no hay 8 FFs seguidos, con que hayan 8 FFs "seguidos" en cualquier orden en que se direccione la memoria, aumentan las chances.
Supongamos la siguiente situación, queremos encontrar 4 direcciones con FFs seguidas en un espacio de 32 direcciones. Lo ideal sería lo marcado en verde:
Esto tambien vale para el orden de los bits dentro de los bytes.
La fantasía es entonces hacer un algoritmo que dado un dump de memoria y el programa que quiero superponer, halle el direccionamiento y ordenamiento de bits tal que sea posible.
La realidad es que sólo voy a hacer la parte de direccionamiento y con poca creatividad.
Plan prudente
O cobarde. Primero voy a leerlo a mano, con unos switches en las direcciones y unos leds en los datos. Si una misma dirección me da el mismo dato siempre, puedo asumir que lo estoy haciendo ok
Luego voy a escribir a mano, usando switches para los datos y el ATMega para el pulso.
The 27C16 is in the programming mode when the V PP power supply is at 25V and OE is at VIH . It is required that a 0.1 mF capacitor be placed across Vpp , Vcc to ground to suppress spurious voltage transients which may damage the device.
The data to be programmed is applied 8 bits in parallel to the data output pins. The levels required for the address and data inputs are TTL.
When the address and data are stable, a 50 ms, active high, TTL program pulse is applied to the CE/PGM input.
A program pulse must be applied at each address location to be programmed.
You can program any location at any time, either individually, sequentially, or at random. The program pulse has a maximum width of 55 ms.
The 27C16 must not be programmed with a DC signal applied to the CE/PGM input.
Resumiendo:
- Para cada chip
- Limpiar la ventanita
- Rotular
- Leer la memoria completa y guardar asociando al rótulo
- Volver a leer y comparar para comprobar que no es basura
- Para cada chip
- Leer la memoria completa y guardar
- Repetir
- Ponerla al sol (horas, dias...)
- Leer la memoria completa y comparar
- Hasta que hayan cambios o FF total o me aburra
En paralelo, aprovechando que tenemos los dumps de memoria, hacer el análisis buscando 8 bytes en FF o aptos para sobreescritura.
Para lograr en entorno de trabajo tengo que hacer lo siguiente, en tu caso si siguieras mis pasos tendrías que adaptarte según el microcontrolador que uses.
- Recuperar capacidad de programar ATMega328p
- ~/Documents/research/avr/bare_programming
- controlar pinout
- tras programar voy a saber cuantos pines tengo disponibles
- Programa
- serial
- armar REPL base
- lectura EPROM
- comprender
- leer
- escritura EPROM
- comprender
- generar pulso escritura
- adaptación 5v - 25v
- escribir
- Ya podría soldar las partes
- Comandos completos del programa
- incrementar contador
- leer valor
- escribir valor
- lectura y transmisión de un rango por serial con formato hexa
transmisión y escritura de un rango por serial con formato hexade este me acobardé, estoy tan cansado que con grabar mis 8 bytes de a uno me contento.
Acciones y resultados
Lectura manual
Tras conectar todas las direcciones a GND salvo algunas con unos switches para elegir Vcc, todos los datos a leds, Vpp = Vcc, OE = CE = GND, sucede la magia barata.
+------------------+
GND -> A7 Vcc - 5v
switch -> A6 2 A8 <- GND
switch -> A5 K A9 <- GND
switch -> A4 B Vpp - Vcc
switch -> A3 OE <- GND
switch -> A2 E A10 <- GND
switch -> A1 P CE <- GND
switch -> A0 R D7 -> led
led <- D0 O D6 -> led
led <- D1 M D5 -> led
led <- D2 D4 -> led
GND - GND D3 -> led
+------------------+
Para leer varias direcciones, es muy tedioso usar los switches, se me van a romper. Me voy a adelantar un paso y voy a usar el atmega328p con un REPL[2] para desde la compu poder operar.
Lectura con microcontrolador
Más fácil dicho que hecho, comenzando con que la comunicación via serial desde uno de mis tantos inconclusos proyectos, estoy acostumbrado a hacerla con una edu-ciaa-nxp. Tambien estoy acostumbrado a que la raspberry pi, el router, la parallella, usan todos 3.3v a diferencia del mundo arduino que usa 5v.
Tuve un momento de horroroso pánico cuando no veía lo que quería en la comunicación y pensé que había quemado parte de la edu-ciaa-nxp hasta caí en cuenta del error.
Tras unas consultas privadas a Eric, es que me da mucha vergüenza no saber electrónica analógica, me explicó un poco y me referenció a un muy buen blog. Tomé el camino del divisor de tensión. Tras mucho probar me quedó esto:
Amarillo tiene escala 1v, el resto 2v. El primer decoder es lo que transmite la edu-ciaa-nxp, en azul. |
Sigue sin funcionar pero es siempre lo mismo, eso es bueno.
El amarillo es tal como sale del atmega328p. El magenta en el divisor, lo que le llega a la edu-ciaa-nxp. El azul es el caractar enviado desde ésta.
En la terminal tambien está roto, apuesto a que es por usar Serial de arduino que no le está pegando bien a alguna configuración.
Tras estudiar un poco como funciona el ATmega328p, me puse a escarbar un poco, le mandé este programa:
void setup() {
Serial.begin(9600);
DDRC = DDRC | B00111111;
DDRB = 0xff;
}
void loop() {
PORTB = UCSR0A; delay(1000);
PORTB = UCSR0B; delay(1000);
PORTB = UCSR0C; delay(1000);
PORTB = UBRR0H; delay(1000);
PORTB = UBRR0L; delay(1000);
blink();
}
Nota: cuando veas lo que sigue vas a pensar que la tengo recontrareclara pero la verdad es que lo entendí en el momento que lo necesité y mirándolo luego me cuesta mucho comprenderlo.
UCSR0A:
0010 0010
RXC0 TXC0 UDRE0 FE0 DOR0 UPE0 U2X0 MPCM0
0 0 1 0 0 0 1 0
| | | | | | | no multiproc
| | | | | | double baud rate
| | | | | no parity error
| | | | no data overrun
| | | no frame error
| | buffer emtpy
| no transmit complete
no received
UCSR0B:
1001 1000
RXCIE0 TXCIE0 UDRIE0 RXEN0 TXEN0 UCSZ02 RXB80 TXB80
1 0 0 1 1 0 0 0
| | | | | | | no ninth bit to transmit
| | | | | | no ninth bit received
| | | | | char size 8 bit ok
| | | | transmitter enabled
| | | receiver enabled
| | no empty data register interrupt
| no tx complete interrupt
no rx complete interrupt
UCSR0C:
0000 0110
UMSEL01 UMSEL00 UPM01 UPM00 USBS0 UCSZ01/UDORD0 UCSZ00/UCPHA0 UCPOL0
0 0 0 0 0 1 1 0
| | | | | | | clock polarity
| | | | | | char size 8 bit ok
| | | | | char size 8 bit ok
| | | | 1 stop bit
| | | no partiy
| | no partiy
| Async usart ok
Async usart ok
Hasta acá todo está ok, pero con los baudrates hay algo mal, fuí probando distintos divisores:
UBRR0H: 0000 0000
UBRR0L: 9600 1100 1111 (207)
19200 0110 0111 (103)
115200 0001 0000 (16)
Tomado de la datasheet |
Hay algo mal en alguna cuenta que hace Arduino IDE, pues cuando le agregué a setup() UBRR0L = B01100111 el decoder empezó a entender y la comunicación con la edu-ciaa-nxp se corrigió.
Pero pensemos un poco, qué sabemos:
Está en double speed) (UCSR0A[U2X0])
Arduino IDE no me ofrece aunque juraría que en algún lugar alguna vez ví que si, cambiar la velocidad del procesador.
Haciendo las cuentas de los baudrates tenemos que dados esos baudrates y esos UBRRn's,
fosc | baudrate | UBRR |
8000000 | 9600 | 103.1666666667 |
8000000 | 19200 | 51.0833333333 |
8000000 | 115200 | 7.6805555556 |
fosc | UBRR | baudarate |
8000000 | 207 | 4807.6923076923 |
8000000 | 103 | 9615.3846153846 |
8000000 | 16 | 58823.5294117647 |
UBRR | baudrate | fosc |
207 | 9600 | 15974400 |
103 | 19200 | 15974400 |
16 | 115200 | 15667200 |
corresponden a un
#define F_CPU 16000000UL
Evidentemente Arduino IDE piensa que tengo un Arduino Nano, es razonable, es lo que le dije.
Si le pido
#define F_CPU 8000000UL
me dice
warning: "F_CPU" redefined
Otro día veré como arreglarlo, ahora le piso UBRR0L = B01100111
El pulso de escritura lo saco de un delay(), tengo que usar 25 en lugar de 50.
Habiendo tomado el control del ATmega328p vía serial puedo implementar el REPL, para leer necesito que:
- El bus de datos de ATmega328p esté en modo input, mejor Z.
- En Address esté la dirección a consultar.
- El CE de EPROM pase a Vlow.
- El OE de EPROM pase a Vlow.
- Leer
y anda perfecto. Hubo una primera versión, una POC, que no vale la pena detallar. En la segunda versión, tengo 10 de 11 lineas de dirección controladas, la última con un switch manual.
+------------------+
PD5 -> A7 Vcc - 5v
PD4 -> A6 2 A8 <- PD6
PD3 -> A5 K A9 <- PD7
PD2 -> A4 B Vpp - Vcc
PC3 -> A3 OE <- PC5
PC2 -> A2 E A10 <- GND
PC1 -> A1 P CE <- PC4
PC0 -> A0 R D7 -> PB7
PB0 <- D0 O D6 -> PB6
PB1 <- D1 M D5 -> PB5
PB2 <- D2 D4 -> PB4
GND - GND D3 -> PB3
+------------------+
+---------------------+
RESET -> PC6 PC5 -> OE
RX -> PD0 A PC4 -> CE
TX <- PD1 T PC3 -> A3
A4 <- PD2 m PC2 -> A2
A5 <- PD3 e PC1 -> A1
A6 <- PD4 g PC0 -> A0
5v - Vcc a GND - GND
GND - GND 3 Aref -
D6 -> PB6 2 AVcc -
D7 -> PB7 8 PB5 <- D5
A7 <- PD5 p PB4 <- D4
A8 <- PD6 PB3 <- D3
A9 <- PD7 PB2 <- D2
D0 -> PB0 PB1 <- D1
+---------------------+
Esta es su interfaz:
#####################################################
MENU Version 2 half memory
#####################################################
a set address : (0400)
d set data : (19)
s set read size : (0001)
r read
w write
@ print current address values
+ increment current address
- decrement current address
i autoincrement mode : (ON)
Size? (xxxx): 0010
Reading address from: 0400 to : 0410
0400 F3 31 EA 40 ED 56 21 00
0407 40 11 00 40 D9 FD 21 EE
040F
El "autoincrement" es que tras leer se incremente la dirección de memoria. La "read size" es para leer. Anda re bien. Tengo consistencia de lecturas a lo largo de los días y tras conectar y reconectar.
Escritura con microcontrolador
Ahora necesito generar las condiciones de escritura
- Vpp a 25v
- CE a Vlow
- El OE pase a Vhigh.
- En Address esté la dirección a consultar.
- El bus de datos de ATmega328p esté en modo output.
- Dato en el bus de datos.
- Pulso en CE de 50ms.
- OE a Vlow
- Vpp a Vcc
+------------------+
PD5 -> A7 Vcc - 5v
PD4 -> A6 2 A8 <- PD6
PD3 -> A5 K A9 <- GND
PD2 -> A4 B Vpp - 25v
PC3 -> A3 OE <- PC5
PC2 -> A2 E A10 <- GND
PC1 -> A1 P CE <- PC4 pulso de 50ms
PC0 -> A0 R D7 <- PB7
PB0 -> D0 O D6 <- PB6
PB1 -> D1 M D5 <- PB5
PB2 -> D2 D4 <- PB4
GND - GND D3 <- PB3
+------------------+
PD5 -> A7 Vcc - 5v
PD4 -> A6 2 A8 <- PD6
PD3 -> A5 K A9 <- GND
PD2 -> A4 B Vpp - 25v
PC3 -> A3 OE <- PC5
PC2 -> A2 E A10 <- GND
PC1 -> A1 P CE <- PC4 pulso de 50ms
PC0 -> A0 R D7 <- PB7
PB0 -> D0 O D6 <- PB6
PB1 -> D1 M D5 <- PB5
PB2 -> D2 D4 <- PB4
GND - GND D3 <- PB3
+------------------+
RESET -> PC6 PC5 -> OE
RX -> PD0 A PC4 -> CE
TX <- PD1 T PC3 -> A3
A4 <- PD2 m PC2 -> A2
A5 <- PD3 e PC1 -> A1
A6 <- PD4 g PC0 -> A0
5v - Vcc a GND - GND
GND - GND 3 Aref -
D6 <- PB6 2 AVcc -
D7 <- PB7 8 PB5 -> D5
A7 <- PD5 p PB4 -> D4
A8 <- PD6 PB3 -> D3
R/W <- PD7 PB2 -> D2
D0 <- PB0 PB1 -> D1
+---------------------+
Escribí algunos 0x00, 0xF0 y 0x0F |
Logré primero tras mucho intento haciendo la transición de modo lectura a modo escritura a mano, tenía que reprogramar el chip ya fuera a leer o escribir y pasar Vpp a 5 y 25 v con un switch. Como POC está ok, pero necesito que lo haga el progama.
Primero había entendido que
Vpp = Vcc < - > 12.5 v
Vcc = 5v < - > 6.5v
OE = DC < - > desconectado
Vcc = 5v < - > 6.5v
OE = DC < - > desconectado
Luego, se redujo a
Vpp = Vcc < - > 25v
Lo del OE desconectado no sé de dónde lo saqué, pero fué el mismo lugar que los 6.5v.
El 12.5v fue por que todas las EPROMs que tengo afuera dicen 12.5v, salvo estas que estoy usando.
Preparado entonces para tres cambios, busqué un relé que tengo de cuatro switches y tras lograr que funcione me encontré con que usa 18v, no puedo meter otro voltaje más.
Del cajón del futuro |
Me puse a revisar la basura y rescaté varios relés pero de un punto. Luego revisé unas placas que había encontrado cartoneando, partes de una centralita telefónica siemens sobre la que algún día tendré que hacer algo. Y en una de ellas hallé relés de mercurio, me supera, tienen que estar verticales para funcionar.
Fijate que dice "up" |
Y en varias encontré microcontroladores 8051, el círculo se cierra, no olvides que todo esto comenzó al querer tomar el dominio de un 8051.
Creeme que dice 8051a |
Y otra cosa buena, al estar revolviendo buscando modems que estoy seguro tienen relés y tambien que los tiré, hallé un panel que dice Tango1 y tiene unos max485 que seguro me van a servir para otro proyecto, pero ya me estoy yendo muy por las ramas, por eso me cuesta tanto terminar cada proyecto. Los modems que encontré no tienen relés, salvo uno muy bonito, pero mirando mejor una placa de la centralita, la segunda desde la derecha en la foto del cajón del futuro, hallé 16 relés RA5WN-K, me alcanza para toda la vida, una pena por que no quería canibalizar esa placa antes de estudiarla, pero bueno....
Tras horribles sufrimientos que de algún modo quedaron plasmados en la abrumadora ayuda que recibí del foro de embebidos logré hacerlo andar de modo correcto.
Habiendo llegado el momento de hacer que el programa cambie el voltaje con el relé, me hallé con que necesito un pin para controlarlo, así que por el momento perdí la dirección A9 en PD7, no importa, luego cuando use el contador o el conversor serie paralelo será irrelevante.
Tengo entonces un prototipo supuestamente correcto, pero no está grabando a diferencia del manual o al menos no esta grabando lo que quiero. Además, al igual que en la prueba manual, se cuelga y se resetea y eso probablemente tenga relación con la escritura inconsistente.
La hoja de datos dice poner unos capacitores de un uF, no me preguntes por qué tenía, deben estar ahí en ese cajón desde hace 30 años.
No es muy estable, algunos chips no toman las escrituras, otros algunas si otras no, llegó el momento de direccionar todo el chip para poder sacarlo del protoboard, hay algunas inconsistencias que pueden ser debidas al cablerio infernal.
Desprolijo pero suele andar |
Acceso completo a todas las direcciones
Ahora necesito poder direccionar toda la memoria para hallar un segmento apropiado para la sobreescritura.
- Lo dudo,quizás en el futuro usaré chips más grandes.
- Por ello, las direcciones más bajas serán vía el serie a paralelo
- Dos patitas para el conversor.
- Tres patitas para el resto del direccionamiento.
- Cuatro patitas libres.
- Reset : entiendo que si lo uso como I/O vía fusibles pierdo la capacidad de reprogramar el ATmega328p
+---------------+
BIT -> A1 7 Vcc - 5v
5v -> A2 4 Qh -> A7
A0 <- Qa H Qg -> A6
A1 <- Qb C Qf -> A5
A2 <- Qc 1 Qe -> A4
A2 <- Qc 1 Qe -> A4
A3 <- Qd 6 RST <- 5v
GND - GND 4 CLK <- CLK
+---------------+
+------------------+
Qh -> A7 Vcc - 5v
Qg -> A6 2 A8 <- PC0
Qf -> A5 K A9 <- PC1
Qe -> A4 B Vpp - 25v
Qd -> A3 OE <- PC5
Qc -> A2 E A10 <- PC2
Qb -> A1 P CE <- PC4 pulso de 50ms
Qa -> A0 R D7 <- PB7
PB0 -> D0 O D6 <- PB6
PB1 -> D1 M D5 <- PB5
PB2 -> D2 D4 <- PB4
GND - GND D3 <- PB3
Qh -> A7 Vcc - 5v
Qg -> A6 2 A8 <- PC0
Qf -> A5 K A9 <- PC1
Qe -> A4 B Vpp - 25v
Qd -> A3 OE <- PC5
Qc -> A2 E A10 <- PC2
Qb -> A1 P CE <- PC4 pulso de 50ms
Qa -> A0 R D7 <- PB7
PB0 -> D0 O D6 <- PB6
PB1 -> D1 M D5 <- PB5
PB2 -> D2 D4 <- PB4
GND - GND D3 <- PB3
+------------------+
RESET -> PC6 PC5 -> OE
RX -> PD0 A PC4 -> CE
TX <- PD1 T PC3 -
- PD2 m PC2 -> A10
- PD3 e PC1 -> A9
- PD4 g PC0 -> A8
5v - Vcc a GND - GND
GND - GND 3 Aref -
D6 <- PB6 2 AVcc -
D7 <- PB7 8 PB5 -> D5
BIT <- PD5 p PB4 -> D4
CLK <- PD6 PB3 -> D3
R/W <- PD7 PB2 -> D2
D0 <- PB0 PB1 -> D1
+---------------------+
Me olvidé de sacarle foto al protoboard con el adaptador serial paralelo, mala suerte.
Armado definitivo
Las lecturas son inconsistentes, siempre tengo algún bit cambiando por acá o por allá. Para descartar que sean falsos contactos, armé la placa soldada.
Con esta placa todo parece andar bien. Para lo que necesito del 8051, este es el programa:
mov A,#254
loop:
mov 144, A
rlc A
sjmp loop
(74 FE F5 90 33 80 FB)
loop:
mov 144, A
rlc A
sjmp loop
(74 FE F5 90 33 80 FB)
Tras varias pruebas, la situación es que parece que no puedo escribir dos direcciones seguidas, aquí grabo el programa en direcciones sucesivas:
Address? (xxxx): 0020
Size? (xxxx): 0010
Reading address from: 0020 to : 0030
0020 1E 00 18 17 FF FF FF FF
0028 FF FF FF FF FF FF FF FF
Reading address from: 0020 to : 0030
0020 1E 00 18 17 FF FF FF FF
0028 FF FF FF FF FF FF FF FF
Address? (xxxx): 0028
Data? (xx):74
Writing 74 in 28
ok
Data? (xx):74
Writing 74 in 28
ok
Data? (xx):fe
Writing FE in 29
ok
Writing FE in 29
ok
Data? (xx):f5
Writing F5 in 2A
ok
Writing F5 in 2A
ok
Data? (xx):90
Writing 90 in 2B
ok
Writing 90 in 2B
ok
Data? (xx):33
Writing 33 in 2C
Writing 33 in 2C
ok
Data? (xx):80
Writing 80 in 2D
ok
Writing 80 in 2D
ok
Data? (xx):fb
Writing FB in 2E
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0038
0028 10 10 11 10 11 00 FB 11
0030 FF FF FF FF FF FF FF FF
Writing FB in 2E
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0038
0028 10 10 11 10 11 00 FB 11
0030 FF FF FF FF FF FF FF FF
Sólo quedó el último bien, así que fuí cambiando la secuencia:
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 FF FF FF FF FF FF FF FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 3E
0048
Data? (xx):74
Address? (xxxx): 0030Writing 74 in 30
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FF FF FF FF FF FF FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 3E
0048
Address? (xxxx): 0034
Data? (xx):33
Writing 33 in 34
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FF FF FF 33 FF FF FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048
Address? (xxxx): 0031
Data? (xx):fe
Writing FE in 31
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FE FF FF 33 FF FF FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048
Address? (xxxx): 0035
Data? (xx):80
Writing 80 in 35
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FE FF FF 33 80 FF FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048
Address? (xxxx): 0032
Data? (xx):f5
Writing F5 in 32
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FE F5 FF 33 80 FF FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048
Address? (xxxx): 0036
Data? (xx):fb
Writing FB in 36
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FE F5 FF 33 80 FB FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048
Address? (xxxx): 0033
Data? (xx):90
Writing 90 in 33
ok
Address? (xxxx): 0028
Size? (xxxx): 0020
Reading address from: 0028 to : 0048
0028 10 10 11 10 11 00 FB 11
0030 74 FE F5 90 33 80 FB FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
Apagué, desconecté, volví a conectar:
Address? (xxxx): 0010
Size? (xxxx): 0040
Reading address from: 0010 to : 0050
0010 40 31 EA 40 D3 01 DB 05
0018 24 22 52 05 3E 40 D3 01
0020 1E 00 18 17 FF FF FF FF
0028 10 10 11 10 11 00 FB 11
0030 74 FE F5 90 33 80 FB FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048 45 D3 12 3E 97 D3 13 3E
Size? (xxxx): 0040
Reading address from: 0010 to : 0050
0010 40 31 EA 40 D3 01 DB 05
0018 24 22 52 05 3E 40 D3 01
0020 1E 00 18 17 FF FF FF FF
0028 10 10 11 10 11 00 FB 11
0030 74 FE F5 90 33 80 FB FF
0038 C3 4E 01 D3 1E D3 1A 10
0040 63 D3 10 3E 49 D3 11 10
0048 45 D3 12 3E 97 D3 13 3E
Éxito parcial
Habiendo llegado a este punto, considero un éxito este proyecto, pues el objetivo era escribir unos poco bytes para el 8051.
Me queda la duda si pude haber puesto Vpp siempre a 25v y leer, la gráfica de la página 6 de la datasheet así lo insinúa.
No importa, aprendí y practiqué un montón de cosas.
El código en github.
Me queda el ver de grabar de un modo más cómodo y un montón de ajustes que difícilmente haga y el asunto del borrado.
Borrado solar
El problema que detecté es que sin el sol de por medio tengo lecturas distintas. Los motivos que se me ocurrieron fueron:
Tiempos: quizás me faltaba algún delay por ahí.
Interferencia por luz ambiente: la ventanita está abierta...
Malas conexiones: tengo todo en un protoboard con un cablerío infernal.
El método que utilicé fue
Leer varias veces y comparar (tiempos)
Leer, desconectar y volver a conectar, leer y comparar
La comparación es si algo cambio, con diff o md5sum y cuantos bits están prendidos, espero que el sol los lleve de "1" a "0" tal como dice la datasheet. Para contar los bits me hice un programita que está en el repo.
for file in chip1.0*; do
./bitCount < "$file"
md5sum "$file"
done
$ ./compare.sh
Bit count : 4315 42229ab8e512cd808e95c3680837826d chip1.00.dump
Bit count : 4356 b0d405a0d2e4029e69290bde79c64da8 chip1.01.dump
Bit count : 4368 27ea92c7d3b7f6dc32c36e3799d72ed5 chip1.02.00.dump
Bit count : 4368 27ea92c7d3b7f6dc32c36e3799d72ed5 chip1.02.01.dump
La convención es
chipID.sol.medición
o sea, si hay asoleado cambia el número "sol", si no, cambia el número "medición".
No he llegado a nada con esto, si algún día consigo que alguien me borre los chips, haré más pruebas.
Notas sueltas
No use las operaciones bitSet(), bitClear() y similares que provee arduino pues entre mis objetivos de aprendizaje se halla adquirir cierta soltura en el uso de operaciones con bits y eso se logra practicando.
En el camino he tenido varios cambios, por ejemplo reemplazar la edu-cia por un ttl-usb dongle, con la ciaa me sentía rehacker, con un sencillo programa haciendo la adaptación, estoy usando una computadora intermedia, pero la verdad es que el dongle me trajo un gran alivio, siempre estaba con el temor de romper la educiaa ya sea por cuestiones eléctricas o físicas y además ocupa mucho menos lugar.
[1] EPROM, EEPROM:
ROM: Memoria de sólo lectura, es un término genérico
Mask ROM: Es una ROM que viene ya con los datos de fábrica
PROM: Programmable ROM
OTP ROM: One Time Programmable ROM, la podés programar una vez y así queda
EPROM: Erasable ROM, la podés borrar con luz UV
EEPROM: Electrically EPROM, la podés borrar con electricidad
[2] REPL (Read Execute Print Loop): un patrón de programación que consiste en esperar un comando, al recibirlo ejecutarlo, imprimir sus resultados y volver a esperar...
No hay comentarios:
Publicar un comentario