Skip to content

Conversation

@Avlaak
Copy link

@Avlaak Avlaak commented Dec 14, 2025

Problem
When hsd->Init.BusWide is set to SDIO_BUS_WIDE_4B, the SD card fails to initialize. Users are forced to use a workaround: set BusWide = SDIO_BUS_WIDE_1B and manually call HAL_SD_ConfigWideBusOperation() afterward.

This issue was discussed in the ST Community forum:
Running SDIO 4BIT wide mode

The recommended workaround requires users to modify MX_SDIO_SD_Init() and is inconsistent with the STM32H7 HAL behavior where 4-bit mode works out of the box.

Root Cause
In the internal function SD_InitCard(), the SDIO peripheral was reconfigured with user parameters including BusWide:

/* Configure SDIO peripheral interface */
(void)SDIO_Init(hsd->Instance, hsd->Init);

At this point, the SD card has not received the ACMD6 command to switch bus width. This causes desynchronization:

  • SDIO controller operates in 4-bit mode
  • SD card still operates in 1-bit mode
  • All subsequent data transfers fail

Solution
Two changes were made to align STM32F4 HAL behavior with STM32H7 HAL:

  1. Fixed SDIO_Init() call in SD_InitCard() to force 1-bit bus width. The SDIO peripheral reconfiguration now explicitly sets 1-bit bus width while preserving other user settings (ClockDiv, ClockEdge, etc.): This ensures the SDIO controller and SD card remain synchronized in 1-bit mode until proper bus width switching via ACMD6.

  2. Added automatic bus width configuration in HAL_SD_Init(). After successful card initialization, HAL_SD_Init() now automatically calls HAL_SD_ConfigWideBusOperation() to apply the user-specified bus width, followed by a readiness check:

/* Configure the bus wide */
if (HAL_SD_ConfigWideBusOperation(hsd, hsd->Init.BusWide) != HAL_OK)
{
  return HAL_ERROR;
}

/* Verify that SD card is ready to use after Initialization */
tickstart = HAL_GetTick();
while ((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER))
{
  if ((HAL_GetTick() - tickstart) >=  SDMMC_SWDATATIMEOUT)
  {
    hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT;
    hsd->State = HAL_SD_STATE_READY;
    return HAL_TIMEOUT;
  }
}

This is consistent with the STM32H7 HAL implementation where this exact code exists and works correctly.

Benefits

  • No workarounds needed: Users can set BusWide = SDIO_BUS_WIDE_4B in CubeMX and it just works
  • Simplified BSP code: BSP_SD_Init() no longer needs to call HAL_SD_ConfigWideBusOperation() manually
  • Consistency: STM32F4 HAL now behaves identically to STM32H7 HAL
  • Backward compatible: Applications already calling HAL_SD_ConfigWideBusOperation() manually will continue to work (the call is idempotent)

@ALABSTM ALABSTM added bug Something isn't working hal HAL-LL driver-related issue or pull-request. sdmmc Secure Digital input/output Multimedia Card interface sd Secure Digital interface labels Dec 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working hal HAL-LL driver-related issue or pull-request. sd Secure Digital interface sdmmc Secure Digital input/output Multimedia Card interface

Projects

Development

Successfully merging this pull request may close these issues.

3 participants