Skip to main content
Visitor II
March 18, 2021
Question

UART in full duplex missing bytes

  • March 18, 2021
  • 3 replies
  • 2242 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

    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

    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

    machinistAuthor
    Visitor II
    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?

    Graduate II
    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.