2025-05-19 7:31 AM - last edited on 2025-05-19 8:05 AM by Andrew Neil
Hello,
I’m working on a custom board based on the STM32H753IITx and I'm trying to access a microSD card via USB_OTG_HS using the USB Mass Storage Class (MSC). I've read this post, which is close to my use case, but unfortunately, I haven’t been able to solve my issue.
Here is a summary of my configuration in STM32CubeMX:
SDMMC1 (SD card interface):
USB_OTG_HS (Mass Storage Device):
Here’s what I’m observing:
I'm using:
STM32CubeFW_H7 v1.12.1
STM32 USB Device Library v1.17.0
I've created a minimal standalone project reproducing the issue — it’s available here: https://github.com/Brandon-Altaneos/STM32H7_SD_USB_StandAlone/tree/master/SD_USB_Stand_Alone .
Any guidance or suggestions would be greatly appreciated.
Thanks in advance,
Brandon
Solved! Go to Solution.
2025-06-13 3:03 AM
Hello,
I wanted to share the solution I found in case it helps others.
After trying various things — including checking for cache coherency using SCB_CleanDCache_by_Addr() and SCB_InvalidateDCache_by_Addr() — I identified the issue was related to the location of the bot_data buffer used by the USB MSC layer.
Since this buffer is accessed during USB interrupt context and the SD card driver uses DMA, I moved the bot_data buffer to a non-cacheable memory region (in my case, external RAM configured as non-cacheable via MPU settings).
in usbd_conf.c:
#ifdef USBD_malloc
#undef USBD_malloc
#define USBD_malloc USBD_static_malloc_sdram
#endif
SDRAM_BUFFER uint32_t USBD_pStaticMem[(sizeof(USBD_MSC_BOT_HandleTypeDef)/4)+1];
...
void *USBD_static_malloc_sdram(uint32_t size);
void *USBD_static_malloc_sdram(uint32_t size)
{
UNUSED(size);
return USBD_pStaticMem;
}
with :
#define SDRAM_BUFFER __attribute__((section(".sdram_buffer"), aligned(32)))
Once that was done, I was able to:
Brandon
2025-05-19 8:26 AM - edited 2025-05-19 8:30 AM
Hi,
> Clock divide factor: 1 (which results in 200 MHz / (2 × 1) = 100 MHz SDMMC_CK
- is too much ! sd-card max is 50MHz , set div to 2 (or3) , to have max. 50 M .
+
Try first without DMA ;
if working, then try with DMA : disable D-cache (to check, if its a problem with cache manage.)
2025-05-21 1:30 AM - edited 2025-05-21 1:30 AM
Hi,
Thanks for the suggestion.
> Clock divide factor: 1 (which results in 200 MHz / (2 × 1) = 100 MHz SDMMC_CK
- is too much ! sd-card max is 50MHz , set div to 2 (or3) , to have max. 50 M .
My SD card actually supports a clock frequency up to 104 MHz, as it complies with the SDHC UHS-I SDR104 standard. when I perform SD read/write operations via the MCU using FatFs, either in blocking mode or with DMA, it works flawlessly even at 100 MHz.
However, the issue appears in the context of USB MSC, i have to reduce the SDMCC clock ot 25 MHz to perform SD read/write operations in blocking mode. otherwise, the system hangs.
Try first without DMA ;
if working, then try with DMA : disable D-cache (to check, if its a problem with cache manage.)
D-Cache is not enabled in the current configuration (standalone project) so cache maintenance isn't an issue here.
Let me know if you have any insight on using DMA safely in the USB context.
Best regards,
Brandon
2025-05-21 7:55 AM
Hi,
>My SD card actually supports a clock frequency up to 104 MHz
fine, but my H7 needs 1.8V transceiver for this - you have this ?
at 3v3 : 50M max ...
2025-05-22 11:28 PM
Hi,
You're absolutely right, the SD card may support up to 104 MHz, but without a 1.8V transceiver, we're limited to 50 MHz at 3.3V operation. I’ll stick to 50 MHz to stay within spec.
That said, even with the reduced clock, the DMA transfer from the SD card still doesn’t work when triggered from the USB interrupt context. I'm still investigating this issue, it seems to be unrelated to the clock speed.
Best regards,
Brandon
2025-06-13 3:03 AM
Hello,
I wanted to share the solution I found in case it helps others.
After trying various things — including checking for cache coherency using SCB_CleanDCache_by_Addr() and SCB_InvalidateDCache_by_Addr() — I identified the issue was related to the location of the bot_data buffer used by the USB MSC layer.
Since this buffer is accessed during USB interrupt context and the SD card driver uses DMA, I moved the bot_data buffer to a non-cacheable memory region (in my case, external RAM configured as non-cacheable via MPU settings).
in usbd_conf.c:
#ifdef USBD_malloc
#undef USBD_malloc
#define USBD_malloc USBD_static_malloc_sdram
#endif
SDRAM_BUFFER uint32_t USBD_pStaticMem[(sizeof(USBD_MSC_BOT_HandleTypeDef)/4)+1];
...
void *USBD_static_malloc_sdram(uint32_t size);
void *USBD_static_malloc_sdram(uint32_t size)
{
UNUSED(size);
return USBD_pStaticMem;
}
with :
#define SDRAM_BUFFER __attribute__((section(".sdram_buffer"), aligned(32)))
Once that was done, I was able to:
Brandon