Jaka jest prawidłowa sekwencja poleceń dla inicjalizacji karty microSD w SPI?

18

Próbuję połączyć kartę microSD (2 GB, Kingston, Sandisk) z kontrolerem Silicon Labs C8051F931 .

Jestem bardzo zdezorientowany sekwencją, którą muszę przestrzegać podczas inicjalizacji. W książce Projekty kart SD za pomocą mikrokontrolera PIC , strona 135 wspomina:

Kroki, aby przełączyć kartę SD w tryb SPI, powinny zatem być następujące:
Uruchomienie.
• Wyślij co najmniej 74 impulsy zegarowe na kartę z CS i Zarysami danych ustawionymi na logiczne „1”.
• Ustaw niską linię CD.
• Wyślij 6-bajtową komendę CMD0 „40 00 00 00 00 95”, aby wprowadzić kartę w tryb SPI.
• Sprawdź odpowiedź R1, aby upewnić się, że nie ustawiono bitów błędów.
• Wysyłaj wielokrotnie polecenie CMD1, dopóki bit „w stanie bezczynności” w odpowiedzi R1 nie zostanie ustawiony na „0”
• i nie ma ustawionych bitów błędów. Karta jest teraz gotowa do operacji odczytu / zapisu.

Próbowałem tego, ale dostaję 01 nawet dla CDM1. 00 jest oczekiwane.

Również tutaj widzę inną sekwencję poleceń, gdzie wysyła CMD8 po CMD0. Ale książka mówi, że muszę wysłać CMD1.

Jaka jest poprawna sekwencja?

gpuguy
źródło

Odpowiedzi:

34

W rzeczywistości większość informacji / kodu, które można znaleźć podczas inicjalizacji SD, jest albo datowana, albo niedokładna, ponieważ wyprzedza SDHC i SDXC o lata. Procedura jest obecnie bardziej skomplikowana, ponieważ zmusza cię do radzenia sobie ze starym sprzętem w sposób zgodny z poprzednimi wersjami.

Po pierwsze, jak wspomniali inni, wybierz niską początkową częstotliwość taktowania (zwykle w zakresie 100 kHz - 400 kHz; użyj 400 kHz, jeśli to możliwe); będziesz mógł później przejść na wyższy zegar, jeśli pozwala na to urządzenie. Podczas gdy nowe karty mogą bezpiecznie wytrzymywać taktowanie MHz, starsze będą narzekać (tj. Nie komunikować się ani nie zwracać śmieci).

Następną rzeczą jest to, że nie powinieneś używać CMD1do inicjalizacji kart SD / SDHC / SDXC, chyba że twoja karta nie rozpoznaje CMD55/ ACMD41; jak powiedziano w specyfikacji karty SD:

W żadnym z przypadków CMD1 nie jest zalecane, ponieważ host może mieć trudności z rozróżnieniem karty MultiMediaCard i karty pamięci SD.

Niektóre kontrolery (głównie nowsze i karty o większej pojemności) po prostu pozostaną bezczynne, jeśli CMD1je wydasz . Najpierw powinieneś wydać polecenie CMD8 0x1AApo resecie ( CMD0), a następnie spróbować użyć CMD55 + ACMD41. Jeśli i tylko jeśli to się nie powiedzie, użyj CMD1.

tl; dr, aby zainicjować kartę w trybie SPI, powinieneś:

  1. CMD0arg:, 0x0CRC: 0x95(odpowiedź:) 0x01- zwróć uwagę, że w przypadku 0xFFzniekształconej odpowiedzi powinieneś po prostu powtórzyć ten krok; więcej informacji znajdziesz poniżej.

  2. CMD8arg:, 0x000001AACRC: 0x87(odpowiedź 0x01:, po którym następuje echo arg, w tym przypadku 0x000001AA) - chociaż może się wydawać, że to polecenie jest opcjonalne, jest całkowicie obowiązkowe dla nowszych kart. Chociaż 0x1AAjest to wspólna wartość argumentu, możesz faktycznie przekazać także inne wartości; patrz „Tabela 7-5: Działanie karty dla CMD8 w trybie SPI”, s. 1. 108 w specyfikacji dla szczegółów.

    3a. CMD55arg:, 0x0CRC: any, 0x65faktycznie (odpowiedź 0x01:; CMD55będący przedrostkiem każdego ACMD ; jeśli odpowiedź brzmi 0x05, masz starą kartę - powtórz CMD1z arg 0x0[CRC 0xF9] zamiast CMD55/ ACMD41)

    3b. ACMD41, arg:, 0x40000000CRC: any, 0x77faktycznie (zauważ, że ten argument zakłada, że ​​karta jest HCS, co zwykle ma miejsce; użyj 0x0arg [CRC 0xE5] dla starszych kart). Jeśli odpowiedź brzmi 0x0, wszystko jest w porządku; jeśli to jest 0x01, goto 3a; jeśli tak 0x05, patrz uwaga na ten temat powyżej (w 3a.); jeśli tak nie jest, coś jest nie tak (patrz również poniżej).

