Skip to main content
Visitor II
January 19, 2023
Solved

STM32H743XI SDMMC1 SD Card - HAL_SD_ERROR_UNSUPPORTED_FEATURE

  • January 19, 2023
  • 5 replies
  • 5562 views

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.

0693W00000Y8g2QQAR.png 

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:

0693W00000Y8g0PQAR.png0693W00000Y8g0jQAB.pngHere 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

    This topic has been closed for replies.
    Best answer by LB.2

    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

    5 replies

    LB.2Author
    Visitor II
    January 20, 2023

    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.

    Visitor II
    January 29, 2023

    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 .

    https://community.st.com/s/question/0D53W00000QvljESAR/4-bit-sdio-sd-card-sdmmc-issue-on-nucleoh723zg-stm32h723zg-stm32h7

    Super User
    January 20, 2023

    on my H743 board here i use this setting :

    0693W00000Y8lNdQAJ.png0693W00000Y8lOCQAZ.png0693W00000Y8lOWQAZ.png 

    0693W00000Y8lOgQAJ.png0693W00000Y8lP0QAJ.pngtry this settings. there never was a startup problem; just "very high" port speed may not work, try medium or high.

    LB.2AuthorAnswer
    Visitor II
    January 30, 2023

    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

    Visitor II
    January 31, 2023

    hi LB.2 (Community Member)

    we have some doubt,please need your help.

    Please Clear the function ....

    1. hw_port_gpio_pwr_5v_critical_enable();
    2. Have you used level shifter(USE_SD_TRANSCEIVER ) for MicroSD Card Communuication.

    which level shifter ic you have used.

    please share connection diagram also,if it possible.

    thanking you

    Visitor II
    February 2, 2023

    Hi @Loïc B​ ,

    Please check your message box,i need your help.

    we are still waiting of your response!

    Thanking you