En fait, la plupart des informations / codes que vous pouvez trouver sur l'initialisation SD sont datés ou inexacts, car ils sont antérieurs à SDHC et SDXC par années. La procédure est plus compliquée de nos jours, car elle vous oblige à gérer l'ancien matériel d'une manière rétrocompatible.
Tout d'abord, comme mentionné par d'autres, sélectionnez une fréquence d'horloge initiale faible (généralement dans la plage de 100 kHz à 400 kHz; utilisez 400 kHz si possible); vous pourrez passer à une horloge supérieure plus tard, si l'appareil le permet. Alors que les nouvelles cartes peuvent résister en toute sécurité à une fréquence de MHz, les anciennes se plaindront (c'est-à-dire qu'elles ne communiqueront pas ou ne retourneront pas de déchets).
La prochaine chose est que vous ne devriez pas utiliser CMD1
pour initialiser les cartes SD / SDHC / SDXC à moins que votre carte ne reconnaisse pas CMD55
/ ACMD41
; comme indiqué dans les spécifications de la carte SD:
Dans tous les cas, CMD1 n'est pas recommandé car il peut être difficile pour l'hôte de faire la distinction entre MultiMediaCard et SD Memory Card.
Certains contrôleurs (les cartes plus récentes et de capacité supérieure principalement) resteront simplement en mode IDLE si vous les émettez CMD1
. Vous devez d'abord émettre CMD8 0x1AA
après la réinitialisation ( CMD0
), puis essayer d'utiliser CMD55 + ACMD41
. Si et seulement si cela échoue, utilisez CMD1
.
tl; dr pour initialiser la carte en mode SPI vous devez:
CMD0
arg:, 0x0
CRC: 0x95
(réponse 0x01
:) - notez qu'en cas de 0xFF
réponse brouillée, vous devez simplement répéter cette étape; voir ci-dessous pour plus d'informations.
CMD8
arg:, 0x000001AA
CRC: 0x87
(réponse 0x01
:, suivi de l'écho de arg, dans ce cas 0x000001AA
) - bien qu'il puisse sembler que cette commande soit facultative, elle est complètement obligatoire pour les cartes plus récentes. Bien qu'il 0x1AA
s'agisse d'une valeur d'argument courante ici, vous pouvez également transmettre d'autres valeurs; voir "Tableau 7-5: Fonctionnement de la carte pour CMD8 en mode SPI", p. 108 en spec pour plus de détails.
3a. CMD55
arg:, 0x0
CRC: any, en 0x65
fait (response 0x01
:; CMD55
étant le préfixe de every ACMD
; si la réponse est 0x05
, vous avez une vieille carte - répétez CMD1
avec arg 0x0
[CRC 0xF9
] au lieu de CMD55
/ ACMD41
)
3b. ACMD41
, arg:, 0x40000000
CRC: any, en 0x77
fait (notez que cet argument suppose que la carte est une carte HCS, ce qui est généralement le cas; utilisez 0x0
arg [CRC 0xE5
] pour les anciennes cartes). Si la réponse est 0x0
, vous êtes OK; si c'est le cas 0x01
, passez à 3a; si c'est le cas 0x05
, voir la note ci-dessus (en 3a.); si ce n'est ni l'un ni l'autre, quelque chose ne va pas (voir aussi ci-dessous).
La plupart des cartes nécessitent que les étapes 3a / 3b (ou CMD1
pour les anciennes cartes) soient répétées, généralement au moins une fois, même si vous attendez un certain temps entre elles ; c'est-à-dire que la séquence réelle est CMD0
/ CMD8
/ CMD55
/ ACMD41
/ CMD55
/ ACMD41
(ou CMD0
/ CMD8
/ CMD1
/ CMD1
) - pour être sûr, essayez le CMD55
/ ACMD41
(ou CMD1
si vous en avez obtenu 0x05
) fois (sélectionnez dans votre raison; il est en fait assez courant d'avoir à attendre un quelques centaines de ms si l'appareil est juste après la mise sous tension, alors visez), avec de petits retards entre les essais si vous le souhaitez, et supposez l'échec si la réponsenn0
n'apparaît pas (c'est-à-dire si l'appareil reste en mode IDLE pour une raison quelconque). En outre, la réception 0xFF
de CMD0
est courante si un appareil était dans un état "étrange" auparavant (par exemple, raccroché, S̲S̲ désactivé [élevé], avait une surtension / sous-tension sur certaines broches, etc.) - donnez-lui juste un peu de temps, rincez et répétez fois. Une réponse brouillée à est parfois tout à fait OK - si vous l'avez envoyée plusieurs fois et que la réponse n'est toujours ni ni , essayez d'aller de l'avant . Si cela fonctionne - vous êtes prêt à partir; sinon, il est probablement cassé .nCMD0
0xFF
0x01
CMD8
Notez que les réponses qui ont le MSB défini mais ne 0xFF
suggèrent généralement pas que votre SPI a changé d'horloge (à la suite, par exemple, de la chute de Vcc, ce qui se produit régulièrement lorsque vous effectuez des hotplugs SD). Pour le réparer, vous pouvez essayer de réinitialiser complètement l'appareil (allumer / éteindre, désactiver / affirmer S̲S̲ etc.); cela fonctionne généralement .
En outre, la spécification dit
Après la dernière transaction de bus de carte mémoire SD, l'hôte est requis, pour fournir 8 (huit) cycles d'horloge à la carte pour terminer l'opération avant d'arrêter l'horloge.
Cela pourrait fonctionner sans, mais comme 8 cycles = 1 octet de sortie SPI, cela ne fera pas beaucoup de mal et c'est juste bien de l'avoir.
Notez que vous devez affirmer S̲S̲ (aka CS) bas au moins avant et après chacun CMD
- c'est complètement obligatoire en cas de CMD0
(l'appareil ne s'allumera pas sans lui) et, en réalité, requis pour tous les autres CMD
si vous avez des normes -Carte SD compatible. La connexion permanente du S̲S̲ de la carte à GND peut semblerêtre une bonne idée si la carte est le seul client SPI auquel votre hôte se connectera jamais, car cela vous éviterait à la fois la broche de sortie uC et la nécessité de la gérer par code, et parce que la carte devrait supposer qu'elle est tout sélectionnée du temps. En réalité, certaines cartes (si ce n'est la plupart d'entre elles) s'attendent en fait à ce qu'une pente haute à basse s'allume au lieu de simplement détecter une faible, et donc se fâchent si vous ne basculez pas du tout le bit S̲S̲, puis retardez horloges ou broche à ordures; certaines cartes (généralement plus récentes) devraient fonctionner, d'autres (plus anciennes) peuvent ne pas fonctionner, YMMV (encore une fois). Néanmoins, pour toute configuration SPI plus robuste (> 1 appareil esclave), n'oubliez pas d'affirmer que la broche est basse avant toute transaction réelle avec la carte SD donnée.
De plus, bien que la spécification indique que seul CMD0
et CMD8
devrait avoir CRC en mode SPI, certaines cartes SD (comme celles de Transcend) semblent nécessiter un CRC approprié pour CMD55
/ ACMD41
- si vous voulez être du bon côté, utilisez simplement une valeur précalculée pour elles.
De plus, bien que SPI ne nécessite pas de pullups / downs par lui-même, lancer une pullup de 47k sur MISO peut être une bonne idée; certains appareils laissent leur broche DO haute-Z dans des circonstances spécifiques (non initialisées par exemple), et les broches flottantes peuvent toujours être une source de problèmes étranges. Si votre uC a 3,3 Vcc, vous pouvez utiliser des pullups internes; si c'est 5V, ne le faites pas à moins que votre ligne MISO ait déjà une traduction logique 5-> 3.3V appropriée.
Lectures complémentaires:
Comment utiliser MMC / SDC
Spécifications SD Partie 1 Couche physique simplifiée Spécifications simplifiées - surtout les sections 6.4.1 Mise sous tension et 7.2.1 Sélection et initialisation du mode avec la figure 7-1 : Diagramme d'état de la carte mémoire SD (mode SPI)
CMD8
émises au préalable. De plus, l'horloge n'est généralement pas un problème, tant qu'elle est dans une plage raisonnable.