www.mikrocontroller.net

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


Autor: Markus ... (made-huk83)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: embedded-os (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Markus ... (made-huk83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus ... (made-huk83)
Datum:

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

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird eigentlich schon mehrmals gesendet: Hier mal der Teil meines Codes:


unsigend char SPI_Transfer_Byte(unsigned char data)
{
unsigned char received=0;

SPDR =data;
while(!(SPSR&(1<<SPIF)));
received=PSDR;
return(received);
}



unsigend char SD_Reset(void)
{

PORTB|=(1<<SPI_CS);  //setzt CS high
unsigned char i;
unsigend char retry;
unsigned char r1=0;

do
{
   for(i=0;i<10;i++) SPI_Transfer:Byte(0xFF); //sendet dummy bytes

  r1 = SD_Send_Command(SD_GO_IDLE_STATE,0);  //sende CMD0
  retry++;
  if(retry>10){return -1;}
}
while(r1 != SD_R1_IN_IDLE_STATE);  // 0x01
 

//.....weiter komm ich gar nicht



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

PORTB &=~(1<<SPI_CS)  //CS low

unsigend char r1;
unsigend char retry=0;


SPI_Transfer_Byte(cmd|0x40);
SPI_Transfer_Byte(arg<<24);
SPI_Transfer_Byte(arg<<16);
SPI_Transfer_Byte(arg<<8);
SPI_Transfer_Byte(arg);
SPI_Transfer_Byte(0x95);   //CRC



// hier hängt das Programm


while( (r1=SPI_Transfer_Byte(0xFF)) ==0xFF)  

if(retry++>8){break;}

PORTB |=(1<<SPI_CS); // CS high

return r1;
}





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!

Autor: Markus ... (made-huk83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oli (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Oli (Gast)
Datum:
Angehängte Dateien:

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

Autor: Pete K. (pete77)
Datum:

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

Autor: dummy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oli (Gast)
Datum:

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

Meine SD Karte antwortet einfach zu langsam....

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Pete K. (pete77)
Datum:

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

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhh, irgendwie will das ganze doch nicht.
Bin mir zwar ziemlich sicher, dass Softwaremäßig alles stimmt, hier aber 
nochmal mein Code:


SD_Reset(void)
{
do
{
  for(i=0;i<10;i++)  SPI_Transfer_Byte(0xFF); //10 dummy bytes 0xFF

  r1= SD_Send_Command(SD_GO_IDLE_STATE,0);  //send CMD0 //r1= response

  if(retry++>200) {return-1;}
}
while(r1!=SD_R1_IN_IDLE_STATE);

//an dieser stelle befindet sich SD-Card IN IDLE STATE
retry=0;
do
{
   r1= SD_Send_Command(SD_SEND_OP_COND,0);

   if(retry++>100) {return-1;}
}
while(r1)   // also solange bis r1=0x00

//An dieser Stelle wäre SD_RESET ERFOLGREICH

//CRC OFF und SET BLOCKLEN kommen dann noch

}


//Die SD_Send_Command  function


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

PORTB &=~(1<<SPI_CS)  //CS low

unsigend char r1;
unsigend char retry=0;


SPI_Transfer_Byte(cmd|0x40);
SPI_Transfer_Byte(arg<<24);
SPI_Transfer_Byte(arg<<16);
SPI_Transfer_Byte(arg<<8);
SPI_Transfer_Byte(arg);
SPI_Transfer_Byte(0x95);   //CRC


while( (r1=SPI_Transfer_Byte(0xFF)) ==0xFF)  

if(retry++>8){break;}

PORTB |=(1<<SPI_CS); // CS high

return r1;
}




unsigned char SPI_transfer_Byte(unsigned char data)
{
unsigend char received=0;
SPDR=data;
while(!(SPSR&(1<<SPIF)));
received=PSDR;
return(received);
}




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....

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

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

Bis morgen^^

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>unsigned char SD_Command(unsigned char cmd, unsigend long arg)

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

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus ... (made-huk83)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oli (Gast)
Datum:

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

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

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...
 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...

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Oli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!
Klappt jetzt:)

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na siehste :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.