OLD | NEW |
| (Empty) |
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
2 # See LICENSE for details. | |
3 | |
4 | |
5 """ | |
6 Serial port support for Windows. | |
7 | |
8 Requires PySerial and win32all, and needs to be used with win32event | |
9 reactor. | |
10 """ | |
11 | |
12 # system imports | |
13 import os | |
14 import serial | |
15 from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD | |
16 from serial import STOPBITS_ONE, STOPBITS_TWO | |
17 from serial import FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS | |
18 import win32file, win32event | |
19 | |
20 # twisted imports | |
21 from twisted.protocols import basic | |
22 from twisted.internet import abstract | |
23 from twisted.python import log | |
24 | |
25 # sibling imports | |
26 from serialport import BaseSerialPort | |
27 | |
28 | |
29 class SerialPort(BaseSerialPort, abstract.FileDescriptor): | |
30 """A select()able serial device, acting as a transport.""" | |
31 | |
32 connected = 1 | |
33 | |
34 def __init__(self, protocol, deviceNameOrPortNumber, reactor, | |
35 baudrate = 9600, bytesize = EIGHTBITS, parity = PARITY_NONE, | |
36 stopbits = STOPBITS_ONE, xonxoff = 0, rtscts = 0): | |
37 self._serial = serial.Serial(deviceNameOrPortNumber, baudrate=baudrate, | |
38 bytesize=bytesize, parity=parity, | |
39 stopbits=stopbits, timeout=None, | |
40 xonxoff=xonxoff, rtscts=rtscts) | |
41 self.flushInput() | |
42 self.flushOutput() | |
43 self.reactor = reactor | |
44 self.protocol = protocol | |
45 self.outQueue = [] | |
46 self.closed = 0 | |
47 self.closedNotifies = 0 | |
48 self.writeInProgress = 0 | |
49 | |
50 self.protocol = protocol | |
51 self._overlappedRead = win32file.OVERLAPPED() | |
52 self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None) | |
53 self._overlappedWrite = win32file.OVERLAPPED() | |
54 self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None) | |
55 | |
56 self.reactor.addEvent(self._overlappedRead.hEvent, self, 'serialReadEven
t') | |
57 self.reactor.addEvent(self._overlappedWrite.hEvent, self, 'serialWriteEv
ent') | |
58 | |
59 self.protocol.makeConnection(self) | |
60 | |
61 flags, comstat = win32file.ClearCommError(self._serial.hComPort) | |
62 rc, self.read_buf = win32file.ReadFile(self._serial.hComPort, | |
63 win32file.AllocateReadBuffer(1), | |
64 self._overlappedRead) | |
65 | |
66 def serialReadEvent(self): | |
67 #get that character we set up | |
68 n = win32file.GetOverlappedResult(self._serial.hComPort, self._overlappe
dRead, 0) | |
69 if n: | |
70 first = str(self.read_buf[:n]) | |
71 #now we should get everything that is already in the buffer | |
72 flags, comstat = win32file.ClearCommError(self._serial.hComPort) | |
73 if comstat.cbInQue: | |
74 win32event.ResetEvent(self._overlappedRead.hEvent) | |
75 rc, buf = win32file.ReadFile(self._serial.hComPort, | |
76 win32file.AllocateReadBuffer(comsta
t.cbInQue), | |
77 self._overlappedRead) | |
78 n = win32file.GetOverlappedResult(self._serial.hComPort, self._o
verlappedRead, 1) | |
79 #handle all the received data: | |
80 self.protocol.dataReceived(first + str(buf[:n])) | |
81 else: | |
82 #handle all the received data: | |
83 self.protocol.dataReceived(first) | |
84 | |
85 #set up next one | |
86 win32event.ResetEvent(self._overlappedRead.hEvent) | |
87 rc, self.read_buf = win32file.ReadFile(self._serial.hComPort, | |
88 win32file.AllocateReadBuffer(1), | |
89 self._overlappedRead) | |
90 | |
91 def write(self, data): | |
92 if data: | |
93 if self.writeInProgress: | |
94 self.outQueue.append(data) | |
95 else: | |
96 self.writeInProgress = 1 | |
97 win32file.WriteFile(self._serial.hComPort, data, self._overlappe
dWrite) | |
98 | |
99 def serialWriteEvent(self): | |
100 try: | |
101 dataToWrite = self.outQueue.pop(0) | |
102 except IndexError: | |
103 self.writeInProgress = 0 | |
104 return | |
105 else: | |
106 win32file.WriteFile(self._serial.hComPort, dataToWrite, self._overla
ppedWrite) | |
107 | |
108 def connectionLost(self, reason): | |
109 self.reactor.removeEvent(self._overlappedRead.hEvent) | |
110 self.reactor.removeEvent(self._overlappedWrite.hEvent) | |
111 abstract.FileDescriptor.connectionLost(self, reason) | |
112 self._serial.close() | |
OLD | NEW |