Implementing RS232 CTS/RTS flow control

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
genosensor
Posts: 65
Joined: Thu Oct 03, 2013 1:06 am
Location: Santa Cruz, California
Has thanked: 1 time
Been thanked: 1 time

Implementing RS232 CTS/RTS flow control

Postby genosensor » Wed Mar 01, 2017 8:06 am

The current serial I/O driver model seems to lack support for CTS/RTS flow control.
While most dedicated serial I/O chips implement CTS/RTS flow control in hardware, many of the serial I/O ports incorporated into microcontrollers do not -- or claim to, but do not implement it correctly.

For example, the STM32's serial ports advertise Request to Send support, but this merely deasserts RTS whenever the receiver data register is not empty. This is incorrect for two reasons:

1) The RTS signal will deassert between *each* character received while the RXNE interrupt is pending
(if you throw this RTS signal on a logic analyzer, you get a great look at ChibiOS's interrupt latency :-)
I observed these RTS glitches causing the sender to throttle its output unnecessarily -- by as much as 30% at very high baud rates.

2) There is nothing protecting the firmware's input queue from overflowing.
The driver may be able to service the USART, but firmware may have no space for the byte read!
This can happen when the thread consuming input is blocked for any reason.
In my case it was waiting for CTS on another port.

When implemented correctly,
RTS is deasserted when the input FIFO becomes "nearly full" (i.e. rises beyond its "high water mark")
It should be reasserted when the input FIFO becomes less full (i.e. falls below its "low water mark")

How to implement this with as little change to the existing serial drivers as possible?

The existing input queue "notify" hook can be used to reassert RTS when a FIFO falls back below its low water mark.
But, there's nothing I could find in the existing STM32 serial driver interrupt service that would allow one to deassert RTS when the FIFO rises past high water.

Most serial drivers queue a received byte via a hard coded call to sdIncomingDataI().
By simply vectoring this call through an "inputHandler" function pointer (stored in the SerialDriver object), custom versions can:

1) Handle the high water case of RTS,
2) Generate CHN_INPUT_AVAILABLE only on receipt of a new line character or other delimiter,
3) etc...

The SerialDriver object would be initialized with the inputHandler pointing to sdIncomingDataI(), so there'd no change in the behavior of exiting applications.

The only change required to each serial driver is to replace the sdIncomingDataI() call in the ISR to:

Code: Select all

   sdp->inputHandler(sdp, byteReceived);
- brent

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Implementing RS232 CTS/RTS flow control

Postby Giovanni » Wed Mar 01, 2017 8:37 am

Hi,

Making that function indirect is not a bad idea however, I think, it is too late for next release, all serial drivers would have to be updated (not just STM32 ones).

Giovanni

lechndo
Posts: 2
Joined: Mon Mar 21, 2016 8:02 am

Re: Implementing RS232 CTS/RTS flow control

Postby lechndo » Thu Jan 04, 2018 11:31 am

Hey guys.

I'm currently on a project where we are talking to a bluetooth module via serial interface with hardware flow control capabilities.
We are using a STM32F303 and the bluetooth module also uses some STM32Fxxx.

I wrote a small quick-fix for STM32 USARTv2 serial LLD which avoids input queue overflows by not reading data from the RDR in case RTS handling is enabled and the input queue is full.
It just disables the RXNE interrupt and re-enables it in the inotify callback of the input queue.

The solution is far from perfect but works for our use case and a slightly reduced transfer speed is still better than buffer overflows.

The second included patch is more or less cosmetic and uses a common onitify callback function for the output queue instead of separate functions for each driver.

Update:
I added another patch providing a proposal for software based RTS handling for the STM32 USARTv2 serial driver.
I tried to keep the changes as small as possible.
What do you think about the used approach?

Dominik
Attachments
patch1.tar.gz
(3.44 KiB) Downloaded 205 times


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 17 guests