Skip to main content
Associate
July 20, 2025
Question

STM32F746G‑DISCO | SDMMC + DMA + D‑Cache – hangs at state 5, FR_DISK_ERR

  • July 20, 2025
  • 5 replies
  • 471 views

Subject: STM32F746G‑DISCO | SDMMC + DMA + D‑Cache – hangs at state 5, FR_DISK_ERR / empty files → root‑cause & minimal fixes


Cube / HAL versions

  • CubeF7: v1.28.0

  • CubeMX: 6.11

  • Board: STM32F746G‑DISCO

  • Middleware: FatFs R0.14, _USE_LFN = 3, _MAX_SS = 512

  • Cache: I‑ & D‑cache enabled (default)


1 – Read path: card never leaves RECEIVING (0x5)

Symptom
HAL_SD_GetCardState() polled after HAL_SD_ReadBlocks_DMA() stays at 0x05 → loop never exits.

Root cause
SD_DMAReceiveCplt() does not re‑enable the DATAEND interrupt, so the SDMMC ISR never runs and HAL state is never cleared.

Fix (HAL driver)
File: stm32f7xx_hal_sd.c

/* inside SD_DMAReceiveCplt() */
__HAL_SD_ENABLE_IT(hsd, SDMMC_IT_DATAEND); /* <- add this line */

After this patch the DATAEND IRQ fires, HAL_SD_IRQHandler() sends CMD12, sets hsd->State = READY, and the read loop exits.


2 – Write path: f_sync() returns FR_DISK_ERR / file size stays 0

2.1 Cache coherency

Before starting a DMA write, the sector buffer FatFs passes to disk_write() must be cleaned; after a DMA read it must be invalidated.
Both address and length must be cache‑line aligned (32 B on F7).

static inline void cache_clean(const void *buf, uint32_t len)
{
 uint32_t a = (uint32_t)buf & ~31U;
 len += (uint32_t)buf - a;
 len = (len + 31U) & ~31U;
 SCB_CleanDCache_by_Addr((uint32_t*)a, len);
}

static inline void cache_invalidate(void *buf, uint32_t len) { … }

Call cache_clean() in every disk_write() (or inside your BSP write routine) and cache_invalidate() in every successful disk_read().

2.2 Card busy after DMA

After the DMA completes the card enters PROGRAMMING (0x07) until its internal erase/program sequence finishes.
The driver must keep polling CMD13 until the card returns TRANSFER (0x04).

/* BSP_SD_WriteBlocks_DMA() – after hsd1.State == READY */
HAL_SD_CardStateTypeDef cs;
uint32_t t1 = HAL_GetTick();

do {
 cs = HAL_SD_GetCardState(&hsd1);
 if ((HAL_GetTick() - t1) >= SD_DATATIMEOUT) /* e.g. 5000 ms */
 {
 HAL_SD_Abort(&hsd1);
 return MSD_ERROR;
 }
} while (cs == HAL_SD_CARD_PROGRAMMING ||
 cs == HAL_SD_CARD_RECEIVING ||
 cs == HAL_SD_CARD_SENDING);

return (cs == HAL_SD_CARD_TRANSFER) ? MSD_OK : MSD_ERROR;

2.3 Timeout

Raise SD_DATATIMEOUT to a realistic value (≥ 500 ms; I used 5000 ms) to cover worst‑case card program times.


3 – FatFs log example (byte‑oriented write)

UINT bw;
size_t len = strlen(msg);

if (f_write(&logFile, msg, len, &bw) != FR_OK || bw != len) goto err;
if (f_write(&logFile, "\r\n", 2, &bw) != FR_OK) goto err;
if (f_sync(&logFile) != FR_OK) goto err;

No f_printf() → avoids the UTF‑16 %s pitfall when _USE_LFN != 0.


Result

  • Read loop exits correctly.

  • f_sync() always returns FR_OK.

  • Log file grows and is readable on a PC after every reset / power loss.

These patches are small (3 driver lines + BSP cache helpers + PROGRAMMING poll) and can be upstreamed to stm32f7xx_hal_sd.c & CubeMX templates.

Hope this saves someone else half a day of head‑scratching.

5 replies

anejatiAuthor
Associate
July 20, 2025

My github is https://github.com/anj1 if you'd like to ask me more details about this fix.

Tesla DeLorean
Guru
July 20, 2025

On the F7 the DTCMRAM can be used to avoid cache coherency issues.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
anejatiAuthor
Associate
July 20, 2025

Thanks Tesla. To be clear, cache coherency is only part of the issue, an equal issue is not respecting the period in which the card is in the PROGRAMMING (0x7) state.

Technical Moderator
July 21, 2025

Hello @anejati 

Could you please specifie how to reproduce the issue?

"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.Saket_Om"
anejatiAuthor
Associate
July 22, 2025

Issue is reproduced on a STM32F746G-Discovery board with the cubemx/library versions I mentioned in the post. Writing to a FAT formatted UHS-I sd card fails, however it likely fails with other sd cards as well.

Technical Moderator
July 28, 2025

Hello @anejati 

There is two examples FATFS on STM32F746G-Discovery board, please check them.

STM32CubeF7/Projects/STM32746G-Discovery/Applications/FatFs at master · STMicroelectronics/STM32CubeF7 · GitHub

"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.Saket_Om"