Forum: Mikrocontroller und Digitale Elektronik SD Karte keine Antwort auf CMD0 -XC161


von Markus .. (made-huk83)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe gewisse Probleme beim Initialisieren meiner SD-Karte. Der 
C-Code basiert auf den Routinen von Ulrich Radig.
Ich benutze allerdings keinen AVR Controller sondern einen XC161 von 
Infineon.

Bekomme beim Versuch das CMD0 zu senden keine Antwort von der Karte. 
Oder besser gesagt, besitzt mein SSC0_RB (Empfangsregister) dauerhaft 
den Wert 0xFF und das Receive-Error-Flag ist im SSC0_CON_EN = 1 gesetzt. 
Was ja soviel bedeutet, wie das ein Datenempfang abgeschlossen wurde, 
jedoch nicht in das Empfangsregister übertragen wurde. Bekomme ich hier 
irgendwie einen Überlauf?

Bei der Übertragung des CMD0 erscheinen alle Bytes nacheinander in der 
richtigen Reihenfolge (MSB first) im SSC0_TB. Erhalte danach aber keine 
Antwort von der Karte. Wert von SSC0_RB weiterhin 0xFF.

Die Schnittstelle initialisiere ich mit 1Mbit/s. Sollte also kein 
Problem sein.

Wäre super, wenn jemand einen Tipp parat hätte.

Habe meinen Code angehangen.

von embedded-os (Gast)


Lesenswert?

Ich kenne den XC161 zwar nicht, aber probiere es mal mit 400kHz. Diese 
start-clk gibt SD als value vor bevor es nach lesen von CSD & CID bis 
auf 20MHz geht ...

hier mein Beispiel-code, der MMC  MMCplus  M-Bridge  SD  SDHC 
beherrscht:

http://www.embedded-os.de/index.html?pcfat_port.htm

von Markus .. (made-huk83)


Lesenswert?

Hallo,

erstmal Danke für die Hilfe. Habe es aber auch schon mit 400kHz 
versucht, auch mit 200kHz.
Bin aber nun auf ein anderes Problem gestoßen. Anscheinend arbeitet 
meine Pegelumsetzung an der MISO-Leitung nicht so wie ich das will.
Hier werde ich als erstes noch mal ansetzen.

von Markus .. (made-huk83)


Lesenswert?

Es lag wirklich an der Pegelumsetzung von der MISO-Leitung. Hatte dort 
einen Verdrahtungsfehler. Bekomme nun die gewünschte Antwort von der 
Karte.

von Oli (Gast)


Lesenswert?

Hey!
Passt hier vielleicht nicht ganz, aber ich bekomme auch keine Antwort 
auf CMD0....kann also meine SD-Karte gar nicht in den SPI-Modus 
Initialisieren.

Hab meinen Code mehr oder weniger von Procyon übernommen und eigentlich 
auch verstanden.
Beobachte die SD Karte am Oszi:
SCK = 300kHz

CS=high
die 10 "dummy Bytes" 0xFF werden gesendet, kommen am DI der SD-Karte an
das Command GO_IDLE_STATE wird auch gesendet 
(0x40,0x00,0x00,0x00,0x00,0x95)
hier müsste dann allerdings von der SD-Karte ein 0xFF zurückkommen, aber 
ich erhalte keine Antwort von der Karte,....


An was könnte das liegen??

Die Pegel an der Karte sind auch bei 3V3

Grüße Oli

von willi (Gast)


Lesenswert?

>...das Command GO_IDLE_STATE wird auch gesendet...

aber nicht nur einmal, oder? GO_IDLE_STATE muss öfter gesendet werden 
bis die karte korrekt drauf antwortet

von Oli (Gast)


Lesenswert?