Większość kart wymagaCMD1 powtórzenia kroków 3a / 3b (lub w przypadku starych kart), zwykle przynajmniej raz, nawet jeśli odczekasz chwilę między nimi ; tzn. faktyczna sekwencja to CMD0/ CMD8/ CMD55/ ACMD41/ CMD55/ ACMD41(lub CMD0/ CMD8/ CMD1/ CMD1) - dla pewności wypróbuj CMD55/ ACMD41(lub CMD1jeśli 0x05je otrzymałeś ) razy (wybierz w swoim rozsądku; w rzeczywistości dość często trzeba czekać kilkaset ms, jeśli urządzenie jest tuż po włączeniu zasilania, więc celuj w to), z małymi opóźnieniami między próbami, jeśli chcesz, i zakładaj porażkę, jeśli odpowiedźnn0nie pojawia się (tzn. jeśli z jakiegoś powodu urządzenie pozostaje w trybie bezczynności). Również otrzymywanie 0xFFod CMD0powszechnie jeśli urządzenie było w jakimś „dziwne” stanu poprzednio (np odłożył, dostał SS dezaktywowane [Wysoka], miał nad- / podnapięciowe na niektóre kołki itd.) - po prostu dać mu trochę czasu, spłukać i powtórzyć razy. Zniekształcona odpowiedź jest czasami OK - jeśli wysłałeś ją kilka razy, a odpowiedź nadal nie jest ani , ani więcej , spróbuj iść dalej . Jeśli to działa - możesz iść; jeśli nie - prawdopodobnie jest zepsuty .nCMD00xFF0x01CMD8

Zauważ, że odpowiedzi, które mają ustawiony MSB, ale 0xFFzwykle nie sugerują, że twój SPI zmienił taktowanie (w wyniku np. Spadku Vcc, co zdarza się rutynowo, gdy robisz hotplugs SD). Aby to naprawić, możesz spróbować całkowicie zresetować urządzenie (włączanie / wyłączanie zasilania, deassert / assert S̲S̲ itp.); to zwykle działa.

Ponadto specyfikacja mówi

Po ostatniej transakcji magistrali na karcie pamięci SD host jest zobowiązany do zapewnienia 8 (ośmiu) cykli zegara, aby karta zakończyła operację przed wyłączeniem zegara.

Może bez niego działać, ale ponieważ 8 cykli = 1 bajt wyjściowy SPI, nie zaszkodzi zbytnio i dobrze jest go mieć.

Pamiętaj, że powinieneś potwierdzić S̲S̲ (aka CS) niski przynajmniej przed i po każdym CMD- jest to całkowicie obowiązkowe w przypadku CMD0(urządzenie nie włączy się bez niego), a w rzeczywistości jest wymagane dla wszystkich innych CMDs, jeśli masz standardy -zgodna karta SD. Łączenie S̲S̲ karty z GND może się wydawać na stałebyć dobrym pomysłem, jeśli karta jest jedynym klientem SPI, z którym host będzie się kiedykolwiek łączył, ponieważ pozwoliłoby to zaoszczędzić zarówno pin wyjściowy uC, jak i potrzebę zarządzania nim za pomocą kodu, i ponieważ karta powinna zakładać, że jest wybrana wszystkie czasu. W rzeczywistości niektóre karty (jeśli nie większość) oczekują włączenia wysokiego lub niskiego nachylenia zamiast po prostu wykrywania niskiego, a więc złościć się, jeśli w ogóle nie przełączysz nieco S̲S̲, a następnie opóźnisz się zegary lub pluć śmieci; niektóre (zwykle nowsze) karty powinny działać, niektóre (starsze) mogą nie działać, YMMV (jeszcze raz). Jednak w przypadku bardziej niezawodnej konfiguracji SPI (> 1 urządzenie podrzędne) pamiętaj o zapewnieniu niskiego styku przed faktyczną transakcją przy użyciu danej karty SD.

Poza tym, chociaż specyfikacja mówi, że tylko CMD0i CMD8powinna mieć CRC w trybie SPI, niektóre karty SD (takie jak Transcend) wydają się wymagać odpowiedniego CRC dla CMD55/ ACMD41- jeśli chcesz być po bezpiecznej stronie, po prostu użyj dla nich wstępnie obliczonej wartości.

Ponadto, chociaż SPI sam w sobie nie wymaga podciągania / spadania, dobrym pomysłem może być podciągnięcie MISO w wysokości 47k; niektóre urządzenia pozostawiają swój pin DO w wysokich Z w określonych okolicznościach (np. nie są inicjowane), a piny swobodne mogą zawsze być źródłem dziwnych problemów. Jeśli twój komputer ma 3,3 Vcc, możesz użyć wewnętrznych podciągnięć; jeśli jest to 5 V, nie rób tego, chyba że twoja linia MISO ma już prawidłowe tłumaczenie logiczne 5-> 3.3 V.

