Forum: Mikrocontroller und Digitale Elektronik Probleme bei SDIO mit STM32F4


von Thomas K. (tomthegeek)


Angehängte Dateien:

Lesenswert?

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

von Thomas W. (diddl)


Lesenswert?

Du willst auf die SD Karte schreiben ohne Filesystem?


Ich habe ein kleines F4 Discovery Beispiel wo SDIO mit FAT32 tadellos 
und robust funktioniert. Mit und ohne DMA, mit 1 und 4 Bit Mode:

xs1541.t-winkler.net/zip/Zoomfloppy/Stm32F407_blink_06.zip

von Thomas K. (tomthegeek)


Lesenswert?

Danke! Ich schaus mir mal an und versuche es auf mein Projekt zu 
portieren.

von holger (Gast)


Lesenswert?

1
typedef struct
2
{
3
  uint16_t preamble;                  // is 0xFFFF in any case
4
  ADCTripleConvertedType dataXYZ[85]; // the measurement values; 
5
} sAdcMeasBuffer;

Ich tipp mal auf ein Alignment Problem verbunden mit Padding Bytes.
Die Struktur ist möglicherweise 514 Bytes gross wegen Padding Bytes.
Musst du mal im MAP File nachsehen wie viel Speicher wirklich belegt 
ist.
Da hilft nur attribute packed (genaue Schreibweise ergoogeln).
Evtl. geht das mit dem typedef nicht. Dann eben halt struct 
sAdcMeasBuffer usw.

von Thomas K. (tomthegeek)


Lesenswert?

Hi,

die beiden Buffer haben genau 512 bytes.
1
    writeBuffer_1                            0x200008fe   Data         512  antmeas.o(.bss)
2
    writeBuffer_2                            0x20000afe   Data         512  antmeas.o(.bss)

von holger (Gast)


Lesenswert?

>die beiden Buffer haben genau 512 bytes.
>
>    writeBuffer_1
>    writeBuffer_2

Die kommen in deinem geposteten Code nicht vor.
Das wars dann von mir. Geh zum Hellseher.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.