Forum: Mikrocontroller und Digitale Elektronik SD karten befehle CMD0 und co.


von overseer (Gast)


Lesenswert?

hi,

ich wälze mich jetzt seit ein paar stunden durch die sd karten 
protokolle...

aber es happert etwas bei den befehlen

mir ist klar das jeder befehl aus 48bits besteht. aber woher weiß ich 
welche bits ich bei standard befehlen setzten muss...

standard heißt für mich z.B. die befehle die man zum initialisieren 
benötigt. die müssten ja eigentlich immer gleich ausehen.

bit 1 ist bei befehlen immer 0
bit 2 gibt die richtung an/ wer es gesendet hat...will ich etwas zum 
slave schicken dann 0, richtig?
bit 3...hier gehts jetzt los...schreibt man da einfach die befehlsnummer 
rein?
bit 4 ist vermutlich immer null bei solchen standard befehlen, oder?
bit 5 ka aber ein crc wert kann sich ja auch nicht groß ändern bei einem 
definierten befehl :/
bit 6 immer 1 wenn ichs richtig verstanden habe

dieses beispiel von cmd1 bestätigt meine vermutungen...aber wo bekommt 
man eine liste was man wo zusetzen hat?
1
      spi_back = Sende_spi(&H40)
2
      spi_back = Sende_spi(0)
3
      spi_back = Sende_spi(0)
4
      spi_back = Sende_spi(0)
5
      spi_back = Sende_spi(0)
6
      spi_back = Sende_spi(&H95)


ich hoffe ihr könnt etwas licht ins dunkel bringen

von R. W. (quakeman)


Lesenswert?

Grundsätzlich solltest du dir die offizielle SD-Karten Spezifikation zur 
Hand nehmen von http://www.sdcard.org/developers/tech/sdcard/pls/

Du hast in deiner Beschreibung etwas die Begriffe Bits und Byte 
vertauscht.
SPI Befehle bestehen aus 6 Bytes, das ist korrekt. Befehle beginnen 
immer mit '01' gefolgt von den 6 Bits für den jeweiligen CMD. Die 
nachfolgenden 4 Bytes werden abhängig vom CMD gefüllt und am Ende kommen 
7Bit CRC und eine '1' als Stopbit.

In der SD-Spec auf S.101 ist der Befehlsaufbau dargestellt. Direkt 
danach sind alle CMDs und deren Argumente aufgelistet. Ab S.109 sind 
alle SPI Responses und deren Aufbau aufgelistet. Und auf S.95 ist ein 
sehr guter Ablaufplan zum Initialisieren einer SD-Karte aufgezeigt.

Mit diesen Infos solltest du eigentlich die Funktionsweise recht schnell 
verstehen können. Bei weiteren Frage einfach hier posten. :)

Achja, der Beispielcode den du aufgelistet hast ist für CMD0 und nicht 
für CMD1.
CMD1 würde z.b. so aussehen (CRC wird nicht mehr benötigt):
1
aucCmd[0] = 0x41;
2
aucCmd[1] = 0x00;
3
aucCmd[2] = 0x00;
4
aucCmd[3] = 0x00;
5
aucCmd[4] = 0x00;
6
aucCmd[5] = 0xFF;

Aber du solltest versuchen CMD1 bei SD-Karten nicht mehr zu benutzen, da 
dieser Befehl nur noch aus Kompatibilitätsgründen implementiert ist. Die 
richtige Initialisierung wird mit ACMD41 gemacht (CMD55 + ACMD41).

Ciao,
     Rainer

von overseer (Gast)


Lesenswert?

d

die pdf hatte ich zwar schon
bin aber zunächst nicht allzu schlau rausgeworden :/

aber ich denke jetzt bin ich etwas weiter...

die sd karte hat 11 verschiedene zustände in denen sie jeweils andere 
befehle akzeptiert, richtig?

da crc mit aktivieren des spi modus deaktiviert wird, ist es wohl nur 
für den cmd0 interessant, denn dort achtet die karte noch auf den 7bit 
crc teil, oder?
nur wie berechnet sich dieser teil? darauf habe ich noch keine antwort 
gefunden :/
/ jedenfalls keine für mich verständliche...das datenblatt wirft nur 
eine "formel" raus nur ist mir nicht so ganz klar was man da einsetzen 
soll :?
s.43/ pdf seite 54 des datenblatts
1
CMD INDEX SPI  Mode   Argument   RespA. Command       Description 
2
CMD0      Yes  [31:0] stuff bits R1    GO_IDLE_STATE  Resets the SD Card

stuff bits bedeutet das sie nich von belang sind/ nicht beachtet werden 
oder?

von R. W. (quakeman)


Lesenswert?

overseer schrieb:
> die sd karte hat 11 verschiedene zustände in denen sie jeweils andere
> befehle akzeptiert, richtig?
Mir ist nicht ganz klar, was du mit 11 Zuständen meinst. Es gibt eine 
Anzahl CMDs und diese sind (fast) immer alle ausführbar auf die gleiche 
Weise.

