[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/devtools/datool/pyserial/serialutil.py b/src/devtools/datool/pyserial/serialutil.py
new file mode 100644
index 0000000..6f31efe
--- /dev/null
+++ b/src/devtools/datool/pyserial/serialutil.py
@@ -0,0 +1,635 @@
+#! python
+#
+# Base class and support functions used by various backends.
+#
+# This file is part of pySerial. https://github.com/pyserial/pyserial
+# (C) 2001-2015 Chris Liechti <cliechti@gmx.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+import io
+import time
+
+# ``memoryview`` was introduced in Python 2.7 and ``bytes(some_memoryview)``
+# isn't returning the contents (very unfortunate). Therefore we need special
+# cases and test for it. Ensure that there is a ``memoryview`` object for older
+# Python versions. This is easier than making every test dependent on its
+# existence.
+try:
+ memoryview
+except (NameError, AttributeError):
+ # implementation does not matter as we do not realy use it.
+ # it just must not inherit from something else we might care for.
+ class memoryview(object):
+ pass
+
+try:
+ unicode
+except (NameError, AttributeError):
+ unicode = str # for Python 3
+
+
+# "for byte in data" fails for python3 as it returns ints instead of bytes
+def iterbytes(b):
+ """Iterate over bytes, returning bytes instead of ints (python3)"""
+ if isinstance(b, memoryview):
+ b = b.tobytes()
+ x = 0
+ while True:
+ a = b[x:x + 1]
+ x += 1
+ if a:
+ yield a
+ else:
+ break
+
+
+# all Python versions prior 3.x convert ``str([17])`` to '[17]' instead of '\x11'
+# so a simple ``bytes(sequence)`` doesn't work for all versions
+def to_bytes(seq):
+ """convert a sequence to a bytes type"""
+ if isinstance(seq, bytes):
+ return seq
+ elif isinstance(seq, bytearray):
+ return bytes(seq)
+ elif isinstance(seq, memoryview):
+ return seq.tobytes()
+ elif isinstance(seq, unicode):
+ raise TypeError('unicode strings are not supported, please encode to bytes: %r' % (seq,))
+ else:
+ b = bytearray()
+ for item in seq:
+ # this one handles int and bytes in Python 2.7
+ # add conversion in case of Python 3.x
+ if isinstance(item, bytes):
+ item = ord(item)
+ b.append(item)
+ return bytes(b)
+
+# create control bytes
+XON = to_bytes([17])
+XOFF = to_bytes([19])
+
+CR = to_bytes([13])
+LF = to_bytes([10])
+
+
+PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = 'N', 'E', 'O', 'M', 'S'
+STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO = (1, 1.5, 2)
+FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)
+
+PARITY_NAMES = {
+ PARITY_NONE: 'None',
+ PARITY_EVEN: 'Even',
+ PARITY_ODD: 'Odd',
+ PARITY_MARK: 'Mark',
+ PARITY_SPACE: 'Space',
+}
+
+
+class SerialException(IOError):
+ """Base class for serial port related exceptions."""
+
+
+class SerialTimeoutException(SerialException):
+ """Write timeouts give an exception"""
+
+
+writeTimeoutError = SerialTimeoutException('Write timeout')
+portNotOpenError = SerialException('Attempting to use a port that is not open')
+
+
+class SerialBase(io.RawIOBase):
+ """\
+ Serial port base class. Provides __init__ function and properties to
+ get/set port settings.
+ """
+
+ # default values, may be overridden in subclasses that do not support all values
+ BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+ 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,
+ 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000,
+ 3000000, 3500000, 4000000)
+ BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)
+ PARITIES = (PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE)
+ STOPBITS = (STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO)
+
+ def __init__(self,
+ port=None, # number of device, numbering starts at
+ # zero. if everything fails, the user
+ # can specify a device string, note
+ # that this isn't portable anymore
+ # port will be opened if one is specified
+ baudrate=9600, # baud rate
+ bytesize=EIGHTBITS, # number of data bits
+ parity=PARITY_NONE, # enable parity checking
+ stopbits=STOPBITS_ONE, # number of stop bits
+ timeout=None, # set a timeout value, None to wait forever
+ xonxoff=False, # enable software flow control
+ rtscts=False, # enable RTS/CTS flow control
+ write_timeout=None, # set a timeout for writes
+ dsrdtr=False, # None: use rtscts setting, dsrdtr override if True or False
+ inter_byte_timeout=None, # Inter-character timeout, None to disable
+ **kwargs
+ ):
+ """\
+ Initialize comm port object. If a port is given, then the port will be
+ opened immediately. Otherwise a Serial port object in closed state
+ is returned.
+ """
+
+ self.is_open = False
+ # correct values are assigned below through properties
+ self._port = None
+ self._baudrate = None
+ self._bytesize = None
+ self._parity = None
+ self._stopbits = None
+ self._timeout = None
+ self._write_timeout = None
+ self._xonxoff = None
+ self._rtscts = None
+ self._dsrdtr = None
+ self._inter_byte_timeout = None
+ self._rs485_mode = None # disabled by default
+ self._rts_state = True
+ self._dtr_state = True
+ self._break_state = False
+
+ # assign values using get/set methods using the properties feature
+ self.port = port
+ self.baudrate = baudrate
+ self.bytesize = bytesize
+ self.parity = parity
+ self.stopbits = stopbits
+ self.timeout = timeout
+ self.write_timeout = write_timeout
+ self.xonxoff = xonxoff
+ self.rtscts = rtscts
+ self.dsrdtr = dsrdtr
+ self.inter_byte_timeout = inter_byte_timeout
+ # watch for backward compatible kwargs
+ if 'writeTimeout' in kwargs:
+ self.write_timeout = kwargs.pop('writeTimeout')
+ if 'interCharTimeout' in kwargs:
+ self.inter_byte_timeout = kwargs.pop('interCharTimeout')
+ if kwargs:
+ raise ValueError('unexpected keyword arguments: %r' % (kwargs,))
+
+ if port is not None:
+ self.open()
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ # to be implemented by subclasses:
+ # def open(self):
+ # def close(self):
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ @property
+ def port(self):
+ """\
+ Get the current port setting. The value that was passed on init or using
+ setPort() is passed back. See also the attribute portstr which contains
+ the name of the port as a string.
+ """
+ return self._port
+
+ @port.setter
+ def port(self, port):
+ """\
+ Change the port. The attribute portstr is set to a string that
+ contains the name of the port.
+ """
+
+ was_open = self.is_open
+ if was_open:
+ self.close()
+ self.portstr = port
+ self._port = port
+ self.name = self.portstr
+ if was_open:
+ self.open()
+
+
+ @property
+ def baudrate(self):
+ """Get the current baud rate setting."""
+ return self._baudrate
+
+ @baudrate.setter
+ def baudrate(self, baudrate):
+ """\
+ Change baud rate. It raises a ValueError if the port is open and the
+ baud rate is not possible. If the port is closed, then the value is
+ accepted and the exception is raised when the port is opened.
+ """
+ try:
+ b = int(baudrate)
+ except TypeError:
+ raise ValueError("Not a valid baudrate: %r" % (baudrate,))
+ else:
+ if b <= 0:
+ raise ValueError("Not a valid baudrate: %r" % (baudrate,))
+ self._baudrate = b
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def bytesize(self):
+ """Get the current byte size setting."""
+ return self._bytesize
+
+ @bytesize.setter
+ def bytesize(self, bytesize):
+ """Change byte size."""
+ if bytesize not in self.BYTESIZES:
+ raise ValueError("Not a valid byte size: %r" % (bytesize,))
+ self._bytesize = bytesize
+ if self.is_open:
+ self._reconfigure_port()
+
+
+
+ @property
+ def parity(self):
+ """Get the current parity setting."""
+ return self._parity
+
+ @parity.setter
+ def parity(self, parity):
+ """Change parity setting."""
+ if parity not in self.PARITIES:
+ raise ValueError("Not a valid parity: %r" % (parity,))
+ self._parity = parity
+ if self.is_open:
+ self._reconfigure_port()
+
+
+
+ @property
+ def stopbits(self):
+ """Get the current stop bits setting."""
+ return self._stopbits
+
+ @stopbits.setter
+ def stopbits(self, stopbits):
+ """Change stop bits size."""
+ if stopbits not in self.STOPBITS:
+ raise ValueError("Not a valid stop bit size: %r" % (stopbits,))
+ self._stopbits = stopbits
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def timeout(self):
+ """Get the current timeout setting."""
+ return self._timeout
+
+ @timeout.setter
+ def timeout(self, timeout):
+ """Change timeout setting."""
+ if timeout is not None:
+ try:
+ timeout + 1 # test if it's a number, will throw a TypeError if not...
+ except TypeError:
+ raise ValueError("Not a valid timeout: %r" % (timeout,))
+ if timeout < 0:
+ raise ValueError("Not a valid timeout: %r" % (timeout,))
+ self._timeout = timeout
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def write_timeout(self):
+ """Get the current timeout setting."""
+ return self._write_timeout
+
+ @write_timeout.setter
+ def write_timeout(self, timeout):
+ """Change timeout setting."""
+ if timeout is not None:
+ if timeout < 0:
+ raise ValueError("Not a valid timeout: %r" % (timeout,))
+ try:
+ timeout + 1 # test if it's a number, will throw a TypeError if not...
+ except TypeError:
+ raise ValueError("Not a valid timeout: %r" % timeout)
+
+ self._write_timeout = timeout
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def inter_byte_timeout(self):
+ """Get the current inter-character timeout setting."""
+ return self._inter_byte_timeout
+
+ @inter_byte_timeout.setter
+ def inter_byte_timeout(self, ic_timeout):
+ """Change inter-byte timeout setting."""
+ if ic_timeout is not None:
+ if ic_timeout < 0:
+ raise ValueError("Not a valid timeout: %r" % ic_timeout)
+ try:
+ ic_timeout + 1 # test if it's a number, will throw a TypeError if not...
+ except TypeError:
+ raise ValueError("Not a valid timeout: %r" % ic_timeout)
+
+ self._inter_byte_timeout = ic_timeout
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def xonxoff(self):
+ """Get the current XON/XOFF setting."""
+ return self._xonxoff
+
+ @xonxoff.setter
+ def xonxoff(self, xonxoff):
+ """Change XON/XOFF setting."""
+ self._xonxoff = xonxoff
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def rtscts(self):
+ """Get the current RTS/CTS flow control setting."""
+ return self._rtscts
+
+ @rtscts.setter
+ def rtscts(self, rtscts):
+ """Change RTS/CTS flow control setting."""
+ self._rtscts = rtscts
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def dsrdtr(self):
+ """Get the current DSR/DTR flow control setting."""
+ return self._dsrdtr
+
+ @dsrdtr.setter
+ def dsrdtr(self, dsrdtr=None):
+ """Change DsrDtr flow control setting."""
+ if dsrdtr is None:
+ # if not set, keep backwards compatibility and follow rtscts setting
+ self._dsrdtr = self._rtscts
+ else:
+ # if defined independently, follow its value
+ self._dsrdtr = dsrdtr
+ if self.is_open:
+ self._reconfigure_port()
+
+
+ @property
+ def rts(self):
+ return self._rts_state
+
+ @rts.setter
+ def rts(self, value):
+ self._rts_state = value
+ if self.is_open:
+ self._update_rts_state()
+
+ @property
+ def dtr(self):
+ return self._dtr_state
+
+ @dtr.setter
+ def dtr(self, value):
+ self._dtr_state = value
+ if self.is_open:
+ self._update_dtr_state()
+
+ @property
+ def break_condition(self):
+ return self._break_state
+
+ @break_condition.setter
+ def break_condition(self, value):
+ self._break_state = value
+ if self.is_open:
+ self._update_break_state()
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+ # functions useful for RS-485 adapters
+
+ @property
+ def rs485_mode(self):
+ """\
+ Enable RS485 mode and apply new settings, set to None to disable.
+ See serial.rs485.RS485Settings for more info about the value.
+ """
+ return self._rs485_mode
+
+ @rs485_mode.setter
+ def rs485_mode(self, rs485_settings):
+ self._rs485_mode = rs485_settings
+ if self.is_open:
+ self._reconfigure_port()
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ _SAVED_SETTINGS = ('baudrate', 'bytesize', 'parity', 'stopbits', 'xonxoff',
+ 'dsrdtr', 'rtscts', 'timeout', 'write_timeout',
+ 'inter_byte_timeout')
+
+ def get_settings(self):
+ """\
+ Get current port settings as a dictionary. For use with
+ apply_settings().
+ """
+ return dict([(key, getattr(self, '_' + key)) for key in self._SAVED_SETTINGS])
+
+ def apply_settings(self, d):
+ """\
+ Apply stored settings from a dictionary returned from
+ get_settings(). It's allowed to delete keys from the dictionary. These
+ values will simply left unchanged.
+ """
+ for key in self._SAVED_SETTINGS:
+ if key in d and d[key] != getattr(self, '_' + key): # check against internal "_" value
+ setattr(self, key, d[key]) # set non "_" value to use properties write function
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def __repr__(self):
+ """String representation of the current port settings and its state."""
+ return "%s<id=0x%x, open=%s>(port=%r, baudrate=%r, bytesize=%r, parity=%r, stopbits=%r, timeout=%r, xonxoff=%r, rtscts=%r, dsrdtr=%r)" % (
+ self.__class__.__name__,
+ id(self),
+ self.is_open,
+ self.portstr,
+ self.baudrate,
+ self.bytesize,
+ self.parity,
+ self.stopbits,
+ self.timeout,
+ self.xonxoff,
+ self.rtscts,
+ self.dsrdtr,
+ )
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+ # compatibility with io library
+
+ def readable(self):
+ return True
+
+ def writable(self):
+ return True
+
+ def seekable(self):
+ return False
+
+ def readinto(self, b):
+ data = self.read(len(b))
+ n = len(data)
+ try:
+ b[:n] = data
+ except TypeError as err:
+ import array
+ if not isinstance(b, array.array):
+ raise err
+ b[:n] = array.array('b', data)
+ return n
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+ # context manager
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args, **kwargs):
+ self.close()
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def send_break(self, duration=0.25):
+ """\
+ Send break condition. Timed, returns to idle state after given
+ duration.
+ """
+ if not self.is_open:
+ raise portNotOpenError
+ self.break_condition = True
+ time.sleep(duration)
+ self.break_condition = False
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+ # backwards compatibility / deprecated functions
+
+ def flushInput(self):
+ self.reset_input_buffer()
+
+ def flushOutput(self):
+ self.reset_output_buffer()
+
+ def inWaiting(self):
+ return self.in_waiting
+
+ def sendBreak(self, duration=0.25):
+ self.send_break(duration)
+
+ def setRTS(self, value=1):
+ self.rts = value
+
+ def setDTR(self, value=1):
+ self.dtr = value
+
+ def getCTS(self):
+ return self.cts
+
+ def getDSR(self):
+ return self.dsr
+
+ def getRI(self):
+ return self.ri
+
+ def getCD(self):
+ return self.cd
+
+ @property
+ def writeTimeout(self):
+ return self.write_timeout
+
+ @writeTimeout.setter
+ def writeTimeout(self, timeout):
+ self.write_timeout = timeout
+
+ @property
+ def interCharTimeout(self):
+ return self.inter_byte_timeout
+
+ @interCharTimeout.setter
+ def interCharTimeout(self, interCharTimeout):
+ self.inter_byte_timeout = interCharTimeout
+
+ def getSettingsDict(self):
+ return self.get_settings()
+
+ def applySettingsDict(self, d):
+ self.apply_settings(d)
+
+ def isOpen(self):
+ return self.is_open
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+ # additional functionality
+
+ def read_all(self):
+ """\
+ Read all bytes currently available in the buffer of the OS.
+ """
+ return self.read(self.in_waiting)
+
+ def read_until(self, terminator=LF, size=None):
+ """\
+ Read until a termination sequence is found ('\n' by default), the size
+ is exceeded or until timeout occurs.
+ """
+ lenterm = len(terminator)
+ line = bytearray()
+ while True:
+ c = self.read(1)
+ if c:
+ line += c
+ if line[-lenterm:] == terminator:
+ break
+ if size is not None and len(line) >= size:
+ break
+ else:
+ break
+ return bytes(line)
+
+ def iread_until(self, *args, **kwargs):
+ """\
+ Read lines, implemented as generator. It will raise StopIteration on
+ timeout (empty read).
+ """
+ while True:
+ line = self.read_until(*args, **kwargs)
+ if not line:
+ break
+ yield line
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - -
+if __name__ == '__main__':
+ import sys
+ s = SerialBase()
+ sys.stdout.write('port name: %s\n' % s.name)
+ sys.stdout.write('baud rates: %s\n' % s.BAUDRATES)
+ sys.stdout.write('byte sizes: %s\n' % s.BYTESIZES)
+ sys.stdout.write('parities: %s\n' % s.PARITIES)
+ sys.stdout.write('stop bits: %s\n' % s.STOPBITS)
+ sys.stdout.write('%s\n' % s)