Wird eigentlich schon mehrmals gesendet: Hier mal der Teil meines Codes:
1
unsigend char SPI_Transfer_Byte(unsigned char data)
2
{
3
unsigned char received=0;
4
5
SPDR =data;
6
while(!(SPSR&(1<<SPIF)));
7
received=PSDR;
8
return(received);
9
}
10
11
12
13
unsigend char SD_Reset(void)
14
{
15
16
PORTB|=(1<<SPI_CS);  //setzt CS high
17
unsigned char i;
18
unsigend char retry;
19
unsigned char r1=0;
20
21
do
22
{
23
   for(i=0;i<10;i++) SPI_Transfer:Byte(0xFF); //sendet dummy bytes
24
25
  r1 = SD_Send_Command(SD_GO_IDLE_STATE,0);  //sende CMD0
26
  retry++;
27
  if(retry>10){return -1;}
28
}
29
while(r1 != SD_R1_IN_IDLE_STATE);  // 0x01
30
 
31
32
//.....weiter komm ich gar nicht
33
34
35
36
unsigned char SD_Command(unsigned char cmd, unsigend long arg)
37
{
38
39
PORTB &=~(1<<SPI_CS)  //CS low
40
41
unsigend char r1;
42
unsigend char retry=0;
43
44
45
SPI_Transfer_Byte(cmd|0x40);
46
SPI_Transfer_Byte(arg<<24);
47
SPI_Transfer_Byte(arg<<16);
48
SPI_Transfer_Byte(arg<<8);
49
SPI_Transfer_Byte(arg);
50
SPI_Transfer_Byte(0x95);   //CRC
51
52
53
54
// hier hängt das Programm
55
56
57
while( (r1=SPI_Transfer_Byte(0xFF)) ==0xFF)  
58
59
if(retry++>8){break;}
60
61
PORTB |=(1<<SPI_CS); // CS high
62
63
return r1;
64
}



Also eigentlich will ich nach einmaligem Senden des CMD0, dass die Karte 
mit 0xFF antwortet (stand glaub im Datenblatt)
Über USART hab ich festgestellt, dass da das Programm hängt und wartet 
bis eben r1 den Wert 0xFF hat....

Ich wäre ja schon froh wenn die SD-Karte überhaupt antworten 
würde...Aber die DataOut Leitung bleibt low.
Und im ProductManual 1.9 von SanDisc steht dass jedes Command eine 
Antwort bekommt (außer SEND_STATUS)

Und es ist ja schon richtig, dass Chip Select der Karte low sein muss 
während ich CMD0 sende, oder???

Danke schon mal!

von Markus .. (made-huk83)


Lesenswert?

/CS muss auf 0 sein. Das ist schon richtig so, weil dann die Karte aktiv 
ist. Wie sieht denn bei dir die Pegelumsetzung aus? Oder benötigst du 
keine?
Ist ja auch merkwürdig, dass du keine Änderung der MISO-Leitung erhälst. 
Das gleiche Problem hatte ich ja auch.

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Meine Karte spricht jetzt mit mir :-)
War doch ein Hardware-Fehler, der Spannungsteiler war zwar richtig 
berechnet, hab dann aber versehentlich einen Fahlschen Wiederstand 
eingelötet...aber das sieht man auch so schwer bei den 0603 SMD 
Teilchen...

Die Software stimmt also soweit. Und die Karte befindet sich immerhin im 
Idle State...
Als nächstes will ich CMD1 schicken und als Antwort müsste ich 0x00 
bekommen (also für R1)

Allerdings sieht mein DataOut Signal nicht wirklich "schön" aus, die 
Flanke ist nicht wirklich steil...
Leider kenn ich mich Hardwaretechnisch nicht soo gut aus, dass ich jetzt 
wüsste wie ich das beheben könnte.

Im Anhang ein Bild...
Man sieht wie die letzten beiden 0x00 übertragen werden, dann 0x95(CRC), 
dann nochmal 0xFF und dann müsste meine Antwort 0x00 kommen. ABer DO 
geht viel zu langsam auf low....dann fängt das Senden des CMD1 von vorne 
an

Soll ich an DataOut der SD Karte ein Pull-Down Widerstand ranmachen? 
Bringt das was?

Danke schon mal....

Grüße

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Ok, das hätte ich geschafft...aber die Antwort der Karte kommt zu 
spät...
Mhhh...

