2020-06-05 08:19 AM
Hello,
We have an application where we want to use basic serial ports to communicate between two STM32 processors (32F030RCTs). The two processors are on two different boards but with the same ground system. Each processor receives and transmits perfectly well with PCs (using USB serial converters). However when we connect the two devices together using a simple crossover cable communication falls over and produces UART overrun errors in the receivers.
The serial port clocks are derived from the internal HSS i.e. no external crystal is not used. The signal quality is excellent. We are trying to figure out what might be going on. We dropped the baud rate to 9600 and changed some of the uart sampling settings but to no avail.
Any clues as to what might be going on would be appreciated.
Thanks and regards.
2020-06-05 08:37 AM
Overrun is more consistent with the software not supporting concurrent/full-duplex communications effectively.
Using HAL?
2020-06-05 08:50 AM
Thanks Clive.
I'm the HW engineer working on this so not overly familiar with the code etc. We are using HAL. According to my SW colleague the overrun originates from the very low level section of HAL UART operation.
Comms operate normally using a PC at baud rates up to 115K2 so it seems like it might be associated with clock inaccuracy or something like that.
2020-06-05 10:23 AM
This is not a hardware problem. The issue is with the way the application handles data transfers. There are two solutions for this.
The first approach is to modify the application code to buffer incoming data. The RX interrupt writes each incoming byte to a memory buffer. The application then reads from the buffer when it requires data. My guess is the application right now uses a sequential approach: send block of data, receive block of data, process data, repeat. The problem is incoming data may arrive at any time, not just when you expect it. A buffer with interrupt handling saves each incoming byte of data even if you aren't ready to receive it.
The second solution is based on hardware. Implement the full RTS-CTS flow control handshaking for your serial port, and enable hardware flow control for the USART. You will need to do this both in the STM32 node and the COM serial port (the port properties should have an option for hardware RTS-CTS). Each node will not send data until the incoming CTS line is asserted (i.e. Clear To Send). When each node is ready to receive data the RTS line is asserted (Ready To Send), signaling the other side it can start sending data. RTS on one side connects to CTS on the other.
Jack Peacock
2020-06-05 10:33 AM
Add additional STOP BITS if you think it is an inter-symbol time / packing issue, but that would likely show up as a framing error.
2020-06-05 10:50 AM
An overrun occurs when the software does not read the incoming byte from the data register before the last bit of the next one arrives. The STM32F030 has no FIFO.
There is no problem with the connection between the two MCUs, don't look for one. If there were any, you'd get some other error. The UART protocol can tolerate up to 5% clock drift between the two sides. You can measure and compare the system clock frequencies just to be sure, but I don't think that it would be the cause. You'd get framing errors in this case anyway.
The overrun does not originate from any section of the software, it just happens. Software can prevent it if it anticipates that a data byte can arrive any time.
Without seeing the code one thing is sure, some part of your software is blocking the part responsible for reading out the received data in time. At 9600 baud, there is more than one millisecond to do it, an eternity for a 48 MHz MCU. Find out what prevents it. Either the software is busy calculating something, or it waits for some event to happen in a busy loop. HAL functions are notorious for doing this.
I'd recommend reading the UART chapter in the reference manual, and write your interrupt based receiving (and maybe transmitting) functions. There are some examples in Appendix A.