¿Cuál es la secuencia de comandos correcta para la inicialización de la tarjeta microSD en SPI?

18

Estoy tratando de conectar una tarjeta microSD (2 GB, Kingston, Sandisk) con un controlador Silicon Labs C8051F931 .

Estoy muy confundido acerca de la secuencia que tengo que seguir para la inicialización. En el libro Proyectos de tarjetas SD que usan el microcontrolador PIC , la página 135 menciona:

Por lo tanto, los pasos para cambiar la tarjeta SD al modo SPI deben ser los siguientes:
Encendido.
• Envíe al menos 74 pulsos de reloj a la tarjeta con CS y contornos de datos configurados en lógica "1."
• Establezca una línea de CD baja.
• Envíe el comando CMD0 de 6 bytes "40 00 00 00 00 95" para poner la tarjeta en modo SPI.
• Verifique la respuesta R1 para asegurarse de que no haya bits de error establecidos.
• Enviar el comando CMD1 repetidamente hasta que el bit "en estado inactivo" en la respuesta R1 se establezca en "0",
• y no haya bits de error establecidos. La tarjeta ahora está lista para operaciones de lectura / escritura.

Intenté esto, pero obtengo 01 incluso para CDM1. Se espera 00.

También aquí veo una secuencia de comando diferente donde envía CMD8 después de CMD0. Pero el libro dice que tengo que enviar CMD1.

¿Cuál es la secuencia correcta?

gpuguy
fuente

Respuestas:

34

En realidad, la mayoría de la información / código que puede encontrar en la inicialización de SD está fechada o no es correcta, ya que es anterior a SDHC y SDXC por años. El procedimiento es más complicado hoy en día, ya que te obliga a lidiar con el hardware antiguo de una manera compatible con versiones anteriores.

En primer lugar, como lo mencionaron otros, seleccione una frecuencia de reloj inicial baja (generalmente en el rango de 100 kHz - 400 kHz; use 400 kHz si es posible); podrá cambiar a un reloj más alto más adelante, si el dispositivo lo permite. Mientras que las nuevas tarjetas pueden soportar de manera segura el reloj de MHz-ish, las antiguas se quejarán (es decir, no se comunicarán ni devolverán basura).

Lo siguiente es que no debe usar CMD1para inicializar tarjetas SD / SDHC / SDXC a menos que su tarjeta no reconozca CMD55/ ACMD41; como se dice en la especificación de la tarjeta SD:

En cualquiera de los casos, no se recomienda CMD1 porque puede ser difícil para el host distinguir entre MultiMediaCard y SD Memory Card.

Algunos controladores (tarjetas más nuevas y de mayor capacidad en su mayoría) simplemente permanecerán en IDLE si los emite CMD1. Primero debe emitir CMD8 0x1AAdespués del reset ( CMD0), y luego intentar usar CMD55 + ACMD41. Si y solo si eso falla, úselo CMD1.

tl; dr para inicializar la tarjeta en modo SPI debe:

  1. CMD0arg:, 0x0CRC: 0x95(respuesta:) 0x01- tenga en cuenta que en caso de 0xFFrespuesta confusa, simplemente repita este paso; ver abajo para más información.

  2. CMD8arg:, 0x000001AACRC: 0x87(respuesta:, 0x01seguida de eco de arg, en este caso 0x000001AA), aunque puede parecer que este comando es opcional, es completamente obligatorio para las tarjetas más nuevas. Si bien 0x1AAes un valor arg común aquí, en realidad también puede pasar otros valores; consulte "Tabla 7-5: Operación de la tarjeta para CMD8 en modo SPI", pág. 108 en especificaciones para más detalles.

    3a. CMD55arg:, 0x0CRC: any, en 0x65realidad (respuesta 0x01:; CMD55siendo el prefijo de todos ACMD ; si la respuesta es 0x05, tienes una tarjeta vieja - repite CMD1con arg 0x0[CRC 0xF9] en lugar de CMD55/ ACMD41)

    3b. ACMD41, arg:, 0x40000000CRC: any, en 0x77realidad (tenga en cuenta que este argumento supone que la tarjeta es una HCS, que suele ser el caso; utilice 0x0arg [CRC 0xE5] para tarjetas más antiguas). Si la respuesta es 0x0, estás bien; si es así 0x01, pase a 3a; si es así 0x05, vea la nota arriba (en 3a.); si no es ninguno, algo está mal (también ver más abajo).

