From: "Tosoni" <jp.tosoni@acksys.fr>
To: JZabalza@cemitec.com, 'linux-serial' <linux-serial@vger.kernel.org>
Cc: Jean-Pierre TOSONI <TOSONI@acksys.local>
Subject: RE: Handling RTS
Date: Mon, 28 Jan 2008 10:27:05 +0100 [thread overview]
Message-ID: <008601c8618f$f3643f30$2e01a8c0@acksys.local> (raw)
In-Reply-To: <OFB4416C24.6CC7E961-ONC12573DB.002E41AD-C12573DB.0034DD9C@cemitec.com>
Please note that the subject has been discussed in deep several times :
http://www.spinics.net/lists/linux-serial/msg00303.html
http://www.mail-archive.com/linux-serial@vger.rutgers.edu/msg00407.html
Also the driver CRISV10.C once had some provision for RTS toggle (at least
this was true three years ago).
I gave you some of my code below, which diverts from the CRISV10 ioctl in a
compatible way. I can send you all the code offline if you wish (not sure it
will help more although).
> Yes, but, I am confused. A line discipline is oriented to translate data
> not to handle flow control protocol , isn't It?
>
- A line discipline defines a way to manage the transmission line, not
merely data translation but mainly the protocol. So it is a good place to
enforce half duplex for example.
> Is it posible implement RTS handling on serial_core.c module to be common
to all uarts?
> This shall be used by all uarts, isn't it?
>
- Well, yes. But some people won't want the feature, so it must be
configurable in some way. hence the need for an ioctl (callable from user
space or from a line discipline, whatever).
> is it posible activate RTS just before start_tx() call using
uart_update_mctrl() function?
>
- I am not familiar with this part of the driver, but there is a problem
mainly with the RTS drop, because we don't know for sure when the UART
serializer is empty. So the implementation on the 8250 requires to start a
timer when the driver's buffer becomes empty. It's no easy because some
uarts have fifo's of their own.
- Also, I have encountered cases where a parametrized delay was needed
between RTS and data, so it would be great if your new IOCTL has parameters
to do this (even if you only implement the 'zero delay' case) just like I
have done in my own implementation, and the CRISV10 driver does the full
implementation.
- Also, pay attention to this use of RTS that may go in the way of flow
control by RTS (CRTSCTS flag), you may want to disable flow control when you
activate RTS toggling.
Here is what I am using for a 82950 device. The ioctl can be used for any
UART but my implementation applies only to the 82950, so, I don't need to
change the RTS in the transmission data path:
///// in 8250.c: ////////////////////
added in uart_ops serial8250_pops:
.ioctl = serial8250_ioctl,
then:
static int
serial8250_ioctl(struct uart_port *port, unsigned int cmd, unsigned long
arg)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
int ret = -ENOIOCTLCMD;
switch (cmd) {
case TIOCSERSETRS485:
if (up->port.type == PORT_16C950) {
// arg may be 1 or struct rs485_control *
// in order to be crisv10 compatible
/* HERE, STUFF to activate built-in 16C950 RTS toggle */
...
return 0;
}
// else, it may be the RTS-TOGGLE kind of RS485 device, needs
// more work to support. See crisv10.c.
break;
default:
break;
}
return ret;
}
///// misc defines which should be included in linux standard headers
////////
/* in asm-i386/ioctls.h */
#ifndef TIOCSERSETRS485
#define TIOCSERSETRS485 0x5461 /* enable rs-485 */
#define TIOCSERWRRS485 0x5462 /* write rs-485 */
#endif
///////////// sample use /////////////////////
#include <stdio.h>
//#include "ioctls.h"
#include <linux/termios.h>
//#include <sys/ioctl.h>
#ifndef TIOCSERSETRS485
#define TIOCSERSETRS485 0x5461 /* enable rs-485 */
#define TIOCSERWRRS485 0x5462 /* write rs-485 */
#endif
main(int c,char **v)
{
int fd,i;
char t[1000];
if (c != 3) {
fprintf(stderr,"usage: %s /dev/ttySxxx 0-or-1\n",v[0]);
exit(1);
}
fd = open(v[1],2);
if(fd < 0) {
perror(v[1]);
exit(1);
}
i = ioctl(fd,TIOCSERSETRS485,atoi(v[2]));
if(i < 0) {
perror("TIOCRS485");
}
printf("%s set to %s\n",v[1],atoi(v[2])
? "RS485 auto turnaround using DTR"
: "normal full-duplex mode");
close(fd);
}
> -----Original Message-----
> From: JZabalza@cemitec.com [mailto:JZabalza@cemitec.com]
> Sent: Friday, January 25, 2008 10:38 AM
> To: 'linux-serial'
> Cc: Tosoni
> Subject: RE: Handling RTS
>
>
> linux-serial-owner@vger.kernel.org escribió el 24/01/2008 14:42:14:
>
> Thank you very munch for your response Jean-Pierre. I think
> you understand
> me.
>
> > It has been known since long ago that this behaviour (which
> is required
> to
> > properly handle many RS485 devices) is not implemented by
> the serial
> driver.
> >
> > So yes, you will have to implement it.
> > There are several ways to do it, by creating a new line
> discipline as
> > suggested by Russell King, or a new termios behaviour, or a
> new serial
> > ioctl.
>
>
> Yes, but, I am confused. A line discipline is oriented to
> translate data
> not to handle flow control protocol , isn't It?
>
>
> >
> > In any case you will also need to add support for this in the 8250
> driver
> > itself. You can do this
> > - by using special features of 82950 uarts (I did this once),
> > - or by implementing RTS toggleing in software, which
> > (1) is more difficult because there is no UART interrupt
> > at the end of the byte serialization process,
> > (2) is more flexible because you may want to handle a
> > configurable delay between RTS rise/data/RTS fall,
> > (3) is the only way with the 16C550 and earlier devices.
> >
>
> Yes, but it's only for 8250 uart. I think that all uarts have
> RTS pin. I
> know it's not true, but
>
> For example this code snipet from serial_core.c
>
> static void __uart_start(struct tty_struct *tty)
> {
> struct uart_state *state = tty->driver_data;
> struct uart_port *port = state->port;
>
> if (!uart_circ_empty(&state->info->xmit) &&
> state->info->xmit.buf
> &&
> !tty->stopped && !tty->hw_stopped)
> port->ops->start_tx(port);
> }
>
> is it posible activate RTS just before start_tx() call using
> uart_update_mctrl() function?
>
> This shall be used by all uarts, isn't it?
>
> Is it posible implement RTS handling on serial_core.c module
> to be common
> to all uarts?
>
> Thanks in avance
>
>
>
>
>
>
>
>
> José Luis Zabalza
>
>
-
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
prev parent reply other threads:[~2008-01-28 9:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-09 18:17 Handling RTS JZabalza
2008-01-09 20:35 ` Chris Doré
2008-01-10 8:27 ` JZabalza
2008-01-14 15:05 ` Chris Doré
2008-01-21 11:57 ` JZabalza
2008-01-24 13:42 ` Tosoni
2008-01-25 9:37 ` JZabalza
2008-01-28 9:27 ` Tosoni [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='008601c8618f$f3643f30$2e01a8c0@acksys.local' \
--to=jp.tosoni@acksys.fr \
--cc=JZabalza@cemitec.com \
--cc=TOSONI@acksys.local \
--cc=linux-serial@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox