Problemas de comunicación de la tarjeta SPI/SD

Estoy trabajando con un PIC18F67K22 y veo algunas cosas extrañas en el flujo de datos SPI. Estoy tratando de interactuar con una partición FAT32 usando FatFs y un archivo diskio.c personalizado. Puedo reconocer la partición FAT32, pero cuando intento crear un archivo, la operación disk_read de repente da errores extraños.

Adjunto una captura de pantalla de la lógica entre el PIC18 y la tarjeta SD para mostrar los datos inusuales.

ingrese la descripción de la imagen aquí

En la captura de pantalla, puede ver que estoy enviando CMD17 (READ_SINGLE_BLOCK) junto con una dirección de 4 bytes de 0x00007D10 y una suma de verificación CRC7 para ese comando.

La respuesta de comando que recibo es 0xC1, seguida de 0x3F, ninguna de las cuales tiene sentido. De acuerdo con la sección Cómo usar MMC/SDC en el sitio web de FatFs, el bit más significativo de la respuesta del comando siempre debe ser 0, pero 0xC1 tiene el bit más significativo establecido en 1. Además, ¿por qué viene después el 0x3F? Eso debería ser 0xFF.

E incluso si asumiera que hubo un pequeño cambio aquí y que el valor real debería ser 0xC13F >> 6 (0x04), sería un comando ilegal. ¿Qué tiene de ilegal CMD17 con esa dirección? ¿La dirección de datos de 0x00007D10 no es válida? La partición debe abarcar todo el medio, excepto el MBR y el registro de arranque.

Editar:

Estos son los sectores devueltos durante la inicialización, con algunas anotaciones en los datos:

Edición 2:

Descubrí que esto solo sucede si llamo a f_mount mucho antes de f_open. Estoy haciendo un f_mount al insertar la tarjeta SD para verificar que la tarjeta sea una partición FAT16/FAT32 adecuada, y luego solo llamo a f_open cuando el usuario comienza a registrar datos. Si llamo a f_mount y f_open en rápida sucesión (o llamo a f_mount con montaje retrasado), entonces la llamada funciona bien y el comando devuelve 0x00 y luego 512 bytes de datos.

Probablemente debería publicar toda la secuencia de inicio hasta ese punto. Díganos su tarifa clk. Mire el tamaño del bloque y vea si cruza un límite de bloque con esa dirección.
Mi frecuencia de reloj es de 2,66 MHz todo el tiempo. Agregué los volcados del MBR y el registro de arranque de la partición 1. Mientras lo anotaba, noté algunas cosas bastante extrañas. El registro de arranque de la partición 1 dice que hay 0 sectores por FAT, lo que parece extraño. Y la etiqueta de volumen es ASCII no imprimible. ¿Estoy leyendo en el área equivocada? Creo que mi endianidad podría haberse vuelto rara en algunos lugares. Windows reconoce la tarjeta SD muy bien, así que creo que la tarjeta está formateada correctamente.
¿Hay una transición chip select high - chip select low antes de la captura de pantalla? ¿Quizás la tarjeta todavía está emitiendo datos de disco en el momento de la captura?

Respuestas (1)

Ha pasado un año desde que se hizo la pregunta, pero decidí agregarla porque estaba teniendo problemas similares al incorporar el controlador de la tarjeta SD en FPGA. Estoy de acuerdo con los comentaristas de su pregunta en que debe brindar información sobre lo que estaba sucediendo antes del ciclo SPI fallido y lo que sucede después.

En general, si bien hay una especificación SD para las tarjetas SD, es un poco desconcertante y no me hizo pasar ni una hora entendiendo qué es lo que está mal con mi diseño.

Entonces, comencemos...

  • Inicialización: hay un requisito previo para tener ciclos de reloj de repuesto con CS desactivado para que la tarjeta se inicialice y comprenda que hay un host disponible. También obtendrá una idea de qué tipo de SPI se utiliza.
  • Inicio del ciclo de comando: necesitará ciclos de reloj de repuesto antes de afirmar CS bajo para iniciar el comando, e idealmente varios ciclos de reloj después de afirmar CS bajo y comenzar a poner el comando en la línea MOSI. Varios aquí significa n*8. Esos ciclos de repuesto son necesarios para garantizar que la tarjeta se recupere del ciclo de E/S anterior si hubo un problema (por ejemplo, su aplicación no transfirió datos/estado completos, y la tarjeta aún espera que el host lea/envíe estos datos o estado). El cronometraje moderado con CS alto convencerá a la tarjeta de que se debe cancelar la operación anterior.

Cuando hice estos dos anteriores correctamente, ya no obtuve códigos de respuesta no válidos de la tarjeta SD. Hay algunas otras peculiaridades que manejan las tarjetas SD a través de SPI, pero deben tratarse cuando sea necesario, porque el ciclo de comando en sí, la respuesta y la fase de datos se explican relativamente bien en la especificación, y probablemente no tendrá problemas para implementarlo.