cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple DMA operations on same channel with UART possible?

Ricko
Senior II

Hi,

first time using DMA so just reading various datasheets and posts. But something is not clear.

 

I would like to use DMA with UART to send large amount of data through the serial port while keeping the CPU as free as possible for other intensive tasks. So I am thinking of using HAL_UART_Transmit_DMA() but, because of the large amount of data that needs to be sent, I might need to call HAL_UART_Transmit_DMA() very often with the risk to it being called while the previous HAL_UART_Transmit_DMA() call/operation is still running.

 

Is there a way to somehow append - or perhaps automatically queue - the new data right at the moment I need to so the code can keep executing, instead of having to wait and check for when the current DMA action is completed (whether inline or through interrupts)?

 

Also is there a limit to the data size I can send with HAL_UART_Transmit_DMA() ?

 

Perhaps using two channels?

Thank you

1 ACCEPTED SOLUTION

Accepted Solutions

You can't keep calling it with operations already "in-flight"

Make a linked list (scatter/gather or chain) and submit new transfers as you get completion interrupts. You can fold contiguous transfers at the time of dispatch. This is a coding/implementation task that YOU get to own, it's not done automagically by the HAL

The underlying buffer needs to exist over the life of the transfer.

>>Also is there a limit to the data size I can send with HAL_UART_Transmit_DMA() ?

The DMA units have a 16-bit Transfer Count which limits the number of units being transferred to 65535, bytes if using bytes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

3 REPLIES 3

You can't keep calling it with operations already "in-flight"

Make a linked list (scatter/gather or chain) and submit new transfers as you get completion interrupts. You can fold contiguous transfers at the time of dispatch. This is a coding/implementation task that YOU get to own, it's not done automagically by the HAL

The underlying buffer needs to exist over the life of the transfer.

>>Also is there a limit to the data size I can send with HAL_UART_Transmit_DMA() ?

The DMA units have a 16-bit Transfer Count which limits the number of units being transferred to 65535, bytes if using bytes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Karl Yamashita
Lead III

Use a queue buffer to hold your packets of data. When the packet is done transmitting, the HAL_UART_TxCpltCallback is called. From there you can check your queue for more messages to send.

 

See this project that does exactly what i just described.

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.
Ricko
Senior II

Thank you both