~ubuntu-branches/ubuntu/quantal/pyserial/quantal

« back to all changes in this revision

Viewing changes to serial/serialwin32.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2008-06-24 19:14:57 UTC
  • mfrom: (3.1.4 lenny)
  • Revision ID: james.westby@ubuntu.com-20080624191457-l7snsahtf9ngtuti
Tags: 2.3-1
* New upstream version.
* Update watch file. Closes: #450106.
* Mention the upstream name in the package description. Closes: #459590.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! python
2
 
#Python Serial Port Extension for Win32, Linux, BSD, Jython
3
 
#serial driver for win32
4
 
#see __init__.py
5
 
#
6
 
#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
7
 
# this is distributed under a free software license, see license.txt
8
 
 
9
 
import win32file  # The base COM port and file IO functions.
10
 
import win32event # We use events and the WaitFor[Single|Multiple]Objects functions.
11
 
import win32con   # constants.
12
 
from serialutil import *
13
 
 
14
 
VERSION = "$Revision: 1.31 $".split()[1]     #extract CVS version
15
 
 
16
 
#from winbase.h. these should realy be in win32con
17
 
MS_CTS_ON  = 16
18
 
MS_DSR_ON  = 32
19
 
MS_RING_ON = 64
20
 
MS_RLSD_ON = 128
21
 
 
22
 
def device(portnum):
23
 
    """Turn a port number into a device name"""
24
 
    #the "//./COMx" format is required for devices >= 9
25
 
    #not all versions of windows seem to support this propperly
26
 
    #so that the first few ports are used with the DOS device name
27
 
    if portnum < 9:
28
 
        return 'COM%d' % (portnum+1) #numbers are transformed to a string
29
 
    else:
30
 
        return r'\\.\COM%d' % (portnum+1)
31
 
 
32
 
class Serial(SerialBase):
33
 
    """Serial port implemenation for Win32. This implemenatation requires a 
34
 
       win32all installation."""
35
 
 
36
 
    BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
37
 
                 19200,38400,57600,115200)
38
 
 
39
 
    def open(self):
40
 
        """Open port with current settings. This may throw a SerialException
41
 
           if the port cannot be opened."""
42
 
        if self._port is None:
43
 
            raise SerialException("Port must be configured before it can be used.")
44
 
        self.hComPort = None
45
 
        try:
46
 
            self.hComPort = win32file.CreateFile(self.portstr,
47
 
                   win32con.GENERIC_READ | win32con.GENERIC_WRITE,
48
 
                   0, # exclusive access
49
 
                   None, # no security
50
 
                   win32con.OPEN_EXISTING,
51
 
                   win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_FLAG_OVERLAPPED,
52
 
                   None)
53
 
        except Exception, msg:
54
 
            self.hComPort = None    #'cause __del__ is called anyway
55
 
            raise SerialException("could not open port: %s" % msg)
56
 
        # Setup a 4k buffer
57
 
        win32file.SetupComm(self.hComPort, 4096, 4096)
58
 
 
59
 
        #Save original timeout values:
60
 
        self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
61
 
 
62
 
        self._rtsState = win32file.RTS_CONTROL_ENABLE
63
 
        self._dtrState = win32file.RTS_CONTROL_ENABLE
64
 
 
65
 
        self._reconfigurePort()
66
 
        
67
 
        # Clear buffers:
68
 
        # Remove anything that was there
69
 
        win32file.PurgeComm(self.hComPort,
70
 
                            win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
71
 
                            win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
72
 
 
73
 
        self._overlappedRead = win32file.OVERLAPPED()
74
 
        self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
75
 
        self._overlappedWrite = win32file.OVERLAPPED()
76
 
        #~ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 1, 0, None)
77
 
        self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
78
 
        self._isOpen = True
79
 
 
80
 
    def _reconfigurePort(self):
81
 
        """Set commuication parameters on opened port."""
82
 
        if not self.hComPort:
83
 
            raise SerialException("Can only operate on a valid port handle")
84
 
        
85
 
        #Set Windows timeout values
86
 
        #timeouts is a tuple with the following items:
87
 
        #(ReadIntervalTimeout,ReadTotalTimeoutMultiplier,
88
 
        # ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier,
89
 
        # WriteTotalTimeoutConstant)
90
 
        if self._timeout is None:
91
 
            timeouts = (0, 0, 0, 0, 0)
92
 
        elif self._timeout == 0:
93
 
            timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
94
 
        else:
95
 
            timeouts = (0, 0, int(self._timeout*1000), 0, 0)
96
 
        if self._writeTimeout is None:
97
 
            pass
98
 
        elif self._writeTimeout == 0:
99
 
            timeouts = timeouts[:-2] + (0, win32con.MAXDWORD)
100
 
        else:
101
 
            timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))
