2025-09-29 5:35 PM
Hello wonderful STM community!
I have identified a possible bug in the HAL Layer for the SDMMC peripheral. First time filing a bug report so please let me know if I miss anything import or if I'm completely wrong
MCU: STM32H5
Firmware Package: STM32Cube FW_H5 V1.5.0
Board: Custom
CubeIDE Version: 1.18.1
Please ask if anything else should be included here!
For a (u)SD to init it needs the clock speed to be slowed down to 400 kHz or lower, init commands and are then sent before the clock is then taken back up to speed. See this electrical engineering post for a good explanation and further reading.
uSD does not init correctly and does not return card info
In the file stm32h5xx_hal_sd.c (under HAL Drivers) and the function:
HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
There are two relevant lines:
Line 494:
Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ);
Line 519:
sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
In Line 494 the division will round down which can result in a clockDiv that will clock the SD slightly above the required 400 kHz. See calculations bellow:
sdmmc_clk = 3000000 (3 MHz)
SD_INIT_FREQ = 400000 (400 kHz)
Init.ClockDiv = 3000000 (3 MHz) / (2U * 400000 (400 kHz));
Init.ClockDiv = 3.75 // This will be rounded down to 3
sdmmc_clk = 3000000/ (2U * 3);
sdmmc_clk = 500000 (500 kHz) // Greater then SD_INIT_FREQ of 400 kHz
// If we use the actual ClockDiv of 3.75:
sdmmc_clk = 3000000/ (2U * 3.75);
sdmmc_clk = 400000 (400 kHz) // Matches SD_INIT_FREQ of 400 kHz
Set:
sdmmc_clk % 400000 != 0
Set:
sdmmc_clk % 400000 == 0
if (sdmmc_clk % SD_INIT_FREQ != 0)
Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ) + 1;
else:
Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ)
If the clk can't be divided down to 400 kHz with a clockDiv, divide it down as close as possible then to insure the result frequency will be less then 400 kHz add one to the clockDiv so that the sdmmc is clocked down bellow 400 kHz .
If it can be divided down to exactly 400 kHz (preferred) then do so.
Again, I'm a mere second year computer engineer so I might be completely wrong with the above so please bare with me and provide constructive feedback.
Cheers,
Michael