Quelle est la séquence de commandes correcte pour l'initialisation de la carte microSD dans SPI?

18

J'essaie d'interfacer une carte microSD (2 Go, Kingston, Sandisk) avec un contrôleur Silicon Labs C8051F931 .

Je suis très confus quant à la séquence que je dois suivre pour l'initialisation. Dans le livre Projets de cartes SD utilisant le microcontrôleur PIC , la page 135 mentionne:

Les étapes pour passer la carte SD en mode SPI doivent donc être les suivantes:
Mise sous tension.
• Envoyez au moins 74 impulsions d'horloge à la carte avec CS et Data Outlines réglés sur la logique «1»
.
• Envoyez la commande CMD0 à 6 octets "40 00 00 00 00 95" pour mettre la carte en mode SPI.
• Vérifiez la réponse R1 pour vous assurer qu'aucun bit d'erreur n'est défini.
• Envoyer la commande CMD1 à plusieurs reprises jusqu'à ce que le bit «in-idle-state» dans la réponse R1 soit réglé sur «0»,
et qu'aucun bit d'erreur ne soit défini. La carte est maintenant prête pour les opérations de lecture / écriture.

J'ai essayé ceci, mais j'obtiens 01 même pour CDM1. 00 est attendu.

Ici aussi , je vois une séquence de commandes différente où il envoie CMD8 après CMD0. Mais le livre dit que je dois envoyer CMD1.

Quelle est la séquence correcte?

gpuguy
la source

Réponses:

34

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 CMD1pour 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 0x1AAaprè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:

  1. CMD0arg:, 0x0CRC: 0x95(réponse 0x01:) - notez qu'en cas de 0xFFréponse brouillée, vous devez simplement répéter cette étape; voir ci-dessous pour plus d'informations.

  2. CMD8arg:, 0x000001AACRC: 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 0x1AAs'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. CMD55arg:, 0x0CRC: any, en 0x65fait (response 0x01:; CMD55étant le préfixe de every ACMD ; si la réponse est 0x05, vous avez une vieille carte - répétez CMD1avec arg 0x0[CRC 0xF9] au lieu de CMD55/ ACMD41)

    3b. ACMD41, arg:, 0x40000000CRC: any, en 0x77fait (notez que cet argument suppose que la carte est une carte HCS, ce qui est généralement le cas; utilisez 0x0arg [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 CMD1pour 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 CMD1si 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éponsenn0n'apparaît pas (c'est-à-dire si l'appareil reste en mode IDLE pour une raison quelconque). En outre, la réception 0xFFde CMD0est 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é .nCMD00xFF0x01CMD8

Notez que les réponses qui ont le MSB défini mais ne 0xFFsuggè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 CMDsi 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 CMD0et CMD8devrait 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)

vaxquis
la source
4

Les spécifications des cartes SD sont disponibles sur sdcard.org . La version simplifiée a omis certains détails, mais vous devriez regarder par exemple la figure 7-2 dans la partie 1, où les séquences d'initialisation sont expliquées pour les cartes SDHC et SD.

Les cartes MicroSD <= 2 Go peuvent fonctionner comme des cartes plus anciennes, donc elles devraient vous donner des 0x00résultats pour CMD1 finalement . Cela peut nécessiter plus de quelques tentatives, car la carte peut utiliser l'horloge externe du bus SPI pour piloter certains traitements internes.

Turbo J
la source
2

En ajoutant à @vaxquis une excellente réponse, je voudrais citer le tableau correspondant de la " Spécification simplifiée de la couche physique version 4.10 , © Copyright 2001-2013 SD Group (Panasonic, SanDisk, Toshiba) et SD Card Association" (Figure 7-2 : Flux d'initialisation du mode SPI):

Séquence d'initialisation SPI de la carte SD

Ici, vous pouvez voir quelles commandes envoyer dans quel ordre et ce que les réponses nous disent sur le type de carte. Je pense qu'il est souhaitable qu'un appareil prenne en charge autant de cartes que possible; et tant qu'il s'agit des opérations de base de lecture et d'écriture de blocs de 512 octets, cela devrait être possible pour au moins toutes les cartes SD et HC V1.x et V2.0.

JimmyB
la source
2

J'offre cela comme une autre possibilité .. En mode SPI, Samsung MicroSD EVO 32GB nécessite tous les codes de commande pour avoir des codes CRC valides. Je parie qu'ils ne sont pas les seuls. J'ai lu un commentaire où la personne pensait que toutes les cartes supérieures à 32 Go pourraient être ainsi. Je débogue un bug depuis plus d'une semaine. Mon code ne fonctionnerait pas tant que tous les codes envoyés à la carte n'auraient pas de codes crc valides. Je l'ai utilisé pour calculer tous les codes CRC https://github.com/hazelnusse/crc7/blob/master/crc7.cc J'ai même essayé d'utiliser une commande 59 pour désactiver les codes CRC, non. J'espère que cela économisera beaucoup de temps et d'efforts à quelqu'un d'autre.

Mon code d'initialisation avec des valeurs 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
la source
-2

Êtes-vous sûr que votre bus SPI est à 400 kHz? L'initialisation doit se produire avec le bus SPI fonctionnant à 400 kHz jusqu'à ce que la carte SD signale qu'elle est à l'état inactif, sur laquelle la fréquence d'horloge du bus SPI peut être augmentée (le maximum exact semble varier d'un fabricant à l'autre, mais il semble que 12 MHz est une valeur sûre pour la plupart des cartes).

En outre, selon ceci: http://elm-chan.org/docs/mmc/mmc_e.html CMD1 est l'initialisation appropriée. CMD8 est uniquement requis pour interroger la plage de tension, ce qui ne devrait pas être un problème avec les cartes non SDHC (<= 2 Go).

Zuofu
la source
en fait, de nombreuses cartes SD (principalement des plus récentes, mon Sony SR-32C4 32 Go en étant une) ne démarreront pas du tout sans avoir été 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.
vaxquis
-3

C'est peut-être trop tard, mais la réponse de la carte est OK! Après CMD0, la réponse doit être 0x01 - cela signifie que la carte EST en état IDLE et prête pour le travail. Si vous avez quelque chose comme 0b00000101, le 1 au 2 e endroit indique qu'il s'agit d'une commande illégale et le 1 au 0 indique que le sard est toujours à l'état IDLE et prêt à travailler. Si la réponse est 0x00, cela signifie que la carte N'EST PAS à l'état inactif et vous devez envoyer une autre commande RESET.

Peca
la source
avez-vous lu la question? OP a dit clairement I tried this, but I am getting 01 even for CDM1- se IDLE en réponse à CMD1au PAS OK. Vous n'abordez pas son vrai problème avec votre "réponse".
vaxquis