Hola amigos!
Estoy embarcado en un proyecto que requiere de una memoria ROM. Despues de dar algunas vueltas y revolver mis cacharros, encontre una
SST 39SF020. En realidad, es una memoria FLASH que soporta hasta 10.000 ciclos de escritura y retiene los datos por 100 años. La capacidad es de 1MBit, y lo mejor de todo, es que no me costó nada por que vienen como "BIOS" en casi todos los motherboars de ordenadores PENTIUM.
La memoria opera con 5V, no necesita de 12V para grabarse ni nada de eso, lo que tambien es una ventaja.
No tengo problemas a la hora de leerla. Este es el diagrama de tiempos:
Y esta la rutina que uso para leerla:
// Lee una direccion de la FLASH
int8 leer_flash (int16 direccion) {
set_tris_b(0xFF); //Bus de datos como entrada
ON (RAMROM); //Seleccion la memoria FLASH
poner_dir_en_bus (direccion); //direccion a leer
OFF ( RD ) ; //Solicito los datos
delay_us (200); //Espero a la memoria
ON ( RD ); //devuelvo RD a 1
}
En mi hard/soft, por diversos motivos, tengo que:
- WR es el equivalente a WE# de la hoja de datos
- RD es el equivalente a OE# de la hoja de datos
- RAMROM es el equivalente a CE# de la hoja de datos.RAMROM está invertido por hardware (hay una compuerta entre el bus de control y el pin del chip de memoria). Eso es por que esa linea permite seleccionar con un valor el chip flash, y con otro la RAM. Quizas venga el lio por ese lado, pero no creo.....de todos modos, la RAM no está implementada todavia (ni siquiera esta puesta en la placa) y no puede estar "molestando" Lo concreto es que cuando en el diagrama de tiempos dice "poner CE# en alto", debo poner "RAMROM en bajo" para que sea lo mismo. Eso lo he comprobado con el tester, y cuando RAMROM está en 0, CE# está en 1 y viceversa.
Y leo cualquier posicion de memoria sin problemas.
Pero no puedo grabar. Hice una funcion que recibe la direccion de memoria y el valor a escrbir, e intenta reproducir este diagrama de tiempos para guardarlo en la FLASH. Es importante aclarar que antes de guardar cada byte hay que "sortear" un esquema de proteccion destinado a impedir perdida de datos.
Los pasos son lo de este esquema:
Y esta la función que estoy intendo hacer funcionar:
// Escribe una direccion de la FLASH
void escribir_flash (int16 direccion, int8 dato) {
//Condiciones iniciales:
set_tris_b(0x00); //Bus de datos como salida
ON ( WR ); //WR a 1
OFF (RD); //RD a 0
OFF (RAMROM); //Este bit está invertido x hardware
//Grabo 0xAA en 0x5555
poner_dir_en_bus (0x5555); //direccion a escribir
ON (RAMROM); //Este bit está invertido x hardware
ON (RD) ; //RD a 1
delay_us (10);
OFF ( WR ) ; //WR a 0
delay_us (50);
PORTB = 0xAA;
delay_us (50);
ON ( WR ); //WR a 1
//Grabo 0x55 en 0x2AAA
poner_dir_en_bus (0x2AAA); //direccion a escribir
PORTB = 0x55;
OFF ( WR ) ; //WR a 0
delay_us (50);
ON ( WR ); //WR a 1
//Grabo 0xA0 en 0x5555
poner_dir_en_bus (0x5555); //direccion a escribir
PORTB = 0xA0;
OFF ( WR ) ; //WR a 0
delay_us (50);
ON ( WR ); //WR a 1
//DATO A GRABAR
poner_dir_en_bus (direccion); //direccion a escribir
PORTB = dato;
OFF ( WR ) ; //WR a 0
delay_us (50);
ON ( WR ); //WR a 1
delay_us (300);
OFF ( WR ) ; //WR a 0
}
poner_dir_en_bus (direccion) es la que se encarga de poner la direccion a escribir en el bus, y funciona perfecto, ya que 16 LEDS que he puesto como "testigos" en el bus de direcciones indican correctamente los valores escritos por ella.
¿alguna idea de donde puedo estar fallando miserablemente?