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 CMD1
per 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 0x1AA
dopo 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:
CMD0
arg:, 0x0
CRC: 0x95
(response :) 0x01
- nota che in caso di 0xFF
risposta confusa o confusa devi semplicemente ripetere questo passaggio; vedi sotto per maggiori informazioni.
CMD8
arg:, 0x000001AA
CRC: 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. CMD55
arg:, 0x0
CRC: any, 0x65
effettivamente (risposta 0x01
:; CMD55
essendo il prefisso di ogni ACMD
; se la risposta è 0x05
, hai una vecchia carta - ripeti CMD1
con arg 0x0
[CRC 0xF9
] invece di CMD55
/ ACMD41
)
3b. ACMD41
, arg:, 0x40000000
CRC: any, in 0x77
realtà (si noti che questo argomento presuppone che la carta sia una HCS, che di solito è il caso; usare 0x0
arg [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).
CMD1
CMD0
CMD8
CMD55
ACMD41
CMD55
ACMD41
CMD0
CMD8
CMD1
CMD1
CMD55
ACMD41
CMD1
0x05
nn0
0xFF
CMD0
nCMD0
0xFF
0x01
CMD8
Nota che le risposte che hanno il MSB impostato ma di 0xFF
solito 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 CMD
se 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 CMD0
e CMD8
dovrebbero 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)
CMD8
emesse in anticipo. Inoltre, l'orologio di solito non è un problema, purché rientri nella portata ragionevole.