Forum: Mikrocontroller und Digitale Elektronik SD Karte antwortet merkwürdig auf CMD0


von C. H. (hedie)


Angehängte Dateien:

Lesenswert?

Guten Abend zusammen

Ich habe folgendes problem,

Am SPI des STM32 hängt eine Micro SD Karte mit 1GB
DataOut der Karte hat einen PullUp von 10k nach 3.3V

Ich versuche die Karte in den Idle mode zu bringen, doch leider 
antwortet diese nicht mit 0x01 sondern mit irgend etwas merkwürdigem....

Anbei mal mein Timing diagram...

CLK Speed ist ca 30KHz

Ich hoffe irgend jemand hat das gleiche auch schon einmal erlebt.

Vor der Sequenz im Bild, sende ich 20x 8 Dummy Clocks mit 0xFF damit die 
DataIn leitung der SD auf high ist.

Habe bereits mehrere Karten versucht. Alle antworten identisch.

Danke schonmal

von holger (Gast)


Lesenswert?

>Vor der Sequenz im Bild, sende ich 20x 8 Dummy Clocks mit 0xFF damit die
>DataIn leitung der SD auf high ist.

Vor dem senden der Dummy Clocks liegt CS auf low.
Das darf es nicht.

von C. H. (hedie)


Lesenswert?

holger schrieb:
> Vor dem senden der Dummy Clocks liegt CS auf low.
> Das darf es nicht.

Vielen Dank für deine Antwort :)

Beim Initialisieren der Ports geht CS Automatisch auf low...

Wie viel früher vor dem senden der 80+ Dummy Clocks muss CS auf high 
sein?

von holger (Gast)


Lesenswert?

>Beim Initialisieren der Ports geht CS Automatisch auf low...

Dann setz ihn vor dem umschalten auf Ausgang auf high.

von C. H. (hedie)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt einfach mal CS ein paar sekunden vorher auf high 
gesetzt...

Doch leider hat sich an der merkwürdigen antwort nichts verändert...

Anbei ein bild der gesamtübersicht und ein detailbild der antwort

von C. H. (hedie)


Lesenswert?

holger schrieb:
> Dann setz ihn vor dem umschalten auf Ausgang auf high.

Wie meinst du vor dem umschalten auf Ausgang?
Vor dem Konfigurieren der Ports kann ich da nichts ausgeben.

Darf die karte vor den Dummyclocks niemals ein Low an der CS Leitung 
sehen?

von C. H. (hedie)


Lesenswert?

Hat niemand mehr einen Tipp für mich? :)

von C. H. (hedie)


Lesenswert?

Kennt vielleicht jemand die Antwort, welche mir die Karte liefert?

von hungrig (Gast)


Lesenswert?

so wie das aussieht steht da eine 0x00 als Antwort.

Die Antwort kommt auf der DO Leitung!!!


Bit Bedeutung
7 Immer 0
6 parameter error
5 address error
4 erase sequence error
3 communication crc error
2 illegal command
1 erase reset
0 in idle state

hast du die SPI einstellungen für CPOL und CPHA korrekt?

von hungrig (Gast)


Lesenswert?

0 ist nicht korrekt, sorry!

Aber was sagt denn dein SPI-RX-Buffer was er empfängt?

von C. H. (hedie)


Angehängte Dateien:

Lesenswert?

hungrig schrieb:
> hast du die SPI einstellungen für CPOL und CPHA korrekt?

Danke für die Antwort...

Ja ich bin im Mode0 also CPOL = 0 und CPHA = 0


Ich habe bei meinen Recherchen herausgefunden, dass es Karten gibt,
welche nicht immer 8 Clocks abwarten bis sie eine Antwort liefern.

Meine Karte wartet nun also 2 Clocks komplett und macht dabei nichts.
Danach sendet sie 0xFF um mitzuteilen das sie beschäftigt ist.

Danach sendet sie 0x01 zurück jedoch verschoben zum normalen 8BIT Block.

Ich weiss nicht, wie regelmässig dieses Verhalten bei den SD Karten ist, 
zumal hier ja anscheinend noch niemals dieses Phänomen erlebt hat.

Meine Idee ist nun, nach dem Senden von 0x95 also dem CRC
sende ich solange clocks, bis ich eine negative Flanke auf der DO 
leitung entdecke , nachdem ich CLK auf low gezogen habe. Ist dies der 
fall, Lese ich wieder mit dem Hardware SPI die Daten aus. (ab dann ja 
wieder 8bits)

