STM32H7, arm-none-eabi-gcc. DMA TX of a 64 byte frame. Cache off: fine. With -DUSE_DCACHE, the analyzer shows wrong frames. The first frame after reset is correct. Later ones carry bytes of the previous frame, in 32 byte blocks. Sometimes the front is new and the tail is old.
Eventually the compiler moves the copy loop behind the enable write. But -O0 is the same. tx_buf volatile is the same. DSB after the loop is the same. In the disassembly the stores come before the CR write.
for (size_t i = 0; i < n; i++)
tx_buf[i] = data[i];
__asm volatile ("dsb 0xF" ::: "memory");
DMA1_S3_M0AR = (uint32_t)(uintptr_t)tx_buf;
DMA1_S3_NDTR = (uint32_t)n;
DMA1_S3_CR |= DMA_EN;
Cache is enabled in board_init():
SystemInit();
#ifdef USE_DCACHE
SCB_EnableICache();
SCB_EnableDCache();
#endif
Build:
make clean && make OPT=-O0 DEFS=-DUSE_DCACHE -DTRACE_ITM
The order looks right to me and the data is still old. What else is there?