La mayoría de las tarjetas requierenCMD1 que se repitan los pasos 3a / 3b (o para tarjetas viejas), generalmente al menos una vez, incluso si espera un tiempo entre ellas ; es decir, la secuencia real es CMD0/ CMD8/ CMD55/ ACMD41/ CMD55/ ACMD41(o CMD0/ CMD8/ CMD1/ CMD1) - para estar seguro, pruebe el CMD55/ ACMD41(o CMD1si lo obtuvo 0x05) veces (seleccione dentro de su razón; en realidad es bastante común tener que esperar un un par de cientos de ms si el dispositivo está justo después del encendido, así que apúntelo), con pequeños retrasos entre los intentos si lo desea, y suponga que falla si la respuestanortenorte0no aparece (es decir, si el dispositivo permanece en modo inactivo por alguna razón). Además, la recepción 0xFFde CMD0es común si un dispositivo estaba en un estado "extraño" anteriormente (por ejemplo, colgó, se desasistió S̲S̲ [alto], tenía sobretensión / subtensión en algunos pines, etc.) - solo déle algo de tiempo, enjuague y repita veces Una respuesta a ilegible está bastante bien a veces - si ha enviado un par de veces y la respuesta no es aún ni tampoco , tratar de seguir adelante con . Si funciona, estás listo para ir; si no es así, probablemente esté roto .norteCMD00xFF0x01CMD8

Tenga en cuenta que las respuestas que tienen el MSB establecido pero que no 0xFFsuelen sugerir que su SPI haya cambiado en la sincronización (como resultado de, por ejemplo, la caída de Vcc, que ocurre de manera rutinaria cuando está haciendo hotplugs SD). Para solucionarlo, puede intentar restablecer completamente el dispositivo (encendido / apagado, desassert / afirmar S̲S̲, etc.); Por lo general funciona.

Además, la especificación dice

Después de la última transacción del bus de la tarjeta de memoria SD, se requiere que el host proporcione 8 (ocho) ciclos de reloj para que la tarjeta complete la operación antes de apagar el reloj.

Podría funcionar sin él, pero como 8 ciclos = 1 byte de salida SPI, no hará mucho daño y es bueno tenerlo.

Tenga en cuenta que debe afirmar que S̲S̲ (también conocido como CS) es bajo al menos antes y después de cada uno CMD; es completamente obligatorio en caso de que CMD0(el dispositivo no se encienda sin él) y, en realidad, es obligatorio para todos los demás CMDsi tiene un estándar tarjeta SD compatible. Conectar el S̲S̲ de la tarjeta a GND de forma permanente puede parecerser una buena idea si la tarjeta es el único cliente SPI al que se conectará su host, ya que le ahorraría tanto el pin de salida uC como la necesidad de administrarlo por código, y porque la tarjeta debería asumir que está seleccionado todo del tiempo. En realidad, algunas cartas (si no la mayoría de ellas) realmente esperan que se active una pendiente de alta a baja en lugar de simplemente detectar baja, y por lo tanto se enojan si no alternan el bit S̲S̲ en absoluto, y luego se retrasan relojes o escupir basura; algunas tarjetas (generalmente más nuevas) deberían funcionar, algunas (más antiguas) pueden no funcionar, YMMV (una vez más). Aún así, para cualquier configuración SPI más robusta (> 1 dispositivo esclavo) recuerde afirmar el pin bajo antes de cualquier transacción real con la tarjeta SD dada.

Además, aunque la especificación dice que solo CMD0y CMD8debe tener CRC en modo SPI, algunas tarjetas SD (como las de Transcend) parecen requerir CRC adecuado para CMD55/ ACMD41- si desea estar seguro, simplemente use un valor precalculado para ellas.

Además, si bien SPI no requiere pullups / down por sí solo, lanzar una pullup de 47k en MISO puede ser una buena idea; algunos dispositivos dejan su pin DO alto-Z bajo circunstancias específicas (no inicializadas, por ejemplo), y los pines flotantes siempre pueden ser una fuente de problemas extraños. Si su uC tiene 3.3 Vcc, puede usar pullups internos; si es 5V, no lo haga a menos que su línea MISO ya tenga una traducción lógica adecuada de 5-> 3.3V.

Otras lecturas:

Cómo usar MMC / SDC

Especificaciones SD Parte 1 Capa física simplificada Especificación simplificada : lo más importante, secciones 6.4.1 Encendido y 7.2.1 Selección e inicialización del modo con la Figura 7-1 : Diagrama de estado de la tarjeta de memoria SD (modo SPI)

vaxquis
fuente
4

