Skip to main content
Visitor II
May 24, 2024
Question

Problem receiving the data through UART using DMA

  • May 24, 2024
  • 2 replies
  • 1597 views

Hi, I am using STM32F407 board to communicate with a serial device. I have been using HAL_UART_Transmit() to send the data and using HAL_UART_Receive_DMA() to receive the data. Part of the code is shown below. After every receive command I am supposed to receive the transmitted data back and additional 8 bit reply. But I am not receiving anything. Is there something wrong with the way I am using the commands. Also when I use plain receive HAL_UART_Receive() instead of DMA, program is stuck in HAL_UART_Receive() function. Please let me know if you see any fundamental problems with the code.

 

uint8_t wakeup_seq[2] = {0xaa,0xaa};

uint8_t WDOG_CNT[6] = {0x1e, 0x80, 0x3d, 0x00, 0x7f,0x92};

 

HAL_UART_Transmit(&huart2,wakeup_seq,sizeof(wakeup_seq),HAL_MAX_DELAY);

HAL_Delay(1);

HAL_UART_Receive_DMA(&huart2,t_rxdata,sizeof(wakeup_seq)+1);

 

for(uint8_t i=0;i<sizeof(wakeup_seq);i++)

printf("%x \n",t_rxdata[i]);

 

HAL_UART_Transmit(&huart2,WDOG_CNT,sizeof(WDOG_CNT),HAL_MAX_DELAY);

HAL_Delay(1);

HAL_UART_Receive_DMA(&huart2,t_rxdata,sizeof(WDOG_CNT)+1);

 

for(uint8_t i=0;i<sizeof(WDOG_CNT)+1;i++)

printf("%x \n",t_rxdata[i]);

 

    This topic has been closed for replies.

    2 replies

    Graduate II
    May 24, 2024

    When you say read data with DMA, you start the reading process in the background. It finishes this line in a few cycles and moves on to the next line.
    If you want to perform serial port reading and writing operations with DMA, you must create an asynchronous structure.

    Visitor II
    May 24, 2024

    Hi, following configuration was used for the DMA.

     

    lachavusache_0-1716534657247.png

     

    Graduate
    May 24, 2024

    HAL_UART_Receive_DMA() returns immediately to allow you to get on with "other things" while the reception actually happens. You have to wait for a callback to know that the reception has actually happened.

    On the other hand, HAL_UART_Transmit() (without _IT, without _DMA) stops execution of your code until the last byte is sent.

    If your other device starts sending before your HAL_Delay(1); has completed (so before you tell the UART to start listening with HAL_UART_Receive_DMA) then you'll miss some or all of the message. So from a "sequencing" point of view you'll have to call HAL_UART_Receive_DMA() before HAL_UART_Transmit().

    But (and this is an important point) I don't know if calling HAL_UART_Transmit() while there is an ongoing HAL_UART_Receive_DMA() will upset the receive or not. This information is something that should be included in HAL documentation. I know I sound like a broken record on this point, but I don't think HAL is adequately documented and so I avoid it where I can, instead writing my own code using the Reference Manual. I strongly recommend that people try to read the appropriate chapters of the Reference Manual for their stm32 to know what the HAL calls are trying to do.

    Visitor II
    May 24, 2024

    Hi, I am using 1000000 baudrate for serial data transmission and reception. So, data is transmitted within microseconds. I am using 1 milliseconds delay. Is it not enough to complete the transmission and receive the data? I agree that many users reported the difficulty with HAL documentation. I will also try working with UART and DMA directly. Thanks for the reply.

    Graduate
    May 24, 2024

    As I said, HAL_UART_Receive_DMA() returns immediately.

    It returns before any data have returned. It is up to you to wait for the callback to know that data have arrived for you to process.