cancel
Showing results for 
Search instead for 
Did you mean: 

SDCARD does not work with 4bits wide bus

JBond.1
Senior

Hi I have STM32F407 and after updating STM32CubeMX 6.6.1 -> 6.9.2 I faced the same issue with SD card:
https://community.st.com/t5/stm32cubemx-mcus/sdcard-does-not-work-fr-not-ready-when-migrating-from-fw-f4-v1/m-p/115499#M3876

It seems that with previous version we were working with 1bit wide bus even if we set 4bit wide bus. Although GPIOS were set for 4bits (SDIO_D0, SDIO_D1, SDIO_D2, SDIO_D3).


So after upgrading it changed to 4bits wide bus, but now we get `FR_NOT_READY`, `HAL_SD_ERROR_REQUEST_NOT_APPLICABLE`

/* If requested card supports wide bus operation */
  if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO)
  {
    //...
    return HAL_SD_ERROR_NONE;
  }
  else
  {
    return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
  }

 

How do I fix this and make SD card work with 4bits wide bus?

8 REPLIES 8
JBond.1
Senior

I think STM32CubeMX has introduced a bug?

Initialization needs to be done with 1B and after that it should switch to 4B mode?

 

static void MX_SDIO_SD_Init(void)
{

  /* USER CODE BEGIN SDIO_Init 0 */

  /* USER CODE END SDIO_Init 0 */

  /* USER CODE BEGIN SDIO_Init 1 */

  /* USER CODE END SDIO_Init 1 */
  hsd.Instance = SDIO;
  hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  hsd.Init.BusWide = SDIO_BUS_WIDE_4B; // Initialization needs to be done with 1B?
  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd.Init.ClockDiv = 12;
  /* USER CODE BEGIN SDIO_Init 2 */
  hsd.Init.BusWide = SDIO_BUS_WIDE_1B; // FIX?
  /* USER CODE END SDIO_Init 2 */

}

 

Now we need to override `hsd.Init.BusWide = SDIO_BUS_WIDE_1B;` for initialization to use 1bit and after initialization it switches to 4bit, no?

 

__weak uint8_t BSP_SD_Init(void)
{
  uint8_t sd_state = MSD_OK;
  /* Check if the SD card is plugged in the slot */
  if (BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR;
  }
  /* HAL SD initialization */
  sd_state = HAL_SD_Init(&hsd);
  /* Configure SD Bus width (4 bits mode selected) */
  if (sd_state == MSD_OK)
  {
    /* Enable wide operation */
    if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
    {
      sd_state = MSD_ERROR;
    }
  }

  return sd_state;
}

 

Can STM32CubeMX team comment on this?

So STM32CubeMX 6.6.1 was correct and new versions have introduced a bug?

just search here in forum - see discussion + solution .

If you feel a post has answered your question, please click "Accept as Solution".
TDK
Guru

There is this thread:

https://community.st.com/t5/stm32cubemx-mcus/sdcard-does-not-work-fr-not-ready-when-migrating-from-fw-f4-v1/td-p/115499

But it looks like the ST member who responded doesn't realize how SD works and thinks the change was a fix, rather than a bug/regression. So good luck with that.

If you feel a post has answered your question, please click "Accept as Solution".
Ghofrane GSOURI
ST Employee

Hello @JBond.1 @TDK @AScha.3 

Thank you all  for your detailed explanation , and it's thanks to your contribution  that we're going to have a more mature version of MX.

An internal ticket is raised to dev team in order to fix this issue asap .

Internal ticket number: 155983 

 

Ghofrane

 

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.

It does not work for me too.

My experience is the following: HAL_SD_Init() is being called twice. The first time is from MX_SDMMC1_SD_Init(). This time, SD_WideBus_Enable() works fine and returns HAL_SD_ERROR_NONE:

Thread #1 [main] 1 [core: 0] (Suspended : Breakpoint)
        SD_WideBus_Enable() at stm32h7xx_hal_sd.c:3,473 0x800bd84
        HAL_SD_ConfigWideBusOperation() at stm32h7xx_hal_sd.c:2,423 0x800b66c
        HAL_SD_Init() at stm32h7xx_hal_sd.c:433 0x800a94e
        MX_SDMMC1_SD_Init() at main.c:399 0x8000c8c
        main() at main.c:157 0x80008a8

The second time, it is called from BSP_SD_Init():