102
 
        win32file.SetCommTimeouts(self.hComPort, timeouts)
103
 
 
104
 
        win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
105
 
 
106
 
        # Setup the connection info.
107
 
        # Get state and modify it:
108
 
        comDCB = win32file.GetCommState(self.hComPort)
109
 
        comDCB.BaudRate = self._baudrate
110
 
 
111
 
        if self._bytesize == FIVEBITS:
112
 
            comDCB.ByteSize     = 5
113
 
        elif self._bytesize == SIXBITS:
114
 
            comDCB.ByteSize     = 6
115
 
        elif self._bytesize == SEVENBITS:
116
 
            comDCB.ByteSize     = 7
117
 
        elif self._bytesize == EIGHTBITS:
118
 
            comDCB.ByteSize     = 8
119
 
        else:
120
 
            raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
121
 
 
122
 
        if self._parity == PARITY_NONE:
123
 
            comDCB.Parity       = win32file.NOPARITY
124
 
            comDCB.fParity      = 0 # Dis/Enable Parity Check
125
 
        elif self._parity == PARITY_EVEN:
126
 
            comDCB.Parity       = win32file.EVENPARITY
127
 
            comDCB.fParity      = 1 # Dis/Enable Parity Check
128
 
        elif self._parity == PARITY_ODD:
129
 
            comDCB.Parity       = win32file.ODDPARITY
130
 
            comDCB.fParity      = 1 # Dis/Enable Parity Check
131
 
        else:
132
 
            raise ValueError("Unsupported parity mode: %r" % self._parity)
133
 
 
134
 
        if self._stopbits == STOPBITS_ONE:
135
 
            comDCB.StopBits     = win32file.ONESTOPBIT
136
 
        elif self._stopbits == STOPBITS_TWO:
137
 
            comDCB.StopBits     = win32file.TWOSTOPBITS
138
 
        else:
139
 
            raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
140
 
            
141
 
        comDCB.fBinary          = 1 # Enable Binary Transmission
142
 
        # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
143
 
        if self._rtscts:
144
 
            comDCB.fRtsControl  = win32file.RTS_CONTROL_HANDSHAKE
145
 
        else:
146
 
            comDCB.fRtsControl  = self._rtsState
147
 
        if self._dsrdtr:
148
 
            comDCB.fDtrControl  = win32file.DTR_CONTROL_HANDSHAKE
149
 
        else:
150
 
            comDCB.fDtrControl  = self._dtrState
151
 
        comDCB.fOutxCtsFlow     = self._rtscts
152
 
        comDCB.fOutxDsrFlow     = self._dsrdtr
153
 
        comDCB.fOutX            = self._xonxoff
154
 
        comDCB.fInX             = self._xonxoff
155
 
        comDCB.fNull            = 0
156
 
        comDCB.fErrorChar       = 0
157
 
        comDCB.fAbortOnError    = 0
158
 
        comDCB.XonChar          = XON
159
 
        comDCB.XoffChar         = XOFF
160
 
 
161
 
        try:
162
 
            win32file.SetCommState(self.hComPort, comDCB)
163
 
        except win32file.error, e:
164
 
            raise ValueError("Cannot configure port, some setting was wrong. Original message: %s" % e)
165
 
 
166
 
    #~ def __del__(self):
167
 
        #~ self.close()
168
 
 
169
 
    def close(self):
170
 
        """Close port"""
171
 
        if self._isOpen:
172
 
            if self.hComPort:
173
 
                #Restore original timeout values:
