summaryrefslogtreecommitdiff
path: root/pyserial
diff options
context:
space:
mode:
authorcliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2003-10-01 02:28:12 +0000
committercliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2003-10-01 02:28:12 +0000
commitd6bf52c0728d64c0afb8ecff47763d7d0dd41d75 (patch)
tree0ccf909b4832197ea3b53a0e264008d0b9fab8f2 /pyserial
parent3a77ac83b99ff59b507450091d3989eb83f91540 (diff)
downloadpyserial-git-d6bf52c0728d64c0afb8ecff47763d7d0dd41d75.tar.gz
Transition to the 2.0 series:
- New implementation only supports Python 2.2+, backwards compatibility should be maintained almost everywhere. The OS handles (like the hComPort or fd attribute) were prefixed with an underscore. The different names stay, as anyone that uses one of these has to write platform specific code anyway. - Common base class serialutil.SerialBase for all implementations. - PARITY_NONE, PARITY_EVEN, PARITY_ODD constants changed and all these constants moved to serialutil.py (still available as serial.PARITY_NONE etc. and they should be used that way) - Added serial.PARITY_NAMES (implemented in serialutil.PARITY_NAMES). This dictionary can be used to convert parity constants to meaningful strings. - Each Serial class and instance has a list of supported values: BAUDRATES, BYTESIZES, PARITIES, STOPBITS (i.e. serial.Serial.BAUDRATES or s = serial.Serial; s.BAUDRATES) these values can be used to fill in value sin GUI dialogs etc. - Creating a Serial() object without port spec returns an unconfigured, closed port. Useful if a GUI dialog should take a port and configure it. - New methods for serial.Serial instances: open(), isOpen() - A port can be opened and closed as many times as desired. - Instances of serial.Serial have baudrate, bytesize, timeout etc. attributes implemented as properties, all can be set while the port is opened. It will then be reconfigured. - Improved __doc__'s. - New test_advanced.py for the property setting/getting testing. - Small bugfix on posix with get* methods (return value should be true a boolean). - added a __repr__ that returns a meaningful string will all the serial setting, easy for debugging. - The serialposix module does not throw an exception on unsupported platforms, the message is still printed. The idea that it may still work even if the platform itself s not known, it simply tries to do the posix stuff anyway (It's likely that opening ports by number fails, but by name it should work).
Diffstat (limited to 'pyserial')
-rw-r--r--pyserial/CHANGES.txt71
-rw-r--r--pyserial/MANIFEST2
-rw-r--r--pyserial/README.txt59
-rw-r--r--pyserial/examples/miniterm.py3
-rw-r--r--pyserial/examples/test.py25
-rw-r--r--pyserial/examples/test_advanced.py156
-rw-r--r--pyserial/serial/serialjava.py215
-rw-r--r--pyserial/serial/serialposix.py306
-rw-r--r--pyserial/serial/serialutil.py247
-rw-r--r--pyserial/serial/serialwin32.py201
-rw-r--r--pyserial/setup.py2
11 files changed, 894 insertions, 393 deletions
diff --git a/pyserial/CHANGES.txt b/pyserial/CHANGES.txt
index fcdf51b..7e53cda 100644
--- a/pyserial/CHANGES.txt
+++ b/pyserial/CHANGES.txt
@@ -40,16 +40,17 @@ Version 1.15 04 Jun 2002
- compatibility to win9x improved
Version 1.16 02 Jul 2002
- added implementation of RI and corrected RTS/CTS on Win32
+ Added implementation of RI and corrected RTS/CTS on Win32
Version 1.17 03 Jul 2002
- silly mix of two versions in win32 code corrected
+ Silly mix of two versions in win32 code corrected
Version 1.18 06 Dec 2002
Bugfixes (general):
- - remove the mapping of flush to the destructive flushOutput as this
- is not the expected behaviour
- - readline: EOL character for lines can be chosen idea by John Florian
+ - remove the mapping of flush to the destructive flushOutput as
+ this is not the expected behaviour.
+ - readline: EOL character for lines can be chosen idea by
+ John Florian.
Bugfixes (posix):
- cygwin port numbering fixed
- test each and every constant for it's existence in termios module,
@@ -62,20 +63,64 @@ Version 1.18 06 Dec 2002
Version 1.19 19 Mar 2003
Bugfixes (posix):
- - removed dgux entry which actualy had a wrong comment and is probably not in use anywhere
+ - removed dgux entry which actualy had a wrong comment and is
+ probably not in use anywhere.
Bugfixes (win32):
- added int() conversion, [Bug 702120]
- - remove code to set control lines in close methond of win32 version. [Bug 669625]
+ - remove code to set control lines in close methond of win32
+ version. [Bug 669625]
Version 1.20 28 Aug 2003
- added serial.device() for all platforms
+ Added serial.device() for all platforms
Bugfixes (win32):
- - don't recreate opverlaped structures and events on each read/write
- - don't set unneded event masks
- - dont use DOS device names for ports > 9
- - remove send timeout (its not used in the linux impl. anyway)
+ - don't recreate opverlaped structures and events on each
+ read/write.
+ - don't set unneded event masks.
+ - dont use DOS device names for ports > 9.
+ - remove send timeout (its not used in the linux impl. anyway).
Version 1.21 30 sep 2003
Bugfixes (win32):
- - name for COM10 was not built correctly, found by Norm Davis
+ - name for COM10 was not built correctly, found by Norm Davis.
+ Bugfixes (examples):
+ - small change in miniterm.py that should mage it run on cygwin,
+ [Bug 809904] submitted by Rolf Campbell.
+
+Version 2.0b1 ...
+ Transition to the 2.0 series:
+ - New implementation only supports Python 2.2+, backwards compatibility
+ should be maintained almost everywhere.
+ The OS handles (like the hComPort or fd attribute) were prefixed with an
+ underscore. The different names stay, as anyone that uses one of these
+ has to write platform specific code anyway.
+ - Common base class serialutil.SerialBase for all implementations.
+ - PARITY_NONE, PARITY_EVEN, PARITY_ODD constants changed and all these
+ constants moved to serialutil.py (still available as serial.PARITY_NONE
+ etc. and they should be used that way)
+ - Added serial.PARITY_NAMES (implemented in serialutil.PARITY_NAMES).
+ This dictionary can be used to convert parity constants to meaningful
+ strings.
+ - Each Serial class and instance has a list of supported values:
+ BAUDRATES, BYTESIZES, PARITIES, STOPBITS
+ (i.e. serial.Serial.BAUDRATES or s = serial.Serial; s.BAUDRATES)
+ these values can be used to fill in value sin GUI dialogs etc.
+ - Creating a Serial() object without port spec returns an unconfigured,
+ closed port. Useful if a GUI dialog should take a port and configure
+ it.
+ - New methods for serial.Serial instances: open(), isOpen()
+ - A port can be opened and closed as many times as desired.
+ - Instances of serial.Serial have baudrate, bytesize, timeout etc.
+ attributes implemented as properties, all can be set while the port is
+ opened. It will then be reconfigured.
+ - Improved __doc__'s.
+ - New test_advanced.py for the property setting/getting testing.
+ - Small bugfix on posix with get* methods (return value should be true a
+ boolean).
+ - added a __repr__ that returns a meaningful string will all the serial
+ setting, easy for debugging.
+ - The serialposix module does not throw an exception on unsupported
+ platforms, the message is still printed. The idea that it may still
+ work even if the platform itself s not known, it simply tries to do
+ the posix stuff anyway (It's likely that opening ports by number
+ fails, but by name it should work).
diff --git a/pyserial/MANIFEST b/pyserial/MANIFEST
index 99e248c..20ea14a 100644
--- a/pyserial/MANIFEST
+++ b/pyserial/MANIFEST
@@ -10,4 +10,6 @@ serial\serialutil.py
examples\miniterm.py
examples\tcp_serial_redirect.py
examples\test.py
+examples\test_advanced.py
examples\scan.py
+examples\enhancedserial.py
diff --git a/pyserial/README.txt b/pyserial/README.txt
index 88aef37..8a582f8 100644
--- a/pyserial/README.txt
+++ b/pyserial/README.txt
@@ -33,7 +33,7 @@ Features
Requirements
------------
-- Python 2.0 or newer (1.5.2 untested)
+- Python 2.2 or newer
- win32all extensions on Windows
- "Java Communications" (JavaComm) extension for Java/Jython
@@ -43,8 +43,7 @@ Installation
Extract files from the archive, open a shell/console in that directory and
let Distutils do the rest: "python setup.py install"
-The files get installed in the "Lib/site-packages" directory in newer
-Python versions.
+The files get installed in the "Lib/site-packages" directory.
Serial to USB adapters
----------------------
@@ -80,7 +79,7 @@ Open named port at "19200,8,N,1", 1s timeout
>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
>>> x = ser.read() #read one byte
>>> s = ser.read(10) #read up to ten bytes (timeout)
->>> line = ser.readline() #read a \n terminated line
+>>> line = ser.readline() #read a '\n' terminated line
>>> ser.close()
Open second port at "38400,8,E,1", non blocking HW handshaking
@@ -89,6 +88,20 @@ Open second port at "38400,8,E,1", non blocking HW handshaking
>>> s = ser.read(100) #read up to one hunded bytes
... #or as much is in the buffer
+Get a Serial instance and configure/open it later
+>>> ser = serial.Serial()
+>>> ser.baudrate = 19200
+>>> ser.port = 0
+>>> ser
+Serial<id=0xa81c10, open=False>(port='COM1', baudrate=19200, bytesize=8,
+parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)
+>>> ser.open()
+>>> ser.isOpen()
+True
+>>> ser.close()
+>>> ser.isOpen()
+False
+
Be carefully when using "readline". Do specify a timeout when
opening the serial port otherwise it could block forever if
no newline character is received. Also note that "readlines" only
@@ -100,10 +113,12 @@ if the port is not opened correctly.
Parameters for the Serial class
-------------------------------
ser = serial.Serial(
- port, #number of device, numbering starts at
+ port=None, #number of device, numbering starts at
#zero. if everything fails, the user
#can specify a device string, note
#that this isn't portable anymore
+ #if no port is specified an unconfigured
+ #an closed serial port object is created
baudrate=9600, #baudrate
bytesize=EIGHTBITS, #number of databits
parity=PARITY_NONE, #enable parity checking
@@ -119,15 +134,16 @@ timeout=None #wait forever
timeout=0 #non-blocking mode (return immediately on read)
timeout=x #set timeout to x seconds (float allowed)
-Serial object Methods
----------------------
+Methods of Serial instances
+---------------------------
+open() #open port
close() #close port immediately
setBaudrate(baudrate) #change baudarte on an open port
inWaiting() #return the number of chars in the receive buffer
read(size=1) #read "size" characters
-write(s) #write the string to the port
-flushInput() #flush input buffer
-flushOutput() #flush output buffer
+write(s) #write the string s to the port
+flushInput() #flush input buffer, discarding all it's contents
+flushOutput() #flush output buffer, abort output
sendBreak() #send break condition
setRTS(level=1) #set RTS line to specified logic level
setDTR(level=1) #set DTR line to specified logic level
@@ -136,6 +152,27 @@ getDSR() #return the state of the DSR line
getRI() #return the state of the RI line
getCD() #return the state of the CD line
+Attributes of Serial instances
+------------------------------
+Read Only:
+portstr #device name
+BAUDRATES #list of valid baudrates
+BYTESIZES #list of valid byte sizes
+PARITIES #list of valid parities
+STOPBITS #list of valid stop bit widths
+
+New values can be assigned to the following attribues, the port
+will be reconfigured, even if it's opened at that time:
+port #port name/number as set by the user
+baudrate #current baudrate setting
+bytesize #bytesize in bits
+parity #parity setting
+stopbits #stop bit with (1,2)
+timeout #timeout setting
+xonxoff #if XonXoff flow control is enabled
+rtscts #if hardware flow control is enabled
+
+
Constants
---------
parity:
@@ -154,7 +191,7 @@ bytesize:
Tips & Tricks
-------------
- Some protocols need CR LF ("\r\n") as line terminator, not just LF ("\n").
- Modems are an example of this behaviour.
+ Telephone modems with the AT command set are an example of this behaviour.
- Scanning for available serial ports is possible with more or less sucess on
some platforms. Look at the tools from Roger Binns:
diff --git a/pyserial/examples/miniterm.py b/pyserial/examples/miniterm.py
index 43b4fa8..446748e 100644
--- a/pyserial/examples/miniterm.py
+++ b/pyserial/examples/miniterm.py
@@ -37,7 +37,8 @@ elif os.name == 'posix':
termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
s = '' # We'll save the characters typed and add them to the pool.
def getkey():
- c = os.read(fd, 1)
+ #~ c = os.read(fd, 1)
+ c = sys.stdin.read(1)
if echo: sys.stdout.write(c)
return c
def clenaup_console():
diff --git a/pyserial/examples/test.py b/pyserial/examples/test.py
index ec8d13a..d312fe6 100644
--- a/pyserial/examples/test.py
+++ b/pyserial/examples/test.py
@@ -1,25 +1,30 @@
#!/usr/bin/env python
-"""Some Tests for the serial module.
-part of pyserial (http://pyserial.sf.net) (C)2002 cliechti@gmx.net
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
-intended to be run on different platforms, to ensure portability of
+"""Some tests for the serial module.
+Part of pyserial (http://pyserial.sf.net) (C)2002-2003 cliechti@gmx.net
+
+Intended to be run on different platforms, to ensure portability of
the code.
-for all these tests a simple hardware is required.
+For all these tests a simple hardware is required.
Loopback HW adapter:
-shortcut these pin pairs:
+Shortcut these pin pairs:
TX <-> RX
RTS <-> CTS
DTR <-> DSR
-on a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)
-
+On a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)
"""
import unittest, threading, time
import serial
-#of which port should the tests be performed:
+#on which port should the tests be performed:
PORT=0
@@ -153,7 +158,7 @@ class Test0_DataWires(unittest.TestCase):
if __name__ == '__main__':
import sys
print __doc__
- print "testing port", PORT
+ print "Testing port", PORT
sys.argv.append('-v')
- # When this module is executed from the command-line, run all its tests
+ # When this module is executed from the command-line, it runs all its tests
unittest.main()
diff --git a/pyserial/examples/test_advanced.py b/pyserial/examples/test_advanced.py
new file mode 100644
index 0000000..d9ca93d
--- /dev/null
+++ b/pyserial/examples/test_advanced.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#needs at least python 2.2.3
+
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+"""Some tests for the serial module.
+Part of pyserial (http://pyserial.sf.net) (C)2002 cliechti@gmx.net
+
+Intended to be run on different platforms, to ensure portability of
+the code.
+
+These tests open a serial port and change all the settings on the fly.
+If the port is realy correctly configured cannot be determined - that
+would require external hardware or a nullmodem cable and an other
+serial port library... Thus it mainly tests that all features are
+correctly implemented and that the interface does what it should.
+"""
+
+import unittest
+import serial
+
+#on which port should the tests be performed:
+PORT=0
+
+class Test_ChangeAttributes(unittest.TestCase):
+ """Test with timeouts"""
+
+ def setUp(self):
+ self.s = serial.Serial() #create an closed serial port
+
+ def tearDown(self):
+ self.s.close()
+
+ def test_PortSetting(self):
+ self.s.port = PORT
+ #portstr has to be set
+ self.failUnlessEqual(self.s.portstr, serial.device(PORT))
+ #test internals
+ self.failUnlessEqual(self.s._port, PORT)
+ #test on the fly change
+ self.s.open()
+ self.failUnless(self.s.isOpen())
+ self.s.port = 0
+ self.failUnless(self.s.isOpen())
+ self.failUnlessEqual(self.s.port, 0)
+ self.failUnlessEqual(self.s.portstr, serial.device(0))
+ try:
+ self.s.port = 1
+ except serial.SerialException: #port not available on system
+ pass #cant test on this machine...
+ else:
+ self.failUnless(self.s.isOpen())
+ self.failUnlessEqual(self.s.port, 1)
+ self.failUnlessEqual(self.s.portstr, serial.device(1))
+
+ def test_BaudrateSetting(self):
+ for baudrate in (300, 9600, 19200, 115200):
+ self.s.baudrate = baudrate
+ #test get method
+ self.failUnlessEqual(self.s.baudrate, baudrate)
+ #test internals
+ self.failUnlessEqual(self.s._baudrate, baudrate)
+ #test illegal values
+ for illegal_value in (-300, -1, 0, 301, 9000, 12345, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setBaudrate, illegal_value)
+
+ def test_BytesizeSetting(self):
+ for bytesize in (5,6,7,8):
+ self.s.bytesize = bytesize
+ #test get method
+ self.failUnlessEqual(self.s.bytesize, bytesize)
+ #test internals
+ self.failUnlessEqual(self.s._bytesize, bytesize)
+ #test illegal values
+ for illegal_value in (0, 1, 3, 4, 9, 10, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setByteSize, illegal_value)
+
+ def test_ParitySetting(self):
+ for parity in (serial.PARITY_NONE, serial.PARITY_EVEN, serial.PARITY_ODD):
+ self.s.parity = parity
+ #test get method
+ self.failUnlessEqual(self.s.parity, parity)
+ #test internals
+ self.failUnlessEqual(self.s._parity, parity)
+ #test illegal values
+ for illegal_value in (0, 57, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setParity, illegal_value)
+
+ def test_StopbitsSetting(self):
+ for stopbits in (1, 2):
+ self.s.stopbits = stopbits
+ #test get method
+ self.failUnlessEqual(self.s.stopbits, stopbits)
+ #test internals
+ self.failUnlessEqual(self.s._stopbits, stopbits)
+ #test illegal values
+ for illegal_value in (0, 3, 1.5, 57, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setStopbits, illegal_value)
+
+ def test_TimeoutSetting(self):
+ for timeout in (None, 0, 1, 3.14159, 10, 1000, 3600):
+ self.s.timeout = timeout
+ #test get method
+ self.failUnlessEqual(self.s.timeout, timeout)
+ #test internals
+ self.failUnlessEqual(self.s._timeout, timeout)
+ #test illegal values
+ for illegal_value in (-1, 'a'):
+ self.failUnlessRaises(ValueError, self.s.setTimeout, illegal_value)
+
+ def test_XonXoffSetting(self):
+ for xonxoff in (True, False):
+ self.s.xonxoff = xonxoff
+ #test get method
+ self.failUnlessEqual(self.s.xonxoff, xonxoff)
+ #test internals
+ self.failUnlessEqual(self.s._xonxoff, xonxoff)
+ #no illegal values here, normal rules for the boolean value of an
+ #object are used thus all objects have a truth value.
+
+ def test_RtsCtsSetting(self):
+ for rtscts in (True, False):
+ self.s.rtscts = rtscts
+ #test get method
+ self.failUnlessEqual(self.s.rtscts, rtscts)
+ #test internals
+ self.failUnlessEqual(self.s._rtscts, rtscts)
+ #no illegal values here, normal rules for the boolean value of an
+ #object are used thus all objects have a truth value.
+
+ def test_UnconfiguredPort(self):
+ #an unconfigured port cannot be opened
+ self.failUnlessRaises(serial.SerialException, self.s.open)
+
+ def test_PortOpenClose(self):
+ self.s.port = PORT
+ for i in range(3):
+ #open the port and check flag
+ self.failUnless(not self.s.isOpen())
+ self.s.open()
+ self.failUnless(self.s.isOpen())
+ self.s.close()
+ self.failUnless(not self.s.isOpen())
+
+
+if __name__ == '__main__':
+ import sys
+ print __doc__
+ print "Testing port", PORT
+ sys.argv.append('-v')
+ # When this module is executed from the command-line, it runs all its tests
+ unittest.main()
diff --git a/pyserial/serial/serialjava.py b/pyserial/serial/serialjava.py
index c199d82..90b0896 100644
--- a/pyserial/serial/serialjava.py
+++ b/pyserial/serial/serialjava.py
@@ -1,136 +1,134 @@
#!jython
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
#module for serial IO for Jython and JavaComm
#see __init__.py
#
-#(C) 2002 Chris Liechti <cliechti@gmx.net>
+#(C) 2002-2003 Chris Liechti <cliechti@gmx.net>
# this is distributed under a free software license, see license.txt
-import sys, os, string, javax.comm
-import serialutil
+import javax.comm
+from serialutil import *
-VERSION = string.split("$Revision: 1.7 $")[1] #extract CVS version
+VERSION = "$Revision: 1.8 $".split()[1] #extract CVS version
-PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = (0,1,2,3,4)
-STOPBITS_ONE, STOPBITS_TWO, STOPBITS_ONE_HALVE = (1, 2, 3)
-FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5,6,7,8)
-
-
-portNotOpenError = ValueError('port not open')
def device(portnumber):
+ """Turn a port number into a device name"""
enum = javax.comm.CommPortIdentifier.getPortIdentifiers()
ports = []
while enum.hasMoreElements():
el = enum.nextElement()
if el.getPortType() == javax.comm.CommPortIdentifier.PORT_SERIAL:
ports.append(el)
- return ports[portnumber]
-
-class Serial(serialutil.FileLike):
- def __init__(self,
- port, #number of device, numbering starts at
- #zero. if everything fails, the user
- #can specify a device string, note
- #that this isn't portable anymore
- baudrate=9600, #baudrate
- bytesize=EIGHTBITS, #number of databits
- parity=PARITY_NONE, #enable parity checking
- stopbits=STOPBITS_ONE, #number of stopbits
- timeout=None, #set a timeout value, None to wait forever
- xonxoff=0, #enable software flow control
- rtscts=0, #enable RTS/CTS flow control
- ):
-
- if type(port) == type(''): #strings are taken directly
- portId = javax.comm.CommPortIdentifier.getPortIdentifier(port)
+ return ports[portnumber].getName()
+
+class Serial(SerialBase):
+ """Serial port class, implemented with javax.comm and thus usable with
+ jython and the appropriate java extension."""
+
+ def open(self):
+ """Open port with current settings. This may throw a SerialException
+ if the port cannot be opened."""
+ if self._port is None:
+ raise SerialException("Port must be configured before it can be used.")
+ if type(self._port) == type(''): #strings are taken directly
+ portId = javax.comm.CommPortIdentifier.getPortIdentifier(self._port)
else:
- portId = device(port) #numbers are transformed to a comportid obj
- self.portstr = portId.getName()
+ portId = javax.comm.CommPortIdentifier.getPortIdentifier(device(self._port)) #numbers are transformed to a comportid obj
try:
self.sPort = portId.open("python serial module", 10)
except Exception, msg:
self.sPort = None
- raise serialutil.SerialException, "could not open port: %s" % msg
- self.instream = self.sPort.getInputStream()
- self.outstream = self.sPort.getOutputStream()
+ raise SerialException("Could not open port: %s" % msg)
+ self._reconfigurePort()
+ self._instream = self.sPort.getInputStream()
+ self._outstream = self.sPort.getOutputStream()
+ self._isOpen = True
+
+ def _reconfigurePort(self):
+ """Set commuication parameters on opened port."""
+ if not self.sPort:
+ raise SerialException("Can only operate on a valid port handle")
+
self.sPort.enableReceiveTimeout(30)
- if bytesize == FIVEBITS:
- self.databits = javax.comm.SerialPort.DATABITS_5
- elif bytesize == SIXBITS:
- self.databits = javax.comm.SerialPort.DATABITS_6
- elif bytesize == SEVENBITS:
- self.databits = javax.comm.SerialPort.DATABITS_7
- elif bytesize == EIGHTBITS:
- self.databits = javax.comm.SerialPort.DATABITS_8
+ if self._bytesize == FIVEBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_5
+ elif self._bytesize == SIXBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_6
+ elif self._bytesize == SEVENBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_7
+ elif self._bytesize == EIGHTBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_8
else:
- raise ValueError, "unsupported bytesize"
+ raise ValueError("unsupported bytesize: %r" % self._bytesize)
- if stopbits == STOPBITS_ONE:
- self.jstopbits = javax.comm.SerialPort.STOPBITS_1
+ if self._stopbits == STOPBITS_ONE:
+ jstopbits = javax.comm.SerialPort.STOPBITS_1
elif stopbits == STOPBITS_ONE_HALVE:
- self.jstopbits = javax.comm.SerialPort.STOPBITS_1_5
- elif stopbits == STOPBITS_TWO:
- self.jstopbits = javax.comm.SerialPort.STOPBITS_2
+ self._jstopbits = javax.comm.SerialPort.STOPBITS_1_5
+ elif self._stopbits == STOPBITS_TWO:
+ jstopbits = javax.comm.SerialPort.STOPBITS_2
else:
- raise ValueError, "unsupported number of stopbits"
-
- if parity == PARITY_NONE:
- self.jparity = javax.comm.SerialPort.PARITY_NONE
- elif parity == PARITY_EVEN:
- self.jparity = javax.comm.SerialPort.PARITY_EVEN
- elif parity == PARITY_ODD:
- self.jparity = javax.comm.SerialPort.PARITY_ODD
- elif parity == PARITY_MARK:
- self.jparity = javax.comm.SerialPort.PARITY_MARK
- elif parity == PARITY_SPACE:
- self.jparity = javax.comm.SerialPort.PARITY_SPACE
+ raise ValueError("unsupported number of stopbits: %r" % self._stopbits)
+
+ if self._parity == PARITY_NONE:
+ jparity = javax.comm.SerialPort.PARITY_NONE
+ elif self._parity == PARITY_EVEN:
+ jparity = javax.comm.SerialPort.PARITY_EVEN
+ elif self._parity == PARITY_ODD:
+ jparity = javax.comm.SerialPort.PARITY_ODD
+ #~ elif self._parity == PARITY_MARK:
+ #~ jparity = javax.comm.SerialPort.PARITY_MARK
+ #~ elif self._parity == PARITY_SPACE:
+ #~ jparity = javax.comm.SerialPort.PARITY_SPACE
else:
- raise ValueError, "unsupported parity type"
+ raise ValueError("unsupported parity type: %r" % self._parity)
jflowin = jflowout = 0
- if rtscts:
- jflowin = jflowin | javax.comm.SerialPort.FLOWCONTROL_RTSCTS_IN
- jflowout = jflowout | javax.comm.SerialPort.FLOWCONTROL_RTSCTS_OUT
- if xonxoff:
- jflowin = jflowin | javax.comm.SerialPort.FLOWCONTROL_XONXOFF_IN
- jflowout = jflowout | javax.comm.SerialPort.FLOWCONTROL_XONXOFF_OUT
+ if self._rtscts:
+ jflowin |= javax.comm.SerialPort.FLOWCONTROL_RTSCTS_IN
+ jflowout |= javax.comm.SerialPort.FLOWCONTROL_RTSCTS_OUT
+ if self._xonxoff:
+ jflowin |= javax.comm.SerialPort.FLOWCONTROL_XONXOFF_IN
+ jflowout |= javax.comm.SerialPort.FLOWCONTROL_XONXOFF_OUT
- self.sPort.setSerialPortParams(baudrate, self.databits, self.jstopbits, self.jparity)
+ self.sPort.setSerialPortParams(baudrate, jdatabits, jstopbits, jparity)
self.sPort.setFlowControlMode(jflowin | jflowout)
- self.timeout = timeout
- if timeout >= 0:
- self.sPort.enableReceiveTimeout(timeout*1000)
+ if self._timeout >= 0:
+ self.sPort.enableReceiveTimeout(self._timeout*1000)
else:
self.sPort.disableReceiveTimeout()
def close(self):
- if self.sPort:
- self.instream.close()
- self.outstream.close()
- self.sPort.close()
- self.sPort = None
+ """Close port"""
+ if self._isOpen:
+ if self.sPort:
+ self._instream.close()
+ self._outstream.close()
+ self.sPort.close()
+ self.sPort = None
+ self._isOpen = False
- def setBaudrate(self, baudrate):
- """change baudrate after port is open"""
- if not self.sPort: raise portNotOpenError
- self.sPort.setSerialPortParams(baudrate, self.databits, self.jstopbits, self.jparity)
+ def makeDeviceName(self, port):
+ return device(port)
+ # - - - - - - - - - - - - - - - - - - - - - - - -
def inWaiting(self):
+ """Return the number of characters currently in the input buffer."""
if not self.sPort: raise portNotOpenError
- return self.instream.available()
-
- def write(self, data):
- if not self.sPort: raise portNotOpenError
- self.outstream.write(data)
+ return self._instream.available()
def read(self, size=1):
+ """Read size bytes from the serial port. If a timeout is set it may
+ return less characters as requested. With no timeout it will block
+ until the requested number of bytes is read."""
if not self.sPort: raise portNotOpenError
read = ''
if size > 0:
while len(read) < size:
- x = self.instream.read()
+ x = self._instream.read()
if x == -1:
if self.timeout >= 0:
break
@@ -138,41 +136,58 @@ class Serial(serialutil.FileLike):
read = read + chr(x)
return read
+ def write(self, data):
+ """Output the given string over the serial port."""
+ if not self.sPort: raise portNotOpenError
+ self._outstream.write(data)
+
def flushInput(self):
+ """Clear input buffer, discarding all that is in the buffer."""
if not self.sPort: raise portNotOpenError
- self.instream.skip(self.instream.available())
+ self._instream.skip(self._instream.available())
def flushOutput(self):
+ """Clear output buffer, aborting the current output and
+ discarding all that is in the buffer."""
if not self.sPort: raise portNotOpenError
- self.outstream.flush()
+ self._outstream.flush()
def sendBreak(self):
+ """Send break condition."""
if not self.sPort: raise portNotOpenError
self.sPort.sendBreak()
- def getDSR(self):
+ def setRTS(self,on=1):
+ """Set terminal status line: Request To Send"""
if not self.sPort: raise portNotOpenError
- self.sPort.isDSR()
+ self.sPort.setRTS(on)
+
+ def setDTR(self,on=1):
+ """Set terminal status line: Data Terminal Ready"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.setDTR(on)
- def getCD(self):
+ def getCTS(self):
+ """Read terminal status line: Clear To Send"""
if not self.sPort: raise portNotOpenError
- self.sPort.isCD()
+ self.sPort.isCTS()
+
+ def getDSR(self):
+ """Read terminal status line: Data Set Ready"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.isDSR()
def getRI(self):
+ """Read terminal status line: Ring Indicator"""
if not self.sPort: raise portNotOpenError
self.sPort.isRI()
- def getCTS(self):
+ def getCD(self):
+ """Read terminal status line: Carrier Detect"""
if not self.sPort: raise portNotOpenError
- self.sPort.isCTS()
+ self.sPort.isCD()
- def setDTR(self,on=1):
- if not self.sPort: raise portNotOpenError
- self.sPort.setDTR(on)
- def setRTS(self,on=1):
- if not self.sPort: raise portNotOpenError
- self.sPort.setRTS(on)
if __name__ == '__main__':
s = Serial(0,
diff --git a/pyserial/serial/serialposix.py b/pyserial/serial/serialposix.py
index 855ee30..1d1c85e 100644
--- a/pyserial/serial/serialposix.py
+++ b/pyserial/serial/serialposix.py
@@ -1,22 +1,19 @@
#!/usr/bin/env python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
#module for serial IO for POSIX compatible systems, like Linux
#see __init__.py
#
-#(C) 2001-2002 Chris Liechti <cliechti@gmx.net>
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
# this is distributed under a free software license, see license.txt
#
#parts based on code from Grant B. Edwards <grante@visi.com>:
# ftp://ftp.visi.com/users/grante/python/PosixSerial.py
# references: http://www.easysw.com/~mike/serial/serial.html
-import sys, os, fcntl, termios, struct, string, select
-import serialutil
+import sys, os, fcntl, termios, struct, select
+from serialutil import *
-VERSION = string.split("$Revision: 1.16 $")[1] #extract CVS version
-
-PARITY_NONE, PARITY_EVEN, PARITY_ODD = range(3)
-STOPBITS_ONE, STOPBITS_TWO = (1, 2)
-FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5,6,7,8)
+VERSION = "$Revision: 1.17 $".split()[1] #extract CVS version
#Do check the Python version as some constants have moved.
if (sys.hexversion < 0x020100f0):
@@ -30,7 +27,7 @@ else:
FCNTL = fcntl
#try to detect the os so that a device can be selected...
-plat = string.lower(sys.platform)
+plat = sys.platform.lower()
if plat[:5] == 'linux': #Linux (confirmed)
def device(port):
@@ -67,7 +64,7 @@ elif plat[:5] == 'sunos': #Solaris®/SunOS® (confirmed)
else:
#platform detection has failed...
info = "sys.platform = %r\nos.name = %r\nserialposix.py version = %s" % (sys.platform, os.name, VERSION)
- print """send this information to the author of this module:
+ print """send this information to the author of the pyserial:
%s
@@ -76,7 +73,12 @@ counting starts for the first serial port.
e.g. 'first serial port: /dev/ttyS0'
and with a bit luck you can get this module running...
"""
- raise Exception, "this module does not run on this platform, sorry."
+ #no exception, just continue with a brave attempt to build a device name
+ #even if the device name is not correct for the platform it has chances
+ #to work using a string with the real device name as port paramter.
+ def device(portum):
+ return '/dev/ttyS%d' % portnum
+ #~ raise Exception, "this module does not run on this platform, sorry."
#whats up with "aix", "beos", "sco", ....
#they should work, just need to know the device names.
@@ -124,166 +126,144 @@ TIOCM_zero_str = struct.pack('I', 0)
TIOCM_RTS_str = struct.pack('I', TIOCM_RTS)
TIOCM_DTR_str = struct.pack('I', TIOCM_DTR)
-portNotOpenError = ValueError('port not open')
-class Serial(serialutil.FileLike):
- def __init__(self,
- port, #number of device, numbering starts at
- #zero. if everything fails, the user
- #can specify a device string, note
- #that this isn't portable anymore
- baudrate=9600, #baudrate
- bytesize=EIGHTBITS, #number of databits
- parity=PARITY_NONE, #enable parity checking
- stopbits=STOPBITS_ONE, #number of stopbits
- timeout=None, #set a timeout value, None to wait forever
- xonxoff=0, #enable software flow control
- rtscts=0, #enable RTS/CTS flow control
- ):
- """init comm port"""
+class Serial(SerialBase):
+ """Serial port class POSIX implementation. Serial port configuration is
+ done with termios and fcntl. Runs on Linux and many other Un*x like
+ systems."""
+
+ def open(self):
+ """Open port with current settings. This may throw a SerialException
+ if the port cannot be opened."""
+ if self._port is None:
+ raise SerialException("Port must be configured before it can be used.")
self.fd = None
- self.timeout = timeout
- vmin = vtime = 0 #timeout is done via select
#open
- if type(port) == type(''): #strings are taken directly
- self.portstr = port
- else:
- self.portstr = device(port) #numbers are transformed to a os dependant string
try:
self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
except Exception, msg:
self.fd = None
- raise serialutil.SerialException, "could not open port: %s" % msg
+ raise SerialException("Could not open port: %s" % msg)
fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) #set blocking
+
+ self._reconfigurePort()
+ self._isOpen = True
+
+
+ def _reconfigurePort(self):
+ """Set commuication parameters on opened port."""
+ if not self.fd:
+ raise SerialException("Can only operate on a valid port handle")
+
+ vmin = vtime = 0 #timeout is done via select
try:
- self.__tcgetattr() #read current settings
+ iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(self.fd)
except termios.error, msg: #if a port is nonexistent but has a /dev file, it'll fail here
- raise serialutil.SerialException, "could not open port: %s" % msg
+ raise SerialException("Could not configure port: %s" % msg)
#set up raw mode / no echo / binary
- self.cflag = self.cflag | (TERMIOS.CLOCAL|TERMIOS.CREAD)
- self.lflag = self.lflag & ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL|
- TERMIOS.ECHOCTL|TERMIOS.ECHOKE|TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT
- self.oflag = self.oflag & ~(TERMIOS.OPOST)
+ cflag |= (TERMIOS.CLOCAL|TERMIOS.CREAD)
+ lflag &= ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL|
+ TERMIOS.ECHOCTL|TERMIOS.ECHOKE|TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT
+ oflag &= ~(TERMIOS.OPOST)
if hasattr(TERMIOS, 'IUCLC'):
- self.iflag = self.iflag & ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IUCLC|TERMIOS.IGNBRK)
+ iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IUCLC|TERMIOS.IGNBRK)
else:
- self.iflag = self.iflag & ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)
+ iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)
#setup baudrate
try:
- self.ispeed = self.ospeed = baudIntToEnum[baudrate]
+ ispeed = ospeed = baudIntToEnum[self._baudrate]
except:
- raise ValueError,'invalid baud rate: %s' % baudrate
+ raise ValueError('Invalid baud rate: %r' % self._baudrate)
#setup char len
- self.cflag = self.cflag & ~TERMIOS.CSIZE
- if bytesize == 8:
- self.cflag = self.cflag | TERMIOS.CS8
- elif bytesize == 7:
- self.cflag = self.cflag | TERMIOS.CS7
- elif bytesize == 6:
- self.cflag = self.cflag | TERMIOS.CS6
- elif bytesize == 5:
- self.cflag = self.cflag | TERMIOS.CS5
+ cflag &= ~TERMIOS.CSIZE
+ if self._bytesize == 8:
+ cflag |= TERMIOS.CS8
+ elif self._bytesize == 7:
+ cflag |= TERMIOS.CS7
+ elif self._bytesize == 6:
+ cflag |= TERMIOS.CS6
+ elif self._bytesize == 5:
+ cflag |= TERMIOS.CS5
else:
- raise ValueError,'invalid char len: '+str(clen)
+ raise ValueError('Invalid char len: %r' % self._bytesize)
#setup stopbits
- if stopbits == STOPBITS_ONE:
- self.cflag = self.cflag & ~(TERMIOS.CSTOPB)
- elif stopbits == STOPBITS_TWO:
- self.cflag = self.cflag | (TERMIOS.CSTOPB)
+ if self._stopbits == STOPBITS_ONE:
+ cflag &= ~(TERMIOS.CSTOPB)
+ elif self._stopbits == STOPBITS_TWO:
+ cflag |= (TERMIOS.CSTOPB)
else:
- raise ValueError,'invalid stopit specification:'+str(stopbits)
+ raise ValueError('Invalid stopit specification: %r' % self._stopbits)
#setup parity
- self.iflag = self.iflag & ~(TERMIOS.INPCK|TERMIOS.ISTRIP)
- if parity == PARITY_NONE:
- self.cflag = self.cflag & ~(TERMIOS.PARENB|TERMIOS.PARODD)
- elif parity == PARITY_EVEN:
- self.cflag = self.cflag & ~(TERMIOS.PARODD)
- self.cflag = self.cflag | (TERMIOS.PARENB)
- elif parity == PARITY_ODD:
- self.cflag = self.cflag | (TERMIOS.PARENB|TERMIOS.PARODD)
+ iflag &= ~(TERMIOS.INPCK|TERMIOS.ISTRIP)
+ if self._parity == PARITY_NONE:
+ cflag &= ~(TERMIOS.PARENB|TERMIOS.PARODD)
+ elif self._parity == PARITY_EVEN:
+ cflag &= ~(TERMIOS.PARODD)
+ cflag |= (TERMIOS.PARENB)
+ elif self._parity == PARITY_ODD:
+ cflag |= (TERMIOS.PARENB|TERMIOS.PARODD)
else:
- raise ValueError,'invalid parity: '+str(par)
+ raise ValueError('Invalid parity: %r' % self._parity)
#setup flow control
#xonxoff
if hasattr(TERMIOS, 'IXANY'):
- if xonxoff:
- self.iflag = self.iflag | (TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
+ if self._xonxoff:
+ iflag |= (TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
else:
- self.iflag = self.iflag & ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
+ iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
else:
- if xonxoff:
- self.iflag = self.iflag | (TERMIOS.IXON|TERMIOS.IXOFF)
+ if self._xonxoff:
+ iflag |= (TERMIOS.IXON|TERMIOS.IXOFF)
else:
- self.iflag = self.iflag & ~(TERMIOS.IXON|TERMIOS.IXOFF)
+ iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF)
#rtscts
if hasattr(TERMIOS, 'CRTSCTS'):
- if rtscts:
- self.cflag = self.cflag | (TERMIOS.CRTSCTS)
+ if self._rtscts:
+ cflag |= (TERMIOS.CRTSCTS)
else:
- self.cflag = self.cflag & ~(TERMIOS.CRTSCTS)
+ cflag &= ~(TERMIOS.CRTSCTS)
elif hasattr(TERMIOS, 'CNEW_RTSCTS'): #try it with alternate constant name
- if rtscts:
- self.cflag = self.cflag | (TERMIOS.CNEW_RTSCTS)
+ if self._rtscts:
+ cflag |= (TERMIOS.CNEW_RTSCTS)
else:
- self.cflag = self.cflag & ~(TERMIOS.CNEW_RTSCTS)
+ cflag &= ~(TERMIOS.CNEW_RTSCTS)
#XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
#buffer
#vmin "minimal number of characters to be read. = for non blocking"
- if vmin<0 or vmin>255:
- raise ValueError,'invalid vmin: '+str(vmin)
- self.cc[TERMIOS.VMIN] = vmin
+ if vmin < 0 or vmin > 255:
+ raise ValueError('Invalid vmin: %r ' % vmin)
+ cc[TERMIOS.VMIN] = vmin
#vtime
- if vtime<0 or vtime>255:
- raise ValueError,'invalid vtime: '+str(vtime)
- self.cc[TERMIOS.VTIME] = vtime
+ if vtime < 0 or vtime > 255:
+ raise ValueError('Invalid vtime: %r' % vtime)
+ cc[TERMIOS.VTIME] = vtime
#activate settings
- self.__tcsetattr()
-
- def __tcsetattr(self):
- """internal function to set port attributes"""
- termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [self.iflag,self.oflag,self.cflag,self.lflag,self.ispeed,self.ospeed,self.cc])
-
- def __tcgetattr(self):
- """internal function to get port attributes"""
- self.iflag,self.oflag,self.cflag,self.lflag,self.ispeed,self.ospeed,self.cc = termios.tcgetattr(self.fd)
+ termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
def close(self):
- """close port"""
- if self.fd:
- os.close(self.fd)
- self.fd = None
+ """Close port"""
+ if self._isOpen:
+ if self.fd:
+ os.close(self.fd)
+ self.fd = None
+ self._isOpen = False
- def setBaudrate(self, baudrate):
- """change baudrate after port is open"""
- if not self.fd: raise portNotOpenError
- self.__tcgetattr() #read current settings
- #setup baudrate
- try:
- self.ispeed = self.ospeed = baudIntToEnum[baudrate]
- except:
- raise ValueError,'invalid baud rate: %s' % baudrate
- self.__tcsetattr()
+ def makeDeviceName(self, port):
+ return device(port)
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
def inWaiting(self):
- """how many character are in the input queue"""
+ """Return the number of characters currently in the input buffer."""
#~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str)
s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
return struct.unpack('I',s)[0]
- def write(self, data):
- """write a string to the port"""
- if not self.fd: raise portNotOpenError
- t = len(data)
- d = data
- while t>0:
- n = os.write(self.fd, d)
- d = d[n:]
- t = t - n
-
def read(self, size=1):
- """read a number of bytes from the port.
- the default is one (unlike files)"""
+ """Read size bytes from the serial port. If a timeout is set it may
+ return less characters as requested. With no timeout it will block
+ until the requested number of bytes is read."""
if not self.fd: raise portNotOpenError
read = ''
inp = None
@@ -299,24 +279,63 @@ class Serial(serialutil.FileLike):
break #early abort on timeout
return read
+ def write(self, data):
+ """Output the given string over the serial port."""
+ if not self.fd: raise portNotOpenError
+ t = len(data)
+ d = data
+ while t>0:
+ n = os.write(self.fd, d)
+ d = d[n:]
+ t = t - n
+
def flushInput(self):
- """clear input queue"""
+ """Clear input buffer, discarding all that is in the buffer."""
if not self.fd:
raise portNotOpenError
termios.tcflush(self.fd, TERMIOS.TCIFLUSH)
def flushOutput(self):
- """flush output"""
+ """Clear output buffer, aborting the current output and
+ discarding all that is in the buffer."""
if not self.fd:
raise portNotOpenError
termios.tcflush(self.fd, TERMIOS.TCOFLUSH)
def sendBreak(self):
- """send break signal"""
+ """Send break condition."""
if not self.fd:
raise portNotOpenError
termios.tcsendbreak(self.fd, 0)
+ def setRTS(self,on=1):
+ """Set terminal status line: Request To Send"""
+ if not self.fd: raise portNotOpenError
+ if on:
+ fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
+ else:
+ fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
+
+ def setDTR(self,on=1):
+ """Set terminal status line: Data Terminal Ready"""
+ if not self.fd: raise portNotOpenError
+ if on:
+ fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
+ else:
+ fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
+
+ def getCTS(self):
+ """Read terminal status line: Clear To Send"""
+ if not self.fd: raise portNotOpenError
+ s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
+ return struct.unpack('I',s)[0] & TIOCM_CTS != 0
+
+ def getDSR(self):
+ """Read terminal status line: Data Set Ready"""
+ if not self.fd: raise portNotOpenError
+ s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
+ return struct.unpack('I',s)[0] & TIOCM_DSR != 0
+
def drainOutput(self):
"""internal - not portable!"""
if not self.fd: raise portNotOpenError
@@ -328,45 +347,18 @@ class Serial(serialutil.FileLike):
raise portNotOpenError
fcntl.fcntl(self.fd, FCNTL.F_SETFL, FCNTL.O_NONBLOCK)
- def getDSR(self):
- """read terminal status line"""
- if not self.fd: raise portNotOpenError
- s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
- return struct.unpack('I',s)[0] & TIOCM_DSR
-
- def getCD(self):
- """read terminal status line"""
- if not self.fd: raise portNotOpenError
- s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
- return struct.unpack('I',s)[0] & TIOCM_CD
-
def getRI(self):
- """read terminal status line"""
+ """Read terminal status line: Ring Indicator"""
if not self.fd: raise portNotOpenError
s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
- return struct.unpack('I',s)[0] & TIOCM_RI
+ return struct.unpack('I',s)[0] & TIOCM_RI != 0
- def getCTS(self):
- """read terminal status line"""
+ def getCD(self):
+ """Read terminal status line: Carrier Detect"""
if not self.fd: raise portNotOpenError
s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
- return struct.unpack('I',s)[0] & TIOCM_CTS
+ return struct.unpack('I',s)[0] & TIOCM_CD != 0
- def setDTR(self,on=1):
- """set terminal status line"""
- if not self.fd: raise portNotOpenError
- if on:
- fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
- else:
- fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
-
- def setRTS(self,on=1):
- """set terminal status line"""
- if not self.fd: raise portNotOpenError
- if on:
- fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
- else:
- fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
if __name__ == '__main__':
s = Serial(0,
diff --git a/pyserial/serial/serialutil.py b/pyserial/serial/serialutil.py
index e3a4bdb..78ab99d 100644
--- a/pyserial/serial/serialutil.py
+++ b/pyserial/serial/serialutil.py
@@ -1,8 +1,33 @@
+#! python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+PARITY_NONE, PARITY_EVEN, PARITY_ODD = 'N', 'E', 'O'
+STOPBITS_ONE, STOPBITS_TWO = (1, 2)
+FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5,6,7,8)
+
+PARITY_NAMES = {
+ PARITY_NONE: 'None',
+ PARITY_EVEN: 'Even',
+ PARITY_ODD: 'Odd',
+}
+
+#Python < 2.2.3 compatibility
+try:
+ True
+except:
+ True = 1
+ False = not True
class SerialException(Exception):
- pass
+ """Base class for serial port related exceptions."""
-class FileLike:
+portNotOpenError = SerialException('Port not open')
+
+class FileLike(object):
"""An abstract file like class.
This class implements readline and readlines based on read and
@@ -63,3 +88,221 @@ class FileLike:
"""flush of file like objects"""
pass
+class SerialBase(FileLike):
+ """Serial port base class. Provides __init__ function and properties to
+ get/set port settings."""
+
+ #default values, may be overriden in subclasses that do not support all values
+ BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
+ 19200,38400,57600,115200,230400,460800,500000,576000,921600,
+ 1000000,1152000,1500000,2000000,2500000,3000000,3500000,4000000)
+ BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)
+ PARITIES = (PARITY_NONE, PARITY_EVEN, PARITY_ODD)
+ STOPBITS = (STOPBITS_ONE, STOPBITS_TWO)
+
+ def __init__(self,
+ port = None, #number of device, numbering starts at
+ #zero. if everything fails, the user
+ #can specify a device string, note
+ #that this isn't portable anymore
+ #port will be opened if one is specified
+ baudrate=9600, #baudrate
+ bytesize=EIGHTBITS, #number of databits
+ parity=PARITY_NONE, #enable parity checking
+ stopbits=STOPBITS_ONE, #number of stopbits
+ timeout=None, #set a timeout value, None to wait forever
+ xonxoff=0, #enable software flow control
+ rtscts=0, #enable RTS/CTS flow control
+ ):
+ """Initialize comm port object. If a port is given, then the port will be
+ opened immediately. Otherwise a Serial port object with in clsoed state
+ is returned."""
+
+ self._isOpen = False
+ self._port = None #correct value is assigned below trough properties
+ self._bytesize = None #correct value is assigned below trough properties
+ self._parity = None #correct value is assigned below trough properties
+ self._stopbits = None #correct value is assigned below trough properties
+ self._timeout = None #correct value is assigned below trough properties
+ self._xonxoff = None #correct value is assigned below trough properties
+ self._rtscts = None #correct value is assigned below trough properties
+
+ #assign values using get/set methods using the properties featrure
+ self.port = port
+ self.baudrate = baudrate
+ self.bytesize = bytesize
+ self.parity = parity
+ self.stopbits = stopbits
+ self.timeout = timeout
+ self.xonxoff = xonxoff
+ self.rtscts = rtscts
+
+ if port is not None:
+ self.open()
+
+ def isOpen(self):
+ """Check if the port is opened."""
+ return self._isOpen
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ #TODO: these are not realy needed as the is the BAUDRATES etc attribute...
+ #maybe i remove them before the final release...
+
+ def getSupportedBaudrates(self):
+ return [(str(b), b) for b in self.BAUDRATES]
+
+ def getSupportedByteSizes(self):
+ return [(str(b), b) for b in self.BYTESIZES]
+
+ def getSupportedStopbits(self):
+ return [(str(b), b) for b in self.STOPBITS]
+
+ def getSupportedParities(self):
+ return [(PARITY_NAMES[b], b) for b in self.PARITIES]
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def setPort(self, port):
+ """Change the port. The attribute portstr is set to a string that
+ contains the name of the port."""
+
+ was_open = self._isOpen
+ if was_open: self.close()
+ if port is not None:
+ if type(port) == type(''): #strings are taken directly
+ self.portstr = port
+ else:
+ self.portstr = self.makeDeviceName(port)
+ else:
+ self.portstr = None
+ self._port = port
+ if was_open: self.open()
+
+ def getPort(self):
+ """get the current port setting. The value that was passed on init or using
+ setPort() is passed back. See also the attribute portstr which contains
+ the name of the port as a string."""
+ return self._port
+
+ port = property(getPort, setPort, "Port setting")
+
+
+ def setBaudrate(self, baudrate):
+ """Change baudrate."""
+ if baudrate not in self.BAUDRATES: raise ValueError("Not a valid baudrate: %r" % baudrate)
+ self._baudrate = baudrate
+ if self._isOpen: self._reconfigurePort()
+
+ def getBaudrate(self):
+ """Get the current baudrate setting."""
+ return self._baudrate
+
+ baudrate = property(getBaudrate, setBaudrate, "Baudrate setting")
+
+
+ def setByteSize(self, bytesize):
+ """Change byte size."""
+ if bytesize not in self.BYTESIZES: raise ValueError("Not a valid byte size: %r" % bytesize)
+ self._bytesize = bytesize
+ if self._isOpen: self._reconfigurePort()
+
+ def getByteSize(self):
+ """Get the current byte size setting."""
+ return self._bytesize
+
+ bytesize = property(getByteSize, setByteSize, "Byte size setting")
+
+
+ def setParity(self, parity):
+ """Change parity setting."""
+ if parity not in self.PARITIES: raise ValueError("Not a valid parity: %r" % parity)
+ self._parity = parity
+ if self._isOpen: self._reconfigurePort()
+
+ def getParity(self):
+ """Get the current parity setting."""
+ return self._parity
+
+ parity = property(getParity, setParity, "Parity setting")
+
+
+ def setStopbits(self, stopbits):
+ """Change stopbits size."""
+ if stopbits not in self.STOPBITS: raise ValueError("Not a valid stopbit size: %r" % stopbits)
+ self._stopbits = stopbits
+ if self._isOpen: self._reconfigurePort()
+
+ def getStopbits(self):
+ """Get the current stopbits setting."""
+ return self._stopbits
+
+ stopbits = property(getStopbits, setStopbits, "Stopbits setting")
+
+
+ def setTimeout(self, timeout):
+ """Change timeout setting."""
+ if timeout is not None:
+ if timeout < 0: raise ValueError("Not a valid timeout: %r" % timeout)
+ try:
+ timeout + 1 #test if it's a number, will throw a TypeError if not...
+ except TypeError:
+ raise ValueError("Not a valid timeout: %r" % timeout)
+
+ self._timeout = timeout
+ if self._isOpen: self._reconfigurePort()
+
+ def getTimeout(self):
+ """Get the current timeout setting."""
+ return self._timeout
+
+ timeout = property(getTimeout, setTimeout, "Timeout setting")
+
+
+ def setXonXoff(self, xonxoff):
+ """Change XonXoff setting."""
+ self._xonxoff = xonxoff
+ if self._isOpen: self._reconfigurePort()
+
+ def getXonXoff(self):
+ """Get the current XonXoff setting."""
+ return self._xonxoff
+
+ xonxoff = property(getXonXoff, setXonXoff, "Xon/Xoff setting")
+
+ def setRtsCts(self, rtscts):
+ """Change RtsCts setting."""
+ self._rtscts = rtscts
+ if self._isOpen: self._reconfigurePort()
+
+ def getRtsCts(self):
+ """Get the current RtsCts setting."""
+ return self._rtscts
+
+ rtscts = property(getRtsCts, setRtsCts, "RTS/CTS setting")
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def __repr__(self):
+ """String representation of the current port settings and its state."""
+ return "%s<id=0x%x, open=%s>(port=%r, baudrate=%r, bytesize=%r, parity=%r, stopbits=%r, timeout=%r, xonxoff=%r, rtscts=%r)" % (
+ self.__class__.__name__,
+ id(self),
+ self._isOpen,
+ self.portstr,
+ self.baudrate,
+ self.bytesize,
+ self.parity,
+ self.stopbits,
+ self.timeout,
+ self.xonxoff,
+ self.rtscts,
+ )
+
+if __name__ == '__main__':
+ s = SerialBase()
+ print s.getSupportedBaudrates()
+ print s.getSupportedByteSizes()
+ print s.getSupportedParities()
+ print s.getSupportedStopbits()
+ print s
diff --git a/pyserial/serial/serialwin32.py b/pyserial/serial/serialwin32.py
index e428bb5..0f33d00 100644
--- a/pyserial/serial/serialwin32.py
+++ b/pyserial/serial/serialwin32.py
@@ -1,23 +1,17 @@
#! python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
#serial driver for win32
#see __init__.py
#
-#(C) 2001-2002 Chris Liechti <cliechti@gmx.net>
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
# this is distributed under a free software license, see license.txt
import win32file # The base COM port and file IO functions.
import win32event # We use events and the WaitFor[Single|Multiple]Objects functions.
import win32con # constants.
-import sys, string
-import serialutil
+from serialutil import *
-VERSION = string.split("$Revision: 1.24 $")[1] #extract CVS version
-
-PARITY_NONE, PARITY_EVEN, PARITY_ODD = range(3)
-STOPBITS_ONE, STOPBITS_TWO = (1, 2)
-FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5,6,7,8)
-
-portNotOpenError = ValueError('port not open')
+VERSION = "$Revision: 1.25 $".split()[1] #extract CVS version
#from winbase.h. these should realy be in win32con
MS_CTS_ON = 16
@@ -26,6 +20,7 @@ MS_RING_ON = 64
MS_RLSD_ON = 128
def device(portnum):
+ """Turn a port number into a device name"""
#the "//./COMx" format is required for devices >= 9
#not all versions of windows seem to support this propperly
#so that the first few ports are used with the DOS device name
@@ -34,29 +29,16 @@ def device(portnum):
else:
return r'\\.\COM%d' % (portnum+1)
-class Serial(serialutil.FileLike):
- def __init__(self,
- port, #number of device, numbering starts at
- #zero. if everything fails, the user
- #can specify a device string, note
- #that this isn't portable anymore
- baudrate=9600, #baudrate
- bytesize=EIGHTBITS, #number of databits
- parity=PARITY_NONE, #enable parity checking
- stopbits=STOPBITS_ONE, #number of stopbits
- timeout=None, #set a timeout value, None to wait forever
- xonxoff=0, #enable software flow control
- rtscts=0, #enable RTS/CTS flow control
- ):
- """initialize comm port"""
-
- self.timeout = timeout
-
- if type(port) == type(''): #strings are taken directly
- self.portstr = port
- else:
- self.portstr = device(port)
+class Serial(SerialBase):
+ """Serial port implemenation for Win32. This implemenatation requires a
+ win32all installation."""
+ def open(self):
+ """Open port with current settings. This may throw a SerialException
+ if the port cannot be opened."""
+ if self._port is None:
+ raise SerialException("Port must be configured before it can be used.")
+ self.hComPort = None
try:
self.hComPort = win32file.CreateFile(self.portstr,
win32con.GENERIC_READ | win32con.GENERIC_WRITE,
@@ -67,120 +49,128 @@ class Serial(serialutil.FileLike):
None)
except Exception, msg:
self.hComPort = None #'cause __del__ is called anyway
- raise serialutil.SerialException, "could not open port: %s" % msg
+ raise SerialException("could not open port: %s" % msg)
# Setup a 4k buffer
win32file.SetupComm(self.hComPort, 4096, 4096)
#Save original timeout values:
- self.orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
+ self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
+
+ self._reconfigurePort()
+
+ # Clear buffers:
+ # Remove anything that was there
+ win32file.PurgeComm(self.hComPort,
+ win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
+ win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
+ self._overlappedRead = win32file.OVERLAPPED()
+ self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
+ self._overlappedWrite = win32file.OVERLAPPED()
+ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
+ self._isOpen = True
+
+ def _reconfigurePort(self):
+ """Set commuication parameters on opened port."""
+ if not self.hComPort:
+ raise SerialException("Can only operate on a valid port handle")
+
#Set Windows timeout values
#timeouts is a tuple with the following items:
#(ReadIntervalTimeout,ReadTotalTimeoutMultiplier,
# ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier,
# WriteTotalTimeoutConstant)
- if timeout is None:
+ if self._timeout is None:
timeouts = (0, 0, 0, 0, 0)
- elif timeout == 0:
+ elif self._timeout == 0:
timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
else:
- #timeouts = (0, 0, 0, 0, 0) #timeouts are done with WaitForSingleObject
- timeouts = (0, 0, int(timeout*1000), 0, 0)
+ timeouts = (0, 0, int(self._timeout*1000), 0, 0)
win32file.SetCommTimeouts(self.hComPort, timeouts)
- #win32file.SetCommMask(self.hComPort, win32file.EV_RXCHAR | win32file.EV_TXEMPTY |
- # win32file.EV_RXFLAG | win32file.EV_ERR)
- #~ win32file.SetCommMask(self.hComPort,
- #~ win32file.EV_RXCHAR | win32file.EV_RXFLAG | win32file.EV_ERR)
win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
# Setup the connection info.
# Get state and modify it:
comDCB = win32file.GetCommState(self.hComPort)
- comDCB.BaudRate = baudrate
+ comDCB.BaudRate = self._baudrate
- if bytesize == FIVEBITS:
+ if self._bytesize == FIVEBITS:
comDCB.ByteSize = 5
- elif bytesize == SIXBITS:
+ elif self._bytesize == SIXBITS:
comDCB.ByteSize = 6
- elif bytesize == SEVENBITS:
+ elif self._bytesize == SEVENBITS:
comDCB.ByteSize = 7
- elif bytesize == EIGHTBITS:
+ elif self._bytesize == EIGHTBITS:
comDCB.ByteSize = 8
+ else:
+ raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
- if parity == PARITY_NONE:
+ if self._parity == PARITY_NONE:
comDCB.Parity = win32file.NOPARITY
comDCB.fParity = 0 # Dis/Enable Parity Check
- elif parity == PARITY_EVEN:
+ elif self._parity == PARITY_EVEN:
comDCB.Parity = win32file.EVENPARITY
comDCB.fParity = 1 # Dis/Enable Parity Check
- elif parity == PARITY_ODD:
+ elif self._parity == PARITY_ODD:
comDCB.Parity = win32file.ODDPARITY
comDCB.fParity = 1 # Dis/Enable Parity Check
+ else:
+ raise ValueError("Unsupported parity mode: %r" % self._parity)
- if stopbits == STOPBITS_ONE:
+ if self._stopbits == STOPBITS_ONE:
comDCB.StopBits = win32file.ONESTOPBIT
- elif stopbits == STOPBITS_TWO:
+ elif self._stopbits == STOPBITS_TWO:
comDCB.StopBits = win32file.TWOSTOPBITS
+ else:
+ raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
+
comDCB.fBinary = 1 # Enable Binary Transmission
# Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
- if rtscts:
+ if self._rtscts:
comDCB.fRtsControl = win32file.RTS_CONTROL_HANDSHAKE
comDCB.fDtrControl = win32file.DTR_CONTROL_HANDSHAKE
else:
comDCB.fRtsControl = win32file.RTS_CONTROL_ENABLE
comDCB.fDtrControl = win32file.DTR_CONTROL_ENABLE
- comDCB.fOutxCtsFlow = rtscts
- comDCB.fOutxDsrFlow = rtscts
- comDCB.fOutX = xonxoff
- comDCB.fInX = xonxoff
+ comDCB.fOutxCtsFlow = self._rtscts
+ comDCB.fOutxDsrFlow = self._rtscts
+ comDCB.fOutX = self._xonxoff
+ comDCB.fInX = self._xonxoff
comDCB.fNull = 0
comDCB.fErrorChar = 0
comDCB.fAbortOnError = 0
win32file.SetCommState(self.hComPort, comDCB)
- # Clear buffers:
- # Remove anything that was there
- win32file.PurgeComm(self.hComPort,
- win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
- win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
-
- #print win32file.ClearCommError(self.hComPort) #flags, comState =
-
- self._overlappedRead = win32file.OVERLAPPED()
- self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
- self._overlappedWrite = win32file.OVERLAPPED()
- self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
-
- def __del__(self):
- self.close()
+ #~ def __del__(self):
+ #~ self.close()
def close(self):
- """close port"""
- if self.hComPort:
- #Restore original timeout values:
- win32file.SetCommTimeouts(self.hComPort, self.orgTimeouts)
- #Close COM-Port:
- win32file.CloseHandle(self.hComPort)
- self.hComPort = None
-
- def setBaudrate(self, baudrate):
- """change baudrate after port is open"""
- if not self.hComPort: raise portNotOpenError
- # Setup the connection info.
- # Get state and modify it:
- comDCB = win32file.GetCommState(self.hComPort)
- comDCB.BaudRate = baudrate
- win32file.SetCommState(self.hComPort, comDCB)
-
+ """Close port"""
+ if self._isOpen:
+ if self.hComPort:
+ #Restore original timeout values:
+ win32file.SetCommTimeouts(self.hComPort, self._orgTimeouts)
+ #Close COM-Port:
+ win32file.CloseHandle(self.hComPort)
+ self.hComPort = None
+ self._isOpen = False
+
+ def makeDeviceName(self, port):
+ return device(port)
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
def inWaiting(self):
- """returns the number of bytes waiting to be read"""
+ """Return the number of characters currently in the input buffer."""
flags, comstat = win32file.ClearCommError(self.hComPort)
return comstat.cbInQue
def read(self, size=1):
- """read num bytes from serial port"""
+ """Read size bytes from the serial port. If a timeout is set it may
+ return less characters as requested. With no timeout it will block
+ until the requested number of bytes is read."""
if not self.hComPort: raise portNotOpenError
if size > 0:
win32event.ResetEvent(self._overlappedRead.hEvent)
@@ -202,7 +192,7 @@ class Serial(serialutil.FileLike):
return read
def write(self, s):
- """write string to serial port"""
+ """Output the given string over the serial port."""
if not self.hComPort: raise portNotOpenError
#print repr(s),
if s:
@@ -212,14 +202,18 @@ class Serial(serialutil.FileLike):
win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
def flushInput(self):
+ """Clear input buffer, discarding all that is in the buffer."""
if not self.hComPort: raise portNotOpenError
win32file.PurgeComm(self.hComPort, win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
def flushOutput(self):
+ """Clear output buffer, aborting the current output and
+ discarding all that is in the buffer."""
if not self.hComPort: raise portNotOpenError
win32file.PurgeComm(self.hComPort, win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT)
def sendBreak(self):
+ """Send break condition."""
if not self.hComPort: raise portNotOpenError
import time
win32file.SetCommBreak(self.hComPort)
@@ -228,7 +222,7 @@ class Serial(serialutil.FileLike):
win32file.ClearCommBreak(self.hComPort)
def setRTS(self,level=1):
- """set terminal status line"""
+ """Set terminal status line: Request To Send"""
if not self.hComPort: raise portNotOpenError
if level:
win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
@@ -236,7 +230,7 @@ class Serial(serialutil.FileLike):
win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
def setDTR(self,level=1):
- """set terminal status line"""
+ """Set terminal status line: Data Terminal Ready"""
if not self.hComPort: raise portNotOpenError
if level:
win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
@@ -244,27 +238,38 @@ class Serial(serialutil.FileLike):
win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
def getCTS(self):
- """read terminal status line"""
+ """Read terminal status line: Clear To Send"""
if not self.hComPort: raise portNotOpenError
return MS_CTS_ON & win32file.GetCommModemStatus(self.hComPort) != 0
def getDSR(self):
- """read terminal status line"""
+ """Read terminal status line: Data Set Ready"""
if not self.hComPort: raise portNotOpenError
return MS_DSR_ON & win32file.GetCommModemStatus(self.hComPort) != 0
def getRI(self):
- """read terminal status line"""
+ """Read terminal status line: Ring Indicator"""
if not self.hComPort: raise portNotOpenError
return MS_RING_ON & win32file.GetCommModemStatus(self.hComPort) != 0
def getCD(self):
- """read terminal status line"""
+ """Read terminal status line: Carrier Detect"""
if not self.hComPort: raise portNotOpenError
return MS_RLSD_ON & win32file.GetCommModemStatus(self.hComPort) != 0
#Nur Testfunktion!!
if __name__ == '__main__':
print __name__
+ s = Serial()
+ print s
+
s = Serial(0)
+ print s
+
+ s.baudrate = 19200
+ s.databits = 7
+ s.close()
+ s.port = 3
+ s.open()
+ print s
diff --git a/pyserial/setup.py b/pyserial/setup.py
index d5a908d..3ce4d54 100644
--- a/pyserial/setup.py
+++ b/pyserial/setup.py
@@ -7,7 +7,7 @@ from distutils.core import setup
setup(
name="pyserial",
description="Python Serial Port Extension",
- version="1.21",
+ version="2.0b1",
author="Chris Liechti",
author_email="cliechti@gmx.net",
url="http://pyserial.sourceforge.net/",