Probleme beim Lesen der Delkin Micro SD 16 GB mit SPI

Ich arbeite seit einiger Zeit mit SD-Karten und Micro-SD-Karten.

Ich verwende Part1_Physical_Layer_Simplified_Specification_Ver6.00 als Referenz.

Ich kann eine erfolgreiche Karteninitialisierung durchführen, lesen und schreiben für andere Micro-SDs wie ATP 8 GB SLC, Panasonic 8 GB SLC usw. Wenn ich jedoch Delkin 16 GB SLC (und auch Swissbit 8 GB SLC) verwende, bin ich bei der Karteninitialisierung erfolgreich und schreiben, wenn ich versuche zu lesen, bekomme ich kein Startblock-Token 0xFE und es gibt ungefähr 512 Bytes Junk-Daten, bevor es wieder normal wird.

Das Muster ist wie folgt (unter Verwendung des Beagle SPI-Analysators):

Nach dem Schreiben des Folgenden (nur die ersten 24 Bytes werden angezeigt, aber das Muster ist dasselbe):

Geben Sie hier die Bildbeschreibung ein

Wenn ich 0xA0 schreibe. Bitte beachten Sie das folgende Bild:

Geben Sie hier die Bildbeschreibung ein

Wenn ich die geschriebenen Bytes ändere, werden auch die gelesenen Bytes geändert, und es besteht auch eine Eins-zu-Eins-Entsprechung zwischen den geschriebenen und den gelesenen Bytes. Aber die Bytes sind nicht gleich.

Ich verifiziere, dass die Daten erfolgreich mit dem SD-Kartenleser mit HxD-Hex-Viewer geschrieben wurden.

Für den ersten Fall:

Geben Sie hier die Bildbeschreibung ein

Für den zweiten Fall:

Geben Sie hier die Bildbeschreibung ein

Es scheint nicht so, als würde die Spannung zur SD-Karte variieren, da ich sie auf dem Oszilloskop überprüft habe und sie während des Lesens 3,3 Volt beträgt.

Als Mikrocontroller verwende ich F28377s Launchpad von TI.

Ich möchte die Inputs von Ihnen erhalten. Was genau kann ich versuchen, um dieses Problem zu beheben?

Edit1: Genau das gleiche Verhalten wird für Swissbit 8 GB SLC beobachtet. Die gleichen Bilder oben können auf Swissbit angewendet werden. Die für Swissbit gelesenen Daten sind die gleichen wie bei Delkin. Der SPI-Takt beträgt vor der Initialisierung 200 kHz und wird nach der Initialisierung auf 1 MHz geändert.

Edit2: Bitte schauen Sie sich die Oszilloskopbilder unten an (ich habe die Taktfrequenz auf 225 KHz geändert):

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Edit3: Das zweite Oszilloskopbild folgt unmittelbar auf das erste Oszilloskopbild. Das erste Bild ist der Lesebefehl und die Antwort, während das zweite Bild 0xFF sendet und auf das Startdatenblock-Token wartet, das im zweiten Bild 0xA8 ist, da 0xFE um 2 Bits bitverschoben ist. Sie können sich die dekodierten Hex-Daten des Oszilloskops unten in den Oszilloskopbildern ansehen. Sie sind die gleichen wie meine Beagle SPI Analyzer Debug Data für Beispiel 2 (wo ich 0xA0 schreibe und 0x28 zurücklese).

Edit4: Gemäß dem Vorschlag von Anonymous habe ich meinen Code so aktualisiert, dass ich vor jedem Befehl und nach CS LOW 8 Takte vor jeder tatsächlich beabsichtigten SPI-Übertragung sende. Nach Abschluss der Befehlsantwort sende ich 8 Taktzyklen unmittelbar vor CS HIGH und 8 Taktzyklen unmittelbar nach CS HIGH. Der Abschluss der Befehlsantwort im SD-Lesefall bedeutet, wenn wir das letzte CRC-Byte empfangen haben. Der Abschluss der Befehlsantwort in SD Write bedeutet, dass die Karte nach dem Schreiben aufhört, das Besetztsignal zu senden. Ähnlich habe ich es auch auf andere Befehle angewendet. Außerdem mache ich CS HIGH erst, wenn der Befehl und seine Antwort abgeschlossen sind. Zum Beispiel mache ich im SD-Lesefall CS LOW und sende den Befehl, erhalte die Befehlsantwort, erhalte das Startblock-Token (0xFE), erhalte den CRC und dann mache ich den CS HIGH.

Danke.

Antworten (1)

Ich denke, Sie sollten das Muster bemerkt haben:

fe 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00 01 02 03 ...

Wenn Sie diese Sequenz um zwei Bits nach rechts verschieben, erhalten Sie

ff 80 00 40 80 c1 01 41 81 ...

Also genau die Reihenfolge, die Sie haben. Sie haben dem Stream zwei freie Bits hinzugefügt, und Bytes wurden falsch ausgerichtet. Warum? Ohne genaue Diagramme, die die Uhr zeigen, ist es nicht möglich zu sagen. Höchstwahrscheinlich haben Sie Probleme mit der Uhrzeit- oder Datensynchronisation.

Diese Fehlausrichtung kann sowohl beim Schreiben als auch beim Lesen auftreten. Es kann also so aussehen, als ob Sie eine falsche Sequenz schreiben, weil bei Ihrem Schreibbefehl Bytes falsch ausgerichtet sind, und diese falsche Sequenz dann (natürlich) zurücklesen, oder es könnte sich um ein reines Lesebefehlsproblem handeln. Die Schlussfolgerung, dass Sie überprüfen müssen , welche SD-Karte tatsächlich darauf geschrieben wurde – mit einem anderen funktionierenden Gerät (z. B. PC, der Ihre Karte in die Datei ausgibt und das Image überprüft) – bevor Sie mit der Ausführung von Lese- oder Schreibbefehlen debuggen.

