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:
CMD0arg:, 0x0CRC: 0x95(response :) 0x01- nota che in caso di 0xFFrisposta confusa o confusa devi semplicemente ripetere questo passaggio; vedi sotto per maggiori informazioni.
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)
CMD8emesse in anticipo. Inoltre, l'orologio di solito non è un problema, purché rientri nella portata ragionevole.