174
 
                win32file.SetCommTimeouts(self.hComPort, self._orgTimeouts)
175
 
                #Close COM-Port:
176
 
                win32file.CloseHandle(self.hComPort)
177
 
                self.hComPort = None
178
 
            self._isOpen = False
179
 
 
180
 
    def makeDeviceName(self, port):
181
 
        return device(port)
182
 
 
183
 
    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
184
 
    
185
 
    def inWaiting(self):
186
 
        """Return the number of characters currently in the input buffer."""
187
 
        flags, comstat = win32file.ClearCommError(self.hComPort)
188
 
        return comstat.cbInQue
189
 
 
190
 
    def read(self, size=1):
191
 
        """Read size bytes from the serial port. If a timeout is set it may
192
 
           return less characters as requested. With no timeout it will block
193
 
           until the requested number of bytes is read."""
194
 
        if not self.hComPort: raise portNotOpenError
195
 
        if size > 0:
196
 
            win32event.ResetEvent(self._overlappedRead.hEvent)
197
 
            flags, comstat = win32file.ClearCommError(self.hComPort)
198
 
            if self.timeout == 0:
199
 
                n = min(comstat.cbInQue, size)
200
 
                if n > 0:
201
 
                    rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(n), self._overlappedRead)
202
 
                    win32event.WaitForSingleObject(self._overlappedRead.hEvent, win32event.INFINITE)
203
 
                    read = str(buf)
204
 
                else:
205
 
                    read = ''
206
 
            else:
207
 
                rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(size), self._overlappedRead)
208
 
                n = win32file.GetOverlappedResult(self.hComPort, self._overlappedRead, 1)
209
 
                read = str(buf[:n])
210
 
        else:
211
 
            read = ''
212
 
        return read
213
 
 
214
 
    def write(self, s):
215
 
        """Output the given string over the serial port."""
216
 
        if not self.hComPort: raise portNotOpenError
217
 
        #print repr(s),
218
 
        if s:
219
 
            #~ win32event.ResetEvent(self._overlappedWrite.hEvent)
220
 
            err, n = win32file.WriteFile(self.hComPort, s, self._overlappedWrite)
221
 
            if err: #will be ERROR_IO_PENDING:
222
 
                # Wait for the write to complete.
223
 
                #~ win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
224
 
                n = win32file.GetOverlappedResult(self.hComPort, self._overlappedWrite, 1)
225
 
                if n != len(s):
226
 
                    raise writeTimeoutError
227
 
                
228
 
 
229
 
    def flushInput(self):
230
 
        """Clear input buffer, discarding all that is in the buffer."""
231
 
        if not self.hComPort: raise portNotOpenError
232
 
        win32file.PurgeComm(self.hComPort, win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
233
 
 
234
 
    def flushOutput(self):
235
 
        """Clear output buffer, aborting the current output and
236
 
        discarding all that is in the buffer."""
237
 
        if not self.hComPort: raise portNotOpenError
238
 
        win32file.PurgeComm(self.hComPort, win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT)
239
 
 
240
 
    def sendBreak(self):
241
 
        """Send break condition."""
242
 
        if not self.hComPort: raise portNotOpenError
243
 
        import time
244
 
        win32file.SetCommBreak(self.hComPort)
245
 
        #TODO: how to set the correct duration??
246
 
        time.sleep(0.020)
247
 
        win32file.ClearCommBreak(self.hComPort)
248
 
 
249
 
    def setRTS(self,level=1):
250
 
        """Set terminal status line: Request To Send"""
251
 
        if not self.hComPort: raise portNotOpenError
252
 
        if level:
253
 
            self._rtsState = win32file.RTS_CONTROL_ENABLE
254
 
            win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
255
 
        else:
256
 
            self._rtsState = win32file.RTS_CONTROL_DISABLE
257
 
            win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
258
 
 
259
 
    def setDTR(self,level=1):
260
 
        """Set terminal status line: Data Terminal Ready"""
261
 
        if not self.hComPort: raise portNotOpenError
262
 
        if level:
263
 
            self._dtrState = win32file.DTR_CONTROL_ENABLE
264
 
            win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
265
 
        else:
266
 
            self._dtrState = win32file.DTR_CONTROL_DISABLE
267
 
            win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
268
 
 
269
 
    def getCTS(self):
270
 
        """Read terminal status line: Clear To Send"""
271
 
        if not self.hComPort: raise portNotOpenError
272
 
        return MS_CTS_ON & win32file.GetCommModemStatus(self.hComPort) != 0
273
 
 
274
 
    def getDSR(self):
275
 
        """Read terminal status line: Data Set Ready"""
276
 
        if not self.hComPort: raise portNotOpenError
277
 
        return MS_DSR_ON & win32file.GetCommModemStatus(self.hComPort) != 0
278
 
 
279
 
    def getRI(self):
280
 
        """Read terminal status line: Ring Indicator"""
281
 
        if not self.hComPort: raise portNotOpenError
282
 
        return MS_RING_ON & win32file.GetCommModemStatus(self.hComPort) != 0
283
 
 
284
 
    def getCD(self):
285
 
        """Read terminal status line: Carrier Detect"""
286
 
        if not self.hComPort: raise portNotOpenError
287
 
        return MS_RLSD_ON & win32file.GetCommModemStatus(self.hComPort) != 0
288
 
 
289
 
    # - - platform specific - - - -
290
 
 
291
 
    def setXON(self, level=True):
292
 
        """Platform specific - set flow state."""
293
 
        if not self.hComPort: raise portNotOpenError
294
 
        if level:
295
 
            win32file.EscapeCommFunction(self.hComPort, win32file.SETXON)
296
 
        else:
297
 
            win32file.EscapeCommFunction(self.hComPort, win32file.SETXOFF)
298
 
 
299
 
#Nur Testfunktion!!
300
 
if __name__ == '__main__':
301
 
    print __name__
302
 
    s = Serial()
303
 
    print s
304
 
    
305
 
    s = Serial(0)
306
 
    print s
307
 
    
308
 
    s.baudrate = 19200
309
 
    s.databits = 7
310
 
    s.close()
311
 
    s.port = 3
312
 
    s.open()
313
 
    print s
314
 
 
 
1
#! python
 
2
#Python Serial Port Extension for Win32, Linux, BSD, Jython
 
3
#serial driver for win32
 
4
#see __init__.py
 
5
#
 
6
#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
 
7
# this is distributed under a free software license, see license.txt
 
8
 
 
9
import win32file  # The base COM port and file IO functions.
 
10
import win32event # We use events and the WaitFor[Single|Multiple]Objects functions.
 
11
import win32con   # constants.
 
12
from serialutil import *
 
13
 
 
14
VERSION = "$Revision: 1.40 $".split()[1]     #extract CVS version
 
15
 
 
16
#from winbase.h. these should realy be in win32con
 
17
MS_CTS_ON  = 16
 
18
MS_DSR_ON  = 32
 
19
MS_RING_ON = 64
 
20
MS_RLSD_ON = 128
 
21
 
 
22
def device(portnum):
 
23
    """Turn a port number into a device name"""
 
24
    return 'COM%d' % (portnum+1) #numbers are transformed to a string
 
25
 
 
26
class Serial(SerialBase):
 
27
    """Serial port implemenation for Win32. This implemenatation requires a 
 
28
       win32all installation."""
 
29
 
 
30
    BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
 
31
                 19200,38400,57600,115200)
 
32
 
 
33
    def open(self):
 
34
        """Open port with current settings. This may throw a SerialException
 
35
           if the port cannot be opened."""
 
36
        if self._port is None:
 
37
            raise SerialException("Port must be configured before it can be used.")
 
38
        self.hComPort = None
 
39
        try:
 
40
            self.hComPort = win32file.CreateFile(self.makeDeviceName(self.portstr),
 
41
                   win32con.GENERIC_READ | win32con.GENERIC_WRITE,
 
42
                   0, # exclusive access
 
43
                   None, # no security
 
44
                   win32con.OPEN_EXISTING,
 
45
                   win32con.FILE_FLAG_OVERLAPPED,
 
46
                   None)
 
47
        except Exception, msg:
 
48
            self.hComPort = None    #'cause __del__ is called anyway
 
