Autor Tema: Comenzando con memorias SD/MMC. Librería a nivel hardware.  (Leído 158637 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #15 en: 11 de Enero de 2010, 19:50:05 »
Suky, muy bueno el post, lo único que tengo para comentar es que ese tipo de timeouts son muy dependientes de la velocidad a la que corre el micro y del compilador. No tenes ningún timer desocupado ?

Saludos !

Si es muy cierto, pero bueno, si alguien lo necesita que lo implemente  :mrgreen: Se coloca una base, después cada uno tiene que estudiar el tema y puede hacer mucho mas eficiente todo el código  ;-)

Joder maestro, te dejo solo unos días y la que lías!!!!! :D :D :D :D

Ahora en serio, a ver si puedo retomarlo ya que ahora estoy muy liado con otro proyecto más rentable económicamente hablando (ya que voy a ganar algo de dinero porque con la sd....)

Una vez más, gracias por tu ayuda!!!



Disculpas por no revisar el tema de porque no te funcionó en hard real la librería en C18, en la simulación me funcionó! Haber si me hago un tiempito  ;-)


Citar
while(SPI_READ(0XFF) != respuesta && espera> 0)
     {
       espera= espera - 1;
     }

Ya estoy dudando de lo poco que se de C :D :D :D, esta memoria ya no me deja ni dormir  :D :D :D, pero hay vamos.

Con estas otras líneas se arregla el problema, será que el compilador no acepta --espera.


 :? No entiendo naa! Si es lo mismo!  :rolleyes:


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Slalen

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1079
    • Página web personal de Guillermo Herrero González
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #16 en: 11 de Enero de 2010, 19:57:31 »
Discúlpame tú a mi por no haber seguido con ello!!!

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #17 en: 11 de Enero de 2010, 20:04:30 »
Hola Suky.

Citar
 No entiendo naa! Si es lo mismo!  

Es que modifique lo siguiente:

Citar
int mmc_respuesta(unsigned char respuesta)
   {
    unsigned long espera = 0xFFFF;
    while(SPI_READ(0xFF) != respuesta && --espera > 0);
    if(espera==0) return 1;
    else return 0;
  }
  }

Por lo siguiente:

Citar
int mmc_respuesta(unsigned char respuesta)
  {
    unsigned long espera = 0xFFFF;
    while(SPI_READ(0xFF) != respuesta && espera > 0)
      {
          espera = espera - 1;
      }
    if(espera==0) return 1;
    else return 0;
  }
Así me funciona haciendo lo mismo pero de diferente forma creo que el compilador que tengo no acepta bien  --espera > 0 debe poner problemas. Creo que ese era el problema porque la una funciona bien y la otra mal pero deberian hacer lo mismo, no se si estoy equivocado pero muchas gracias por la atención.

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #18 en: 12 de Enero de 2010, 15:55:39 »
Saludos

Todavia trabajando con la memoria sd tratando de ponerla al pelo, pero no he podido ponerla a funcionar bien, el leido el artículo del compañero Suky una y tras vez buscando el posible error (aunque he encontrado ya varios) , todavia sigo buscando en mis rutinas y nada no se que pueda pasar :shock:.

El programa debe hacer lo siguiente:

Al inicio la memoria debe inicializar en modo SPI para cual tengo un rutina que creo ya funciona.

y es la siguiente:

Código: [Seleccionar]
int init_mmc()
  {
    SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 | SPI_XMIT_L_TO_H);
    OUTPUT_HIGH(PIN_C2);
    for(i=0; i<20; i++)
      {
        SPI_WRITE(0xFF);             // espero a que se inicialice la memoria que van desde 8 a 10 pulso del reloj
      }
    OUTPUT_LOW(PIN_C2);             // Activo la targeta
    for(i=0; i<20; i++)
      {
        SPI_WRITE(0XFF);             // espero a que se inicialice la memoria que van desde 8 a 10 pulso del reloj
      }
    SPI_WRITE(0x40);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x95);                // Comando CMDO datos a enviar
    if(mmc_respuesta(0x01)==1)
      {
        return 1;                    // Error en memoria por que se supero el tiempo
      }
    OUTPUT_HIGH(PIN_C2);
    return 0;
  }

