Skip to main content
FPlow.1
Associate
February 10, 2023
Solved

STM32CubeMX 6.7.0 does not configure SDMMC DMA correctly

  • February 10, 2023
  • 1 reply
  • 1299 views

I am having an issue similar to https://community.st.com/s/question/0D53W000027iXpbSAE/spi-dma-configuration-generated-by-stm32cubemx-does-not-work but with the SDMMC peripheral rather than SPI.

I have an STM32CubeMX project targeting the 32F746GDISCOVERY with the following relevant peripherals and settings:

  • SDMMC SD 4 Bits Wide bus
    • SDMMC1 global interrupt enabled
    • SDMMC1 bidirectional DMA request enabled on DMA2 stream 3
  • FatFS enabled with DMA template

With the above STM32CubeMX configuration and the minimum working example below:

#define TEST_DATA_SIZE 32768
 
// -- snip
 
static FRESULT fatfs_err;
static const unsigned char test_data[TEST_DATA_SIZE] __attribute__ ((section (".dtcm"), aligned (4))) = {0};
static unsigned int bytes;
 
// -- snip
 
int main(void) {
 // -- snip
 
 fatfs_err = f_mount(&SDFatFS, SDPath, 1);
 if (fatfs_err != FR_OK) {
 printf("failed to mount card, code: %i.\n", fatfs_err);
 if (fatfs_err != FR_NOT_READY) {
 printf("exiting.\n");
 exit(fatfs_err);
 }
 printf("continuing.\n");
 }
 
 // Open file
 fatfs_err = f_open(&SDFile, "test.txt", FA_WRITE | FA_CREATE_ALWAYS);
 if (fatfs_err != FR_OK) {
 printf("failed to open file, code: %i.\n", fatfs_err);
 printf("exiting.\n");
 exit(fatfs_err);
 }
 
 // Write file
 fatfs_err = f_write(&SDFile,
 test_data,
 TEST_DATA_SIZE,
 &bytes);
 if (fatfs_err != FR_OK) {
 printf("failed to write file, code: %i\n", fatfs_err);
 printf("exiting.\n");
 exit(fatfs_err);
 }
 if (bytes != TEST_DATA_SIZE) {
 printf("wrote %i bytes, less than the expected %i.\n",
 bytes, TEST_DATA_SIZE);
 }
 
 // Close file
 fatfs_err = f_close(&SDFile);
 if (fatfs_err != FR_OK) {
 exit(fatfs_err);
 }
 
 // -- snip

The project works fine on 6.6.1, but as soon as I migrate to 6.7.0 the SDMMC peripheral times out. Specifically, it hangs on line 220 of sd_diskio.c, while waiting for a DMA callback.

This topic has been closed for replies.
Best answer by FPlow.1

Where 661 and 670 are STM32CubeIDE projects generated by STM32CubeMX 6.6.1 and 6.7.0, respectively, this command:

diff -r 661 670 --exclude ".project" --exclude ".cproject" --exclude ".settings" --exclude "Debug"

produces the following output

Only in 661: 661 Debug.launch
Only in 661: 661.ioc
Only in 670: 670 Debug.launch
Only in 670: 670.ioc
diff -r --ex 661/Core/Inc/main.h 670/Core/Inc/main.h
383a384
> 
diff -r --ex 661/Core/Inc/stm32f7xx_hal_conf.h 670/Core/Inc/stm32f7xx_hal_conf.h
40,62c40,61
< /* #define HAL_ADC_MODULE_ENABLED */
< /* #define HAL_CRYP_MODULE_ENABLED */
< /* #define HAL_CAN_MODULE_ENABLED */
< /* #define HAL_CEC_MODULE_ENABLED */
< /* #define HAL_CRC_MODULE_ENABLED */
< /* #define HAL_CRYP_MODULE_ENABLED */
< /* #define HAL_DAC_MODULE_ENABLED */
< /* #define HAL_DCMI_MODULE_ENABLED */
< /* #define HAL_DMA2D_MODULE_ENABLED */
< /* #define HAL_ETH_MODULE_ENABLED */
< /* #define HAL_NAND_MODULE_ENABLED */
< /* #define HAL_NOR_MODULE_ENABLED */
< /* #define HAL_SRAM_MODULE_ENABLED */
< /* #define HAL_SDRAM_MODULE_ENABLED */
< /* #define HAL_HASH_MODULE_ENABLED */
< /* #define HAL_I2S_MODULE_ENABLED */
< /* #define HAL_IWDG_MODULE_ENABLED */
< /* #define HAL_LPTIM_MODULE_ENABLED */
< /* #define HAL_LTDC_MODULE_ENABLED */
< /* #define HAL_QSPI_MODULE_ENABLED */
< /* #define HAL_RNG_MODULE_ENABLED */
< /* #define HAL_RTC_MODULE_ENABLED */
< /* #define HAL_SAI_MODULE_ENABLED */
---
> /* #define HAL_CRYP_MODULE_ENABLED */
> /* #define HAL_ADC_MODULE_ENABLED */
> /* #define HAL_CAN_MODULE_ENABLED */
> /* #define HAL_CEC_MODULE_ENABLED */
> /* #define HAL_CRC_MODULE_ENABLED */
> /* #define HAL_DAC_MODULE_ENABLED */
> /* #define HAL_DCMI_MODULE_ENABLED */
> /* #define HAL_DMA2D_MODULE_ENABLED */
> /* #define HAL_ETH_MODULE_ENABLED */
> /* #define HAL_NAND_MODULE_ENABLED */
> /* #define HAL_NOR_MODULE_ENABLED */
> /* #define HAL_SRAM_MODULE_ENABLED */
> /* #define HAL_SDRAM_MODULE_ENABLED */
> /* #define HAL_HASH_MODULE_ENABLED */
> /* #define HAL_I2S_MODULE_ENABLED */
> /* #define HAL_IWDG_MODULE_ENABLED */
> /* #define HAL_LPTIM_MODULE_ENABLED */
> /* #define HAL_LTDC_MODULE_ENABLED */
> /* #define HAL_QSPI_MODULE_ENABLED */
> /* #define HAL_RNG_MODULE_ENABLED */
> /* #define HAL_RTC_MODULE_ENABLED */
> /* #define HAL_SAI_MODULE_ENABLED */
64,80c63,79
< /* #define HAL_MMC_MODULE_ENABLED */
< /* #define HAL_SPDIFRX_MODULE_ENABLED */
< /* #define HAL_SPI_MODULE_ENABLED */
< /* #define HAL_TIM_MODULE_ENABLED */
< /* #define HAL_UART_MODULE_ENABLED */
< /* #define HAL_USART_MODULE_ENABLED */
< /* #define HAL_IRDA_MODULE_ENABLED */
< /* #define HAL_SMARTCARD_MODULE_ENABLED */
< /* #define HAL_WWDG_MODULE_ENABLED */
< /* #define HAL_PCD_MODULE_ENABLED */
< /* #define HAL_HCD_MODULE_ENABLED */
< /* #define HAL_DFSDM_MODULE_ENABLED */
< /* #define HAL_DSI_MODULE_ENABLED */
< /* #define HAL_JPEG_MODULE_ENABLED */
< /* #define HAL_MDIOS_MODULE_ENABLED */
< /* #define HAL_SMBUS_MODULE_ENABLED */
< /* #define HAL_EXTI_MODULE_ENABLED */
---
> /* #define HAL_MMC_MODULE_ENABLED */
> /* #define HAL_SPDIFRX_MODULE_ENABLED */
> /* #define HAL_SPI_MODULE_ENABLED */
> /* #define HAL_TIM_MODULE_ENABLED */
> /* #define HAL_UART_MODULE_ENABLED */
> /* #define HAL_USART_MODULE_ENABLED */
> /* #define HAL_IRDA_MODULE_ENABLED */
> /* #define HAL_SMARTCARD_MODULE_ENABLED */
> /* #define HAL_WWDG_MODULE_ENABLED */
> /* #define HAL_PCD_MODULE_ENABLED */
> /* #define HAL_HCD_MODULE_ENABLED */
> /* #define HAL_DFSDM_MODULE_ENABLED */
> /* #define HAL_DSI_MODULE_ENABLED */
> /* #define HAL_JPEG_MODULE_ENABLED */
> /* #define HAL_MDIOS_MODULE_ENABLED */
> /* #define HAL_SMBUS_MODULE_ENABLED */
> /* #define HAL_EXTI_MODULE_ENABLED */
213c212
< #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
---
> #define ETH_RX_BUF_SIZE /* buffer size for receive */
diff -r --ex 661/Core/Src/main.c 670/Core/Src/main.c
218c218
< hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;
---
> hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
diff -r --ex 661/Core/Src/syscalls.c 670/Core/Src/syscalls.c
13c13
< * Copyright (c) 2022 STMicroelectronics.
---
> * Copyright (c) 2020-2022 STMicroelectronics.
50c50
< 	return 1;
---
> return 1;
55,56c55,58
< 	errno = EINVAL;
< 	return -1;
---
> (void)pid;
> (void)sig;
> errno = EINVAL;
> return -1;
61,62c63,64
< 	_kill(status, -1);
< 	while (1) {}		/* Make sure we hang here */
---
> _kill(status, -1);
> while (1) {} /* Make sure we hang here */
67c69,70
< 	int DataIdx;
---
> (void)file;
> int DataIdx;
69,72c72,75
< 	for (DataIdx = 0; DataIdx < len; DataIdx++)
< 	{
< 		*ptr++ = __io_getchar();
< 	}
---
> for (DataIdx = 0; DataIdx < len; DataIdx++)
> {
> *ptr++ = __io_getchar();
> }
74c77
< return len;
---
> return len;
79c82,83
< 	int DataIdx;
---
> (void)file;
> int DataIdx;
81,85c85,89
< 	for (DataIdx = 0; DataIdx < len; DataIdx++)
< 	{
< 		__io_putchar(*ptr++);
< 	}
< 	return len;
---
> for (DataIdx = 0; DataIdx < len; DataIdx++)
> {
> __io_putchar(*ptr++);
> }
> return len;
90c94,95
< 	return -1;
---
> (void)file;
> return -1;
96,97c101,103
< 	st->st_mode = S_IFCHR;
< 	return 0;
---
> (void)file;
> st->st_mode = S_IFCHR;
> return 0;
102c108,109
< 	return 1;
---
> (void)file;
> return 1;
107c114,117
< 	return 0;
---
> (void)file;
> (void)ptr;
> (void)dir;
> return 0;
112,113c122,125
< 	/* Pretend like we always fail */
< 	return -1;
---
> (void)path;
> (void)flags;
> /* Pretend like we always fail */
> return -1;
118,119c130,132
< 	errno = ECHILD;
< 	return -1;
---
> (void)status;
> errno = ECHILD;
> return -1;
124,125c137,139
< 	errno = ENOENT;
< 	return -1;
---
> (void)name;
> errno = ENOENT;
> return -1;
130c144,145
< 	return -1;
---
> (void)buf;
> return -1;
135,136c150,152
< 	st->st_mode = S_IFCHR;
< 	return 0;
---
> (void)file;
> st->st_mode = S_IFCHR;
> return 0;
141,142c157,160
< 	errno = EMLINK;
< 	return -1;
---
> (void)old;
> (void)new;
> errno = EMLINK;
> return -1;
147,148c165,166
< 	errno = EAGAIN;
< 	return -1;
---
> errno = EAGAIN;
> return -1;
153,154c171,175
< 	errno = ENOMEM;
< 	return -1;
---
> (void)name;
> (void)argv;
> (void)env;
> errno = ENOMEM;
> return -1;

Based on this, I tried changing

hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;

to

hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;

in the 6.7.0 project and it fixed the issue. Note this is not the same as running the card in 1-bit mode, the FatFS Disk I/O driver switches it to 4-bit mode later in initialisation:

~/SDMMC_STM32CubeMX_Test/661 % rg "SDMMC_BUS_WIDE_4B"
Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c
2180: * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2202: else if(WideMode == SDMMC_BUS_WIDE_4B)
 
Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_sdmmc.h
365:#define SDMMC_BUS_WIDE_4B SDMMC_CLKCR_WIDBUS_0
369: ((WIDE) == SDMMC_BUS_WIDE_4B) || \
 
Debug/661.list
10552: * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
10597: else if(WideMode == SDMMC_BUS_WIDE_4B)
14765: if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)
 
