Grüße!
Ich arbeite im Zuge eines kleinen Projektes daran einen MP3 Player zu
implementieren. Dazu verwende ich folgende Komponennten:
SD Karte (<=2GB) im SPI Modus
µC: XC164CM Easy-Kit (Ein Übungsboard von Infineon)
ein Display
einen MP3 Decoder Chip.
Bis jetzt habe ich es geschafft, auf einem Steckbrett eine brauchbare
Schaltung zu erstellen (Versorgungsspannung der SD Karte ist stabil, es
wird über einen Pegelwandler 5V<->3.3V kommuniziert) und die SD Karte
korrekt zu booten (CMD0 , CMD55 , ACMD41).
Weiters ist es mir auch schon gelungen das CSD (Card Specific Data)
Register auszulesen (CMD9), sowie die Blocklänge von Lese- und
Schreiboperationen auf 512Byte zu fixieren (CMD16).
Der nächste logische Schritt war es, Daten aus der Karte auszulesen
(READ_SINGLE_BLOCK CMD17 , READ_MULTIPLE_BLOCK CMD18).
Ich habe bisher nur CMD17 implementiert, um zu sehen, ob die Karte mir
auch schon Daten sendet, und ich diese korrekt erkenne. Weiters wollte
ich mir auch schon einmal kurz den ausgelesenen FAT Table ansehen... Die
Karte wurde zuvor mit dem "sd-formatter"
(http://www.sdcard.org/consumers/formatter/) formatiert, es wurde 1 MP3
File draufgespielt (keine Ordner oder sonst was).
Soweit, so gut - nun zu meinem Problem. Ich nahm an, dass ich den Boot
Sector, bzw. erste FAT Daten bereits im allerersten Datenblock (Adresse
0x00000000 - 0x0001FF) finde. Allerdings bekomme ich als Rückmeldung von
der Karte einen haufen 0er (ca. die ersten 190) und dann folgende
Bytefolge:
0x02 , 0x0A , 0x00 , 0x06 , 0x3F , 0xFF , 0xBC , 0x87 , 0x00, 0x00 ,
0x00 , 0x39 , 0xE0 , 0x3A
Dies scheint mir aber nicht korrekt zu sein!
Weiters sind die nächsten paar Blöcke (3 oder 4) komplett leer (also 512
mal "0x00")
Das Kommando für die ersten 512Bytes an der Adresse 0x000000, welches
ich sende ist:
1
ubyteCMD17[6]={0x51,0x0,0x0,0x0,0x0,0x01};
FRAGEN:
-)Auf welcher Adresse finde ich den Boot-Sector, bzw. einen Verweis auf
die eigentliche FAT Tabelle normalerweise?
-)Sollte ich den sd formatter oder eine Windows Formatierung verwenden?
-)Berechnung des Parameters NAC: Es handelt sich um den "Timeout"
Parameter für das Lesen von Datenblöcken (Anzahl der Bytes, bis die
Karte Daten sendet, ab dem letzen Byte des Lesekommandos).
Laut einem im Internet kursierenden Datenblatt berechnet sich dieser zu:
NAC = 100((TAAC*fpp)+(100*NSAC))
Die Werte TAAC und NSAC erhalte ich aus dem CSD Register - allerdings
stimmt meine Berechnung von NAC mit der tatsächlichen "Totzeit" nicht
überein! - ich komme auf <10 Byte, real sind es jedoch 16Byte aufwärts.
Weiters wird NAC in der (sehr bescheidenen) freien SD Spezifikation
einfach als "the sum of TAAC and NSAC" beschrieben - wie berechnet sich
dieser Parameter nun?
Für Kommentare und Hilfe wäre ich sehr Dankbar!
MfG Eagle
1)
Der MBR ist immer in LBA0 und bei einer frisch formatierten SD-Karte
besteht dieser größtenteils aus Nullen. Ab einem Offset von 446 Bytes
steht der Eintrag der ersten Partition mit einer Länge von 16 Bytes.
Wenn du diesen Eintrag auswertest, dann bekommst du den Start-LBA der
ersten Partition. In diesem steht dann die FAT32 Volume-ID, aus welcher
du den Start-Cluster der FAT und weitere nötige Dinge extrahieren
kannst.
2)
Ich habe letztlich mit Windows formatiert und das hat gut funktioniert.
Ich benutzte aber die Kommandozeile, da ch dort mehr Parameter vorgeben
kann.
3)
Für CMD17 warte ich nach dem Befehl erst auf die Bestätigung per 0x00
und dann auf 0xFE von der SD-Karte, was den Datenblock einleitet.
CMD18 habe ich nich nicht benutzt, aber wenn ich das richtig gesehen
habe, wird auch bei CMD18 jeder Datenblock per 0xFE eingeleitet.
Sogesehen könntest du auch hier anstatt einer ausgerechneten Wartezeit
einfach auf diese Bytefolge warten um den nächsten Datenblock
einzulesen.
Ciao,
Rainer
Vielen Dank Rainer, du hast mich auf die richtige Fährte gebracht - ich
hab den FAT Table.
zu 3)
Naja, verwendest du denn keinen Timeout Mechanismus? Wenn man nur auf
0xFE wartet und sonst nichts tut, kann es ja zu einer Endlosschleife
kommen (wenn irgendwelche unvorhergesehenen Fehler auftreten)
MfG
>Naja, verwendest du denn keinen Timeout Mechanismus? Wenn man nur auf>0xFE wartet und sonst nichts tut, kann es ja zu einer Endlosschleife>kommen (wenn irgendwelche unvorhergesehenen Fehler auftreten)
Das ist richtig. Aber wozu brauchst du da die NAC?
Mach nach 1s Schluß und gut is.
Bernhard R. schrieb:
> Naja, verwendest du denn keinen Timeout Mechanismus? Wenn man nur auf> 0xFE wartet und sonst nichts tut, kann es ja zu einer Endlosschleife> kommen (wenn irgendwelche unvorhergesehenen Fehler auftreten)
Ich habe schon einen Timeout eingebaut per Timer. Aber dieser wird nicht
berechnet, sondern steht auf einer festen Zeit die immer größer ist als
die maximale Zugriffszeit.
Da er sowieso nur im Fehlerfall in Kraft tritt, stört es mich dann
wenig, ob der schon nach 100ms oder erst nach 1s einen Fehler meldet.
Hallo,
ich beschäftige mich gerade mit SD Karten. Bisher nur mit dem Ansprechen
über SPI noch nicht mit dem Filesystem. Ich habe mit CMD17 Block 0
ausgelesen im Anhang das Ergebnis, sind die Werte plausibel? Die Karte
ist mit Fat 16 formatiert.
MfG
Steffen
Bis jetzt habe ich herausgefunden, dass ich aus daraus berechnen kann wo
der Sektor 0 vom FAT liegt, stimmt das? Wenn ja könnte mir jemand bitte
sagen, ich das machen kann?
Vieleicht gibt Dir das ein bischen Schub...
Mußt halt die Sachen wegassen, was Du nicht benötigst...
Ich will den Souce Code in meinem CAN Controller C8051F502 verwenden,
damit ich Langzeitdaten der LiPoly Zellen aufnehmen kann.
Grüße
Michelle
Steffen schrieb:
> Bis jetzt habe ich herausgefunden, dass ich aus daraus berechnen kann wo> der Sektor 0 vom FAT liegt, stimmt das? Wenn ja könnte mir jemand bitte> sagen, ich das machen kann?
Das von dir gewählte Dateiformat für den Block ist etwas
gewöhnungsbedürftig. Du hättest lieber eine Binärdatei hochgeladen.
Schau dir am besten mal die Beschreibung zu FAT32 unter [1] an. Der
Anfang der Beschreibung ist auch für FAT16 zutreffend. Dort steht, wie
man aus Block0 die erste Partition und den Typ des Dateisystems
herauslesen kann.
In deinem Block findest du ab Offset 450 den Dateityp (0x06) was FAT16
entspricht und ab Offset 454 den Startblock der Parrition (0x00000087),
was dem Block 135 entspricht.
Ciao,
Rainer
[1] http://www.pjrc.com/tech/8051/ide/fat32.html