Las especificaciones para las tarjetas SD están disponibles en sdcard.org . La versión simplificada omitió algunos detalles, pero debería ver, por ejemplo, la figura 7-2 en la parte 1, donde se explican las secuencias de inicialización para las tarjetas SDHC y SD.

Las tarjetas MicroSD <= 2 GB pueden funcionar como las tarjetas más antiguas, por lo que eventualmente deberían darle 0x00resultados . Esto puede necesitar más de unos pocos reintentos, ya que la tarjeta puede usar el reloj externo del bus SPI para controlar el procesamiento interno.CMD1

Turbo J
fuente
2

Agregando a @vaxquis una excelente respuesta, me gustaría citar el cuadro correspondiente de la " Especificación simplificada de la capa física versión 4.10 , © Copyright 2001-2013 SD Group (Panasonic, SanDisk, Toshiba) y SD Card Association" (Figura 7-2 : Flujo de inicialización del modo SPI):

Secuencia de inicio de la tarjeta SD SPI

Aquí puede ver qué comandos enviar en qué orden y qué nos dicen las respuestas sobre el tipo de tarjeta. Creo que es deseable que un dispositivo admita tantas tarjetas como sea posible; y siempre que se trate de las operaciones básicas de lectura y escritura de bloques de 512 bytes, eso debería ser factible al menos para todas las tarjetas SD y HC V1.xy V2.0.

JimmyB
fuente
2

Ofrezco esto como otra posibilidad. En el modo SPI, Samsung MicroSD EVO 32GB requiere que todos los códigos de comando tengan códigos CRC válidos. Apuesto a que no son los únicos. Leí un comentario donde la persona creía que todas las tarjetas de más de 32 GB podrían ser así. He estado depurando un error por más de una semana. Mi código no funcionaría hasta que todos los códigos enviados a la tarjeta tuvieran códigos CRC válidos. Usé esto para calcular todos los códigos CRC https://github.com/hazelnusse/crc7/blob/master/crc7.cc Incluso intenté usar un comando 59 para desactivar los códigos CRC, no. Espero que esto le ahorre a alguien mucho tiempo y esfuerzo.

Mi código de inicialización con valores CRC.

Power On..
Clock card at least 74 (I use 80) cycles with cs high
CMD0 0, crc=0x95
CMD8 0x01aa, crc=0x87
CMD58 0, crc=0xfd
CMD55 0, crc=0x65
CMD41 0x40000000, crc=0x77
CMD9 0, crc=0xaf
CMD16, 512, crc=0x81 (If you want block length of 512)

Some random other commands..
CMD17 0, crc=0x3b (Read one block)
CMD18 0, crc=0x57 (Read multiple blocks)
CMD24 0, crc=0x6f (set write address for single block)
CMD25 0, crc=0x03 (set write address for first block)
Dave
fuente
-2

¿Estás seguro de que tu bus SPI está a 400 kHz? La inicialización debe ocurrir con el bus SPI funcionando a 400 kHz hasta que la tarjeta SD informe que está en el estado inactivo, en el cual la velocidad del reloj del bus SPI puede incrementarse (el máximo exacto parece variar de un fabricante a otro, pero parece que 12 MHz es una apuesta segura para la mayoría de las tarjetas).

Además, de acuerdo con esto: http://elm-chan.org/docs/mmc/mmc_e.html CMD1 es la inicialización adecuada. CMD8 solo es necesario para consultar el rango de voltaje, lo que no debería ser un problema con las tarjetas que no son SDHC (<= 2GB).

Zuofu
fuente
en realidad, muchas tarjetas SD (en su mayoría más nuevas, mi Sony SR-32C4 32GB es una) no se iniciarán sin una CMD8emisión previa. Además, el reloj generalmente no es un problema, siempre que esté dentro del rango razonable.
vaxquis
-3

Quizás sea demasiado tarde, ¡pero la respuesta de la tarjeta está bien! Después de CMD0, la respuesta debe ser 0x01, esto significa que la tarjeta ESTÁ en estado inactivo y lista para trabajar. Si tiene algo como 0b00000101, el 1 en el 2do lugar dice que este es un comando ilegal y el 1 en el lugar 0 dice que Sard todavía está en estado inactivo y listo para trabajar. Si la respuesta es 0x00, significa que la tarjeta NO ESTÁ en estado IDLE y debe enviar otro comando RESET.

Peca
fuente
¿Has leído la pregunta? OP dijo claramente I tried this, but I am getting 01 even for CDM1- conseguir IDLE en respuesta a CMD1en NO OK. No estás abordando su verdadero problema con tu "respuesta".
vaxquis