Qual è la sequenza di comandi corretta per l'inizializzazione della scheda microSD in SPI?


18

Sto cercando di interfacciare una scheda microSD (2 GB, Kingston, Sandisk) con un controller Silicon Labs C8051F931 .

Sono molto confuso riguardo alla sequenza che devo seguire per l'inizializzazione. Nel libro Progetti di schede SD che utilizzano il microcontrollore PIC , pagina 135 menziona:

I passaggi per commutare la scheda SD in modalità SPI dovrebbero quindi essere i seguenti:
Accensione.
• Inviare almeno 74 impulsi di clock alla scheda con CS e Data Outlines impostati sulla logica “1.”
• Impostare la linea CD in basso.
• Invia il comando CMD0 a 6 byte “40 00 00 00 00 95” per mettere la scheda in modalità SPI.
• Controllare la risposta R1 per assicurarsi che non siano impostati bit di errore.
• Invia ripetutamente il comando CMD1 fino a quando il bit "in-id-state" nella risposta R1 è impostato su "0",
• e non sono impostati bit di errore. La scheda è ora pronta per le operazioni di lettura / scrittura.

Ho provato questo, ma sto ottenendo 01 anche per CDM1. 00 è previsto.

Anche qui vedo una diversa sequenza di comandi in cui invia CMD8 dopo CMD0. Ma il libro dice che devo inviare CMD1.

Qual è la sequenza corretta?

Risposte:


34

In realtà, la maggior parte delle informazioni / del codice che è possibile trovare sull'inizializzazione di SD è datata o non precisa, poiché precede SDHC e SDXC da anni. La procedura è più complicata al giorno d'oggi, in quanto ti costringe a gestire il vecchio hardware in modo compatibile con le versioni precedenti.

In primo luogo, come menzionato da altri, selezionare una frequenza di clock iniziale bassa (generalmente nell'intervallo 100 kHz - 400 kHz; se possibile, utilizzare 400 kHz); sarai in grado di passare a un orologio superiore in seguito, se il dispositivo lo consente. Mentre le nuove schede possono resistere in modo sicuro al clock ish MHz, le più vecchie si lamentano (ovvero non comunicano o restituiscono immondizia).

La prossima cosa è che non dovresti usare CMD1per inizializzare le schede SD / SDHC / SDXC a meno che la tua scheda non riconosca CMD55/ ACMD41; come detto nelle specifiche della scheda SD:

In ogni caso, CMD1 non è raccomandato perché potrebbe essere difficile per l'host distinguere tra MultiMediaCard e SD Memory Card.

Alcuni controller (per lo più schede nuove e di capacità superiore) rimarranno semplicemente in IDLE se vengono emessi CMD1. Dovresti prima rilasciare CMD8 0x1AAdopo il reset ( CMD0), quindi provare a utilizzare CMD55 + ACMD41. Se e solo se fallisce, usare CMD1.

tl; dr per inizializzare la scheda in modalità SPI dovresti:

  1. CMD0arg:, 0x0CRC: 0x95(response :) 0x01- nota che in caso di 0xFFrisposta confusa o confusa devi semplicemente ripetere questo passaggio; vedi sotto per maggiori informazioni.

  2. CMD8arg:, 0x000001AACRC: 0x87(risposta 0x01:, seguito da echo of arg, in questo caso 0x000001AA) - mentre può sembrare che questo comando sia facoltativo, è completamente obbligatorio per le schede più recenti. Mentre 0x1AAè un valore arg comune qui, puoi effettivamente passare anche altri valori; vedere "Tabella 7-5: Funzionamento della scheda per CMD8 in modalità SPI", p. 108 in spec per i dettagli.

    3a. CMD55arg:, 0x0CRC: any, 0x65effettivamente (risposta 0x01:; CMD55essendo il prefisso di ogni ACMD ; se la risposta è 0x05, hai una vecchia carta - ripeti CMD1con arg 0x0[CRC 0xF9] invece di CMD55/ ACMD41)

    3b. ACMD41, arg:, 0x40000000CRC: any, in 0x77realtà (si noti che questo argomento presuppone che la carta sia una HCS, che di solito è il caso; usare 0x0arg [CRC 0xE5] per le carte più vecchie). Se la risposta è 0x0, stai bene; se lo è 0x01, vai a 3a; se lo è 0x05, vedere la nota sopra (in 3a.); in caso contrario, c'è qualcosa che non va (vedi anche sotto).

CMD1CMD0CMD8CMD55ACMD41CMD55ACMD41CMD0CMD8CMD1CMD1CMD55ACMD41CMD10x05nn00xFFCMD0nCMD00xFF0x01CMD8

Nota che le risposte che hanno il MSB impostato ma di 0xFFsolito non suggeriscono che il tuo SPI abbia avuto un cambio di clock (a causa di un calo di Vcc, che accade di routine quando si eseguono hot plug SD). Per risolverlo, puoi provare a ripristinare completamente il dispositivo (accensione / spegnimento, deassert / assert S̲S̲ ecc.); di solito funziona.

Inoltre, dice la specifica

Dopo l'ultima transazione del bus della scheda di memoria SD, l'host è tenuto a fornire 8 (otto) cicli di clock affinché la scheda completi l'operazione prima di spegnere l'orologio.

Potrebbe funzionare senza di essa, ma poiché 8 cicli = 1 byte di output SPI, non farà molto male ed è bello averlo.

Nota che dovresti affermare che S̲S̲ (aka CS) è basso almeno prima e dopo ciascuno CMD- è completamente obbligatorio in caso di CMD0(il dispositivo non si accenderà senza di esso) e, in realtà, richiesto per tutti gli altri CMDse hai uno standard SD compatibile Può sembrare che il collegamento permanente dell'S̲S̲ della scheda a GNDper essere una buona idea se la scheda è l'unico client SPI a cui il tuo host si connetterà mai, in quanto risparmierebbe sia il pin di output uC sia la necessità di gestirlo per codice, e poiché la scheda dovrebbe presumere che sia selezionata tutta del tempo. In realtà, alcune carte (se non la maggior parte di esse) in realtà si aspettano che si attivi una pendenza da alta a bassa invece di rilevare semplicemente il basso, e quindi si arrabbiano se non si attiva / disattiva il bit S̲S̲, e poi si rallenta orologi o sputi immondizia; alcune carte (di solito più recenti) dovrebbero funzionare, alcune (più vecchie) potrebbero non funzionare, YMMV (ancora una volta). Tuttavia, per qualsiasi configurazione SPI più robusta (> 1 dispositivo slave) ricordarsi di affermare che il pin è basso prima di qualsiasi transazione effettiva con la scheda SD fornita.

Inoltre, mentre le specifiche dicono che solo CMD0e CMD8dovrebbero avere CRC in modalità SPI, alcune schede SD (come quelle Transcend) sembrano richiedere un CRC adeguato per CMD55/ ACMD41- se vuoi essere al sicuro, usa semplicemente un valore precalcolato per loro.

Inoltre, mentre SPI non richiede pull-up / down da solo, lanciare un pull-up 47k su MISO può essere una buona idea; alcuni dispositivi lasciano il loro pin DO alto-Z in circostanze specifiche (non inizializzate ad es.) e i pin flottanti possono sempre essere fonte di strani problemi. Se il tuo uC ha 3.3 Vcc, puoi usare pullup interni; se è 5V, non farlo a meno che la tua linea MISO non abbia già una corretta traduzione logica 5-> 3.3V.

Ulteriori letture:

Come usare MMC / SDC

Specifiche SD Parte 1 Specifica semplificata del livello fisico semplificato - soprattutto sezioni 6.4.1 Accensione e 7.2.1 Selezione e inizializzazione della modalità con Figura 7-1 : Diagramma di stato della scheda di memoria SD (modalità SPI)


4

Le specifiche per le schede SD sono disponibili su sdcard.org . La versione semplificata tralasciava alcuni dettagli, ma dovresti guardare ad esempio la figura 7-2 nella parte 1, in cui sono spiegate le sequenze di inizializzazione per le schede SDHC e SD.

Schede MicroSD <= 2 GB possono funzionare come schede più vecchie, quindi dovrebbero dare 0x00dei risultati per CMD1 fine . Questo potrebbe richiedere più di un paio di tentativi, poiché la scheda può utilizzare l'orologio esterno dal bus SPI per guidare l'elaborazione interna.


2

Aggiungendo a @vaxquis un'eccellente risposta, vorrei citare il grafico corrispondente dal " Specifiche fisiche semplificate Versione 4.10 , © Copyright 2001-2013 SD Group (Panasonic, SanDisk, Toshiba) e SD Card Association" (Figura 7-2 : Flusso di inizializzazione della modalità SPI):

Sequenza iniziale SPI scheda SD

Qui puoi vedere quali comandi inviare in quale ordine e cosa ci dicono le risposte sul tipo di carta. Penso che sia desiderabile che un dispositivo supporti il ​​maggior numero possibile di schede; e fintanto che si tratta delle operazioni di base di lettura e scrittura di blocchi di 512 byte, ciò dovrebbe essere fattibile per almeno tutte le schede SD e HC V1.xe V2.0.


2

Lo offro come un'altra possibilità. In modalità SPI, Samsung MicroSD EVO 32GB richiede che tutti i codici di comando abbiano codici CRC validi. Scommetto che non sono i soli. Ho letto un commento in cui la persona credeva che tutte le carte sopra i 32 GB potrebbero essere così. Ho eseguito il debug di un bug per oltre una settimana. Il mio codice non funzionerebbe fino a quando tutti i codici inviati alla carta non avessero codici crc validi. Ho usato questo per calcolare tutti i codici CRC https://github.com/hazelnusse/crc7/blob/master/crc7.cc Ho anche provato a usare un comando 59 per disattivare i codici CRC, no. Spero che questo risparmi a qualcun altro un sacco di tempo e fatica.

Il mio codice di inizializzazione con valori 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)

-2

Sei sicuro che il tuo bus SPI sia a 400 kHz? L'inizializzazione deve avvenire con il bus SPI in esecuzione a 400 kHz fino a quando la scheda SD segnala che è nello stato inattivo, su cui la frequenza di clock del bus SPI può essere aumentata (il massimo esatto sembra variare da produttore a produttore, ma sembra che 12 MHz è una scommessa sicura per la maggior parte delle carte).

Inoltre, secondo questo: http://elm-chan.org/docs/mmc/mmc_e.html CMD1 è l'inizializzazione corretta. CMD8 è richiesto solo per interrogare l'intervallo di tensione, che non dovrebbe costituire un problema con le schede non SDHC (<= 2 GB).


in realtà, molte schede SD (per lo più nuove, la mia Sony SR-32C4 da 32 GB) non si avviano affatto senza averle CMD8emesse in anticipo. Inoltre, l'orologio di solito non è un problema, purché rientri nella portata ragionevole.
vaxquis,

-3

Forse è troppo tardi, ma la risposta della carta è OK! Dopo CMD0, la risposta deve essere 0x01, ciò significa che la scheda È nello stato IDLE e pronta per il lavoro. Se hai qualcosa come 0b00000101, 1 al 2 ° posto indica che si tratta di un comando illegale e 1 al 0 ° posto indica che il sard È ancora in stato IDLE e pronto per il lavoro. Se la risposta è 0x00 significa che la scheda NON È in stato IDLE ed è necessario inviare un altro comando RESET.


hai letto la domanda? OP ha detto chiaramente I tried this, but I am getting 01 even for CDM1- ottenendo IDLE in risposta a CMD1in NOT OK. Non stai affrontando il suo vero problema con la tua "risposta".
vaxquis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.