2004-10-04 22:55:53

by Samuel Thibault

[permalink] [raw]
Subject: [Patch] new serial flow control

Hi,

Some Visiobraille braille terminals (TVB) need a peculiar serial flow
control:
- There is no flow control for the PC -> device way (yes, oddly enough)
- For the device -> PC way,
* RTS must be kept low, the device keeps CTS low as well.
* when the device wants to send data, it raises CTS. RTS must
be raised as well. Data can then pass, CTS and RTS are lowered.

We tried to implement that in user space, with ioctl(TIOCMBIS) & al, but
the responsiveness is too low: RTS is not raised soon enough, and the
device aborts transmission.

Here is a patch for 2.4, a 2.6 patch is coming in another mail. It
defines a CTVB flag the same way CRTSCTS is defined, letting user
space choose whether to use it or not (better ideas for the name
are welcome). This makes the device work perfectly (even better than
shipped drivers for DOS).

Applying it to vanilla kernel would be a real good thing for people
having such costly and useful hardware.

Regards,
Samuel Thibault


Attachments:
(No filename) (977.00 B)
tvbpatch-2.4 (14.00 kB)
Download all attachments

2004-10-05 16:51:21

by Chuck Ebbert

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Samual Thibault wrote:

>+ } else if (info->flags & ASYNC_TVB_FLOW) {
>+ if (status & UART_MSR_CTS) {
>+ if (!(info->MCR & UART_MCR_RTS)) {
>+ /* start of TVB frame, raise RTS to greet data */
>+ info->MCR |= UART_MCR_RTS;
>+ serial_out(info, UART_MCR, info->MCR);
>+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
>+ printk("TVB frame start...");
>+#endif
>+ }
>+ } else {
>+ if (info->MCR & UART_MCR_RTS) {
>+ /* CTS went down, lower RTS as well */
>+ info->MCR &= ~UART_MCR_RTS;
>+ serial_out(info, UART_MCR, info->MCR);
>+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
>+ printk("TVB frame started...");
>+#endif
^^^^^^^

Shouldn't this be "ended"? ... or "end" since frame begin msg says "start"
i.e. is not past tense?


--Chuck Ebbert

2004-10-05 17:25:47

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Le mar 05 oct 2004 ? 12:46:34 -0400, Chuck Ebbert a tapot? sur son clavier :
> Samual Thibault wrote:
>
> >+ } else if (info->flags & ASYNC_TVB_FLOW) {
> >+ if (status & UART_MSR_CTS) {
> >+ if (!(info->MCR & UART_MCR_RTS)) {
> >+ /* start of TVB frame, raise RTS to greet data */
> >+ info->MCR |= UART_MCR_RTS;
> >+ serial_out(info, UART_MCR, info->MCR);
> >+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
> >+ printk("TVB frame start...");
> >+#endif
> >+ }
> >+ } else {
> >+ if (info->MCR & UART_MCR_RTS) {
> >+ /* CTS went down, lower RTS as well */
> >+ info->MCR &= ~UART_MCR_RTS;
> >+ serial_out(info, UART_MCR, info->MCR);
> >+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
> >+ printk("TVB frame started...");
> >+#endif
> ^^^^^^^
>
> Shouldn't this be "ended"? ... or "end" since frame begin msg says "start"
> i.e. is not past tense?

No: data actually pass _after_ CTS and RTS are lowered back: the flow control
only indicate the beginning of one frame.

Regards,
Samuel Thibault

2004-10-05 23:54:33

by Alan

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

On Llu, 2004-10-04 at 23:55, Samuel Thibault wrote:
> Here is patch for 2.6

How is this different from CRTSCTS ?


2004-10-06 07:16:05

by Sébastien Hinderer

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

> > Here is patch for 2.6
>
> How is this different from CRTSCTS ?

I'd say it is symmetric. I think the roles of RTS and CTS are exchanged.
Sam, am I right ?

S?bastien.

2004-10-06 07:38:55

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Le mer 06 oct 2004 ? 09:11:10 +0200, S?bastien Hinderer a tapot? sur son clavier :
> > > Here is patch for 2.6
> >
> > How is this different from CRTSCTS ?
>
> I'd say it is symmetric. I think the roles of RTS and CTS are exchanged.
> Sam, am I right ?

No: CRTSCTS is a one-signal-for-each-way flow control: each
side of the link tells whether it can receive data. CTVB is a
two-signals-for-only-one-way flow control: the device tells when it
wants to send data, the PC acknowledges that, and then one frame of
data can pass.

Regards,
Samuel Thibault

2004-10-06 14:31:58

by Alan

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

On Mer, 2004-10-06 at 08:38, Samuel Thibault wrote:
> No: CRTSCTS is a one-signal-for-each-way flow control: each
> side of the link tells whether it can receive data. CTVB is a
> two-signals-for-only-one-way flow control: the device tells when it
> wants to send data, the PC acknowledges that, and then one frame of
> data can pass.

This sounds a lot like RS485 and some other related stuff. I need to
poke my pet async guru and find out if they are the same thing. If so
that would be useful.

2004-10-07 01:30:40

by Stuart MacDonald

[permalink] [raw]
Subject: RE: [Patch] new serial flow control

From: Alan Cox
> On Mer, 2004-10-06 at 08:38, Samuel Thibault wrote:
> > No: CRTSCTS is a one-signal-for-each-way flow control: each
> > side of the link tells whether it can receive data. CTVB is a
> > two-signals-for-only-one-way flow control: the device tells when it
> > wants to send data, the PC acknowledges that, and then one frame of
> > data can pass.
>
> This sounds a lot like RS485 and some other related stuff. I need to
> poke my pet async guru and find out if they are the same thing. If so
> that would be useful.

RS485 is a driver-transparent electrical interface. Unfortunately the
half-duplex and master-slave(s) arrangements require some sort of
token passing to know when they can successfully transmit. This is
usually handled by the apps in some manner, although it's often wanted
to be handled by the serial driver. This could be one method of
signalling, but isn't sufficient to show RS485 operation.

I haven't seen this style of flow control before. What uses it?

..Stu

2004-10-07 01:48:35

by Paul Fulghum

[permalink] [raw]
Subject: RE: [Patch] new serial flow control

On Wed, 2004-10-06 at 20:30, Stuart MacDonald wrote:
> RS485 is a driver-transparent electrical interface.

Yes.

This protocol issue is independent of the electrical interface.

> I haven't seen this style of flow control before. What uses it?

terminal visio-braille (TVB)
A device for the sight impaired.

--
Paul Fulghum
[email protected]


2004-10-07 07:26:12

by Sébastien Hinderer

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Hi,

> > I haven't seen this style of flow control before. What uses it?
>
> terminal visio-braille (TVB)
> A device for the sight impaired.

Just to give a litle bit more precise information: this braille terminal
has been designed more than 10 years ago by the Handialog socity which is
now part of the TechniBraille/United Vision group.
Modern VisioBra"lles (with Prom of version 4 or higher) support both a
standard serial port management, and this odd flow control which was
originally designed to be used under MS-DOS, and was appropriate for doing
polling.

The integration of Samuel's patch into the kernel would allow users of
teominals containing a PROM older than 4 to use brltty with their terminal,
which would be a very useful thing, because updating such a PROM has a very
high cost.

S?bastien.

2004-10-07 11:08:08

by Nick Craig-Wood

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Stuart MacDonald <[email protected]> wrote:
> From: Alan Cox
> > On Mer, 2004-10-06 at 08:38, Samuel Thibault wrote:
> > > No: CRTSCTS is a one-signal-for-each-way flow control: each
> > > side of the link tells whether it can receive data. CTVB is a
> > > two-signals-for-only-one-way flow control: the device tells when it
> > > wants to send data, the PC acknowledges that, and then one frame of
> > > data can pass.
> >
> > This sounds a lot like RS485 and some other related stuff. I need to
> > poke my pet async guru and find out if they are the same thing. If so
> > that would be useful.
>
> RS485 is a driver-transparent electrical interface.

Yes, in theory! In practice it isn't quite transparent due to
tristating.

These are the 4 main types of serial interface that I use regularly
RS232, RS422, RS485 4-Wire and RS485 2-Wire.

RS232 we all know and love - 12 V signalling etc

RS422 is RS232 with a different electrical interface, ie 5V
differential (2 wires per signal, eg rx+, rx- etc)

RS485 4-Wire is like RS422 but the bus has the potential to go
tri-state. In a bus with only one master, the master can just
transmit all the time and all the slaves will listen. However if you
want to be a slave or have multiple masters it is necessary for you to
tristate the bus.

RS485 2-Wire is like RS485 4-Wire except the transmit and receive
lines are combined into rx_tx+ and rx_tx-. In this kind of bus it is
essential everyone tristates the line after transmitting.

For the RS485 busses there needs to be some way of telling the serial
interface hardware that you want the bus to be tristate. This is
typically done with DTR (which isn't used for RS485 busses), DTR=1
means untristate the bus and DTR=0 means tristate it.

When used like this timing is very critical - you must de-assert DTR
as soon as the serial character has left the serial UART. This is
difficult to do exactly in user-space. Alternatively you can use a
specialist serial interface which will do it for you.

In practice for our applications we use RS485 in master mode which
requires no difficult control. When we have to do RS485 in 2-Wire
mode we transmit a character and block our application to wait for it
to come back then de-assert RTS. Thats nasty though and would be much
better done in the serial driver, where you get an interrupt at
exactly the moment the tx fifo is empty.

> Unfortunately the half-duplex and master-slave(s) arrangements
> require some sort of token passing to know when they can
> successfully transmit.

It does. Its usually done with a packet protocol and addresses.

> This is usually handled by the apps in some manner, although it's
> often wanted to be handled by the serial driver. This could be one
> method of signalling, but isn't sufficient to show RS485 operation.

The tristating above should be done in the driver if possible. The
packet protocol etc should be done in the application.

The flow control method described by the OP doesn't sound exactly like
RS485, but the timing constraints of waggling RTS are exactly the
same.

--
Nick Craig-Wood <[email protected]> -- http://www.craig-wood.com/nick

2004-10-07 14:03:59

by Alan

[permalink] [raw]
Subject: RE: [Patch] new serial flow control

On Iau, 2004-10-07 at 02:30, Stuart MacDonald wrote:
> RS485 is a driver-transparent electrical interface. Unfortunately the
> half-duplex and master-slave(s) arrangements require some sort of
> token passing to know when they can successfully transmit. This is
> usually handled by the apps in some manner, although it's often wanted
> to be handled by the serial driver. This could be one method of
> signalling, but isn't sufficient to show RS485 operation.

No its one I've seen a lot there and it turns out having dug into docs
and consulted the serial people in pointy hats that it is RS232
half-duplex mode which is one of those bits of the spec nobody ever
uses.

In this mode the DTE end (host normally) asserts RTS to request
transmit access to the link. The DCE asserts CTS to indicate it has
finished sending bits, and the DTE then transmits.

RTS is a direction selector (RTS = 0, DCE transmit) (RTS = 1, DTE
transmit). CTS acts as the handshake to deal with the link turn around.

So that makes this much more useful.

Alan

2004-10-07 14:30:26

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Hi,

Le jeu 07 oct 2004 ? 14:00:24 +0100, Alan Cox a tapot? sur son clavier :
> In this mode the DTE end (host normally) asserts RTS to request
> transmit access to the link. The DCE asserts CTS to indicate it has
> finished sending bits, and the DTE then transmits.
>
> RTS is a direction selector (RTS = 0, DCE transmit) (RTS = 1, DTE
> transmit). CTS acts as the handshake to deal with the link turn around.

Hum... It seems like every role is inverted with TVB: _TVB_ raises
_CTS_ to request transmit access. The _PC_ then raises _RTS_ to
indicate it has finished sending bits, TVB then transmits.

(Yes, the cabling is correct: that's the way the DOS driver works)

Regards,
Samuel

2004-10-07 20:15:24

by Alan

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

On Maw, 2004-10-05 at 18:25, Samuel Thibault wrote:
> No: data actually pass _after_ CTS and RTS are lowered back: the flow control
> only indicate the beginning of one frame.

Ok I've pondered this somewhat. I don't think the hack proposed is the
right answer for this. I believe you should implement a simple line
discipline for this device so that it stays out of the general code.

Right now that poses a challenge but if drivers were to implement
ldisc->modem_change() or a similar callback for such events an ldisc
could then handle many of the grungy suprises and handle them once and
in one place.

Thoughts ?

Alan

2004-10-07 20:31:12

by Russell King

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

On Thu, Oct 07, 2004 at 08:08:56PM +0100, Alan Cox wrote:
> On Maw, 2004-10-05 at 18:25, Samuel Thibault wrote:
> > No: data actually pass _after_ CTS and RTS are lowered back: the flow control
> > only indicate the beginning of one frame.
>
> Ok I've pondered this somewhat. I don't think the hack proposed is the
> right answer for this. I believe you should implement a simple line
> discipline for this device so that it stays out of the general code.
>
> Right now that poses a challenge but if drivers were to implement
> ldisc->modem_change() or a similar callback for such events an ldisc
> could then handle many of the grungy suprises and handle them once and
> in one place.

To me at least that sounds like a good solution. I can't help but
wonder whether moving some of the usual modem line status change
processing should also be moved into the higher levels. This will
probably make more sense if the "block till ready" code also moves,
which I think Ted was considering at one point.

However, that's probably something to think about later.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core

2004-10-07 21:46:04

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Le jeu 07 oct 2004 ? 20:08:56 +0100, Alan Cox a ?crit:
> Right now that poses a challenge but if drivers were to implement
> ldisc->modem_change() or a similar callback for such events an ldisc
> could then handle many of the grungy suprises and handle them once and
> in one place.

Surprises like regular RTS/CTS flow control ?
Aren't there serial chips that are able to handle it themselves ? (so
that the _serial driver_ should be responsible for that, doing it in
software if needed)

I'm asking because there was some funny bug not that far ago: async
ppp people thought that xon/xoff were processed in the serial driver,
because "some serial chips may be able to handle that themselves". So
they weren't processing them. But actually it's really up to the
ldisc to process them. Thus nobody was processing it !

Regards,
Samuel Thibault

2004-10-07 22:15:59

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Le jeu 07 oct 2004 ? 21:27:22 +0100, Russell King a ?crit:
> I can't help but wonder whether moving some of the usual modem line
> status change processing should also be moved into the higher levels.

The more I'm thinking about it, the more I think it's not a good idea:
that would require *every* line discipline to implement hardware flow
control (just like xon/xoff), while I think they shouldn't really care
about it.

The asynchronous ppp ldisc for instance can be used on a serial line,
but can very well be used on a ssh tunnel (in which case rts/cts flow
control has no meaning).

I can understand that xon/xoff processing be implemented in ldiscs
since it is characters stuff, but one can't ask the ldisc to know
details about hardware flow control which depends on the tty it is
used on.

Regards,
Samuel Thibault

2004-10-07 23:03:27

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Le jeu 07 oct 2004 ? 23:43:30 +0200, Samuel Thibault a ?crit:
> I'm asking because there was some funny bug not that far ago: async
> ppp people thought that xon/xoff were processed in the serial driver,

For some record
http://groups.google.com/groups?threadm=Pine.LNX.4.10.10112042358240.2290-100000@youpi.residence.ens-lyon.fr#link15
and
http://groups.google.com/groups?threadm=Pine.LNX.4.10.10112062257590.1328-100000@youpi.residence.ens-lyon.fr
(google didn't like the subject change)

Regards,
Samuel Thibault

2004-10-07 23:27:43

by Russell King

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

On Fri, Oct 08, 2004 at 12:08:51AM +0200, Samuel Thibault wrote:
> Le jeu 07 oct 2004 ? 21:27:22 +0100, Russell King a ?crit:
> > I can't help but wonder whether moving some of the usual modem line
> > status change processing should also be moved into the higher levels.
>
> The more I'm thinking about it, the more I think it's not a good idea:
> that would require *every* line discipline to implement hardware flow
> control (just like xon/xoff), while I think they shouldn't really care
> about it.

Please note that I said "into the higher levels" and not "into line
disciplines" - I completely agree with you. For the general case,
line disciplines do not need to know that the CTS signal has been
deasserted, or that DCD has deasserted - these are all meaningless
to the vast majority.

There are special cases though, such as the one being discussed in
this thread, where it does make sense for the line discipline to
override the default behaviour.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core

2004-10-08 19:01:27

by Samuel Thibault

[permalink] [raw]
Subject: Re: [Patch] new serial flow control

Le jeu 07 oct 2004 ? 20:08:56 +0100, Alan Cox wrote:
> On Maw, 2004-10-05 at 18:25, Samuel Thibault wrote:
> > No: data actually pass _after_ CTS and RTS are lowered back: the flow control
> > only indicate the beginning of one frame.
>
> Ok I've pondered this somewhat. I don't think the hack proposed is the
> right answer for this. I believe you should implement a simple line
> discipline for this device so that it stays out of the general code.
>
> Right now that poses a challenge but if drivers were to implement
> ldisc->modem_change() or a similar callback for such events an ldisc
> could then handle many of the grungy suprises and handle them once and
> in one place.

Serial drivers should then at least (when seeing ldisc->modem_change
!= NULL) do no RTS/CTS/DTR/etc handling at all (to avoid interfering),
and activate "MSI" for calling modem_change in the interrupt handler.

Being able to call port->ops->start/stop_tx by some way will also be
necessary, by grouping
{
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port;
tty->hw_stopped = 0;
port->ops->start_tx(port, 0);
uart_write_wakeup(port);
}
and its dual in some function for instance.

Regards,
Samuel Thibault