blob: e6105738ed23cc75a1c32d2dad40951a94800c87 [file] [log] [blame]
cliechti0d6029a2008-06-21 01:28:46 +00001#! python
cliechtiff0c3792008-06-22 01:01:21 +00002# Python Serial Port Extension for Win32, Linux, BSD, Jython and .NET/Mono
3# serial driver for .NET/Mono (IronPython), .NET >= 2
4# see __init__.py
cliechti0d6029a2008-06-21 01:28:46 +00005#
cliechtiff0c3792008-06-22 01:01:21 +00006# (C) 2008 Chris Liechti <cliechti@gmx.net>
cliechti0d6029a2008-06-21 01:28:46 +00007# this is distributed under a free software license, see license.txt
8
9import System.IO.Ports
10from serialutil import *
11
12def device(portnum):
13 """Turn a port number into a device name"""
14 return System.IO.Ports.SerialPort.GetPortNames()[portnum]
15
16class Serial(SerialBase):
17 """Serial port implemenation for .NET/Mono."""
18
19 BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
20 19200,38400,57600,115200)
21
22 def open(self):
23 """Open port with current settings. This may throw a SerialException
24 if the port cannot be opened."""
25 if self._port is None:
26 raise SerialException("Port must be configured before it can be used.")
cliechti0d6029a2008-06-21 01:28:46 +000027 try:
28 self._port_handle = System.IO.Ports.SerialPort(self.portstr)
29 except Exception, msg:
cliechtiff0c3792008-06-22 01:01:21 +000030 self._port_handle = None
cliechti0d6029a2008-06-21 01:28:46 +000031 raise SerialException("could not open port %s: %s" % (self.portstr, msg))
32
33 self._reconfigurePort()
34 self._port_handle.Open()
35 self._isOpen = True
cliechtiff0c3792008-06-22 01:01:21 +000036 self.flushInput()
37 self.flushOutput()
cliechti0d6029a2008-06-21 01:28:46 +000038
39 def _reconfigurePort(self):
cliechtiff0c3792008-06-22 01:01:21 +000040 """Set communication parameters on opened port."""
cliechti0d6029a2008-06-21 01:28:46 +000041 if not self._port_handle:
42 raise SerialException("Can only operate on a valid port handle")
43
44 self.ReceivedBytesThreshold = 1
45
46 if self._timeout is None:
47 self._port_handle.ReadTimeout = System.IO.Ports.SerialPort.InfiniteTimeout
48 else:
49 self._port_handle.ReadTimeout = int(self._timeout*1000)
50
51 # if self._timeout != 0 and self._interCharTimeout is not None:
52 # timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:]
53
54 if self._writeTimeout is None:
cliechtiff0c3792008-06-22 01:01:21 +000055 self._port_handle.WriteTimeout = System.IO.Ports.SerialPort.InfiniteTimeout
cliechti0d6029a2008-06-21 01:28:46 +000056 else:
57 self._port_handle.WriteTimeout = int(self._writeTimeout*1000)
58
59
60 # Setup the connection info.
61 self._port_handle.BaudRate = self._baudrate
62
63 if self._bytesize == FIVEBITS:
64 self._port_handle.DataBits = 5
65 elif self._bytesize == SIXBITS:
66 self._port_handle.DataBits = 6
67 elif self._bytesize == SEVENBITS:
68 self._port_handle.DataBits = 7
69 elif self._bytesize == EIGHTBITS:
70 self._port_handle.DataBits = 8
71 else:
72 raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
73
74 if self._parity == PARITY_NONE:
75 self._port_handle.Parity = System.IO.Ports.Parity.None
76 elif self._parity == PARITY_EVEN:
77 self._port_handle.Parity = System.IO.Ports.Parity.Even
78 elif self._parity == PARITY_ODD:
79 self._port_handle.Parity = System.IO.Ports.Parity.Odd
80 elif self._parity == PARITY_MARK:
81 self._port_handle.Parity = System.IO.Ports.Parity.Mark
82 elif self._parity == PARITY_SPACE:
83 self._port_handle.Parity = System.IO.Ports.Parity.Space
84 else:
85 raise ValueError("Unsupported parity mode: %r" % self._parity)
86
87 if self._stopbits == STOPBITS_ONE:
88 self._port_handle.StopBits = System.IO.Ports.StopBits.One
89 elif self._stopbits == STOPBITS_TWO:
90 self._port_handle.StopBits = System.IO.Ports.StopBits.Two
91 else:
92 raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
93
94 if self._rtscts and self._xonxoff:
95 self._port_handle.Handshake = System.IO.Ports.Handshake.RequestToSendXOnXOff
96 elif self._rtscts:
97 self._port_handle.Handshake = System.IO.Ports.Handshake.RequestToSend
98 elif self._xonxoff:
99 self._port_handle.Handshake = System.IO.Ports.Handshake.XOnXOff
100 else:
101 self._port_handle.Handshake = System.IO.Ports.Handshake.None
102
103 #~ def __del__(self):
104 #~ self.close()
105
106 def close(self):
107 """Close port"""
108 if self._isOpen:
109 if self._port_handle:
110 try:
cliechtiff0c3792008-06-22 01:01:21 +0000111 self._port_handle.Close()
cliechti0d6029a2008-06-21 01:28:46 +0000112 except System.IO.Ports.InvalidOperationException:
113 # ignore errors. can happen for unplugged USB serial devices
114 pass
115 self._port_handle = None
116 self._isOpen = False
117
118 def makeDeviceName(self, port):
119 return device(port)
120
121 # - - - - - - - - - - - - - - - - - - - - - - - -
122
123 def inWaiting(self):
124 """Return the number of characters currently in the input buffer."""
125 if not self._port_handle: raise portNotOpenError
126 return self._port_handle.BytesToRead
127
128 def read(self, size=1):
129 """Read size bytes from the serial port. If a timeout is set it may
130 return less characters as requested. With no timeout it will block
131 until the requested number of bytes is read."""
132 if not self._port_handle: raise portNotOpenError
133 data = []
134 while size:
cliechtiff0c3792008-06-22 01:01:21 +0000135 try:
136 data.append(self._port_handle.ReadByte())
137 except System.TimeoutException, e:
138 break
139 else:
140 size -= 1
cliechti0d6029a2008-06-21 01:28:46 +0000141 return ''.join(data)
142
143 def write(self, data):
144 """Output the given string over the serial port."""
145 if not self._port_handle: raise portNotOpenError
146 if not isinstance(data, str):
147 raise TypeError('expected str, got %s' % type(data))
cliechtiff0c3792008-06-22 01:01:21 +0000148 try:
149 self._port_handle.Write(data)
150 except System.TimeoutException, e:
151 raise writeTimeoutError
cliechti0d6029a2008-06-21 01:28:46 +0000152
153 def flushInput(self):
154 """Clear input buffer, discarding all that is in the buffer."""
155 if not self._port_handle: raise portNotOpenError
156 self._port_handle.DiscardInBuffer()
157
158 def flushOutput(self):
159 """Clear output buffer, aborting the current output and
160 discarding all that is in the buffer."""
161 if not self._port_handle: raise portNotOpenError
162 self._port_handle.DiscardOutBuffer()
163
164 def sendBreak(self, duration=0.25):
165 """Send break condition. Timed, returns to idle state after given duration."""
166 if not self._port_handle: raise portNotOpenError
167 import time
168 self._port_handle.BreakState = True
169 time.sleep(duration)
170 self._port_handle.BreakState = False
171
cliechtiff0c3792008-06-22 01:01:21 +0000172 def setBreak(self, level=True):
cliechti0d6029a2008-06-21 01:28:46 +0000173 """Set break: Controls TXD. When active, to transmitting is possible."""
174 if not self._port_handle: raise portNotOpenError
cliechtiff0c3792008-06-22 01:01:21 +0000175 self._port_handle.BreakState = bool(level)
cliechti0d6029a2008-06-21 01:28:46 +0000176
cliechtiff0c3792008-06-22 01:01:21 +0000177 def setRTS(self, level=True):
cliechti0d6029a2008-06-21 01:28:46 +0000178 """Set terminal status line: Request To Send"""
179 if not self._port_handle: raise portNotOpenError
cliechtiff0c3792008-06-22 01:01:21 +0000180 self._port_handle.RtsEnable = bool(level)
cliechti0d6029a2008-06-21 01:28:46 +0000181
cliechtiff0c3792008-06-22 01:01:21 +0000182 def setDTR(self, level=True):
cliechti0d6029a2008-06-21 01:28:46 +0000183 """Set terminal status line: Data Terminal Ready"""
184 if not self._port_handle: raise portNotOpenError
cliechtiff0c3792008-06-22 01:01:21 +0000185 self._port_handle.DtrEnable = bool(level)
cliechti0d6029a2008-06-21 01:28:46 +0000186
187 def getCTS(self):
188 """Read terminal status line: Clear To Send"""
189 if not self._port_handle: raise portNotOpenError
190 return self._port_handle.CtsHolding
191
192 def getDSR(self):
193 """Read terminal status line: Data Set Ready"""
194 if not self._port_handle: raise portNotOpenError
195 return self._port_handle.DsrHolding
196
cliechtiff0c3792008-06-22 01:01:21 +0000197 def getRI(self):
198 """Read terminal status line: Ring Indicator"""
199 if not self._port_handle: raise portNotOpenError
cliechti0d6029a2008-06-21 01:28:46 +0000200 #~ return self._port_handle.XXX
cliechtiff0c3792008-06-22 01:01:21 +0000201 return False #XXX an error would be better
cliechti0d6029a2008-06-21 01:28:46 +0000202
203 def getCD(self):
204 """Read terminal status line: Carrier Detect"""
205 if not self._port_handle: raise portNotOpenError
206 return self._port_handle.CDHolding
207
208 # - - platform specific - - - -
209
210#Nur Testfunktion!!
211if __name__ == '__main__':
212 s = Serial(0)
213 print s
214
215 s = Serial()
216 print s
217
218
219 s.baudrate = 19200
220 s.databits = 7
221 s.close()
222 s.port = 0
223 s.open()
224 print s
225