cancel
Showing results for 
Search instead for 
Did you mean: 

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

anejati
Associate II

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.

6 REPLIES 6
anejati
Associate II

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

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
anejati
Associate II

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.

Saket_Om
ST Employee

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
anejati
Associate II

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.

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