CVS: python/msp430/serial __init__.py,1.1,1.2 serialjava.py,1.1,1.2 serialposix.py,1.1,1.2 serialutil.py,1.1,1.2 serialwin32.py,1.1,1.2
Chris Liechti <[email protected]>
| Newsgroups | gmane.comp.hardware.texas-instruments.msp430.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/mspgcc/python/msp430/serial
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22128/python/msp430/serial
Modified Files:
__init__.py serialjava.py serialposix.py serialutil.py
serialwin32.py
Log Message:
update to pyserial 2.2 (this verison keeps RTS/DTR states when changing the baudrate. this is a required fix if the BSL is used with --invertTEST or --invertRST)
Index: __init__.py
===================================================================
RCS file: /cvsroot/mspgcc/python/msp430/serial/__init__.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -d -r1.1 -r1.2
--- __init__.py 29 Feb 2004 23:06:36 -0000 1.1
+++ __init__.py 29 Sep 2005 21:29:10 -0000 1.2
@@ -16,6 +16,5 @@
elif os.name == 'java':
from serialjava import *
else:
- raise "Sorry no implementation for your platform available."
+ raise Exception("Sorry: no implementation for your platform ('%s') available" % os.name)
-#no "mac" implementation. someone want's to write it? i have no access to a mac.
Index: serialposix.py
===================================================================
RCS file: /cvsroot/mspgcc/python/msp430/serial/serialposix.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -d -r1.1 -r1.2
--- serialposix.py 29 Feb 2004 23:06:36 -0000 1.1
+++ serialposix.py 29 Sep 2005 21:29:10 -0000 1.2
@@ -10,7 +10,7 @@
# ftp://ftp.visi.com/users/grante/python/PosixSerial.py
# references: http://www.easysw.com/~mike/serial/serial.html
-import sys, os, fcntl, termios, struct, select
+import sys, os, fcntl, termios, struct, select, errno
from serialutil import *
VERSION = "$Revision$".split()[1] #extract CVS version
@@ -42,13 +42,16 @@
return '/dev/ttyp%d' % port
elif plat[:3] == 'bsd' or \
- plat[:6] == 'netbsd' or \
plat[:7] == 'freebsd' or \
plat[:7] == 'openbsd' or \
plat[:6] == 'darwin': #BSD (confirmed for freebsd4: cuaa%d)
def device(port):
return '/dev/cuaa%d' % port
+elif plat[:6] == 'netbsd': #NetBSD 1.6 testing by Erk
+ def device(port):
+ return '/dev/dty%02d' % port
+
elif plat[:4] == 'irix': #IRIX (not tested)
def device(port):
return '/dev/ttyf%d' % port
@@ -61,18 +64,25 @@
def device(port):
return '/dev/tty%c' % (ord('a')+port)
+elif plat[:3] == 'aix': #aix
+ def device(port):
+ return '/dev/tty%d' % (port)
+
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 the pyserial:
+ print """don't know how to number ttys on this system.
+! Use an explicit path (eg /dev/ttyS1) or send this information to
+! the author of this module:
-%s
+sys.platform = %r
+os.name = %r
+serialposix.py version = %s
also add the device name of the serial port and where the
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...
-"""
+""" % (sys.platform, os.name, VERSION)
#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.
@@ -84,21 +94,6 @@
#they should work, just need to know the device names.
-# construct dictionaries for baud rate lookups
-baudEnumToInt = {}
-baudIntToEnum = {}
-for rate in (0,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
- ):
- try:
- i = eval('TERMIOS.B'+str(rate))
- baudEnumToInt[i]=rate
- baudIntToEnum[rate] = i
- except:
- pass
-
-
#load some constants for later use.
#try to use values from TERMIOS, use defaults from linux otherwise
TIOCMGET = hasattr(TERMIOS, 'TIOCMGET') and TERMIOS.TIOCMGET or 0x5415
@@ -144,15 +139,16 @@
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):
"""Set commuication parameters on opened port."""
- if not self.fd:
+ if self.fd is None:
raise SerialException("Can only operate on a valid port handle")
vmin = vtime = 0 #timeout is done via select
@@ -163,16 +159,22 @@
#set up raw mode / no echo / binary
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
+ TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT
+ for flag in ('ECHOCTL', 'ECHOKE'): #netbsd workaround for Erk
+ if hasattr(TERMIOS, flag):
+ lflag &= ~getattr(TERMIOS, flag)
+
oflag &= ~(TERMIOS.OPOST)
- if hasattr(TERMIOS, 'IUCLC'):
- iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IUCLC|TERMIOS.IGNBRK)
- else:
iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)
+ if hasattr(TERMIOS, 'IUCLC'):
+ iflag &= ~TERMIOS.IUCLC
+ if hasattr(TERMIOS, 'PARMRK'):
+ iflag &= ~TERMIOS.PARMRK
+
#setup baudrate
try:
- ispeed = ospeed = baudIntToEnum[self._baudrate]
- except:
+ ispeed = ospeed = getattr(TERMIOS,'B%s' % (self._baudrate))
+ except AttributeError:
raise ValueError('Invalid baud rate: %r' % self._baudrate)
#setup char len
cflag &= ~TERMIOS.CSIZE
@@ -208,7 +210,7 @@
#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:
@@ -244,7 +246,7 @@
def close(self):
"""Close port"""
if self._isOpen:
- if self.fd:
+ if self.fd is not None:
os.close(self.fd)
self.fd = None
self._isOpen = False
@@ -264,30 +266,42 @@
"""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
+ if self.fd is None: raise portNotOpenError
read = ''
inp = None
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
def write(self, data):
"""Output the given string over the serial port."""
- if not self.fd: raise portNotOpenError
+ if self.fd is None: raise portNotOpenError
t = len(data)
d = data
while t>0:
+ try:
+ 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
+ except OSError,v:
+ if v.errno != errno.EAGAIN:
+ raise
def flush(self):
"""Flush of file like objects. In this case, wait until all data
@@ -296,26 +310,26 @@
def flushInput(self):
"""Clear input buffer, discarding all that is in the buffer."""
- if not self.fd:
+ if self.fd is None:
raise portNotOpenError
termios.tcflush(self.fd, TERMIOS.TCIFLUSH)
def flushOutput(self):
"""Clear output buffer, aborting the current output and
discarding all that is in the buffer."""
- if not self.fd:
+ if self.fd is None:
raise portNotOpenError
termios.tcflush(self.fd, TERMIOS.TCOFLUSH)
def sendBreak(self):
"""Send break condition."""
- if not self.fd:
+ if self.fd is None:
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 self.fd is None: raise portNotOpenError
if on:
fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
else:
@@ -323,7 +337,7 @@
def setDTR(self,on=1):
"""Set terminal status line: Data Terminal Ready"""
- if not self.fd: raise portNotOpenError
+ if self.fd is None: raise portNotOpenError
if on:
fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
else:
@@ -331,25 +345,25 @@
def getCTS(self):
"""Read terminal status line: Clear To Send"""
- if not self.fd: raise portNotOpenError
+ if self.fd is None: 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
+ if self.fd is None: raise portNotOpenError
s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
return struct.unpack('I',s)[0] & TIOCM_DSR != 0
def getRI(self):
"""Read terminal status line: Ring Indicator"""
- if not self.fd: raise portNotOpenError
+ if self.fd is None: raise portNotOpenError
s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
return struct.unpack('I',s)[0] & TIOCM_RI != 0
def getCD(self):
"""Read terminal status line: Carrier Detect"""
- if not self.fd: raise portNotOpenError
+ if self.fd is None: raise portNotOpenError
s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
return struct.unpack('I',s)[0] & TIOCM_CD != 0
@@ -357,15 +371,20 @@
def drainOutput(self):
"""internal - not portable!"""
- if not self.fd: raise portNotOpenError
+ if self.fd is None: raise portNotOpenError
termios.tcdrain(self.fd)
def nonblocking(self):
"""internal - not portable!"""
- if not self.fd:
+ if self.fd is None:
raise portNotOpenError
fcntl.fcntl(self.fd, FCNTL.F_SETFL, FCNTL.O_NONBLOCK)
+ def fileno(self):
+ """For easier of the serial port instance with select.
+ WARNING: this function is not portable to different platforms!"""
+ if self.fd is None: raise portNotOpenError
+ return self.fd
if __name__ == '__main__':
s = Serial(0,
Index: serialutil.py
===================================================================
RCS file: /cvsroot/mspgcc/python/msp430/serial/serialutil.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -d -r1.1 -r1.2
--- serialutil.py 29 Feb 2004 23:06:36 -0000 1.1
+++ serialutil.py 29 Sep 2005 21:29:10 -0000 1.2
@@ -15,6 +15,9 @@
PARITY_ODD: 'Odd',
}
+XON = chr(17)
+XOFF = chr(19)
+
#Python < 2.2.3 compatibility
try:
True
@@ -27,6 +30,11 @@
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,8 @@
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
+ dsrdtr=None, #None: use rtscts setting, dsrdtr override if true or false
):
"""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,18 +135,22 @@
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
+ self._dsrdtr = 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
+ self.dsrdtr = dsrdtr
if port is not None:
self.open()
@@ -171,7 +185,7 @@
was_open = self._isOpen
if was_open: self.close()
if port is not None:
- if type(port) == type(''): #strings are taken directly
+ if type(port) in [type(''), type(u'')]: #strings are taken directly
self.portstr = port
else:
self.portstr = self.makeDeviceName(port)
@@ -186,7 +200,7 @@
the name of the port as a string."""
return self._port
- port = property(getPort, setPort, "Port setting")
+ port = property(getPort, setPort, doc="Port setting")
def setBaudrate(self, baudrate):
@@ -205,7 +219,7 @@
"""Get the current baudrate setting."""
return self._baudrate
- baudrate = property(getBaudrate, setBaudrate, "Baudrate setting")
+ baudrate = property(getBaudrate, setBaudrate, doc="Baudrate setting")
def setByteSize(self, bytesize):
@@ -218,7 +232,7 @@
"""Get the current byte size setting."""
return self._bytesize
- bytesize = property(getByteSize, setByteSize, "Byte size setting")
+ bytesize = property(getByteSize, setByteSize, doc="Byte size setting")
def setParity(self, parity):
@@ -231,7 +245,7 @@
"""Get the current parity setting."""
return self._parity
- parity = property(getParity, setParity, "Parity setting")
+ parity = property(getParity, setParity, doc="Parity setting")
def setStopbits(self, stopbits):
@@ -244,7 +258,7 @@
"""Get the current stopbits setting."""
return self._stopbits
- stopbits = property(getStopbits, setStopbits, "Stopbits setting")
+ stopbits = property(getStopbits, setStopbits, doc="Stopbits setting")
def setTimeout(self, timeout):
@@ -263,7 +277,26 @@
"""Get the current timeout setting."""
return self._timeout
- timeout = property(getTimeout, setTimeout, "Timeout setting")
+ timeout = property(getTimeout, setTimeout, doc="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, doc="Timeout setting for write()")
def setXonXoff(self, xonxoff):
@@ -275,24 +308,40 @@
"""Get the current XonXoff setting."""
return self._xonxoff
- xonxoff = property(getXonXoff, setXonXoff, "Xon/Xoff setting")
+ xonxoff = property(getXonXoff, setXonXoff, doc="Xon/Xoff setting")
def setRtsCts(self, rtscts):
- """Change RtsCts setting."""
+ """Change RtsCts flow control setting."""
self._rtscts = rtscts
if self._isOpen: self._reconfigurePort()
def getRtsCts(self):
- """Get the current RtsCts setting."""
+ """Get the current RtsCts flow control setting."""
return self._rtscts
- rtscts = property(getRtsCts, setRtsCts, "RTS/CTS setting")
+ rtscts = property(getRtsCts, setRtsCts, doc="RTS/CTS flow control setting")
+
+ def setDsrDtr(self, dsrdtr=None):
+ """Change DsrDtr flow control setting."""
+ if dsrdtr is None:
+ #if not set, keep backwards compatibility and follow rtscts setting
+ self._dsrdtr = self._rtscts
+ else:
+ #if defined independently, follow its value
+ self._dsrdtr = dsrdtr
+ if self._isOpen: self._reconfigurePort()
+
+ def getDsrDtr(self):
+ """Get the current DsrDtr flow control setting."""
+ return self._dsrdtr
+
+ dsrdtr = property(getDsrDtr, setDsrDtr, "DSR/DTR flow control 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)" % (
+ return "%s<id=0x%x, open=%s>(port=%r, baudrate=%r, bytesize=%r, parity=%r, stopbits=%r, timeout=%r, xonxoff=%r, rtscts=%r, dsrdtr=%r)" % (
self.__class__.__name__,
id(self),
self._isOpen,
@@ -304,10 +353,12 @@
self.timeout,
self.xonxoff,
self.rtscts,
+ self.dsrdtr,
)
if __name__ == '__main__':
s = SerialBase()
+ print s.portstr
print s.getSupportedBaudrates()
print s.getSupportedByteSizes()
print s.getSupportedParities()
Index: serialwin32.py
===================================================================
RCS file: /cvsroot/mspgcc/python/msp430/serial/serialwin32.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -d -r1.1 -r1.2
--- serialwin32.py 29 Feb 2004 23:06:36 -0000 1.1
+++ serialwin32.py 29 Sep 2005 21:29:10 -0000 1.2
@@ -59,6 +59,9 @@
#Save original timeout values:
self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
+ self._rtsState = win32file.RTS_CONTROL_ENABLE
+ self._dtrState = win32file.RTS_CONTROL_ENABLE
+
self._reconfigurePort()
# Clear buffers:
@@ -90,6 +93,12 @@
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)
@@ -133,17 +142,21 @@
# Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
if self._rtscts:
comDCB.fRtsControl = win32file.RTS_CONTROL_HANDSHAKE
+ else:
+ comDCB.fRtsControl = self._rtsState
+ if self._dsrdtr:
comDCB.fDtrControl = win32file.DTR_CONTROL_HANDSHAKE
else:
- comDCB.fRtsControl = win32file.RTS_CONTROL_ENABLE
- comDCB.fDtrControl = win32file.DTR_CONTROL_ENABLE
+ comDCB.fDtrControl = self._dtrState
comDCB.fOutxCtsFlow = self._rtscts
- comDCB.fOutxDsrFlow = self._rtscts
+ comDCB.fOutxDsrFlow = self._dsrdtr
comDCB.fOutX = self._xonxoff
comDCB.fInX = self._xonxoff
comDCB.fNull = 0
comDCB.fErrorChar = 0
comDCB.fAbortOnError = 0
+ comDCB.XonChar = XON
+ comDCB.XoffChar = XOFF
try:
win32file.SetCommState(self.hComPort, comDCB)
@@ -207,7 +220,11 @@
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."""
@@ -233,16 +250,20 @@
"""Set terminal status line: Request To Send"""
if not self.hComPort: raise portNotOpenError
if level:
+ self._rtsState = win32file.RTS_CONTROL_ENABLE
win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
else:
+ self._rtsState = win32file.RTS_CONTROL_DISABLE
win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
def setDTR(self,level=1):
"""Set terminal status line: Data Terminal Ready"""
if not self.hComPort: raise portNotOpenError
if level:
+ self._dtrState = win32file.DTR_CONTROL_ENABLE
win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
else:
+ self._dtrState = win32file.DTR_CONTROL_DISABLE
win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
def getCTS(self):
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl