2020/05/25

Programando EPROM con ATMega328p






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:





Pero tambien sirve lo amarillo si negamos el bit más significativo en rojo y tambien lo naranja si hacemos constantes los bits en rojo (3,2 y 0) y usamos 4 y 1 para direccionar.

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.





Mezclando lo anterior con varias cosas que ví en diversos sitios, entiendo que necesito que Vpp = Vcc cuando esté leyendo y al programar que Vpp = 12.5v, Vcc = 6.5 y que OE no esté conectado a nada y que además el micro controlador se entere y pueda validar.




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 hexa de 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.

Obtuve:

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
            +------------------+



          +---------------------+
   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

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
        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
            +------------------+


          +---------------------+
   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)

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 

Address? (xxxx): 0028
Data? (xx):74
Writing 74 in 28
ok

Data? (xx):fe
Writing FE in 29
ok

Data? (xx):f5
Writing F5 in 2A
ok

Data? (xx):90
Writing 90 in 2B
ok

Data? (xx):33
Writing 33 in 2C
ok

Data? (xx):80
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 



Sólo quedó el último bien, así que fuí cambiando la secuencia:


Address? (xxxx): 0028
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): 0030
Writing 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


É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


Para saber si el borrado solar funciona, tengo que leer, guardar, asolear, leer y comparar.

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


Miré por encima https://dragaosemchama.com/en/2016/10/arduino-mega-eprom-programmer/ que hallé mientras buscaba por EPROM, no hay nada por EPROM, todo es para EEPROM.

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