cancel
Showing results for 
Search instead for 
Did you mean: 

SD Card problem with sd-diskio.c generation

CYBR
Associate II

I have a simple program using Touchgfx and Freertos running on the following:

STM32H735G-DK

STM32CubeIDE V 1.19.0

STM32Cube_FW_H7_V1.12.1

I have enabled SDMMC1 (in 1 bit mode, but 4 bit is the same), configured FATFS, and created a task to mount the SD card and open a file, from a button on a touchgfx screen. The card is formatted for FAT16, but format type makes no difference.

f_mount fails every time with mostly file system not found, and sometimes disk error.

After weeks of painstaking step by step debugging, I realized the problem occurs at line 274 in sd_diskio.c:

if (!((uint32_t)buff & 0x3))

This file is automatically generated by CubeMX as part of the generation process. Once generated, this file has two user options, which are both required when using the H7 to enable cache maintenance:

#define ENABLE_SD_DMA_CACHE_MAINTENANCE 1

#define ENABLE_SCRATCH_BUFFER

With the scratch buffer enabled, this line is supposed to check whether the fs-win buffer where the SD card sector will be loaded to is 32-byte aligned, which is required to ensure the internal DMA loads correctly. A subsequent line then invalidates the cache and updates the data storage. If the result of this test is true, the next block of code thinks it is 32 byte aligned and loads the sector at the buffer address. (If it fails, a 32 byte aligned scratch buffer is used instead).

The bug is that this test is incorrect. Line 274 should read:

if (!((uint32_t)buff & 0x1F))

to properly test for 32 byte alignment. In my case, it happens that the buffer is not 32-byte aligned (the actual address is 240008b4), but because the 2 LSBs just happen to be zero, it actually passes the faulty test. The result of this bug is that the next block of code reads the sector into a non-32 byte aligned buffer, and the first 12 or so bytes of the buffered sector read are cleared to zero. This stops the code from confirming the read sector is in fact a proper FAT sector, because that test checks for 0XEB in the first read byte, which fails.

I proved this was the problem by editing the sd-diskio.c file, and everything works perfectly.

The problem is that every time I regenerate the code, the edit is lost and the error is back. So I tried looking for the library file source for sd-diskio.c. According to the header at the top, this file is generated from:

Note: code generation based on sd_diskio_dma_rtos_template_bspv1.c v2.1.4

This file is located in:

STM32Cube\Repository\STM32Cube_FW_H7_V1.12.1\Middlewares\Third_Party\FatFs\src\drivers

It is there, but when I check this file, the corresponding line is correct:

if (!((uint32_t)buff & 0x1F))

Also the date of the generated sd-diskio.c is:

Copyright (c) 2025 STMicroelectronics.

but the date of the template file is:

Copyright (c) 2017 STMicroelectronics. All rights reserved.

So clearly the generated file does not come from this template.

So my question is where does it come from, and how can I correct the actual source template so that code generation does not keep recreating this bug?

0 REPLIES 0