Hallo!
Ich habe ein Problem mit der ansteuerung der MMC. Wenn vielleicht mal
jemand einen Blick in den Code werfen könnte.
Die Karte ist am SPI des AtMega8 angehängt, die beschaktung sollte
eigentlich korrekt sein (ich komme darauf, weil ich ja eine Antwort
erhalte). Es sollte also am Programm liegen.
Wenn ich cmd0 sende, dann bekomme ich als Antwort 0x00, anstatt 0x01,
dass sie sich jetzt im idle state befindet. Wenn ich nochmals cmd0
sende, dann erhalte ich immer 0x05 (illegal command und in idle state),
egal wie oft ich cmd0 sende.
Ich hab dann mal versucht cmd1 zu senden, aber natürlich kommt auch da
nichts gescheites raus. Wenn ich sie doch nur mal initialisieren könnte
wäre ich schon superhappy.
Mein avr läuft mit 1 Mhz, und die SPI habe ich mit 128 vorteiler am
laufen, also überrenne ich die MMC nicht, habe auch zu testzwecken
überall grosse Pausen eingebaut - vergebens.
Wenn jemand in den Code schaut und nicht gleich wieder wegklickt, weil
so scheusslich, wäre ich sehr dankbar
Gruss
Hallo!
Ohne jetzt deinen Code genauer angeschaut zu haben, eine paar
Anmerkungen zur Init.
Du solltest die SPI-Frequenz auf max 400KHz einstellen. Dies gult nur
für die Initialisierungsphase.
Gibt der Karte etwas Zeit zum "Starten".
Schick ihr danach für mindestens 74cycles ein "High".
Schicke das CMD0 (0x40,0x00,0x00,0x00,0x00,0x95)
Warte einige Zeit auf eine gültige Antwort (falls in dieser Zeit keine
Antwort kommt, abbrechen)
->>>Schicke danach sooft das CMD1 (0x41,0x00,0x00,0x00,0x00,0xff) bis du
eine gültige Antwort bekommst. Auch hier empfehle ich nach einiger Zeit
ohne gültige Antwort abzubrechen). Gerade beim CMD1 braucht die Karte
eine längere Zeit.
Check mal die Dinge ab und meld dich bei Fragen.
Hias
P.S.: Dein Code ist, wie du schon gesagt hast nicht sehr einladend.
Vielleicht kannst du die Lesbarkeit etwas verbessern. (Nicht böse
gemeint :) )
EDIT: Hab doch mal schnell deinen Code überflogen. Die mit ->>>>>
gekenntzeichnete Stelle könnte dein Problem sein. Du sendest nämlich nur
einmal das CMD.
Ich glaube ich habe fast alles so wie du das beschrieben hast (ausser
der Lesbarkeit des Codes)...
Was ich anders habe als du vorgeschlagen: ich sende als CRC am Schluss
von CMD1 nicht 0xff sondern 0x95, aber das sollte keine Rolle spielen,
da CRC deaktiviert und nur das letzte Bit eine 1 sein muss, der Rest
dieses Bytes kommt ja, nachdem man in den SPI-Mode gewechselt hat, nicht
mehr drauf an (wenn man CRC nicht wieder reaktiviert).
Welche Stelle im Code meinst du mit '->>>>>'? Kann sie nirgends
finden...
Gruss und dake fürs Code ansehen
Hi!
Mit dem '->>>>>' hab ich in meinem Post das gemeint:
->>>Schicke danach sooft das CMD1 (0x41,0x00,0x00,0x00,0x00,0xff) bis du
eine gültige Antwort bekommst. Auch hier empfehle ich nach einiger Zeit
ohne gültige Antwort abzubrechen). Gerade beim CMD1 braucht die Karte
eine längere Zeit.
Du schickst soweit ich dass auf die schnelle erkennen konnte nur einmal
das CMD 1 und wartest dann auf die Antwort.
Probier mal das CMD1 sooft zu senden bis du eine gültige Antwort hast.
hias
Sorry hab da nicht genau genug hingeschaut!
Noch was ist mir aufgefallen.
Bevor man der MMC Karte ein Commando schickt sollte man.
Ein paar Bits senden, wenn die Karte noch deaktiviert ist.
Ich sende ein Byte (0xff) bevor ich CS auf low ziehe.
Vielleicht bringt ja das was.
Hias
Hallo Philipp, hallo Hias
Erstmal Danke für eure Bemühungen...
@Philipp: Ich hab das mit CPOL und CPHA zusetzen nicht versucht, weil
der Mode0 eigentlich stimmen sollte. (siehe
http://elm-chan.org/docs/mmc/mmc_e.html)
@Hias: Das mache ich bereits, siehe:
//mind. 74 clock cycles und DI high
ldi temp1, 20
ldi arg0, 0xff
weiter_machen:
out SPDR, arg0
wait
dec temp1
brne weiter_machen
Ja ich mein was anderes.
Deine Funktion Befehl senden schaut so aus:
CS Low
6Bytes Befehl senden
auf Antwort warten.
Ich hab gemeint du sollst hier noch folgendes machen:
0xFF senden (1x reicht)
CS Low
6Bytes Befehl senden
auf Antwort warten
Das einfach mal in deine cmd_send Funktion einbauen und testen.
ldi temp1, 0xff
out SPDR, temp1
Hias
Hallo, danke für deine Bemühungen. Habe das mal eingebaut... Jetzt
bekomme ich nicht mehr die selben Antowrten, aber immer noch nicht das
was ich erwarte.
Ich bin nun wieder auf der Suche auf der Hardwareseite, weil mich die
antworten die ich empfange plötzlich zufällig erscheinen. Ich habe die
Anbindung an den ATmega ähnlich wie bei Ulrich Radig, er hat die DO
leitung welche die Daten zurück zum AVR bringen sollte ohne irgendwelche
Pullups, könnte da ein Fehler sein? Ich nehme mal an, dass er die
internen Pullups nicht eingeschltet hat, denn sonst würde ja 5V da
anliegen, das hätte wohl ein schlechtes Ende.
übrigens die MMC lebt noch, das habe ich mit einem Kartenleser
überprüft....
Hallo!
DO heißt nichts anderes als DataOut aus der Sicht der MMC.
Das heißt ein high bedeutet hier einen Pegel von 3,3V. Dein Atmel
versteht aber auch die 3,3V als high. Des passt also so.
Hast du vielleicht vergessen, den DO_Pin am Atmel (aus der Sicht des
Atmel also als Data in) als Eingang zu definieren?
ldi temp1, 0b11111111 //PORTB (cs) auf output
out DDRB, temp1
Du legt nämlich den ganzen PortB als Ausgang fest.
Hias
Die Frage ist halt ob die MMC auch wirklich 3.3V rausschickt, oder ob
sie einfach bei low gegen Masse schaltet und bei High "loslässt" und
wenns nicht hoch gezogen wird dann macht der Pegel irgendwas.
Eigentlich sollte doch durch einschalten des SPI dieser Pin richtig
eingerichtet werden (also als Eingang)?!?
Ste wrote:
> Die Frage ist halt ob die MMC auch wirklich 3.3V rausschickt, oder ob> sie einfach bei low gegen Masse schaltet und bei High "loslässt" und> wenns nicht hoch gezogen wird dann macht der Pegel irgendwas.
Soweit ich weiß ist der Dataout der MMC ein PushPull Ausgang, es werden
also die Pegel nahe an 0V und der Versorgungsspannung der MMC sein.
> Eigentlich sollte doch durch einschalten des SPI dieser Pin richtig> eingerichtet werden (also als Eingang)?!?
Dabei bin ich mir nicht so sicher. Das lässt sich aber einfach testen,
durch ausprobieren :).
Hias
Hallo!
Mit einem Pullup gegen die Betriebsspannung und mit deinem Trick mit dem
zuerst ein Byte senden scheint es nun tatsächlich zu funktionieren, aber
weshalb zuerst ein Byte schicken, bevor man cs low zieht? Muss er erst
warm laufen? Woher weisst du das? Durch raten? Ich habe das Datenblatt
einer MMC angeschaut und dort nichts gefunden....
Danke erst mal!!
Hi,
im DB der MMCs ist das irgendwo in einem Timing-Diagramm aufgeführt. Du
kannst das Byte auch nach dem Command übertragen, spielt AFAIK keine
Rolle. Hast du's denn jetzt nochmal ohne des probiert?
Ja, wenn ich es vor dem cs low weglasse gehts nicht mehr, hinterher
senden (nach dem cs wieder high??) habe ich noch nicht probiert, werde
ich aber noch tun und berichten, aber hauptsache es funktioniert jetzt
mal, danke danke danke....
Hallo!
Ja steht im Datenblatt, z.B. in dem von Ulrich Radigs Seite. (Ab Seite
72)
Da wird CS aber auf low gezogen und dann die 8 bit gesendet. Bei mir war
das anderes rum. Scheint in der Praxis egal zu sein.
Ich denke das ganze wird benutzt um die MMC auf das Empfangen
vorzubereiten.
Ach ja, hast du jetzt den MISO Pin als Eingang deklariert?
Oder nur einen Pull-Up eingebaut?
Hias
Ah, ok danke, da steht auch, dass es nach einem Befehl gesendet werden
muss, ob cs low oder high spielt auch keine Rolle...
Nein, ich habe ihn nicht als Input definiert, auf Seite 57 im AtMega8
Datenblatt steht, dass wenn SPI als Master aktiviert wird, dass dann
egal was in DDRB eingestellt wurde automatisch MISO als Input verwendet
wird.
Hingegen einen Pullup ist nun drin.
Also Danke nochmals an alle Helfer...
Gruss