cancel
Showing results for 
Search instead for 
Did you mean: 

STM UART DMA to receive Multibyte packet

SandeepKel
Associate II

hi,

 

This is question regarding UART reception.

UART configured with 115200 8 N1

 I have a project where i need to receive a multibyte packet on UART and the length is not fixed.

My Queries 

1> Which approach should I take to receive a multibyte packet.

2> Is DMA a suitable in this scenario, DMA generates interrupt only when the number of bytes are received, if the packet size is not fixed how to handle this situation.

3> I'm planning to decipher single byte at a time and build the packet as per my protocol requirement Is there any function to receive one byte at a time.

4> Is there any way to receive single byte using DMA ?

Kindly provide some inputs

1 ACCEPTED SOLUTION

Accepted Solutions
Uwe Bonnes
Principal III

Consider also a device with UART Fifo. B.t.w. at 115200 Baud even without Fifo, interrupt  rate should be handable.

View solution in original post

7 REPLIES 7
boxtor
Associate II

1.  There's a idle line detection mode for UART DMA that exists for some MCU's.

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

Karl Yamashita
Lead III

You can use DMA with idle interrupt for any size packet. This eliminates having to receive each byte one at a time and building a packet.  

Read this Wiki on how to use Half Completed callback to put each packet in a queue buffer for parsing outside of the interrupt.

https://github.com/karlyamashita/Nucleo-G431RB_Three_UART/wiki

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
Uwe Bonnes
Principal III

Consider also a device with UART Fifo. B.t.w. at 115200 Baud even without Fifo, interrupt  rate should be handable.

magene
Senior II

I use the character match functionality built into the STM32H7 MCU.  I have to talk to a lot of serial port devices but luckily they all send messages that are terminated with a carriage return/line feed.  I can set up a DMA transfer to terminate when it gets the line feed character and it all gets handled by the hardware. I don't use the idle line detection feature because some of the devices I have to talk to don't always send their messages in a continuous stream of bytes. 

gbm
Lead III

Without HAL and DMA that could easily be handled by any STM32, even L0/F0. Just write your own UART ISR (25 lines of C code with idle detection) and call the packet asembly state machine from it (another 25 lines for classic MODBUS). Much easier and faster than HAL callback calling a HAL routine for re-enabling the unnecessarily-disabled UART interrupt.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

I've done it this way for MCUs that don't have character match functionality and it works fine.  If the messages are terminated with a known character, you can interrupt on every byte and terminate when the expected termination character is received or and IdleLine interrupt happens. Some more competent programmers than me have suggested that interrupting on every byte is a dumb idea but this approach does work and doesn't have the disadvantages of a polled/blocking approach. Particularly if the ISR puts the message in a FIFO queue and the main code checks the queue when it need to.

SandeepKel
Associate II

Thank you  every one.

for the pointer about handling variable length packet.

In my case I don't have a idle line, so i'm going ahead with Interrupt handler for every byte.

All the discussion and example gave me an insight on how the issue can be handled.