SD-Karte an AVR idlet nur

Gast #1582620
Lesenswert?

Hallo zusammen,

seit Wochen versuche ich eine SD-Karte am AVR zum Laufen zu kriegen - 
ohne Erfolg. Die Eckdaten:
- ATmega8L, 8MHz
- AVR und Karte laufen mit 3,3V
- Hardware-SPI des AVR mit 125kHz (Vorteiler 64)

Das Problem: ACMD41 (aber genauso CMD1) zeigt keine Wirkung. Auch nach 
tausendfachem Aufruf bleibt die Karte hartnäckig im Idle-Modus. CMD0 
funktioniert, ebenso andere Befehle, die man im IDLE-Modus absetzen darf 
(CMD58 zum Beispiel). Ich habe 4 Karten von Kingston und SanDisk 
getestet. Abgesehen von einer MicroSD (die vermutlich kein SPI spricht) 
überall das gleiche Ergebnis.

Meine Vorgehensweise (siehe auch angehängter Code):
- MOSI, SS, SCK als Output konfigurieren, MISO als Input
- MOSI und SS auf high
- SPI an und Takt auf 125kHz
- 100ms warten
- 74+ Takte an Karte
- SS auf low
- CMD0 (0x40 0x00 0x00 0x00 0x00 0x95) auf's SPI
- Antwort abwarten (es kommt 0x01)
- SS auf high
- ein paar Takte senden
ACMD41-Schleife:
{
- SS auf low
- CMD55 (0x77 0x00 0x00 0x00 0x00 0x01) auf's SPI
- Antwort abwarten (es kommt 0x01)
- SS auf high
- ein paar Takte senden
- SS auf low
- ACMD41 (0x69 0x00 0x00 0x00 0x00 0x01) auf's SPI
- Antwort abwarten (es kommt 0x01)
- SS auf high
- ein paar Takte senden
}

Vielleicht übersehe ich ja etwas, aber eigentlich müsste das mit der 
Spezifikation übereinstimmen, oder? Leichte Modifikationen, wie z.B. 
Einfügen oder Weglassen von kleinen Pausen oder 'Leertakten' zwischen 
den einzelnen Schritten bringen keine Änderung.

Natürlich habe ich das Forum durchsucht und gesehen, dass das Problem 
schon häufiger aufgetaucht ist. Die Lösung (wenn es denn eine gab) 
bestand meistens darin, Pegelwandler statt Dioden einzusetzen. Aber da 
mein AVR mit der Kartenspannung läuft, sollte bei mir das Problem nicht 
hier liegen, richtig?

Ein bisschen unsicher bin ich mir bei der aufgebauten Elektronik (bin 
eher in der Softwareecke zu Hause): Die Karte hat - um wackelige 
Kontakte zu vermeiden - einen Slot bekommen, Leitungslänge zum AVR <2cm. 
Die Energieversorgung überimmt ein LD1117V33 mit Kondensatoren wie im 
Datenblatt empfohlen. Mein (zugegeben rudimentäres) Messgerät zeigt 
3,34V.

Weiß jemand Rat? Oder hat jemand dasselbe Problem (und es womöglich 
gelöst)? Vielen Dank schonmal an alle Hilfswilligen!
Angehängte Dateien:
Gast #1582685
Lesenswert?

Das scheint ein schwieriger Fall zu sein.

Mir fällt bei Deiner Vorgehensweise nichts auf, was auf Probleme 
hindeuten
könnte (außer dem High-Setzen von SS nach den Kommandos, was überhaupt
nicht nötig ist).

Der Takt (125kHz) ist extrem niedrig, also hast Du damit auch keine
Fehlerquelle bei der Initialisierung.

Den Code habe ich mir nicht angesehen, ich habe mich darauf verlassen,
daß Du Deine Vorgehensweise 1:1 umgesetzt hast.

Vielleicht liegt der Fehler dort?
Gast #1582720
Lesenswert?

