cancel
Showing results for 
Search instead for 
Did you mean: 

FR_DISK_ERROR always is returned by f_open.

Ali Esmailpor
Associate III

Hi all.

My team has been working on a project that contains a SD card based on Standard Library. Recently we've decided to migrate to HAL and it started.

Fortunately, All part of our project were changed as well as possible to HAL and they're working great but we don't know why SD card doesn't work well.

We have not changed peripheral's configuration clocks, but we had to change "clock frequency of the SDMMC controller" to 1.5MHz in HAL while it was 24MHz in STDLibrary. Because, it didn't work at all.

In addition, our customers are using a wide range of SD card types and all of them are OK but not great. I mean, FR_DISK_ERR is returned a lot in during of working but our device tries to get FR_OK.

Unfortunately, we always receive FR_DISK_ERR in some SD cards while, it worked all the time in our STDLibrary version.

Furthermore, we've found if "f_mount" function was called once and after that you take away the SD card and put it again, it will never work until you reset your microcontroller.

My microcontroller is STM32F427VI and SDIO configured as same as this:

 hsd.Instance = SDIO;

 hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;

 hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;

 hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;

 hsd.Init.BusWide = SDIO_BUS_WIDE_1B;

 hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;

 hsd.Init.ClockDiv = 14;

and it's working with 4bits wide bus.

Also, my device's clock is 96MHz and "APB2 Peripheral Clock" is 48MHz.

Edited (2020/02/24):

Finally, it worked when I updated my HAL Library to STM32Cube_FW_F4_V1.24.2. But HAL still doesn't work as well as Standard Peripheral. For example, I can't set 'ClockDiv' to '0' (24MHz) yet. It doesn't work at all. Now I set 'ClockDiv' to '1' (16MHz) that's not good enough for my project but I have to. Or if you take SDCard away and insert it again when program is working you can not init FATFS with f_mount. It's not going to work at all. You have to init SDIO Peripheral again by yourself. Unfortunately, now I can't put any time for getting more detail about what's going on in my schedule. Maybe in future.

32 REPLIES 32

Yes, thank you for your helping. I edited my question above.

Ayuks.1
Associate II

hello, ı want to communicate sccard via sdio with fatfs . in while loop and before while my code is working. but my code is not working timer callback and gpio external callback. this error is fr_disk_error or fr_no_filesystem. ı searched everything but happened.

cube Version: 1.5.1

stm32cube ide is usşng0693W000006I75hQAC.png0693W000006I75cQAC.png 

may you help me pleas. how to solve this error (return = fr_no_filesystem)

thank you advance

Hi dear Ayuks,

Actually Timer's callback is not a good place for doing something like that. You can set a Flag as well and use it in main loop. I think you're doing great.

About why did you get those Error I have no idea. If it's important to you, you can easily debug that with your own and see what's going on there.

In addition, when you get those Error you can re-initial the fatfs and make it to work. You can try re-initial for tens of times to get FR_OK.

Ayuks.1
Associate II

which flag is set? may you help me . why not happened exti callback?

You have to consider a flag (everything that you want) for this purpose and set it in the callback. And you have to check it in your main loop. Anytime that flag changed to set you can do everything that you want in main loop (for example reading from SD-Card).

You can't do large calculation or heavy communication in callbacks. Assume, if you be in a callback and have a new data you may lose the new data. So you are forbidden doing something like that in the callback.

But in your case, maybe you haven't configured well your NVIC Priority. Maybe you set Priority of Timer or EXTI higher or equal with SDIO DMA.

Ayuks.1
Associate II

thank you brother ı changed nvic priority well work.

Ali Esmailpor
Associate III

My pleasure dear Ayuks.

TJack.2
Associate III

Having just been down this rabbit hole myself, here is what I found. I had a STM32F407 board that I was migrating to Cube. The SD card, which had been working (same board, same card) with StdPeriph library and fragments from the Discovery package, failed to mount. I found that the HAL SD_PowerON() routine was seeing no response to initialisation commands, the card appeared not to be recognising anything. This resulted in the 30-second hang-up followed by f_mount returning with timeout error (due to rudimentary error handling in stm32f4xx_hal_sd.c). Note that during power-up the SD clock is running at 1/200th of its full speed, being in Open Drain mode, so fiddling with the divider setting won't do anything. However, as someone on this forum mentioned, CubeMX does not by default enable pull-up resistors on the I/O lines: these need to be manually enabled in CubeMX in the SDIO configuration (GPIO Settings tab). It appears that the lines are switched between input, push-pull and open drain by hardware, so the pull-ups have to be enabled from the start. This worked OK with the processor clocks running at full speed and the SDIO divide factor register set to zero (i.e. SDIO_CK=24MHz with SDIOCLK=48MHz).

Ayuks.1
Associate II

we've found if "f_mount" function was called once and after that you take away the SD card and put it again, it will never work until you reset your microcontroller.

My microcontroller is STM32F427VI and SDIO configured as same as this: .. this error how to solve since ı have same problem. thank you

Dear Ayuks, you have to change some files:

  1. Go to this address Drivers/STM32F4xx_HAL_Driver/Inc/, open stm32f4xx_ll_sdmmc.h file and change SDIO_CMDTIMEOUT define from 5000 to 1.
  2. Go to this address Middlewares/Third_Party/FatFs/src, open diskio.c file and change disk_initialize function to this:
extern SD_HandleTypeDef hsd;
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
  DSTATUS stat = RES_OK;
 
  if(disk.is_initialized[pdrv] == 0)
  {
    disk.is_initialized[pdrv] = 1;
    stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
  }
  else {
	  HAL_SD_InitCard(&hsd);
  }
  return stat;
}

Done.

In addition you have to be carful, every time that you get Error (like when you take away the SD card and put it back), you have to f_mount it again.