> da crc mit aktivieren des spi modus deaktiviert wird, ist es wohl nur
> für den cmd0 interessant, denn dort achtet die karte noch auf den 7bit
> crc teil, oder?
Genau, nach CMD0 (CMD8) wird die CRC nicht mehr beachtet.

> nur wie berechnet sich dieser teil? darauf habe ich noch keine antwort
> gefunden :/
> / jedenfalls keine für mich verständliche...das datenblatt wirft nur
> eine "formel" raus nur ist mir nicht so ganz klar was man da einsetzen
> soll :?
> s.43/ pdf seite 54 des datenblatts
Die Formel im Datenblatt ist auf Anhieb auch nicht unbedingt einfach zu 
verstehen. Ich habe es auch nur schnell hinbekommen die zu berechnen, 
weil ich die CRC32 in einer Vorlesung mal behandelt hatte. Und die CRC7, 
die bei der SD-Karte verwendet wird, ist identisch zu berechnen, nur 
eben mit einem anderen Generatorpolynom. Auf Wikipedia findest du einen 
schönen Artikel zur Berechnung der CRC unter 
http://de.wikipedia.org/wiki/Cyclic_Redundancy_Check
Wenn du dich an den Ablaufplan der Initialisierung einer SD-Karte laut 
Spezifikation hälst, dann müsstest du noch per CMD8 die Spezifikation 
der SD-Karte überprüfen (V1.x oder V2.x). Wobei CMD8 ebenfalls noch eine 
gültige CRC7 benötigt.

Mein CMD8 sieht folgendermassen aus:
1
// CMD8
2
aucCmd[0] = 0x48;
3
aucCmd[1] = 0x00;
4
aucCmd[2] = 0x00;
5
// VHS = 0001 (2,7V - 3,6V)
6
aucCmd[3] = 0x01;
7
// Check Pattern = 10101010
8
aucCmd[4] = 0xAA;
9
// CRC7 = 1000011 (0x43)
10
// Danach folgt noch eine 1 als Stopbit wodurch 10000111 (0x87) zustandekommt
11
aucCmd[5] = 0x87;

> stuff bits bedeutet das sie nich von belang sind/ nicht beachtet werden
> oder?
Genau. Der Einfachheit halber setze ich diese Bits immer 0.

Falls es sich um eine SD-Karte nach Spezifikation v2.x handelt kannst du 
am Ende der Initialisierung per CMD58 dann noch feststellen, ob es sich 
um eine SD oder SDHC Karte handelt (CCS Bit prüfen.

Ciao,
     Rainer

von overseer (Gast)


Lesenswert?

ok...

nachdem ich die polynomdivision jetzt auch wieder kann...*hüstel

sind mir noch ein paar fragen offen geblieben die wiki leider nicht 
beantworten konnte

1.welchen bereich genau nimmt man für M(x)?

und viel wichtiger...

2. wie "berechnet" man aus G(x)die binärkette?

meine idee war
G(x)=x^7+x^3+1 = 10001001 >die darf eigentlich nur 7bit lang sein oder?

sprich für x jeweils 2 einsetzen...bei dem mikrocontroller wiki beispiel 
klappt das, zufall?
mit dem wikipedia beispiel kann ichs allerdings nicht in einklang 
bringen...allerdings zaubern die da die binärketten auch irgendwie aus 
dem boden :?
http://www.mikrocontroller.net/articles/CRC

gruß

von R. W. (quakeman)


Lesenswert?

Ich habe dir mal die CRC7 für meinen Beispiel CMD8 von Hand 
durchgerechnet. Da solltest du es sehen können, wie man es von Hand 
macht. :)

Generator Polynom CRC7: x^7 + x^3 + 1 = 10001001
Generatorpolynom Grad = 7
-> 7 Nullen fuer CRC7 Berechnung an Daten hängen
Daten durch Generatorpolynom teilen (XOR)

  0x48    0x00    0x00    0x01    0xAA