Dalsza lektura:

Jak korzystać z MMC / SDC

Specyfikacje SD Część 1 Uproszczona warstwa fizyczna Uproszczona specyfikacja - najważniejsze sekcje 6.4.1 Włączenie zasilania i 7.2.1 Wybór i inicjalizacja trybu za pomocą rysunku 7-1 : Diagram stanu karty pamięci SD (tryb SPI)

vaxquis
źródło
4

Specyfikacje kart SD są dostępne na stronie sdcard.org . Uproszczona wersja pominęła pewne szczegóły, ale powinieneś poszukać na przykład rysunku 7-2 w części 1, gdzie sekwencje inicjalizacji są wyjaśnione dla kart SDHC i SD.

Karty microSD <= 2 GB może pracować jak starszych kart, więc powinny dać Ci 0x00doprowadzić do CMD1 ostatecznie . Może to wymagać więcej niż kilku prób, ponieważ karta może wykorzystywać zegar zewnętrzny z magistrali SPI do sterowania niektórymi procesami wewnętrznymi.

Turbo J
źródło
2

Dodając do doskonałej odpowiedzi @vaxquis, chciałbym zacytować odpowiednią tabelę z „ Uproszczonej specyfikacji warstwy fizycznej w wersji 4.10 , © Copyright 2001–2013 SD Group (Panasonic, SanDisk, Toshiba) i SD Card Association” (Rysunek 7-2 : Proces inicjalizacji trybu SPI):

Sekwencja początkowa SPI karty SD

Tutaj możesz zobaczyć, które polecenia wysyłać w jakiej kolejności i jakie odpowiedzi mówią nam o typie karty. Myślę, że pożądane jest, aby urządzenie obsługiwało jak najwięcej kart; i tak długo, jak chodzi o podstawowe operacje odczytu i zapisu bloków 512 bajtów, powinno to być wykonalne dla co najmniej wszystkich kart SD i HC V1.x i V2.0.

JimmyB
źródło
2

Oferuję to jako kolejną możliwość. W trybie SPI, Samsung MicroSD EVO 32GB wymaga, aby wszystkie kody poleceń miały prawidłowe kody CRC. Założę się, że nie są jedynymi. Czytam komentarz, w którym osoba uważa, że ​​wszystkie karty powyżej 32 GB mogą być w ten sposób. Od ponad tygodnia debuguję błąd. Mój kod nie zadziała, dopóki wszystkie kody wysłane na kartę nie będą miały prawidłowych kodów CRC. Użyłem tego do obliczenia wszystkich kodów CRC https://github.com/hazelnusse/crc7/blob/master/crc7.cc Próbowałem nawet użyć polecenia 59, aby wyłączyć kody CRC, nie. Mam nadzieję, że pozwoli to zaoszczędzić komuś dużo czasu i wysiłku.

Mój kod inicjujący z wartościami 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
źródło
-2

Czy jesteś pewien, że Twoja magistrala SPI ma częstotliwość 400 kHz? Inicjalizacja musi nastąpić w przypadku magistrali SPI pracującej z częstotliwością 400 kHz, dopóki karta SD nie zgłosi, że jest w stanie bezczynności, po czym można zwiększyć częstotliwość taktowania magistrali SPI (dokładne maksimum wydaje się różnić od producenta do producenta, ale wydaje się, że 12 MHz to bezpieczny zakład dla większości kart).

Ponadto, zgodnie z tym: http://elm-chan.org/docs/mmc/mmc_e.html CMD1 to właściwa inicjalizacja. CMD8 jest wymagane tylko do sprawdzenia zakresu napięcia, co nie powinno być problemem w przypadku kart innych niż SDHC (<= 2 GB).

Zuofu
źródło
w rzeczywistości wiele kart SD (głównie nowszych, mój Sony SR-32C4 32GB jest jednym) w ogóle nie uruchomi się bez CMD8wcześniejszego wydania. Ponadto zegar zwykle nie stanowi problemu, o ile znajduje się w rozsądnym zakresie.
vaxquis
-3

Może jest już za późno, ale odpowiedź z karty jest OK! Po CMD0 odpowiedź musi wynosić 0x01 - oznacza to, że karta JEST w stanie BEZCZYNNOŚCI i gotowa do pracy. Jeśli masz coś takiego jak 0b00000101, 1 na drugim miejscu mówi, że jest to polecenie niezgodne z prawem, a 1 na 0 oznacza, że ​​sard jest nadal w stanie bezczynności i jest gotowy do pracy. Jeśli odpowiedź wynosi 0x00, oznacza to, że karta NIE JEST w stanie BIEGU bezczynnego i musisz wysłać kolejne polecenie RESET.

Peca
źródło
czy w ogóle przeczytałeś pytanie? PO wyraźnie powiedział I tried this, but I am getting 01 even for CDM1- coraz bezczynnie odpowiedzi CMD1na NOT OK. „Odpowiedź” nie rozwiązuje jego prawdziwego problemu.
vaxquis