Skip to main content
Visitor II
June 3, 2025
Question

DMA - USART transfer Peripheral to Peripheral

  • June 3, 2025
  • 4 replies
  • 697 views

Hi,

I am experiencing a packet loss issue using Peripheral-to-Peripheral DMA between UARTs.

While Peripheral-to-Peripheral configuration is referenced in the STM32U585's Reference Manual, it is not available in the HAL library. Therefore, the DMA is configured for Peripheral-to-Memory mode, with the destination address set to the UART's Transmit Data Register (TDR). FIFO mode is not used.

The reference setup I am using is based on the B-U585I-IOT02A, where no packet loss occurs.

(MSI Clock)

  • USART2_RX → USART3_TX
  • USART3_RX → USART2_TX

The packet loss issue occurs on another STM32U5 (u585cit6q) with the same software but different UART configurations. 

(HSE Clock)

  • USART3_RX to UART4_TX
  • UART4_RX to USART3_TX

USART3 is configured to use the RS485 protocol.

The packet loss varies between 0.0025% and 10%, depending on the baud rate, and it is not correlated to an increase in speed.

Is it possible to experience synchronization issues between USART and UART? 
Can the addition of the RS85 be the source of the issue ?


Regards,
Loïc

    This topic has been closed for replies.

    4 replies

    Super User
    June 3, 2025

    Please post your schematic and a minimum but complete example which illustrates the problem

    How to insert source code

     


    @lotou wrote:

    Can the addition of the RS85 be the source of the issue ?


    Have you tried without it?

    Have you tried without DMA?

    lotouAuthor
    Visitor II
    June 3, 2025

    Sure,
    here is the application code:

    while ((UART_A.Instance->ISR & USART_ISR_TXE) != USART_ISR_TXE);
    while ((UART_B.Instance->ISR & USART_ISR_TXE) != USART_ISR_TXE);
    
    HAL_UART_Receive_DMA(&UART_A,(uint8_t *)&UART_B.Instance->TDR,1);
    HAL_UART_Receive_DMA(&UART_B,(uint8_t *)&UART_A.Instance->TDR,1);	


    The main difference is the mcu and its configuration, both done with CubeMX.
     STM32U585AII6Q :
    - UART_A = USART2
    - UART_B = USART3
    - MSI Clock

    STM32U585CIT6Q:
    - UART_A = USART3 - RS485 (PB1 set High)
    - UART_B = UART4
    - HSE Clock


    Test procedure :
    Read from UART_A_TX (/dev/ttyUSBx) and store it to result.bin file.
    Send a random binary file to UART_B_RX ( /dev/ttyUSBy).
    Compared sent file and result.bin: must be exactly the same.

    Repeat the test but send to UART_A_RX and read from UART_B_TX
    Baudrate: 4M bauds

     

    Test results:

    STM32U585AII6Q: OK
    STM32U585CIT6Q: NOK - Change baudrate changes the amount of byte loss.

    4M bauds: 0.0025% loss

    3M bauds: ~0.0025% loss
    1M bauds: 10% loss

     

    • Have you tried without it (RS485) ?

    No and i am not suppose to.

    • Have you tried without DMA ? 

    That's also a no.




    Graduate II
    June 16, 2025

    I don't see ONE byte operation like this being a viable solution.

    Need to have larger buffers to decimate interrupt loading. With continuous / circular operation. Need to manage potential discrepancies in rates, and flow.

    Would also not create dependencies on both UART, and blocking.

    Have you considered just using wire?

    Super User
    June 3, 2025

    > The packet loss varies between 0.0025% and 10%, depending on the baud rate, and it is not correlated to an increase in speed.

    What is the nature of the packet loss? Garbled characters? Missing characters? Do parity or frame or noise errors get triggered?

    lotouAuthor
    Visitor II
    June 16, 2025

    Hi!
    Apologies for the delayed response.

    The packet loss indicates missing data.
    Triggered Errors: None

    The test configuration used is as follows:

    • UARTs baud rate set to 4 MBaud
    • File Size: 4 MB

    USART_A -> UART_B: Test OK
    UART_B -> USART_A: 100 bytes missing

    Super User
    June 16, 2025
    while ((UART_A.Instance->ISR & USART_ISR_TXE) != USART_ISR_TXE);
    while ((UART_B.Instance->ISR & USART_ISR_TXE) != USART_ISR_TXE);
    
    HAL_UART_Receive_DMA(&UART_A,(uint8_t *)&UART_B.Instance->TDR,1);
    HAL_UART_Receive_DMA(&UART_B,(uint8_t *)&UART_A.Instance->TDR,1);	

    > UARTs baud rate set to 4 MBaud

    So two interrupts at 500 kHz. That won't work. The code presented is insufficient. You never send characters.

    I would guess general software bugs are the cause.

    Super User
    June 16, 2025

    I don't quite understand your setup, but if you receive a continuous stream of data from PC to UART (by which I mean both USART and UART in asynchronous mode) in mcu and then try to transmit those data from another UART (let's call it UART-B) in the same mcu at the same nominal baudrate, you may lose data due to the PC transmitting faster than UART-B.

    JW