Skip to main content
Visitor II
November 4, 2024
Solved

HAL_UART_Receive_DMA only receive last byte

  • November 4, 2024
  • 2 replies
  • 2802 views

Hi, i want use usart DMA to receive data, but i only get last data by HAL_UART_Receive_DMA.

 

STM32U575VITX

STM32CUBEMX 6.8.0

STM32CubeIDE 1.12.0

 

the transmit data is $$......##

my code is in main function

alyssa_2-1730708550293.png

when i use HAL_UART_Receive(), i can get correct data, but it has packet loss to some extend.

alyssa_0-1730708476592.png

when i use HAL_UART_Receive_DMA(), i only get last byte # .

alyssa_1-1730708507952.png

 

cubemx setting for DMA:

alyssa_3-1730708599135.png

cubemx setting for usart :

alyssa_4-1730708627709.png

usart.c file is attached below.

 

i try this solution https://community.st.com/t5/stm32-mcus-embedded-software/stm32h750-dma-hal-uart-receive-dma-acting-oddly/m-p/569897 but, still can't solve it.

 

it will be very helpful, if any one tell me something.

thank you.

    This topic has been closed for replies.
    Best answer by embedko

    Hi. Problem with DMA configuration. You must set Enabled for Destination Address Increment After Transfer.

    embedko_1-1730834773457.png

     

     

    2 replies

    Graduate II
    November 4, 2024

    The function returns immediately, you can't have multiple operations in flight concurrently. Manage fill of buffer in the completion callback.

    Avoid using auto/local buffers for DMA, they have collapsing scope on the stack.

    alyssaAuthor
    Visitor II
    November 5, 2024

    Hi, let me make the situation more clear.

    alyssa_2-1730789896207.png

    i can run into IQRHander.

    alyssa_5-1730798844893.png

    i use the callback function, length=__HAL_DMA_GET_COUNTER can change.  (i think MCU have known the interrupt received by usart, but dont know where to read the buffer data)

    alyssa_0-1730786069431.png

    alyssa_3-1730792174164.png

    observation:

    1. hdmarx state is HAL_DMA_STATE_BUSY, HAL_UART_Receive_DMA state is HAL_OK 

    2. pRxBuffPtr is #000....... (only first byte have data, other bytes are all 0)

    3. hdmarx->init are all 0, if i set HAL_DMA_Init() in usart.c, it will into HardFault_Handler()

    4. i change baud rate from 921600 to 115200, but still not work

     

    i attach the .ioc and main.c file below.

     thank you

    Graduate II
    November 5, 2024

    It's not a clarity issue, its a one that lacks understanding of the mechanics

    I've told you HAL_UART_Receive_DMA(&hlpuart1,data,256); returns immediately, not after you have 256 bytes, immediately.

    You need some volatile semaphone coming back from the callback indicating it completed and is read for a second usage.

     

    volatile int global_flag = 0;
    ...
    while(1)
    {
     if (global_flag == 0) // nothing pending
     {
     global_flag = 1; // busy
     HAL_UART_Receive_DMA(&hlpuart1,data,256);
     }
    }
    
    In full completion callback
     global_flag = 0;

     

      

    embedkoAnswer
    Visitor II
    November 5, 2024

    Hi. Problem with DMA configuration. You must set Enabled for Destination Address Increment After Transfer.

    embedko_1-1730834773457.png

     

     

    alyssaAuthor
    Visitor II
    November 6, 2024

    Yes! thank you ,you are right!

    After I set this, everything go done well.