UART RTS/CTS hardware flow control?
Sam Hanes last edited by
I would like to use one of the UARTs on my Omega2+ to communicate with another device that's quite slow and depends on RTS/CTS flow control to prevent overrun of its input buffer.
The Omega2+ pinout diagram doesn't list the RTS or CTS lines, nor does the pinout diagram or listing in the MT7688 "datasheet". However, in the register map for the UART the datasheet lists status/control registers (
UARTn_MCR) and interrupts (
UARTn_IIR) for RTS and CTS as well as enable bits for hardware RTS/CTS flow control (
UARTn_EFR[7:6]). The UART (or at least its register interface) clearly supports RTS/CTS flow control.
Is there any way to route the RTS and CTS lines from one of the UARTs to external pins on the Omega2+?
luz last edited by
As much as I would like to have that myself, my current conclusion is that MediaTek decided to leave that part away in hardware. The logic is in the UART block, but the hardware handshake signals seem connected nowhere. That's probably why they call these UARTs "lite".
Still, the fact that the MT7688 datasheet does not list or explain a feature does not necessarily mean the chip does not have it. The PWM IRQ and the associated registers were nowhere mentioned, but still, the MT7688 does have those and they work. I found out by sifting through datasheets of close relative's of the MT7688, such as MT7628. I did the same for the UART, but found not the slightest trace of how the internally available HW handshake signals could be mapped to actual pins
To prevent overrun of its (end device's) input buffer,
slowing down Omega2 side's sending rate is the king.
Flow control signals (RTS/CTS), after all, are just signaling flags in between two devices.
The sender should slow down in the first place.
Sam Hanes last edited by
@luz I too suspected that the modem control signals not being connected was what makes the UARTs "lite". Unfortunately in my application the UART on the other side doesn't support automatic XON/XOFF – just automatic RTS/CTS – but if yours does that might work.
@ccs-hello the problem with "the sender should just slow down" is that the receiver is variably slow. Most of the time it can saturate the connection at 115200 baud, but if one of its other subsystems causes a load spike it can fall behind. Since RTS/CTS handshaking forces the sender to wait when the receiver's FIFO is full I can push the limits on transfer rate without having to worry about data corruption if the receiver takes too long to pump the receive queue occasionally. Dropping the baud rate to something the receiver can handle 100% of the time instead of just 95% will cause something like an 80% slowdown in overall system performance, but if I can't get RTS/CTS flow control to work properly I guess I'll have to take it.
Once I've got the prototype for this project put together I'll see if I can get RTS/CTS working thorough the Omega's GPIO by setting an interrupt and disabling transmit in software. I'll probably have to adjust the automatic RTS threshold on the receiving UART, but I can do that and it might just work. That'll be a while, though.
If there's no hardware handshaking, have you considered software handshaking? Instead of firing a (e.g.) 20kByte buffer at your device at any given time, first write a small "write request" (which includes the length) on the UART, wait for a "write acknowledgement" from the device, then write the buffer. You could even do it chunk-wise with known chunk sizes and acknowledge each chunk (and resend if something was lost). Preferrably, the transfer on the receiver side from the UART peripheral into RAM should happen via an interrupt / ISR or be DMA accellerated. I think this would actually eliminate most of the problems you're seeing right now. How does it currently work? Does some application thread read the data from UART into RAM?
@Sam-Hanes Could you find a solution to this problem? How to implement hardware RTS / STS?