Danke für deine Antwort!

> (außer dem High-Setzen von SS nach den Kommandos, was überhaupt
> nicht nötig ist).
Ok, danke für die Info. Das war mir bislang nie so richtig klar (die 
Spezifikation sagt - glaube ich - hierzu nicht viel). Ich meine mal 
gelesen zu haben, dass man SS nach jeder Transaktion hochheben soll, 
habe aber vergessen wo das war und kann dementsprechend auch nicht 
sagen, ob es sich um eine ernst zu nehmende Quelle gehandelt hat.
Einen Unterschied in Bezug auf mein Problem macht es leider nicht.

> Der Takt (125kHz) ist extrem niedrig, also hast Du damit auch keine
> Fehlerquelle bei der Initialisierung.
Das war auch meine Hoffnung. Für die Datenübertragung wollte ich den 
Takt natürlich hochsetzen, aber so weit komme ich ja gar nicht.

> Den Code habe ich mir nicht angesehen, ich habe mich darauf verlassen,
> daß Du Deine Vorgehensweise 1:1 umgesetzt hast.
>
> Vielleicht liegt der Fehler dort?
Gut möglich. Ich bilde mir schon ein, dass der Code korrekt ist, aber 
nachdem ich jetzt tagelang draufgestarrt habe, kann es gut sein, dass 
mittlerweile eine gewisse Betriebsblindheit eingesetzt hat.

Dagegen spricht nur, dass der Radig-Code dasselbe Verhalten zeigt 
(mmc_init() liefert 2 zurück, d.h. die CMD1-Schleife wurde mit Timeout 
verlassen). Also vielleicht doch ein Hardware-Fehler? Allerdings 
funktionieren CMD0 und CMD58 problemlos...

Würde es helfen, wenn ich meine Schaltung poste? Habe noch nie in meinem 
Leben ein Schaltbild gezeichnet, aber versuchen könnte ich es...
Gast #1582729
Lesenswert?

>- AVR und Karte laufen mit 3,3V

Also wozu ein Schaltbild? Du benutzt ja keine Spannungsteiler, die als
Fehlerquellen in Frage kämen.

Außerdem empfängst Du ja eine R1-Antwort (01h) von der Karte, wenn Du
CMD0 gesendet hast.
Gast #1582762
Lesenswert?

Georg schrieb:
> Also wozu ein Schaltbild? Du benutzt ja keine Spannungsteiler, die als
> Fehlerquellen in Frage kämen.
Aus purer Verzweiflung :(
Weil mir inzwischen die Ideen ausgehen, was falsch sein könnte.

> Außerdem empfängst Du ja eine R1-Antwort (01h) von der Karte, wenn Du
> CMD0 gesendet hast.
Korrigiere mich, wenn ich falsch liege, aber könnte es nicht sein, dass 
die Karten im IDLE-Modus toleranter sind? Die Spezifikation sieht ja 
vor, dass man die Init-Sequenz bis CMD58 durchführt und die Karte dann 
ablehnt, falls man feststellt, dass die Spannung nicht passt. Wäre die 
Karte hierbei schon genauso empfindlich wie nachher im Betrieb, wäre 
dieser Hinweis doch überflüssig, oder?

Eigentlich glaube ich selbst nicht, dass es hieran liegt, aber wie du 
siehst greife ich nach jedem Strohhalm.
Gast #1582794
Lesenswert?

>Korrigiere mich, wenn ich falsch liege, aber könnte es nicht sein, dass
>die Karten im IDLE-Modus toleranter sind?

Leider nein.

>Die Spezifikation sieht ja vor, dass man die Init-Sequenz bis CMD58
>durchführt und die Karte dann ablehnt, falls man feststellt,
>dass die Spannung nicht passt.

Die Karten haben eine unglaubliche Spannungstoleranz: ich habe alles
mögliche versucht, um eine Karte in den Wahnsinn zu treiben, es ist mir
nicht gelungen: 1,8 bis 4,6V, kein Problem. Initialisierung mit 5MHz
SPI-Takt: ohne weiteres.
Gast #1582818
Lesenswert?

Ja, meistens. Ich habe eine Karte (Kingston, MicroSD, 2GB), die ab ca. 
4V anfängt Unsinn zu produzieren. Allerdings erst bei ACMD41. CMD0 und 
CMD58 klappen trotzdem. Kann aber sein, dass das einfach eine 
Montagskarte ist. Alle anderen, die ich getestet habe, sind tatsächlich 
sehr stabil in diesem Sinne.

Darf ich fragen, wie die Software aussieht, mit der du das hinkriegst?
Gast #1583957
Lesenswert?

Michael H. schrieb:
> pull-ups an den entsprechenden leitungen? MISO und MOSI heißen die bei
> euch wohl :)
Genau, so heißen sie.

