cancel
Showing results for 
Search instead for 
Did you mean: 

Need help getting SD+FATFS working with an STM32H747I-Disco

tgrant
Associate II

I'm trying to use the SD card reader on the STM32H747I-Disco with FatFs. It's working as expected with the M7 core -- I'm able to initialize the SD interface and the filesystem, and access files on the SD card.

However, when I perform the same initialization using the M4 core (which is the core I would like to access the SD card), I get FR_DISK_ERROR when I try to open files or directories.

I'm using the BSP initialization functions. The SD interface initializes correctly (without error, anyway), and BSP_SD_GetCardInfo returns the correct information. After I link the driver, I'm able to mount the SD card, but attempting to open a file fails.

The failing part of my setup code looks something like this:

    if( FATFS_LinkDriver( &SD_Driver, sdPath ) != 0 )
    {
        sendString( "FATFS error: unable to link driver!\r\n" );
    }
    else if( (res = f_mount( &sdFatFs, (TCHAR const*)sdPath, 0 )) != FR_OK )
    {
        sendString( "FATFS error: unable to mount SD card!\r\n" );
    }
    else if( (res = f_open( &file, "test.txt", FA_READ )) != FR_OK )
    {
        // This call fails with FR_DISK_ERROR
        sendString( "FATFS error: unable to open file!\r\n" );
    }

Does anybody know why FatFs would work on one core and not the other? Is anyone successfully using the SD interface with the M4 core?

7 REPLIES 7
tgrant
Associate II

I have found a solution.

The M7 is being clocked at 400MHz, and the M4 is at 200MHz. I noticed that doubling the clock divider set in BSP_SD_Init caused the file operations to start working on the M4. I wasn't too keen on modifying that function, so instead I found the clock source for SDMMC1 (PLL1) and set the divider to supply a 200MHz clock to the SDMMC.

It's not clear to me what the relationship between the different clocks is, but I'm happy to have it working for now.

@tgrant,

Would you be willing to share a few more details/guidance related to how you managed to get an SD Card / FatFS working on the DISCO board?

I have been struggling for the past 3 days, to no avail. I am using CubeIDE 1.1, with CubeMX 5.4. Since there is no direct H747-DISCO SD Card project/example, I have been attempting to modify the H747-EVAL example for FatFS. I actually want to access the SD Card from the M7 processor, but the SD Card is not getting initialized. I have tried to faithfully follow the rat's nest of #defines and #includes to get the proper BSP_SD_Init code, but I don't think I have it, and I also think the problem is related to clock speeds. In my case, I **think** the right clocks are being initialized in the SystemClock_Config() that I pulled from the -EVAL application, but I am frankly not sure (I expect to eventually figure out what I need to know about the clocks and configuration, but right now I just need working code that will let me pull a couple of files off an SD Card). I did not expect this to be the nightmare it has become.

Thanks.

>>Since there is no direct H747-DISCO SD Card project/example...

STM32Cube_FW_H7_V1.5.0\Projects\STM32H747I-DISCO\Examples\JPEG\JPEG_DecodingUsingFs_DMA

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

Yes, that is the sample (actually, JPEG_DecodingUsingFs_Polling, but the SD stuff is the same) that I used as the starting point for my implementation.

I'm using BSP_SD_Init, so I would start there and make sure the SD interface is being initialized without error, otherwise there is no point in proceeding. After that is working, you can use functions like HAL_SD_GetState and BSP_SD_GetCardInfo to perform more functional tests.

Try linking the FatFs driver only after you're fairly certain that the SDMMC is setup correctly, following the JPEG decoding example. As usual, make sure to perform error checking at each step in the initialization. Otherwise debugging is almost impossible.

As I found, if the clocks are not quite right it's possible for the SDMMC to be partially functional, but fail with FatFs operations. So if you continue to have issues make sure to revisit your clock tree and make sure that the SDMMC is being fed a sensible clock (I'm not sure what it requires, but it must be in the documentation).

@tgrant​  and @Community member

Thanks for the tips. Without an inordinate amount of aggravation (though, in my humble opinion, way too much for a 'flagship' product), I was able to get the JPEG example working - basically by starting a new STM32 project, then carefully copying from the JPEG example; carefully adding files until I stopped getting compile/link errors. Brute force, but fine for now.

It really irks me that each example (in the generic sense - i.e., Projects, Demonstrations, etc. in ST vernacular) has hidden dependencies that go all the way back to the root of the H7_V1.5 firmware folder (e.g., the fonts needed for the LCD, the extra code needed for FatFS). Particularly when so much has to be fixed in terms of paths for the FatFS code and any other Middleware (drop the s, please).​ Plus there are multiple files that have almost the same functionality. For example, previously I was using a file named sd_diskio_dma.c, whereas the JPEG example uses simply sd_diskio.c. I suppose there is probably a good reason buried somewhere in the finer points of using dma, but it sure does make what ought to be fairly straightforward awfully complicated.

Anyway, I do appreciate your responses - including the added bonus that I now have an inkling of how to drive the LCD.

I can't figure out how to mark your responses as answers or to ring the bell in this 'forum', but consider it rung.

Cheers

LBarn.1
Associate II

This seems very similar to the issue I posted in December. Would the stack and heap size have any affect on this? Where are they stored in the Cube IDE project?

Thanks in advance for your reply.

For CubeIDE (GNU/GCC) the stack/heap generally commingled, and are called out in the linker script. The actually allocator code is actually in the __sbrk() code in newlibs.c or syscalls.c

Generally you want the stack in the fastest available memory (DTCM SRAM)

The H7 has some particularly difficult memory/dma controller issues, so one must pay attention to memory alignment, and cache coherency.

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