Re: pl2303.c and the pin status

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 21/03/2012 7:29 PM, Greg KH wrote:
On Wed, Mar 21, 2012 at 06:54:37PM -0400, Gerald Villemure wrote:
On 21/03/2012 3:08 PM, Greg KH wrote:
On Wed, Mar 21, 2012 at 02:47:56PM -0400, Gerald Villemure wrote:
Currently if we want to read the status of the PINs on a serial
port, I need to open the file (e.g. /dev/ttyUSB0) unfortunately in
doing so we *change* RTS/DTR
Hm, just opening the port shouldn't change the line settings.  Is this
unique to the pl2303 driver, or does it also happen on a "normal" serial
port as well?
I tryed it on:  USB:pl2303,cp210x,ftdi_sio and also on the regular
motherboard /dev/ttyS0
In every case DTR and RTS go high as soon as OPEN is called on the
device file.
I can't find my old RS232 book at the moment, but I think that the spec
requires this, as really, you are ready to send at this point in time.

And, this shouldn't cause anything to happen on the device side, or does
it?  I guess data could start flowing, but heck, that's what you want to
have happen on a normal port, right?

Can you verify this somehow?
When using the serial port for serial communication its perfectly reasonable to want DTR to be high, and you want RTS to be high when ready to send data.
Using serial port lines as toggle switches is generally not the best
thing to do, lots of the cheaper usb-to-serial devices don't even hook
them up at all, so no matter how hard you try, nothing happens.
I recently started to play around with electronics and there are MANY situation when all you need is a toggle. USB to RS232 adapters are readily available online (less then $3, avoid those under $2) and work quite well.

In my view the serial port is still the cheapest and simplest solution for many small DIY electronics projects. Unfortunately most projects I find on the Internet use VB code for reading/writing to the pins. The one advantage the windows driver has over the Linux driver right now is that you can access the status of the pins without altering them.
I hacked the pl2303.c files to add the following param:
parm:           openmode:Intitial settings on open, default=3
(0=!DTR_!RTS, 1=DTS_!RTS, 2=!DTR_RTS, 3=DTR_RTS) (int)

That way you can load the module using something like this:
insmod /.../pl2303.ko debug openmode=0

But its an ugly hack... If you want it let me know.
The diff would be interesting to see at the least.

I don't like this approach since it will break more stuff then it fixes. Opening the device file SHOULD properly prepare the port for serial communication. That is why I am thinking that an alternate way to read the pins is in order for DIY electronic use.

Anyhow, here is the patch:


--- pl2303.c_orig       2011-11-30 13:05:16.000000000 -0500
+++ pl2303.c    2012-01-07 00:11:02.000000000 -0500
@@ -37,6 +37,7 @@
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"

 static int debug;
+static int openmode = 0x03;

 #define PL2303_CLOSING_WAIT    (30*HZ)

@@ -696,14 +697,14 @@
        /* change control lines if we are switching to or from B0 */
        spin_lock_irqsave(&priv->lock, flags);
        control = priv->line_control;
-       if ((cflag & CBAUD) == B0)
-               priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
-       else
-               priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
+//     if ((cflag & CBAUD) == B0)
+//             priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
+//     else
+//             priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
        if (control != priv->line_control) {
                control = priv->line_control;
                spin_unlock_irqrestore(&priv->lock, flags);
-               set_control_lines(serial->dev, control);
+//             set_control_lines(serial->dev, control);
        } else {
                spin_unlock_irqrestore(&priv->lock, flags);
        }
@@ -740,13 +741,12 @@

        spin_lock_irqsave(&priv->lock, flags);
        /* Change DTR and RTS */
-       if (on)
-               priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
-       else
-               priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
+//     priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
+       priv->line_control = openmode;
+       dbg("Initial openmode %d", openmode);
        control = priv->line_control;
        spin_unlock_irqrestore(&priv->lock, flags);
-       set_control_lines(port->serial->dev, control);
+//     set_control_lines(port->serial->dev, control);
 }

 static void pl2303_close(struct usb_serial_port *port)
@@ -1256,3 +1256,6 @@
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");

+module_param(openmode, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(openmode, "Intitial settings on open, default=3 (0=!DTR_!RTS, 1=DTS_!RTS, 2=!DTR_RTS, 3=DTR_RTS)");
+


How difficult would it be to extent the usb_serial driver to expose
the pin status like this:

/sys/class/tty/ttyUSB0/device/RTS (rw, Request To Send)
/sys/class/tty/ttyUSB0/device/CTS (r,  Clear To Send)
/sys/class/tty/ttyUSB0/device/DSR (r,  Data Set Ready)
/sys/class/tty/ttyUSB0/device/DCD (r,  Data Carrier Detect)
/sys/class/tty/ttyUSB0/device/DTR (rw, Data Terminal Ready)
/sys/class/tty/ttyUSB0/device/RI  (r,  Ring Indicator)

We could then simply read the file /sys/class/tty/ttyUSB0/device/DCD
and get a 1 if it is high.
That would imply that at all times, even if the port is not open, the
driver needs to be watching the line settings of the device?  For usb to
serial devices, this can take a lot of USB traffic to do so, and might
make people who care about power usage unhappy.

Or we could just do the querying of the device if the sysfs file is
open...
That is correct, you poll the device ONLY when the sysfs file is opened.

This would open up the use of the serial port PIN's to scripting.
Again, don't try to use these pins as toggles, that's generally a bad
idea for the above reason.

I supposed that is where we differ. I want to use all the pins EXCEPT Tx and Rx in my projects.

I know some will think I should just buy a big fancy PIC chip that has native USB support and control my projects that way. The the simple truth is, it would be a great deal more complex and more expensive.

My ideal solution is; you plug in the usb->serial adapter in ANY Linux based device (e.g. OpenWRT router) install the shell script, your done.

We could also control RTS/DTS by using something like:
echo 1>   /sys/class/tty/ttyUSB0/device/DTR

I realize that if we LIMIT our usage of the serial port to ONLY
serial communication then there is not value is this extension.  But
the moment you start using it to drive DIY electronics it would be a
VERY welcomed addition.
There is the POSIX interface for serial ports, which we can't ignore, so
we need to keep that.  But, to extend this to all serial ports, not just
USB ones, might be nice for some users.
I would agree.
So, care to work on a patch to the tty core that implements this to see
if it's even viable?  :)
I am far from being a proper kernel hacker.  I would not know where
to start.
It sounds like you started already with the module parameter :)

greg k-h

I am willing to help to get the ball rolling. I can help to test to make sure the patch works as expected, etc.

I think if I was to write the patch myself you would likely end up re-writing it. :)

Gérald
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux