Hallo,
ich verwende an einem STM32F4 Discovery Board eine SD-Karte die über die
SDIO-Schnittstelle verbunden ist um Messwerte die über drei ADC-Kanäle
(je 12 bit) aufgenommen wurden zu puffern und später über USB
auszulesen.
Da auf die SD-Karte nur Blockweise geschrieben werden kann, warte ich
bis ich 85 Messungen habe (85*3*2byte = 510byte) und schreibe dann über
DMA und SDIO auf die Karte. Das Format sieht folgendermaßen aus:
Die ersten beiden Byte sind 0xFF, danach folgen die Daten (Summe 512
Byte).
1 | typedef struct
|
2 | {
|
3 | uint16_t preamble; // is 0xFFFF in any case
|
4 | ADCTripleConvertedType dataXYZ[85]; // the measurement values; 85: 512byte/(3*2byte) = 85.3333.. -> 85
|
5 | } sAdcMeasBuffer;
|
1 | ADCTripleConvertedType tripleConvertedValue;
|
2 | sAdcMeasBuffer *tempBuffer;
|
3 |
|
4 | /* use temporary variable, so the value may be overridden by next DMA transfer. */
|
5 | tripleConvertedValue = sm_ADCTripleConvertedValue;
|
6 | iNumSamplesRecorded++;
|
7 |
|
8 | (*currentBuffer).dataXYZ[u16_Position++] = tripleConvertedValue;
|
9 |
|
10 | if(u16_Position == 85)
|
11 | {
|
12 | u16_Position = 0x00;
|
13 | if(iWriteAddress < 12)
|
14 | {
|
15 | SD_Error err;
|
16 | if(iWriteAddress != 0)
|
17 | {
|
18 | /* Check if the Transfer is finished */
|
19 | SD_WaitWriteOperation();
|
20 | while(SD_GetStatus() != SD_TRANSFER_OK);
|
21 | }
|
22 | err = SD_WriteBlock((uint8_t*)currentBuffer, iWriteAddress*512, 512);
|
23 | if( err!= 0)
|
24 | {
|
25 | VCP_put_char(err);
|
26 | }
|
27 |
|
28 | /*
|
29 | Swap the buffers
|
30 | */
|
31 | tempBuffer = currentBuffer;
|
32 | currentBuffer = nextBuffer;
|
33 | nextBuffer = tempBuffer;
|
34 |
|
35 |
|
36 | iWriteAddress++;
|
37 | }
|
38 | }
|
Das Lesen funktioniert wie folgt: Über USB wird eine virtuelle
COM-Schnittstelle emuliert die mit 512000 Baud betrieben wird. Über
diese Schnittstelle werden mit HDLC die Daten blockweise übertragen.
(Die Übertragung funktioniert einwandfrei).
1 | SD_ReadBlock(sd_readBuffer, uCardAddress*512, 512);
|
2 | /* Check if the Transfer is finished */
|
3 | SD_WaitReadOperation();
|
4 | while(SD_GetStatus() != SD_TRANSFER_OK);
|
5 | /*
|
6 | * One Block contains 512 bytes. One Measurment (3*16bit) = 6bytes.
|
7 | * So one Block can contain 85 complete Measurements. Two bytes remain.
|
8 | * Those two bytes are 0xFF (at the beginning of the block).
|
9 | */
|
10 | if((sd_readBuffer[0] != 0xFF) || (sd_readBuffer[1] != 0xFF))
|
11 | {
|
12 | // TODO: an error occurred --- this shall be handled!
|
13 | }
|
14 | uCardAddress++;
|
15 | sd_currentMeasurement = sd_readBuffer;
|
16 |
|
17 | tx_buffer[0] = 0x1A;
|
18 | for(i=0; i< 512; i++)
|
19 | {
|
20 | tx_buffer[i+1] = *(sd_currentMeasurement++);
|
21 | }
|
22 | hdlc_tx_frame(tx_buffer, 513);
|
Nun zum eigentlichen Problem: Beim schreiben auf die Karte habe ich das
oben genannte Format. Dieses schreibe ich zu Beginn an die Adresse 0x00.
Beim lesen von der Karte beginnt der Block jedoch nicht mit 0xFF 0xFF
sondern mit 0x00 0x00 0xFF 0xFF, also um 4 Bytes verschoben. Ich habe
wirklich lange gesucht, konnte aber keine Fehlerquelle finden. Der Rest
stimmt mit den Daten die geschrieben wurden überein.
Ich bin für alle Tips dankbar!
Gruß Thomas