Dentro de esta rutina hay otra rutina que se llama mmc_respuesta(espera) que tiene como parámetro la variable espera y unsigned char (0 hasta 255 sin signo), lo que hace esta rutina es verificar la respuesta de la memoria ante un comando (llamese CMD0, CMD16 etc) es decir, espera el R1 y lo compara con la respuesta adecuada. Esta rutina es general para todas.
Y es la siguiente: Con alguna modificaciones que he hecho.

Código: [Seleccionar]
int mmc_respuesta(unsigned char respuesta)
  {
    unsigned long espera = 0xFFFF;
    while(SPI_READ(0xFF) != respuesta && espera> 0)
     {
       espera= espera - 1;
     }
    if(espera==0)
     {
      return 1;                  // se ha superado el tiempo
     }
    else
     {
      return 0;
     }
  }

La que sigue se llama inicializacion_mmc() y lo que hace esta rutina es inicializar la memoria para quedar lista para escritura y lectura de un bloque de 512 bytes, en esta rutina se envian los comandos CMD1, y CMD16 la configuración de CMD16 se hace de la siguiente forma se envia el comando (0x50, 0x00, 0x00, 0x02, 0x00, 0xFF) en el 4 byte se pone 0x02 para configura el bloque a 512 bytes que es equivalente en hex 0x200 y siempre en multiplos de este número. Lo siguiente es el código.

Código: [Seleccionar]
int inicializacion_mmc()
  {
    OUTPUT_HIGH(PIN_C2);
    for(i=0; i<16; i++)
      {
        SPI_WRITE(0xFF);
      }
    OUTPUT_LOW(PIN_C2);
      {
        SPI_WRITE(0xFF);
      } 
    i = 0; 
    do
      {     
        SPI_WRITE(0x41);         // Envia comando hasta que de la respuesta y hasta que se cumpla el tiempo
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);            // Secuencia del comando CMD1
        i= i + 1;
      }
    while(i<250 && mmc_respuesta(0x00)==1);
    if(i==250)
      {
        return 1;                // si se supera el tiempo de respuesta no se ha inicializado bien la targeta
      }
    OUTPUT_HIGH(PIN_C2);
    for(i=0; i<16; i++)          // Alguno cloks para estabilizar la comunicación
      {
        SPI_WRITE(0xFF);
      }
    OUTPUT_LOW(PIN_C2);
    for(i=0; i<16; i++)
      {
        SPI_WRITE(0XFF);
      } 
    SPI_WRITE(0x50);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x02);
    SPI_WRITE(0x00);
    SPI_WRITE(0xFF);              // Comando CMD16 para configurarlo de 512 bytes
    if(mmc_respuesta(0x00)==1)
      {
        return 1;                // se ha inicializado incorrectamente
      }
        OUTPUT_HIGH(PIN_C2);
        return 0;                // se ha inicializado correctamente
  }
 

La siguiente rutina escribe un bloque de 512 bytes segun las especificaciones de la targeta. En esta rutina escribo en el bloque número 2 el valor de 0x17 que es el envio en el bucle de 512 bytes y espero la respuesta de la memoria que debe ser 0x05, para lograr este valor leeo la respuesta de la memoria y hago una mascara con 0x0F para sólo tener en cuenta los primero 4 bits, pero ocurre algo que no se que pueda ser siemple la operación de la mascara  es decir
Código: [Seleccionar]
(resp&0x0f=!0x05)siempe está operación lógica me da 0x01 y no se porque lo he revisado una y otra vez no se pueda pasar :shock:.

El código es el siguiente de la rutina que escribe un bloque de 512 bytes en la memoria sd.

Código: [Seleccionar]
int mmc_escribir_bloque()
  {
    resp = 0;
    OUTPUT_HIGH(PIN_C2);
    for(i=0; i<16; i++)
      {
        SPI_WRITE(0xFF);               // Unos cuantos ciclos del reloj
      }
    OUTPUT_LOW(PIN_C2); 
    for(i=0; i<16; i++)
      {
        SPI_WRITE(0xFF);         // Espero a que se estabilice la memoria
      }
    SPI_WRITE(0x58);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x02);
    SPI_WRITE(0x00);
    SPI_WRITE(0xFF);          // Comando CMD24 pero escribé en el segundo bloque 0x200
    if((mmc_respuesta(0x00))==0x01)         // Espero la respuesta RB1
      {
        return 1;              // no respondio correctamente la memoria
      }
    SPI_WRITE(0xFE);          // Envio el token de inicio
    for(i=0; i<512; i++)
      {
        SPI_WRITE(0x17);         // Escribó 512 % que en hex es 0x25
      }
    SPI_WRITE(0xFF);
    SPI_WRITE(0xFF);             // espero ha que se estabilice o envio 2 CRC
    i=0;
    do
      {
        resp = SPI_READ(0xFF);
        i=i+1;
      }
    while(i!=200 && resp==0xFF);
    if(i==200)                                   // Se ha superado el tiempo
      {
        return 1;
      }
    if((resp&0x0F)!=0x05)
      {
        return 1;                            // No se escribio correctamente el bloque de 512 bytes dirente de 00101
      }
    OUTPUT_HIGH(PIN_C2);
    return 0;
  }


y por ultimo pongo la rutina principal que lo único que hace es decir si hubo error o todo bien a la hora de la respuesta de la memoria frente a un comando, es decir, por ejemplo responde si estuvo bien la escritura o si hubo un error, lo mismo es para la demás rutinas. Hago una aclaración cuando la rutina retorna "1" hubo un error y cuando retorna un "0".

Acá el código del main.

Código: [Seleccionar]
void main()
  {
    int lectura;
    set_tris_c(0x93);
    disable_interrupts(global);
    retorno = init_mmc();
    if(retorno==0x01)
      {
        printf("Error en memoria");
      }
    else
      {
        retorno = inicializacion_mmc();
        if(retorno==0x01)
          {
            printf("error");
          }
        else
          {
            retorno=mmc_escribir_bloque();
            if(retorno==0x01)
              {
                printf("No se pudo escribir el bloque\r");
              }
            else
              {
                printf("Escritura realizada");
              }
          }
      }
 while(;)
}

No se si ire por mal camino o tendré mal plateado el programa.

Bueno compañeros espero que me puedan ayudar ya que no he encontrado el posible error no se si estoy inicilizando mal la memoria, oh hay algún problema de programación o lógico o de configuración o de hardware etc.

Agradesco al compañero Suky ya que me ha asesorado y me ha aclarado muchas dudas con mucha paciencia, y gracias a él he podido avanzar con problemas pero lo he hecho.  ;-)

Acá dejo un artículo que encontre es de un dispositivo o mejor dicho un electrocardiograma muy interesante la parte matemática (por si alguién se le mide :mrgreen:) pero lo que me interesa es que en este proyecto también utilizaron una memoria mmc para almacenar los datos del sensor y lo que más me llamo la atención es que está programada en el esamblador. :shock:

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #19 en: 12 de Enero de 2010, 19:37:22 »
mmm... Podrías ver que respuesta estas recibiendo (que es distinta a 0x05) para ver si ayuda a encontrar el inconveniente. En el código no veo el problema, parece estar correcto  :? Igual hay que agregar, al final de realizar escritura y haber recibido el 0x05, el testeo de estado de la memoria para saber cuando se desocupo. Igual esto es dependiente de la aplicación.

En proteus podes colocar un SPI debugger para ver los datos enviados y las respuesta recibida.


Saludos!
« Última modificación: 13 de Enero de 2010, 01:16:59 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #20 en: 12 de Enero de 2010, 20:31:16 »
Hola Suky

Para darme cuenta como esta respondiendo la memoria he definido unos bytes de la siguiente forma que son los siguientes:

Código: [Seleccionar]
#byte resp = 0x20
#byte and = 0x21
#byte retorno = 0x22

el byte resp contiene la respuesta de la memoria frente a la escritura es decir deberia tener 0x05 pero siempre tiene 0x01 y no se porque :?

ahora el byte and es el resultado de la operación lógica resp&0x0f. Está operación deberia dar 0x05 pero da 0x01 y tampoco he podido encontrar la causa.

y finalmente el byte retorno contiene el valor del return es decir, cuando esta bien (0) y cuando está mal (1).

Con respecto a debug de proteus nunca lo he podido manejar  :oops: siempre me pone super lenta la simulación (no se si sera normal) pero las conexiones deben ser triviales. acá adjunto el esqumático que estoy utilizando.

