cancel
Showing results for 
Search instead for 
Did you mean: 

SD Card Cannot be mounted successfully using the Code generated by CubeMX

Lingjun Kong
Associate III
Posted on July 17, 2017 at 13:01

to use the FATFs on the STM32F746NG-Discovery Board, I generate the code using the CubeMX.

this is my main.c file.

during the debugging, I found that the value returned by the f_mount is FR_NOT_READY, so that the function will always fall into Error_Handle();

0690X00000607TyQAI.png

but with the same board and sd card, the demo project:

STM32Cube_FW_F7_V1.7.0\Projects\STM32746G-Discovery\Applications\FatFs\FatFs_uSD\MDK-ARM

it could work well.

I want to know whether there is any other thing I've forgot to add to the project? Or the code generator itself has a big bug?

the method i generate the code is:

  1. select the board
0690X00000607OaQAI.png

2. config the pinout

0690X00000607bhQAA.png0690X00000607WiQAI.png

and choose the FATFS

0690X00000607ZNQAY.png

3. resolve the clock

0690X00000607bmQAA.png

4.do nothing

0690X00000607bwQAA.png

5. change the heap size

0690X00000607brQAA.png

7. and generate the project

8.open project and add this line to main.c

FATFS SDFatFs; /* File system object for SD card logical drive */

FIL MyFile; /* File object */

char SDPath[4]; /* SD card logical drive path */

if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 1) != FR_OK)

{

Error_Handler();

}

and rebuilt it, debug, falls into error_handle.

11 REPLIES 11
john doe
Lead
Posted on July 17, 2017 at 14:46

taken directly from stm32746g_discovery_sd.c

  uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;

  uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;

  uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;

  uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;

  uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;

  uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;

so, try 1-bit bus instead of 4 bits

Posted on July 17, 2017 at 16:56

1. Your suggestion is helpful

Thank you very much the value f_mount returned is FR_OK now. this time I generate the code with SD bus width is 1 bit.

is that mean the CubeMX has a bug when generate the code? it cannot choose a correct bus width.

2. how could I use the 4-bit width mode?

and when I trying to modify the sd init function like this

0690X00000607c1QAA.png

the f_mount function will lead the mcu to  here:

0690X00000607c6QAA.png

and the mcu will stuck at this loop of the function

0690X00000607cGQAQ.png

so, how could I use the 4-bit wide SDIO mode?

3. f_open return FR_INVALID_NAME. (I just meet this problem but I solved it)

in the 1-bit width mode, after mount the sd card, i add a f_open function but it couldn't work.

0690X00000607cLQAQ.png

the value the f_open returned is FR_INVALID_NAME

This is because the file name I used is too long.  when USE_FLN is disabled, the file name must be 8.3 format

0690X00000607X7QAI.png

STM32TEST has 9 characters >8. so the file name is invilade 

Posted on July 17, 2017 at 23:48

About 4bit wide mode:

As far as I know, MX_SDIO_SD_Init() only sets the SDIO to a known, default state for card initialization -> 1bit wide.

Only during MX_FATFS_Init() will the bus be switched to faster 4bit wide mode. Have a look into BSP_SD_Init(). That function gets called when the SD driver is loaded during FATFS init. In there, a function named HAL_SD_ConfigWideBusOperation() is called. That sets the sdio to 4bit mode - if set up accordingly.

In short: don't change the SD_Init function to 4bit.

luuk
Associate II
Posted on July 05, 2018 at 21:32

I am running into exactly the same problem. A few years ago I did a small test project with 4 bit SDIO with CubeMX, had it up and running in a few minutes without a problem. Now I am trying to do the same thing using the current version of CubeMX and have been stuck for a month now, I just can't get it to work.

My setup is almost identical. I'm using a STM32F446 and have setup the SDIO, DMA, and FATFS. Actually I first had everything in a project with FreeRTOS and had lots of code doing other things. Thinking FREERTOS could be part of the problem I had created an empty bare metal project with only the SD card setup, hoping to quickly get it up and running.

When I run the firmware it will hang in f_mount() for about 15 seconds, before returning an error. In the past weeks I have been trying many things to narrow down the exact cause. My first thought was it must be a hardware problem, so I used my oscilloscope to check the signals and VCC on the SD card, which all turned out to be absolutely perfect.

Then I used my logic analyzer to see what is actually happening on the data lines. This is what I see:

0690X0000060LeiQAE.png

First, the clock operates on 400KHz and sends the configuration over the CMD line. On the last few bytes the clock frequency is increased to the much higher specified frequency (which has been lowered in this capture). There's a small pause and the SD card responds on the DAT0 line. Then the MCU sends a bit more data on the CMD line and then the SD card responds using all 4 data lines.

