Skip to main content
Graduate II
October 26, 2023
Question

STM32H7 UART DMA recieve issue

  • October 26, 2023
  • 3 replies
  • 2387 views

Hello,

I have been trying to establish the UART communication using DMA. To implement that I referred to https://community.st.com/t5/stm32-mcus-products/stm32h7-uart-dma-receive-unknown-length-of-data/m-p/86869#M11292 post. I am trying to implement DMA using ReceivetoIdle method.

The problem I am facing is that for first communication the DMA buffer is correctly reading the data, but for the consecutive communications the DMA data read are incorrect. It seems that the data is not getting flushed. I will explain this with the below example.

1. Let's say my first transaction is "HelloWorld". The buffer correctly reads this data.

2. Now if I send "HelloWhirpool", the buffer read is "HelloWhrld". And this issue continues.

I tried resetting the DMA buffer but it won't help. I even checked the MPU configuration and address. When I checked the DMA read buffer size in the callback function void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size), the size is read correctly as expected. I am using X-CTU terminal for testing the uart interface.

 

Also I tried using ReceivetoIdle for IT method, and this method was working fine.

 

Could you please tell exactly where I could have gone wrong. Why the DMA buffer is not correctly reading the Data correctly.

 

-Regards

    This topic has been closed for replies.

    3 replies

    Super User
    October 26, 2023

    Should work. Can you show your code to start the transaction and to read data?

    Make sure you're not mistaking a half-transfer complete event for the full message.

    HDesa.1Author
    Graduate II
    November 1, 2023

    Hi,

    I have as off now used the Interrupt method to receive the chunck of data. I will once again try out the DMA method and share the code with you.

    ST Employee
    November 1, 2023

    I have met the same problem when I used "HAL_UARTEx_ReceiveToIdle_DMA90" to receive data, it is because some DMA parameters need be configured after it received one frame data.

    I used it as 3 steps:

    1. start the UART.

    void UART_start( void )
    {
        HAL_UARTEx_ReceiveToIdle_DMA(&UART3_Handler, &Usart3_Data.RX_buffer[0], RXBUFFERSIZE);
    }

    2. UART ISR

    void USART3_IRQHandler(void)
    {
    if(__HAL_UART_GET_FLAG(&UART3_Handler, UART_FLAG_IDLE) != RESET)
    {
    HAL_UART_IRQHandler(&UART3_Handler);
        HAL_UART_RxIdleCallback(&UART3_Handler);
    }
    else
    {
        HAL_UART_IRQHandler(&UART3_Handler);
    }
    }

    3. HAL_UART_RxIdleCallback().

    void HAL_UART_RxIdleCallback(UART_HandleTypeDef *huart)
    {
       switch((u32)huart->Instance)
      {

          case (u32)USART3:
          HAL_UARTEx_ReceiveToIdle_DMA(&UART3_Handler, &Usart3_Data.RX_buffer[0], RXBUFFERSIZE);
          break;

        }

    }

    ST Employee
    November 1, 2023

    in this way, the HAL_UARTEx_ReceiveToIdle_DMA() can work correctly.