Interne Pull-Ups sind an (in dem obigen Code nicht, aber es macht keinen 
Unterschied - hab's eben nochmal getestet).
Gast #1584045
Lesenswert?

>Ich würde an Deiner Stelle lieber die Finger stillhalten, wenn Du
>nichts Konstruktives beizutragen hast.
>
>Dämliche Kommentare sind hier fehl am Platz.

Buhaha. Das musst gerade du sagen;)

>Was hast Du denn für einen µController?
>Entschuldigung, steht ja oben.

Und jetzt schaust du dir den ersten Post noch mal
ganz genau an. Tip: Brille aufsetzen.
Gast #1584060
Lesenswert?

Um zum Thema zurückzukommen: Ich bin natürlich sehr froh um jeden, der 
Lust hat, mal in meinen Code reinzuschauen. Wer weiß was ich 
möglicherweise übersehen habe.

Hier nochmal eine leicht geänderte Version. Der Pull-Up ist jetzt ein 
und das CMD58 habe ich rausgeworfen, um die Sache kürzer und leichter 
lesbar zu machen.
Angehängte Dateien:
Gast #1584078
Lesenswert?

; Sendet einen 6-Byte-Befehl an die SD-Karte
; Eingabe in sd_reg1 bis sd_reg6, Ausgabe in sd_reg1
sd_send_cmd:
    ; 8 Takte senden
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
    ; SS auf low
    cbi    spi_port, spi_ss_bit
    nop
    nop

Nimm das hier mal raus
    ; 8 Takte senden
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
Gast #1584106
Lesenswert?

>Die Leertakte? Hab sie rausgenommen - leider kein Unterschied.

Was heißt leider? Du hast gerade festgestellt das die
überflüssig sind;)

Dann zu dem hier:

; Zieht nach dem Ende einer Transaktion CSS wieder hoch
; und gibt der Karte ein paar Takte zum Verschnaufen
sd_end_trans:
    ; 8 Takte senden
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
    ; SS auf high
    sbi    spi_port, spi_ss_bit
    nop
    nop
    ; 16 Takte senden
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
    ret

Reduzieren auf:

sd_end_trans:
    ; SS auf high
    sbi    spi_port, spi_ss_bit
    ret

Die 8 nötigen Dummyclocks bei CS High machst du schon vor dem
Kommando.
Gast #1584123
Lesenswert?

Und das:

    ; Auf Antwort warten, d.h. auf erstes Byte ungleich 0xff
  sd_send_cmd_loop:
    cpi    spi_reg, 0xff
    brne  sd_send_cmd_done
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
    rjmp  sd_send_cmd_loop

baust du mal um:

    ; Auf Antwort warten, d.h. auf erstes Byte ungleich 0xff
  sd_send_cmd_loop:
    ldi    spi_reg, 0xff
    rcall  spi_send_recv
    cpi    spi_reg, 0xff
    brne  sd_send_cmd_done
    rjmp  sd_send_cmd_loop
Gast #1584129
Lesenswert?

