He estado trabajando con tarjetas SD y tarjetas micro SD por un tiempo.
Estoy usando Part1_Physical_Layer_Simplified_Specification_Ver6.00 como referencia.
Puedo realizar correctamente la inicialización de la tarjeta, leer y escribir para otras micro SD como ATP 8GB SLC, Panasonic 8GB SLC, etc. Sin embargo, cuando estoy usando Delkin 16 GB SLC (y también Swissbit 8GB SLC), aunque tengo éxito en la inicialización de la tarjeta y escribo, cuando intento leer, no obtengo el token de bloque de inicio 0xFE y hay alrededor de 512 bytes de datos basura antes de que vuelva a ser normal.
El patrón es el siguiente (utilizando el analizador Beagle SPI):
Después de escribir lo siguiente (solo se muestran los primeros 24 bytes, pero el patrón es el mismo):
Si estoy escribiendo 0xA0. Por favor, consulte la siguiente imagen:
Si cambio los bytes escritos, también se cambian los bytes leídos y también hay una correspondencia uno a uno entre los bytes escritos y los bytes leídos. Pero los bytes no son los mismos.
Estoy verificando que los datos se escribieron correctamente usando el lector de tarjetas SD con el visor hexadecimal HxD.
Para el primer caso:
Para el segundo caso:
No parece que el voltaje de la tarjeta SD varíe, ya que lo verifiqué en el osciloscopio y permanece en 3,3 voltios durante la lectura.
Estoy usando el Launchpad F28377s de TI como microcontrolador.
Me gustaría obtener las entradas de usted. ¿Qué puedo hacer exactamente para solucionar este problema?
Edit1: se observa exactamente el mismo comportamiento para Swissbit 8GB SLC. Las mismas imágenes de arriba se pueden aplicar a Swissbit. Los datos leídos para Swissbit son los mismos que para Delkin. El reloj SPI antes de la inicialización es de 200 kHz y después de la inicialización se cambia a 1 MHz.
Edit2: mire las imágenes del osciloscopio a continuación (he cambiado la frecuencia del reloj a 225 KHz):
Edit3: La segunda imagen del osciloscopio sigue inmediatamente a la primera imagen del osciloscopio. La primera imagen es el comando de lectura y la respuesta, mientras que la segunda imagen envía 0xFF y espera el token del bloque de datos de inicio, que es 0xA8 en la segunda imagen, ya que 0xFE se desplaza 2 bits. Puede ver los datos hexadecimales decodificados del osciloscopio en la parte inferior de las imágenes del osciloscopio. Son los mismos que los datos de depuración de mi analizador Beagle SPI para el ejemplo 2 (donde estoy escribiendo 0xA0 y leyendo 0x28).
Edit4: según la sugerencia de Anonymous, actualicé mi código de modo que antes de cada comando y después de CS LOW, envío 8 relojes antes de cualquier transmisión SPI real prevista. Después de completar la respuesta del comando, envío 8 ciclos de reloj justo antes de CS HIGH y 8 ciclos de reloj justo después de CS HIGH. La finalización de la respuesta del comando en el caso de lectura SD significa que hemos recibido el último byte CRC. La finalización de la respuesta del comando en SD Write significa que la tarjeta deja de enviar la señal de ocupado después de escribir. Del mismo modo, también lo he aplicado a otros comandos. Además, no hago CS HIGH hasta que se completan el comando y su respuesta. Por ejemplo, en SD Read Case, hago CS LOW y envío el comando, obtengo la respuesta del comando, obtengo el token de bloque de inicio (0xFE), obtengo el CRC y luego hago CS HIGH.
Gracias.
Creo que deberías haber notado el patrón:
fe 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00 01 02 03 ...
cambiando esta secuencia dos bits a la derecha se obtiene
ff 80 00 40 80 c1 01 41 81 ...
Así que exactamente la secuencia que tienes. Ha agregado dos bits de repuesto en la transmisión y los bytes se desalinearon. ¿Por qué? Sin diagramas exactos que muestren el reloj, no es posible decirlo. Lo más probable es que tenga problemas con el reloj o la sincronización de datos.
Esta desalineación puede ocurrir en escritura o lectura, por lo que puede parecer que escribe una secuencia incorrecta porque su comando de escritura tiene bytes desalineados y luego vuelve a leer esa secuencia incorrecta (por supuesto), o podría ser un problema de comando de lectura pura. La conclusión de que debe verificar qué tarjeta SD ha escrito realmente en ella, utilizando otro dispositivo que funcione (por ejemplo, PC volcando su tarjeta en el archivo y verificando la imagen), antes de depurar la ejecución del comando de lectura o escritura.
Editar: mirando los diagramas de alcance, veo/recomiendo lo siguiente:
Edición 2:
La segunda imagen del osciloscopio sigue inmediatamente a la primera imagen del osciloscopio.
Tenga mucho cuidado al anular la selección de la tarjeta: sus imágenes muestran que emite un comando a la tarjeta, anula la selección elevando CS alto y luego vuelve a seleccionarla enviando continuamente 0xFF a la tarjeta. Parece que la tarjeta no entiende eso, y devuelve 0x28s, que en realidad son 0x05: la respuesta R1 de "comando no válido" cambió. Solo hay circunstancias específicas en las que puede anular la selección de la tarjeta, se explica en la especificación SD simplificada y sigue un protocolo muy específico:
Cuando la tarjeta indica que está ocupada, el anfitrión puede anular su selección (elevando el CS) en cualquier momento. La tarjeta liberará la línea DataOut un reloj después de que el CS pase a nivel alto. Para verificar si la tarjeta todavía está ocupada, debe volver a seleccionarse afirmando (establecer en baja) la señal CS. La tarjeta reanudará la señal de ocupado (tirando de DataOut bajo) un reloj después del flanco descendente de CS.
Con respecto a mi segundo comentario.
Además, su comentario 2, ¿es necesario para todos los comandos? Actualmente, solo he aplicado su sugerencia a Read Command.
Los ciclos de repuesto, aunque tomarán algún tiempo, asegurarán que la tarjeta haya completado/cancelado correctamente la operación anterior y esté lista para la siguiente. Así que te recomiendo que lo implementes para todos los comandos si es posible.
Ankit Srivastava
Anónimo
ff fe
obtenerff ff 80
Ankit Srivastava
Anónimo
Ankit Srivastava
Anónimo
Ankit Srivastava
Anónimo
Ankit Srivastava