von Pete K. (pete77)


Lesenswert?

Ich habe zwar keinen Beitrag zu Deiner Frage, allerdings würde mich Dein 
Meßequipment interessieren :-)

von dummy (Gast)


Lesenswert?

>Soll ich an DataOut der SD Karte ein Pull-Down Widerstand ranmachen?
>Bringt das was?

Sicher bringt das was. Deine Schaltung zieht unnötig viel Strom,
und dein für 5V sowieso schon kritischer Highpegel wird noch
kleiner.

von Oli (Gast)


Lesenswert?

schickes Agilent Oszi...nicht mein eigenes versteht sich^^
Bringt mir trotzdem nichts :(

Meine SD Karte antwortet einfach zu langsam....

von Oli (Gast)


Lesenswert?

So, ich geb auf für heute...

Morgen werde ich noch ein paar andere Karten testen, habe momentan nur 
eine 1GB Karte von SanDisk hier, aber eigentlich dürfte das ja auch 
keinen unterschied machen, oder?! Ich mach ja noch nichts mit dem 
Dateisystem FAT.....nur initialisieren...

Vielleicht hat von euch noch jemand eine Idee wiso die Karte mit 
verzögertem Signal antwortet...

Grüße Olivia

von Pete K. (pete77)


Lesenswert?

Kann es sein, dass die Karte noch nicht ready ist ? Eventuell eine 
Sekunde warten, bis auf die Karte das erste mal zugegriffen wird.

von Oli (Gast)


Lesenswert?

Morgen!
Es funktioniert :-)
Hab noch eine 256MB SD-Card gefunden, mit der funktioniert es 
einwandfrei...(DO kommt rechtzeitig)
Ich habe aber leider keine Ahnung wiso es mit der 1GB nicht 
funktioniert.

Dann kann ich mich mal an die nächsten Funktionen Read/Write machen..

Grüße Oli

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Gib einfach nach dem CMD0 noch 8 zusätzliche Clocks mit DI=$FF, bevor Du 
mit R1 weiterfragst. Dann sollte es gehen. Dies wird von einigen Karten 
benötigt, um das Ausgangsregister zu initialisieren.

von Oli (Gast)


Lesenswert?

Danke, werd ich ausprobieren.
Dachte nur das darf ich nicht, weil im Product Manual auch "nur" 2 mal 
FF gesendet wird und die Antwort dann kommen müsste!

Brauch aber zuerst noch einen ATmega mit größerem RAM, weil Schreiben 
und anschließend lesen geht nicht auf einmal, meine Buffer belegn wohl 
zu viel Platz...aber bin ja ausgerüstet, hab noch einen ATmega644 in der 
Schublade :-)

Grüße

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Generell muß die Anfrage nach R1 solange wiederholt werden, bis die 
Karte einen Wert ungleich $FF ausgibt, bzw. das obere Bit der Antwort 
"0" ist. Bei meinen getesteten Karten war dies stets 8 Clocks nach dem 
CMD0 der Fall. Um dies eindeutig erkennen zu können, sollte DO der Karte 
bzw. MISO am Controller mit einem PullUp beschaltet werden, da eine 
frisch eingesteckte Karte den Bus erst nach erfolgreichem CMD0 
anschaltet und die Leitung vorher floatet, also auch Low sein kann. 
Somit kann der Controller überhaupt nichts erkennen. Der interne PullUp 
reicht völlig (falls vorhanden).

von Oli (Gast)


Lesenswert?