Kann es sein, das dies bereits schon immer das normale vorgehen gewesen 
ist, es jedoch in so gut wie keiner SD Lib umgesetzt wird?
Bei denen welche ich gesehen habe, wird nach dem CRC direkt das nächste 
Byte als antwort gesehen.

Es wäre noch interessant zu sehen, wie das fertig gekaufte SD Leser 
machen.

Denn diese haben keinerlei Probleme mit meinen Karten...


Bin froh über eine Diskussion über dieses Phänomen. Denn mommentan kann 
ich noch nicht auf die Karte schreiben :)

Anbei ein Foto, welches den versatz zeigt.

von hungrig (Gast)


Lesenswert?

ich versuche gerade das selbe mit einem MSP430F449 und einer 2GB 
microSD-Karte von Kingston.

Ich guck morgen mal nach ob ich auch ein verschobenes verhalten habe.
Ich bekomme bei der Initialisierung eine Korrekte 0x01 nach 16 CLK's 
also 1. Byte 0xFF 2. Byte die erwartete Antwort 0x01.

Danach versuche ich die Karte aus dem IDLE-mode zu holen und da bekomme 
ich eine 0x05 als Antwort, und mit der kann ich nix anfangen.

Was für eine Karte verwendest du?
Und hast du eine Vorlage nach der du die Implementation machst?
oder hast du die selbst geschrieben?

Gruss ein hungriger --> der geht jetzt Nachtessen.
Melde mich bei Gelegenheit morgen nochmal.

von C. H. (hedie)


Lesenswert?

hungrig schrieb:
> Was für eine Karte verwendest du?
> Und hast du eine Vorlage nach der du die Implementation machst?
> oder hast du die selbst geschrieben?

Vielen Dank für deine Antwort :)

Ich verwende 3 Karten zum testen...

1: Original SanDisk MicroSD 8GB SDHC mit Speed level 2
2: China Billig SanDisk (eventuell gefälscht) MicroSD 1GB Speed Level 
unbekannt
3: Original SanDisk MiniSD 1GB Speed Level unbekannt

Mit allen 3 Modellen habe ich das gleiche Phänomen.


Für die Implementation habe ich zuerst Elm Chans petit FAT verwendet.
Doch als da schon die Initialisierung nicht klappte, wurde ich stutzig.

Nun habe ich lediglich den Code im Main für CMD0

Also ganz rudimentär einfach SPI_SEND(0x40)...SPI_SEND(0x95) etc....

hungrig schrieb:
> Melde mich bei Gelegenheit morgen nochmal.

Fänd ich toll :)

von hungrig (war ich vorhin) (Gast)


Lesenswert?

Ok,

ich verwende ebenfalls diesen Code,

das Dokument zum Code, als dieser im CIRCUIT CELLAR veröffentlicht 
wurde.
Link: http://antiradio.narod.ru/raznoe/sd.pdf


ich habe für CS einen 100k PullDown gegen Masse
und MISO und MOSI mit 100k PullUp an 3.3V gehängt.

Lasse den Code mit 400k laufen und soweit alles i.O. bis auf das oben 
erwähnte.

Ich habe den LogicAnalyzer und den Aufbau jetzt nicht mehr zur Hand.

guck doch noch mal in das PDF, die Funktion bool 
card_response(expectedVal)
find ich i.O.

Ach ja, hast du für SPI den 3-Wire Modus eingeschaltet? nicht das dir CS 
der SPI-HW noch dazwischenfunkt.

eine gute Nacht wünsche ich.

von holger (Gast)


Lesenswert?

>ich habe für CS einen 100k PullDown gegen Masse

Der gehört an VCC.

von hungrig (war ich mal) (Gast)


Lesenswert?

holger schrieb:
> Der gehört an VCC.

hatte ich auch zuerst, aber im oben genannten PDF von CIRCUIT CELLAR
ist der gegen GND...

Wie und wo genau das definiert ist, ist mir noch nicht ganz klar.
Wir ja wohl irgendwo einen Standard dafür geben!

von holger (Gast)


Lesenswert?

> Der gehört an VCC.
>
>hatte ich auch zuerst, aber im oben genannten PDF von CIRCUIT CELLAR
<ist der gegen GND...

