2023-01-19 09:07 AM
Hello,
I'm currently facing an issue with a basic project to setup the SDMMC1 peripheral where the function HAL_SD_Init() fails. The issue is happening inside HAL_SD_Init(), in SD_PowerON(), where it always returns HAL_SD_ERROR_UNSUPPORTED_FEATURE.
I'm using a custom board with the STM32H743XI MCU with an external clock of 26MHz and the STM32CubeH7_FW_H7_V1.11.0 package.
Please find below a picture of the STM32CubeMX Clock configuration:
Here is the code that setup the clock:
void hw_port_clock_init(void)
{
hw_clock_system_clock_init();
hw_clock_init_peripheral_clocks();
}
static void hw_clock_system_clock_init(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
// Supply configuration update enable
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
// Configure the main internal regulator output voltage
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY))
{
}
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY))
{
}
// Initializes the RCC Oscillators according to the specified parameters in the
RCC_OscInitTypeDef structure.
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 13;
RCC_OscInitStruct.PLL.PLLN = 480;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 24;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
assert_param(HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK);
// Initializes the CPU, AHB and APB buses clocks
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1 |
RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
assert_param(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) == HAL_OK);
}
static void hw_clock_init_peripheral_clocks(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC;
PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
assert_param(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) == HAL_OK);
// Enable GPIOs clock
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
// Enable SDIO clock
__HAL_RCC_SDMMC1_CLK_ENABLE();
}
Ans here is the SDMMC1 init code (4bits wide bus):
void hw_port_sd_init(void)
{
/** SDMMC1 GPIO Configuration
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
*/
GPIO_InitTypeDef gpio_init_structure = { 0 };
gpio_init_structure.Pin = GPIO_MICROSD_D0_PIN | GPIO_MICROSD_D1_PIN | GPIO_MICROSD_D2_PIN |
GPIO_MICROSD_D3_PIN | GPIO_MICROSD_CLK_PIN;
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init_structure.Alternate = GPIO_AF12_SDIO1;
HAL_GPIO_Init(GPIOC, &gpio_init_structure);
gpio_init_structure.Pin = GPIO_MICROSD_CMD_PIN;
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init_structure.Alternate = GPIO_MICROSD_CMD_AF;
HAL_GPIO_Init(GPIO_MICROSD_CMD_PORT, &gpio_init_structure);
__HAL_RCC_SDMMC1_FORCE_RESET();
__HAL_RCC_SDMMC1_RELEASE_RESET();
g_sd_handle.Instance = SDMMC1;
g_sd_handle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
g_sd_handle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
g_sd_handle.Init.BusWide = SDMMC_BUS_WIDE_4B;
g_sd_handle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
g_sd_handle.Init.ClockDiv = 0;
assert_param(HAL_SD_Init(&g_sd_handle) == HAL_OK);
// NVIC configuration for SDMMC1 interrupt
HAL_NVIC_SetPriority(SDMMC1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
}
The parameter USE_SD_TRANSCEIVER from stm32h7xx_hal_conf.h is set to 0.
Does anyone experienced this issue before ? Any help would be appreciated.
Many Thanks!
LB
Solved! Go to Solution.
2023-01-29 11:52 PM
Hi all,
Sorry for this late update...
Thanks for you help!
I managed to solve my problem, which was ultimately not related to the HAL library.
Basically, on the custom board I'm using, I have to enable the 5V power supply via a GPIO. This 5V is necessary for the SD card to function. So without enabling 5V on my system, the SD card will not work.
I had correctly activated it just before initializing the HAL SD, but it seems that a delay is needed between the two to allow the 5v to stabilize throughout the custom board.
HAL_Init();
hw_port_clock_init();
hw_port_gpio_init();
// Enable 5V critical needed for the SD card
hw_port_gpio_pwr_5v_critical_enable();
while(hw_port_gpio_get_5v_critical_pg_state() == 0)
{
}
// This delay is necessary to allow 5v to stabilise throughout the system.
// We have seen that without this delay, the initialization of the SD fails
HAL_Delay(5);
// SD card must be plugged in !!!
assert_param(hw_port_gpio_is_sd_detected());
hw_port_sd_init();
The funny thing is that I already waited for the PGOOD pin of the 5V regulator to be HIGH before initializing the HAL SD but that was not enough, the 5ms delay is necessary.
In conclusion, this problem was not related to the HAL library but specific to the custom board I use.
cheers,
LB
2023-01-20 02:50 AM
I dug a little deeper and found that if I increase the delay that is done just before SD_PowerON(), it works fine.
Where the issue is located: HAL_SD_Init() -> HAL_SD_InitCard()
HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
{
uint32_t errorstate;
SD_InitTypeDef Init;
uint32_t sdmmc_clk;
/* Default SDMMC peripheral configuration for SD card initialization */
Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
Init.BusWide = SDMMC_BUS_WIDE_1B;
Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
/* Init Clock should be less or equal to 400Khz*/
sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
if (sdmmc_clk == 0U)
{
hsd->State = HAL_SD_STATE_READY;
hsd->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
return HAL_ERROR;
}
Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ);
/* Initialize SDMMC peripheral interface with default configuration */
(void)SDMMC_Init(hsd->Instance, Init);
/* Set Power State to ON */
(void)SDMMC_PowerState_ON(hsd->Instance);
/* wait 74 Cycles: required power up waiting time before starting
the SD initialization sequence */
if (Init.ClockDiv != 0U)
{
sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
}
if (sdmmc_clk != 0U)
{
HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
}
/* 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;
}
...
}
The first steps of the HAL_SD_InitCard() must be performed with a clock that is less than or equal to 400Khz. My SDMMC clock is configured to 40Mhz so the code inside HAL_SD_InitCard() divide it to match the 400Khz requirements.
Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ);
Init.ClockDiv = 40000000 / (2 * 400000) = 50
sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
sdmmc_clk = 40000000 / (2 * 50) = 400000
HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
HAL_Delay(1 + (74 * 1000 / 400000))
=> HAL_Delay(1.185)
But a delay of 1.185ms seems too low and makes the SD_PowerON() function fail.
Obviously touching this delay and the code inside the stm32 hal library is not a solution, so I don't know what I could change in the application to make it work.
2023-01-20 04:21 AM
on my H743 board here i use this setting :
try this settings. there never was a startup problem; just "very high" port speed may not work, try medium or high.
2023-01-28 11:15 PM
hi,
same issue with maine for controller-STM32H723VGT6.
After a deeply study ,i also found issue with sd card initialization on the level of.....
if (hsd->SdCard.CardVersion == CARD_V2_X)
{
/* SEND CMD55 APP_CMD with RCA as 0 */
errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0);
if (errorstate != HAL_SD_ERROR_NONE)
{
return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
}
}
please share the solution ,how you have been resolved .
2023-01-29 11:52 PM
Hi all,
Sorry for this late update...
Thanks for you help!
I managed to solve my problem, which was ultimately not related to the HAL library.
Basically, on the custom board I'm using, I have to enable the 5V power supply via a GPIO. This 5V is necessary for the SD card to function. So without enabling 5V on my system, the SD card will not work.
I had correctly activated it just before initializing the HAL SD, but it seems that a delay is needed between the two to allow the 5v to stabilize throughout the custom board.
HAL_Init();
hw_port_clock_init();
hw_port_gpio_init();
// Enable 5V critical needed for the SD card
hw_port_gpio_pwr_5v_critical_enable();
while(hw_port_gpio_get_5v_critical_pg_state() == 0)
{
}
// This delay is necessary to allow 5v to stabilise throughout the system.
// We have seen that without this delay, the initialization of the SD fails
HAL_Delay(5);
// SD card must be plugged in !!!
assert_param(hw_port_gpio_is_sd_detected());
hw_port_sd_init();
The funny thing is that I already waited for the PGOOD pin of the 5V regulator to be HIGH before initializing the HAL SD but that was not enough, the 5ms delay is necessary.
In conclusion, this problem was not related to the HAL library but specific to the custom board I use.
cheers,
LB
2023-01-30 02:41 AM
hi,
i have some query, please come in your Message Box.
Thanking you
2023-01-30 07:46 PM
hi LB.2 (Community Member)
we have some doubt,please need your help.
Please Clear the function ....
which level shifter ic you have used.
please share connection diagram also,if it possible.
thanking you
2023-02-01 08:30 PM
Hi @Loïc B ,
Please check your message box,i need your help.
we are still waiting of your response!
Thanking you