summaryrefslogtreecommitdiff
path: root/pyserial/serial
diff options
context:
space:
mode:
Diffstat (limited to 'pyserial/serial')
-rw-r--r--pyserial/serial/.cvsignore1
-rw-r--r--pyserial/serial/serialposix.py19
-rw-r--r--pyserial/serial/serialutil.py34
-rw-r--r--pyserial/serial/serialwin32.py16
4 files changed, 61 insertions, 9 deletions
diff --git a/pyserial/serial/.cvsignore b/pyserial/serial/.cvsignore
new file mode 100644
index 0000000..7e99e36
--- /dev/null
+++ b/pyserial/serial/.cvsignore
@@ -0,0 +1 @@
+*.pyc \ No newline at end of file
diff --git a/pyserial/serial/serialposix.py b/pyserial/serial/serialposix.py
index 30e1eab..a03622e 100644
--- a/pyserial/serial/serialposix.py
+++ b/pyserial/serial/serialposix.py
@@ -13,7 +13,7 @@
import sys, os, fcntl, termios, struct, select
from serialutil import *
-VERSION = "$Revision: 1.20 $".split()[1] #extract CVS version
+VERSION = "$Revision: 1.21 $".split()[1] #extract CVS version
#Do check the Python version as some constants have moved.
if (sys.hexversion < 0x020100f0):
@@ -144,10 +144,11 @@ class Serial(SerialBase):
except Exception, msg:
self.fd = None
raise SerialException("Could not open port: %s" % msg)
- fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) #set blocking
+ #~ fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) #set blocking
self._reconfigurePort()
self._isOpen = True
+ #~ self.flushInput()
def _reconfigurePort(self):
@@ -208,7 +209,7 @@ class Serial(SerialBase):
#xonxoff
if hasattr(TERMIOS, 'IXANY'):
if self._xonxoff:
- iflag |= (TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
+ iflag |= (TERMIOS.IXON|TERMIOS.IXOFF) #|TERMIOS.IXANY)
else:
iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
else:
@@ -270,12 +271,12 @@ class Serial(SerialBase):
if size > 0:
while len(read) < size:
#print "\tread(): size",size, "have", len(read) #debug
- ready,_,_ = select.select([self.fd],[],[], self.timeout)
+ ready,_,_ = select.select([self.fd],[],[], self._timeout)
if not ready:
break #timeout
buf = os.read(self.fd, size-len(read))
read = read + buf
- if self.timeout >= 0 and not buf:
+ if self._timeout >= 0 and not buf:
break #early abort on timeout
return read
@@ -285,7 +286,15 @@ class Serial(SerialBase):
t = len(data)
d = data
while t > 0:
+ if self._writeTimeout is not None and self._writeTimeout > 0:
+ _,ready,_ = select.select([],[self.fd],[], self._writeTimeout)
+ if not ready:
+ raise writeTimeoutError
n = os.write(self.fd, d)
+ if self._writeTimeout is not None and self._writeTimeout > 0:
+ _,ready,_ = select.select([],[self.fd],[], self._writeTimeout)
+ if not ready:
+ raise writeTimeoutError
d = d[n:]
t = t - n
diff --git a/pyserial/serial/serialutil.py b/pyserial/serial/serialutil.py
index c503568..0d4883b 100644
--- a/pyserial/serial/serialutil.py
+++ b/pyserial/serial/serialutil.py
@@ -15,6 +15,9 @@ PARITY_NAMES = {
PARITY_ODD: 'Odd',
}
+XON = chr(16)
+XOFF = chr(18)
+
#Python < 2.2.3 compatibility
try:
True
@@ -27,6 +30,11 @@ class SerialException(Exception):
portNotOpenError = SerialException('Port not open')
+class SerialTimeoutException(SerialException):
+ """Write timeouts give an exception"""
+
+writeTimeoutError = SerialTimeoutException("Write timeout")
+
class FileLike(object):
"""An abstract file like class.
@@ -113,6 +121,7 @@ class SerialBase(FileLike):
timeout=None, #set a timeout value, None to wait forever
xonxoff=0, #enable software flow control
rtscts=0, #enable RTS/CTS flow control
+ writeTimeout=None, #set a timeout for writes
):
"""Initialize comm port object. If a port is given, then the port will be
opened immediately. Otherwise a Serial port object in closed state
@@ -125,16 +134,18 @@ class SerialBase(FileLike):
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._writeTimeout = 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
+ #assign values using get/set methods using the properties feature
self.port = port
self.baudrate = baudrate
self.bytesize = bytesize
self.parity = parity
self.stopbits = stopbits
self.timeout = timeout
+ self.writeTimeout = writeTimeout
self.xonxoff = xonxoff
self.rtscts = rtscts
@@ -263,7 +274,26 @@ class SerialBase(FileLike):
"""Get the current timeout setting."""
return self._timeout
- timeout = property(getTimeout, setTimeout, "Timeout setting")
+ timeout = property(getTimeout, setTimeout, "Timeout setting for read()")
+
+
+ def setWriteTimeout(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._writeTimeout = timeout
+ if self._isOpen: self._reconfigurePort()
+
+ def getWriteTimeout(self):
+ """Get the current timeout setting."""
+ return self._writeTimeout
+
+ writeTimeout = property(getWriteTimeout, setWriteTimeout, "Timeout setting for write()")
def setXonXoff(self, xonxoff):
diff --git a/pyserial/serial/serialwin32.py b/pyserial/serial/serialwin32.py
index fa04029..5a22efd 100644
--- a/pyserial/serial/serialwin32.py
+++ b/pyserial/serial/serialwin32.py
@@ -11,7 +11,7 @@ import win32event # We use events and the WaitFor[Single|Multiple]Objects functi
import win32con # constants.
from serialutil import *
-VERSION = "$Revision: 1.28 $".split()[1] #extract CVS version
+VERSION = "$Revision: 1.29 $".split()[1] #extract CVS version
#from winbase.h. these should realy be in win32con
MS_CTS_ON = 16
@@ -90,6 +90,12 @@ class Serial(SerialBase):
timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
else:
timeouts = (0, 0, int(self._timeout*1000), 0, 0)
+ if self._writeTimeout is None:
+ pass
+ elif self._writeTimeout == 0:
+ timeouts = timeouts[:-2] + (0, win32con.MAXDWORD)
+ else:
+ timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))
win32file.SetCommTimeouts(self.hComPort, timeouts)
win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
@@ -144,6 +150,8 @@ class Serial(SerialBase):
comDCB.fNull = 0
comDCB.fErrorChar = 0
comDCB.fAbortOnError = 0
+ comDCB.XonChar = XON
+ comDCB.XoffChar = XOFF
try:
win32file.SetCommState(self.hComPort, comDCB)
@@ -207,7 +215,11 @@ class Serial(SerialBase):
err, n = win32file.WriteFile(self.hComPort, s, self._overlappedWrite)
if err: #will be ERROR_IO_PENDING:
# Wait for the write to complete.
- win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
+ #~ win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
+ n = win32file.GetOverlappedResult(self.hComPort, self._overlappedWrite, 1)
+ if n != len(s):
+ raise writeTimeoutError
+
def flushInput(self):
"""Clear input buffer, discarding all that is in the buffer."""