49
            raise SerialException("could not open port %s: %s" % (self.portstr, msg))
 
50
        # Setup a 4k buffer
 
51
        win32file.SetupComm(self.hComPort, 4096, 4096)
 
52
 
 
53
        #Save original timeout values:
 
54
        self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
 
55
 
 
56
        self._rtsState = win32file.RTS_CONTROL_ENABLE
 
57
        self._dtrState = win32file.DTR_CONTROL_ENABLE
 
58
 
 
59
        self._reconfigurePort()
 
60
        
 
61
        # Clear buffers:
 
62
        # Remove anything that was there
 
63
        win32file.PurgeComm(self.hComPort,
 
64
                            win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
 
65
                            win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
 
66
 
 
67
        self._overlappedRead = win32file.OVERLAPPED()
 
68
        self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
 
69
        self._overlappedWrite = win32file.OVERLAPPED()
 
70
        #~ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 1, 0, None)
 
71
        self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
 
72
        self._isOpen = True
 
73
 
 
74
    def _reconfigurePort(self):
 
75
        """Set commuication parameters on opened port."""
 
76
        if not self.hComPort:
 
77
            raise SerialException("Can only operate on a valid port handle")
 
78
        
 
79
        #Set Windows timeout values
 
80
        #timeouts is a tuple with the following items:
 
81
        #(ReadIntervalTimeout,ReadTotalTimeoutMultiplier,
 
82
        # ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier,
 
83
        # WriteTotalTimeoutConstant)
 
84
        if self._timeout is None:
 
85
            timeouts = (0, 0, 0, 0, 0)
 
86
        elif self._timeout == 0:
 
87
            timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
 
88
        else:
 
89
            timeouts = (0, 0, int(self._timeout*1000), 0, 0)
 
90
        if self._writeTimeout is None:
 
91
            pass
 
92
        elif self._writeTimeout == 0:
 
93
            timeouts = timeouts[:-2] + (0, win32con.MAXDWORD)
 
94
        else:
 
95
            timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))
 
96
        win32file.SetCommTimeouts(self.hComPort, timeouts)
 
97
 
 
98
        win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
 
99
 
 
100
        # Setup the connection info.
 
101
        # Get state and modify it:
 
102
        comDCB = win32file.GetCommState(self.hComPort)
 
103
        comDCB.BaudRate = self._baudrate
 
104
 
 
105
        if self._bytesize == FIVEBITS:
 
106
            comDCB.ByteSize     = 5
 
107
        elif self._bytesize == SIXBITS:
 
108
            comDCB.ByteSize     = 6
 
109
        elif self._bytesize == SEVENBITS:
 
110
            comDCB.ByteSize     = 7
 
111
        elif self._bytesize == EIGHTBITS:
 
112
            comDCB.ByteSize     = 8
 
113
        else:
 
114
            raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
 
115
 
 
116
        if self._parity == PARITY_NONE:
 
117
            comDCB.Parity       = win32file.NOPARITY
 
118
            comDCB.fParity      = 0 # Dis/Enable Parity Check
 
119
        elif self._parity == PARITY_EVEN:
 
120
            comDCB.Parity       = win32file.EVENPARITY
 
121
            comDCB.fParity      = 1 # Dis/Enable Parity Check
 
122
        elif self._parity == PARITY_ODD:
 
123
            comDCB.Parity       = win32file.ODDPARITY
 
124
            comDCB.fParity      = 1 # Dis/Enable Parity Check
 
125
        else:
 
126
            raise ValueError("Unsupported parity mode: %r" % self._parity)
 
127
 
 
128
        if self._stopbits == STOPBITS_ONE:
 
129
            comDCB.StopBits     = win32file.ONESTOPBIT
 
130
        elif self._stopbits == STOPBITS_TWO:
 
131
            comDCB.StopBits     = win32file.TWOSTOPBITS
 
132
        else:
 
133
            raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
 
134
            
 
135
        comDCB.fBinary          = 1 # Enable Binary Transmission
 
136
        # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
 
137
        if self._rtscts:
 
138
            comDCB.fRtsControl  = win32file.RTS_CONTROL_HANDSHAKE
 
