2025-09-25 2:11 AM - last edited on 2025-09-25 2:28 AM by mƎALLEm
Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code
Hi everyone,
I’m interfacing a microSD card with an STM32U575 microcontroller using the SDMMC1 peripheral. In my project (generated by CubeIDE) I’m using the MX_SDMMC1_SD_Init( ) function to initialize the peripheral. Everything works fine when the card is inserted.
The problem occurs when I remove the microSD card (or if it’s not inserted at all): during initialization, the code stops at this point:
/* Identify card operating voltage */
errorstate = SD_PowerON(hsd);
if (errorstate != HAL_SD_ERROR_NONE)
{
hsd->State = HAL_SD_STATE_READY;
hsd->ErrorCode |= errorstate;
return HAL_ERROR;
}
This condition returns HAL_ERROR, which is then handled by the default Error_Handler( ) function.
However, the default Error_Handler( ) generated by CubeIDE contains a while(1) loop, which completely
blocks the system.
I’m wondering if this behavior is “normal”:
Is it expected that when the SD card is not present, the initialization fails and the code ends up in a blocking while(1)?
Shouldn’t the peripheral simply return an initialization error, allowing the firmware to handle it gracefully without blocking the entire system?
In other words, what is the correct way to handle the absence of the SD card (or a failed initialization) so that the
firmware can continue running and handle the error more gracefully instead of entering an infinite loop inside Error_Handler( )?
Any advice or best practices on how to properly manage this scenario?
Thanks in advance!
2025-09-30 6:38 AM
Hello @StefanoSperandio_ST
The Error_Handler function is actually a weak function defined in the main.c. and you can edit the code between the User code section or better provide your own implementation of Error_Handler().
KR,
Souhaib
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-10-14 2:57 AM
Same problem here:
The void MX_SDMMC1_SD_Init(void) generated by CubeMx V6.15.0 calls HAL_SD_Init(&hsd1) which tries to connect to the SD card during initialization.
If no SD card is present at start-up, we end-up in the Error_Handler function.
This was not the case with CubeMx V6.14.0.
Code generated by STM32CubeMx V6.14.0, STM32Cube FW_H7 V1.12.1:
void MX_SDMMC1_SD_Init(void)
{
/* USER CODE BEGIN SDMMC1_Init 0 */
/* USER CODE END SDMMC1_Init 0 */
/* USER CODE BEGIN SDMMC1_Init 1 */
/* USER CODE END SDMMC1_Init 1 */
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd1.Init.ClockDiv = 4;
if (HAL_SD_Init(&hsd1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SDMMC1_Init 2 */
/* USER CODE END SDMMC1_Init 2 */
}
Code generated by STM32CubeMx V6.15.0, STM32Cube FW_H7 V1.12.1:
void MX_SDMMC1_SD_Init(void)
{
/* USER CODE BEGIN SDMMC1_Init 0 */
/* USER CODE END SDMMC1_Init 0 */
/* USER CODE BEGIN SDMMC1_Init 1 */
/* USER CODE END SDMMC1_Init 1 */
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd1.Init.ClockDiv = 4;
/* USER CODE BEGIN SDMMC1_Init 2 */
/* USER CODE END SDMMC1_Init 2 */
}
2025-10-14 3:04 AM
@franck23 wrote:we end-up in the Error_Handler function.
So use the debugger to find out how you got there.
As @Souhaib MAZHOUD said back in 2025, you can customise the error handler to give you more & better information to assist in debugging; eg, passing __FILE__ and __LINE__ might help...
On debugging Hard Faults:
2025-10-14 6:13 AM
How we get to the error handler is explained in my message.
The issue is the implementation of MX_SDMMC1_SD_Init that has changed in the last version of CubeMX.
Fixing the issue is easy enough, just re-implement the initialization and return without calling HAL_SD_Init.
I am flagging the issue in the forum so that other people like Stephano can fix it in there code.
void MX_SDMMC1_SD_Init(void)
{
/* USER CODE BEGIN SDMMC1_Init 0 */
// CubeMx V6.15.0 calls HAL_SD_Init() which attempt to communicate with the SD card.
// The SD card may not be present at start-up and it send us straight to the Error_Handler function.
// Here we do the same initialization routine as below but we return before calling HAL_SD_Init();
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd1.Init.ClockDiv = 4;
return;
/* USER CODE END SDMMC1_Init 0 */
/* USER CODE BEGIN SDMMC1_Init 1 */
/* USER CODE END SDMMC1_Init 1 */
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd1.Init.ClockDiv = 4;
if (HAL_SD_Init(&hsd1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SDMMC1_Init 2 */
/* USER CODE END SDMMC1_Init 2 */
}