2022-07-17 11:03 PM
I use STM32H753 and USART1 with DMA to receive data of unknown length (Min: 8 bytes Max: 512 bytes) from PC. Data will be sent in burst after every one second. My baud rate is 9600. So approx 1ms per byte.
So, maximum, I'm going to get all the data in 512 ms and I'm free to analyze the data for another 488 ms.So, I want some algorithm so that I can parse all data (Min: 8 bytes Max: 512 Bytes) on DMA after all data received.
I am using follwoing methods.
1) Receiving without DMA and interrupt on every byte.
-> Working fine. But the more CPU interference required.
2) Receiving with Half and Full transfer interrupt with DMA.
-> Working fine but sometime we need to wait for one second (or more than that, depending upon buffer size) till the filling the buffer (HALF or FULL). It makes the communication process slower.
3) Receiving with DMA_CIRCULAR with DMA and keep eye on NDTR of DMA Stream.
-> Working fine but sometime we get error because NDTR updates first after receiving data in UART peripheral. And then DMA will copy data into memory.
4) Receiving with DMA_NORMAL with DMA and using "HAL_UARTEx_ReceiveToIdle_DMA"
-> Working fine but some time call back calls (with "Size") before actual data received in memory. Same problem as point no 3.
So please suggest best method for my case.
Solved! Go to Solution.
2022-07-19 02:00 AM
@MJ_1992 Maybe check out this page for implementing Idle detection and the correct way to use the variable "Size". Without source code its hard to judge why your code dosen't work.
Link 1: https://controllerstech.com/uart-dma-with-idle-line-detection/
2022-07-17 11:56 PM
Using DMA for UART reception is usually not a good idea. Not that it can't be done but the programming overhead is much higher than for simple UART interrupts.
My advice: don't use HAL for UART, write your own UART ISR for reception and initial interpretation of data (packet assembly).
2022-07-18 03:43 AM
For 2. you could implement a timeout interrupt via a timer that processes the data earlier if data transmission is slow. Make sure to set the interrupt prioritys for dma and timer correct to avoid problems.
As your data rate is very slow I would just implement a interrupt for reception without the DMA as @gbm already mentions.
2022-07-18 05:12 AM
@gbm "don't use HAL for UART"
Well, don't use it for the interrupt handling - which needs to be quick.
You could still use it for the setup - as that only happens at startup, so it doesn't need to be quick.
@MJ_1992 "1) Receiving without DMA and interrupt on every byte -> Working fine. But the more CPU interference required"
It shouldn't take a lot of CPU effort - just get the received byte, and put it into a buffer (usually, a circular buffer).
Handling of the received data should be handled outside the ISR.
2022-07-18 05:26 AM
Hi, I have found that ‘4’ works very well when data will be delivered in discrete bursts … but as others suggested, at 9600 it’s probably not necessary and interrupt based solution will suffice.
If you do head in in ‘4’ direction, there is a requirement to carefully discriminate between ‘Half Full’ and ’Idle’ when using HAL implementation (at least on F4).
Let me know if you need details on this.
2022-07-18 02:37 PM
USART on the newer STM32 series have an IDLE and RTO features and interrupts, which solves this problem easily.
2022-07-18 02:41 PM
The HAL/Cube developers are incapable of understanding that a typical USART is a stream interface, therefore they have not been capable of designing an appropriate API.
2022-07-19 12:18 AM
Thank you to all for replay
@JMeye.2 AND @Piranha You mean I need to use Combinetion of 2 + 4. ?
Half and Full buffer interrupt and also give interrupt for Ideal ( i.e. HAL_UARTEx_ReceiveToIdle_DMA ).
I will check and inform.
But as my previous observation 4. ( Without Half and Full int. ). Whan function HAL_UARTEx_ReceiveToIdle_DMA call the variable "Size" upadted as per no. of bytes sent by PC. but I din't get any data in my buffer. This problem happens only some times. (May be same problem as NDTR and Data sync prblem in case 3).
2022-07-19 01:15 AM
@MJ_1992 "Thank you to all for replay"
* reply
;)
2022-07-19 02:00 AM
@MJ_1992 Maybe check out this page for implementing Idle detection and the correct way to use the variable "Size". Without source code its hard to judge why your code dosen't work.
Link 1: https://controllerstech.com/uart-dma-with-idle-line-detection/