blob: ccc974aa0dded6875ab1c08de164f18e267d0174 [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 Liechti21a306b2016-10-09 23:41:26 +0200193elif plat[:3] == 'bsd' or \
194 plat[:7] == 'freebsd' or \
195 plat[:6] == 'netbsd' or \
196 plat[:7] == 'openbsd':
197
198 class ReturnBaudrate(object):
199 def __getitem__(self, key):
200 return key
201
202 class PlatformSpecific(PlatformSpecificBase):
203 # Only tested on FreeBSD:
204 # The baud rate may be passed in as
205 # a literal value.
206 BAUDRATE_CONSTANTS = ReturnBaudrate()
207
Chris Liechtid6847af2015-08-06 17:54:30 +0200208else:
209 class PlatformSpecific(PlatformSpecificBase):
210 pass
cliechti89b4af12002-02-12 23:24:41 +0000211
cliechti89b4af12002-02-12 23:24:41 +0000212
cliechti58b481c2009-02-16 20:42:32 +0000213# load some constants for later use.
Chris Liechti11465c82015-08-04 15:55:22 +0200214# try to use values from termios, use defaults from linux otherwise
Chris Liechti033f17c2015-08-30 21:28:04 +0200215TIOCMGET = getattr(termios, 'TIOCMGET', 0x5415)
216TIOCMBIS = getattr(termios, 'TIOCMBIS', 0x5416)
217TIOCMBIC = getattr(termios, 'TIOCMBIC', 0x5417)
218TIOCMSET = getattr(termios, 'TIOCMSET', 0x5418)
cliechti89b4af12002-02-12 23:24:41 +0000219
Chris Liechti033f17c2015-08-30 21:28:04 +0200220# TIOCM_LE = getattr(termios, 'TIOCM_LE', 0x001)
Chris Liechtid6847af2015-08-06 17:54:30 +0200221TIOCM_DTR = getattr(termios, 'TIOCM_DTR', 0x002)
222TIOCM_RTS = getattr(termios, 'TIOCM_RTS', 0x004)
Chris Liechti033f17c2015-08-30 21:28:04 +0200223# TIOCM_ST = getattr(termios, 'TIOCM_ST', 0x008)
224# TIOCM_SR = getattr(termios, 'TIOCM_SR', 0x010)
cliechti89b4af12002-02-12 23:24:41 +0000225
Chris Liechtid6847af2015-08-06 17:54:30 +0200226TIOCM_CTS = getattr(termios, 'TIOCM_CTS', 0x020)
227TIOCM_CAR = getattr(termios, 'TIOCM_CAR', 0x040)
228TIOCM_RNG = getattr(termios, 'TIOCM_RNG', 0x080)
229TIOCM_DSR = getattr(termios, 'TIOCM_DSR', 0x100)
Chris Liechti033f17c2015-08-30 21:28:04 +0200230TIOCM_CD = getattr(termios, 'TIOCM_CD', TIOCM_CAR)
231TIOCM_RI = getattr(termios, 'TIOCM_RI', TIOCM_RNG)
232# TIOCM_OUT1 = getattr(termios, 'TIOCM_OUT1', 0x2000)
233# TIOCM_OUT2 = getattr(termios, 'TIOCM_OUT2', 0x4000)
Chris Liechti11465c82015-08-04 15:55:22 +0200234if hasattr(termios, 'TIOCINQ'):
235 TIOCINQ = termios.TIOCINQ
cliechti28b8fd02011-12-28 21:39:42 +0000236else:
Chris Liechtid6847af2015-08-06 17:54:30 +0200237 TIOCINQ = getattr(termios, 'FIONREAD', 0x541B)
Chris Liechti033f17c2015-08-30 21:28:04 +0200238TIOCOUTQ = getattr(termios, 'TIOCOUTQ', 0x5411)
cliechti89b4af12002-02-12 23:24:41 +0000239
240TIOCM_zero_str = struct.pack('I', 0)
241TIOCM_RTS_str = struct.pack('I', TIOCM_RTS)
242TIOCM_DTR_str = struct.pack('I', TIOCM_DTR)
243
Chris Liechti033f17c2015-08-30 21:28:04 +0200244TIOCSBRK = getattr(termios, 'TIOCSBRK', 0x5427)
245TIOCCBRK = getattr(termios, 'TIOCCBRK', 0x5428)
cliechti997b63c2008-06-21 00:09:31 +0000246
cliechti89b4af12002-02-12 23:24:41 +0000247
Chris Liechtief6b7b42015-08-06 22:19:26 +0200248class Serial(SerialBase, PlatformSpecific):
cliechti7d448562014-08-03 21:57:45 +0000249 """\
Chris Liechti033f17c2015-08-30 21:28:04 +0200250 Serial port class POSIX implementation. Serial port configuration is
cliechtid6bf52c2003-10-01 02:28:12 +0000251 done with termios and fcntl. Runs on Linux and many other Un*x like
cliechtif0a81d42014-08-04 14:03:53 +0000252 systems.
253 """
cliechtid6bf52c2003-10-01 02:28:12 +0000254
255 def open(self):
cliechti7d448562014-08-03 21:57:45 +0000256 """\
257 Open port with current settings. This may throw a SerialException
258 if the port cannot be opened."""
cliechtid6bf52c2003-10-01 02:28:12 +0000259 if self._port is None:
260 raise SerialException("Port must be configured before it can be used.")
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200261 if self.is_open:
cliechti02ef43a2011-03-24 23:33:12 +0000262 raise SerialException("Port is already open.")
263 self.fd = None
cliechti58b481c2009-02-16 20:42:32 +0000264 # open
cliechti4616bf12002-04-08 23:13:14 +0000265 try:
Chris Liechti033f17c2015-08-30 21:28:04 +0200266 self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
Chris Liechti68340d72015-08-03 14:15:48 +0200267 except OSError as msg:
cliechti4616bf12002-04-08 23:13:14 +0000268 self.fd = None
Chris Liechti984c5c52016-02-15 23:48:45 +0100269 raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
Chris Liechti11465c82015-08-04 15:55:22 +0200270 #~ fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # set blocking
cliechti58b481c2009-02-16 20:42:32 +0000271
cliechtib2f5fc82006-10-20 00:09:07 +0000272 try:
Chris Liechti94284702015-11-15 01:21:48 +0100273 self._reconfigure_port(force_update=True)
cliechtib2f5fc82006-10-20 00:09:07 +0000274 except:
cliechti2750b832009-07-28 00:13:52 +0000275 try:
276 os.close(self.fd)
277 except:
278 # ignore any exception when closing the port
279 # also to keep original exception that happened when setting up
280 pass
cliechtib2f5fc82006-10-20 00:09:07 +0000281 self.fd = None
cliechtif0a4f0f2009-07-21 21:12:37 +0000282 raise
cliechtib2f5fc82006-10-20 00:09:07 +0000283 else:
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200284 self.is_open = True
Chris Liechtif2fdeb92016-05-07 23:57:50 +0200285 try:
286 if not self._dsrdtr:
287 self._update_dtr_state()
288 if not self._rtscts:
289 self._update_rts_state()
290 except IOError as e:
Chris Liechtie1029622016-10-02 23:54:36 +0200291 if e.errno in (errno.EINVAL, errno.ENOTTY):
292 # ignore Invalid argument and Inappropriate ioctl
Chris Liechtif2fdeb92016-05-07 23:57:50 +0200293 pass
294 else:
295 raise
Chris Liechtief1fe252015-08-27 23:25:21 +0200296 self.reset_input_buffer()
Chris Liechti42ab2b42016-05-15 23:35:05 +0200297 self.pipe_abort_read_r, self.pipe_abort_read_w = os.pipe()
Chris Liechti13949c62016-05-16 22:45:38 +0200298 self.pipe_abort_write_r, self.pipe_abort_write_w = os.pipe()
Chris Liechti68cecce2016-06-03 23:52:34 +0200299 fcntl.fcntl(self.pipe_abort_read_r, fcntl.F_SETFL, os.O_NONBLOCK)
300 fcntl.fcntl(self.pipe_abort_write_r, fcntl.F_SETFL, os.O_NONBLOCK)
cliechti58b481c2009-02-16 20:42:32 +0000301
Chris Liechti94284702015-11-15 01:21:48 +0100302 def _reconfigure_port(self, force_update=False):
cliechtib2f5fc82006-10-20 00:09:07 +0000303 """Set communication parameters on opened port."""
cliechtic6178262004-03-22 22:04:52 +0000304 if self.fd is None:
cliechtia9a093e2010-01-02 03:05:08 +0000305 raise SerialException("Can only operate on a valid file descriptor")
cliechtie8c45422008-06-20 23:23:14 +0000306 custom_baud = None
cliechti58b481c2009-02-16 20:42:32 +0000307
cliechti2750b832009-07-28 00:13:52 +0000308 vmin = vtime = 0 # timeout is done via select
Chris Liechti518b0d32015-08-30 02:20:39 +0200309 if self._inter_byte_timeout is not None:
cliechti679bfa62008-06-20 23:58:15 +0000310 vmin = 1
Chris Liechti518b0d32015-08-30 02:20:39 +0200311 vtime = int(self._inter_byte_timeout * 10)
cliechti6ce7ab12002-11-07 02:15:00 +0000312 try:
cliechti4d0af5e2011-08-05 02:18:16 +0000313 orig_attr = termios.tcgetattr(self.fd)
314 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
Chris Liechti68340d72015-08-03 14:15:48 +0200315 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 +0100316 raise SerialException("Could not configure port: {}".format(msg))
cliechti58b481c2009-02-16 20:42:32 +0000317 # set up raw mode / no echo / binary
Chris Liechti033f17c2015-08-30 21:28:04 +0200318 cflag |= (termios.CLOCAL | termios.CREAD)
319 lflag &= ~(termios.ICANON | termios.ECHO | termios.ECHOE |
320 termios.ECHOK | termios.ECHONL |
321 termios.ISIG | termios.IEXTEN) # |termios.ECHOPRT
322 for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk
Chris Liechti11465c82015-08-04 15:55:22 +0200323 if hasattr(termios, flag):
324 lflag &= ~getattr(termios, flag)
cliechti58b481c2009-02-16 20:42:32 +0000325
Chris Liechti033f17c2015-08-30 21:28:04 +0200326 oflag &= ~(termios.OPOST | termios.ONLCR | termios.OCRNL)
327 iflag &= ~(termios.INLCR | termios.IGNCR | termios.ICRNL | termios.IGNBRK)
Chris Liechti11465c82015-08-04 15:55:22 +0200328 if hasattr(termios, 'IUCLC'):
329 iflag &= ~termios.IUCLC
330 if hasattr(termios, 'PARMRK'):
331 iflag &= ~termios.PARMRK
cliechti58b481c2009-02-16 20:42:32 +0000332
cliechtif0a4f0f2009-07-21 21:12:37 +0000333 # setup baud rate
cliechti89b4af12002-02-12 23:24:41 +0000334 try:
Chris Liechti984c5c52016-02-15 23:48:45 +0100335 ispeed = ospeed = getattr(termios, 'B{}'.format(self._baudrate))
cliechti895e8302004-04-20 02:40:28 +0000336 except AttributeError:
cliechtif1559d02007-11-08 23:43:58 +0000337 try:
Chris Liechtid6847af2015-08-06 17:54:30 +0200338 ispeed = ospeed = self.BAUDRATE_CONSTANTS[self._baudrate]
cliechtif1559d02007-11-08 23:43:58 +0000339 except KeyError:
cliechtie8c45422008-06-20 23:23:14 +0000340 #~ raise ValueError('Invalid baud rate: %r' % self._baudrate)
cliechtif0a4f0f2009-07-21 21:12:37 +0000341 # may need custom baud rate, it isn't in our list.
Chris Liechti11465c82015-08-04 15:55:22 +0200342 ispeed = ospeed = getattr(termios, 'B38400')
cliechtif0a4f0f2009-07-21 21:12:37 +0000343 try:
Chris Liechti033f17c2015-08-30 21:28:04 +0200344 custom_baud = int(self._baudrate) # store for later
cliechtif0a4f0f2009-07-21 21:12:37 +0000345 except ValueError:
Chris Liechti984c5c52016-02-15 23:48:45 +0100346 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate))
cliechtif0a4f0f2009-07-21 21:12:37 +0000347 else:
348 if custom_baud < 0:
Chris Liechti984c5c52016-02-15 23:48:45 +0100349 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate))
cliechti58b481c2009-02-16 20:42:32 +0000350
351 # setup char len
Chris Liechti11465c82015-08-04 15:55:22 +0200352 cflag &= ~termios.CSIZE
cliechtid6bf52c2003-10-01 02:28:12 +0000353 if self._bytesize == 8:
Chris Liechti11465c82015-08-04 15:55:22 +0200354 cflag |= termios.CS8
cliechtid6bf52c2003-10-01 02:28:12 +0000355 elif self._bytesize == 7:
Chris Liechti11465c82015-08-04 15:55:22 +0200356 cflag |= termios.CS7
cliechtid6bf52c2003-10-01 02:28:12 +0000357 elif self._bytesize == 6:
Chris Liechti11465c82015-08-04 15:55:22 +0200358 cflag |= termios.CS6
cliechtid6bf52c2003-10-01 02:28:12 +0000359 elif self._bytesize == 5:
Chris Liechti11465c82015-08-04 15:55:22 +0200360 cflag |= termios.CS5
cliechti89b4af12002-02-12 23:24:41 +0000361 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100362 raise ValueError('Invalid char len: {!r}'.format(self._bytesize))
cliechtif0a81d42014-08-04 14:03:53 +0000363 # setup stop bits
Chris Liechti033f17c2015-08-30 21:28:04 +0200364 if self._stopbits == serial.STOPBITS_ONE:
Chris Liechti11465c82015-08-04 15:55:22 +0200365 cflag &= ~(termios.CSTOPB)
Chris Liechti033f17c2015-08-30 21:28:04 +0200366 elif self._stopbits == serial.STOPBITS_ONE_POINT_FIVE:
367 cflag |= (termios.CSTOPB) # XXX same as TWO.. there is no POSIX support for 1.5
368 elif self._stopbits == serial.STOPBITS_TWO:
369 cflag |= (termios.CSTOPB)
cliechti89b4af12002-02-12 23:24:41 +0000370 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100371 raise ValueError('Invalid stop bit specification: {!r}'.format(self._stopbits))
cliechti58b481c2009-02-16 20:42:32 +0000372 # setup parity
Chris Liechti033f17c2015-08-30 21:28:04 +0200373 iflag &= ~(termios.INPCK | termios.ISTRIP)
374 if self._parity == serial.PARITY_NONE:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200375 cflag &= ~(termios.PARENB | termios.PARODD | CMSPAR)
Chris Liechti033f17c2015-08-30 21:28:04 +0200376 elif self._parity == serial.PARITY_EVEN:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200377 cflag &= ~(termios.PARODD | CMSPAR)
Chris Liechti033f17c2015-08-30 21:28:04 +0200378 cflag |= (termios.PARENB)
379 elif self._parity == serial.PARITY_ODD:
Chris Liechti6dc58e82016-08-29 23:02:13 +0200380 cflag &= ~CMSPAR
Chris Liechti033f17c2015-08-30 21:28:04 +0200381 cflag |= (termios.PARENB | termios.PARODD)
Chris Liechti6dc58e82016-08-29 23:02:13 +0200382 elif self._parity == serial.PARITY_MARK and CMSPAR:
Chris Liechti033f17c2015-08-30 21:28:04 +0200383 cflag |= (termios.PARENB | CMSPAR | termios.PARODD)
Chris Liechti6dc58e82016-08-29 23:02:13 +0200384 elif self._parity == serial.PARITY_SPACE and CMSPAR:
Chris Liechti033f17c2015-08-30 21:28:04 +0200385 cflag |= (termios.PARENB | CMSPAR)
Chris Liechti11465c82015-08-04 15:55:22 +0200386 cflag &= ~(termios.PARODD)
cliechti89b4af12002-02-12 23:24:41 +0000387 else:
Chris Liechti984c5c52016-02-15 23:48:45 +0100388 raise ValueError('Invalid parity: {!r}'.format(self._parity))
cliechti58b481c2009-02-16 20:42:32 +0000389 # setup flow control
390 # xonxoff
Chris Liechti11465c82015-08-04 15:55:22 +0200391 if hasattr(termios, 'IXANY'):
cliechtid6bf52c2003-10-01 02:28:12 +0000392 if self._xonxoff:
Chris Liechti033f17c2015-08-30 21:28:04 +0200393 iflag |= (termios.IXON | termios.IXOFF) # |termios.IXANY)
cliechti89b4af12002-02-12 23:24:41 +0000394 else:
Chris Liechti033f17c2015-08-30 21:28:04 +0200395 iflag &= ~(termios.IXON | termios.IXOFF | termios.IXANY)
cliechti89b4af12002-02-12 23:24:41 +0000396 else:
cliechtid6bf52c2003-10-01 02:28:12 +0000397 if self._xonxoff:
Chris Liechti033f17c2015-08-30 21:28:04 +0200398 iflag |= (termios.IXON | termios.IXOFF)
cliechti89b4af12002-02-12 23:24:41 +0000399 else:
Chris Liechti033f17c2015-08-30 21:28:04 +0200400 iflag &= ~(termios.IXON | termios.IXOFF)
cliechti58b481c2009-02-16 20:42:32 +0000401 # rtscts
Chris Liechti11465c82015-08-04 15:55:22 +0200402 if hasattr(termios, 'CRTSCTS'):
cliechtid6bf52c2003-10-01 02:28:12 +0000403 if self._rtscts:
Chris Liechti033f17c2015-08-30 21:28:04 +0200404 cflag |= (termios.CRTSCTS)
cliechti89b4af12002-02-12 23:24:41 +0000405 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200406 cflag &= ~(termios.CRTSCTS)
407 elif hasattr(termios, 'CNEW_RTSCTS'): # try it with alternate constant name
cliechtid6bf52c2003-10-01 02:28:12 +0000408 if self._rtscts:
Chris Liechti033f17c2015-08-30 21:28:04 +0200409 cflag |= (termios.CNEW_RTSCTS)
cliechtid4743692002-04-08 22:39:53 +0000410 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200411 cflag &= ~(termios.CNEW_RTSCTS)
cliechti2750b832009-07-28 00:13:52 +0000412 # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
cliechti58b481c2009-02-16 20:42:32 +0000413
414 # buffer
cliechtif0a81d42014-08-04 14:03:53 +0000415 # vmin "minimal number of characters to be read. 0 for non blocking"
cliechtid6bf52c2003-10-01 02:28:12 +0000416 if vmin < 0 or vmin > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100417 raise ValueError('Invalid vmin: {!r}'.format(vmin))
Chris Liechti11465c82015-08-04 15:55:22 +0200418 cc[termios.VMIN] = vmin
cliechti58b481c2009-02-16 20:42:32 +0000419 # vtime
cliechtid6bf52c2003-10-01 02:28:12 +0000420 if vtime < 0 or vtime > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100421 raise ValueError('Invalid vtime: {!r}'.format(vtime))
Chris Liechti11465c82015-08-04 15:55:22 +0200422 cc[termios.VTIME] = vtime
cliechti58b481c2009-02-16 20:42:32 +0000423 # activate settings
Chris Liechti94284702015-11-15 01:21:48 +0100424 if force_update or [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr:
Chris Liechti033f17c2015-08-30 21:28:04 +0200425 termios.tcsetattr(
Chris Liechti9eaa40c2016-02-12 23:32:59 +0100426 self.fd,
427 termios.TCSANOW,
428 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
cliechti58b481c2009-02-16 20:42:32 +0000429
cliechtie8c45422008-06-20 23:23:14 +0000430 # apply custom baud rate, if any
431 if custom_baud is not None:
Chris Liechtid6847af2015-08-06 17:54:30 +0200432 self._set_special_baudrate(custom_baud)
433
434 if self._rs485_mode is not None:
435 self._set_rs485_mode(self._rs485_mode)
cliechti89b4af12002-02-12 23:24:41 +0000436
437 def close(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000438 """Close port"""
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200439 if self.is_open:
cliechtic6178262004-03-22 22:04:52 +0000440 if self.fd is not None:
cliechtid6bf52c2003-10-01 02:28:12 +0000441 os.close(self.fd)
442 self.fd = None
Chris Liechtib658eac2016-05-22 20:51:44 +0200443 os.close(self.pipe_abort_read_w)
444 os.close(self.pipe_abort_read_r)
445 os.close(self.pipe_abort_write_w)
446 os.close(self.pipe_abort_write_r)
447 self.pipe_abort_read_r, self.pipe_abort_read_w = None, None
448 self.pipe_abort_write_r, self.pipe_abort_write_w = None, None
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200449 self.is_open = False
cliechtid6bf52c2003-10-01 02:28:12 +0000450
451 # - - - - - - - - - - - - - - - - - - - - - - - -
cliechti95c62212002-03-04 22:17:53 +0000452
Chris Liechtief1fe252015-08-27 23:25:21 +0200453 @property
454 def in_waiting(self):
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200455 """Return the number of bytes currently in the input buffer."""
Chris Liechti11465c82015-08-04 15:55:22 +0200456 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str)
cliechtif5831e02002-12-05 23:15:27 +0000457 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200458 return struct.unpack('I', s)[0]
cliechti89b4af12002-02-12 23:24:41 +0000459
cliechtia9a093e2010-01-02 03:05:08 +0000460 # select based implementation, proved to work on many systems
461 def read(self, size=1):
cliechti7d448562014-08-03 21:57:45 +0000462 """\
463 Read size bytes from the serial port. If a timeout is set it may
464 return less characters as requested. With no timeout it will block
465 until the requested number of bytes is read.
466 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200467 if not self.is_open:
468 raise portNotOpenError
cliechtia9a093e2010-01-02 03:05:08 +0000469 read = bytearray()
Chris Liechti935a2622016-08-30 23:39:15 +0200470 timeout = Timeout(self._timeout)
cliechtia9a093e2010-01-02 03:05:08 +0000471 while len(read) < size:
cliechti8d744de2013-10-11 14:31:13 +0000472 try:
Chris Liechti935a2622016-08-30 23:39:15 +0200473 ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
Chris Liechti42ab2b42016-05-15 23:35:05 +0200474 if self.pipe_abort_read_r in ready:
Chris Liechti68cecce2016-06-03 23:52:34 +0200475 os.read(self.pipe_abort_read_r, 1000)
Chris Liechti42ab2b42016-05-15 23:35:05 +0200476 break
cliechti8d744de2013-10-11 14:31:13 +0000477 # If select was used with a timeout, and the timeout occurs, it
478 # returns with empty lists -> thus abort read operation.
Chris Liechti033f17c2015-08-30 21:28:04 +0200479 # For timeout == 0 (non-blocking operation) also abort when
480 # there is nothing to read.
cliechti8d744de2013-10-11 14:31:13 +0000481 if not ready:
482 break # timeout
Chris Liechti033f17c2015-08-30 21:28:04 +0200483 buf = os.read(self.fd, size - len(read))
cliechti8d744de2013-10-11 14:31:13 +0000484 # read should always return some data as select reported it was
485 # ready to read when we get to this point.
486 if not buf:
487 # Disconnected devices, at least on Linux, show the
488 # behavior that they are always ready to read immediately
489 # but reading returns nothing.
Chris Liechti92df95a2016-02-09 23:30:37 +0100490 raise SerialException(
491 'device reports readiness to read but returned no data '
492 '(device disconnected or multiple access on port?)')
cliechti8d744de2013-10-11 14:31:13 +0000493 read.extend(buf)
Chris Liechti68340d72015-08-03 14:15:48 +0200494 except OSError as e:
Chris Liechti033f17c2015-08-30 21:28:04 +0200495 # this is for Python 3.x where select.error is a subclass of
496 # OSError ignore EAGAIN errors. all other errors are shown
nexcvon50ec2232016-05-24 15:48:46 +0800497 if e.errno != errno.EAGAIN and e.errno != errno.EINTR:
Chris Liechti984c5c52016-02-15 23:48:45 +0100498 raise SerialException('read failed: {}'.format(e))
Chris Liechti68340d72015-08-03 14:15:48 +0200499 except select.error as e:
cliechtic7cd7212014-08-03 21:34:38 +0000500 # this is for Python 2.x
cliechti8d744de2013-10-11 14:31:13 +0000501 # ignore EAGAIN errors. all other errors are shown
502 # see also http://www.python.org/dev/peps/pep-3151/#select
503 if e[0] != errno.EAGAIN:
Chris Liechti984c5c52016-02-15 23:48:45 +0100504 raise SerialException('read failed: {}'.format(e))
Chris Liechti935a2622016-08-30 23:39:15 +0200505 if timeout.expired():
506 break
cliechtia9a093e2010-01-02 03:05:08 +0000507 return bytes(read)
cliechti89b4af12002-02-12 23:24:41 +0000508
Chris Liechti42ab2b42016-05-15 23:35:05 +0200509 def cancel_read(self):
510 os.write(self.pipe_abort_read_w, b"x")
511
Chris Liechti13949c62016-05-16 22:45:38 +0200512 def cancel_write(self):
513 os.write(self.pipe_abort_write_w, b"x")
514
cliechti4a567a02009-07-27 22:09:31 +0000515 def write(self, data):
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200516 """Output the given byte string over the serial port."""
Chris Liechti033f17c2015-08-30 21:28:04 +0200517 if not self.is_open:
518 raise portNotOpenError
cliechti38077122013-10-16 02:57:27 +0000519 d = to_bytes(data)
520 tx_len = len(d)
Chris Liechti935a2622016-08-30 23:39:15 +0200521 timeout = Timeout(self._write_timeout)
cliechti9f7c2352013-10-11 01:13:46 +0000522 while tx_len > 0:
cliechti5d4d0bd2004-11-13 03:27:39 +0000523 try:
cliechti5d4d0bd2004-11-13 03:27:39 +0000524 n = os.write(self.fd, d)
Chris Liechti935a2622016-08-30 23:39:15 +0200525 if timeout.is_non_blocking:
Robert Smallshire325a7382016-03-25 21:18:38 +0100526 # Zero timeout indicates non-blocking - simply return the
527 # number of bytes of data actually written
528 return n
Chris Liechti935a2622016-08-30 23:39:15 +0200529 elif not timeout.is_infinite:
cliechti3cf46d62009-08-07 00:19:57 +0000530 # when timeout is set, use select to wait for being ready
531 # with the time left as timeout
Chris Liechti935a2622016-08-30 23:39:15 +0200532 if timeout.expired():
cliechti3cf46d62009-08-07 00:19:57 +0000533 raise writeTimeoutError
Chris Liechti935a2622016-08-30 23:39:15 +0200534 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], timeout.time_left())
Chris Liechti13949c62016-05-16 22:45:38 +0200535 if abort:
Chris Liechti68cecce2016-06-03 23:52:34 +0200536 os.read(self.pipe_abort_write_r, 1000)
Chris Liechti13949c62016-05-16 22:45:38 +0200537 break
cliechti5d4d0bd2004-11-13 03:27:39 +0000538 if not ready:
539 raise writeTimeoutError
cliechti88c62442013-10-12 04:03:16 +0000540 else:
Chris Liechti935a2622016-08-30 23:39:15 +0200541 assert timeout.time_left() is None
cliechti88c62442013-10-12 04:03:16 +0000542 # wait for write operation
Chris Liechti13949c62016-05-16 22:45:38 +0200543 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], None)
544 if abort:
545 os.read(self.pipe_abort_write_r, 1)
546 break
cliechti88c62442013-10-12 04:03:16 +0000547 if not ready:
548 raise SerialException('write failed (select)')
cliechti5d4d0bd2004-11-13 03:27:39 +0000549 d = d[n:]
cliechti9f7c2352013-10-11 01:13:46 +0000550 tx_len -= n
Chris Liechti675f7e12015-08-03 15:48:41 +0200551 except SerialException:
552 raise
Chris Liechti68340d72015-08-03 14:15:48 +0200553 except OSError as v:
cliechti5d4d0bd2004-11-13 03:27:39 +0000554 if v.errno != errno.EAGAIN:
Chris Liechti984c5c52016-02-15 23:48:45 +0100555 raise SerialException('write failed: {}'.format(v))
Chris Liechtic6362db2015-12-13 23:44:35 +0100556 # still calculate and check timeout
Chris Liechti935a2622016-08-30 23:39:15 +0200557 if timeout.expired():
Chris Liechtic6362db2015-12-13 23:44:35 +0100558 raise writeTimeoutError
cliechtif81362e2009-07-25 03:44:33 +0000559 return len(data)
cliechtid6bf52c2003-10-01 02:28:12 +0000560
cliechtia30a8a02003-10-05 12:28:13 +0000561 def flush(self):
cliechti7d448562014-08-03 21:57:45 +0000562 """\
563 Flush of file like objects. In this case, wait until all data
564 is written.
565 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200566 if not self.is_open:
567 raise portNotOpenError
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200568 termios.tcdrain(self.fd)
cliechtia30a8a02003-10-05 12:28:13 +0000569
Chris Liechtief1fe252015-08-27 23:25:21 +0200570 def reset_input_buffer(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000571 """Clear input buffer, discarding all that is in the buffer."""
Chris Liechti033f17c2015-08-30 21:28:04 +0200572 if not self.is_open:
573 raise portNotOpenError
Chris Liechti11465c82015-08-04 15:55:22 +0200574 termios.tcflush(self.fd, termios.TCIFLUSH)
cliechti89b4af12002-02-12 23:24:41 +0000575
Chris Liechtief1fe252015-08-27 23:25:21 +0200576 def reset_output_buffer(self):
cliechti7d448562014-08-03 21:57:45 +0000577 """\
578 Clear output buffer, aborting the current output and discarding all
579 that is in the buffer.
580 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200581 if not self.is_open:
582 raise portNotOpenError
Chris Liechti11465c82015-08-04 15:55:22 +0200583 termios.tcflush(self.fd, termios.TCOFLUSH)
cliechti89b4af12002-02-12 23:24:41 +0000584
Chris Liechtief1fe252015-08-27 23:25:21 +0200585 def send_break(self, duration=0.25):
cliechti7d448562014-08-03 21:57:45 +0000586 """\
587 Send break condition. Timed, returns to idle state after given
588 duration.
589 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200590 if not self.is_open:
591 raise portNotOpenError
592 termios.tcsendbreak(self.fd, int(duration / 0.25))
cliechti89b4af12002-02-12 23:24:41 +0000593
Chris Liechtief1fe252015-08-27 23:25:21 +0200594 def _update_break_state(self):
cliechti7d448562014-08-03 21:57:45 +0000595 """\
596 Set break: Controls TXD. When active, no transmitting is possible.
597 """
Chris Liechtief1fe252015-08-27 23:25:21 +0200598 if self._break_state:
cliechti997b63c2008-06-21 00:09:31 +0000599 fcntl.ioctl(self.fd, TIOCSBRK)
600 else:
601 fcntl.ioctl(self.fd, TIOCCBRK)
602
Chris Liechtief1fe252015-08-27 23:25:21 +0200603 def _update_rts_state(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000604 """Set terminal status line: Request To Send"""
Chris Liechtif7534c82016-05-07 23:35:54 +0200605 if self._rts_state:
606 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
607 else:
608 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
cliechtid6bf52c2003-10-01 02:28:12 +0000609
Chris Liechtief1fe252015-08-27 23:25:21 +0200610 def _update_dtr_state(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000611 """Set terminal status line: Data Terminal Ready"""
Chris Liechtif7534c82016-05-07 23:35:54 +0200612 if self._dtr_state:
613 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
614 else:
615 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
cliechtid6bf52c2003-10-01 02:28:12 +0000616
Chris Liechtief1fe252015-08-27 23:25:21 +0200617 @property
618 def cts(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000619 """Read terminal status line: Clear To Send"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200620 if not self.is_open:
621 raise portNotOpenError
cliechtid6bf52c2003-10-01 02:28:12 +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_CTS != 0
cliechtid6bf52c2003-10-01 02:28:12 +0000624
Chris Liechtief1fe252015-08-27 23:25:21 +0200625 @property
626 def dsr(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000627 """Read terminal status line: Data Set Ready"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200628 if not self.is_open:
629 raise portNotOpenError
cliechtid6bf52c2003-10-01 02:28:12 +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_DSR != 0
cliechtid6bf52c2003-10-01 02:28:12 +0000632
Chris Liechtief1fe252015-08-27 23:25:21 +0200633 @property
634 def ri(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000635 """Read terminal status line: Ring Indicator"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200636 if not self.is_open:
637 raise portNotOpenError
cliechti89b4af12002-02-12 23:24:41 +0000638 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200639 return struct.unpack('I', s)[0] & TIOCM_RI != 0
cliechti89b4af12002-02-12 23:24:41 +0000640
Chris Liechtief1fe252015-08-27 23:25:21 +0200641 @property
642 def cd(self):
cliechtid6bf52c2003-10-01 02:28:12 +0000643 """Read terminal status line: Carrier Detect"""
Chris Liechti033f17c2015-08-30 21:28:04 +0200644 if not self.is_open:
645 raise portNotOpenError
cliechti89b4af12002-02-12 23:24:41 +0000646 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200647 return struct.unpack('I', s)[0] & TIOCM_CD != 0
cliechti89b4af12002-02-12 23:24:41 +0000648
cliechtia30a8a02003-10-05 12:28:13 +0000649 # - - platform specific - - - -
650
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200651 @property
652 def out_waiting(self):
653 """Return the number of bytes currently in the output buffer."""
Chris Liechti11465c82015-08-04 15:55:22 +0200654 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str)
cliechti28b8fd02011-12-28 21:39:42 +0000655 s = fcntl.ioctl(self.fd, TIOCOUTQ, TIOCM_zero_str)
Chris Liechti033f17c2015-08-30 21:28:04 +0200656 return struct.unpack('I', s)[0]
cliechti28b8fd02011-12-28 21:39:42 +0000657
cliechti8753bbc2005-01-15 20:32:51 +0000658 def fileno(self):
cliechti2f0f8a32011-12-28 22:10:00 +0000659 """\
660 For easier use of the serial port instance with select.
661 WARNING: this function is not portable to different platforms!
662 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200663 if not self.is_open:
664 raise portNotOpenError
cliechti8753bbc2005-01-15 20:32:51 +0000665 return self.fd
cliechti89b4af12002-02-12 23:24:41 +0000666
Chris Liechti518b0d32015-08-30 02:20:39 +0200667 def set_input_flow_control(self, enable=True):
cliechti2f0f8a32011-12-28 22:10:00 +0000668 """\
669 Manually control flow - when software flow control is enabled.
Chris Liechti3ad62fb2015-08-29 21:53:32 +0200670 This will send XON (true) or XOFF (false) to the other device.
cliechti2f0f8a32011-12-28 22:10:00 +0000671 WARNING: this function is not portable to different platforms!
672 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200673 if not self.is_open:
674 raise portNotOpenError
cliechti4a601342011-12-29 02:22:17 +0000675 if enable:
Chris Liechti11465c82015-08-04 15:55:22 +0200676 termios.tcflow(self.fd, termios.TCION)
cliechti57e48a62009-08-03 22:29:58 +0000677 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200678 termios.tcflow(self.fd, termios.TCIOFF)
cliechti57e48a62009-08-03 22:29:58 +0000679
Chris Liechti518b0d32015-08-30 02:20:39 +0200680 def set_output_flow_control(self, enable=True):
cliechti2f0f8a32011-12-28 22:10:00 +0000681 """\
682 Manually control flow of outgoing data - when hardware or software flow
683 control is enabled.
684 WARNING: this function is not portable to different platforms!
685 """
Chris Liechti033f17c2015-08-30 21:28:04 +0200686 if not self.is_open:
687 raise portNotOpenError
cliechti2f0f8a32011-12-28 22:10:00 +0000688 if enable:
Chris Liechti11465c82015-08-04 15:55:22 +0200689 termios.tcflow(self.fd, termios.TCOON)
cliechti2f0f8a32011-12-28 22:10:00 +0000690 else:
Chris Liechti11465c82015-08-04 15:55:22 +0200691 termios.tcflow(self.fd, termios.TCOOFF)
cliechti2f0f8a32011-12-28 22:10:00 +0000692
Chris Liechti59848422016-06-04 22:28:14 +0200693 def nonblocking(self):
694 """DEPRECATED - has no use"""
695 import warnings
696 warnings.warn("nonblocking() has no effect, already nonblocking", DeprecationWarning)
697
cliechtif81362e2009-07-25 03:44:33 +0000698
cliechtia9a093e2010-01-02 03:05:08 +0000699class PosixPollSerial(Serial):
cliechti7d448562014-08-03 21:57:45 +0000700 """\
cliechtif0a81d42014-08-04 14:03:53 +0000701 Poll based read implementation. Not all systems support poll properly.
702 However this one has better handling of errors, such as a device
cliechti7d448562014-08-03 21:57:45 +0000703 disconnecting while it's in use (e.g. USB-serial unplugged).
704 """
cliechtia9a093e2010-01-02 03:05:08 +0000705
706 def read(self, size=1):
cliechti7d448562014-08-03 21:57:45 +0000707 """\
708 Read size bytes from the serial port. If a timeout is set it may
709 return less characters as requested. With no timeout it will block
710 until the requested number of bytes is read.
711 """
Chris Liechtiacac2362016-03-29 22:37:48 +0200712 if not self.is_open:
Chris Liechti033f17c2015-08-30 21:28:04 +0200713 raise portNotOpenError
cliechtia9a093e2010-01-02 03:05:08 +0000714 read = bytearray()
715 poll = select.poll()
Chris Liechti033f17c2015-08-30 21:28:04 +0200716 poll.register(self.fd, select.POLLIN | select.POLLERR | select.POLLHUP | select.POLLNVAL)
cliechtia9a093e2010-01-02 03:05:08 +0000717 if size > 0:
718 while len(read) < size:
719 # print "\tread(): size",size, "have", len(read) #debug
720 # wait until device becomes ready to read (or something fails)
Chris Liechti033f17c2015-08-30 21:28:04 +0200721 for fd, event in poll.poll(self._timeout * 1000):
722 if event & (select.POLLERR | select.POLLHUP | select.POLLNVAL):
cliechtia9a093e2010-01-02 03:05:08 +0000723 raise SerialException('device reports error (poll)')
724 # we don't care if it is select.POLLIN or timeout, that's
725 # handled below
726 buf = os.read(self.fd, size - len(read))
727 read.extend(buf)
Chris Liechti518b0d32015-08-30 02:20:39 +0200728 if ((self._timeout is not None and self._timeout >= 0) or
Chris Liechti033f17c2015-08-30 21:28:04 +0200729 (self._inter_byte_timeout is not None and self._inter_byte_timeout > 0)) and not buf:
cliechtia9a093e2010-01-02 03:05:08 +0000730 break # early abort on timeout
731 return bytes(read)
732
cliechtif81362e2009-07-25 03:44:33 +0000733
Chris Liechti4cf54702015-10-18 00:21:56 +0200734class VTIMESerial(Serial):
735 """\
736 Implement timeout using vtime of tty device instead of using select.
737 This means that no inter character timeout can be specified and that
738 the error handling is degraded.
739
740 Overall timeout is disabled when inter-character timeout is used.
741 """
742
Chris Liechti94284702015-11-15 01:21:48 +0100743 def _reconfigure_port(self, force_update=True):
Chris Liechti4cf54702015-10-18 00:21:56 +0200744 """Set communication parameters on opened port."""
745 super(VTIMESerial, self)._reconfigure_port()
Chris Liechtid6bcaaf2016-02-01 22:55:26 +0100746 fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # clear O_NONBLOCK
Chris Liechti4cf54702015-10-18 00:21:56 +0200747
748 if self._inter_byte_timeout is not None:
749 vmin = 1
750 vtime = int(self._inter_byte_timeout * 10)
Chris Liechti3ec9c412016-08-08 01:06:46 +0200751 elif self._timeout is None:
752 vmin = 1
753 vtime = 0
Chris Liechti4cf54702015-10-18 00:21:56 +0200754 else:
755 vmin = 0
756 vtime = int(self._timeout * 10)
757 try:
758 orig_attr = termios.tcgetattr(self.fd)
759 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr
760 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 +0100761 raise serial.SerialException("Could not configure port: {}".format(msg))
Chris Liechti4cf54702015-10-18 00:21:56 +0200762
763 if vtime < 0 or vtime > 255:
Chris Liechti984c5c52016-02-15 23:48:45 +0100764 raise ValueError('Invalid vtime: {!r}'.format(vtime))
Chris Liechti4cf54702015-10-18 00:21:56 +0200765 cc[termios.VTIME] = vtime
766 cc[termios.VMIN] = vmin
767
768 termios.tcsetattr(
769 self.fd,
770 termios.TCSANOW,
771 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
772
Chris Liechti4cf54702015-10-18 00:21:56 +0200773 def read(self, size=1):
774 """\
775 Read size bytes from the serial port. If a timeout is set it may
776 return less characters as requested. With no timeout it will block
777 until the requested number of bytes is read.
778 """
779 if not self.is_open:
780 raise portNotOpenError
781 read = bytearray()
782 while len(read) < size:
783 buf = os.read(self.fd, size - len(read))
784 if not buf:
785 break
786 read.extend(buf)
787 return bytes(read)
Chris Liechti3ec9c412016-08-08 01:06:46 +0200788
789 # hack to make hasattr return false
790 cancel_read = property()