Autor Tema: SD - otro que no puede...  (Leído 2680 veces)

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

Desconectado irukza

  • PIC12
  • **
  • Mensajes: 87
SD - otro que no puede...
« en: 24 de Febrero de 2012, 13:03:46 »
Hola gentes

LLevo días renegando con este tema, y ya se me acabaron los recursos... :oops:

Estoy tratando de convencer a una SD Kingston de 1GB, pero no me hace caso.

Primero les cuento lo que ya leí, si me perdí de algo me avisan

Suky 1
Suky 2
Manual de Sandisk
SD spec 1
SD spec 2
Todopic 1
todopic 2
todopic 3
todopic 4
todopic 5
Interfaz FAT16 Para Wytec Dragon

Además de las excelentes publicaciones de Suky Aplicaciones Avanzadadas para C18 1 y 2, y su publicación en la revista uControl nº9.

El tema es que me gustaría poder escribir una librería propia, aunque inevitablemente "influenciada" por el trabajo de Suky. No obstante, he tratado de usar las librerías de Suky pero, aunque compila y aparentemente lee los registros CSD y CID, no genera el archivo en la memoria. Confieso que no le he dedicado demasiado tiempo a hacer andar estas librerías, sobre todo por evitar el plagio "involuntario" a la hora de escribir la mia.

Con lo que escrbí hasta ahora pareciera ser que la memoria responde, al menos recibo los token que espero. Como primer paso intento escribir cualquier porquería en la memoria para estar seguro de que estamos conectados, pero...

El primer misterio que me gustaría resolver es el siguiente, cuando mando un dato para llenar un sector, en la memoria me aparece el doble de ese valor indefectiblemente. Si mando un 0x20 aparece 0x40, si mando un 0x21 aparece un 0x42. Adjunto imagen del misterio



Todo eso significa que llegó hasta donde espero que llegue.
Luego abro la memoria con el WinHex para ver el sector que escribí, y lo veo (comienza en la direccion 0x800)



efectivamente, todo el sector está escrito, pero con el doble del valor que envié.
Este es el fragmento del código con el que envío los datos, como ven uso un vector cargado con el valor 0x20

//************************** Programa Principal ********************************
sd_ini();
// ****************** FIN INICIALIZACION *********************
for(i=0;i<512;i++)data[i]=0x20;
sd_Write(0x1fa00,&data);             // Sector 4 -> 0x800
//sd_CSD();
//sd_CID();
//sd_Read(0x00041000,&data);
while(1);
} // main()


el módulo SPI lo inicio asi:   OpenSPI(SPI_FOSC_64,MODE_00,SMPMID);   //    

y lo cambio a maxima velocidad cuando la SD entra en modo SPI:    OpenSPI(SPI_FOSC_4,MODE_00,SMPMID);

No subo el código completo para no complicar el mensaje, cualquier parte que quieran ver me avisan.
Sólo me falta revisar que el circuito esté respondiendo bien, y no se deformen los pulsos de reloj, pero hasta el fin de semana estoy sin osciloscopio.
Sospecho que estoy cometiendo un error muy básico, porque, justo el doble? ahí hay gato encerrado, pero no lo puedo encontrar  :oops:

Gracias de antemano
« Última modificación: 28 de Febrero de 2012, 20:40:33 por irukza »

Desconectado irukza

  • PIC12
  • **
  • Mensajes: 87
Re: SD - otro que no puede...
« Respuesta #1 en: 28 de Febrero de 2012, 10:45:38 »
a nadie se le ocurre nada o no me contestan porque soy feo... jaja

Acabo de revisar el circuito y todo está aparentemente bien. Probé con muchos valores diferentes y siempre pasa lo mismo: en la memoria aparece el doble del valor que envío...

Cualquier sugerencia será bienvenida.
gracias

Desconectado AcoranTf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1093
Re: SD - otro que no puede...
« Respuesta #2 en: 28 de Febrero de 2012, 15:58:13 »
Hola irukza, yo no te puedo ayudar mucho, ya que estoy empezando a aprender algo de C, pero tengo una duda al ver tu codigo. En el bucle creas y aumentas i hasta 512, (for(i=0;i<512;i++)data=0x20;) pero no veo donde utilizas i a la hora de escribir, (sd_Write(0x1fa00,&data); ).
¿Me lo podrias explicar?.

Saludos.

Desconectado irukza

  • PIC12
  • **
  • Mensajes: 87
Re: SD - otro que no puede...
« Respuesta #3 en: 28 de Febrero de 2012, 20:39:06 »
Claro que sí, puedo intentarlo.

Antes que nada, quiero aclararte que cuando copié el código cometí el error de pegarlo y no me di cuenta que iba a ser interpretado como código html. En la línea for(i=0;i<512;i++)data=0x20; no aparece lo que ves en rojo en esta línea for(i=0;i<512;i++)data[i]=0x20;
lo que está en rojo fue interpretado como código html (que indica que la letra aparezca en cursiva :lol:) y desapareció de la pantalla.
Esa sola línea es todo el bucle for, y por ser una sola línea no es obligatorio poner llaves. Lo que hace esa línea es llenar el vector data con el valor 0x20.
La línea sd_Write(0x1fa00,&data); está fuera del bucle for.
Lamento el error.