Thread #1 [main] 1 [core: 0] (Suspended : Breakpoint)
        SD_WideBus_Enable() at stm32h7xx_hal_sd.c:3,473 0x800bd84
        HAL_SD_ConfigWideBusOperation() at stm32h7xx_hal_sd.c:2,423 0x800b66c
        HAL_SD_Init() at stm32h7xx_hal_sd.c:433 0x800a94e
        BSP_SD_Init() at bsp_driver_sd.c:50 0x800fb16
        SD_initialize() at sd_diskio.c:155 0x800fce6
        disk_initialize() at diskio.c:60 0x800ffd0
        f_mkfs() at ff.c:5,334 0x8012280
        main() at main.c:180 0x800090c

 

This time it fails with HAL_SD_ERROR_REQUEST_NOT_APPLICABLE. It boils down to this code:

/* If requested card supports wide bus operation */
if ((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO) {
        /* Send CMD55 APP_CMD with argument as card's RCA.*/
        errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
        if (errorstate != HAL_SD_ERROR_NONE) {
               return errorstate;
        }

        /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
        errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U);
        if (errorstate != HAL_SD_ERROR_NONE) {
               return errorstate;
        }

        return HAL_SD_ERROR_NONE;
} else {
        return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
}

 Either HAL_SD_Init() should be an idempotent thing, i.e., it should be possible to call it several times in a row without problems, or care should be taken to call HAL_SD_DeInit() before calling HAL_SD_Init() again. After the first call, something happens and it doesn't return to the initial state.

In order to fix that issue, I have put some code in HAL_SD_MspInit() to poweroff the SD:

void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
{
        GPIO_InitTypeDef GPIO_InitStruct = {0};
        RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
        if (hsd->Instance == SDMMC1) {
        /* USER CODE BEGIN SDMMC1_MspInit 0 */
               (void)SDMMC_PowerState_OFF(hsd->Instance);
        /* USER CODE END SDMMC1_MspInit 0 */
...

Now HAL_SD_Init() works always. But the code fails soon after for the same reason, because BSP_SD_Init() insists on calling HAL_SD_ConfigWideBusOperation(), which effectivelly is called a third time.

 

Currently, I have commented the call to HAL_SD_ConfigWideBusOperation() in BSP_SD_Init(). The f_mkfs() now succeeds, but I still have issues with f_open(). On my next debug session, I hope I can report some success then.

 

Regards,

Marcelo.

1. set 1-bit mode (more easy to begin, less problems with lines/ringing)

2. set port/pins pullup + speed medium

3. clock smmc with 50MHz , or lower until its working.

4. never mkfs !!! no write ! only read at beginning, otherwise good chance to destroy sd-card.

5. use "good" card (and test in PC first, put some file there, to test reading) i use only SanDisk .

6. about init...maybe you have set "too much" : try to set > no function call  to sd_init

AScha3_0-1701418065148.png

 

 

If you feel a post has answered your question, please click "Accept as Solution".
Marcelo Jimenez
Associate III

Hi,

After some debugging, I found that there is a parameter called SDMMC clock divide factor that defaults to zero. The path to it is Connectivity -> SDMMC1 -> Configuration -> Parameter Settings -> SDMMC clock divide factor. I have set it to 1, which means one half of the kernel clock frequency, and now everything works, even with the triple initialization. I had 200 MHz in the original frequency, so I think this means the controller will operate at 100 MHz.

 

I suggest anyone with a similar problem to test increasing this parameter until the device works, maybe to a binary search, should take less than 10 attempts.

 

By the way, I am using 4 bit mode, so I still hope I can get a good speed from the card. Still, without a level converter circuit to 1.8 Volts, I know it is not possible to go full speed.

 

I did some changes to the original code, which I got from a tutorial video from ST. If anyone is interested, here is the code:

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_MDMA_Init();
MX_ADC3_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
MX_SDMMC1_SD_Init();
MX_FATFS_Init();
/* USER CODE BEGIN 2 */
...
res = f_mkfs((TCHAR const *)"", FM_ANY, 0, rtext, sizeof rtext);
if (res != FR_OK) {
        Error_Handler();
}
res = f_mount(&SDFatFS, (TCHAR const *)"", 1);
if (res != FR_OK) {
        Error_Handler();
}
// Open file for writing (Create)
res = f_open(&SDFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE);
if (res != FR_OK) {
        Error_Handler();
}
// Write to the text file
res = f_write(&SDFile, wtext, strlen((char *)wtext), (void *)&bytes_written);
if ((bytes_written == 0) || (res != FR_OK)) {
        Error_Handler();
}
f_close(&SDFile);
/* FS == NULL -> umount */
res = f_mount(NULL, "", 0);
/* USER CODE END 2 */

 

btw

i wrote, you should set a max. clk of 50MHz...

>3. clock smmc with 50MHz , or lower until its working.

If you feel a post has answered your question, please click "Accept as Solution".