blob: 78959ceb322d03acf3d184c1d0fcf41485d8c96a [file] [log] [blame]
cliechti89b4af12002-02-12 23:24:41 +00001#!/usr/bin/env python
cliechti58b481c2009-02-16 20:42:32 +00002#
Chris Liechti3e02f702015-12-16 23:06:04 +01003# backend for serial IO for POSIX compatible systems, like Linux, OSX
cliechti89b4af12002-02-12 23:24:41 +00004#
Chris Liechti3e02f702015-12-16 23:06:04 +01005# This file is part of pySerial. https://github.com/pyserial/pyserial
Chris Liechtie13d0f62016-04-25 23:30:44 +02006# (C) 2001-2016 Chris Liechti <cliechti@gmx.net>
Chris Liechtifbdd8a02015-08-09 02:37:45 +02007#
8# SPDX-License-Identifier: BSD-3-Clause
cliechti89b4af12002-02-12 23:24:41 +00009#
cliechtic54b2c82008-06-21 01:59:08 +000010# parts based on code from Grant B. Edwards <grante@visi.com>:
cliechti89b4af12002-02-12 23:24:41 +000011# ftp://ftp.visi.com/users/grante/python/PosixSerial.py
cliechti53c9fd42009-07-23 23:51:51 +000012#
cliechti89b4af12002-02-12 23:24:41 +000013# references: http://www.easysw.com/~mike/serial/serial.html
14
Chris Liechtie13d0f62016-04-25 23:30:44 +020015# Collection of port names (was previously used by number_to_device which was
16# removed.
17# - Linux /dev/ttyS%d (confirmed)
18# - cygwin/win32 /dev/com%d (confirmed)
19# - openbsd (OpenBSD) /dev/cua%02d
20# - bsd*, freebsd* /dev/cuad%d
21# - darwin (OS X) /dev/cuad%d
22# - netbsd /dev/dty%02d (NetBSD 1.6 testing by Erk)
23# - irix (IRIX) /dev/ttyf%d (partially tested) names depending on flow control
24# - hp (HP-UX) /dev/tty%dp0 (not tested)
25# - sunos (Solaris/SunOS) /dev/tty%c (letters, 'a'..'z') (confirmed)
26# - aix (AIX) /dev/tty%d
27
28
Chris Liechti9eaa40c2016-02-12 23:32:59 +010029# pylint: disable=abstract-method
Chris Liechti33f0ec52015-08-06 16:37:21 +020030import errno
31import fcntl
Chris Liechti33f0ec52015-08-06 16:37:21 +020032import os
33import select
34import struct
35import sys
36import termios
37import time
Chris Liechti033f17c2015-08-30 21:28:04 +020038
39import serial
Chris Liechti935a2622016-08-30 23:39:15 +020040from serial.serialutil import SerialBase, SerialException, to_bytes, \
41 portNotOpenError, writeTimeoutError, Timeout
cliechti89b4af12002-02-12 23:24:41 +000042
cliechti89b4af12002-02-12 23:24:41 +000043
Chris Liechtid6847af2015-08-06 17:54:30 +020044class PlatformSpecificBase(object):
45 BAUDRATE_CONSTANTS = {}
cliechti89b4af12002-02-12 23:24:41 +000046
Chris Liechtid6847af2015-08-06 17:54:30 +020047 def _set_special_baudrate(self, baudrate):
48 raise NotImplementedError('non-standard baudrates are not supported on this platform')
49
50 def _set_rs485_mode(self, rs485_settings):
51 raise NotImplementedError('RS485 not supported on this platform')
52
Chris Liechti6dc58e82016-08-29 23:02:13 +020053
54# some systems support an extra flag to enable the two in POSIX unsupported
Chris Liechti11538242016-09-06 22:20:09 +020055# paritiy settings for MARK and SPACE
Chris Liechti6dc58e82016-08-29 23:02:13 +020056CMSPAR = 0 # default, for unsupported platforms, override below
57
Chris Liechtid6847af2015-08-06 17:54:30 +020058# try to detect the OS so that a device can be selected...
59# this code block should supply a device() and set_special_baudrate() function
60# for the platform
61plat = sys.platform.lower()
62
Chris Liechtiba45c522016-02-06 23:53:23 +010063if plat[:5] == 'linux': # Linux (confirmed) # noqa
Chris Liechtid6847af2015-08-06 17:54:30 +020064 import array
65
Chris Liechti6dc58e82016-08-29 23:02:13 +020066 # extra termios flags
67 CMSPAR = 0o10000000000 # Use "stick" (mark/space) parity
68
Chris Liechtid6847af2015-08-06 17:54:30 +020069 # baudrate ioctls
70 TCGETS2 = 0x802C542A
71 TCSETS2 = 0x402C542B
72 BOTHER = 0o010000
73
74 # RS485 ioctls
75 TIOCGRS485 = 0x542E
76 TIOCSRS485 = 0x542F
Chris Liechti033f17c2015-08-30 21:28:04 +020077 SER_RS485_ENABLED = 0b00000001
78 SER_RS485_RTS_ON_SEND = 0b00000010
Chris Liechtid6847af2015-08-06 17:54:30 +020079 SER_RS485_RTS_AFTER_SEND = 0b00000100
Chris Liechti033f17c2015-08-30 21:28:04 +020080 SER_RS485_RX_DURING_TX = 0b00010000
Chris Liechtid6847af2015-08-06 17:54:30 +020081
82 class PlatformSpecific(PlatformSpecificBase):
83 BAUDRATE_CONSTANTS = {
84 0: 0o000000, # hang up
85 50: 0o000001,
86 75: 0o000002,
87 110: 0o000003,
88 134: 0o000004,
89 150: 0o000005,
90 200: 0o000006,
91 300: 0o000007,
92 600: 0o000010,
93 1200: 0o000011,
94 1800: 0o000012,
95 2400: 0o000013,
96 4800: 0o000014,
97 9600: 0o000015,
98 19200: 0o000016,
99 38400: 0o000017,
100 57600: 0o010001,
101 115200: 0o010002,
102 230400: 0o010003,
103 460800: 0o010004,
104 500000: 0o010005,
105 576000: 0o010006,
106 921600: 0o010007,
107 1000000: 0o010010,
108 1152000: 0o010011,
109 1500000: 0o010012,
110 2000000: 0o010013,
111 2500000: 0o010014,
112 3000000: 0o010015,
113 3500000: 0o010016,
114 4000000: 0o010017
115 }
116
Chris Liechtid6847af2015-08-06 17:54:30 +0200117 def _set_special_baudrate(self, baudrate):
118 # right size is 44 on x86_64, allow for some growth
119 buf = array.array('i', [0] * 64)
120 try:
121 # get serial_struct
122 fcntl.ioctl(self.fd, TCGETS2, buf)
123 # set custom speed
124 buf[2] &= ~termios.CBAUD
125 buf[2] |= BOTHER
126 buf[9] = buf[10] = baudrate
127
128 # set serial_struct
Chris Liechti033f17c2015-08-30 21:28:04 +0200129 fcntl.ioctl(self.fd, TCSETS2, buf)
Chris Liechtid6847af2015-08-06 17:54:30 +0200130 except IOError as e:
Chris Liechti984c5c52016-02-15 23:48:45 +0100131 raise ValueError('Failed to set custom baud rate ({}): {}'.format(baudrate, e))
Chris Liechtid6847af2015-08-06 17:54:30 +0200132
133 def _set_rs485_mode(self, rs485_settings):
Chris Liechti033f17c2015-08-30 21:28:04 +0200134 buf = array.array('i', [0] * 8) # flags, delaytx, delayrx, padding
Chris Liechtid6847af2015-08-06 17:54:30 +0200135 try:
136 fcntl.ioctl(self.fd, TIOCGRS485, buf)
Chris Liechti7a554462016-03-24 21:17:22 +0100137 buf[0] |= SER_RS485_ENABLED
Chris Liechtid6847af2015-08-06 17:54:30 +0200138 if rs485_settings is not None:
139 if rs485_settings.loopback:
140 buf[0] |= SER_RS485_RX_DURING_TX
141 else:
142 buf[0] &= ~SER_RS485_RX_DURING_TX
143 if rs485_settings.rts_level_for_tx:
144 buf[0] |= SER_RS485_RTS_ON_SEND
145 else:
146 buf[0] &= ~SER_RS485_RTS_ON_SEND
147 if rs485_settings.rts_level_for_rx:
148 buf[0] |= SER_RS485_RTS_AFTER_SEND
149 else:
150 buf[0] &= ~SER_RS485_RTS_AFTER_SEND
Chris Liechti279201b2016-06-09 20:27:05 +0200151 if rs485_settings.delay_before_tx is not None:
152 buf[1] = int(rs485_settings.delay_before_tx * 1000)
153 if rs485_settings.delay_before_rx is not None:
154 buf[2] = int(rs485_settings.delay_before_rx * 1000)
Chris Liechtid6847af2015-08-06 17:54:30 +0200155 else:
156 buf[0] = 0 # clear SER_RS485_ENABLED
Chris Liechti033f17c2015-08-30 21:28:04 +0200157 fcntl.ioctl(self.fd, TIOCSRS485, buf)
Chris Liechtid6847af2015-08-06 17:54:30 +0200158 except IOError as e:
Chris Liechti984c5c52016-02-15 23:48:45 +0100159 raise ValueError('Failed to set RS485 mode: {}'.format(e))
Chris Liechtid6847af2015-08-06 17:54:30 +0200160
161
162elif plat == 'cygwin': # cygwin/win32 (confirmed)
163
164 class PlatformSpecific(PlatformSpecificBase):
165 BAUDRATE_CONSTANTS = {
166 128000: 0x01003,
167 256000: 0x01005,
168 500000: 0x01007,
169 576000: 0x01008,
170 921600: 0x01009,
171 1000000: 0x0100a,
172 1152000: 0x0100b,
173 1500000: 0x0100c,
174 2000000: 0x0100d,
175 2500000: 0x0100e,
176 3000000: 0x0100f
177 }
178
Chris Liechtid6847af2015-08-06 17:54:30 +0200179
180elif plat[:6] == 'darwin': # OS X
181 import array
Chris Liechti033f17c2015-08-30 21:28:04 +0200182 IOSSIOSPEED = 0x80045402 # _IOW('T', 2, speed_t)
Chris Liechtid6847af2015-08-06 17:54:30 +0200183
184 class PlatformSpecific(PlatformSpecificBase):
Chris Liechtid6847af2015-08-06 17:54:30 +0200185 osx_version = os.uname()[2].split('.')
186 # Tiger or above can support arbitrary serial speeds
187 if int(osx_version[0]) >= 8:
188 def _set_special_baudrate(self, baudrate):
189 # use IOKit-specific call to set up high speeds
190 buf = array.array('i', [baudrate])
191 fcntl.ioctl(self.fd, IOSSIOSPEED, buf, 1)
192
Chris Liechtid6847af2015-08-06 17:54:30 +0200193else:
194 class PlatformSpecific(PlatformSpecificBase):
195 pass
cliechti89b4af12002-02-12 23:24:41 +0000196
cliechti89b4af12002-02-12 23:24:41 +0000197
cliechti58b481c2009-02-16 20:42:32 +0000198# load some constants for later use.
Chris Liechti11465c82015-08-04 15:55:22 +0200199# try to use values from termios, use defaults from linux otherwise
Chris Liechti033f17c2015-08-30 21:28:04 +0200200TIOCMGET = getattr(termios, 'TIOCMGET', 0x5415)
201TIOCMBIS = getattr(termios, 'TIOCMBIS', 0x5416)
202TIOCMBIC = getattr(termios, 'TIOCMBIC', 0x5417)
203TIOCMSET = getattr(termios, 'TIOCMSET', 0x5418)
cliechti89b4af12002-02-12 23:24:41 +0000204
Chris Liechti033f17c2015-08-30 21:28:04 +0200205# TIOCM_LE = getattr(termios, 'TIOCM_LE', 0x001)
Chris Liechtid6847af2015-08-06 17:54:30 +0200206TIOCM_DTR = getattr(termios, 'TIOCM_DTR', 0x002)
207TIOCM_RTS = getattr(termios, 'TIOCM_RTS', 0x004)
Chris Liechti033f17c2015-08-30 21:28:04 +0200208# TIOCM_ST = getattr(termios, 'TIOCM_ST', 0x008)
209# TIOCM_SR = getattr(termios, 'TIOCM_SR', 0x010)
cliechti89b4af12002-02-12 23:24:41 +0000210
Chris Liechtid6847af2015-08-06 17:54:30 +0200211TIOCM_CTS = getattr(termios, 'TIOCM_CTS', 0x020)
212TIOCM_CAR = getattr(termios, 'TIOCM_CAR', 0x040)
213TIOCM_RNG = getattr(termios, 'TIOCM_RNG', 0x080)
214TIOCM_DSR = getattr(termios, 'TIOCM_DSR', 0x100)
Chris Liechti033f17c2015-08-30 21:28:04 +0200215TIOCM_CD = getattr(termios, 'TIOCM_CD', TIOCM_CAR)
216TIOCM_RI = getattr(termios, 'TIOCM_RI', TIOCM_RNG)
217# TIOCM_OUT1 = getattr(termios, 'TIOCM_OUT1', 0x2000)
218# TIOCM_OUT2 = getattr(termios, 'TIOCM_OUT2', 0x4000)
Chris Liechti11465c82015-08-04 15:55:22 +0200219if hasattr(termios, 'TIOCINQ'):
220 TIOCINQ = termios.TIOCINQ
cliechti28b8fd02011-12-28 21:39:42 +0000221else:
Chris Liechtid6847af2015-08-06 17:54:30 +0200222 TIOCINQ = getattr(termios, 'FIONREAD', 0x541B)
Chris Liechti033f17c2015-08-30 21:28:04 +0200223TIOCOUTQ = getattr(termios, 'TIOCOUTQ', 0x5411)
cliechti89b4af12002-02-12 23:24:41 +0000224
225TIOCM_zero_str = struct.pack('I', 0)
226TIOCM_RTS_str = struct.pack('I', TIOCM_RTS)
227TIOCM_DTR_str = struct.pack('I', TIOCM_DTR)
228
Chris Liechti033f17c2015-08-30 21:28:04 +0200229TIOCSBRK = getattr(termios, 'TIOCSBRK', 0x5427)
230TIOCCBRK = getattr(termios, 'TIOCCBRK', 0x5428)
cliechti997b63c2008-06-21 00:09:31 +0000231
cliechti89b4af12002-02-12 23:24:41 +0000232
Chris Liechtief6b7b42015-08-06 22:19:26 +0200233class Serial(SerialBase, PlatformSpecific):
cliechti7d448562014-08-03 21:57:45 +0000234 """\
Chris Liechti033f17c2015-08-30 21:28:04 +0200235 Serial port class POSIX implementation. Serial port configuration is
cliechtid6bf52c2003-10-01 02:28:12 +0000236 done with termios and fcntl. Runs on Linux and many other Un*x like
cliechtif0a81d42014-08-04 14:03:53 +0000237 systems.
238 """
cliechtid6bf52c2003-10-01 02:28:12 +0000239
240 def open(self):
cliechti7d448562014-08-03 21:57:45 +0000241 """\
242 Open port with current settings. This may throw a SerialException
243 if the port cannot be opened."""
cliechtid6bf52c2003-10-01 02:28:12 +0000244 if self._port is None:
245 raise SerialException("Port must be configured before it can be used.")
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200246 if self.is_open:
cliechti02ef43a2011-03-24 23:33:12 +0000247 raise SerialException("Port is already open.")
248 self.fd = None
cliechti58b481c2009-02-16 20:42:32 +0000249 # open
cliechti4616bf12002-04-08 23:13:14 +0000250 try:
Chris Liechti033f17c2015-08-30 21:28:04 +0200251 self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
Chris Liechti68340d72015-08-03 14:15:48 +0200252 except OSError as msg:
cliechti4616bf12002-04-08 23:13:14 +0000253 self.fd = None
Chris Liechti984c5c52016-02-15 23:48:45 +0100254 raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
Chris Liechti11465c82015-08-04 15:55:22 +0200255 #~ fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # set blocking
cliechti58b481c2009-02-16 20:42:32 +0000256
cliechtib2f5fc82006-10-20 00:09:07 +0000257 try:
Chris Liechti94284702015-11-15 01:21:48 +0100258 self._reconfigure_port(force_update=True)
cliechtib2f5fc82006-10-20 00:09:07 +0000259 except:
cliechti2750b832009-07-28 00:13:52 +0000260 try:
261 os.close(self.fd)
262 except:
263 # ignore any exception when closing the port
264 # also to keep original exception that happened when setting up
265 pass
cliechtib2f5fc82006-10-20 00:09:07 +0000266 self.fd = None
cliechtif0a4f0f2009-07-21 21:12:37 +0000267 raise
cliechtib2f5fc82006-10-20 00:09:07 +0000268 else:
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200269 self.is_open = True
Chris Liechtif2fdeb92016-05-07 23:57:50 +0200270 try:
271 if not self._dsrdtr:
272 self._update_dtr_state()
273 if not self._rtscts:
274 self._update_rts_state()
275 except IOError as e:
Chris Liechti68239372016-06-13 21:22:42 +0200276 if e.errno in (22, 25): # ignore Invalid argument and Inappropriate ioctl
Chris Liechtif2fdeb92016-05-07 23:57:50 +0200277 pass
278 else:
279 raise
Chris Liechtief1fe252015-08-27 23:25:21 +0200280 self.reset_input_buffer()
Chris Liechti42ab2b42016-05-15 23:35:05 +0200281 self.pipe_abort_read_r, self.pipe_abort_read_w = os.pipe()
Chris Liechti13949c62016-05-16 22:45:38 +0200282 self.pipe_abort_write_r, self.pipe_abort_write_w = os.pipe()
Chris Liechti68cecce2016-06-03 23:52:34 +0200283 fcntl.fcntl(self.pipe_abort_read_r, fcntl.F_SETFL, os.O_NONBLOCK)
284 fcntl.fcntl(self.pipe_abort_write_r, fcntl.F_SETFL, os.O_NONBLOCK)
cliechti58b481c2009-02-16 20:42:32 +0000285
Chris Liechti94284702015-11-15 01:21:48 +0100286 def _reconfigure_port(self, force_update=False):
cliechtib2f5fc82006-10-20 00:09:07 +0000287 """Set communication parameters on opened port."""
cliechtic6178262004-03-22 22:04:52 +0000288 if self.fd is None:
cliechtia9a093e2010-01-02 03:05:08 +0000289 raise SerialException("Can only operate on a valid file descriptor")
cliechtie8c45422008-06-20 23:23:14 +0000290 custom_baud = None
cliechti58b481c2009-02-16 20:42:32 +0000291
cliechti2750b832009-07-28 00:13:52 +0000292 vmin = vtime = 0 # timeout is done via select
Chris Liechti518b0d32015-08-30 02:20:39 +0200293 if self._inter_byte_timeout is not None:
cliechti679bfa62008-06-20 23:58:15 +0000294 vmin = 1
Chris Liechti518b0d32015-08-30 02:20:39 +0200295 vtime = int(self._inter_byte_timeout * 10)
cliechti6ce7ab12002-11-07 02:15:00 +0000296 try:
cliechti4d0af5e2011-08-05 02:18:16 +0000297 orig_attr = termios.tcgetattr(self.fd)
298 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
Chris Liechti68340d72015-08-03 14:15:48 +0200299 except termios.error as msg: # if a port is nonexistent but has a /dev file, it'll fail here
Chris Liechti984c5c52016-02-15 23:48:45 +0100300 raise SerialException("Could not configure port: {}".format(msg))
cliechti58b481c2009-02-16 20:42:32 +0000301 # set up raw mode / no echo / binary
Chris Liechti033f17c2015-08-30 21:28:04 +0200302 cflag |= (termios.CLOCAL | termios.CREAD)
303 lflag &= ~(termios.ICANON | termios.ECHO | termios.ECHOE |
304 termios.ECHOK | termios.ECHONL |
305 termios.ISIG | termios.IEXTEN) # |termios.ECHOPRT
306 for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk
Chris Liechti11465c82015-08-04 15:55:22 +0200307 if hasattr(termios, flag):
308 lflag &= ~getattr(termios, flag)
cliechti58b481c2009-02-16 20:42:32 +0000309
Chris Liechti033f17c2015-08-30 21:28:04 +0200310 oflag &= ~(termios.OPOST | termios.ONLCR | termios.OCRNL)
311 iflag &= ~(termios.INLCR | termios.IGNCR | termios.ICRNL | termios.IGNBRK)
Chris Liechti11465c82015-08-04 15:55:22 +0200312 if hasattr(termios, 'IUCLC'):
313 iflag &= ~termios.IUCLC
314 if hasattr(termios, 'PARMRK'):
315 iflag &= ~termios.PARMRK
cliechti58b481c2009-02-16 20:42:32 +0000316
cliechtif0a4f0f2009-07-21 21:12:37 +0000317 # setup baud rate
cliechti89b4af12002-02-12 23:24:41 +0000318 try:
Chris Liechti984c5c52016-02-15 23:48:45 +0100319 ispeed = ospeed = getattr(termios, 'B{}'.format(self._baudrate))
cliechti895e8302004-04-20 02:40:28 +0000320 except AttributeError:
cliechtif1559d02007-11-08 23:43:58 +0000321 try:
Chris Liechtid6847af2015-08-06 17:54:30 +0200322 ispeed = ospeed = self.BAUDRATE_CONSTANTS[self._baudrate]
cliechtif1559d02007-11-08 23:43:58 +0000323 except KeyError:
cliechtie8c45422008-06-20 23:23:14 +0000324 #~ raise ValueError('Invalid baud rate: %r' % self._baudrate)
cliechtif0a4f0f2009-07-21 21:12:37 +0000325 # may need custom baud rate, it isn't in our list.
Chris Liechti11465c82015-08-04 15:55:22 +0200326 ispeed = ospeed = getattr(termios, 'B38400')
cliechtif0a4f0f2009-07-21 21:12:37 +0000327 try:
Chris Liechti033f17c2015-08-30 21:28:04 +0200328 custom_baud = int(self._baudrate) # store for later
cliechtif0a4f0f2009-07-21 21:12:37 +0000329 except ValueError:
Chris Liechti984c5c52016-02-15 23:48:45 +0100330 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate))
cliechtif0a4f0f2009-07-21 21:12:37 +0000331 else:
332 if custom_baud < 0:
Chris Liechti984c5c52016-02-15 23:48:45 +0100333 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate))
cliechti58b481c2009-02-16 20:42:32 +0000334
335 # setup char len
Chris Liechti11465c82015-08-04 15:55:22 +0200336 cflag &= ~termios.CSIZE
cliechtid6bf52c2003-10-01 02:28:12 +0000337 if self._bytesize == 8:
Chris Liechti11465c82015-08-04 15:55:22 +0200338 cflag |= termios.CS8
cliechtid6bf52c2003-10-01 02:28:12 +0000339 elif self._bytesize == 7:
Chris Liechti11465c82015-08-04 15:55:22 +0200340 cflag |= termios.CS7
cliechtid6bf52c2003-10-01 02:28:12 +0000341 elif self._bytesize == 6:
Chris Liechti11465c82015-08-04 15:55:22 +0200342 cflag |= termios.CS6
cliechtid6bf52c2003-10-01 02:28:12 +0000343 elif self._bytesize == 5:
Chris Liechti11465c82015-08-04 15:55:22 +0200344 cflag |= termios.CS5
cliechti89b4af12002-02-12 23:24:41 +0000345 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100346 raise ValueError('Invalid char len: {!r}'.format(self._bytesize))
cliechtif0a81d42014-08-04 14:03:53 +0000347 # setup stop bits
Chris Liechti033f17c2015-08-30 21:28:04 +0200348 if self._stopbits == serial.STOPBITS_ONE:
Chris Liechti11465c82015-08-04 15:55:22 +0200349 cflag &= ~(termios.CSTOPB)
Chris Liechti033f17c2015-08-30 21:28:04 +0200350 elif self._stopbits == serial.STOPBITS_ONE_POINT_FIVE:
351 cflag |= (termios.CSTOPB) # XXX same as TWO.. there is no POSIX support for 1.5
352 elif self._stopbits == serial.STOPBITS_TWO:
353 cflag |= (termios.CSTOPB)
cliechti89b4af12002-02-12 23:24:41 +0000354 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100355 raise ValueError('Invalid stop bit specification: {!r}'.format(self._stopbits))
cliechti58b481c2009-02-16 20:42:32 +0000356 # setup parity
Chris Liechti033f17c2015-08-30 21:28:04 +0200357 iflag &= ~(termios.INPCK | termios.ISTRIP)
358 if self._parity == serial.PARITY_NONE:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200359 cflag &= ~(termios.PARENB | termios.PARODD | CMSPAR)
Chris Liechti033f17c2015-08-30 21:28:04 +0200360 elif self._parity == serial.PARITY_EVEN:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200361 cflag &= ~(termios.PARODD | CMSPAR)
Chris Liechti033f17c2015-08-30 21:28:04 +0200362 cflag |= (termios.PARENB)
363 elif self._parity == serial.PARITY_ODD:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200364 cflag &= ~CMSPAR
Chris Liechti033f17c2015-08-30 21:28:04 +0200365 cflag |= (termios.PARENB | termios.PARODD)
Chris Liechti6dc58e82016-08-29 23:02:13 +0200366 elif self._parity == serial.PARITY_MARK and CMSPAR:
Chris Liechti033f17c2015-08-30 21:28:04 +0200367 cflag |= (termios.PARENB | CMSPAR | termios.PARODD)
Chris Liechti6dc58e82016-08-29 23:02:13 +0200368 elif self._parity == serial.PARITY_SPACE and CMSPAR:
Chris Liechti033f17c2015-08-30 21:28:04 +0200369 cflag |= (termios.PARENB | CMSPAR)
Chris Liechti11465c82015-08-04 15:55:22 +0200370 cflag &= ~(termios.PARODD)
cliechti89b4af12002-02-12 23:24:41 +0000371 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100372 raise ValueError('Invalid parity: {!r}'.format(self._parity))
cliechti58b481c2009-02-16 20:42:32 +0000373 # setup flow control
374 # xonxoff
Chris Liechti11465c82015-08-04 15:55:22 +0200375 if hasattr(termios, 'IXANY'):
cliechtid6bf52c2003-10-01 02:28:12 +0000376 if self._xonxoff:
Chris Liechti033f17c2015-08-30 21:28:04 +0200377 iflag |= (termios.IXON | termios.IXOFF) # |termios.IXANY)
cliechti89b4af12002-02-12 23:24:41 +0000378 else:
Chris Liechti033f17c2015-08-30 21:28:04 +0200379 iflag &= ~(termios.IXON | termios.IXOFF | termios.IXANY)
cliechti89b4af12002-02-12 23:24:41 +0000380 else:
cliechtid6bf52c2003-10-01 02:28:12 +0000381 if self._xonxoff:
Chris Liechti033f17c2015-08-30 21:28:04 +0200382 iflag |= (termios.IXON | termios.IXOFF)
cliechti89b4af12002-02-12 23:24:41 +0000383 else:
Chris Liechti033f17c2015-08-30 21:28:04 +0200384 iflag &= ~(termios.IXON | termios.IXOFF)
cliechti58b481c2009-02-16 20:42:32 +0000385 # rtscts
Chris Liechti11465c82015-08-04 15:55:22 +0200386 if hasattr(termios, 'CRTSCTS'):
cliechtid6bf52c2003-10-01 02:28:12 +0000387 if self._rtscts:
Chris Liechti033f17c2015-08-30 21:28:04 +0200388 cflag |= (termios.CRTSCTS)
cliechti89b4af12002-02-12 23:24:41 +0000389 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200390 cflag &= ~(termios.CRTSCTS)
391 elif hasattr(termios, 'CNEW_RTSCTS'): # try it with alternate constant name
cliechtid6bf52c2003-10-01 02:28:12 +0000392 if self._rtscts:
Chris Liechti033f17c2015-08-30 21:28:04 +0200393 cflag |= (termios.CNEW_RTSCTS)
cliechtid4743692002-04-08 22:39:53 +0000394 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200395 cflag &= ~(termios.CNEW_RTSCTS)
cliechti2750b832009-07-28 00:13:52 +0000396 # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
cliechti58b481c2009-02-16 20:42:32 +0000397
398 # buffer
cliechtif0a81d42014-08-04 14:03:53 +0000399 # vmin "minimal number of characters to be read. 0 for non blocking"
cliechtid6bf52c2003-10-01 02:28:12 +0000400 if vmin < 0 or vmin > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100401 raise ValueError('Invalid vmin: {!r}'.format(vmin))
Chris Liechti11465c82015-08-04 15:55:22 +0200402 cc[termios.VMIN] = vmin
cliechti58b481c2009-02-16 20:42:32 +0000403 # vtime
cliechtid6bf52c2003-10-01 02:28:12 +0000404 if vtime < 0 or vtime > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100405 raise ValueError('Invalid vtime: {!r}'.format(vtime))
Chris Liechti11465c82015-08-04 15:55:22 +0200406 cc[termios.VTIME] = vtime
cliechti58b481c2009-02-16 20:42:32 +0000407 # activate settings
Chris Liechti94284702015-11-15 01:21:48 +0100408 if force_update or [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr:
Chris Liechti033f17c2015-08-30 21:28:04 +0200409 termios.tcsetattr(
Chris Liechti9eaa40c2016-02-12 23:32:59 +0100410 self.fd,
411 termios.TCSANOW,
412 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
cliechti58b481c2009-02-16 20:42:32 +0000413
cliechtie8c45422008-06-20 23:23:14 +0000414 # apply custom baud rate, if any
415 if custom_baud is not None:
Chris Liechtid6847af2015-08-06 17:54:30 +0200416 self._set_special_baudrate(custom_baud)
417
418 if self._rs485_mode is not None:
419 self._set_rs485_mode(self._rs485_mode)
cliechti89b4af12002-02-12 23:24:41 +0000420
421 def close(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000422 """Close port"""
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200423 if self.is_open:
cliechtic6178262004-03-22 22:04:52 +0000424 if self.fd is not None:
cliechtid6bf52c2003-10-01 02:28:12 +0000425 os.close(self.fd)
426 self.fd = None
Chris Liechtib658eac2016-05-22 20:51:44 +0200427 os.close(self.pipe_abort_read_w)
428 os.close(self.pipe_abort_read_r)
429 os.close(self.pipe_abort_write_w)
430 os.close(self.pipe_abort_write_r)
431 self.pipe_abort_read_r, self.pipe_abort_read_w = None, None
432 self.pipe_abort_write_r, self.pipe_abort_write_w = None, None
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200433 self.is_open = False
cliechtid6bf52c2003-10-01 02:28:12 +0000434
435 # - - - - - - - - - - - - - - - - - - - - - - - -
cliechti95c62212002-03-04 22:17:53 +0000436
Chris Liechtief1fe252015-08-27 23:25:21 +0200437 @property
438 def in_waiting(self):
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200439 """Return the number of bytes currently in the input buffer."""
Chris Liechti11465c82015-08-04 15:55:22 +0200440 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str)
cliechtif5831e02002-12-05 23:15:27 +0000441 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200442 return struct.unpack('I', s)[0]
cliechti89b4af12002-02-12 23:24:41 +0000443
cliechtia9a093e2010-01-02 03:05:08 +0000444 # select based implementation, proved to work on many systems
445 def read(self, size=1):
cliechti7d448562014-08-03 21:57:45 +0000446 """\
447 Read size bytes from the serial port. If a timeout is set it may
448 return less characters as requested. With no timeout it will block
449 until the requested number of bytes is read.
450 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200451 if not self.is_open:
452 raise portNotOpenError
cliechtia9a093e2010-01-02 03:05:08 +0000453 read = bytearray()
Chris Liechti935a2622016-08-30 23:39:15 +0200454 timeout = Timeout(self._timeout)
cliechtia9a093e2010-01-02 03:05:08 +0000455 while len(read) < size:
cliechti8d744de2013-10-11 14:31:13 +0000456 try:
Chris Liechti935a2622016-08-30 23:39:15 +0200457 ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
Chris Liechti42ab2b42016-05-15 23:35:05 +0200458 if self.pipe_abort_read_r in ready:
Chris Liechti68cecce2016-06-03 23:52:34 +0200459 os.read(self.pipe_abort_read_r, 1000)
Chris Liechti42ab2b42016-05-15 23:35:05 +0200460 break
cliechti8d744de2013-10-11 14:31:13 +0000461 # If select was used with a timeout, and the timeout occurs, it
462 # returns with empty lists -> thus abort read operation.
Chris Liechti033f17c2015-08-30 21:28:04 +0200463 # For timeout == 0 (non-blocking operation) also abort when
464 # there is nothing to read.
cliechti8d744de2013-10-11 14:31:13 +0000465 if not ready:
466 break # timeout
Chris Liechti033f17c2015-08-30 21:28:04 +0200467 buf = os.read(self.fd, size - len(read))
cliechti8d744de2013-10-11 14:31:13 +0000468 # read should always return some data as select reported it was
469 # ready to read when we get to this point.
470 if not buf:
471 # Disconnected devices, at least on Linux, show the
472 # behavior that they are always ready to read immediately
473 # but reading returns nothing.
Chris Liechti92df95a2016-02-09 23:30:37 +0100474 raise SerialException(
475 'device reports readiness to read but returned no data '
476 '(device disconnected or multiple access on port?)')
cliechti8d744de2013-10-11 14:31:13 +0000477 read.extend(buf)
Chris Liechti68340d72015-08-03 14:15:48 +0200478 except OSError as e:
Chris Liechti033f17c2015-08-30 21:28:04 +0200479 # this is for Python 3.x where select.error is a subclass of
480 # OSError ignore EAGAIN errors. all other errors are shown
nexcvon50ec2232016-05-24 15:48:46 +0800481 if e.errno != errno.EAGAIN and e.errno != errno.EINTR:
Chris Liechti984c5c52016-02-15 23:48:45 +0100482 raise SerialException('read failed: {}'.format(e))
Chris Liechti68340d72015-08-03 14:15:48 +0200483 except select.error as e:
cliechtic7cd7212014-08-03 21:34:38 +0000484 # this is for Python 2.x
cliechti8d744de2013-10-11 14:31:13 +0000485 # ignore EAGAIN errors. all other errors are shown
486 # see also http://www.python.org/dev/peps/pep-3151/#select
487 if e[0] != errno.EAGAIN:
Chris Liechti984c5c52016-02-15 23:48:45 +0100488 raise SerialException('read failed: {}'.format(e))
Chris Liechti935a2622016-08-30 23:39:15 +0200489 if timeout.expired():
490 break
cliechtia9a093e2010-01-02 03:05:08 +0000491 return bytes(read)
cliechti89b4af12002-02-12 23:24:41 +0000492
Chris Liechti42ab2b42016-05-15 23:35:05 +0200493 def cancel_read(self):
494 os.write(self.pipe_abort_read_w, b"x")
495
Chris Liechti13949c62016-05-16 22:45:38 +0200496 def cancel_write(self):
497 os.write(self.pipe_abort_write_w, b"x")
498
cliechti4a567a02009-07-27 22:09:31 +0000499 def write(self, data):
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200500 """Output the given byte string over the serial port."""
Chris Liechti033f17c2015-08-30 21:28:04 +0200501 if not self.is_open:
502 raise portNotOpenError
cliechti38077122013-10-16 02:57:27 +0000503 d = to_bytes(data)
504 tx_len = len(d)
Chris Liechti935a2622016-08-30 23:39:15 +0200505 timeout = Timeout(self._write_timeout)
cliechti9f7c2352013-10-11 01:13:46 +0000506 while tx_len > 0:
cliechti5d4d0bd2004-11-13 03:27:39 +0000507 try:
cliechti5d4d0bd2004-11-13 03:27:39 +0000508 n = os.write(self.fd, d)
Chris Liechti935a2622016-08-30 23:39:15 +0200509 if timeout.is_non_blocking:
Robert Smallshire325a7382016-03-25 21:18:38 +0100510 # Zero timeout indicates non-blocking - simply return the
511 # number of bytes of data actually written
512 return n
Chris Liechti935a2622016-08-30 23:39:15 +0200513 elif not timeout.is_infinite:
cliechti3cf46d62009-08-07 00:19:57 +0000514 # when timeout is set, use select to wait for being ready
515 # with the time left as timeout
Chris Liechti935a2622016-08-30 23:39:15 +0200516 if timeout.expired():
cliechti3cf46d62009-08-07 00:19:57 +0000517 raise writeTimeoutError
Chris Liechti935a2622016-08-30 23:39:15 +0200518 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], timeout.time_left())
Chris Liechti13949c62016-05-16 22:45:38 +0200519 if abort:
Chris Liechti68cecce2016-06-03 23:52:34 +0200520 os.read(self.pipe_abort_write_r, 1000)
Chris Liechti13949c62016-05-16 22:45:38 +0200521 break
cliechti5d4d0bd2004-11-13 03:27:39 +0000522 if not ready:
523 raise writeTimeoutError
cliechti88c62442013-10-12 04:03:16 +0000524 else:
Chris Liechti935a2622016-08-30 23:39:15 +0200525 assert timeout.time_left() is None
cliechti88c62442013-10-12 04:03:16 +0000526 # wait for write operation
Chris Liechti13949c62016-05-16 22:45:38 +0200527 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], None)
528 if abort:
529 os.read(self.pipe_abort_write_r, 1)
530 break
cliechti88c62442013-10-12 04:03:16 +0000531 if not ready:
532 raise SerialException('write failed (select)')
cliechti5d4d0bd2004-11-13 03:27:39 +0000533 d = d[n:]
cliechti9f7c2352013-10-11 01:13:46 +0000534 tx_len -= n
Chris Liechti675f7e12015-08-03 15:48:41 +0200535 except SerialException:
536 raise
Chris Liechti68340d72015-08-03 14:15:48 +0200537 except OSError as v:
cliechti5d4d0bd2004-11-13 03:27:39 +0000538 if v.errno != errno.EAGAIN:
Chris Liechti984c5c52016-02-15 23:48:45 +0100539 raise SerialException('write failed: {}'.format(v))
Chris Liechtic6362db2015-12-13 23:44:35 +0100540 # still calculate and check timeout
Chris Liechti935a2622016-08-30 23:39:15 +0200541 if timeout.expired():
Chris Liechtic6362db2015-12-13 23:44:35 +0100542 raise writeTimeoutError
cliechtif81362e2009-07-25 03:44:33 +0000543 return len(data)
cliechtid6bf52c2003-10-01 02:28:12 +0000544
cliechtia30a8a02003-10-05 12:28:13 +0000545 def flush(self):
cliechti7d448562014-08-03 21:57:45 +0000546 """\
547 Flush of file like objects. In this case, wait until all data
548 is written.
549 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200550 if not self.is_open:
551 raise portNotOpenError
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200552 termios.tcdrain(self.fd)
cliechtia30a8a02003-10-05 12:28:13 +0000553
Chris Liechtief1fe252015-08-27 23:25:21 +0200554 def reset_input_buffer(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000555 """Clear input buffer, discarding all that is in the buffer."""
Chris Liechti033f17c2015-08-30 21:28:04 +0200556 if not self.is_open:
557 raise portNotOpenError
Chris Liechti11465c82015-08-04 15:55:22 +0200558 termios.tcflush(self.fd, termios.TCIFLUSH)
cliechti89b4af12002-02-12 23:24:41 +0000559
Chris Liechtief1fe252015-08-27 23:25:21 +0200560 def reset_output_buffer(self):
cliechti7d448562014-08-03 21:57:45 +0000561 """\
562 Clear output buffer, aborting the current output and discarding all
563 that is in the buffer.
564 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200565 if not self.is_open:
566 raise portNotOpenError
Chris Liechti11465c82015-08-04 15:55:22 +0200567 termios.tcflush(self.fd, termios.TCOFLUSH)
cliechti89b4af12002-02-12 23:24:41 +0000568
Chris Liechtief1fe252015-08-27 23:25:21 +0200569 def send_break(self, duration=0.25):
cliechti7d448562014-08-03 21:57:45 +0000570 """\
571 Send break condition. Timed, returns to idle state after given
572 duration.
573 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200574 if not self.is_open:
575 raise portNotOpenError
576 termios.tcsendbreak(self.fd, int(duration / 0.25))
cliechti89b4af12002-02-12 23:24:41 +0000577
Chris Liechtief1fe252015-08-27 23:25:21 +0200578 def _update_break_state(self):
cliechti7d448562014-08-03 21:57:45 +0000579 """\
580 Set break: Controls TXD. When active, no transmitting is possible.
581 """
Chris Liechtief1fe252015-08-27 23:25:21 +0200582 if self._break_state:
cliechti997b63c2008-06-21 00:09:31 +0000583 fcntl.ioctl(self.fd, TIOCSBRK)
584 else:
585 fcntl.ioctl(self.fd, TIOCCBRK)
586
Chris Liechtief1fe252015-08-27 23:25:21 +0200587 def _update_rts_state(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000588 """Set terminal status line: Request To Send"""
Chris Liechtif7534c82016-05-07 23:35:54 +0200589 if self._rts_state:
590 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
591 else:
592 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
cliechtid6bf52c2003-10-01 02:28:12 +0000593
Chris Liechtief1fe252015-08-27 23:25:21 +0200594 def _update_dtr_state(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000595 """Set terminal status line: Data Terminal Ready"""
Chris Liechtif7534c82016-05-07 23:35:54 +0200596 if self._dtr_state:
597 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
598 else:
599 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
cliechtid6bf52c2003-10-01 02:28:12 +0000600
Chris Liechtief1fe252015-08-27 23:25:21 +0200601 @property
602 def cts(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000603 """Read terminal status line: Clear To Send"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200604 if not self.is_open:
605 raise portNotOpenError
cliechtid6bf52c2003-10-01 02:28:12 +0000606 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200607 return struct.unpack('I', s)[0] & TIOCM_CTS != 0
cliechtid6bf52c2003-10-01 02:28:12 +0000608
Chris Liechtief1fe252015-08-27 23:25:21 +0200609 @property
610 def dsr(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000611 """Read terminal status line: Data Set Ready"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200612 if not self.is_open:
613 raise portNotOpenError
cliechtid6bf52c2003-10-01 02:28:12 +0000614 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200615 return struct.unpack('I', s)[0] & TIOCM_DSR != 0
cliechtid6bf52c2003-10-01 02:28:12 +0000616
Chris Liechtief1fe252015-08-27 23:25:21 +0200617 @property
618 def ri(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000619 """Read terminal status line: Ring Indicator"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200620 if not self.is_open:
621 raise portNotOpenError
cliechti89b4af12002-02-12 23:24:41 +0000622 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200623 return struct.unpack('I', s)[0] & TIOCM_RI != 0
cliechti89b4af12002-02-12 23:24:41 +0000624
Chris Liechtief1fe252015-08-27 23:25:21 +0200625 @property
626 def cd(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000627 """Read terminal status line: Carrier Detect"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200628 if not self.is_open:
629 raise portNotOpenError
cliechti89b4af12002-02-12 23:24:41 +0000630 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200631 return struct.unpack('I', s)[0] & TIOCM_CD != 0
cliechti89b4af12002-02-12 23:24:41 +0000632
cliechtia30a8a02003-10-05 12:28:13 +0000633 # - - platform specific - - - -
634
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200635 @property
636 def out_waiting(self):
637 """Return the number of bytes currently in the output buffer."""
Chris Liechti11465c82015-08-04 15:55:22 +0200638 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str)
cliechti28b8fd02011-12-28 21:39:42 +0000639 s = fcntl.ioctl(self.fd, TIOCOUTQ, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200640 return struct.unpack('I', s)[0]
cliechti28b8fd02011-12-28 21:39:42 +0000641
cliechti8753bbc2005-01-15 20:32:51 +0000642 def fileno(self):
cliechti2f0f8a32011-12-28 22:10:00 +0000643 """\
644 For easier use of the serial port instance with select.
645 WARNING: this function is not portable to different platforms!
646 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200647 if not self.is_open:
648 raise portNotOpenError
cliechti8753bbc2005-01-15 20:32:51 +0000649 return self.fd
cliechti89b4af12002-02-12 23:24:41 +0000650
Chris Liechti518b0d32015-08-30 02:20:39 +0200651 def set_input_flow_control(self, enable=True):
cliechti2f0f8a32011-12-28 22:10:00 +0000652 """\
653 Manually control flow - when software flow control is enabled.
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200654 This will send XON (true) or XOFF (false) to the other device.
cliechti2f0f8a32011-12-28 22:10:00 +0000655 WARNING: this function is not portable to different platforms!
656 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200657 if not self.is_open:
658 raise portNotOpenError
cliechti4a601342011-12-29 02:22:17 +0000659 if enable:
Chris Liechti11465c82015-08-04 15:55:22 +0200660 termios.tcflow(self.fd, termios.TCION)
cliechti57e48a62009-08-03 22:29:58 +0000661 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200662 termios.tcflow(self.fd, termios.TCIOFF)
cliechti57e48a62009-08-03 22:29:58 +0000663
Chris Liechti518b0d32015-08-30 02:20:39 +0200664 def set_output_flow_control(self, enable=True):
cliechti2f0f8a32011-12-28 22:10:00 +0000665 """\
666 Manually control flow of outgoing data - when hardware or software flow
667 control is enabled.
668 WARNING: this function is not portable to different platforms!
669 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200670 if not self.is_open:
671 raise portNotOpenError
cliechti2f0f8a32011-12-28 22:10:00 +0000672 if enable:
Chris Liechti11465c82015-08-04 15:55:22 +0200673 termios.tcflow(self.fd, termios.TCOON)
cliechti2f0f8a32011-12-28 22:10:00 +0000674 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200675 termios.tcflow(self.fd, termios.TCOOFF)
cliechti2f0f8a32011-12-28 22:10:00 +0000676
Chris Liechti59848422016-06-04 22:28:14 +0200677 def nonblocking(self):
678 """DEPRECATED - has no use"""
679 import warnings
680 warnings.warn("nonblocking() has no effect, already nonblocking", DeprecationWarning)
681
cliechtif81362e2009-07-25 03:44:33 +0000682
cliechtia9a093e2010-01-02 03:05:08 +0000683class PosixPollSerial(Serial):
cliechti7d448562014-08-03 21:57:45 +0000684 """\
cliechtif0a81d42014-08-04 14:03:53 +0000685 Poll based read implementation. Not all systems support poll properly.
686 However this one has better handling of errors, such as a device
cliechti7d448562014-08-03 21:57:45 +0000687 disconnecting while it's in use (e.g. USB-serial unplugged).
688 """
cliechtia9a093e2010-01-02 03:05:08 +0000689
690 def read(self, size=1):
cliechti7d448562014-08-03 21:57:45 +0000691 """\
692 Read size bytes from the serial port. If a timeout is set it may
693 return less characters as requested. With no timeout it will block
694 until the requested number of bytes is read.
695 """
Chris Liechtiacac2362016-03-29 22:37:48 +0200696 if not self.is_open:
Chris Liechti033f17c2015-08-30 21:28:04 +0200697 raise portNotOpenError
cliechtia9a093e2010-01-02 03:05:08 +0000698 read = bytearray()
699 poll = select.poll()
Chris Liechti033f17c2015-08-30 21:28:04 +0200700 poll.register(self.fd, select.POLLIN | select.POLLERR | select.POLLHUP | select.POLLNVAL)
cliechtia9a093e2010-01-02 03:05:08 +0000701 if size > 0:
702 while len(read) < size:
703 # print "\tread(): size",size, "have", len(read) #debug
704 # wait until device becomes ready to read (or something fails)
Chris Liechti033f17c2015-08-30 21:28:04 +0200705 for fd, event in poll.poll(self._timeout * 1000):
706 if event & (select.POLLERR | select.POLLHUP | select.POLLNVAL):
cliechtia9a093e2010-01-02 03:05:08 +0000707 raise SerialException('device reports error (poll)')
708 # we don't care if it is select.POLLIN or timeout, that's
709 # handled below
710 buf = os.read(self.fd, size - len(read))
711 read.extend(buf)
Chris Liechti518b0d32015-08-30 02:20:39 +0200712 if ((self._timeout is not None and self._timeout >= 0) or
Chris Liechti033f17c2015-08-30 21:28:04 +0200713 (self._inter_byte_timeout is not None and self._inter_byte_timeout > 0)) and not buf:
cliechtia9a093e2010-01-02 03:05:08 +0000714 break # early abort on timeout
715 return bytes(read)
716
cliechtif81362e2009-07-25 03:44:33 +0000717
Chris Liechti4cf54702015-10-18 00:21:56 +0200718class VTIMESerial(Serial):
719 """\
720 Implement timeout using vtime of tty device instead of using select.
721 This means that no inter character timeout can be specified and that
722 the error handling is degraded.
723
724 Overall timeout is disabled when inter-character timeout is used.
725 """
726
Chris Liechti94284702015-11-15 01:21:48 +0100727 def _reconfigure_port(self, force_update=True):
Chris Liechti4cf54702015-10-18 00:21:56 +0200728 """Set communication parameters on opened port."""
729 super(VTIMESerial, self)._reconfigure_port()
Chris Liechtid6bcaaf2016-02-01 22:55:26 +0100730 fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # clear O_NONBLOCK
Chris Liechti4cf54702015-10-18 00:21:56 +0200731
732 if self._inter_byte_timeout is not None:
733 vmin = 1
734 vtime = int(self._inter_byte_timeout * 10)
Chris Liechti3ec9c412016-08-08 01:06:46 +0200735 elif self._timeout is None:
736 vmin = 1
737 vtime = 0
Chris Liechti4cf54702015-10-18 00:21:56 +0200738 else:
739 vmin = 0
740 vtime = int(self._timeout * 10)
741 try:
742 orig_attr = termios.tcgetattr(self.fd)
743 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
744 except termios.error as msg: # if a port is nonexistent but has a /dev file, it'll fail here
Chris Liechti984c5c52016-02-15 23:48:45 +0100745 raise serial.SerialException("Could not configure port: {}".format(msg))
Chris Liechti4cf54702015-10-18 00:21:56 +0200746
747 if vtime < 0 or vtime > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100748 raise ValueError('Invalid vtime: {!r}'.format(vtime))
Chris Liechti4cf54702015-10-18 00:21:56 +0200749 cc[termios.VTIME] = vtime
750 cc[termios.VMIN] = vmin
751
752 termios.tcsetattr(
753 self.fd,
754 termios.TCSANOW,
755 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
756
Chris Liechti4cf54702015-10-18 00:21:56 +0200757 def read(self, size=1):
758 """\
759 Read size bytes from the serial port. If a timeout is set it may
760 return less characters as requested. With no timeout it will block
761 until the requested number of bytes is read.
762 """
763 if not self.is_open:
764 raise portNotOpenError
765 read = bytearray()
766 while len(read) < size:
767 buf = os.read(self.fd, size - len(read))
768 if not buf:
769 break
770 read.extend(buf)
771 return bytes(read)
Chris Liechti3ec9c412016-08-08 01:06:46 +0200772
773 # hack to make hasattr return false
774 cancel_read = property()