Suky nuevamente muchas gracias por responder y sigo trabajando haber si la pongo a andar al fin.

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #21 en: 14 de Enero de 2010, 18:24:39 »
Hola.

Bueno continuo con la pruebas no medoy por vencido pero no se que pasa.

en esta imagen pongo el circuito que estoy utlizando para simularlo en el proteus



En la siguiente gràfica utilizo el debug SPI pero despuès de leer la ayuda lo pude maneja, en esta gràfica se puede observar como responde al comando CMD0 pero no responde al comando CMD1

no se porque la respuesta es simplemente un ? :?

acà la figura



En esta figura ya utilizo el cmando de escritura de 512 bloque se puede observar como el micro está mandando lo acertado pero la memoria no responde.

Acà la figura igual que el caso anterior la memoria responde con ?



y `por ultimo la respuesta frente a la cadena de 512 bytes enviados por el micro, yo espero que la respuesta sea 0x05 pero no la respuesta es ?, no se definitivamente que pasa, pero seguiere intentando voy a cambiar la imagen que se carga en la memoria a ver si es eso.



Igualmente agradesco la ayuda prestada y recivo cualquier tipo de sujerencia :mrgreen: mientras tanto a seguir probando

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #22 en: 14 de Enero de 2010, 22:01:58 »
Hola Chenao! mmm... Si la memoria no responde al comando CMD1 entonces la escritura y lectura de sectores no van a funcionar. Prueba colocando en una misma función el envío del CMD0 y CMD1, para no "apagar" la memoria entre los 2 comandos, osea habilitar memoria (CS=0), enviar comando CMD0 y CMD1, y después deshabilitar si se quiere.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #23 en: 15 de Enero de 2010, 12:50:20 »
Hola Suky.

Suky si tienes razón el comando CMD1 es primordial, pero creo que es problema del simulador voy a intentar colacar la imagen que utilisaste en el proteus a ver como funciona, no sin antes seguir tu consejo profesional  ;-).

Cada día que sigo cacharriando más con esta memoria me engomo mucho más pero con trabajo todo se logra, ya al menos he tenido resultados no los esperados pero dentro de poco la pongo a funcionar al pelo, nuevamente Suky muchas gracias por tu paciencia y por tus consejos y seguire publicando mis experiencias con estás memorias para que así los foreros tengan más ayuda  :P.

Saludos y seguiremos en contacto.
Un saludo desde Pereira - Colombia

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #24 en: 15 de Enero de 2010, 13:03:56 »
El cambio de imagen a la memoria no va a cambiar el modo de funcionar (Como esta programado en proteus) de ella, seguramente es necesario como inicialización enviar estos dos comandos sin desactivar la memoria en el proceso.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #25 en: 15 de Enero de 2010, 13:09:14 »
Hola.

Citar
El cambio de imagen a la memoria no va a cambiar el modo de funcionar (Como esta programado en proteus) de ella, seguramente es necesario como inicialización enviar estos dos comandos sin desactivar la memoria en el proceso.

Listo profe así va a hacer  :D :D :D. Pero creo que ese es el problema no habia pensado en eso antes  8).

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #26 en: 16 de Enero de 2010, 18:44:21 »
Saludos.

Continuan la pruebas pero esta vez con buenas noticias después de tanto experimentar (simular) por fin he podido inicializar, escribir y leer un bloque de 512 bytes  :-/ :-/ :-/, acá los resultados.

En esta imagén podemos como ver la memoria responde acertadamente al los comandos CMD0 y CMD1, además también responde acertadamente al comando CMD17, acá la figura



Bonito no :mrgreen:. En la siguiente gráfica vemos como el PIC manda la secuencia de escritura y como la memoria responde acertadamente, además se ve como el pic manda la secuencia 0xfe y dos 0xff y después manda el dato a almacenar en este caso es (0x17), acá la figura.



Y la ultima figura que muestra la respuesta que se escribió bien y además el comando de lectura y como empieza a recibir el micro los datos, acá la figura.



Bueno cual era el problema, si el profe Suky tenia toda la razón habia que en cuenta enviar el comando CMD0, CMD1 y el comando CMD17 a la misma vez.

Acá la rutina de inicilización

Código: [Seleccionar]
int init_mmc()
  {
    SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 | SPI_XMIT_L_TO_H);
    OUTPUT_HIGH(PIN_C2);
    for(i=0; i<20; i++)
      {
        SPI_WRITE(0xFF);             // espero a que se inicialice la memoria que van desde 8 a 10 pulso del reloj
      }
    OUTPUT_LOW(PIN_C2);             // Activo la targeta
    for(i=0; i<20; i++)
      {
        SPI_WRITE(0xFF);             // espero a que se inicialice la memoria que van desde 8 a 10 pulso del reloj
      }
    SPI_WRITE(0x40);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x95);                // Comando CMDO datos a enviar
    if(mmc_respuesta(0x01)==1)
      {
        return 1;                    // Error en memoria por que se supero el tiempo
      }
    do
      {
        SPI_WRITE(0x41);         // Envia comando hasta que de la respuesta y hasta que se cumpla el tiempo
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);            // Secuencia del comando CMD1
        i= i + 1;
      }
    while((i<250) && (mmc_respuesta(0x00)==0x01));
    if(i>=250)
      {
        return 1;                // si se supera el tiempo de respuesta no se ha inicializado bien la targeta
      }
    OUTPUT_LOW(PIN_C2);
    for(i=0; i<16; i++)
      {
        SPI_WRITE(0xFF);
      }
    SPI_WRITE(0x50);
    SPI_WRITE(0x00);
    SPI_WRITE(0x00);
    SPI_WRITE(0x02);
    SPI_WRITE(0x00);
    SPI_WRITE(0xFF);              // Comando CMD16 para configurarlo de 512 bytes
    if((mmc_respuesta(0x00))==0x01)
      {
        return 1;                // se ha inicializado incorrectamente
      }
        OUTPUT_HIGH(PIN_C2);
        return 0;                // se ha inicializado correctamente
  }

Bueno el trabajo no para aquí se sigue trabajando con la memoria pienso montarla, es decir diseñar una pcb haber como anda, además de programar otras funciones entre ellas la de borrar la memoria etc. Acá pongo la primera pregunta he visto en el foro que hay unos socalos o conectores mi pregunta le sirven el socalo para una mmc a una sd? por que pienso desarmar unos que tengo acá de un convertidor viejo malo que me encontré en la herramienta de mi hermano.

Ya para despedirme agradesco enormemente al compañero Suky por colaborarme con tanta paciencia y darme consejos, pero hay una buena noticia sigo con el proyecto a ver si programo más comando y además también si hago mis funciones para el manejo de la fat. No se si te incomoda que te siga haciendo consultas :mrgreen:. Nuevamente gracias Suky ;-).

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #27 en: 16 de Enero de 2010, 18:50:17 »
 :-/ :-/ :-/ Grande! Felicitaciones! Y no hay problema, si puedo contesto  ;-) Respecto a los socalos, los de SD Card sirven para las MMC, pero los socalos para las MMC no sirven para las SD Card.  :(


Saludos, y a seguir trabajando  :mrgreen:
No contesto mensajes privados, las consultas en el foro

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #28 en: 16 de Enero de 2010, 19:02:44 »

Gracias profe por la fecitación se hace lo que se puede :D :D :D.

Que cosa lo del socalo a buscar donde puedo conseguirme uno haber si me hecho con cautin a la mano y con mano en el teclado para superar tu proyecto :mrgreen:.

Saludos.
Un saludo desde Pereira - Colombia

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comenzando con memorias SD/MMC. Librería a nivel hardware.
« Respuesta #29 en: 16 de Enero de 2010, 19:06:19 »

Gracias profe por la fecitación se hace lo que se puede :D :D :D.

Que cosa lo del socalo a buscar donde puedo conseguirme uno haber si me hecho con cautin a la mano y con mano en el teclado para superar tu proyecto :mrgreen:.

Saludos.

 :D :D :D Guarda que mi proyecto no esta terminado!  :D :D

Respecto a los conectores, por ahí estas paginas te dan una idea:

http://www.instructables.com/id/Cheap-DIY-SD-card-breadboard-socket/

http://uanr.com/sdfloppy/

Y Tyco puede mandarte un sample.


Saludos!
No contesto mensajes privados, las consultas en el foro


 

anything