summaryrefslogtreecommitdiff
path: root/pyserial/serial/serialwin32.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyserial/serial/serialwin32.py')
-rw-r--r--pyserial/serial/serialwin32.py201
1 files changed, 103 insertions, 98 deletions
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