cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745ZITx - USART RX DMA Not Working

KemalUzgoren
Associate III

Hello,

I'm working with the STM32H745ZITx and trying to receive data over USART3 using RX DMA. However, the usart_rx_dma_buffer remains all zeros — as if no data is written. Here’s what I’ve checked:

:small_blue_diamond: DMA Configuration:

  • DMA1_Stream0, Peripheral-to-Memory direction

  • Tried both Circular and Normal mode

  • DMA RX request enabled for USART3

  • HT and TC interrupts are enabled

  • NVIC settings verified

:small_blue_diamond: Memory & MPU:

  • RX buffer is aligned using __attribute__((aligned(32)))

  • Proper cache invalidation is applied using SCB_InvalidateDCache_by_Addr()

  • Buffer region tested in .ld file using both D1 domain (0x2400xxxx) and D2 domain (0x3004xxxx)

  • MPU region configured as Normal, Cacheable, Shareable

:small_blue_diamond: What I’ve Tried:

Note: I’ve tested both 0x2400xxxx and 0x3004xxxx address ranges for the RX buffer. Even when HT or TC interrupt is triggered, no actual data appears in the buffer.

Has anyone faced a similar issue on STM32H745 and successfully resolved it?

Thank you,
Kemal

2 REPLIES 2
TDK
Super User

If HT and TC get triggered, data was received. It could be that the data is 0, in which case there is no problem. Initialize it to something nonzero to tell.

If non-zero data is coming in, but it shows up as zero when read, this is a caching issue. Show the code you're using when this happens.

If you feel a post has answered your question, please click "Accept as Solution".
During message sending, I perform cache cleaning with the following function: 
SCB_CleanDCache_by_Addr(
    (uint32_t *)(((uint32_t)lwrb_get_linear_block_read_address(&usart_tx_rb)) & ~(uint32_t)0x1F),
    usart_tx_dma_current_len
);
I can confirm on the oscilloscope that the data is physically being sent.
 
On the RX side, when data is received via DMA, the following DMA1_Stream0_IRQHandler function is called. At this point, when HT or TC interrupt is triggered, I try to read the data by invalidating the relevant buffer field:
Note: The data physically reaches the MCU, activity on the RX pin was observed with an oscilloscope. However, no data is written into usart_rx_dma_buffer.
void DMA1_Stream0_IRQHandler(void) {
    if (LL_DMA_IsActiveFlag_HT0(DMA1)) {
        LL_DMA_ClearFlag_HT0(DMA1);
        SCB_InvalidateDCache_by_Addr(
            (uint32_t *)(((uint32_t)usart_rx_dma_buffer) & ~0x1F),
            sizeof(usart_rx_dma_buffer)
        );
        usart_rx_check();
    }
    if (LL_DMA_IsActiveFlag_TC0(DMA1)) {
        LL_DMA_ClearFlag_TC0(DMA1);
        SCB_InvalidateDCache_by_Addr(
            (uint32_t *)(((uint32_t)usart_rx_dma_buffer) & ~0x1F),
            sizeof(usart_rx_dma_buffer)
        );
        usart_rx_check();
    }
}
Both usart_tx_dma_buffer and usart_rx_dma_buffer variables are placed in a special memory section in the .ld file.
These fields are used in the MPU configuration:
Base Address: 0x30047C00 / 0x2407FC00
Size: 512B
Access Permission: All Access Permitted
Instruction Access: Disable
Shareable: ENABLE
Cacheable: DISABLE
Bufferable: ENABLE​
32-byte alignment of buffers is ensured.