holger schrieb:
> Was heißt leider? Du hast gerade festgestellt das die
> überflüssig sind;)
So gesehen...auch wieder wahr.

> Die 8 nötigen Dummyclocks bei CS High machst du schon vor dem
> Kommando.
Korrekt. Habe alles rausgenommen, abgesehen von 8 Takten zwischen den 
Kommandos. Weiterhin keine Veränderung, sprich: aus dem IDLE-Mode wollen 
sie nicht raus.

Wenn ich die letzten 8 Takte auch noch sein lasse, meldet eine meiner 
Karten ein 'Illegal Command'. Was ja auch nicht ganz unerwartet ist.
Gast #1584156
Lesenswert?

holger schrieb:
> baust du mal um:
>
>     ; Auf Antwort warten, d.h. auf erstes Byte ungleich 0xff
>   sd_send_cmd_loop:
>     ldi    spi_reg, 0xff
>     rcall  spi_send_recv
>     cpi    spi_reg, 0xff
>     brne  sd_send_cmd_done
>     rjmp  sd_send_cmd_loop

Keinerlei Änderung. Ich habe mal mitzählen lassen: Nach Senden des 
CRC-Bytes eines Befehls kommen 2 0xff-Bytes und dann 0x01. 
Beziehungsweise 3 mal 0xff, wenn man das während des CRC-Sendens 
empfangene Byte mitzählt.
Gast #1585772
Lesenswert?

Nochmal vielen Dank, holger!

Das Problem ist zwar noch nicht gelöst, aber ich habe jetzt immerhin 
einige Ansätze.

Dein hex-File habe ich zum Anlass genommen zu lernen, was ein UART ist 
und habe selbigen auf dem STK500 zum Laufen bekommen. Außerdem habe ich 
herausgefunden, dass man die Versorgungsspannung des STK einstellen kann 
(erwähnte ich, dass ich Anfänger bin?) und einen SD-Kartenhalter so 
verlötet, dass ich ihn ans STK stecken kann. Und siehe da: Es 
funktioniert. Und zwar sowohl mit deinem Code als auch mit meinem.

Ich werde also als nächstes meine Schaltung unter die Lupe nehmen und 
versuchen, den Fehler dort zu finden.
Gast #1611169
Lesenswert?

Habe genau das identische Problem.
Hast du inzwischen herausbekommen, woran es lag?

@holger:
funktioniert dein Programm auch auf einem Atmega32?
Wäre nett wenn du es anpassen könntest.


Gruß
Richi
Gast #1611197
Lesenswert?

Ja, ich habs ja auch nur mit Software gemacht weils mit Hardware nicht 
ging. Ich hab eben auch alle möglichen Fehlerquellen überprüft.

Hardware-SPI ist kein Problem, ich meinte nur ob ich deinen HEX-Code 
auch auf meinen Atmega32 spielen kann?
Gast #1611326
Lesenswert?

>Nachdem ich die PullUps bei den ganzen Master-Ausgängen entfernt habe,
>geht zumindest eine Karte.

Wie, nur eine? Bei mir gehen alle. 10 verschiedene Karten
von 16MB bis 4GB SDHC.

>Woran könnte es liegen?

An deiner Hardware?
Gast #1611374
Lesenswert?

Ich wäre ja schon zufrieden, wenn mal eine Karte läuft!

Bei der Karte, die läuft, kommt folgende Ausgabe:

Send CMD0
CMD0 retrys 19
Send CMD8
CMD8 illegal command
Send CMD55 CMD55 illegal command
Send CMD1
Send CMD1
... (Ca 20x)
Send CMD1
Send CMD1
Send CMD1

CMD1 retrys 28
Read CSD
 0x00 0x26 0x00 0x7F 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF
CSD done
read_bl_len is 32768 !
CSD_STRUCT 0    SPEC_VERSION 0
MMC card
c_size 4095    c_size_mult 512
DriveSize 67108864 kB  maxsect 134217728
mmc_init() ok
Flash found