Mhh, irgendwie will das ganze doch nicht.
Bin mir zwar ziemlich sicher, dass Softwaremäßig alles stimmt, hier aber 
nochmal mein Code:
1
SD_Reset(void)
2
{
3
do
4
{
5
  for(i=0;i<10;i++)  SPI_Transfer_Byte(0xFF); //10 dummy bytes 0xFF
6
7
  r1= SD_Send_Command(SD_GO_IDLE_STATE,0);  //send CMD0 //r1= response
8
9
  if(retry++>200) {return-1;}
10
}
11
while(r1!=SD_R1_IN_IDLE_STATE);
12
13
//an dieser stelle befindet sich SD-Card IN IDLE STATE
14
retry=0;
15
do
16
{
17
   r1= SD_Send_Command(SD_SEND_OP_COND,0);
18
19
   if(retry++>100) {return-1;}
20
}
21
while(r1)   // also solange bis r1=0x00
22
23
//An dieser Stelle wäre SD_RESET ERFOLGREICH
24
25
//CRC OFF und SET BLOCKLEN kommen dann noch
26
27
}
28
29
30
//Die SD_Send_Command  function
31
32
33
unsigned char SD_Command(unsigned char cmd, unsigend long arg)
34
{
35
36
PORTB &=~(1<<SPI_CS)  //CS low
37
38
unsigend char r1;
39
unsigend char retry=0;
40
41
42
SPI_Transfer_Byte(cmd|0x40);
43
SPI_Transfer_Byte(arg<<24);
44
SPI_Transfer_Byte(arg<<16);
45
SPI_Transfer_Byte(arg<<8);
46
SPI_Transfer_Byte(arg);
47
SPI_Transfer_Byte(0x95);   //CRC
48
49
50
while( (r1=SPI_Transfer_Byte(0xFF)) ==0xFF)  
51
52
if(retry++>8){break;}
53
54
PORTB |=(1<<SPI_CS); // CS high
55
56
return r1;
57
}
58
59
60
61
62
unsigned char SPI_transfer_Byte(unsigned char data)
63
{
64
unsigend char received=0;
65
SPDR=data;
66
while(!(SPSR&(1<<SPIF)));
67
received=PSDR;
68
return(received);
69
}



Was mich jetzt verwirrt ist, dass ich die Richtige Antwort auf CMD0 
bekomme (0x01).
Die Karte befindet sich also im Idle State.
Dann sende ich auf GENAU die GLEICHE weiße CMD1...aber hier erhalte ich 
nicht das erwünschte r1 von 0x00

Natürlich wird dann CMD1 wieder und wieder gesendet...
Die Antworten von der Karte sind immer: 0xC1 0xF0  0xFC  0x05
also immer die gleichen und halt 100mal....

Aber wie gesagt, genau diese Software funktioniert mit der 256MB Karte.

Gibt es denn noch andere unterschiede zw. einzelnen Karten?
Weil genaue Datenblätter zu den einzelnen SD Karten finde ich nicht.
Hab alles aus ScanDisk ProductManual 1.9 für SD Karten.
Die 1GB Karte ist ja sogar von ScanDisk

Kann es an der Stromaufnahme liegen?? Aber wenn ich mit dem Oszi die 
Pegel an der Karte messe sind die ok.

Kann es am Takt liegen?
Zur Init muss der Takt zw. 100KHz und 400KHz ligen. Bei mir sind es 
260KHz....gibt es Karten die doch einen anderen brauchen?

Kann es sein dass die Karte defekt ist auch wenn ich sie am PC 
ansprechen kann und auch schon die Defekten Sektoren unter Windows 
repariert habe??
Und das erste CMD0 ja funktioniert?

Danke schon mal....

von Oli (Gast)


Lesenswert?

Kaum hier gepostet hab ich auch schon die Lösung meines Problems :-)
Manchmal hilft es doch hier nochmal alles niederzuschreiben....sorry!!

hab im Code BEVOR ich CMD1 sende nochmal 10 dummyBytes gesendet 
(0xFF)...

In der Spec steht davon auf S.87 zwar nichts aber was solls.

Juhuuu :-)

Falls jemand das gleiche Problem hat:
(Kann ja nicht sein dass ich die erste bin die das Problem hatte)

1
//an dieser stelle befindet sich SD-Card IN IDLE STATE
2
retry=0;
3
do
4
{
5
for(i=0;i<10;i++)  SPI_Transfer_Byte(0xFF); // diese Zeile zusätzlich einfügen!!!
6
...
7
...
8
...

Bis morgen^^

von holger (Gast)


Lesenswert?

>unsigned char SD_Command(unsigned char cmd, unsigend long arg)

Was ist ein "unsigend long" ?
Dein Compiler übersetzt das sicher nicht ;)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