139
        else:
 
140
            comDCB.fRtsControl  = self._rtsState
 
141
        if self._dsrdtr:
 
142
            comDCB.fDtrControl  = win32file.DTR_CONTROL_HANDSHAKE
 
143
        else:
 
144
            comDCB.fDtrControl  = self._dtrState
 
145
        comDCB.fOutxCtsFlow     = self._rtscts
 
146
        comDCB.fOutxDsrFlow     = self._dsrdtr
 
147
        comDCB.fOutX            = self._xonxoff
 
148
        comDCB.fInX             = self._xonxoff
 
149
        comDCB.fNull            = 0
 
150
        comDCB.fErrorChar       = 0
 
151
        comDCB.fAbortOnError    = 0
 
152
        comDCB.XonChar          = XON
 
153
        comDCB.XoffChar         = XOFF
 
154
 
 
155
        try:
 
156
            win32file.SetCommState(self.hComPort, comDCB)
 
157
        except win32file.error, e:
 
158
            raise ValueError("Cannot configure port, some setting was wrong. Original message: %s" % e)
 
159
 
 
160
    #~ def __del__(self):
 
161
        #~ self.close()
 
162
 
 
163
    def close(self):
 
164
        """Close port"""
 
165
        if self._isOpen:
 
166
            if self.hComPort:
 
167
                try:
 
168
                    # Restore original timeout values:
 
169
                    win32file.SetCommTimeouts(self.hComPort, self._orgTimeouts)
 
170
                except win32file.error:
 
171
                    # ignore errors. can happen for unplugged USB serial devices
 
172
                    pass
 
173
                # Close COM-Port:
 
174
                win32file.CloseHandle(self.hComPort)
 
175
                win32file.CloseHandle(self._overlappedRead.hEvent)
 
176
                win32file.CloseHandle(self._overlappedWrite.hEvent)
 
177
                self.hComPort = None
 
178
            self._isOpen = False
 
179
 
 
180
    def makeDeviceName(self, port):
 
181
        # the "\\.\COMx" format is required for devices other than COM1-COM8
 
182
        # not all versions of windows seem to support this properly
 
183
        # so that the first few ports are used with the DOS device name
 
184
        if port.upper().startswith('COM') and int(port[3:]) <= 8:
 
185
            return port
 
186
        return '\\\\.\\' + port
 
187
 
 
188
    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
 
189
    
 
190
    def inWaiting(self):
 
191
        """Return the number of characters currently in the input buffer."""
 
192
        flags, comstat = win32file.ClearCommError(self.hComPort)
 
193
        return comstat.cbInQue
 
194
 
 
195
    def read(self, size=1):
 
196
        """Read size bytes from the serial port. If a timeout is set it may
 
197
           return less characters as requested. With no timeout it will block
 
198
           until the requested number of bytes is read."""
 
199
        if not self.hComPort: raise portNotOpenError
 
200
        if size > 0:
 
201
            win32event.ResetEvent(self._overlappedRead.hEvent)
 
202
            flags, comstat = win32file.ClearCommError(self.hComPort)
 
203
            if self.timeout == 0:
 
204
                n = min(comstat.cbInQue, size)
 
205
                if n > 0:
 
206
                    rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(n), self._overlappedRead)
 
207
                    win32event.WaitForSingleObject(self._overlappedRead.hEvent, win32event.INFINITE)
 
208
                    read = str(buf)
 
209
                else:
 
210
                    read = ''
 
211
            else:
 
212
                rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(size), self._overlappedRead)
 
213
                n = win32file.GetOverlappedResult(self.hComPort, self._overlappedRead, 1)
 
214
                read = str(buf[:n])
 
215
        else:
 
216
            read = ''
 
217
        return read
 
218
 
 
219
    def write(self, data):
 
220
        """Output the given string over the serial port."""
 
221
        if not self.hComPort: raise portNotOpenError
 
222
        if not isinstance(data, str):
 
223
            raise TypeError('expected str, got %s' % type(data))
 
224
        #print repr(s),
 
225
        if data:
 
226
            #~ win32event.ResetEvent(self._overlappedWrite.hEvent)
 