FATFS/Target/bsp_driver_sd.c
62: if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)

I'm not quite sure what the whole sequence is for initialisation in the SD specification, but I think the card has to be in 1-bit mode first in order to set up 4-bit mode.

1 reply

FPlow.1
FPlow.1AuthorBest answer
Associate
February 10, 2023

Where 661 and 670 are STM32CubeIDE projects generated by STM32CubeMX 6.6.1 and 6.7.0, respectively, this command:

diff -r 661 670 --exclude ".project" --exclude ".cproject" --exclude ".settings" --exclude "Debug"

produces the following output

Only in 661: 661 Debug.launch
Only in 661: 661.ioc
Only in 670: 670 Debug.launch
Only in 670: 670.ioc
diff -r --ex 661/Core/Inc/main.h 670/Core/Inc/main.h
383a384
> 
diff -r --ex 661/Core/Inc/stm32f7xx_hal_conf.h 670/Core/Inc/stm32f7xx_hal_conf.h
40,62c40,61
< /* #define HAL_ADC_MODULE_ENABLED */
< /* #define HAL_CRYP_MODULE_ENABLED */
< /* #define HAL_CAN_MODULE_ENABLED */
< /* #define HAL_CEC_MODULE_ENABLED */
< /* #define HAL_CRC_MODULE_ENABLED */
< /* #define HAL_CRYP_MODULE_ENABLED */
< /* #define HAL_DAC_MODULE_ENABLED */
< /* #define HAL_DCMI_MODULE_ENABLED */
< /* #define HAL_DMA2D_MODULE_ENABLED */
< /* #define HAL_ETH_MODULE_ENABLED */
< /* #define HAL_NAND_MODULE_ENABLED */
< /* #define HAL_NOR_MODULE_ENABLED */
< /* #define HAL_SRAM_MODULE_ENABLED */
< /* #define HAL_SDRAM_MODULE_ENABLED */
< /* #define HAL_HASH_MODULE_ENABLED */
< /* #define HAL_I2S_MODULE_ENABLED */
< /* #define HAL_IWDG_MODULE_ENABLED */
< /* #define HAL_LPTIM_MODULE_ENABLED */
< /* #define HAL_LTDC_MODULE_ENABLED */
< /* #define HAL_QSPI_MODULE_ENABLED */
< /* #define HAL_RNG_MODULE_ENABLED */
< /* #define HAL_RTC_MODULE_ENABLED */
< /* #define HAL_SAI_MODULE_ENABLED */
---
> /* #define HAL_CRYP_MODULE_ENABLED */
> /* #define HAL_ADC_MODULE_ENABLED */
> /* #define HAL_CAN_MODULE_ENABLED */
> /* #define HAL_CEC_MODULE_ENABLED */
> /* #define HAL_CRC_MODULE_ENABLED */
> /* #define HAL_DAC_MODULE_ENABLED */
> /* #define HAL_DCMI_MODULE_ENABLED */
> /* #define HAL_DMA2D_MODULE_ENABLED */
> /* #define HAL_ETH_MODULE_ENABLED */
> /* #define HAL_NAND_MODULE_ENABLED */
> /* #define HAL_NOR_MODULE_ENABLED */
> /* #define HAL_SRAM_MODULE_ENABLED */
> /* #define HAL_SDRAM_MODULE_ENABLED */
> /* #define HAL_HASH_MODULE_ENABLED */
> /* #define HAL_I2S_MODULE_ENABLED */
> /* #define HAL_IWDG_MODULE_ENABLED */
> /* #define HAL_LPTIM_MODULE_ENABLED */
> /* #define HAL_LTDC_MODULE_ENABLED */
> /* #define HAL_QSPI_MODULE_ENABLED */
> /* #define HAL_RNG_MODULE_ENABLED */
> /* #define HAL_RTC_MODULE_ENABLED */
> /* #define HAL_SAI_MODULE_ENABLED */
64,80c63,79
< /* #define HAL_MMC_MODULE_ENABLED */
< /* #define HAL_SPDIFRX_MODULE_ENABLED */
< /* #define HAL_SPI_MODULE_ENABLED */
< /* #define HAL_TIM_MODULE_ENABLED */
< /* #define HAL_UART_MODULE_ENABLED */
< /* #define HAL_USART_MODULE_ENABLED */
< /* #define HAL_IRDA_MODULE_ENABLED */
< /* #define HAL_SMARTCARD_MODULE_ENABLED */
< /* #define HAL_WWDG_MODULE_ENABLED */
< /* #define HAL_PCD_MODULE_ENABLED */
< /* #define HAL_HCD_MODULE_ENABLED */
< /* #define HAL_DFSDM_MODULE_ENABLED */
< /* #define HAL_DSI_MODULE_ENABLED */
< /* #define HAL_JPEG_MODULE_ENABLED */
< /* #define HAL_MDIOS_MODULE_ENABLED */
< /* #define HAL_SMBUS_MODULE_ENABLED */
< /* #define HAL_EXTI_MODULE_ENABLED */
---
> /* #define HAL_MMC_MODULE_ENABLED */
> /* #define HAL_SPDIFRX_MODULE_ENABLED */
> /* #define HAL_SPI_MODULE_ENABLED */
> /* #define HAL_TIM_MODULE_ENABLED */
> /* #define HAL_UART_MODULE_ENABLED */
> /* #define HAL_USART_MODULE_ENABLED */
> /* #define HAL_IRDA_MODULE_ENABLED */
> /* #define HAL_SMARTCARD_MODULE_ENABLED */
> /* #define HAL_WWDG_MODULE_ENABLED */
> /* #define HAL_PCD_MODULE_ENABLED */
> /* #define HAL_HCD_MODULE_ENABLED */
> /* #define HAL_DFSDM_MODULE_ENABLED */
> /* #define HAL_DSI_MODULE_ENABLED */
> /* #define HAL_JPEG_MODULE_ENABLED */
> /* #define HAL_MDIOS_MODULE_ENABLED */
> /* #define HAL_SMBUS_MODULE_ENABLED */
> /* #define HAL_EXTI_MODULE_ENABLED */
213c212
< #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
---
> #define ETH_RX_BUF_SIZE /* buffer size for receive */
diff -r --ex 661/Core/Src/main.c 670/Core/Src/main.c
218c218
< hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;
---
> hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
diff -r --ex 661/Core/Src/syscalls.c 670/Core/Src/syscalls.c
13c13
< * Copyright (c) 2022 STMicroelectronics.
---
> * Copyright (c) 2020-2022 STMicroelectronics.
50c50
< 	return 1;
---
> return 1;
55,56c55,58
< 	errno = EINVAL;
< 	return -1;
---
> (void)pid;
> (void)sig;
> errno = EINVAL;
> return -1;
61,62c63,64
< 	_kill(status, -1);
< 	while (1) {}		/* Make sure we hang here */
---
> _kill(status, -1);
> while (1) {} /* Make sure we hang here */
67c69,70
< 	int DataIdx;
---
> (void)file;
> int DataIdx;
69,72c72,75
< 	for (DataIdx = 0; DataIdx < len; DataIdx++)
< 	{
< 		*ptr++ = __io_getchar();
< 	}
---
> for (DataIdx = 0; DataIdx < len; DataIdx++)
> {
> *ptr++ = __io_getchar();
> }
74c77
< return len;
---
> return len;
79c82,83
< 	int DataIdx;
---
> (void)file;
> int DataIdx;
81,85c85,89
< 	for (DataIdx = 0; DataIdx < len; DataIdx++)
< 	{
< 		__io_putchar(*ptr++);
< 	}
< 	return len;
---
> for (DataIdx = 0; DataIdx < len; DataIdx++)
> {
> __io_putchar(*ptr++);
> }
> return len;
90c94,95
< 	return -1;
---
> (void)file;
> return -1;
96,97c101,103
< 	st->st_mode = S_IFCHR;
< 	return 0;
---
> (void)file;
> st->st_mode = S_IFCHR;
> return 0;
102c108,109
< 	return 1;
---
> (void)file;
> return 1;
107c114,117
< 	return 0;
---
> (void)file;
> (void)ptr;
> (void)dir;
> return 0;
112,113c122,125
< 	/* Pretend like we always fail */
< 	return -1;
---
> (void)path;
> (void)flags;
> /* Pretend like we always fail */
> return -1;
118,119c130,132
< 	errno = ECHILD;
< 	return -1;
---
> (void)status;
> errno = ECHILD;
> return -1;
124,125c137,139
< 	errno = ENOENT;
< 	return -1;
---
> (void)name;
> errno = ENOENT;
> return -1;
130c144,145
< 	return -1;
---
> (void)buf;
> return -1;
135,136c150,152
< 	st->st_mode = S_IFCHR;
< 	return 0;
---
> (void)file;
> st->st_mode = S_IFCHR;
> return 0;
141,142c157,160
< 	errno = EMLINK;
< 	return -1;
---
> (void)old;
> (void)new;
> errno = EMLINK;
> return -1;
147,148c165,166
< 	errno = EAGAIN;
< 	return -1;
---
> errno = EAGAIN;
> return -1;
153,154c171,175
< 	errno = ENOMEM;
< 	return -1;
---
> (void)name;
> (void)argv;
> (void)env;
> errno = ENOMEM;
> return -1;

