Hallo Leute!
Das Wichtigste vorweg: Multiple Block Write gelingt sehr gut und ich
bekomme sagenhafte 2.5 MBytes/s! Ich tickse das FAT-System aus, indem
ich die leere Karte mit grösseren ebenfalls leeren Dateien fülle und mit
dem Startsektor der ersten Datei beginne. Mein Chip ist PIC24Hxxxx.
Was nicht geht, ist, den Datentransfer zu stoppen, ohne ohne die
Brechstange zu verwenden, sprich die Karte neu initialisieren zu müssen.
Irgendwie will die Karte weder STOP_TRANS_TOKEN (0xFD) noch CMD12
fressen. Ich wüsste auch nicht, welchen Responce zu erwarten, wenn sie
es fressen würde.
In so mancher Dokumentation steht geschrieben, dass STOP_TRANS_TOKEN für
SPI-Modus angedacht, während CMD12 für dem SD-Modus bestimmt ist. Die
anderen unterscheiden gar nicht dazwischen.
Ähm... ja...
Gruss
Dimitri
Hallo,
ich mache das bei Multiblock so wie in der Spezifikation, und das
klappt, wenn die Karte das halt unterstützt.
Erstmal muss das block alligned sein. Also nur nach einem 512 Byte block
klappt das.
Dann wie folgt:
In der ersten for-Schleife starte in den DMA-Transfer für SPI. Ich
schicke 1 + 512 + 2 Bytes, wobei das erste Byte
DATA_START_MULTIBLOCK_TOKEN ist, gefolgt von 512 Bytes Daten und 2 Bytes
Pseudo-CRC. Danach wird DMA deaktiviert, damit ich SPI wieder manuell
ansteuert kann. Ich sende eine Anfrage, ob meine Daten akzeptiert
wurden, und bekomme eine saubere Antwort (DATA_ACCEPTED = 0b101). Dann
wird die SPO-Leitung der Karte gepolt, bis sie wieder hochgeht. Je nach
Alter der Karte dauert es unterschiedlich lang. Aber OK. Ich musste
feststellen, dass ich das Dummy-Byte (mSend8ClkCycles) eigentlich nicht
brauche, um im Geschäft zu bleiben.
Meine Frage ist nun, wo soll ich STOP_TRANS_TOKEN reinwürgen und welche
Reaktion darauf von der Karte zu erwarten wäre. Es muss doch danach
sofort möglich sein, SendMMCCmd(WRITE_MULTI_BLOCK,(sector_addr << 9)) zu
senden, so dass es akzeptiert wird.
Nach jedem Block während des Schreibens geht die SPO-Leitung der Karte
recht schnell hoch (not busy). Muss ich denn mit längeren Wartezeiten
rechnen, wenn ich den Transfer abschliesse?
Ich sehe, Du schickst, CMD13, um den Status zu ermitteln, stimmt's?
Gruss
Dimitri
P.S. nop's sind nötig, weil offensichtlich DMA0CONbits.CHEN bereits auf
Null gesetzt wird, noch before das letzte Byte vollständig übertragen
wurde. Wenn ich DMA3CONbits.CHEN = 0 sofort ausführe, schneidet es mir
die letzten Bits ab.
Ich glaube, ich hab's :-)
Nachdem der letzte Block der Sequenz akzeptiert wurde und die Leitung
wieder auf HIGH gegangen ist, macht man Folgendes:
1
WriteSPIM(STOP_TRAN_TOKEN);// 1 Byte : 0xFD
2
mSend8ClkCycles();// <= wichtig!
3
index=0;//using i as a timeout counter
4
do//Wait for write completion
5
{
6
SPIBUF=0xFF;
7
while(!SPISTAT_RBF);
8
data_response=SPIBUF;
9
index++;
10
}while((data_response==0x00)&&(index!=0));
Wichtig ist, nach dem Senden von STOP_TRAN_TOKEN ein Dummy-Byte zu
senden, denn erst dann geht die Leitung runter auf BUSY und kann gepolt
werden.
Hier auf der Seite 6 bekommt man ungefähr mit, was geschieht:
http://forums.parallax.com/forums/attach.aspx?a=32012
Je nach Karte dauert's dann um 2 ms, bis die restlichen Daten geflasht
sind.
Gruss
Dimitri
Sieht ja spannend aus :)
Ja ich frage mit cmd13 ob die Karte alles flaschen konnte und ob alles
Ok gelaufen ist. Das ist so weit ich weiß die korrekte Methode bei
multiblock-write Operationen bzw. beim beenden einer solchen.
Ja, nach dem stop-tran-token müsste ein dummy byte rein.
Grüße Daniel