Skip to main content
Explorer
July 29, 2024
Question

Issue with UART Hardware Flow Control and High Baud Rate on STM32U5 Nucleo Board

  • July 29, 2024
  • 4 replies
  • 3774 views

Hello,

I am trying to interface the STM32U5 Nucleo board (STM32-U575ZI-Q) with a PC tool (Python-based) connected physically with a USB to TTL Serial 3.3V converter. The goal is to transfer an entire file over UART to the Nucleo board. I have made the following modifications to the example project (UART_TwoBoards_ComIT:(

  • Set the UART baud rate to 921600.
  • Enabled hardware flow control.
  • Updated the code to handle larger data transfers.

The modified code is available on my GitHub fork: akhilpanayamparambil/STM32CubeU5 at ap/uart_test.

I am encountering an issue where, when the data size sent from the U5 board to the PC tool is increased to three times the initial size in aTxBuffer, the code hits the Error_Handler during HAL_UART_Transmit_IT. This also happens when I add a HAL_Delay(100) in the main loop.

When enabling hardware flow control for UART with a baud rate of 921600, the code hits Error_Handler when there is still data coming into RX even when RTS goes high.

Adding few screenshots of the transfer.

Screenshot 2024-07-29 013900.png

Code snippet of python script below.

Screenshot 2024-07-30 003350.png

Has anyone experienced similar issues or have any insights on how to resolve this?

Thank you!

    This topic has been closed for replies.

    4 replies

    Technical Moderator
    July 31, 2024

    Hello @APana.1 ,

     

    I see in your code that the aTxBuffer has the same size as in the Cube firmware example.

    Did you try with lower baud rate such as 9600?

    APana.1Author
    Explorer
    August 1, 2024

    Tried with 9600 and there is no difference here. And yes aTxBuffer has the same size and for testing made the buffer 3 times bigger and have not pushed those changes. But the main issue is with the hardware flow control, even if I add a 100ms delay in the main while loop, the code gets to error. Ideally it should toggle the flow control pins and control the data coming from the transmitter. 

    The issue can be reproduced even if the board does not transmit anything back to the PC tool, instead add a delay in the main while loop. 

    Super User
    August 1, 2024

    @APana.1 wrote:

    Tried with 9600 and there is no difference ... the code gets to error. . 


    and is it still the same error - Noise?

    Super User
    July 31, 2024

    @APana.1 wrote:

    the code hits the Error_Handler during HAL_UART_Transmit_IT


    So check to see what error, exactly, is occurring.

     


    @APana.1 wrote:

    the code hits Error_Handler when there is still data coming into RX even when RTS goes high.


    Again, check to see what error, exactly, is occurring - overrun?

    Is the PC correctly configured to obey hardware flow control?

    Even with hardware flow control, I think it's to be expected that the sender will take some time to react, so a few characters may get through - especially at such a high baud rate.

     


    @APana.1 wrote:

    The goal is to transfer an entire file over UART to the Nucleo board. I have made the following modifications to the example project (UART_TwoBoards_ComIT


    I really don't think that example is suitable for high-speed file transfer - you want something with a proper file transfer protocol; eg, X/Y/Z-modem.

    APana.1Author
    Explorer
    August 1, 2024

    @Andrew Neil wrote:

    Again, check to see what error, exactly, is occurring - overrun?

    Is the PC correctly configured to obey hardware flow control?


    It is not getting into overrun error but to Noise Error. And yes the Python script is configured to obey hardware flow control. Please see the code snippet of script above which enables,

    APana1_0-1722520129349.png

     

    rtscts=True, 


    I really don't think that example is suitable for high-speed file transfer - you want something with a proper file transfer protocol; eg, X/Y/Z-modem.

     Do we have any other example that we can refer to here ?

    Super User
    August 1, 2024

    @APana.1 wrote:

     Do we have any other example that we can refer to here ?


    The UART IAP (In-Application Programming) App Note implements one of Y- or Z-modem ...

     

    EDIT:

     


    @APana.1 wrote:


    It is not getting into overrun error but to Noise Error. 


    I guess that's a risk at such a high baud rate!

    How, exactly, are you making this connection? Screened cable?

    Have you looked at the signal on an oscilloscope?

    Graduate II
    August 1, 2024

    Just some insights, no solutions. Your data is coming in at 921600 baud. That is 92,160 characters per second or one character every 11 microseconds.

    You get an interrupt when your input buffer is full (since you set up the receive to generate an interrupt then), so if you put your program into a 100 millisecond (100,000 microsecond) hold, and that interrupt fires, you have 11 microseconds to deal with the input buffer of the UART before it overflows. But if you're sitting in a HAL_Delay(100) call, you're going to miss your deadline. No?

    At that speed, the rise and fall times of your waveform are going to be pretty slow. Add in the capacitance of the wires involved, and you're going to need some very short wires to have a good signal. Like singles of inches.

    Take a look at the rx and tx lines with an oscilloscope (not a logic analyzer) and see if the bits still look okay. Logic analyzers square up signals by design, hiding all sorts of issues.

    Make sure that the slew rate on all of your pins is set to very high.

    Visitor II
    August 4, 2024

    I’m experiencing the same issue, even when using the RX Fifo (which the example does not use by default).

     

    I believe this is happening because RTS flow control is only asserted when either the buffer or FIFO is full.  This means that any byte received after RTS assertion will cause an overflow error.  However, since RTS isn’t asserted until the previous byte is fully received, if the host is already sending the next byte this byte will result in an overflow.

     

    Here’s an example where you can see RTS assertion in yellow and host byte transfer in blue.  The hardware is not asserting RTS until there’s no space left in the buffer, and the next byte received results in overflow.

     

     

    dwalkes_1-1722808261229.png

     

     

    There’s already a FIFO threshold programmed when using FIFO mode, ideally the flow control would use this to ensure that a byte or two sent after de-asserting RTS would allow the transfer to complete successfully.

     

    I’ve been able to demonstrate this with https://github.com/Trellis-Logic/STM32CubeU5/tree/uart-test-rx including a hack at https://github.com/Trellis-Logic/stm32u5xx_hal_driver/commit/6b009909b726aaa786217cfe91f846673274abed to use the FIFO threshold to hold off the host while bytes still remain in the FIFO.


    With this change I can insert a variable delay at https://github.com/Trellis-Logic/STM32CubeU5/blob/c3dff424630d16360e91d035726f90c4c1944e7b/Projects/NUCLEO-U575ZI-Q/Examples/UART/UART_TwoBoards_ComIT/Src/main.c#L190 which does simulated processing in the main loop for between 1-14 ms while the buffer transfer itself only takes 10ms.  The resulting flow control shows that the host is only blocked for portions of the transfer which occur when waiting for 11, 12, 13, or 14ms, the rest of the time the transfer is fully overlapped with the delay.  Also, no bytes are lost and exactly the number of bytes sent by the host are received by the device

     

    dwalkes_2-1722808291082.png

     

    My question is:

    • Is this expected behavior?
    • Is there another/better way to prevent the host from sending bytes while processing for a variable amount of time in the main loop without resulting in overflow and ideally using the hardware flow control already supported by the device?

     

    FWIW I believe we had similar code on the H7 series previously which used hardware flow control and which did not experience receive overrun or dropped bytes.  I’m not sure if there’s a difference between series which would explain this.  I didn’t see anything obvious in the errata.