CMD1 wird von SD-Karten aber gar nicht verwendet - zumindest nicht für 
die Init. Dazu braucht es CMD8 und ACMD41. Siehe Simplified SD-Card 
Specification.

von Markus .. (made-huk83)


Lesenswert?

Travel Rec. wrote:
> CMD1 wird von SD-Karten aber gar nicht verwendet - zumindest nicht für
> die Init. Dazu braucht es CMD8 und ACMD41. Siehe Simplified SD-Card
> Specification.

Das ist so nicht ganz richtig. CMD1 wird von allen MMCs und allen 
"dicken" SD-Karten unterstützt. Für die "dünnen" (1.4mm) ist CMD1 ein 
illegales Kommando! Wenn man erstmal den einfachen Weg gehen möchte, ist 
es in den meisten Fällen OK CMD1 zu benutzen.
Sobald aber eine Unterscheidung der Kartentypen erfolgen soll, muss man 
für SD-Karten ACMD41 benutzen. Hier muss vorher jedoch noch das CMD55 
gesendet werden, um auf das "Anwendungsspezifische"-Kommando zugreifen 
zu können.
CMD8 ist nur für die Initialisierung von SDHC-Karten relevant.


Gruß
Markus

von holger (Gast)


Lesenswert?

@ Travel Rec.
>CMD1 wird von SD-Karten aber gar nicht verwendet

Das ist falsch. Ältere SD Karten nehmen CMD1 durchaus.
CMD8 mögen die älteren auch nicht. Das geht erst ab
SD Spec. V2.00. Es ist aber immer einen Versuch wert
erstmal ACMD41 statt CMD1 bei SD Karten zu nehmen.
Da stimme ich mit dir überein.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Na okay, ich kann nur von eigenen Erfahrungen berichten. Alle Karten, 
die bei mir herumliegen, waren CMD1 gegenüber etwas zurückhaltend. CMD8 
habe ich zur Differenzierung eingefügt, bislang gibt es auch darauf nur 
ein "illegal" zurück. Mit ACMD41 ließen sich alle initialisieren. Die 
Karten stammen aus 2003-2006, HC-SD habe ich nicht mit dabei.

von Oli (Gast)


Lesenswert?

>Was ist ein "unsigend long" ?
>Dein Compiler übersetzt das sicher nicht ;)

Wiso? Würde er dann nicht meckern?
ich habe doch
1
#include <stdint.h>
  eingebunden...

von Oli (Gast)


Lesenswert?

War ja klar, dass ich schon vor dem nächsten Problem stehe...
Will das CID Register auslesen. Schicke das richtige CMD, die SD Karte 
antwortet auch mit 0xFF und müsste dann 0xFE (STARTBLOCK_READ) senden...
1
 while(SPI_Transfer_Byte(0xFF)!= STARTBLOCK_READ);

Ich trau ja meinen C-Künsten mittlerweile und auch meinem ATmega ^^
Nur die SD-Karten sind mir suspekt...
Kann es sein dass sich das CID Register manchmal nicht auslesen lässt??

Danke schon mal...

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Angehängte Dateien:

Lesenswert?

Nein, das läßt sich immer auslesen. Da hast Du bestimmt irgendetwas 
übersehen. Ich lege Dir oben aufgeführtes Dokument an´s Herz.

>Schicke das richtige CMD, die SD Karte
>antwortet auch mit 0xFF

0xFF ist keine Antwort sondern der Hinweis, daß die Karte noch nicht 
fertig ist mit Datenschaufeln. Du mußt solange weiterclocken, bis 0xFE 
kommt. Das kann, je nach Karte, schon ein paar Bytes dauern.

von Oli (Gast)


Lesenswert?

Danke!
Klappt jetzt:)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Na siehste :-)

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.