2017-07-17 04:01 AM
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();
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:
2. config the pinout
and choose the FATFS
3. resolve the clock
4.do nothing
5. change the heap size
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.
2017-07-17 05:46 AM
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
2017-07-17 09:56 AM
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
the f_mount function will lead the mcu to here:
and the mcu will stuck at this loop of the function
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.
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
STM32TEST has 9 characters >8. so the file name is invilade
2017-07-17 04:48 PM
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.
2018-07-05 12:32 PM
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:
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
2018-07-05 03:31 PM
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.
2018-07-06 12:36 PM
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.
2018-07-06 01:18 PM
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.
2018-07-06 03:05 PM
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.
2018-07-06 03:10 PM
There's months of complaints about the CubeMX FatFs/SDIO/SDMMC implementation.