Skip to main content
TVan .8
Associate III
May 11, 2024
Solved

UART_DMA_FIFO burst size and treshhold

  • May 11, 2024
  • 3 replies
  • 2642 views

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

 

This topic has been closed for replies.
Best answer by Karl Yamashita

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

3 replies

Karl Yamashita
Karl YamashitaBest answer
Principal
May 14, 2024

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

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
TVan .8
TVan .8Author
Associate III
May 15, 2024

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

Tesla DeLorean
Guru
May 14, 2024

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 VenmoUp vote any posts that you find helpful, it shows what's working..
TVan .8
TVan .8Author
Associate III
May 19, 2024

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