blob: 35eb858a6f7b6588037f015a8daadda81a2c2329 [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 Liechtie1029622016-10-02 23:54:36 +0200276 if e.errno in (errno.EINVAL, errno.ENOTTY):
277 # ignore Invalid argument and Inappropriate ioctl
Chris Liechtif2fdeb92016-05-07 23:57:50 +0200278 pass
279 else:
280 raise
Chris Liechtief1fe252015-08-27 23:25:21 +0200281 self.reset_input_buffer()
Chris Liechti42ab2b42016-05-15 23:35:05 +0200282 self.pipe_abort_read_r, self.pipe_abort_read_w = os.pipe()
Chris Liechti13949c62016-05-16 22:45:38 +0200283 self.pipe_abort_write_r, self.pipe_abort_write_w = os.pipe()
Chris Liechti68cecce2016-06-03 23:52:34 +0200284 fcntl.fcntl(self.pipe_abort_read_r, fcntl.F_SETFL, os.O_NONBLOCK)
285 fcntl.fcntl(self.pipe_abort_write_r, fcntl.F_SETFL, os.O_NONBLOCK)
cliechti58b481c2009-02-16 20:42:32 +0000286
Chris Liechti94284702015-11-15 01:21:48 +0100287 def _reconfigure_port(self, force_update=False):
cliechtib2f5fc82006-10-20 00:09:07 +0000288 """Set communication parameters on opened port."""
cliechtic6178262004-03-22 22:04:52 +0000289 if self.fd is None:
cliechtia9a093e2010-01-02 03:05:08 +0000290 raise SerialException("Can only operate on a valid file descriptor")
cliechtie8c45422008-06-20 23:23:14 +0000291 custom_baud = None
cliechti58b481c2009-02-16 20:42:32 +0000292
cliechti2750b832009-07-28 00:13:52 +0000293 vmin = vtime = 0 # timeout is done via select
Chris Liechti518b0d32015-08-30 02:20:39 +0200294 if self._inter_byte_timeout is not None:
cliechti679bfa62008-06-20 23:58:15 +0000295 vmin = 1
Chris Liechti518b0d32015-08-30 02:20:39 +0200296 vtime = int(self._inter_byte_timeout * 10)
cliechti6ce7ab12002-11-07 02:15:00 +0000297 try:
cliechti4d0af5e2011-08-05 02:18:16 +0000298 orig_attr = termios.tcgetattr(self.fd)
299 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
Chris Liechti68340d72015-08-03 14:15:48 +0200300 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 +0100301 raise SerialException("Could not configure port: {}".format(msg))
cliechti58b481c2009-02-16 20:42:32 +0000302 # set up raw mode / no echo / binary
Chris Liechti033f17c2015-08-30 21:28:04 +0200303 cflag |= (termios.CLOCAL | termios.CREAD)
304 lflag &= ~(termios.ICANON | termios.ECHO | termios.ECHOE |
305 termios.ECHOK | termios.ECHONL |
306 termios.ISIG | termios.IEXTEN) # |termios.ECHOPRT
307 for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk
Chris Liechti11465c82015-08-04 15:55:22 +0200308 if hasattr(termios, flag):
309 lflag &= ~getattr(termios, flag)
cliechti58b481c2009-02-16 20:42:32 +0000310
Chris Liechti033f17c2015-08-30 21:28:04 +0200311 oflag &= ~(termios.OPOST | termios.ONLCR | termios.OCRNL)
312 iflag &= ~(termios.INLCR | termios.IGNCR | termios.ICRNL | termios.IGNBRK)
Chris Liechti11465c82015-08-04 15:55:22 +0200313 if hasattr(termios, 'IUCLC'):
314 iflag &= ~termios.IUCLC
315 if hasattr(termios, 'PARMRK'):
316 iflag &= ~termios.PARMRK
cliechti58b481c2009-02-16 20:42:32 +0000317
cliechtif0a4f0f2009-07-21 21:12:37 +0000318 # setup baud rate
cliechti89b4af12002-02-12 23:24:41 +0000319 try:
Chris Liechti984c5c52016-02-15 23:48:45 +0100320 ispeed = ospeed = getattr(termios, 'B{}'.format(self._baudrate))
cliechti895e8302004-04-20 02:40:28 +0000321 except AttributeError:
cliechtif1559d02007-11-08 23:43:58 +0000322 try:
Chris Liechtid6847af2015-08-06 17:54:30 +0200323 ispeed = ospeed = self.BAUDRATE_CONSTANTS[self._baudrate]
cliechtif1559d02007-11-08 23:43:58 +0000324 except KeyError:
cliechtie8c45422008-06-20 23:23:14 +0000325 #~ raise ValueError('Invalid baud rate: %r' % self._baudrate)
cliechtif0a4f0f2009-07-21 21:12:37 +0000326 # may need custom baud rate, it isn't in our list.
Chris Liechti11465c82015-08-04 15:55:22 +0200327 ispeed = ospeed = getattr(termios, 'B38400')
cliechtif0a4f0f2009-07-21 21:12:37 +0000328 try:
Chris Liechti033f17c2015-08-30 21:28:04 +0200329 custom_baud = int(self._baudrate) # store for later
cliechtif0a4f0f2009-07-21 21:12:37 +0000330 except ValueError:
Chris Liechti984c5c52016-02-15 23:48:45 +0100331 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate))
cliechtif0a4f0f2009-07-21 21:12:37 +0000332 else:
333 if custom_baud < 0:
Chris Liechti984c5c52016-02-15 23:48:45 +0100334 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate))
cliechti58b481c2009-02-16 20:42:32 +0000335
336 # setup char len
Chris Liechti11465c82015-08-04 15:55:22 +0200337 cflag &= ~termios.CSIZE
cliechtid6bf52c2003-10-01 02:28:12 +0000338 if self._bytesize == 8:
Chris Liechti11465c82015-08-04 15:55:22 +0200339 cflag |= termios.CS8
cliechtid6bf52c2003-10-01 02:28:12 +0000340 elif self._bytesize == 7:
Chris Liechti11465c82015-08-04 15:55:22 +0200341 cflag |= termios.CS7
cliechtid6bf52c2003-10-01 02:28:12 +0000342 elif self._bytesize == 6:
Chris Liechti11465c82015-08-04 15:55:22 +0200343 cflag |= termios.CS6
cliechtid6bf52c2003-10-01 02:28:12 +0000344 elif self._bytesize == 5:
Chris Liechti11465c82015-08-04 15:55:22 +0200345 cflag |= termios.CS5
cliechti89b4af12002-02-12 23:24:41 +0000346 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100347 raise ValueError('Invalid char len: {!r}'.format(self._bytesize))
cliechtif0a81d42014-08-04 14:03:53 +0000348 # setup stop bits
Chris Liechti033f17c2015-08-30 21:28:04 +0200349 if self._stopbits == serial.STOPBITS_ONE:
Chris Liechti11465c82015-08-04 15:55:22 +0200350 cflag &= ~(termios.CSTOPB)
Chris Liechti033f17c2015-08-30 21:28:04 +0200351 elif self._stopbits == serial.STOPBITS_ONE_POINT_FIVE:
352 cflag |= (termios.CSTOPB) # XXX same as TWO.. there is no POSIX support for 1.5
353 elif self._stopbits == serial.STOPBITS_TWO:
354 cflag |= (termios.CSTOPB)
cliechti89b4af12002-02-12 23:24:41 +0000355 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100356 raise ValueError('Invalid stop bit specification: {!r}'.format(self._stopbits))
cliechti58b481c2009-02-16 20:42:32 +0000357 # setup parity
Chris Liechti033f17c2015-08-30 21:28:04 +0200358 iflag &= ~(termios.INPCK | termios.ISTRIP)
359 if self._parity == serial.PARITY_NONE:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200360 cflag &= ~(termios.PARENB | termios.PARODD | CMSPAR)
Chris Liechti033f17c2015-08-30 21:28:04 +0200361 elif self._parity == serial.PARITY_EVEN:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200362 cflag &= ~(termios.PARODD | CMSPAR)
Chris Liechti033f17c2015-08-30 21:28:04 +0200363 cflag |= (termios.PARENB)
364 elif self._parity == serial.PARITY_ODD:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200365 cflag &= ~CMSPAR
Chris Liechti033f17c2015-08-30 21:28:04 +0200366 cflag |= (termios.PARENB | termios.PARODD)
Chris Liechti6dc58e82016-08-29 23:02:13 +0200367 elif self._parity == serial.PARITY_MARK and CMSPAR:
Chris Liechti033f17c2015-08-30 21:28:04 +0200368 cflag |= (termios.PARENB | CMSPAR | termios.PARODD)
Chris Liechti6dc58e82016-08-29 23:02:13 +0200369 elif self._parity == serial.PARITY_SPACE and CMSPAR:
Chris Liechti033f17c2015-08-30 21:28:04 +0200370 cflag |= (termios.PARENB | CMSPAR)
Chris Liechti11465c82015-08-04 15:55:22 +0200371 cflag &= ~(termios.PARODD)
cliechti89b4af12002-02-12 23:24:41 +0000372 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100373 raise ValueError('Invalid parity: {!r}'.format(self._parity))
cliechti58b481c2009-02-16 20:42:32 +0000374 # setup flow control
375 # xonxoff
Chris Liechti11465c82015-08-04 15:55:22 +0200376 if hasattr(termios, 'IXANY'):
cliechtid6bf52c2003-10-01 02:28:12 +0000377 if self._xonxoff:
Chris Liechti033f17c2015-08-30 21:28:04 +0200378 iflag |= (termios.IXON | termios.IXOFF) # |termios.IXANY)
cliechti89b4af12002-02-12 23:24:41 +0000379 else:
Chris Liechti033f17c2015-08-30 21:28:04 +0200380 iflag &= ~(termios.IXON | termios.IXOFF | termios.IXANY)
cliechti89b4af12002-02-12 23:24:41 +0000381 else:
cliechtid6bf52c2003-10-01 02:28:12 +0000382 if self._xonxoff:
Chris Liechti033f17c2015-08-30 21:28:04 +0200383 iflag |= (termios.IXON | termios.IXOFF)
cliechti89b4af12002-02-12 23:24:41 +0000384 else:
Chris Liechti033f17c2015-08-30 21:28:04 +0200385 iflag &= ~(termios.IXON | termios.IXOFF)
cliechti58b481c2009-02-16 20:42:32 +0000386 # rtscts
Chris Liechti11465c82015-08-04 15:55:22 +0200387 if hasattr(termios, 'CRTSCTS'):
cliechtid6bf52c2003-10-01 02:28:12 +0000388 if self._rtscts:
Chris Liechti033f17c2015-08-30 21:28:04 +0200389 cflag |= (termios.CRTSCTS)
cliechti89b4af12002-02-12 23:24:41 +0000390 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200391 cflag &= ~(termios.CRTSCTS)
392 elif hasattr(termios, 'CNEW_RTSCTS'): # try it with alternate constant name
cliechtid6bf52c2003-10-01 02:28:12 +0000393 if self._rtscts:
Chris Liechti033f17c2015-08-30 21:28:04 +0200394 cflag |= (termios.CNEW_RTSCTS)
cliechtid4743692002-04-08 22:39:53 +0000395 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200396 cflag &= ~(termios.CNEW_RTSCTS)
cliechti2750b832009-07-28 00:13:52 +0000397 # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
cliechti58b481c2009-02-16 20:42:32 +0000398
399 # buffer
cliechtif0a81d42014-08-04 14:03:53 +0000400 # vmin "minimal number of characters to be read. 0 for non blocking"
cliechtid6bf52c2003-10-01 02:28:12 +0000401 if vmin < 0 or vmin > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100402 raise ValueError('Invalid vmin: {!r}'.format(vmin))
Chris Liechti11465c82015-08-04 15:55:22 +0200403 cc[termios.VMIN] = vmin
cliechti58b481c2009-02-16 20:42:32 +0000404 # vtime
cliechtid6bf52c2003-10-01 02:28:12 +0000405 if vtime < 0 or vtime > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100406 raise ValueError('Invalid vtime: {!r}'.format(vtime))
Chris Liechti11465c82015-08-04 15:55:22 +0200407 cc[termios.VTIME] = vtime
cliechti58b481c2009-02-16 20:42:32 +0000408 # activate settings
Chris Liechti94284702015-11-15 01:21:48 +0100409 if force_update or [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr:
Chris Liechti033f17c2015-08-30 21:28:04 +0200410 termios.tcsetattr(
Chris Liechti9eaa40c2016-02-12 23:32:59 +0100411 self.fd,
412 termios.TCSANOW,
413 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
cliechti58b481c2009-02-16 20:42:32 +0000414
cliechtie8c45422008-06-20 23:23:14 +0000415 # apply custom baud rate, if any
416 if custom_baud is not None:
Chris Liechtid6847af2015-08-06 17:54:30 +0200417 self._set_special_baudrate(custom_baud)
418
419 if self._rs485_mode is not None:
420 self._set_rs485_mode(self._rs485_mode)
cliechti89b4af12002-02-12 23:24:41 +0000421
422 def close(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000423 """Close port"""
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200424 if self.is_open:
cliechtic6178262004-03-22 22:04:52 +0000425 if self.fd is not None:
cliechtid6bf52c2003-10-01 02:28:12 +0000426 os.close(self.fd)
427 self.fd = None
Chris Liechtib658eac2016-05-22 20:51:44 +0200428 os.close(self.pipe_abort_read_w)
429 os.close(self.pipe_abort_read_r)
430 os.close(self.pipe_abort_write_w)
431 os.close(self.pipe_abort_write_r)
432 self.pipe_abort_read_r, self.pipe_abort_read_w = None, None
433 self.pipe_abort_write_r, self.pipe_abort_write_w = None, None
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200434 self.is_open = False
cliechtid6bf52c2003-10-01 02:28:12 +0000435
436 # - - - - - - - - - - - - - - - - - - - - - - - -
cliechti95c62212002-03-04 22:17:53 +0000437
Chris Liechtief1fe252015-08-27 23:25:21 +0200438 @property
439 def in_waiting(self):
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200440 """Return the number of bytes currently in the input buffer."""
Chris Liechti11465c82015-08-04 15:55:22 +0200441 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str)
cliechtif5831e02002-12-05 23:15:27 +0000442 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200443 return struct.unpack('I', s)[0]
cliechti89b4af12002-02-12 23:24:41 +0000444
cliechtia9a093e2010-01-02 03:05:08 +0000445 # select based implementation, proved to work on many systems
446 def read(self, size=1):
cliechti7d448562014-08-03 21:57:45 +0000447 """\
448 Read size bytes from the serial port. If a timeout is set it may
449 return less characters as requested. With no timeout it will block
450 until the requested number of bytes is read.
451 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200452 if not self.is_open:
453 raise portNotOpenError
cliechtia9a093e2010-01-02 03:05:08 +0000454 read = bytearray()
Chris Liechti935a2622016-08-30 23:39:15 +0200455 timeout = Timeout(self._timeout)
cliechtia9a093e2010-01-02 03:05:08 +0000456 while len(read) < size:
cliechti8d744de2013-10-11 14:31:13 +0000457 try:
Chris Liechti935a2622016-08-30 23:39:15 +0200458 ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
Chris Liechti42ab2b42016-05-15 23:35:05 +0200459 if self.pipe_abort_read_r in ready:
Chris Liechti68cecce2016-06-03 23:52:34 +0200460 os.read(self.pipe_abort_read_r, 1000)
Chris Liechti42ab2b42016-05-15 23:35:05 +0200461 break
cliechti8d744de2013-10-11 14:31:13 +0000462 # If select was used with a timeout, and the timeout occurs, it
463 # returns with empty lists -> thus abort read operation.
Chris Liechti033f17c2015-08-30 21:28:04 +0200464 # For timeout == 0 (non-blocking operation) also abort when
465 # there is nothing to read.
cliechti8d744de2013-10-11 14:31:13 +0000466 if not ready:
467 break # timeout
Chris Liechti033f17c2015-08-30 21:28:04 +0200468 buf = os.read(self.fd, size - len(read))
cliechti8d744de2013-10-11 14:31:13 +0000469 # 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.
Chris Liechti92df95a2016-02-09 23:30:37 +0100475 raise SerialException(
476 'device reports readiness to read but returned no data '
477 '(device disconnected or multiple access on port?)')
cliechti8d744de2013-10-11 14:31:13 +0000478 read.extend(buf)
Chris Liechti68340d72015-08-03 14:15:48 +0200479 except OSError as e:
Chris Liechti033f17c2015-08-30 21:28:04 +0200480 # this is for Python 3.x where select.error is a subclass of
481 # OSError ignore EAGAIN errors. all other errors are shown
nexcvon50ec2232016-05-24 15:48:46 +0800482 if e.errno != errno.EAGAIN and e.errno != errno.EINTR:
Chris Liechti984c5c52016-02-15 23:48:45 +0100483 raise SerialException('read failed: {}'.format(e))
Chris Liechti68340d72015-08-03 14:15:48 +0200484 except select.error as e:
cliechtic7cd7212014-08-03 21:34:38 +0000485 # this is for Python 2.x
cliechti8d744de2013-10-11 14:31:13 +0000486 # ignore EAGAIN errors. all other errors are shown
487 # see also http://www.python.org/dev/peps/pep-3151/#select
488 if e[0] != errno.EAGAIN:
Chris Liechti984c5c52016-02-15 23:48:45 +0100489 raise SerialException('read failed: {}'.format(e))
Chris Liechti935a2622016-08-30 23:39:15 +0200490 if timeout.expired():
491 break
cliechtia9a093e2010-01-02 03:05:08 +0000492 return bytes(read)
cliechti89b4af12002-02-12 23:24:41 +0000493
Chris Liechti42ab2b42016-05-15 23:35:05 +0200494 def cancel_read(self):
495 os.write(self.pipe_abort_read_w, b"x")
496
Chris Liechti13949c62016-05-16 22:45:38 +0200497 def cancel_write(self):
498 os.write(self.pipe_abort_write_w, b"x")
499
cliechti4a567a02009-07-27 22:09:31 +0000500 def write(self, data):
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200501 """Output the given byte string over the serial port."""
Chris Liechti033f17c2015-08-30 21:28:04 +0200502 if not self.is_open:
503 raise portNotOpenError
cliechti38077122013-10-16 02:57:27 +0000504 d = to_bytes(data)
505 tx_len = len(d)
Chris Liechti935a2622016-08-30 23:39:15 +0200506 timeout = Timeout(self._write_timeout)
cliechti9f7c2352013-10-11 01:13:46 +0000507 while tx_len > 0:
cliechti5d4d0bd2004-11-13 03:27:39 +0000508 try:
cliechti5d4d0bd2004-11-13 03:27:39 +0000509 n = os.write(self.fd, d)
Chris Liechti935a2622016-08-30 23:39:15 +0200510 if timeout.is_non_blocking:
Robert Smallshire325a7382016-03-25 21:18:38 +0100511 # Zero timeout indicates non-blocking - simply return the
512 # number of bytes of data actually written
513 return n
Chris Liechti935a2622016-08-30 23:39:15 +0200514 elif not timeout.is_infinite:
cliechti3cf46d62009-08-07 00:19:57 +0000515 # when timeout is set, use select to wait for being ready
516 # with the time left as timeout
Chris Liechti935a2622016-08-30 23:39:15 +0200517 if timeout.expired():
cliechti3cf46d62009-08-07 00:19:57 +0000518 raise writeTimeoutError
Chris Liechti935a2622016-08-30 23:39:15 +0200519 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], timeout.time_left())
Chris Liechti13949c62016-05-16 22:45:38 +0200520 if abort:
Chris Liechti68cecce2016-06-03 23:52:34 +0200521 os.read(self.pipe_abort_write_r, 1000)
Chris Liechti13949c62016-05-16 22:45:38 +0200522 break
cliechti5d4d0bd2004-11-13 03:27:39 +0000523 if not ready:
524 raise writeTimeoutError
cliechti88c62442013-10-12 04:03:16 +0000525 else:
Chris Liechti935a2622016-08-30 23:39:15 +0200526 assert timeout.time_left() is None
cliechti88c62442013-10-12 04:03:16 +0000527 # wait for write operation
Chris Liechti13949c62016-05-16 22:45:38 +0200528 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], None)
529 if abort:
530 os.read(self.pipe_abort_write_r, 1)
531 break
cliechti88c62442013-10-12 04:03:16 +0000532 if not ready:
533 raise SerialException('write failed (select)')
cliechti5d4d0bd2004-11-13 03:27:39 +0000534 d = d[n:]
cliechti9f7c2352013-10-11 01:13:46 +0000535 tx_len -= n
Chris Liechti675f7e12015-08-03 15:48:41 +0200536 except SerialException:
537 raise
Chris Liechti68340d72015-08-03 14:15:48 +0200538 except OSError as v:
cliechti5d4d0bd2004-11-13 03:27:39 +0000539 if v.errno != errno.EAGAIN:
Chris Liechti984c5c52016-02-15 23:48:45 +0100540 raise SerialException('write failed: {}'.format(v))
Chris Liechtic6362db2015-12-13 23:44:35 +0100541 # still calculate and check timeout
Chris Liechti935a2622016-08-30 23:39:15 +0200542 if timeout.expired():
Chris Liechtic6362db2015-12-13 23:44:35 +0100543 raise writeTimeoutError
cliechtif81362e2009-07-25 03:44:33 +0000544 return len(data)
cliechtid6bf52c2003-10-01 02:28:12 +0000545
cliechtia30a8a02003-10-05 12:28:13 +0000546 def flush(self):
cliechti7d448562014-08-03 21:57:45 +0000547 """\
548 Flush of file like objects. In this case, wait until all data
549 is written.
550 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200551 if not self.is_open:
552 raise portNotOpenError
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200553 termios.tcdrain(self.fd)
cliechtia30a8a02003-10-05 12:28:13 +0000554
Chris Liechtief1fe252015-08-27 23:25:21 +0200555 def reset_input_buffer(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000556 """Clear input buffer, discarding all that is in the buffer."""
Chris Liechti033f17c2015-08-30 21:28:04 +0200557 if not self.is_open:
558 raise portNotOpenError
Chris Liechti11465c82015-08-04 15:55:22 +0200559 termios.tcflush(self.fd, termios.TCIFLUSH)
cliechti89b4af12002-02-12 23:24:41 +0000560
Chris Liechtief1fe252015-08-27 23:25:21 +0200561 def reset_output_buffer(self):
cliechti7d448562014-08-03 21:57:45 +0000562 """\
563 Clear output buffer, aborting the current output and discarding all
564 that is in the buffer.
565 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200566 if not self.is_open:
567 raise portNotOpenError
Chris Liechti11465c82015-08-04 15:55:22 +0200568 termios.tcflush(self.fd, termios.TCOFLUSH)
cliechti89b4af12002-02-12 23:24:41 +0000569
Chris Liechtief1fe252015-08-27 23:25:21 +0200570 def send_break(self, duration=0.25):
cliechti7d448562014-08-03 21:57:45 +0000571 """\
572 Send break condition. Timed, returns to idle state after given
573 duration.
574 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200575 if not self.is_open:
576 raise portNotOpenError
577 termios.tcsendbreak(self.fd, int(duration / 0.25))
cliechti89b4af12002-02-12 23:24:41 +0000578
Chris Liechtief1fe252015-08-27 23:25:21 +0200579 def _update_break_state(self):
cliechti7d448562014-08-03 21:57:45 +0000580 """\
581 Set break: Controls TXD. When active, no transmitting is possible.
582 """
Chris Liechtief1fe252015-08-27 23:25:21 +0200583 if self._break_state:
cliechti997b63c2008-06-21 00:09:31 +0000584 fcntl.ioctl(self.fd, TIOCSBRK)
585 else:
586 fcntl.ioctl(self.fd, TIOCCBRK)
587
Chris Liechtief1fe252015-08-27 23:25:21 +0200588 def _update_rts_state(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000589 """Set terminal status line: Request To Send"""
Chris Liechtif7534c82016-05-07 23:35:54 +0200590 if self._rts_state:
591 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
592 else:
593 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
cliechtid6bf52c2003-10-01 02:28:12 +0000594
Chris Liechtief1fe252015-08-27 23:25:21 +0200595 def _update_dtr_state(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000596 """Set terminal status line: Data Terminal Ready"""
Chris Liechtif7534c82016-05-07 23:35:54 +0200597 if self._dtr_state:
598 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
599 else:
600 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
cliechtid6bf52c2003-10-01 02:28:12 +0000601
Chris Liechtief1fe252015-08-27 23:25:21 +0200602 @property
603 def cts(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000604 """Read terminal status line: Clear To Send"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200605 if not self.is_open:
606 raise portNotOpenError
cliechtid6bf52c2003-10-01 02:28:12 +0000607 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200608 return struct.unpack('I', s)[0] & TIOCM_CTS != 0
cliechtid6bf52c2003-10-01 02:28:12 +0000609
Chris Liechtief1fe252015-08-27 23:25:21 +0200610 @property
611 def dsr(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000612 """Read terminal status line: Data Set Ready"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200613 if not self.is_open:
614 raise portNotOpenError
cliechtid6bf52c2003-10-01 02:28:12 +0000615 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200616 return struct.unpack('I', s)[0] & TIOCM_DSR != 0
cliechtid6bf52c2003-10-01 02:28:12 +0000617
Chris Liechtief1fe252015-08-27 23:25:21 +0200618 @property
619 def ri(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000620 """Read terminal status line: Ring Indicator"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200621 if not self.is_open:
622 raise portNotOpenError
cliechti89b4af12002-02-12 23:24:41 +0000623 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200624 return struct.unpack('I', s)[0] & TIOCM_RI != 0
cliechti89b4af12002-02-12 23:24:41 +0000625
Chris Liechtief1fe252015-08-27 23:25:21 +0200626 @property
627 def cd(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000628 """Read terminal status line: Carrier Detect"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200629 if not self.is_open:
630 raise portNotOpenError
cliechti89b4af12002-02-12 23:24:41 +0000631 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200632 return struct.unpack('I', s)[0] & TIOCM_CD != 0
cliechti89b4af12002-02-12 23:24:41 +0000633
cliechtia30a8a02003-10-05 12:28:13 +0000634 # - - platform specific - - - -
635
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200636 @property
637 def out_waiting(self):
638 """Return the number of bytes currently in the output buffer."""
Chris Liechti11465c82015-08-04 15:55:22 +0200639 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str)
cliechti28b8fd02011-12-28 21:39:42 +0000640 s = fcntl.ioctl(self.fd, TIOCOUTQ, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200641 return struct.unpack('I', s)[0]
cliechti28b8fd02011-12-28 21:39:42 +0000642
cliechti8753bbc2005-01-15 20:32:51 +0000643 def fileno(self):
cliechti2f0f8a32011-12-28 22:10:00 +0000644 """\
645 For easier use of the serial port instance with select.
646 WARNING: this function is not portable to different platforms!
647 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200648 if not self.is_open:
649 raise portNotOpenError
cliechti8753bbc2005-01-15 20:32:51 +0000650 return self.fd
cliechti89b4af12002-02-12 23:24:41 +0000651
Chris Liechti518b0d32015-08-30 02:20:39 +0200652 def set_input_flow_control(self, enable=True):
cliechti2f0f8a32011-12-28 22:10:00 +0000653 """\
654 Manually control flow - when software flow control is enabled.
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200655 This will send XON (true) or XOFF (false) to the other device.
cliechti2f0f8a32011-12-28 22:10:00 +0000656 WARNING: this function is not portable to different platforms!
657 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200658 if not self.is_open:
659 raise portNotOpenError
cliechti4a601342011-12-29 02:22:17 +0000660 if enable:
Chris Liechti11465c82015-08-04 15:55:22 +0200661 termios.tcflow(self.fd, termios.TCION)
cliechti57e48a62009-08-03 22:29:58 +0000662 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200663 termios.tcflow(self.fd, termios.TCIOFF)
cliechti57e48a62009-08-03 22:29:58 +0000664
Chris Liechti518b0d32015-08-30 02:20:39 +0200665 def set_output_flow_control(self, enable=True):
cliechti2f0f8a32011-12-28 22:10:00 +0000666 """\
667 Manually control flow of outgoing data - when hardware or software flow
668 control is enabled.
669 WARNING: this function is not portable to different platforms!
670 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200671 if not self.is_open:
672 raise portNotOpenError
cliechti2f0f8a32011-12-28 22:10:00 +0000673 if enable:
Chris Liechti11465c82015-08-04 15:55:22 +0200674 termios.tcflow(self.fd, termios.TCOON)
cliechti2f0f8a32011-12-28 22:10:00 +0000675 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200676 termios.tcflow(self.fd, termios.TCOOFF)
cliechti2f0f8a32011-12-28 22:10:00 +0000677
Chris Liechti59848422016-06-04 22:28:14 +0200678 def nonblocking(self):
679 """DEPRECATED - has no use"""
680 import warnings
681 warnings.warn("nonblocking() has no effect, already nonblocking", DeprecationWarning)
682
cliechtif81362e2009-07-25 03:44:33 +0000683
cliechtia9a093e2010-01-02 03:05:08 +0000684class PosixPollSerial(Serial):
cliechti7d448562014-08-03 21:57:45 +0000685 """\
cliechtif0a81d42014-08-04 14:03:53 +0000686 Poll based read implementation. Not all systems support poll properly.
687 However this one has better handling of errors, such as a device
cliechti7d448562014-08-03 21:57:45 +0000688 disconnecting while it's in use (e.g. USB-serial unplugged).
689 """
cliechtia9a093e2010-01-02 03:05:08 +0000690
691 def read(self, size=1):
cliechti7d448562014-08-03 21:57:45 +0000692 """\
693 Read size bytes from the serial port. If a timeout is set it may
694 return less characters as requested. With no timeout it will block
695 until the requested number of bytes is read.
696 """
Chris Liechtiacac2362016-03-29 22:37:48 +0200697 if not self.is_open:
Chris Liechti033f17c2015-08-30 21:28:04 +0200698 raise portNotOpenError
cliechtia9a093e2010-01-02 03:05:08 +0000699 read = bytearray()
700 poll = select.poll()
Chris Liechti033f17c2015-08-30 21:28:04 +0200701 poll.register(self.fd, select.POLLIN | select.POLLERR | select.POLLHUP | select.POLLNVAL)
cliechtia9a093e2010-01-02 03:05:08 +0000702 if size > 0:
703 while len(read) < size:
704 # print "\tread(): size",size, "have", len(read) #debug
705 # wait until device becomes ready to read (or something fails)
Chris Liechti033f17c2015-08-30 21:28:04 +0200706 for fd, event in poll.poll(self._timeout * 1000):
707 if event & (select.POLLERR | select.POLLHUP | select.POLLNVAL):
cliechtia9a093e2010-01-02 03:05:08 +0000708 raise SerialException('device reports error (poll)')
709 # we don't care if it is select.POLLIN or timeout, that's
710 # handled below
711 buf = os.read(self.fd, size - len(read))
712 read.extend(buf)
Chris Liechti518b0d32015-08-30 02:20:39 +0200713 if ((self._timeout is not None and self._timeout >= 0) or
Chris Liechti033f17c2015-08-30 21:28:04 +0200714 (self._inter_byte_timeout is not None and self._inter_byte_timeout > 0)) and not buf:
cliechtia9a093e2010-01-02 03:05:08 +0000715 break # early abort on timeout
716 return bytes(read)
717
cliechtif81362e2009-07-25 03:44:33 +0000718
Chris Liechti4cf54702015-10-18 00:21:56 +0200719class VTIMESerial(Serial):
720 """\
721 Implement timeout using vtime of tty device instead of using select.
722 This means that no inter character timeout can be specified and that
723 the error handling is degraded.
724
725 Overall timeout is disabled when inter-character timeout is used.
726 """
727
Chris Liechti94284702015-11-15 01:21:48 +0100728 def _reconfigure_port(self, force_update=True):
Chris Liechti4cf54702015-10-18 00:21:56 +0200729 """Set communication parameters on opened port."""
730 super(VTIMESerial, self)._reconfigure_port()
Chris Liechtid6bcaaf2016-02-01 22:55:26 +0100731 fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # clear O_NONBLOCK
Chris Liechti4cf54702015-10-18 00:21:56 +0200732
733 if self._inter_byte_timeout is not None:
734 vmin = 1
735 vtime = int(self._inter_byte_timeout * 10)
Chris Liechti3ec9c412016-08-08 01:06:46 +0200736 elif self._timeout is None:
737 vmin = 1
738 vtime = 0
Chris Liechti4cf54702015-10-18 00:21:56 +0200739 else:
740 vmin = 0
741 vtime = int(self._timeout * 10)
742 try:
743 orig_attr = termios.tcgetattr(self.fd)
744 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
745 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 +0100746 raise serial.SerialException("Could not configure port: {}".format(msg))
Chris Liechti4cf54702015-10-18 00:21:56 +0200747
748 if vtime < 0 or vtime > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100749 raise ValueError('Invalid vtime: {!r}'.format(vtime))
Chris Liechti4cf54702015-10-18 00:21:56 +0200750 cc[termios.VTIME] = vtime
751 cc[termios.VMIN] = vmin
752
753 termios.tcsetattr(
754 self.fd,
755 termios.TCSANOW,
756 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
757
Chris Liechti4cf54702015-10-18 00:21:56 +0200758 def read(self, size=1):
759 """\
760 Read size bytes from the serial port. If a timeout is set it may
761 return less characters as requested. With no timeout it will block
762 until the requested number of bytes is read.
763 """
764 if not self.is_open:
765 raise portNotOpenError
766 read = bytearray()
767 while len(read) < size:
768 buf = os.read(self.fd, size - len(read))
769 if not buf:
770 break
771 read.extend(buf)
772 return bytes(read)
Chris Liechti3ec9c412016-08-08 01:06:46 +0200773
774 # hack to make hasattr return false
775 cancel_read = property()