227
            err, n = win32file.WriteFile(self.hComPort, data, self._overlappedWrite)
 
228
            if err: #will be ERROR_IO_PENDING:
 
229
                # Wait for the write to complete.
 
230
                #~ win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
 
231
                n = win32file.GetOverlappedResult(self.hComPort, self._overlappedWrite, 1)
 
232
                if n != len(data):
 
233
                    raise writeTimeoutError
 
234
                
 
235
 
 
236
    def flushInput(self):
 
237
        """Clear input buffer, discarding all that is in the buffer."""
 
238
        if not self.hComPort: raise portNotOpenError
 
239
        win32file.PurgeComm(self.hComPort, win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
 
240
 
 
241
    def flushOutput(self):
 
242
        """Clear output buffer, aborting the current output and
 
243
        discarding all that is in the buffer."""
 
244
        if not self.hComPort: raise portNotOpenError
 
245
        win32file.PurgeComm(self.hComPort, win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT)
 
246
 
 
247
    def sendBreak(self, duration=0.25):
 
248
        """Send break condition."""
 
249
        if not self.hComPort: raise portNotOpenError
 
250
        import time
 
251
        win32file.SetCommBreak(self.hComPort)
 
252
        time.sleep(duration)
 
253
        win32file.ClearCommBreak(self.hComPort)
 
254
 
 
255
    def setRTS(self, level=1):
 
256
        """Set terminal status line: Request To Send"""
 
257
        if not self.hComPort: raise portNotOpenError
 
258
        if level:
 
259
            self._rtsState = win32file.RTS_CONTROL_ENABLE
 
260
            win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
 
261
        else:
 
262
            self._rtsState = win32file.RTS_CONTROL_DISABLE
 
263
            win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
 
264
 
 
265
    def setDTR(self, level=1):
 
266
        """Set terminal status line: Data Terminal Ready"""
 
267
        if not self.hComPort: raise portNotOpenError
 
268
        if level:
 
269
            self._dtrState = win32file.DTR_CONTROL_ENABLE
 
270
            win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
 
271
        else:
 
272
            self._dtrState = win32file.DTR_CONTROL_DISABLE
 
273
            win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
 
274
 
 
275
    def getCTS(self):
 
276
        """Read terminal status line: Clear To Send"""
 
277
        if not self.hComPort: raise portNotOpenError
 
278
        return MS_CTS_ON & win32file.GetCommModemStatus(self.hComPort) != 0
 
279
 
 
280
    def getDSR(self):
 
281
        """Read terminal status line: Data Set Ready"""
 
282
        if not self.hComPort: raise portNotOpenError
 
283
        return MS_DSR_ON & win32file.GetCommModemStatus(self.hComPort) != 0
 
284
 
 
285
    def getRI(self):
 
286
        """Read terminal status line: Ring Indicator"""
 
287
        if not self.hComPort: raise portNotOpenError
 
288
        return MS_RING_ON & win32file.GetCommModemStatus(self.hComPort) != 0
 
289
 
 
290
    def getCD(self):
 
291
        """Read terminal status line: Carrier Detect"""
 
292
        if not self.hComPort: raise portNotOpenError
 
293
        return MS_RLSD_ON & win32file.GetCommModemStatus(self.hComPort) != 0
 
294
 
 
295
    # - - platform specific - - - -
 
296
 
 
297
    def setXON(self, level=True):
 
298
        """Platform specific - set flow state."""
 
299
        if not self.hComPort: raise portNotOpenError
 
300
        if level:
 
301
            win32file.EscapeCommFunction(self.hComPort, win32file.SETXON)
 
302
        else:
 
303
            win32file.EscapeCommFunction(self.hComPort, win32file.SETXOFF)
 
304
 
 
305
#Nur Testfunktion!!
 
306
if __name__ == '__main__':
 
307
    s = Serial(0)
 
308
    print s
 
309
    
 
310
    s = Serial()
 
311
    print s
 
312
    
 
313
    
 
314
    s.baudrate = 19200
 
315
    s.databits = 7
 
316
    s.close()
 
317
    s.port = 0
 
318
    s.open()
 
319
    print s
 
320