Por otra parte, y creo que de ahí viene tu pregunta, lo que se aplica en la línea sd_Write(0x1fa00,&data); es el concepto de punteros, que es una característica fundamental del lenguaje C. Es sin duda lo que provoca los mayores dolores cuando empiezas con este lenguaje, pero cuando lo manejas bien es una gran herramienta.
Cuando pones el operador "&" antes de una variable (en este caso un vector, &data), le estas diciendo al compilador que lo que querés no es el valor que contiene la variable sino la dirección de memoria en donde esta está almacenado el valor de esa variable. Esto es muy útil, ya que a priori, no sabemos en que posición de memoria el compilador ubicará a esa variable.
ejemplo:

supongamos que defino un par de variables

char mi_variable=15;
int tmp;


y supongamos que el compilador ubica la variable "mi_variable" en la posición 0x0f8.
Luego, si escribo este código:

tmp=mi_variable;       tmp contiene el valor 15

pero si escribo este código:

tmp=&mi_variable;    tmp contiene el valor 0x0f8

Si mi_variable fuese un vector, 0x0f8 sería la dirección de memoria del primer elemento del vector.
 
En el caso de la función sd_Write(0x1fa00,&data); yo estoy pasando como argumento de la función, dos valores, uno es una constante 0x1fa00, y el otro es la dirección de memoria del primer elemento del vector data[];

Esto es el primer paso.

Ahora, lo que no ves en este código es la definición de la función sd_Write y ahí está la otra parte del truco.
El prototipo de esta función es asi:

sd_Write(unsigned long long dir,unsigned long long *buffer );

Como ves, "dir" es una variable local "normal". En este caso recibe el valor 0x1fa00 que le paso como primer argumento cuando llamo a la función. El segundo argumento (buffer) tiene delante un *. Esto le dice al compilador que lo que quiero usar no es el vaor que recibo, sino que lo que recibo es la direción de memoria donde se encuentra almacenado el valor que quiero usar. Es decir, buffer apunta (puntero) a la dirección de memoria donde está el valor que necesito usar. A ver si lo puedo resumir

en la llamada        sd_Write(0x1fa00,&data);
el segundo argumento no es el valor de data, sino la dirección de memoria en donde está almacenado. Luego *buffer le dice al compilador: en "esta dirección" (buffer) está el valor que quiero usar, ve y tráelo.

Ahora, ¿por qué es tan útil este enriedo? porque si incremento (*buffer) estoy apuntando a la siguiente posición de memoria, estoy accediendo a la memoria donde se encuentra el segundo valor del vector data[]. Y si haces algo como esto.

for(j=0;j<512;j++){

WriteSPI( *(buffer + j) );

}

Estás mandando por SPI secuencialmente cada valor del vector data[], ya que (una vez más), *buffer indica la dirección donde ir a buscar el valor que me interesa.

Nunca me resulta fácil explicar esto, pero lo sigo intentando  :D

Pero si no entendiste nada, no te desanimes, no es difícil, sólo es cuestión de dar con la explicación adecuada. Hay excelentes tutoriales en este foro y en toda la web, con miles de ejemplos más claros que este. Espero haber ayudado.
« Última modificación: 29 de Febrero de 2012, 12:14:01 por irukza »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: SD - otro que no puede...
« Respuesta #4 en: 28 de Febrero de 2012, 21:06:17 »
El código podes colocarlo entre [ code ] [ /code] o ir a la solapa GeShi.


« Última modificación: 28 de Febrero de 2012, 21:09:04 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado irukza

  • PIC12
  • **
  • Mensajes: 87
Re: SD - otro que no puede...
« Respuesta #5 en: 28 de Febrero de 2012, 21:08:26 »
ok, gracias.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: SD - otro que no puede...
« Respuesta #6 en: 28 de Febrero de 2012, 21:09:10 »
Respecto al problema, el modo en que inicias SPI no es el correcto, debe ser 11.


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

Desconectado irukza

  • PIC12
  • **
  • Mensajes: 87
Re: SD - otro que no puede...
« Respuesta #7 en: 28 de Febrero de 2012, 21:14:25 »
si, ayer me di cuenta, mientras revisaba tu librería. Lo cambié, pero el resultado es el mismo. :(

Desconectado AcoranTf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1093
Re: SD - otro que no puede...
« Respuesta #8 en: 29 de Febrero de 2012, 16:36:35 »
Muchas gracias por tu extensa explicacion, la entendi casi al 100 %, me falta releerla un par de veces para asegurarme de que todo es como lo entendi.
Respecto a mi pregunta anterior, en realidad era sobre esos caracteres "desaparecidos", ya que no me cuadraba que definieses una variable en un bucle y luego no la utilizases. Por otro lado yo habia entendido mal la siguiente linea, la que has explicado y pense que formaba parte del bucle y era en esa linea que se escribia en la SD. Ya tengo claro como es. Por cierto me gusta la potencia y versatilidad de los bucles en C, comparado con los de BASIC, lenguaje en el que hice algunas cosillas hace años, en C es mucho mas simple y versatil.
Gracias de nuevo.

Saludos.
« Última modificación: 29 de Febrero de 2012, 16:39:40 por AcoranTf »

Desconectado irukza

  • PIC12
  • **
  • Mensajes: 87
Re: SD - otro que no puede...
« Respuesta #9 en: 01 de Marzo de 2012, 13:16:09 »
Me alegro que sirva.
Saludos


 

anything