cancel
Showing results for 
Search instead for 
Did you mean: 

Problem receiving the data through UART using DMA

lachavusache
Associate II

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]);

 

5 REPLIES 5
Muhammed Güler
Senior III

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.

Hi, following configuration was used for the DMA.

 

lachavusache_0-1716534657247.png

 

Danish1
Lead II

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.

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.

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.