2025-10-22 12:03 AM
Hi,
On the STM32N6570-DK board, I’m running an application that uses TouchGFX and FileX.
Both the TouchGFX frame buffer and FileX temporary buffers are located in external memory (XSPI1).
I’m observing intermittent write failures when SDMMC IDMA is used for direct transfers from external memory to the SD card. The issue appears as incorrect data being written — typically affecting the entire transfer block (a few kilobytes), as shown in the image below.
External memory is attributed as non-cacheable all the time. Selecting various shareability options for the ext memory introduces very strange behavior, so it's been disabled finally.
However, when the write operation is performed from internal SRAM (either via an intermediate buffer in SRAM or the FileX driver’s scratch buffer), the transfers are always successful.
I’ve also found a very similar case involving the TouchGFX frame buffer and SD card buffer in external memory on the STM32F7 platform.
2025-10-22 12:29 AM
Hi,
>intermittent write failures when SDMMC IDMA is used
And if set SDMMC without DMA , then working fine ?
2025-10-22 12:43 AM
Hi @AScha.3
I bet it works, but I did not try, beacuse it is the less acceptable approach for my multi-threaded application.
Regards.
2025-10-22 6:07 AM - edited 2025-10-22 6:15 AM
Hello @ERROR
Is your external memory configured in memory-mapped mode?
Before launching the DMA transfer, you should insert a DSB() (Data Synchronization Barrier) instruction in your code to ensure that all memory accesses are completed and the memory is up to date.
2025-10-23 12:18 AM
Hi @Saket_Om ,
Yes, the external memory is configured in memory-mapped mode.
__DSB() is used.
In the fx_stm32_sd_driver.c, there is clean_cache_by_addr() invoked.
#if (FX_STM32_SD_CACHE_MAINTENANCE == 1)
clean_cache_by_addr((uint32_t*)media_ptr->fx_media_driver_buffer, num_sectors * FX_STM32_SD_DEFAULT_SECTOR_SIZE);
#endif
status = fx_stm32_sd_write_blocks(FX_STM32_SD_INSTANCE, (UINT *)media_ptr->fx_media_driver_buffer, (UINT)start_sector, num_sectors);clean_cache_by_addr() is a substitute for SCB_CleanDCache_by_Addr(), that already contains __DSB()
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}Regards.
2025-10-30 6:32 AM
Hello @ERROR ,
To further assist you in debugging this issue, I recommend starting by significantly reducing the SDMMC clock frequencies. If the errors disappear after this adjustment, it likely indicates a timing margin or signal integrity problem.
Simultaneously, implement a data trap mechanism to capture the failure as it happens. Before initiating the transfer, write a known, repeating data pattern (for example, 0xDEADBEEF) into the XSPI buffer. Then, within your SDMMC transfer complete callback or a dedicated verification task, immediately verify the data integrity. If a mismatch is detected, trigger a breakpoint (e.g., __BKPT(0);). This approach will halt the processor exactly at the moment of failure, enabling you to inspect the live state of the XSPI, SDMMC, and DMA registers to pinpoint where the data pipeline is breaking down.
Please keep me updated on your progress.
Kind regards,
DHIF Khaled
2025-11-01 11:59 PM
Hi @Khaled_DHIF
Thank you for your efforts!
The external SRAM is used extensively by TouchGFX (for its framebuffer) as well as by the application code, and there are no indications of any timing issues.
Also, simultaneous recording of 4–5 audio files to the SD card works perfectly when using internal SRAM.
For now, I’ve put this issue aside — it costs me 16 KB of internal SRAM, which is acceptable at the moment.
Regards.