Und das ist falsch.

>Wie und wo genau das definiert ist, ist mir noch nicht ganz klar.

Ganz einfach: Dein uC ist beim Powerup noch nicht angelaufen
und alle Datenleitungen zur SD floaten. Wär doch scheisse
wenn die Karte da was draus erkennt was sie nicht mag und in
einen Fehlerzustand geht. Der PULLUP sorgt dafür das die
Karte erst mal gar nichts annimmt bis man CS mal auf low zieht.

von hungrig (war ich mal) (Gast)


Lesenswert?

holger schrieb:
>>Wie und wo genau das definiert ist, ist mir noch nicht ganz klar.
>
> Ganz einfach: Dein uC ist beim Powerup noch nicht angelaufen
> und alle Datenleitungen zur SD floaten. Wär doch scheisse
> wenn die Karte da was draus erkennt was sie nicht mag und in
> einen Fehlerzustand geht. Der PULLUP sorgt dafür das die
> Karte erst mal gar nichts annimmt bis man CS mal auf low zieht.

Danke für die Erklärung! Mir ist ein Licht aufgegangen!
Hatte dies auch erst mit einem PullUp gelöst, und dann gesehen dass das 
in dem erwähnten Artikel anders rum gemacht wurde. Jedoch war das 
eigentliche Problem nicht dass setzen des CS Pegels, sondern meine 
Kartenkontaktiereinheit hatte keinen sauberen Kontakt zur Karte.

Ich schliess mal die Klammer wieder, so dass obiges Problem weiter 
Behandelt werden kann.

von C. H. (hedie)


Lesenswert?

hungrig (war ich vorhin) schrieb:
> guck doch noch mal in das PDF, die Funktion bool
> card_response(expectedVal)
> find ich i.O.

Werde ich heute machen :) Danke
Wo finde ich den Code zur besagten Funktion?

>
> Ach ja, hast du für SPI den 3-Wire Modus eingeschaltet? nicht das dir CS
> der SPI-HW noch dazwischenfunkt.

Ja, ich habe den 2LineFullDuplex Mode aktiviert...

Empfangen geht also :)

Aber mommentan schaue ich nicht was im Register des uC als Antwort 
zurückkommt sondern ich sehe mir einfach das Diagram des LAs an...

Aber Danke für den Hinweis :)

von codehamster (Gast)


Lesenswert?

Guten Morgen,

den Code habe ich von hier:

ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2005/176/Sham176.zip

von Holger H. (onifred)


Lesenswert?

Hallo,

Habe auch gerade die SD Initialisierung in Gang bekommen.

Mein System Mega8L8 3,3V mit SD-Mikro Adapter.
Meine Karten: alle SD-mikro. NOKIA 2GB, SAMSUNG 4GB SDHC, SANDISK 8GB 
SDHC

Welche Dokumentation benutzt du?

Hier das wichtigste:
http://www.sdcard.org/

Part_1_Physical_Layer_Simplified_Specification_Ver_3.01_Final_100518.pdf

Zur Initialisierung ist Diagramm 4.1 sehr interessant.

Es steht auch drin welche Pullups benutzt werden sollten.

Hatte die 4GB Karten am laufen, nur die anderen funktionierten nicht.
Habe die Lösung im Kapitel 4.4 Clock Contol gefunden.
Bitte genau lesen.

Als nächstes versuche ich mich an FAT32.

Gruß Holger

von C. H. (hedie)


Lesenswert?

codehamster schrieb:
> Guten Morgen,
>
> den Code habe ich von hier:
>
> ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2005/176/Sham176.zip

Guten Nachmittag :)

Vielen Dank für den Link, werde ich gleich mal prüfen :)

### EDIT ###

Hier also die Funktion welche auf das Response wartet...
1
/**
2
 *  waits for the memory card to response
3
 *
4
 *  @param expRes    expected response
5
 *
6
 *  @return TRUE    card responded within time limit
7
 *  @return FALSE    card did not response
8
 **/
9
boolean cardResponse(unsigned char expRes)
10
{
11
  unsigned char actRes;
12
  unsigned int count = 256;
13
  actRes = 0xFF;
14
  while ((actRes != expRes) && (count > 0))
15
  {
16
    actRes = spi_get();    
17
    count--;
18
  }
19
  if (count == 0)
20
    return FALSE; 
21
  return TRUE;
22
}

