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
Versuch mal, bei der Initialisierung vom SPI entweder CPOL ODER CPHA zu setzen, möglicherweise hilft's. Oder war das nur für die SD-Karten?
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
Nö, das macht er schon richtig:
1 | //cmd1 senden bis ready |
2 | not_ready: |
3 | ldi temp1, 1 |
4 | rcall cmd_send |
5 | tst temp1 |
6 | brne not_ready |
7 | //READY!!! |
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.