Ich weiß ja nicht ob das mit den illegalen Commands gut ist?

Woran soll es denn an meiner Hardware liegen?
Ich lass ja alles sauber über Pegelwandler etc. laufen.


Gruß
Richi
Gast #1611394
Lesenswert?

Hab jetzt dieselbe Karte nochmal ausgelesen:

Send CMD0
CMD0 retrys 17
Send CMD8
CMD8 illegal command
Send CMD55 CMD55 illegal command
Send CMD1
Send CMD1
Send CMD1
Send CMD1
CMD1 retrys 3
Read CSD


Wieso kommen jetzt andere Rückgabewerte?
Gast #1611409
Lesenswert?

>Ich weiß ja nicht ob das mit den illegalen Commands gut ist?

Das ist schon ok so. Wenn die Karte ein Kommando nicht
kennt wird halt erstmal mit anderen Kommandos weiter
versucht bis die Karte mal eins versteht.

Aber das hier kann irgendwie nicht sein:

>read_bl_len is 32768 !

Mehr als 2048 habe ich noch nicht gesehen.

>MMC card
>DriveSize 67108864 kB  maxsect 134217728

67GB MMC. Cool!

Deine Hardware ist irgendwie, wie soll ich es sagen, instabil?

>Woran soll es denn an meiner Hardware liegen?
>Ich lass ja alles sauber über Pegelwandler etc. laufen.

Wie sieht denn das Vogelnest aus? Mach mal ein Foto!
Gast #1611672
Lesenswert?

Ich hab gerade auch ein Problem mit SD-Karten.

Eine SanDisk Micro SD 2 GB antwortet auf CMD0 nur 0xFF.

Eine Kingston Micro SD 4 GB SDHC antwortet mit 0x01 - Das ist ja der 
korrekte Wert, den man da erwartet, oder?

Unterstützt die SanDisk Micro SD wirklich kein SPI mehr?

Gruß
Dennis
Gast #1612292
Lesenswert?

Hier das Foto, wems was hilft.

Hab jetzt auch die SD-Karte mal näher zum Microcontroller gebracht und, 
siehe da, Manchmal kommt sogar was sinnvolles raus.
Es ist also durchaus wahrscheinlich, dass es am Steckbrett liegt.
Aber warum?

Gruß
Richi
Angehängte Dateien:
Gast #1612608
Lesenswert?

>Wann muss man mit CMD1 und wann mit ACM... initialisieren?

Das hängt von deiner Karte ab. Sieh dir doch mal die
Ausgabe von meinem Programm an.

Fängt an mit CMD0. Das können sie alle.
SDHC oder SD V2.x brauchen dann erstmal CMD8.
Kennt die Karte CMD8 nicht dann erstmal mit CMD55 + ACMD41
probieren. Kennt die Karte CMD55 nicht dann CMD1 nehmen.
Das wars im groben;)
Gast #1612670
Lesenswert?

aha, aber bei mir steht bei deinem Init-Programm nicht immer 0.
Aber es stimmen alle Werte.

Mit Ulrich Radigs Code funktioniert das Schreiben nun Wunderbar.

Ich werde mir mal die Fehlercodes anschauen (sind doch im R1 Format)
Gast #1612705
Lesenswert?

>aha, aber bei mir steht bei deinem Init-Programm nicht immer 0.

An welcher Stelle?
Mein Programm gibt den Wert doch gar nicht aus!?

>Aber es stimmen alle Werte.

Macht man es richtig funktionierts;)
Gast #1612771
Lesenswert?

Doch, z.B kommt Sende CMD0, Retry 0

Die werte stimmen, aber aufgrund der falschen Retry-Werte beim ACMD41 
kommt immer no-Flash.

Aber es geht jetzt ja also ist es ja nicht so schlimm!!!


Viele Grüße
Richi

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren