diff options
Diffstat (limited to 'pyserial/serial')
-rw-r--r-- | pyserial/serial/.cvsignore | 1 | ||||
-rw-r--r-- | pyserial/serial/serialposix.py | 19 | ||||
-rw-r--r-- | pyserial/serial/serialutil.py | 34 | ||||
-rw-r--r-- | pyserial/serial/serialwin32.py | 16 |
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.""" |