Skip to main content
Associate III
September 25, 2025
Question

STM32U575 - SD card Hard Fault

  • September 25, 2025
  • 3 replies
  • 1186 views

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!

 

3 replies

Technical Moderator
September 30, 2025

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.
franck23
Associate III
October 14, 2025

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 */
}

 

 

Andrew Neil
Super User
October 14, 2025

@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:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/tac-p/708193/highlight/true#M51

 

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
franck23
Associate III
October 14, 2025

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 */

}