Hallo,
ich bin gerade dabei einen eigenen Treiber für das SDIO Modul des
STM32F4 zu schreiben.
Ich habe eine Frage zu den Multiple Block Operationen (Read/Write).
Laut Spec, muss ich am Ende der Sequenz CMD12 (Stop transmission)
senden, um die operation sauber zu beenden.
Ich habe mir einige Codes angeschaut, auch von einem LPC1788 mit
ähnlichem Interface.
Dort wird zum lesen nur das Kommando für Multi-Block-Read gesendet und
dann empfangen. Es wird nie ein Stop Kommando gesendet.
Da ich im SDIO Modul die Länge der Übertragung angeben kann, wäre eine
Möglichkeit, dass der SDIO Controller eine Art Token sendet, dass der SD
Karte anzeigt, dass die notwendige Anzahl an Blöcken übertragen wurde.
Leider finde ich im Reference Manual des Controllers und auch in der
Spec der SD Karte so etwas nicht für SDIO, nur SPI.
Wie implementiert man diese Multi-Block Zugriffe richtig?
Muss ich ein Stop Command (CMD12) senden?
Vielen Dank
M. H. schrieb:> Dort wird zum lesen nur das Kommando für Multi-Block-Read gesendet und> dann empfangen. Es wird nie ein Stop Kommando gesendet.
Simplfied Spec 4.14.5 sagt: CMD23 kann als Stop Ersatz benutzt werden,
d.h. vor dem Lese/Schreib Kommando wird die Block Anzahl gesetzt. Das
Kommando ist optional, dürfte aber von modernen Karten implementiert
werden.
Jim M. schrieb:> Simplfied Spec 4.14.5 sagt: CMD23 kann als Stop Ersatz benutzt werden,> d.h. vor dem Lese/Schreib Kommando wird die Block Anzahl gesetzt. Das> Kommando ist optional, dürfte aber von modernen Karten implementiert> werden.
Ja. Das habe ich auch gelesen. Leider wird das Kommando nicht verwendet.
Das hier ist der source Code:
https://www.lpcware.com/system/files/lpc177x_8x_mci.c
Das ist die Funktion zum Lesen eines Blocks.
Es wird lediglich der DMA initialisiert, der die Daten automatisch vom
SDIO-FIFO in den RAM kopiert, und über eine weitere Funktion das
Kommando an die SD Karte gesendet. Die MCI_Cmd_ReadBlock(blockNum,
numOfBlock) Funktion evaluiert lediglich, ob 1 Block oder mehrere
gelesen werden sollen und setzt das Kommando und die parameter richtig.
Nichts mit CMD23...
Übersehe ich etwas?
Mir ist nicht klar, wie diese Implementierung funktioniert/funktionieren
kann.
Angesichts diverser Leerschleifen, die moderne Compiler wegoptimieren:
1
for(i=0;i<0x10;i++);
würde ich von oben gepostetem Code nix halten. Ich denke der
funktioniert nur wenn jeweils ein einzelner Block gelesen oder
geschrieben wird - was übrigens gängige FAT Implementationen genau so
machen, solange man nicht viele Daten am Stück schreibt.
Wäre nich das erste Mal das NXP Code nicht tut...
M. H. schrieb:> Mir ist nicht klar, wie diese Implementierung funktioniert/funktionieren> kann.
Er schmeisst DMA an und jagt dann das Lesekommando raus.
Das "Stop Transmission" müsste dann irgendwie hinterher erfolgen,
wenn der DMA Transfer abgeschlossen ist.
Siehe: https://www.lpcware.com/system/files/Mci_ReadWrite.c
Jim M. schrieb:> Das "Stop Transmission" müsste dann irgendwie hinterher erfolgen,> wenn der DMA Transfer abgeschlossen ist.
Ja. Das macht Sinn.
Wäre es möglich bei der Initilisierung der Karte das CMD23 zu senden und
zu schauen, ob ein INVALID_CMD Error auftritt, um zu überprüfen, ob die
Karte dieses Kommando unterstützt?
Sollte ja keinen Einfluss auf die nachfolgenden Befehle haben, solange
die Karte bereits vollständig initialisiert ist und vor einer Multi
Block Operation das Kommando erneut gesendet wird.
M. H. schrieb:> Wäre es möglich bei der Initilisierung der Karte das CMD23 zu senden und> zu schauen, ob ein INVALID_CMD Error auftritt, um zu überprüfen, ob die> Karte dieses Kommando unterstützt?
Es gibt sogar ein Kommando mit dem man abfragen kann welche Kommandos
unterstützt werden, ich weiß gerade nur nicht mehr genau welches (22
oder 42?).
Oh, es war ACMD51. Dies liest das SCR Register aus, welches die "Command
Support Bits" (CMD_SUPPORT) enthält. Wenn Bit 33 gesetzt ist, wird CMD23
unterstützt (siehe S. 128 in den SD Simplified Specifications). SDSC
Karten (bis 2 GB) unterstützen CMD23 grundsätzlich nicht. Es ist aber
auch kein Problem, CMD12 zu senden wenn der DMA fertig ist. Die nach der
Beendigung des DMA-Transfers, und vor der Ankunft von CMD12 gesendeten
Datenblöcke werden einfach ignoriert und stören nicht.
Okay. Danke
Dann weiß ich jetzt, wie ich das mache.
Eine Frage hab ich noch:
Und zwar bezüglich des Card Status, der in der R1 Antwort zurückkommt.
Wann bzw. wodurch werden etwaige Fehlerflags gelöscht?
Werden diese gelöscht, durch reines Auslesen, oder sobald ein weiteres
Kommando gesendet wird und sich der Status somit ändert?