2024-05-11 01:39 PM
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:
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.
Solved! Go to Solution.
2024-05-14 01:32 PM
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
2024-05-14 01:32 PM
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
2024-05-14 01:46 PM
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.
2024-05-15 01:40 PM
Thx for your great eample, I will try to implement this.
2024-05-18 11:19 PM
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