Based on this, I tried changing

hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;

to

hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;

in the 6.7.0 project and it fixed the issue. Note this is not the same as running the card in 1-bit mode, the FatFS Disk I/O driver switches it to 4-bit mode later in initialisation:

~/SDMMC_STM32CubeMX_Test/661 % rg "SDMMC_BUS_WIDE_4B"
Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c
2180: * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2202: else if(WideMode == SDMMC_BUS_WIDE_4B)
 
Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_sdmmc.h
365:#define SDMMC_BUS_WIDE_4B SDMMC_CLKCR_WIDBUS_0
369: ((WIDE) == SDMMC_BUS_WIDE_4B) || \
 
Debug/661.list
10552: * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
10597: else if(WideMode == SDMMC_BUS_WIDE_4B)
14765: if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)
 
FATFS/Target/bsp_driver_sd.c
62: if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)

I'm not quite sure what the whole sequence is for initialisation in the SD specification, but I think the card has to be in 1-bit mode first in order to set up 4-bit mode.

Amel NASRI
Technical Moderator
February 15, 2023

Hi @FPlow.1​ ,

An explanation of what was updated is provided by @Ghofrane GSOURI​ in this thread: SDCARD does not work (FR_NOT_READY) when migrating from FW_F4 V1.27.0 to newer FW_F4 V1.27.1.

-Amel

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.