2024-05-23 11:35 PM
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]);
2024-05-24 12:05 AM
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.
2024-05-24 12:11 AM
Hi, following configuration was used for the DMA.
2024-05-24 12:16 AM
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.
2024-05-24 12:24 AM
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.
2024-05-24 01:36 AM
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.