cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 UART DMA recieve issue

HDesa.1
Senior

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

-Regards
Hrishikesh
4 REPLIES 4
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".
HDesa.1
Senior

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.

-Regards
Hrishikesh
EXUE.2
ST Employee

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;

    }

}

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