Bearbeiten: Wenn ich mir die Scope-Diagramme ansehe, sehe/empfehle ich Folgendes:

  1. Ändern Sie die Taktpolarität im Leerlauf auf niedrig. Aktuell ist es hoch. Überprüfen Sie hier . Mit anderen Worten - verwenden Sie den SPI-Modus 0;
  2. Führen Sie vor dem Befehlsstart (bevor Sie die erste 0 auf die MOSI-Leitung setzen) 8 Ersatztaktzyklen mit CS Low durch. Idealerweise tun Sie dasselbe am Ende des Befehls - setzen Sie 8 Ersatztakte mit CS auf Low, wenn der Befehl abgeschlossen ist, und weitere 8 Ersatztakte mit CS auf High;
  3. Ich bin mir nicht sicher, ob ich das zweite Bild verstehe - Sie senden FFs als Befehl an die Karte? Und anscheinend meldet die Karte ständig 0x05 (ungültiger Befehl).

Bearbeiten 2:

Das zweite Oszilloskopbild folgt unmittelbar auf das erste Oszilloskopbild.

Seien Sie sehr vorsichtig, wenn Sie die Karte abwählen - Ihre Bilder zeigen, dass Sie Befehle an die Karte erteilen, sie abwählen, CS hoch heben, und sie dann erneut auswählen und kontinuierlich 0xFFs an die Karte senden. Anscheinend versteht die Karte das nicht und sendet 0x28s zurück, die eigentlich 0x05 sind - R1-Antwort "ungültiger Befehl" verschoben. Es gibt nur bestimmte Umstände, unter denen Sie die Karte abwählen können, dies wird in der vereinfachten SD-Spezifikation erklärt und folgt einem sehr spezifischen Protokoll:

Wenn die Karte besetzt signalisiert, kann der Host sie jederzeit abwählen (durch Erhöhen des CS). Die Karte gibt die DataOut-Leitung einen Takt nach dem Hochgehen des CS frei. Um zu prüfen, ob die Karte immer noch beschäftigt ist, muss sie erneut ausgewählt werden, indem das CS-Signal aktiviert (auf niedrig gesetzt) ​​wird. Die Karte wird einen Takt nach der abfallenden Flanke von CS das Belegtsignal wieder aufnehmen (DataOut auf Low ziehen).

Zu meinem zweiten Kommentar

Auch Ihr Kommentar 2, ist es für alle Befehle erforderlich? Derzeit habe ich Ihren Vorschlag nur auf Read Command angewendet.

Ersatzzyklen werden zwar einige Zeit in Anspruch nehmen, stellen jedoch sicher, dass die Karte den vorherigen Vorgang ordnungsgemäß abgeschlossen/abgebrochen hat und sich für den nächsten bereit macht. Daher empfehle ich Ihnen, es nach Möglichkeit für alle Befehle zu implementieren.

Hallo Anonym, danke für deine Antwort. Bitte schauen Sie sich das vorletzte Bild an. Ich habe dort gezeigt, dass ich die SD-Kartendaten manuell von einem SD-Kartenleser am PC mit HxD-Hex-Viewer auslese. Und es bestätigt, dass mein Schreiben erfolgreich war. Die Sache mit der Bitverschiebung beim Lesen ist mir auch aufgefallen und macht Sinn. Ich werde am Montag Oszilloskopbilder machen und sie auch hier anhängen. Aber als ich das letzte Mal die Oszilloskopsignale gesehen habe, zeigen sie auch die Bitverschiebung, von der Sie sprechen. Ich bekomme jedoch immer noch nicht das Startblock-Token 0xFE von der Karte, was mir Sorgen bereitet.
Sie erhalten das Token, aber es ist um zwei Bits nach rechts verschoben - und ff feSie erhalten somit statt dessenff ff 80
Danke Anonym ... Ich verstehe, wie beide Fälle um zwei Bits nach rechts verschoben werden. Gibt es einen bestimmten Grund, warum das Schreiben kein Problem hat, aber das Lesen um zwei Bits verschoben wird?
Wie ich bereits sagte, sind Scope-Diagramme mit Daten- und Taktsignalen erforderlich, um sie zu sehen. Es muss ein Problem mit der Uhr-/Datensynchronisierung geben.
Hi Anonymous...Ich habe die Oszilloskopbilder in Edit2 hinzugefügt. Bitte guck dir das an.
Antwort aktualisiert.
Hallo Anonymous, "bevor der Befehl startet (bevor Sie die erste 0 auf die MOSI-Leitung setzen) führen Sie 8 Ersatztaktzyklen mit CS Low durch" hat das Problem gelöst. Ich bin mir nicht sicher, ob ich es übersehen habe, aber wird es in Part1_Physical_Layer_Simplified_Specification_Ver6.00 erwähnt? Auch Ihr Kommentar 2, ist es für alle Befehle erforderlich? Derzeit habe ich Ihren Vorschlag nur auf Read Command angewendet. Bei allen anderen Befehlen sende ich vor CS Low (vor dem Senden von cmd) 8 Takte und nach CS High (nach der Antwort) sende ich 8 Takte. Zu Ihrem Kommentar 3 sehen Sie sich bitte die Bearbeitung an.
Antwort aktualisiert
Bitte beachten Sie edit4, ich habe Ihren Vorschlag aufgenommen, es funktioniert gut für alle verschiedenen SD-Karten, die ich habe.