cancel
Showing results for 
Search instead for 
Did you mean: 

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

APana.1
Associate II

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!

10 REPLIES 10
Saket_Om
ST Employee

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?

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

@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.


@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 ?


@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?

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. 


@APana.1 wrote:

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


and is it still the same error - Noise?

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.

I made a mistake here. I made the change in the code for but did not update the same for the UART baud rate in the script and I think that is the reason it got into the noise error. Once I have both the example code and the script in 9600 or 921600, it is getting into overrun error. Also I am not getting into noise error now. 

APana1_2-1722773031879.png

Also from my understanding once we have the flow control enabled, the receiver (Nucleo board) should toggle the CTS pin based on its availability to receive the data packets. So without the HAL_Delay(100), it is available all the time and we are not getting into any issues. But when I introduced the delay, ideally the received should make the CTS pin during this delay period asking the transmitter not to send any more packets. Here that happens, but the additional byte that the transmitter had sent in between gets it into overrun error. Since we have the hardware FIFO enabled, it should also be taken care for at least a byte ?