|      ||      ||      ||      ||      |      |
01001000000000000000000000000001101010100000000
10001001|||||||||||||||||||||||||||||||||||||||
--------|||||||||||||||||||||||||||||||||||||||
11000001|||||||||||||||||||||||||||||||||||||||
10001001|||||||||||||||||||||||||||||||||||||||
--------|||||||||||||||||||||||||||||||||||||||
010010000||||||||||||||||||||||||||||||||||||||
 10001001||||||||||||||||||||||||||||||||||||||
 --------||||||||||||||||||||||||||||||||||||||
 00011001000|||||||||||||||||||||||||||||||||||
    10001001|||||||||||||||||||||||||||||||||||
    --------|||||||||||||||||||||||||||||||||||
    010000010||||||||||||||||||||||||||||||||||
     10001001||||||||||||||||||||||||||||||||||
     --------||||||||||||||||||||||||||||||||||
     000010110000||||||||||||||||||||||||||||||
         10001001||||||||||||||||||||||||||||||
         --------||||||||||||||||||||||||||||||
         0011100100||||||||||||||||||||||||||||
           10001001||||||||||||||||||||||||||||
           --------||||||||||||||||||||||||||||
           011011010|||||||||||||||||||||||||||
            10001001|||||||||||||||||||||||||||
            --------|||||||||||||||||||||||||||
            010100110||||||||||||||||||||||||||
             10001001||||||||||||||||||||||||||
             --------||||||||||||||||||||||||||
             0010111100||||||||||||||||||||||||
               10001001||||||||||||||||||||||||
               --------||||||||||||||||||||||||
               0011010100||||||||||||||||||||||
                 10001001||||||||||||||||||||||
                 --------||||||||||||||||||||||
                 010111010|||||||||||||||||||||
                  10001001|||||||||||||||||||||
                  --------|||||||||||||||||||||
                  0011001100|||||||||||||||||||
                    10001001|||||||||||||||||||
                    --------|||||||||||||||||||
                    010001010||||||||||||||||||
                     10001001||||||||||||||||||
                     --------||||||||||||||||||
                     00000011001101||||||||||||
                           10001001||||||||||||
                           --------||||||||||||
                           010001000|||||||||||
                            10001001|||||||||||
                            --------|||||||||||
                            000000011010000||||
                                   10001001||||
                                   --------||||
                                   010110010|||
                                    10001001|||
                                    --------|||
                                    0011101100|
                                      10001001|
                                      --------|
                                      011001010
                                       10001001
                                       --------
                                       01000011
CRC7 = 1000011 (0x43)
Dazu kommt noch das letzte Stopbit mit einer 1 ans Ende dran wodurch 
dann 10000111 (0x87) entsteht, welches das letzte Byte des Befehls 
darstellt.

Ciao,
     Rainer

von overseer (Gast)


Lesenswert?

wow danke für den ausführlichen post

die rechnung wäre aber nicht nötig gewesen :)

aber eine sache bleibt immer noch offen. und zwar wie man aus dem 
polynom die binärzahl bildet

auf deine 10001001 kommt man ja wenn man einfach in das polynom 2 
einsetzt...

wikipedia spuckt aber sowas hier aus

[code]
x7 + x3 + 1 (telecom systems,MMC,SD)   0x09  0x48  0x44
[code]
http://en.wikipedia.org/wiki/Cyclic_redundancy_check

auf die 0x09 kommt man wenn man die x7 rauslässt und einfach in x3+1 2 
einsetzt...funktioniert bei (nahezu) der gesamten liste dort.

berechnen die da jetzt was total anderes?

im mikrocontroller wiki liest man folgendes
[code]
Das Generator-Polynom sei x5 + x2 + x. Dies entspricht der binären Zahl 
100110. Das Polynom ist vom 5. Grad, weil das höchste gesetzte Bit den 
Wert 2^5 hat. Gerechnet wird aber immer nur mit den unteren 5 Bit, hier 
also 00110. Jetzt ist natürlich auch noch ein binäre Zeichenkette 
notwendig, die unsere Daten darstellt. Beispielsweise 1110100111001 
(willkürlich gewählt).
[code]
http://www.mikrocontroller.net/articles/CRC

rechnen tuen die da in ihrem beispiel aber trotzdem mit dem ganzen 
ergebnis :/


gruß

von R. W. (quakeman)


Lesenswert?

overseer schrieb:
> aber eine sache bleibt immer noch offen. und zwar wie man aus dem
> polynom die binärzahl bildet
Das Polynom sieht ja für CRC7 folgendermassen aus:
Generatorpoly => 10001001
Und genauso kannst du sämtliche Generatorpolynome für andere CRCs 
herleiten.

> Das Generator-Polynom sei x5 + x2 + x. Dies entspricht der binären Zahl
> 100110. Das Polynom ist vom 5. Grad, weil das höchste gesetzte Bit den
> Wert 2^5 hat. Gerechnet wird aber immer nur mit den unteren 5 Bit, hier
> also 00110. Jetzt ist natürlich auch noch ein binäre Zeichenkette
Das ist nicht korrekt. Du arbeitest in der Division mit der Kompletten 
Zahl 100110, wie du in meinem Beispiel sehen kannst (die volle 8- 
stellige Zahl für ein Generatorpolynom des 7. Grades). Vielleicht gibt 
es da irgend welche Optimierungen, aber der original CRC Algorithmus 
benutzt immer die volle (n+1)-stellige Zahl für ein Generatorpolynom des 
n. Grades.

Ciao,
     Rainer

von overseer (Gast)


Lesenswert?

super, dank dir :>

dann ist damit jetzt auch die letzte unklarheit beseitigt :D


gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.