2023-02-10 04:55 AM
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:
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.
Solved! Go to Solution.
2023-02-10 07:20 AM
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.
2023-02-10 07:20 AM
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.
2023-02-15 07:07 AM
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.