This all happens in the function disk_initialize(fs->drv) in ff.c, line 3036 and this function succeeds. After this function is done, after a few more steps it enters check_fs(fs, bsect); on line 3050. This is where the problem starts. Tracing down the steps in this function takes me to if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) on line 927, which takes me to diskio.c, line 122 to: res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count); which returns RES_ERROR.

The strange thing here is when I try to follow this function so I can go deeper into the rabbit hole, I see this function is only defined in ff_gen_drv.h: DRESULT (*disk_read)       (BYTE, BYTE*, DWORD, UINT);

It appears this function pointer should be set somewhere in the process, but I never see that happening. It looks like the disk driver must be linked using the function FATFS_LinkDriver() in ff_gen_drv.c, but this function is never called.

I'm starting to think there is a problem in the FatFS implementation in CubeMX and I'm in a dead end. Finding your post here confirms I'm not the only one facing this problem, but I see there's no solution posted yet. Did you already find a solution, or is there any bright mind here that can enlighten us?

It looks like I can't attach files on this forum, so I've uploaded my source files here, in case anyone wants to have a look:

http://www.zigncreations.com/downloads/ZignLink-TX-BareMetal.zip

 
Posted on July 05, 2018 at 22:31

As functional starting points you might want to look at the HAL examples

STM32Cube_FW_F4_V1.21.0\Projects\STM32446E_EVAL\Applications\FatFs\FatFs_uSD_RTOS

STM32Cube_FW_F4_V1.21.0\Projects\STM32446E_EVAL\Applications\FatFs\FatFs_uSD

You have to click on 'Use advanced editor', from the thread view, rather than in-box view, to add attachments.

The code doing the IO will likely be in sd_diskio.c or sd_diskio_dma.c, though you'd probably want to focus on the DMA builds, as the others have the potential for data loss, and are sensitive to interrupt loading.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
GreenGuy
Senior III
Posted on July 06, 2018 at 21:36

I am seeing the same problem but with STM32H743i_Eval board.  Thought maybe they (STM32) may have fixed something with the latest release of CubeMX (4.26.0) but no.  I am seeing though the addition of the cache maint. calls so DMA should not be an issue. 

So you don't feel to singular in your confusion I have needed this fixed since March 1. 

In any case, the F746 discvoery data sheet shows the hardware support for 4 bit.  In the CubeMX builds you have to be careful especially when the using FatFs, FreeRTOS, and DMA.  There are two files that have to be excluded from the build; bsp_driver_sd.c and sd_diskio.c as the functions in these files are duplicated by one of the ...[eval][discovery] files and one of the template files that have to manually added to the project from STM32Cube\Repository\STM32Cube_FW_xx_Vxxx\Middlewares\Third_Party\FatFs\src\drivers.  In my case, stm32h743i_eval_sd.c replaces bsp_driver_sd.c and  sd_diskio_dma_rtos_template (in the middlewares as noted) replaces sd_diskio.c.  Note: the sd_diskio_dma_rtos.c is a template and you will need to open the .h file of the same name and modify the generic include to point to your particular .h file for your eval or discovery BSP equivalent.

Now to add to the confusion, I just found where in the generated code along with the replacements noted above two different functions to setup the SD card bus width.  One call in the stm32h7xx_hal_sd.c inside the function HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd) that sets the bus width to Init.BusWide = SDMMC_BUS_WIDE_1B;

The other in stm32h743i_eval_sd inside the function uint8_t BSP_SD_Init(void) that sets the bus width to uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_4B;

In my case, the BSP_SD_Init(void) is getting called first and HAL_SD_InitCard(SD_HandleTypeDef *hsd) is called after which leaves the bus set to 1B.

Seems to me this an oversight which precludes the use of 4B operation. 

This also exists for the project application example as well.

Posted on July 06, 2018 at 20:18

Thank you Clive. For a moment I thought you had made my day. The samples you refer to actually call the function FATFS_LinkDriver(&SD_Driver, SDPath); before calling f_mount(). I had looked at many other examples (also from ST) which are perhaps a bit outdated and did not have to call FATFS_LinkDriver() first. So I've added this line and found this function fails as well. When I started debugging this function I found it was already called in MX_FATFS_Init() which was generated by CubeMX. The first time it enters this function it succeeds, but when I call it again, it fails.

Of course I should not have to call it again, but other then this I don't see significant differences between my code that tries to setup the SD card and that in the examples.

So, I'm still thinking something strange is going on in the FatFs files generated by CubeMX, causing it to fail. I'll spend some more time on it trying to find where exactly it goes wrong.

Posted on July 06, 2018 at 22:05

Update:  In the working project\application changing the xxx_hal_sd.c in the function HAL_SD_InitCard() so the bus width is 4B causes the program to hang in SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR) (between lines 2655 and 2668) trying to get status info from the SD card.  It looks like the bus width needs to change depending on what operation is being performed on the SC card.

Posted on July 06, 2018 at 22:10

There's months of complaints about the CubeMX FatFs/SDIO/SDMMC implementation.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..