Skip to main content
Associate
December 13, 2023
Solved

STM UART DMA to receive Multibyte packet

  • December 13, 2023
  • 7 replies
  • 2307 views

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

This topic has been closed for replies.
Best answer by Uwe Bonnes

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

7 replies

Associate II
December 14, 2023

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
Principal
December 15, 2023

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

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Uwe Bonnes
Uwe BonnesBest answer
Chief
December 15, 2023

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

magene
Senior
December 15, 2023

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
Super User
December 15, 2023

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
magene
Senior
December 15, 2023

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.

Associate
December 19, 2023

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.