STM32H7RS UART RX with circular linked-list GPDMA: DTE Error resolved by adding __DSB() before ENABLE
Hi everyone,
I'm using UART Receive-to-IDLE with circular linked-list GPDMA on an STM32H7RS and ran into a problem where reception stopped with HAL_DMA_ERROR_DTE.
The DMA node and RX buffer are both in DMA-accessible, non-cacheable RAM and aligned to 32 bytes.
The DMA handle and queue structure are in normal BSS. Everything is global/static and zero-initialized.
I checked the queue/node connection and the source address in LinkRegisters[3], which correctly pointed to UART RDR. The node address reconstructed from CLBAR and CLLR was also correct when checked.
However, these were the actual DMA register values in the working and failing cases:
Working Failing
CBR1 0x00000080 0x0000049B
CSAR 0x40007824 0x00000005
CDAR 0x24001960 0x200065A0After the DMA error, UART error handling stopped reception and disabled the IDLE interrupt, so I stopped getting HAL_UARTEx_RxEventCallback() calls.
What fixed it was adding __DSB() inside HAL_DMAEx_List_Start_IT(), after the CLBAR/CLLR configuration and immediately before ENABLE:
__DSB();
__HAL_DMA_ENABLE(hdma);So far, the issue has not returned.
My understanding is that the UART HAL updates the node before calling this function. With the initial transfer count at zero and a valid link, the DMA then fetches the node and loads its transfer registers in hardware after ENABLE. The barrier ensures the earlier CPU writes have completed before that happens, even though they were made in the calling function.
This looks like a memory synchronization issue, but I haven't established exactly where those incorrect register values came from.
Is this barrier expected here, and should it already be part of the HAL? Are there other DMA start/restart paths or descriptor updates where I should add one?
I'm also wondering about peripherals with their own DMA engines, particularly Ethernet and SDMMC DMA. Do their HAL drivers already handle the required synchronization, or are there points where the application needs to add barriers too?