Dieser Code wiederholt solange spi_get() bis entweder die gewünschte 
Antwort eingetroffen ist, oder aber das Zeitlimit erreicht wurde.

In meinem Fall, habe ich jedoch noch eine verschiebung der Antwort um 2 
Clocks.

Somit wird diese Funktion niemals die gewünschte Antwort einlesen und 
somit immer einen Error zurückgeben.

Holger H. schrieb:
> Hatte die 4GB Karten am laufen, nur die anderen funktionierten nicht.
> Habe die Lösung im Kapitel 4.4 Clock Contol gefunden.
> Bitte genau lesen.

Also funktionieren nun alle mit der Lösung aus Kapitel 4.4?

von R2D2 (Gast)


Lesenswert?

Ihr benutzt alle MicroSD-Karten. Dabei solltet ihr beachten, dass nur 
bei den normalen der SPI-Modus verpflichend, aber bei MicroSD optional 
ist.

von C. H. (hedie)


Lesenswert?

R2D2 schrieb:
> Ihr benutzt alle MicroSD-Karten. Dabei solltet ihr beachten, dass nur
> bei den normalen der SPI-Modus verpflichend, aber bei MicroSD optional
> ist.

Vielen Dank für den Hinweis...

Jedoch verwende ich auch eine MiniSD.

Diese liefert die selben ergebnisse.

von Holger H. (onifred)


Lesenswert?

Hallo,

R2D2 schrieb:
> Ihr benutzt alle MicroSD-Karten. Dabei solltet ihr beachten, dass nur
> bei den normalen der SPI-Modus verpflichend, aber bei MicroSD optional
> ist.

Wo steht das? Bei www.sdcard.org?
Benutze microSD weil ich den microSD nach SD Adapter auf meine Platine 
gelötet habe. Wollte eigentlich 1GB Karten mit Adapter kaufen.
Gab nur noch SDHC 4GB Karten für 5,-EUR.

hedie schrieb
> Also funktionieren nun alle mit der Lösung aus Kapitel 4.4?

Ja, die Init und das Auslesen der CID und der CSD funktionieren
bei den drei verschiedenen Karten. Bin noch nicht weiter.

Gruß Holger

von Holger H. (onifred)


Lesenswert?

Hier noch was mein Mega ausgibt:
1
SDHC Test
2
sdhc      : Start
3
sdhc_ident: send cmd0: R1: 0x01 idle OK
4
sdhc_ident: send cmd8: R1: 0x01 idle OK
5
sdhc_ident: cmd8: response : 0x000001aa OK
6
sdhc_ident: send acmd41 High Capacity Support: R1: 0x00 OK
7
sdhc_ident: send cmd58 Card Capacity Status: R1: 0x00 OK
8
sdhc_ident: cmd 58 response: 0xc0ff8000 OK, Card Capacity Status=1
9
10
sdhc_info: send cmd10 Card ID (CID): R1: 0x00 OK
11
sdhc_info: DataBlock Start:  Start R1: 0xfe OK
12
sdhc_info: MID: 0x1b
13
sdhc_info: OID: SM
14
sdhc_info: PNM: 00000
15
sdhc_info: PRV: 1.0
16
sdhc_info: PSN: 0x7675ec1f
17
sdhc_info: MDT: 5.2011
18
19
sdhc_info: send cmd9 card-specific data (CSD): R1: 0x00 OK
20
sdhc_info: DataBlock Start:  Start R1: 0xfe OK
21
sdhc_info: CSD structure: CSD Version 2.0 High Capacity and Extended Capacity
22
sdhc_info: max. data transfer rate: 0x32 = 25 MHz
23
sdhc_info: DSR implemented: 0
24
sdhc_info: copy flag: 1
25
sdhc_info: permanent write protection: 0
26
sdhc_info: temporary write protection: 0
27
28
sdhc_shutdown: send cmd0 CS_HIGH
29
sdhc      : End

Gruß Holger

von einGast (Gast)


Lesenswert?

Claudio Hediger schrieb:
> Anbei mal mein Timing diagram...
>
> CLK Speed ist ca 30KHz

die vorgeschriebene Frequenz laut Spezifikation in der 
Initialisierungsphase ist 100..400 kHz!

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.