Skip to main content
campbiel
Associate II
July 9, 2014
Question

CubeMX - FatFS - SDIO not working

  • July 9, 2014
  • 8 replies
  • 2832 views
Posted on July 09, 2014 at 11:09

Hello,

I'm trying to make working the fatFS thought SDIO-4bits but I have the same problem on 2 different boards (devkit and custom board with STM32F437).

All the code is generated by cubeMX (v4.3, firmware 1.3).

The MX_SDIO_SD_Init(); function executes with no errors. Before the init the clock is 400kHz and then 25MHz. I modified a #define to reduce the clock speed to 400kHz to remove potential signal integrity errors.

After the init the HAL_SD_GetStatus(&hsd); returns SD_TRANSFER_OK.

But all others functions (HAL_SD_GetCardStatus(), HAL_SD_ReadBlocks(), HAL_SD_WriteBlocks(), f_mount()) loop indefinitely in a while : 

HAL_SD_SendSDStatus(...)

{

...

  /* Get status data */

  while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))

  {

    if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))

    {

      for (count = 0; count < 8; count++)

      {

        *(pSDstatus + count) = SDIO_ReadFIFO(hsd->Instance);

      }

      

      pSDstatus += 8;

    }   

  }

  }

...

}

I have also tried to make the SDIO 1 bit wide only, the problem persist. Optimisations are desactivated.

