Ali Esmailpor
Ali Esmailpor

Reputation: 1201

FR_DISK_ERROR always is returned by f_open

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:

As for re-inserting the card - I did initial again by recalling f_mount when FR_DISK_ERR was returned by f_open. I did it until giving FR_OK but it's never returned FR_OK in this case.

I realized f_mount doesn't initial SDIO for second time as dear Jacek Ślimok said.

Because there's a flag that doesn't let 'SD_initialize' be recall again (SD_initialize function includes BSP_SD_Init).

Here is the diskio.c's code:

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]);

 }

 return stat;

}

Now I used SD_PowerON and SD_InitCard before recalling f_mount and it worked correctly now. It's a bug, isn't it? 😥

But other problems have still remained. It doesn't work with 24MHz clock at all and FR_DISK_ERR is still returned by some SD cards.

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.

Upvotes: 0

Views: 3640

Answers (1)

Hans Lepoeter
Hans Lepoeter

Reputation: 149

disk.is_initialized[0] =0; // force reinit

Before mounting. That's the easy way to support hot plugged sd card.

Upvotes: 0

Related Questions