def _open_port(device, baudrate, logfile=False, debug=False): """Open the serial communication port""" try: from serial.serialutil import SerialException except ImportError: raise ImportError("Python serial module not installed") try: from serial import serial_for_url, VERSION as serialver versions = [int(x) for x in serialver.split(".", 1)] if (versions[0] < 2) or (versions[1] < 6): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 2.6+ is required") import pyftdi.serialext try: port = serial_for_url(device, baudrate=baudrate, timeout=0) if logfile: port.set_logger(logfile) if not port.isOpen(): port.open() if not port.isOpen(): raise AssertionError('Cannot open port "%s"' % device) if debug: print "Using serial backend '%s'" % port.BACKEND return port except SerialException, e: raise AssertionError(str(e))
def _open_port(device, baudrate, logfile=False, debug=False): """Open the serial communication port""" try: from serial.serialutil import SerialException except ImportError: raise ImportError("Python serial module not installed") try: from serial import serial_for_url, VERSION as serialver versions = [int(x) for x in serialver.split('.', 1)] if (versions[0] < 2) or (versions[1] < 6): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 2.6+ is required") import pyftdi.serialext try: port = serial_for_url(device, baudrate=baudrate, timeout=0) if logfile: port.set_logger(logfile) if not port.isOpen(): port.open() if not port.isOpen(): raise AssertionError('Cannot open port "%s"' % device) if debug: print "Using serial backend '%s'" % port.BACKEND return port except SerialException, e: raise AssertionError(str(e))
def _open_port(device, baudrate, logfile=False, debug=False): """Open the serial communication port""" try: from serial.serialutil import SerialException except ImportError: raise ImportError("Python serial module not installed") try: from serial import serial_for_url, VERSION as serialver version = tuple([int(x) for x in serialver.split('.')]) if version < (2,6): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 2.6+ is required") # the following import enables serial protocol extensions import pyftdi.serialext try: port = serial_for_url(device, baudrate=baudrate, timeout=0) if logfile: port.set_logger(logfile) if not port.isOpen(): port.open() if not port.isOpen(): raise IOError('Cannot open port "%s"' % device) if debug: print_("Using serial backend '%s'" % port.BACKEND) return port except SerialException as e: raise IOError(str(e))
def _open_port(device, baudrate, logfile=False, debug=False): """Open the serial communication port""" try: from serial.serialutil import SerialException except ImportError: raise ImportError("Python serial module not installed") try: from serial import serial_for_url, VERSION as serialver version = tuple([int(x) for x in serialver.split('.')]) if version < (2, 6): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 2.6+ is required") # the following import enables serial protocol extensions import pyftdi.serialext try: port = serial_for_url(device, baudrate=baudrate, timeout=0) if logfile: port.set_logger(logfile) if not port.isOpen(): port.open() if not port.isOpen(): raise IOError('Cannot open port "%s"' % device) if debug: print_("Using serial backend '%s'" % port.BACKEND) return port except SerialException as e: raise IOError(str(e))
def is_correct_pyserial_version(): """Returns whether the pyserial version is supported""" version_tags = [int(version_tag) for version_tag in PYSERIAL_VERSION.split('.')] if version_tags[0] >= 3: if version_tags[0] == 3 and version_tags[1] <= 3: warn("PySerial out of date, please update to v3.4 if possible", stacklevel=0) return True return False
def _open_port(device, baudrate, parity, rtscts, debug=False): """Open the serial communication port""" try: from serial.serialutil import SerialException from serial import PARITY_NONE except ImportError: raise ImportError("Python serial module not installed") try: from serial import serial_for_url, VERSION as serialver version = tuple([int(x) for x in serialver.split('.')]) if version < (2, 6): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 2.6+ is required") # the following import enables serial protocol extensions if device.startswith('ftdi:'): try: from pyftdi import serialext serialext.touch() except ImportError: raise ImportError("PyFTDI module not installed") try: port = serial_for_url(device, baudrate=baudrate, parity=parity or PARITY_NONE, rtscts=rtscts, timeout=0) if not port.is_open: port.open() if not port.is_open: raise IOError('Cannot open port "%s"' % device) if debug: backend = port.BACKEND if hasattr(port, 'BACKEND') else '?' print("Using serial backend '%s'" % backend) return port except SerialException as exc: raise IOError(str(exc))
def _open_port(device, baudrate, parity, rtscts, debug=False): """Open the serial communication port""" try: from serial.serialutil import SerialException from serial import PARITY_NONE except ImportError: raise ImportError("Python serial module not installed") try: from serial import serial_for_url, VERSION as serialver version = tuple([int(x) for x in serialver.split('.')]) if version < (2, 6): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 2.6+ is required") # the following import enables serial protocol extensions if device.startswith('ftdi:'): try: from pyftdi import serialext serialext.touch() except ImportError: raise ImportError("PyFTDI module not installed") try: port = serial_for_url(device, baudrate=baudrate, parity=parity or PARITY_NONE, rtscts=rtscts, timeout=0) if not port.is_open: port.open() if not port.is_open: raise IOError('Cannot open port "%s"' % device) if debug: backend = hasattr(port, 'BACKEND') and port.BACKEND or '?' print("Using serial backend '%s'" % backend) return port except SerialException as e: raise IOError(str(e))
# Copyright (c) 2010-2016 Emmanuel Blot <*****@*****.**> # Copyright (c) 2008-2015, Neotion # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause """Serial modules compliant with pyserial APIs """ try: from serial.serialutil import SerialException except ImportError as exc: raise ImportError("Python serial module not installed") from exc try: from serial import VERSION, serial_for_url as serial4url version = tuple([int(x) for x in VERSION.split('.')]) if version < (3, 0): raise ValueError except (ValueError, IndexError, ImportError) as exc: raise ImportError("pyserial 3.0+ is required") from exc try: from serial import protocol_handler_packages protocol_handler_packages.append('pyftdi.serialext') except ImportError as exc: raise SerialException('Cannot register pyftdi extensions') from exc serial_for_url = serial4url def touch(): """Do nothing, only for static checkers than do not like module import with no module references
class FtdiSerial(SerialBase): """Base class for Serial port implementation compatible with pyserial API using a USB device. """ BAUDRATES = sorted([9600 * (x+1) for x in range(6)] + list(range(115200, 1000000, 115200)) + list(range(1000000, 13000000, 100000))) PYSERIAL_VERSION = tuple([int(x) for x in pyserialver.split('.')]) def open(self): """Open the initialized serial port""" if self.port is None: raise SerialException("Port must be configured before use.") try: device = Ftdi.create_from_url(self.port) except (UsbToolsError, IOError) as ex: raise SerialException('Unable to open USB port %s: %s' % (self.portstr, str(ex))) self.udev = device self._set_open_state(True) self._reconfigure_port() def close(self): """Close the open port""" self._set_open_state(False) if self.udev: self.udev.close() self.udev = None def read(self, size=1): """Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.""" data = bytearray() start = now() while True: buf = self.udev.read_data(size) data.extend(buf) size -= len(buf) if size <= 0: break if self._timeout is not None: if buf: break ms = now()-start if ms > self._timeout: break sleep(0.01) return bytes(data) def write(self, data): """Output the given string over the serial port.""" return self.udev.write_data(data) def flush(self): """Flush of file like objects. In this case, wait until all data is written.""" pass def reset_input_buffer(self): """Clear input buffer, discarding all that is in the buffer.""" self.udev.purge_rx_buffer() def reset_output_buffer(self): """Clear output buffer, aborting the current output and discarding all that is in the buffer.""" self.udev.purge_tx_buffer() def send_break(self, duration=0.25): """Send break condition.""" self.udev.set_break(True) sleep(duration) self.udev.set_break(False) def _update_break_state(self): """Send break condition. Not supported""" self.udev.set_break(self._break_state) def _update_rts_state(self): """Set terminal status line: Request To Send""" self.udev.set_rts(self._rts_state) def _update_dtr_state(self): """Set terminal status line: Data Terminal Ready""" self.udev.set_dtr(self._dtr_state) @property def usb_path(self): """Return the physical location as a triplet, only for debugging purposes. * bus is the USB bus * address is the address on the USB bus * interface is the interface number on the FTDI debice :return: (bus, address, interface) :rtype: tuple(int) """ return (self.udev.usb_dev.bus, self.udev.usb_dev.address, self.udev.interface.bInterfaceNumber) @property def cts(self): """Read terminal status line: Clear To Send""" return self.udev.get_cts() @property def dsr(self): """Read terminal status line: Data Set Ready""" return self.udev.get_dsr() @property def ri(self): """Read terminal status line: Ring Indicator""" return self.udev.get_ri() @property def cd(self): """Read terminal status line: Carrier Detect""" return self.udev.get_cd() @property def in_waiting(self): """Return the number of characters currently in the input buffer.""" # not implemented return 0 @property def out_waiting(self): """Return the number of bytes currently in the output buffer.""" return 0 @property def fifoSizes(self): """Return the (TX, RX) tupple of hardware FIFO sizes""" return self.udev.fifo_sizes def _reconfigure_port(self): try: self.udev.set_baudrate(self._baudrate) self._baudrate = self.udev.baudrate self.udev.set_line_property(self._bytesize, self._stopbits, self._parity) if self._rtscts: self.udev.set_flowctrl('hw') elif self._xonxoff: self.udev.set_flowctrl('sw') else: self.udev.set_flowctrl('') try: self.udev.set_dynamic_latency(12, 200, 50) except AttributeError: # backend does not support this feature pass except IOError as e: err = self.udev.get_error_string() raise SerialException("%s (%s)" % (str(e), err)) def _set_open_state(self, open_): self.is_open = bool(open_)
class SocketSerial(SerialBase): """Fake serial port redirected to a Unix socket. This is basically a copy of the serialposix serial port implementation with redefined IO for a Unix socket""" BACKEND = 'socket' VIRTUAL_DEVICE = True PYSERIAL_VERSION = tuple([int(x) for x in pyserialver.split('.')]) def _reconfigure_port(self): pass def makeDeviceName(self, port): return port def open(self): """Open the initialized serial port""" if self._port is None: raise SerialException("Port must be configured before use.") if self.isOpen(): raise SerialException("Port is already open.") self._dump = False self.sock = None try: self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) filename = self.portstr[self.portstr.index('://')+3:] if filename.startswith('~/'): home = os.getenv('HOME') if home: filename = os.path.join(home, filename[2:]) self._filename = filename self.sock.connect(self._filename) except Exception as e: self.close() msg = "Could not open port: %s" % (str(e),) if isinstance(e, socket.error): raise SerialExceptionWithErrno(msg, e.errno) else: raise SerialException(msg) self._set_open_state(True) self._lastdtr = None def close(self): if self.sock: try: self.sock.shutdown(socket.SHUT_RDWR) except Exception: pass try: self.sock.close() except Exception: pass self.sock = None self._set_open_state(False) def in_waiting(self): """Return the number of characters currently in the input buffer.""" return 0 def read(self, size=1): """Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.""" if self.sock is None: raise portNotOpenError read = bytearray() if size > 0: while len(read) < size: ready, _, _ = select.select([self.sock], [], [], self._timeout) if not ready: break # timeout buf = self.sock.recv(size-len(read)) if not len(buf): # Some character is ready, but none can be read # it is a marker for a disconnected peer raise portNotOpenError read += buf if self._timeout >= 0 and not buf: break # early abort on timeout return read def write(self, data): """Output the given string over the serial port.""" if self.sock is None: raise portNotOpenError t = len(data) d = data while t > 0: try: if self._writeTimeout is not None and self._writeTimeout > 0: _, ready, _ = select.select([], [self.sock], [], self._writeTimeout) if not ready: raise writeTimeoutError n = self.sock.send(d) if self._dump: print(hexdump(d[:n])) if self._writeTimeout is not None and self._writeTimeout > 0: _, ready, _ = select.select([], [self.sock], [], self._writeTimeout) if not ready: raise writeTimeoutError d = d[n:] t = t - n except OSError as e: if e.errno != errno.EAGAIN: raise def flush(self): """Flush of file like objects. In this case, wait until all data is written.""" pass def reset_input_buffer(self): """Clear input buffer, discarding all that is in the buffer.""" pass def reset_output_buffer(self): """Clear output buffer, aborting the current output and discarding all that is in the buffer.""" pass def send_break(self, duration=0.25): """Send break condition. Not supported""" def _update_break_state(self): """Send break condition. Not supported""" pass def _update_rts_state(self): """Set terminal status line: Request To Send""" pass def _update_dtr_state(self): """Set terminal status line: Data Terminal Ready""" pass def setDTR(self, on=1): """Set terminal status line: Data Terminal Ready""" pass @property def cts(self): """Read terminal status line: Clear To Send""" return True @property def dsr(self): """Read terminal status line: Data Set Ready""" return True @property def ri(self): """Read terminal status line: Ring Indicator""" return False @property def cd(self): """Read terminal status line: Carrier Detect""" return False # - - platform specific - - - - def nonblocking(self): """internal - not portable!""" if self.sock is None: raise portNotOpenError self.sock.setblocking(0) def dump(self, enable): self._dump = enable # - - Helpers - - def _set_open_state(self, open_): if self.PYSERIAL_VERSION < (3, 0): self._isOpen = bool(open_) else: self.is_open = bool(open_)
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Serial modules compliant with pyserial APIs """ try: from serial.serialutil import SerialException except ImportError: raise ImportError("Python serial module not installed") try: from serial import VERSION, serial_for_url as serial4url version = tuple([int(x) for x in VERSION.split('.')]) if version < (3, 0): raise ValueError except (ValueError, IndexError, ImportError): raise ImportError("pyserial 3.0+ is required") try: from serial import protocol_handler_packages protocol_handler_packages.append('pyftdi.serialext') except ImportError: raise SerialException('Cannot register pyftdi extensions') serial_for_url = serial4url def touch(): """Do nothing, only for static checkers than do not like module import
class UsbSerial(SerialBase): """Base class for Serial port implementation compatible with pyserial API using a USB device. """ BAUDRATES = sorted([9600 * (x+1) for x in range(6)] + list(range(115200, 1000000, 115200)) + list(range(1000000, 13000000, 100000))) PYSERIAL_VERSION = tuple([int(x) for x in pyserialver.split('.')]) def makeDeviceName(self, port): return port def open(self, devclass, scheme, vdict, pdict, default_vendor): """Open the initialized serial port""" from serial import SerialException if self._port is None: raise SerialException("Port must be configured before use.") try: vendor, product, interface, sernum, ix = UsbTools.parse_url( self.portstr, devclass, scheme, vdict, pdict, default_vendor) except UsbToolsError as e: raise SerialException(str(e)) try: self.udev = devclass() self.udev.open(vendor, product, interface, ix, sernum) self.flushOutput() self.flushInput() except IOError: raise SerialException('Unable to open USB port %s' % self.portstr) self._set_open_state(True) self._reconfigurePort() self._product = product def close(self): """Close the open port""" self._set_open_state(False) self.udev.close() self.udev = None def read(self, size=1): """Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.""" data = bytearray() start = time.time() while size > 0: buf = self.udev.read_data(size) data += buf size -= len(buf) if self._timeout > 0: if buf: break ms = time.time()-start if ms > self._timeout: break time.sleep(0.01) return data def write(self, data): """Output the given string over the serial port.""" self.udev.write_data(data) def flush(self): """Flush of file like objects. In this case, wait until all data is written.""" # do nothing def flushInput(self): """Clear input buffer, discarding all that is in the buffer.""" self.udev.purge_rx_buffer() def flushOutput(self): """Clear output buffer, aborting the current output and discarding all that is in the buffer.""" self.udev.purge_tx_buffer() def sendBreak(self): """Send break condition.""" # Not supported pass def setRTS(self, level=True): """Set terminal status line: Request To Send""" self.udev.set_rts(level) def setDTR(self, level=True): """Set terminal status line: Data Terminal Ready""" self.udev.set_dtr(level) def getCTS(self): """Read terminal status line: Clear To Send""" return self.udev.get_cts() def getDSR(self): """Read terminal status line: Data Set Ready""" return self.udev.get_dsr() def getRI(self): """Read terminal status line: Ring Indicator""" return self.udev.get_ri() def getCD(self): """Read terminal status line: Carrier Detect""" return self.udev.get_cd() def inWaiting(self): """Return the number of characters currently in the input buffer.""" # not implemented return 0 @property def fifoSizes(self): """Return the (TX, RX) tupple of hardware FIFO sizes""" return self.udev.fifo_sizes def _reconfigurePort(self): try: self.udev.set_baudrate(self._baudrate) self.udev.set_line_property(self._bytesize, self._stopbits, self._parity) if self._rtscts: self.udev.set_flowctrl('hw') elif self._xonxoff: self.udev.set_flowctrl('sw') else: self.udev.set_flowctrl('') try: self.udev.set_dynamic_latency(2, 200, 400) except AttributeError: # backend does not support this feature pass except IOError as e: from serial import SerialException err = self.udev.get_error_string() raise SerialException("%s (%s)" % (str(e), err)) _reconfigure_port = _reconfigurePort def _set_open_state(self, open_): if self.PYSERIAL_VERSION < (3, 0): self._isOpen = bool(open_) else: self.is_open = bool(open_)