cancel
Showing results for 
Search instead for 
Did you mean: 

UART_DMA_FIFO burst size and treshhold

TVan .8
Associate III

Hi,

I want to use the DMA FIFO for UART2 on the STM32H753ZI discovery board.

DMA in direct mode works, but sometimes I have almost concurrent events that need to be transmitted ASAP over the same UART (a few ms delay is no problem). It seems sometimes an UART message is not send because the last message was still sending.
Each message is exactly four bytes, so I would try to use the FIFO function on the UART DMA. I would like to set the burst size to four bytes so each message of four bytes would be send immediatly, except if the DMA UART is still blocked by the former message, which would give a slight but not problematic delay. I'd rather have a slight delay than a completely missed message.

I'm a bit confused by the DMA request settings As specified by AN4031 I would set:

  • threshold: 1/4
  • data width: byte
  • Burst Size: 4 Increment

Is it correct that this would give me a burst size of 4 bytes and that each message of 4 bytes would be send immediatly by the function HAL_UART_Transmit_DMA(&huart2,message,sizeof(message)). Except when the DMA is still blocked by the last message, in which case the message will be stored in the FIFO buffer and immediatly transmitted when the DMA is free again.

There is also an option to set the Burst Size to: single, I have no idea what that means, it is not specified in AN4031.

I also now this is not what the FIFO function was meant for, so if there are better (easier) methods to achieve this, I would gladly hear them.

TVan8_0-1715458581357.png

TVan8_1-1715458723967.png

 

1 ACCEPTED SOLUTION

Accepted Solutions
Karl Yamashita
Lead III

Create a queue to hold your tx packets. When the DMA is finished sending it'll call HAL_UART_TxCpltCallback in which you can send the next queue, and so on. 

See this project to see how to queue messages for transmitting

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.

View solution in original post

4 REPLIES 4
Karl Yamashita
Lead III

Create a queue to hold your tx packets. When the DMA is finished sending it'll call HAL_UART_TxCpltCallback in which you can send the next queue, and so on. 

See this project to see how to queue messages for transmitting

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.

Probably because you just use HAL_UART_Transmit_DMA() without checking if anything is pending / in-flight.

Just FIFO/QUEUE the data in application buffers, and light off or chain in the next one in the completion call-back. If something isn't in progress HAL_UART_Transmit_DMA() can be used.

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

Thx for your great eample, I will try to implement this.

TVan .8
Associate III

Just in case anybody else has a similar problem:

You guys pointed me in the right direction and I managed to solve my problem in a very easy way:

while(HAL_UART_Transmit_DMA(&huart2,message,sizeof(message)) == HAL_BUSY);

I didn't have to create a message queue. This blocks the mainloop, but the only function of my mainloop is sending the messages (everything else is handled by interrupts and DMA), so it's effectively a very simple message queue.

Also, I'm not going to need it now, but maybe later: does anyone know the "single" burst size? It's not mentioned in the APnote.

Thx