Any ideas ?
    This topic has been closed for replies.

    8 replies

    campbiel
    campbielAuthor
    Associate II
    July 9, 2014
    Posted on July 09, 2014 at 11:46

    Below is what I get when halting the CPU in the infinite while() :

    POWER.POWERCTL = 3 - Power-on: the card is clocked.

    CLKCR.WIDBUS = 0 - Default bus mode: SDIO_D0 used

    CLKCR.CLKEN = 1 - SDIO_CK is enabled and visible at scope

    DTIMER = 0xFFFFFFFF - max value - The timeout doesn't decrement ?!

    DLEN = 64

    DCTRL.SDIOEN = 0

    DCTRL.DBLOCKSIZE = 64

    DCTRL.DTDIR = 1 - From card to controller.

    DCTRL.DTEN = 1

    DCOUNT = 64

    STA.RXFIFOE = 1 - FIFO empty

    STA.RXACT = 1 - data receive in progress

    FIFOCNT = 16

     0690X000006058iQAA.png

    campbiel
    campbielAuthor
    Associate II
    July 9, 2014
    Posted on July 09, 2014 at 12:12

    Note that on my custom design, there is no pull-up on the board for D0-D3 and CMD lines. I use the STM32 internal pull-up instead.

    I dont't think the problem come from theses pull-up since I have the same issue with the devkit.
    Montassar BEN ROMDHANE_O
    Visitor II
    July 9, 2014
    Posted on July 09, 2014 at 12:24

    Hi eigerMount,

    Which ST board are you working with ? EVAL or Discovery ?

    Why you're configuring the SDIO in 1bit wide all time ? It's used only for initialization process. Please provide as a little more information about the issue you’re experiencing.

    With regards.

    campbiel
    campbielAuthor
    Associate II
    July 9, 2014
    Posted on July 09, 2014 at 19:03

    Well!

    Everything is working fine. The EMI protection (EMIF06-MSD02N16) was soldered in the wrong way. The SDIO module works definitely better with the EMIF righlty connected :)

    Some benchmarks:

    Core@96MHz, SDIO@24MHz, Write test (I'am not interested by reading performance). f_sync to be sure that there is no pending FIFO and all data is written.

        HAL_GPIO_WritePin(GPIOE, LED_ORANGE, GPIO_PIN_SET);

        for(i = 0; i < nbBlocs; i++) 

        {

          fres = f_write(&file, txBuf, blocSize, (UINT*)&len);

        }

        fres = f_sync(&file);

        HAL_GPIO_WritePin(GPIOE, LED_ORANGE, GPIO_PIN_RESET);

    SD card = 2GB ''Dane elec'', formated with SDformater (clusters 32k)

    blocSize nbBlocs     kBps

    512          32         95 

    1024      32        168

    2048      16        141

    4096      16        536

    8192      8         883

    16384      8        1292

    32768      8        1747

    SD card = 2GB ''taiwan'', formated with SDformater (clusters 32k)

    blocSize nbBlocs     kBps

    512          32         58 

    1024      32        168

    2048      16        474

    4096      16        864

    8192      8         1356

    16384      8         1136

    32768      8         1413

    SD card = 8GB transcend class 10, formated with SDformater (clusters 32k)

    blocSize nbBlocs     kBps

    512          32         145 

    1024      32        277

    2048      16        461

    4096      16        789

    8192      8         1108

    16384      8         1711

    32768      8         1860

    Tesla DeLorean
    Guru
    July 9, 2014
    Posted on July 09, 2014 at 19:22

    1.8 MBps seems a bit on the sad side, the cheap 128MB SD card supplied with ST's EVAL boards should be able to do that, I'd expect a decent 16GB SDHC card to post >7MBps writing and >10MBps reading

    32MB written as 32KB blocks, FatFs, 4-bit SDIO, interface clock 24 MHz, SDIOCLK 48 MHz
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    campbiel
    campbielAuthor
    Associate II
    July 10, 2014
    Posted on July 10, 2014 at 16:33

    One more benchmark:

    SD card = 8GB varbatim class 4, formated with SDformater (clusters 32k)

    blocSize nbBlocs     kBps

    512               32        199 

    1024      32        317

    2048      16        617

    4096      16        1017

    8192      8         1394

    16384      8         2004

    32768      8         1614

    I was also expecting some better results, even if it will be enough for the most of my applications. Now I'm going to use DMA, I hope it will speed up the transfert.

    Note I also updated the ff.c/ff.h from 1.0 to 1.0b, adding some #defines it compile and works fine (all the previous benchmarks have been done with fatfs 1.0b)
    Ryan Stephen
    Associate
    March 13, 2017
    Posted on March 13, 2017 at 09:29

    Hi

    I know this has been a while but I want to open this case up again as I am experiencing the same issue.

    After performing the following:

    /* StartDefaultTask function */
    void StartDefaultTask(void const * argument)
    {
    for(;;) {
    /*##-1- Link the micro SD disk I/O driver ##################################*/
    if(FATFS_LinkDriver(&SD_Driver, (char *)SD_Path) == 0) { 
     /*##-2- Register the file system object to the FatFs module ##############*/
     if(f_mount((FATFS *)&SDFatFs, (TCHAR const*)SD_Path, 0) == FR_OK) {
     for(;;) {
     fr = WriteSDCard();
     osDelay(1000);
     if(fr) {
     f_mount(NULL,'',1);
     break;
     }
     }
     /*##-11- Unlink the micro SD disk I/O driver ###############################*/
     FATFS_UnLinkDriver((char *)SD_Path);
     }
    }
    }
    }
    
    FRESULT WriteSDCard() {
     char * filename = 'TEST.txt';
     char Buf[7] = {'H','e','l','l','o','
    ','
    '};
     uint8_t BufLen = 7;
     FRESULT fr;
     
     fr=f_open((FIL *)&MyFile, (char *)filename, FA_OPEN_ALWAYS | FA_READ | FA_WRITE); 
     if(fr){
     return fr;
     } 
     
     fr = f_lseek((FIL *)&MyFile,MyFile.fsize); 
     if(fr){
     return fr;
     }
     
     fr= f_write((FIL *)&MyFile, (uint8_t *)Buf, BufLen, (void *)&BytesWritten);
     if(fr){ 
     return fr;
     }
     
     fr=f_close((FIL *)&MyFile); 
     if(fr){ 
     return fr;
     }
    }
    �?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    If WriteSDCard returns anything but FR_OK then when it unlinks the driver/unmounts and tries to link/mount again i get stuck in this while loop forever looking for the start bit:

    #ifdef SDIO_STA_STBITERR 
     while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))
    #else /* SDIO_STA_STBITERR not defined */
     while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
    #endif /* SDIO_STA_STBITERR */
     {
     if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
     {
     *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
     index++;
     }
     }�?�?�?�?�?�?�?�?�?�?�?�?

    I am using CubeMx 4.0 STM32Cube V1.0, RTOS is also enabled.

    Am I possibly seeing WriteSDCard return an error if the task has context switched during an f_*** operation?

    Thanks

    Tesla DeLorean
    Guru
    March 13, 2017
    Posted on March 13, 2017 at 11:11

    A new thread would have made more sense after 3 years.

    I'm pretty sure that the SDIO and FATFS are not thread safe. I'd lean to having IO in a single thread, as you would need to serialize access to the peripheral / card.

    I would generally try to avoid repetitively mounting and unmounting the card, f_sync or f_close should be sufficient to push all file system structures onto the media 

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Ryan Stephen
    Associate
    March 13, 2017
    Posted on March 13, 2017 at 12:11

    Hi

    Thank you for your reply, It is all within one thread (task), the task calls the WriteSDCard function which is in the same thread isn't it? It only really ever unmounts if an error occurs.

    Ryan