Skip to main content
machinist
Associate III
March 18, 2021
Question

UART in full duplex missing bytes

  • March 18, 2021
  • 3 replies
  • 2253 views

Hello,

I have an application where I transfer data to and from a PC with a FT232R and a UART. There is data beeing transfered back and foth constantly and asynchrone to another, so it is sending and receiveing at any random time and simultaneously. Sending and receiving is done by interrupt and use the same interrupt (checking in the interrupt which flag is active). I noticed that there was something wrong and toggled a pin each time the UART reived a byte. The problem is that it occaseonly misses some single bytes. This is when there are several hundred bytes transmitted to the STM32 at the maximum rate without delay between the bytes. Generally the UART is supposed to be fullduplex. The interrupt routine is shorter than a byte. So maybe the sending and receiving on the same interrupt is causing this.

I wondered now if it is possible to send the bytes not by interrupt but by using a DMA with a DMA finished interrupt while receiving the bytes with the UART interrupt? It seems strange as the USRT interrupt is the second highes priority with the highes only active for very short times (much less than one byte length). So it should fire after the other one is done. But the byte is missed completely.

So how is the "normal" way to acheive sending and receiving at high rates over the full duplex UART (I got FIFOs for both directions)? I thought it was quite straight forward.

Edit: Is it possible to use two DMA for transmitting and receiving at the same time on the UART?

This topic has been closed for replies.

3 replies

Guenael Cadier
ST Employee
March 18, 2021

Dear @machinist​ 

Yes UART transfer could be used for simultaneously send/receive data to/from your PC.

HAL UART API using DMA are :

  • HAL_UART_Transmit_DMA()
  • HAL_UART_Receive_DMA()

I don't know what STM32 serie you are using, but there are some HAL UART examples that show this behavior.

Please try to have a look at Examples\UART\UART_HyperTerminal_DMA or Examples\UART\UART_TwoBoards_ComDMA examples, if available in your STM32Cube FW package.

Regards

waclawek.jan
Super User
March 18, 2021

Which STM32? What baudrate, what system clock?

> Sending and receiving is done by interrupt and use the same interrupt (checking in the interrupt which flag is active).

Show your code, together with the pin toggling you mentioned.

JW

machinist
machinistAuthor
Associate III
March 23, 2021

Thanks for the answers. It is working now using the TX DMA and a RX interrupt. Even at maximum byterates there are no misses.

Visitor II
July 12, 2024

it is some time ago you posted this,but i am running in the same issue. 

Were you receiving and sending single bytes in the continuous incoming stream, or were you able to buffer a couple of bytes and then send them with the dma transfer?

Could you share some of the code in the interrupt handler and tx function?

Tesla DeLorean
Guru
July 12, 2024

There are several approaches to DMA, you need to send from a long-term global buffer as the DMA can span many milliseconds.

I would stage to a buffer, if there is currently no active transaction you can light off that data immediately, if there is an active transaction, leave and let the completion call-back light off the next available block of data.

Managing as a ring buffer might be the most efficient, splitting the wrapping cases into two transactions.

Implementation is STM32 device/family specific, and not stated. The Cube repo's should have UART DMA examples for EVAL or DISCO boards, review.

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