Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / third_party / pyserial / serial / serialposix.py
blobb9b4b282682dbeec291a503e1ca7533bcd676067
1 #!/usr/bin/env python
3 # Python Serial Port Extension for Win32, Linux, BSD, Jython
4 # module for serial IO for POSIX compatible systems, like Linux
5 # see __init__.py
7 # (C) 2001-2010 Chris Liechti <cliechti@gmx.net>
8 # this is distributed under a free software license, see license.txt
10 # parts based on code from Grant B. Edwards <grante@visi.com>:
11 # ftp://ftp.visi.com/users/grante/python/PosixSerial.py
13 # references: http://www.easysw.com/~mike/serial/serial.html
15 import sys, os, fcntl, termios, struct, select, errno, time
16 from serial.serialutil import *
18 # Do check the Python version as some constants have moved.
19 if (sys.hexversion < 0x020100f0):
20 import TERMIOS
21 else:
22 TERMIOS = termios
24 if (sys.hexversion < 0x020200f0):
25 import FCNTL
26 else:
27 FCNTL = fcntl
29 # try to detect the OS so that a device can be selected...
30 # this code block should supply a device() and set_special_baudrate() function
31 # for the platform
32 plat = sys.platform.lower()
34 if plat[:5] == 'linux': # Linux (confirmed)
36 def device(port):
37 return '/dev/ttyS%d' % port
39 TCGETS2 = 0x802C542A
40 TCSETS2 = 0x402C542B
41 BOTHER = 0o010000
43 def set_special_baudrate(port, baudrate):
44 # right size is 44 on x86_64, allow for some growth
45 import array
46 buf = array.array('i', [0] * 64)
48 try:
49 # get serial_struct
50 FCNTL.ioctl(port.fd, TCGETS2, buf)
51 # set custom speed
52 buf[2] &= ~TERMIOS.CBAUD
53 buf[2] |= BOTHER
54 buf[9] = buf[10] = baudrate
56 # set serial_struct
57 res = FCNTL.ioctl(port.fd, TCSETS2, buf)
58 except IOError, e:
59 raise ValueError('Failed to set custom baud rate (%s): %s' % (baudrate, e))
61 baudrate_constants = {
62 0: 0000000, # hang up
63 50: 0000001,
64 75: 0000002,
65 110: 0000003,
66 134: 0000004,
67 150: 0000005,
68 200: 0000006,
69 300: 0000007,
70 600: 0000010,
71 1200: 0000011,
72 1800: 0000012,
73 2400: 0000013,
74 4800: 0000014,
75 9600: 0000015,
76 19200: 0000016,
77 38400: 0000017,
78 57600: 0010001,
79 115200: 0010002,
80 230400: 0010003,
81 460800: 0010004,
82 500000: 0010005,
83 576000: 0010006,
84 921600: 0010007,
85 1000000: 0010010,
86 1152000: 0010011,
87 1500000: 0010012,
88 2000000: 0010013,
89 2500000: 0010014,
90 3000000: 0010015,
91 3500000: 0010016,
92 4000000: 0010017
95 elif plat == 'cygwin': # cygwin/win32 (confirmed)
97 def device(port):
98 return '/dev/com%d' % (port + 1)
100 def set_special_baudrate(port, baudrate):
101 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
103 baudrate_constants = {
104 128000: 0x01003,
105 256000: 0x01005,
106 500000: 0x01007,
107 576000: 0x01008,
108 921600: 0x01009,
109 1000000: 0x0100a,
110 1152000: 0x0100b,
111 1500000: 0x0100c,
112 2000000: 0x0100d,
113 2500000: 0x0100e,
114 3000000: 0x0100f
117 elif plat[:7] == 'openbsd': # OpenBSD
119 def device(port):
120 return '/dev/cua%02d' % port
122 def set_special_baudrate(port, baudrate):
123 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
125 baudrate_constants = {}
127 elif plat[:3] == 'bsd' or \
128 plat[:7] == 'freebsd':
130 def device(port):
131 return '/dev/cuad%d' % port
133 def set_special_baudrate(port, baudrate):
134 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
136 baudrate_constants = {}
138 elif plat[:6] == 'darwin': # OS X
140 version = os.uname()[2].split('.')
141 # Tiger or above can support arbitrary serial speeds
142 if int(version[0]) >= 8:
143 def set_special_baudrate(port, baudrate):
144 # use IOKit-specific call to set up high speeds
145 import array, fcntl
146 buf = array.array('i', [baudrate])
147 IOSSIOSPEED = 0x80045402 #_IOW('T', 2, speed_t)
148 fcntl.ioctl(port.fd, IOSSIOSPEED, buf, 1)
149 else: # version < 8
150 def set_special_baudrate(port, baudrate):
151 raise ValueError("baud rate not supported")
153 def device(port):
154 return '/dev/cuad%d' % port
156 baudrate_constants = {}
159 elif plat[:6] == 'netbsd': # NetBSD 1.6 testing by Erk
161 def device(port):
162 return '/dev/dty%02d' % port
164 def set_special_baudrate(port, baudrate):
165 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
167 baudrate_constants = {}
169 elif plat[:4] == 'irix': # IRIX (partially tested)
171 def device(port):
172 return '/dev/ttyf%d' % (port+1) #XXX different device names depending on flow control
174 def set_special_baudrate(port, baudrate):
175 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
177 baudrate_constants = {}
179 elif plat[:2] == 'hp': # HP-UX (not tested)
181 def device(port):
182 return '/dev/tty%dp0' % (port+1)
184 def set_special_baudrate(port, baudrate):
185 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
187 baudrate_constants = {}
189 elif plat[:5] == 'sunos': # Solaris/SunOS (confirmed)
191 def device(port):
192 return '/dev/tty%c' % (ord('a')+port)
194 def set_special_baudrate(port, baudrate):
195 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
197 baudrate_constants = {}
199 elif plat[:3] == 'aix': # AIX
201 def device(port):
202 return '/dev/tty%d' % (port)
204 def set_special_baudrate(port, baudrate):
205 raise ValueError("sorry don't know how to handle non standard baud rate on this platform")
207 baudrate_constants = {}
209 else:
210 # platform detection has failed...
211 sys.stderr.write("""\
212 don't know how to number ttys on this system.
213 ! Use an explicit path (eg /dev/ttyS1) or send this information to
214 ! the author of this module:
216 sys.platform = %r
217 os.name = %r
218 serialposix.py version = %s
220 also add the device name of the serial port and where the
221 counting starts for the first serial port.
222 e.g. 'first serial port: /dev/ttyS0'
223 and with a bit luck you can get this module running...
224 """ % (sys.platform, os.name, VERSION))
225 # no exception, just continue with a brave attempt to build a device name
226 # even if the device name is not correct for the platform it has chances
227 # to work using a string with the real device name as port parameter.
228 def device(portum):
229 return '/dev/ttyS%d' % portnum
230 def set_special_baudrate(port, baudrate):
231 raise SerialException("sorry don't know how to handle non standard baud rate on this platform")
232 baudrate_constants = {}
233 #~ raise Exception, "this module does not run on this platform, sorry."
235 # whats up with "aix", "beos", ....
236 # they should work, just need to know the device names.
239 # load some constants for later use.
240 # try to use values from TERMIOS, use defaults from linux otherwise
241 TIOCMGET = hasattr(TERMIOS, 'TIOCMGET') and TERMIOS.TIOCMGET or 0x5415
242 TIOCMBIS = hasattr(TERMIOS, 'TIOCMBIS') and TERMIOS.TIOCMBIS or 0x5416
243 TIOCMBIC = hasattr(TERMIOS, 'TIOCMBIC') and TERMIOS.TIOCMBIC or 0x5417
244 TIOCMSET = hasattr(TERMIOS, 'TIOCMSET') and TERMIOS.TIOCMSET or 0x5418
246 #TIOCM_LE = hasattr(TERMIOS, 'TIOCM_LE') and TERMIOS.TIOCM_LE or 0x001
247 TIOCM_DTR = hasattr(TERMIOS, 'TIOCM_DTR') and TERMIOS.TIOCM_DTR or 0x002
248 TIOCM_RTS = hasattr(TERMIOS, 'TIOCM_RTS') and TERMIOS.TIOCM_RTS or 0x004
249 #TIOCM_ST = hasattr(TERMIOS, 'TIOCM_ST') and TERMIOS.TIOCM_ST or 0x008
250 #TIOCM_SR = hasattr(TERMIOS, 'TIOCM_SR') and TERMIOS.TIOCM_SR or 0x010
252 TIOCM_CTS = hasattr(TERMIOS, 'TIOCM_CTS') and TERMIOS.TIOCM_CTS or 0x020
253 TIOCM_CAR = hasattr(TERMIOS, 'TIOCM_CAR') and TERMIOS.TIOCM_CAR or 0x040
254 TIOCM_RNG = hasattr(TERMIOS, 'TIOCM_RNG') and TERMIOS.TIOCM_RNG or 0x080
255 TIOCM_DSR = hasattr(TERMIOS, 'TIOCM_DSR') and TERMIOS.TIOCM_DSR or 0x100
256 TIOCM_CD = hasattr(TERMIOS, 'TIOCM_CD') and TERMIOS.TIOCM_CD or TIOCM_CAR
257 TIOCM_RI = hasattr(TERMIOS, 'TIOCM_RI') and TERMIOS.TIOCM_RI or TIOCM_RNG
258 #TIOCM_OUT1 = hasattr(TERMIOS, 'TIOCM_OUT1') and TERMIOS.TIOCM_OUT1 or 0x2000
259 #TIOCM_OUT2 = hasattr(TERMIOS, 'TIOCM_OUT2') and TERMIOS.TIOCM_OUT2 or 0x4000
260 if hasattr(TERMIOS, 'TIOCINQ'):
261 TIOCINQ = TERMIOS.TIOCINQ
262 else:
263 TIOCINQ = hasattr(TERMIOS, 'FIONREAD') and TERMIOS.FIONREAD or 0x541B
264 TIOCOUTQ = hasattr(TERMIOS, 'TIOCOUTQ') and TERMIOS.TIOCOUTQ or 0x5411
266 TIOCM_zero_str = struct.pack('I', 0)
267 TIOCM_RTS_str = struct.pack('I', TIOCM_RTS)
268 TIOCM_DTR_str = struct.pack('I', TIOCM_DTR)
270 TIOCSBRK = hasattr(TERMIOS, 'TIOCSBRK') and TERMIOS.TIOCSBRK or 0x5427
271 TIOCCBRK = hasattr(TERMIOS, 'TIOCCBRK') and TERMIOS.TIOCCBRK or 0x5428
274 class PosixSerial(SerialBase):
275 """Serial port class POSIX implementation. Serial port configuration is
276 done with termios and fcntl. Runs on Linux and many other Un*x like
277 systems."""
279 def open(self):
280 """Open port with current settings. This may throw a SerialException
281 if the port cannot be opened."""
282 if self._port is None:
283 raise SerialException("Port must be configured before it can be used.")
284 if self._isOpen:
285 raise SerialException("Port is already open.")
286 self.fd = None
287 # open
288 try:
289 self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
290 except IOError, msg:
291 self.fd = None
292 raise SerialException(msg.errno, "could not open port %s: %s" % (self._port, msg))
293 #~ fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) # set blocking
295 try:
296 self._reconfigurePort()
297 except:
298 try:
299 os.close(self.fd)
300 except:
301 # ignore any exception when closing the port
302 # also to keep original exception that happened when setting up
303 pass
304 self.fd = None
305 raise
306 else:
307 self._isOpen = True
308 self.flushInput()
311 def _reconfigurePort(self):
312 """Set communication parameters on opened port."""
313 if self.fd is None:
314 raise SerialException("Can only operate on a valid file descriptor")
315 custom_baud = None
317 vmin = vtime = 0 # timeout is done via select
318 if self._interCharTimeout is not None:
319 vmin = 1
320 vtime = int(self._interCharTimeout * 10)
321 try:
322 orig_attr = termios.tcgetattr(self.fd)
323 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
324 except termios.error, msg: # if a port is nonexistent but has a /dev file, it'll fail here
325 raise SerialException("Could not configure port: %s" % msg)
326 # set up raw mode / no echo / binary
327 cflag |= (TERMIOS.CLOCAL|TERMIOS.CREAD)
328 lflag &= ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL|
329 TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT
330 for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk
331 if hasattr(TERMIOS, flag):
332 lflag &= ~getattr(TERMIOS, flag)
334 oflag &= ~(TERMIOS.OPOST)
335 iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)
336 if hasattr(TERMIOS, 'IUCLC'):
337 iflag &= ~TERMIOS.IUCLC
338 if hasattr(TERMIOS, 'PARMRK'):
339 iflag &= ~TERMIOS.PARMRK
341 # setup baud rate
342 try:
343 ispeed = ospeed = getattr(TERMIOS, 'B%s' % (self._baudrate))
344 except AttributeError:
345 try:
346 ispeed = ospeed = baudrate_constants[self._baudrate]
347 except KeyError:
348 #~ raise ValueError('Invalid baud rate: %r' % self._baudrate)
349 # may need custom baud rate, it isn't in our list.
350 ispeed = ospeed = getattr(TERMIOS, 'B38400')
351 try:
352 custom_baud = int(self._baudrate) # store for later
353 except ValueError:
354 raise ValueError('Invalid baud rate: %r' % self._baudrate)
355 else:
356 if custom_baud < 0:
357 raise ValueError('Invalid baud rate: %r' % self._baudrate)
359 # setup char len
360 cflag &= ~TERMIOS.CSIZE
361 if self._bytesize == 8:
362 cflag |= TERMIOS.CS8
363 elif self._bytesize == 7:
364 cflag |= TERMIOS.CS7
365 elif self._bytesize == 6:
366 cflag |= TERMIOS.CS6
367 elif self._bytesize == 5:
368 cflag |= TERMIOS.CS5
369 else:
370 raise ValueError('Invalid char len: %r' % self._bytesize)
371 # setup stopbits
372 if self._stopbits == STOPBITS_ONE:
373 cflag &= ~(TERMIOS.CSTOPB)
374 elif self._stopbits == STOPBITS_ONE_POINT_FIVE:
375 cflag |= (TERMIOS.CSTOPB) # XXX same as TWO.. there is no POSIX support for 1.5
376 elif self._stopbits == STOPBITS_TWO:
377 cflag |= (TERMIOS.CSTOPB)
378 else:
379 raise ValueError('Invalid stop bit specification: %r' % self._stopbits)
380 # setup parity
381 iflag &= ~(TERMIOS.INPCK|TERMIOS.ISTRIP)
382 if self._parity == PARITY_NONE:
383 cflag &= ~(TERMIOS.PARENB|TERMIOS.PARODD)
384 elif self._parity == PARITY_EVEN:
385 cflag &= ~(TERMIOS.PARODD)
386 cflag |= (TERMIOS.PARENB)
387 elif self._parity == PARITY_ODD:
388 cflag |= (TERMIOS.PARENB|TERMIOS.PARODD)
389 else:
390 raise ValueError('Invalid parity: %r' % self._parity)
391 # setup flow control
392 # xonxoff
393 if hasattr(TERMIOS, 'IXANY'):
394 if self._xonxoff:
395 iflag |= (TERMIOS.IXON|TERMIOS.IXOFF) #|TERMIOS.IXANY)
396 else:
397 iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
398 else:
399 if self._xonxoff:
400 iflag |= (TERMIOS.IXON|TERMIOS.IXOFF)
401 else:
402 iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF)
403 # rtscts
404 if hasattr(TERMIOS, 'CRTSCTS'):
405 if self._rtscts:
406 cflag |= (TERMIOS.CRTSCTS)
407 else:
408 cflag &= ~(TERMIOS.CRTSCTS)
409 elif hasattr(TERMIOS, 'CNEW_RTSCTS'): # try it with alternate constant name
410 if self._rtscts:
411 cflag |= (TERMIOS.CNEW_RTSCTS)
412 else:
413 cflag &= ~(TERMIOS.CNEW_RTSCTS)
414 # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
416 # buffer
417 # vmin "minimal number of characters to be read. = for non blocking"
418 if vmin < 0 or vmin > 255:
419 raise ValueError('Invalid vmin: %r ' % vmin)
420 cc[TERMIOS.VMIN] = vmin
421 # vtime
422 if vtime < 0 or vtime > 255:
423 raise ValueError('Invalid vtime: %r' % vtime)
424 cc[TERMIOS.VTIME] = vtime
425 # activate settings
426 if [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr:
427 termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
429 # apply custom baud rate, if any
430 if custom_baud is not None:
431 set_special_baudrate(self, custom_baud)
433 def close(self):
434 """Close port"""
435 if self._isOpen:
436 if self.fd is not None:
437 os.close(self.fd)
438 self.fd = None
439 self._isOpen = False
441 def makeDeviceName(self, port):
442 return device(port)
444 # - - - - - - - - - - - - - - - - - - - - - - - -
446 def inWaiting(self):
447 """Return the number of characters currently in the input buffer."""
448 #~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str)
449 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
450 return struct.unpack('I',s)[0]
452 # select based implementation, proved to work on many systems
453 def read(self, size=1):
454 """Read size bytes from the serial port. If a timeout is set it may
455 return less characters as requested. With no timeout it will block
456 until the requested number of bytes is read."""
457 if not self._isOpen: raise portNotOpenError
458 read = bytearray()
459 while len(read) < size:
460 try:
461 ready,_,_ = select.select([self.fd],[],[], self._timeout)
462 # If select was used with a timeout, and the timeout occurs, it
463 # returns with empty lists -> thus abort read operation.
464 # For timeout == 0 (non-blocking operation) also abort when there
465 # is nothing to read.
466 if not ready:
467 break # timeout
468 buf = os.read(self.fd, size-len(read))
469 # read should always return some data as select reported it was
470 # ready to read when we get to this point.
471 if not buf:
472 # Disconnected devices, at least on Linux, show the
473 # behavior that they are always ready to read immediately
474 # but reading returns nothing.
475 raise SerialException('device reports readiness to read but returned no data (device disconnected or multiple access on port?)')
476 read.extend(buf)
477 except select.error, e:
478 # ignore EAGAIN errors. all other errors are shown
479 # see also http://www.python.org/dev/peps/pep-3151/#select
480 if e[0] != errno.EAGAIN:
481 raise SerialException('read failed: %s' % (e,))
482 except OSError, e:
483 # ignore EAGAIN errors. all other errors are shown
484 if e.errno != errno.EAGAIN:
485 raise SerialException('read failed: %s' % (e,))
486 return bytes(read)
488 def write(self, data):
489 """Output the given string over the serial port."""
490 if not self._isOpen: raise portNotOpenError
491 d = to_bytes(data)
492 tx_len = len(d)
493 if self._writeTimeout is not None and self._writeTimeout > 0:
494 timeout = time.time() + self._writeTimeout
495 else:
496 timeout = None
497 while tx_len > 0:
498 try:
499 n = os.write(self.fd, d)
500 if timeout:
501 # when timeout is set, use select to wait for being ready
502 # with the time left as timeout
503 timeleft = timeout - time.time()
504 if timeleft < 0:
505 raise writeTimeoutError
506 _, ready, _ = select.select([], [self.fd], [], timeleft)
507 if not ready:
508 raise writeTimeoutError
509 else:
510 # wait for write operation
511 _, ready, _ = select.select([], [self.fd], [], None)
512 if not ready:
513 raise SerialException('write failed (select)')
514 d = d[n:]
515 tx_len -= n
516 except OSError, v:
517 if v.errno != errno.EAGAIN:
518 raise SerialException('write failed: %s' % (v,))
519 return len(data)
521 def flush(self):
522 """Flush of file like objects. In this case, wait until all data
523 is written."""
524 self.drainOutput()
526 def flushInput(self):
527 """Clear input buffer, discarding all that is in the buffer."""
528 if not self._isOpen: raise portNotOpenError
529 termios.tcflush(self.fd, TERMIOS.TCIFLUSH)
531 def flushOutput(self):
532 """Clear output buffer, aborting the current output and
533 discarding all that is in the buffer."""
534 if not self._isOpen: raise portNotOpenError
535 termios.tcflush(self.fd, TERMIOS.TCOFLUSH)
537 def sendBreak(self, duration=0.25):
538 """Send break condition. Timed, returns to idle state after given duration."""
539 if not self._isOpen: raise portNotOpenError
540 termios.tcsendbreak(self.fd, int(duration/0.25))
542 def setBreak(self, level=1):
543 """Set break: Controls TXD. When active, no transmitting is possible."""
544 if self.fd is None: raise portNotOpenError
545 if level:
546 fcntl.ioctl(self.fd, TIOCSBRK)
547 else:
548 fcntl.ioctl(self.fd, TIOCCBRK)
550 def setRTS(self, level=1):
551 """Set terminal status line: Request To Send"""
552 if not self._isOpen: raise portNotOpenError
553 if level:
554 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
555 else:
556 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
558 def setDTR(self, level=1):
559 """Set terminal status line: Data Terminal Ready"""
560 if not self._isOpen: raise portNotOpenError
561 if level:
562 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
563 else:
564 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
566 def getCTS(self):
567 """Read terminal status line: Clear To Send"""
568 if not self._isOpen: raise portNotOpenError
569 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
570 return struct.unpack('I',s)[0] & TIOCM_CTS != 0
572 def getDSR(self):
573 """Read terminal status line: Data Set Ready"""
574 if not self._isOpen: raise portNotOpenError
575 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
576 return struct.unpack('I',s)[0] & TIOCM_DSR != 0
578 def getRI(self):
579 """Read terminal status line: Ring Indicator"""
580 if not self._isOpen: raise portNotOpenError
581 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
582 return struct.unpack('I',s)[0] & TIOCM_RI != 0
584 def getCD(self):
585 """Read terminal status line: Carrier Detect"""
586 if not self._isOpen: raise portNotOpenError
587 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
588 return struct.unpack('I',s)[0] & TIOCM_CD != 0
590 # - - platform specific - - - -
592 def outWaiting(self):
593 """Return the number of characters currently in the output buffer."""
594 #~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str)
595 s = fcntl.ioctl(self.fd, TIOCOUTQ, TIOCM_zero_str)
596 return struct.unpack('I',s)[0]
598 def drainOutput(self):
599 """internal - not portable!"""
600 if not self._isOpen: raise portNotOpenError
601 termios.tcdrain(self.fd)
603 def nonblocking(self):
604 """internal - not portable!"""
605 if not self._isOpen: raise portNotOpenError
606 fcntl.fcntl(self.fd, FCNTL.F_SETFL, os.O_NONBLOCK)
608 def fileno(self):
609 """\
610 For easier use of the serial port instance with select.
611 WARNING: this function is not portable to different platforms!
613 if not self._isOpen: raise portNotOpenError
614 return self.fd
616 def setXON(self, level=True):
617 """\
618 Manually control flow - when software flow control is enabled.
619 This will send XON (true) and XOFF (false) to the other device.
620 WARNING: this function is not portable to different platforms!
622 if not self.hComPort: raise portNotOpenError
623 if enable:
624 termios.tcflow(self.fd, TERMIOS.TCION)
625 else:
626 termios.tcflow(self.fd, TERMIOS.TCIOFF)
628 def flowControlOut(self, enable):
629 """\
630 Manually control flow of outgoing data - when hardware or software flow
631 control is enabled.
632 WARNING: this function is not portable to different platforms!
634 if not self._isOpen: raise portNotOpenError
635 if enable:
636 termios.tcflow(self.fd, TERMIOS.TCOON)
637 else:
638 termios.tcflow(self.fd, TERMIOS.TCOOFF)
641 # assemble Serial class with the platform specifc implementation and the base
642 # for file-like behavior. for Python 2.6 and newer, that provide the new I/O
643 # library, derrive from io.RawIOBase
644 try:
645 import io
646 except ImportError:
647 # classic version with our own file-like emulation
648 class Serial(PosixSerial, FileLike):
649 pass
650 else:
651 # io library present
652 class Serial(PosixSerial, io.RawIOBase):
653 pass
655 class PosixPollSerial(Serial):
656 """poll based read implementation. not all systems support poll properly.
657 however this one has better handling of errors, such as a device
658 disconnecting while it's in use (e.g. USB-serial unplugged)"""
660 def read(self, size=1):
661 """Read size bytes from the serial port. If a timeout is set it may
662 return less characters as requested. With no timeout it will block
663 until the requested number of bytes is read."""
664 if self.fd is None: raise portNotOpenError
665 read = bytearray()
666 poll = select.poll()
667 poll.register(self.fd, select.POLLIN|select.POLLERR|select.POLLHUP|select.POLLNVAL)
668 if size > 0:
669 while len(read) < size:
670 # print "\tread(): size",size, "have", len(read) #debug
671 # wait until device becomes ready to read (or something fails)
672 for fd, event in poll.poll(self._timeout*1000):
673 if event & (select.POLLERR|select.POLLHUP|select.POLLNVAL):
674 raise SerialException('device reports error (poll)')
675 # we don't care if it is select.POLLIN or timeout, that's
676 # handled below
677 buf = os.read(self.fd, size - len(read))
678 read.extend(buf)
679 if ((self._timeout is not None and self._timeout >= 0) or
680 (self._interCharTimeout is not None and self._interCharTimeout > 0)) and not buf:
681 break # early abort on timeout
682 return bytes(read)
685 if __name__ == '__main__':
686 s = Serial(0,
687 baudrate=19200, # baud rate
688 bytesize=EIGHTBITS, # number of data bits
689 parity=PARITY_EVEN, # enable parity checking
690 stopbits=STOPBITS_ONE, # number of stop bits
691 timeout=3, # set a timeout value, None for waiting forever
692 xonxoff=0, # enable software flow control
693 rtscts=0, # enable RTS/CTS flow control
695 s.setRTS(1)
696 s.setDTR(1)
697 s.flushInput()
698 s.flushOutput()
699 s.write('hello')
700 sys.stdout.write('%r\n' % s.read(5))
701 sys.stdout.write('%s\n' % s.inWaiting())
702 del s