Autor Tema: controlador de memoria flash  (Leído 2699 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado micro_mon

  • PIC10
  • *
  • Mensajes: 29
controlador de memoria flash
« en: 06 de Diciembre de 2005, 07:51:00 »
Hola a todos en el foro....

Estoy tratando de hacer un controlador de la memoria flash m29w320db la que viene incluida en la tarjeta de evaluacion de Nuhorizons, la idea es poder leer y grabar datos en principio, luego implementar otras funciones de la misma. A pesar de seguir los pasos de la hoja de datos, no tengo exito en poder grabar dato alguno, cada vez que grabo algun dato y lo leo siempre me sale FF (y eso que antes de grabar siempre borro todo el bloque de memoria....Ardiendo) en el display.

Si alguien ya tuvo alguna experiencia con este tipo de memorias a ver si me puede dar algun consejo, incluyo abajo el codigo vhdl que  trato de implementar, las hojas tecnicas estan en http://www.st.com/stonline/books/pdf/docs/7876.pdf
quisiera adjuntarlos como archivos pero la pagina web no lo permite (Nota para el webmaster...)

El codigo hace lo siguiente:

- captura un dato del teclado y lo muestra en el LCD y lo guarda en una memoria temporal "prueba"

- al ejecutar "reset" borra el bloque 35 de la memoria cuyo referente es la direccion 200000h

- al presionar "grabar" se ejecuta la maquina de estados y lo que estaba en memoria temporal "prueba " debería grabarse en la posicion de memoria elejida dentro del bloque 35.

-al presionar granbar deberia desplegar el dato grabado. (pero sigue saliendo FF)




library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--use IEEE.STD_LOGIC_SIGNED.ALL;

--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;

entity fff is
port(
   --para la memoria flash
   memf_dir:out std_logic_vector(20 downto 0);
   memf_w:out std_logic:="1";
   memf_e:out std_logic:="1";
   memf_g:out std_logic:="0";
   memf_rp:out std_logic:="1";
   memf_wp:out std_logic:="1";
   memf_data:inout std_logic_vector(7 downto 0);
   memf_dq15A:out std_logic;
   memf_rb:in std_logic;
   ------------------------
   -- para el lcd
     rs: out std_logic;
   rw:out std_logic;
   en:out std_logic;
   lcd:out std_logic_vector (7 downto 0);
   --para los leds
   leds:out std_logic_vector (7 downto 0);
   ------------------------
   reset:in std_logic;
--   bot_graba: in std_logic;
--   bot_lee: in std_logic;
   teclado:in std_logic_vector (4 downto 0);
   clk: in std_logic
   );

end fff;

architecture behabioral of fff is
--señales para el clock
signal clkout: std_logic:="0";
signal count1: integer:=0;
--señales para el lcd y teclado
signal letra_e:std_logic:="0";
--signal letra_ee:std_logic:="0";
signal letra_m:std_logic:="0";
signal letra:std_logic_vector (7 downto 0):=X"00";
signal letra_mm: std_logic_vector (7 downto 0):=X"00";
signal token_lcd:std_logic:="0";
--señales varias

signal lee_sdram: std_logic:="0";   --se pulso del teclado leer sdram
signal graba_sdram:std_logic:="0";--se pulso del teclado grabar
signal dir_int:integer;
signal inc_dir_sdram:std_logic;
signal dec_dir_sdram:std_logic;
signal direccion:integer:=0;
signal proc_init:std_logic;
signal dir_e:std_logic;
--cambiar en lo futuro por variables internas
signal count3: integer range 0 to 12:=0;
signal count5: integer range 0 to 22:=0;
signal count4: integer range 0 to 32:=0;
signal countram :integer:=0;
signal count: integer range 0 to 19;
signal countbuf: integer range 0 to 18;
-- señales de conversion de datos
signal token_read:std_logic:="0";
signal token_write:std_logic:="0";
signal prueba:std_logic_vector(7 downto 0);
signal prueba1:std_logic_vector(7 downto 0);
signal direccion_std:std_logic_vector(20 downto 0);
signal muxflashlcd:std_logic;
begin
----------------------------------------------------------
memf_rp<="1";
memf_wp<="1";
----------------------------------------------------------
--inicializacion de la SDRAM
----------------------------------------------------------
iniSDRAM:process (clkout,reset)
begin
if reset = "0" then
   count4 <= 0;
elsif (clkout"event and clkout ="1") then
      --para borrar un bloque de la flash al resetear (solo por prueba)
   if count4 = 32 then
      count4<=32;
   else
      count4 <= count4+1;
   end if;
   case count4 is
         when 0 =>   memf_dir<= "000000000001010101010";
               memf_dq15A<="1"; --AAA
               prueba1<=X"AA";
               muxflashlcd<=  "1";
                 token_write <= "1";
         when 1 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 2 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 3 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 4 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 5 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 6 =>   memf_dir<= "000000000010101010101";
               memf_dq15A<="0"; --555
               prueba1<=X"55";
         when 7 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 8 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 9 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 10 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 11 =>   memf_dir<= "000000000001010101010";
               memf_dq15A<="1"; --AAA,80
               prueba1<=X"80";
         when 12 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 13 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 14 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 15 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         
         when 16 => memf_dir<= "000000000001010101010";
               memf_dq15A<="1"; --AAA
               prueba1<=X"AA";
               muxflashlcd<=  "1";
                 token_write <= "1";
         when 17 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 18 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 19 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 20 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 21=>   memf_dir<= "000000000010101010101";
               memf_dq15A<="0"; --555
               prueba1<=X"55";
         when 22 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 23 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 24 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 25 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 26=>   memf_dir<= "000000000000000000000";
               memf_dq15A<="1"; --BA  30
               prueba1<=X"30";
               muxflashlcd<=  "1";
         when 27 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 28 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 29 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 30 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 31=>   token_write <="0";
         when 32=> null;
   end case;
   --maquina de estados para leer la flash
   if lee_sdram="1" then
      if count3 = 12 then
         
            count3 <= 12;
      
      else
         count3<= count3 +1;     --aumenta estado
      case count3 is

      when 0=>      prueba1<=X"F0";
               muxflashlcd<= "1";
         
      when 1 =>      memf_e<="1";
               memf_g<="1";
               memf_w<="1";
      when 2 =>      memf_e<="0";
               memf_g<="1";
               memf_w<="1";
      when 3 =>    memf_e<="0";
               memf_g<="1";
               memf_w<="0";
      when 4 =>    memf_e<="0";
               memf_g<="1";
               memf_w<="1";
      when 5 =>      memf_e<="1";
               memf_g<="1";
               memf_w<="1";
      when 6 =>      null;
      when 7 =>      memf_dir<=direccion_std;
               memf_dq15A<="1";
      when 8 =>      memf_e<="0";
               memf_g<="0";
               memf_w<="1";
      when 9 =>      memf_e<="0";
               memf_g<="0";
               memf_w<="1";   
               
      when 10 =>      token_read<="1";
               
      when 11 =>      memf_e<="1";
               memf_g<="1";
               memf_w<="1";
               token_read<="0";
      when 12 => null;   
         
         end case;
      end if;   
      elsif lee_sdram = "0" then
         count3 <= 0;
      end if;
   --para grabar datos en la flash
   if graba_sdram = "1" then
      if count5 = 22 then
         count5 <= 22;
      else
         count5 <= count5 +1;
      end if;
      case count5 is
         when 0 =>   memf_dir<= "000000000001010101010";
               memf_dq15A<="1"; --AAA
               prueba1<=X"AA";  --AA
               muxflashlcd<=  "1";
                 token_write <= "1";
         when 1 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 2 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 3 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 4 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 5 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 6 =>   memf_dir<= "000000000010101010101";
               memf_dq15A<="0"; --555
               prueba1<=X"55";
         when 7 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 8 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 9 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 10 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 11=>   memf_dir<= "000000000001010101010";
               memf_dq15A<="1"; --AAA,A0
               prueba1<=X"A0";
         
         when 12 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 13 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 14 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 15 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
         when 16=>   memf_dir <= direccion_std;
               memf_dq15A<="1"; --direccion
               muxflashlcd<=  "0";
         
         when 17 =>   memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 18 => memf_e<="0";
               memf_g<="1";
               memf_w<="0";
         when 19 => memf_e<="0";
               memf_g<="1";
               memf_w<="1";
         when 20 =>   memf_e<="1";
               memf_g<="1";
               memf_w<="1";
      --   when 13=>   prueba1<=X"F0";
      --         muxflashlcd<= "1";
         
      --   when 14 =>memf_e<="0";
      --         memf_g<="1";
      --         memf_w<="0";
      --   when 15 =>memf_e<="1";
      --         memf_g<="1";
      --         memf_w<="1";
         when 21=>   token_write <="0";
         when 22 => null;
      end case;
   elsif graba_sdram ="0" then
      count5 <= 0;
   end if;
end if; --clk
end process;
----------------------------------------------------------
-- incrementar o decrementar las direcicones d ela flash
----------------------------------------------------------
indecsdram:process (inc_dir_sdram,dec_dir_sdram)
variable countpulsador:integer range 0 to 2:=0;
begin
if clkout"event and clkout = "1" then
   if countpulsador = 0 then
      if dir_e = "1" then
         countpulsador:= 1;
      else
         countpulsador:=0;
      end if;
   elsif countpulsador = 2 then
      countpulsador:= countpulsador;
   else
      countpulsador:= countpulsador +1;
   end if;
      case countpulsador is
         when 0 => countpulsador:= 0;
         when 1 =>   if inc_dir_sdram = "1" then
                  direccion <= direccion +1;
               elsif dec_dir_sdram = "1" then
                   direccion <= direccion -1;
               end if;
         when 2 => if dir_e = "1" then
                  countpulsador:=2;
               elsif dir_e = "0" then
                  countpulsador:=0;
               end if;
      end case;
   
   direccion_std <= CONV_STD_LOGIC_VECTOR(direccion,21);
   leds<=CONV_STD_LOGIC_VECTOR(direccion,8);
end if;
end process;
----------------------------------------------------------
--proceso de captura e insercion de datos en la flash de
--acuerdo al control de las señales.
----------------------------------------------------------
SDRAM_flanco_up:process (token_read, token_write,muxflashlcd,prueba1,prueba)
begin
   --if (clkout"event and clkout="1") then
      if token_read = "1" then
         letra_mm <= memf_data;
      else
         if token_write = "1" then
            if muxflashlcd = "1" then
               memf_data<=prueba1;
            else
               memf_data <= prueba;
            --   leds<= prueba;
            end if;
         else
            memf_data<= (others => "Z");
         end if;
      end if;

   --end if;
end process;
----------------------------------------------------------
-- controlador de ack rec de la memoria y el LCD
----------------------------------------------------------
lcd_memo:process (token_read,token_lcd)
begin
if token_read = "1" then
   if token_lcd = "0" then
      letra_m <= "1";
   else
      letra_m <="0";
   end if;
end if;
end process;
------------------------------------------------------------------
-- codificador   del teclado
------------------------------------------------------------------
codif_gab: process (teclado)

begin
case teclado is
     when "00001" => letra <= X"30"; --0
             letra_e <= "1";
             dir_e <= "0";
   when "00010" => letra <= X"31"; --1
             letra_e <= "1";
             dir_e <= "0";
   when "00011" => letra <= X"32"; --2
             letra_e <= "1";
             dir_e <= "0";
   when "00100" => letra <= X"33"; --3
             letra_e <= "1";
             dir_e <= "0";
   when "00101" => letra <= X"34"; --4
             letra_e <= "1";
             dir_e <= "0";
   when "00110" => letra <= X"35"; --5
             letra_e <= "1";
             dir_e <= "0";
   when "00111" => letra <= X"36"; --6
             letra_e <= "1";
             dir_e <= "0";
   when "01000" => letra <= X"37"; --7
             letra_e <= "1";
             dir_e <= "0";
   when "01001" => letra <= X"38"; --8
             letra_e <= "1";
             dir_e <= "0";
   when "01010" => letra <= X"39"; --9
             letra_e <= "1";
             dir_e <= "0";
   when "10001" => letra <= X"41";--A
             letra_e <= "1";
             dir_e <= "0";
   when "10010" => letra <= X"42";--B
               letra_e <= "1";
             dir_e <= "0";
   when "10011" => letra <= X"43";--C
              letra_e <= "1";
             dir_e <= "0";
   when "10100" => letra <= X"44";--D
             letra_e <= "1";
             dir_e <= "0";
   when "10101" => letra <= X"45";--E
             letra_e <= "1";
             dir_e <= "0";
   when "10110" => letra <= X"46";--F
             letra_e <= "1";
             dir_e <= "0";         
   when "10111" => lee_sdram <= "1"; --leer sdram
             letra_e <= "0";
             dir_e <= "0";
   when "11000" => graba_sdram <="1";--grabar sdram
             letra_e <= "0";
             dir_e <= "0";      
       when "11001" => inc_dir_sdram <= "1";--incrementa dir
             --direccion <= direccion +1;
             --leds<=CONV_STD_LOGIC_VECTOR(direccion,8);
             dir_e <= "1";
             letra_e <= "0";
   when "11010" => dec_dir_sdram <= "1";--dec direccion
             --direccion <= direccion -1;
             --leds<=CONV_STD_LOGIC_VECTOR(direccion,8);
             letra_e <= "0";
             dir_e <= "1";
     when others =>  letra_e <= "0";
             dir_e <= "0";
             lee_sdram <= "0";
             graba_sdram <= "0";
             inc_dir_sdram <= "0";
             dec_dir_sdram <= "0";
  end case;
end process;

-------------------------------------------------
--Rutina de retardo de clock para el LCD
-------------------------------------------------
clockin: process (clk)
begin
   if clk"event and clk ="1" then
      count1<= count1 + 1;
      if count1 = 18000 then
      clkout <= not clkout;
      count1 <= 0;
      end if;
   end if;

end process;

------------------------------------------------
--maquina de estado del LCD
------------------------------------------------
maquina: process (reset,clkout)
--variable count: integer range 0 to 19;
--variable countbuf: integer range 0 to 18;

   begin
   if (reset ="0") then
      count<=0;
    elsif(clkout"event and clkout ="1") then
   
      if count = 19 then
         count<= count;
      elsif count =18 then
         if letra_e = "1"  then
             count<=18;
         elsif letra_m = "1" then
         --elsif token_lcd = "1" then
             count<=18;
         else
             count<=16;
         end if;
      elsif count = 16 then
         if letra_e = "1" then
            lcd<=letra; -- dato del teclado
            --letra_sdram<= letra;
            prueba <= letra;
            count<= 17;
         elsif letra_m = "1" then
            lcd<=letra_mm;   -- dato de la memoria
            token_lcd<="1";--token de la memoria control
            count<=17;
         else
            count<=16;
         end if;
      else
         count<=count+1;
      end if;      

   case count is
   when 0 => en<="1";
           rw<="0";
         rs<="0";
         countbuf<=count;
         count<=19;
         lcd<=X"38";
   when 1 => en<="1";
         rw<="0";
         rs<="0";
         countbuf<=count;
         count<=19;
         lcd<=X"38";
   when 2 => en<="1";
         rw<="0";
         rs<="0";
         countbuf<=count;
         count<=19;
         lcd<=X"38";
   when 3 => en<="1";
          rw<="0";
         rs<="0";
         countbuf<=count;
         count<=19;
         lcd<=X"06";
   when 4 => en<="1";
          rw<="0";
          rs<="0";
          countbuf<=count;
         count<=19;
          lcd<=X"0C";
   when 5 => en<="1";
          rw<="0";
          rs<="0";
          countbuf<=count;
         count<=19;
          lcd<=X"01";
   when 6 => en<="1";
          rw<="0";
          rs<="0";
          countbuf<=count;
         count<=19;
          lcd<=X"80";
   when 7 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
         count<=19;
          lcd<=X"45"; --E
   when 8 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
         count<=19;
          lcd<=X"54"; --T
   when 9 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
         count<=19;
          lcd<=X"4E"; --N
   when 10 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
         count<=19;
          lcd<=X"FE"; -- " "
   when 11 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
          count<=19;
          lcd<=X"31"; --1
   when 12 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
          count<=19;
          lcd<=X"30"; --0
   when 13 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
          count<=19;
          lcd<=X"34"; --4
   when 14 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
          count<=19;
          lcd<=X"30"; --0
   when 15 => en<="1";
          rw<="0";
          rs<="0";
          countbuf<=count;
          count<=19;
          lcd<=X"0C"; --Nueva linea
   when 16 => token_lcd <= "0";
          null;
                         
   when 17 => en<="1";
          rw<="0";
          rs<="1";
          countbuf<=count;
          count<=19;
          token_lcd<="1"; --fin
   when 18 => --se queda en loop mientras no se deje letra_e
          null;
   when 19 => en<= "0"; --genera
          count<= countbuf+1;
   end case;
   end if;

end process;
end behabioral;




Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: controlador de memoria flash
« Respuesta #1 en: 06 de Diciembre de 2005, 12:57:00 »
Buenas.

He echado un vistazo al user manual de tu placa, que por cierto es una de las mejores placas que he visto. En la mía hay un jumper que te permite proteger la flash contra borrado/escritura. Mi placa tiene un flash serie, por lo que no tiene nada que ver con la tuya, pero me he dado cuenta que tiene un pin de Vpp/WriteProtect que no se si has tenido en cuenta.

Por otra parte, las memoria flash cuando se borran se inicializan al valor 0xFFFF, por lo que si estas leyendo FF es porque la operacion de borrado funciona bien.

Otra cosa a tener en cuenta, es el pin de Busy de la memoria, que estará activo mientras el controlador interno está escribiendo sobre ella. Mientras la memoria esta "busy" no podrás leer ningún dato de ella y te responderá con FF.

Normalmente, los fabricantes de las placas estas suelen desarrollar aplicaciones que testean las memorias, los leds y, en tu caso, el LCD de la placa. ¿Has probado a ejecutar alguna de estas aplicaciones para ver que por lo menos se escribe correctamente en la FLASH?


Tema aparte, te comento que todo lo que estas haciendo en vhdl esta muy bien para aprender a programar en VHDL, pero que llegará un momento en que tu aplicacion será enorme y te consumirá muchos recursos. No se si sabes la existencia del microprocesador "Microblaze" y del entorno de desarrollo EDK. Con este entorno puedes programar dentro de la FPGA un microprocesador, controlador de memoria externa, interfaz para tu LCD, etc, etc, que te facilitará enormemente hacer cualquier aplicación.

Bueno, no te cuento más rollos. Si tienes alguna duda postea. Prueba lo del Vpp y busca a ver si hay algún jumper que esté protegiendo la memoria contra escritura.

Desconectado micro_mon

  • PIC10
  • *
  • Mensajes: 29
RE: controlador de memoria flash
« Respuesta #2 en: 06 de Diciembre de 2005, 15:50:00 »
hola...

gracias por responder. pues si... verifique y no hay jumpers de proteccion, el pin vpp/writeprotect lo tengo a "1" donde estan desprotejidos todos los bloques de la memoria (segun la hoja de datos), aun no hice una rutina para verificar el estado del pin busy, lo hare estos dias.....te comentare los resultados...

En cuanto a EDK si, he escuchado hablar de ese software, pero en la pagina de xilinx no esta disponible para evaluacion, asi que lo estoy tratando de bajar de un p2p (tardará un poco!!Helado) . Los distribuidores de la placa me lo vendieron con el ise, las hojas de datos y una aplicacion basica en vhdl, hay unos cuantos archivos en edk, los voy a ver una vez que tenga el software. A proposito no sabes de alguna pagina web ftp donde se lo pueda descargar?

SAludos cordialesNavidad

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: controlador de memoria flash
« Respuesta #3 en: 06 de Diciembre de 2005, 18:35:00 »
Sitios ftp no se, pero donde este la mula ya se sabe.

En alguna web me baje un proyecto para el EDK donde se testeaban las memorias. De hay cogi las rutinas para escribir y leer de la FLASH. Las rutinas venían en C, ya que las ejecuta el microblaze, pero si sabes algo de C, pasarlas a VHDL es coser y cantar.


 

anything