示例#1
0
    def open(self):
        """\
        Open port with current settings. This may throw a SerialException
        if the port cannot be opened."""
        if self._port is None:
            raise SerialException("Port must be configured before it can be used.")
        if self.is_open:
            raise SerialException("Port is already open.")
        self.fd = None
        # open
        try:
            self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
        except OSError as msg:
            self.fd = None
            raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
        #~ fcntl.fcntl(self.fd, fcntl.F_SETFL, 0)  # set blocking

        try:
            self._reconfigure_port(force_update=True)
        except:
            try:
                os.close(self.fd)
            except:
                # ignore any exception when closing the port
                # also to keep original exception that happened when setting up
                pass
            self.fd = None
            raise
        else:
            self.is_open = True
        if not self._dsrdtr:
            self._update_dtr_state()
        if not self._rtscts:
            self._update_rts_state()
        self.reset_input_buffer()
示例#2
0
    def open(self):
        """\
        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        """
        self.logger = None
        if self._port is None:
            raise SerialException("Port must be configured before it can be used.")
        if self.is_open:
            raise SerialException("Port is already open.")
        try:
            self._socket = socket.create_connection(self.from_url(self.portstr))
        except Exception as msg:
            self._socket = None
            raise SerialException("Could not open port %s: %s" % (self.portstr, msg))

        self._socket.settimeout(POLL_TIMEOUT)  # used for write timeout support :/

        # not that there anything to configure...
        self._reconfigure_port()
        # all things set up get, now a clean start
        self.is_open = True
        if not self._dsrdtr:
            self._update_dtr_state()
        if not self._rtscts:
            self._update_rts_state()
        self.reset_input_buffer()
        self.reset_output_buffer()
示例#3
0
    def test_interrupt(self, serial_readline_mock, serial_open_mock):
        """ Test whether interrupts are handled. """
        serial_open_mock.return_value = None

        # First call raises expected exception, second call should just return data.
        eintr_error = SerialException(
            'read failed: [Errno 4] Interrupted system call')
        serial_readline_mock.side_effect = [eintr_error
                                            ] + self._dsmr_dummy_data()
        self.assertFalse(DsmrReading.objects.exists())

        self._intercept_command_stdout('dsmr_datalogger')
        self.assertTrue(DsmrReading.objects.exists())

        # Everything else should be reraised.
        serial_readline_mock.side_effect = SerialException(
            'Unexpected error from Serial')

        DsmrReading.objects.all().delete()
        self.assertFalse(DsmrReading.objects.exists())

        with self.assertRaises(SerialException):
            self._intercept_command_stdout('dsmr_datalogger')

        self.assertFalse(DsmrReading.objects.exists())
示例#4
0
    def open(self):
        """\
        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        """
        if self.is_open:
            raise SerialException("Port is already open.")
        self.logger = None
        self.queue = queue.Queue(self.buffer_size)

        if self._port is None:
            raise SerialException(
                "Port must be configured before it can be used.")
        # not that there is anything to open, but the function applies the
        # options found in the URL
        self.from_url(self.port)

        # not that there anything to configure...
        self._reconfigure_port()
        # all things set up get, now a clean start
        self.is_open = True
        if not self._dsrdtr:
            self._update_dtr_state()
        if not self._rtscts:
            self._update_rts_state()
        self.reset_input_buffer()
        self.reset_output_buffer()
示例#5
0
    def reset_input_buffer(self):
        """Clear input buffer, discarding all that is in the buffer."""
        if not self.is_open:
            raise portNotOpenError

        # just use recv to remove input, while there is some
        ready = True
        while ready:
            ready, _, _ = select.select([self._socket], [], [], 0)
            try:
                self._socket.recv(4096)
            except OSError as e:
                # this is for Python 3.x where select.error is a subclass of
                # OSError ignore BlockingIOErrors and EINTR. other errors are shown
                # https://www.python.org/dev/peps/pep-0475.
                if e.errno not in (errno.EAGAIN, errno.EALREADY,
                                   errno.EWOULDBLOCK, errno.EINPROGRESS,
                                   errno.EINTR):
                    raise SerialException('read failed: {}'.format(e))
            except (select.error, socket.error) as e:
                # this is for Python 2.x
                # ignore BlockingIOErrors and EINTR. all errors are shown
                # see also http://www.python.org/dev/peps/pep-3151/#select
                if e[0] not in (errno.EAGAIN, errno.EALREADY,
                                errno.EWOULDBLOCK, errno.EINPROGRESS,
                                errno.EINTR):
                    raise SerialException('read failed: {}'.format(e))
示例#6
0
 def write(self, data):
     """Output the given byte string over the serial port."""
     if not self.is_open:
         raise portNotOpenError
     d = to_bytes(data)
     tx_len = len(d)
     if self._write_timeout is not None and self._write_timeout > 0:
         timeout = time.time() + self._write_timeout
     else:
         timeout = None
     while tx_len > 0:
         try:
             n = os.write(self.fd, d)
             if timeout:
                 # when timeout is set, use select to wait for being ready
                 # with the time left as timeout
                 timeleft = timeout - time.time()
                 if timeleft < 0:
                     raise writeTimeoutError
                 _, ready, _ = select.select([], [self.fd], [], timeleft)
                 if not ready:
                     raise writeTimeoutError
             else:
                 # wait for write operation
                 _, ready, _ = select.select([], [self.fd], [], None)
                 if not ready:
                     raise SerialException('write failed (select)')
             d = d[n:]
             tx_len -= n
         except SerialException:
             raise
         except OSError as v:
             if v.errno != errno.EAGAIN:
                 raise SerialException('write failed: %s' % (v,))
     return len(data)
示例#7
0
    def from_url(self, url):
        """extract host and port from an URL string"""
        parts = urlparse.urlsplit(url)
        if parts.scheme != "socket":
            raise SerialException(
                'expected a string in the form '
                '"socket://<host>:<port>[?logging={debug|info|warning|error}]": '
                'not starting with socket:// ({!r})'.format(parts.scheme))
        try:
            # process options now, directly altering self
            for option, values in urlparse.parse_qs(parts.query, True).items():
                if option == 'logging':
                    logging.basicConfig()  # XXX is that good to call it here?
                    self.logger = logging.getLogger('pySerial.socket')
                    self.logger.setLevel(LOGGER_LEVELS[values[0]])
                    self.logger.debug('enabled logging')
                else:
                    raise ValueError('unknown option: {!r}'.format(option))
            if not 0 <= parts.port < 65536:
                raise ValueError("port not in range 0...65535")
        except ValueError as e:
            raise SerialException(
                'expected a string in the form '
                '"socket://<host>:<port>[?logging={debug|info|warning|error}]": {}'
                .format(e))

        return (parts.hostname, parts.port)
示例#8
0
 def write(self, data):
     """Output the given byte string over the serial port."""
     if not self.is_open:
         raise portNotOpenError
     d = to_bytes(data)
     tx_len = length = len(d)
     timeout = Timeout(self._write_timeout)
     while tx_len > 0:
         try:
             n = os.write(self.fd, d)
             if timeout.is_non_blocking:
                 # Zero timeout indicates non-blocking - simply return the
                 # number of bytes of data actually written
                 return n
             elif not timeout.is_infinite:
                 # when timeout is set, use select to wait for being ready
                 # with the time left as timeout
                 if timeout.expired():
                     raise writeTimeoutError
                 abort, ready, _ = select.select([self.pipe_abort_write_r],
                                                 [self.fd], [],
                                                 timeout.time_left())
                 if abort:
                     os.read(self.pipe_abort_write_r, 1000)
                     break
                 if not ready:
                     raise writeTimeoutError
             else:
                 assert timeout.time_left() is None
                 # wait for write operation
                 abort, ready, _ = select.select([self.pipe_abort_write_r],
                                                 [self.fd], [], None)
                 if abort:
                     os.read(self.pipe_abort_write_r, 1)
                     break
                 if not ready:
                     raise SerialException('write failed (select)')
             d = d[n:]
             tx_len -= n
         except SerialException:
             raise
         except OSError as e:
             # this is for Python 3.x where select.error is a subclass of
             # OSError ignore BlockingIOErrors and EINTR. other errors are shown
             # https://www.python.org/dev/peps/pep-0475.
             if e.errno not in (errno.EAGAIN, errno.EALREADY,
                                errno.EWOULDBLOCK, errno.EINPROGRESS,
                                errno.EINTR):
                 raise SerialException('write failed: {}'.format(e))
         except select.error as e:
             # this is for Python 2.x
             # ignore BlockingIOErrors and EINTR. all errors are shown
             # see also http://www.python.org/dev/peps/pep-3151/#select
             if e[0] not in (errno.EAGAIN, errno.EALREADY,
                             errno.EWOULDBLOCK, errno.EINPROGRESS,
                             errno.EINTR):
                 raise SerialException('write failed: {}'.format(e))
         if not timeout.is_non_blocking and timeout.expired():
             raise writeTimeoutError
     return length - len(d)
示例#9
0
    def open(self):
        if self._port is None:
            raise SerialException(
                "Port must be configured before it can be used.")
        if self.is_open:
            raise SerialException("Port is already open.")

        self._read_buffer = Queue.Queue()

        self._hid_handle = hid.device()
        try:
            portpath = self.from_url(self.portstr)
            self._hid_handle.open_path(portpath)
        except OSError as msg:
            raise SerialException(
                msg.errno,
                "could not open port {}: {}".format(self._port, msg))

        try:
            self._reconfigure_port()
        except:
            try:
                self._hid_handle.close()
            except:
                pass
            self._hid_handle = None
            raise
        else:
            self.is_open = True
            self._thread = threading.Thread(target=self._hid_read_loop)
            self._thread.setDaemon(True)
            self._thread.setName('pySerial CP2110 reader thread for {}'.format(
                self._port))
            self._thread.start()
示例#10
0
    def _open_interface(self):
        device = self._device
        log.debug("claiming interfaces, count={}".format(
            device.getInterfaceCount()))

        self._control_interface = device.getInterface(0)
        log.debug("Control iface={}".format(self._control_interface))

        if not self._connection.claimInterface(self._control_interface, True):
            raise SerialException("Could not claim control interface")

        self._control_endpoint = self._control_interface.getEndpoint(0)
        log.debug("Control endpoint direction: {}".format(
            self._control_endpoint.getDirection()))

        log.debug("Claiming data interface.")
        self._data_interface = device.getInterface(1)
        log.debug("data iface={}".format(self._data_interface))

        if not self._connection.claimInterface(self._data_interface, True):
            raise SerialException("Could not claim data interface")

        self._read_endpoint = self._data_interface.getEndpoint(1)
        log.debug("Read endpoint direction: {}".format(
            self._read_endpoint.getDirection()))

        self._write_endpoint = self._data_interface.getEndpoint(0)
        log.debug("Write endpoint direction: {}".format(
            self._write_endpoint.getDirection()))
示例#11
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 not self._port_handle:
         raise portNotOpenError
     if size > 0:
         win32.ResetEvent(self._overlapped_read.hEvent)
         flags = win32.DWORD()
         comstat = win32.COMSTAT()
         if not win32.ClearCommError(self._port_handle, ctypes.byref(flags),
                                     ctypes.byref(comstat)):
             raise SerialException('call to ClearCommError failed')
         n = min(comstat.cbInQue, size) if self.timeout == 0 else size
         if n > 0:
             buf = ctypes.create_string_buffer(n)
             rc = win32.DWORD()
             read_ok = win32.ReadFile(self._port_handle, buf, n,
                                      ctypes.byref(rc),
                                      ctypes.byref(self._overlapped_read))
             if not read_ok and win32.GetLastError() not in (
                     win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                 raise SerialException("ReadFile failed (%r)" %
                                       ctypes.WinError())
             win32.GetOverlappedResult(self._port_handle,
                                       ctypes.byref(self._overlapped_read),
                                       ctypes.byref(rc), True)
             read = buf.raw[:rc.value]
         else:
             read = bytes()
     else:
         read = bytes()
     return bytes(read)
示例#12
0
    def open_conn(self) -> None:
        """ Open serial port

        :return: None
        """
        modi_ports = list_modi_ports()
        if not modi_ports:
            raise SerialException("No MODI network module is available")

        if self.__port:
            if self.__port not in map(lambda info: info.device, modi_ports):
                raise SerialException(f"{self.__port} is not connected "
                                      f"to a MODI network module.")
            else:
                try:
                    self._bus = self.__init_serial(self.__port)
                    self._bus.open()
                    return
                except SerialException:
                    raise SerialException(f"{self.__port} is not available.")

        for modi_port in modi_ports:
            self._bus = self.__init_serial(modi_port.device)
            try:
                self._bus.open()
                print(f'Serial is open at "{modi_port}"')
                return
            except SerialException:
                continue
        raise SerialException("No MODI port is available now")
示例#13
0
    def open(self):
        """\
        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        """
        self.logger = None
        if self._port is None:
            raise SerialException("Port must be configured before it can be used.")
        if self.is_open:
            raise SerialException("Port is already open.")
        try:
            # timeout is used for write timeout support :/ and to get an initial connection timeout
            self._socket = socket.create_connection(self.from_url(self.portstr), timeout=POLL_TIMEOUT)
        except Exception as msg:
            self._socket = None
            raise SerialException("Could not open port {}: {}".format(self.portstr, msg))
        # after connecting, switch to non-blocking, we're using select
        self._socket.setblocking(False)

        # not that there is anything to configure...
        self._reconfigure_port()
        # all things set up get, now a clean start
        self.is_open = True
        if not self._dsrdtr:
            self._update_dtr_state()
        if not self._rtscts:
            self._update_rts_state()
        self.reset_input_buffer()
        self.reset_output_buffer()
示例#14
0
    def _set_break(self, break_):
        '''Start or stop a break exception event on the serial line.
        
        Parameters:
            break_ (bool): either start or stop break event.
        '''
        ch34x_break_reg = (self.CH34X_REG_LCR << 8) | self.CH34X_REG_BREAK
        break_reg = bytearray(2)
        if self._ctrl_transfer_in(self.CH34X_REQ_READ_REG, ch34x_break_reg, 0,
                                  break_reg) < 0:
            raise SerialException('Unable to read break state!')

        if break_:
            break_reg[0] &= (~self.CH34X_NBREAK_BITS)
            break_reg[1] &= (~self.CH34X_LCR_ENABLE_TX)
        else:
            break_reg[0] |= self.CH34X_NBREAK_BITS
            break_reg[1] |= self.CH34X_LCR_ENABLE_TX

        #Unpack break_reg into int
        reg_contents = break_reg[1] * 256 + break_reg[0]

        if self._ctrl_transfer_out(self.CH34X_REQ_WRITE_REG, ch34x_break_reg,
                                   reg_contents) < 0:
            raise SerialException('Unable to set break state!')
示例#15
0
    def open(self):
        '''Open the serial port.
        
        When the serial port is instantiated, it will try to open automatically.
        '''
        self.close()

        device = usb.get_usb_device(self.portstr)
        if not device:
            raise SerialException("Device not present {}".format(self.portstr))

        if not usb.has_usb_permission(device):
            usb.request_usb_permission(device)
            return

        connection = usb.get_usb_manager().openDevice(device)
        if not connection:
            raise SerialException("Failed to open device!")

        self._device = device
        self._connection = connection

        raw_descriptors = self._connection.getRawDescriptors()
        self._bcd_device = raw_descriptors[12] + raw_descriptors[13] * 256

        for i in range(self._device.getInterfaceCount()):
            if i == 0:
                self._interface = self._device.getInterface(i)
            if not self._connection.claimInterface(
                    self._device.getInterface(i), True):
                raise SerialException(
                    "Could not claim interface {}.".format(i))

        self._index = self._interface.getId() + 1

        for i in range(self._interface.getEndpointCount()):
            ep = self._interface.getEndpoint(i)
            if (
                (ep.getDirection() == usb.UsbConstants.USB_DIR_IN) \
                and (ep.getType() == usb.UsbConstants.USB_ENDPOINT_XFER_INT)
            ):
                self._control_endpoint = ep
            elif (
                (ep.getDirection() == usb.UsbConstants.USB_DIR_IN) \
                and (ep.getType() == usb.UsbConstants.USB_ENDPOINT_XFER_BULK)
            ):
                self._read_endpoint = ep
            elif (
                (ep.getDirection() == usb.UsbConstants.USB_DIR_OUT) \
                and (ep.getType() == usb.UsbConstants.USB_ENDPOINT_XFER_BULK)
            ):
                self._write_endpoint = ep

        # Check that all endpoints are good
        if None in [self._write_endpoint, self._read_endpoint]:
            raise SerialException("Could not establish all endpoints!")

        self.is_open = True
        self._reconfigure_port()
示例#16
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 not self.is_open:
            raise PortNotOpenError()
        read = bytearray()
        timeout = Timeout(self._timeout)
        while len(read) < size:
            try:
                ready, _, _ = select.select([self.fd, self.pipe_abort_read_r],
                                            [], [], timeout.time_left())
                if self.pipe_abort_read_r in ready:
                    os.read(self.pipe_abort_read_r, 1000)
                    break
                # If select was used with a timeout, and the timeout occurs, it
                # returns with empty lists -> thus abort read operation.
                # For timeout == 0 (non-blocking operation) also abort when
                # there is nothing to read.
                if not ready:
                    break  # timeout
                buf = os.read(self.fd, size - len(read))
            except OSError as e:
                # this is for Python 3.x where select.error is a subclass of
                # OSError ignore BlockingIOErrors and EINTR. other errors are shown
                # https://www.python.org/dev/peps/pep-0475.
                if e.errno not in (errno.EAGAIN, errno.EALREADY,
                                   errno.EWOULDBLOCK, errno.EINPROGRESS,
                                   errno.EINTR):
                    raise SerialException('read failed: {}'.format(e))
            except select.error as e:
                # this is for Python 2.x
                # ignore BlockingIOErrors and EINTR. all errors are shown
                # see also http://www.python.org/dev/peps/pep-3151/#select
                if e[0] not in (errno.EAGAIN, errno.EALREADY,
                                errno.EWOULDBLOCK, errno.EINPROGRESS,
                                errno.EINTR):
                    raise SerialException('read failed: {}'.format(e))
            else:
                # read should always return some data as select reported it was
                # ready to read when we get to this point.
                if not buf:
                    # Disconnected devices, at least on Linux, show the
                    # behavior that they are always ready to read immediately
                    # but reading returns nothing.
                    raise SerialException(
                        'device reports readiness to read but returned no data '
                        '(device disconnected or multiple access on port?)')
                read.extend(buf)

            if timeout.expired():
                break
            elif self._inter_byte_timeout is not None and self._inter_byte_timeout > 0:
                #atleast one char received --> overwrite timeout by setting it to inter_byte_timeout
                timeout = Timeout(self._inter_byte_timeout)

        return bytes(read)
示例#17
0
    def _set_line_property(self, bits, stopbits, parity):
        '''Set serial port line property.
        
        Parameters:
            bits (int): number of bits in data(5, 6, 7 or 8).
            stopbits (float): number of stop bits(1, 1.5, 2).
            parity (str): 'N', 'E', 'O', 'M' or 'S'.
        '''
        lcr = self.CH34X_LCR_ENABLE_RX | self.CH34X_LCR_ENABLE_TX

        if bits == 5:
            lcr |= self.CH34X_LCR_CS5
        elif bits == 6:
            lcr |= self.CH34X_LCR_CS6
        elif bits == 7:
            lcr |= self.CH34X_LCR_CS7
        elif bits == 8:
            lcr |= self.CH34X_LCR_CS8
        else:
            raise ValueError('Unknown bits value: {}'.format(bits))

        if parity == 'N':
            pass
        elif parity == 'O':
            lcr |= (self.CH34X_LCR_ENABLE_PAR)
        elif parity == 'E':
            lcr |= (self.CH34X_LCR_ENABLE_PAR | self.CH34X_LCR_PAR_EVEN)
        elif parity == 'M':
            lcr |= (self.CH34X_LCR_ENABLE_PAR | self.CH34X_LCR_MARK_SPACE)
        elif parity == 'S':
            lcr |= (
                self.CH34X_LCR_ENABLE_PAR \
                | self.CH34X_LCR_MARK_SPACE \
                | self.CH34X_LCR_PAR_EVEN
            )
        else:
            raise ValueError('Unknown parity value: {}'.format(parity))

        if stopbits == 1:
            pass
        elif stopbits == 1.5:
            pass
        elif stopbits == 2:
            lcr |= self.CH34X_LCR_STOP_BITS_2
        else:
            raise ValueError('Unknown stopbits value: {}'.format(stopbits))

        if self._ctrl_transfer_out(self.CH34X_REQ_WRITE_REG, 0x2518, lcr) < 0:
            raise SerialException('Setting line property failed!')

        self._check_state('Set parity', self.CH34X_REQ_READ_REG, 0x0706,
                          [0x9f, 0xee])

        if self._ctrl_transfer_out(self.CH34X_REQ_WRITE_REG, 0x2727, 0) < 0:
            raise SerialException('Fail to set line property!')

        self._lineprop = lcr
示例#18
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 not self.is_open:
         raise portNotOpenError
     read = bytearray()
     timeout = self._timeout
     while len(read) < size:
         try:
             start_time = time.time()
             ready, _, _ = select.select([self.fd, self.pipe_abort_read_r],
                                         [], [], timeout)
             if self.pipe_abort_read_r in ready:
                 os.read(self.pipe_abort_read_r, 1000)
                 break
             # If select was used with a timeout, and the timeout occurs, it
             # returns with empty lists -> thus abort read operation.
             # For timeout == 0 (non-blocking operation) also abort when
             # there is nothing to read.
             if not ready:
                 break  # timeout
             buf = os.read(self.fd, size - len(read))
             # read should always return some data as select reported it was
             # ready to read when we get to this point.
             if not buf:
                 # Disconnected devices, at least on Linux, show the
                 # behavior that they are always ready to read immediately
                 # but reading returns nothing.
                 raise SerialException(
                     'device reports readiness to read but returned no data '
                     '(device disconnected or multiple access on port?)')
             read.extend(buf)
         except OSError as e:
             # this is for Python 3.x where select.error is a subclass of
             # OSError ignore EAGAIN errors. all other errors are shown
             if e.errno != errno.EAGAIN and e.errno != errno.EINTR:
                 raise SerialException('read failed: {}'.format(e))
         except select.error as e:
             # this is for Python 2.x
             # ignore EAGAIN errors. all other errors are shown
             # see also http://www.python.org/dev/peps/pep-3151/#select
             if e[0] != errno.EAGAIN:
                 raise SerialException('read failed: {}'.format(e))
         if timeout is not None:
             timeout -= time.time() - start_time
             if timeout <= 0:
                 break
     return bytes(read)
示例#19
0
 def write(self, data):
     """Output the given byte string over the serial port."""
     if not self.is_open:
         raise portNotOpenError
     d = to_bytes(data)
     tx_len = len(d)
     timeout = self._write_timeout
     if timeout and timeout > 0:  # Avoid comparing None with zero
         timeout += time.time()
     while tx_len > 0:
         try:
             n = os.write(self.fd, d)
             if timeout == 0:
                 # Zero timeout indicates non-blocking - simply return the
                 # number of bytes of data actually written
                 return n
             elif timeout and timeout > 0:  # Avoid comparing None with zero
                 # when timeout is set, use select to wait for being ready
                 # with the time left as timeout
                 timeleft = timeout - time.time()
                 if timeleft < 0:
                     raise writeTimeoutError
                 abort, ready, _ = select.select([self.pipe_abort_write_r],
                                                 [self.fd], [], timeleft)
                 if abort:
                     os.read(self.pipe_abort_write_r, 1000)
                     break
                 if not ready:
                     raise writeTimeoutError
             else:
                 assert timeout is None
                 # wait for write operation
                 abort, ready, _ = select.select([self.pipe_abort_write_r],
                                                 [self.fd], [], None)
                 if abort:
                     os.read(self.pipe_abort_write_r, 1)
                     break
                 if not ready:
                     raise SerialException('write failed (select)')
             d = d[n:]
             tx_len -= n
         except SerialException:
             raise
         except OSError as v:
             if v.errno != errno.EAGAIN:
                 raise SerialException('write failed: {}'.format(v))
             # still calculate and check timeout
             if timeout and timeout - time.time() < 0:
                 raise writeTimeoutError
     return len(data)
示例#20
0
    def _init_device(self):
        if self._ctrl_transfer_out(0xa1, 0xc29c, 0xb2b9) < 0:
            raise SerialException('Init failed! #1')
        if self._ctrl_transfer_out(0xa4, 0xdf, 0) < 0:
            raise SerialException('Init failed! #2')
        if self._ctrl_transfer_out(0xa4, 0x9f, 0) < 0:
            raise SerialException('Init failed! #3')

        self._check_state('Init #4', self.CH34X_REQ_READ_REG, 0x0706,
                          [0x9f, 0xee])

        if self._ctrl_transfer_out(0x9a, 0x2727, 0x0000) < 0:
            raise SerialException('Init failed! #5')
        if self._ctrl_transfer_out(0x9a, 0x1312, 0xb282) < 0:
            raise SerialException('Init failed! #6')
        if self._ctrl_transfer_out(0x9a, 0x0f2c, 0x0008) < 0:
            raise SerialException('Init failed! #7')
        if self._ctrl_transfer_out(0x9a, 0x2518, 0x00c3) < 0:
            raise SerialException('Init failed! #8')

        self._check_state('Init #9', self.CH34X_REQ_READ_REG, 0x0706,
                          [0x9f, 0xee])

        if self._ctrl_transfer_out(0x9a, 0x2727, 0x0000) < 0:
            raise SerialException('Init failed! #10')
示例#21
0
 def _set_break(self, break_):
     '''Start or stop a break exception event on the serial line.
     
     Parameters:
         break_ (bool): either start or stop break event.
     '''
     if break_:
         if self._ctrl_transfer_out(self.CP210X_SET_BREAK,
                                    self.BREAK_ON) < 0:
             raise SerialException('Unable to start break sequence')
     else:
         if self._ctrl_transfer_out(self.CP210X_SET_BREAK,
                                    self.BREAK_OFF) < 0:
             raise SerialException('Unable to stop break sequence')
示例#22
0
 def _set_break(self, break_):
     '''Start or stop a break exception event on the serial line.
     
     Parameters:
         break_ (bool): either start or stop break event.
     '''
     if break_:
         value = self._lineprop | (0x01 << 14)
         if self._ctrl_transfer_out(self.SIO_SET_DATA, value, self._index):
             raise SerialException('Unable to start break sequence')
     else:
         value = self._lineprop & ~(0x01 << 14)
         if self._ctrl_transfer_out(self.SIO_SET_DATA, value, self._index):
             raise SerialException('Unable to stop break sequence')
     self._lineprop = value
示例#23
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 not self.is_open:
         raise portNotOpenError
     read = bytearray()
     timeout = self._timeout
     while len(read) < size:
         try:
             start_time = time.time()
             ready, _, _ = select.select([self._socket], [], [], timeout)
             # If select was used with a timeout, and the timeout occurs, it
             # returns with empty lists -> thus abort read operation.
             # For timeout == 0 (non-blocking operation) also abort when
             # there is nothing to read.
             if not ready:
                 break  # timeout
             buf = self._socket.recv(size - len(read))
             # read should always return some data as select reported it was
             # ready to read when we get to this point, unless it is EOF
             if not buf:
                 raise SerialException('socket disconnected')
             read.extend(buf)
             if timeout is not None:
                 timeout -= time.time() - start_time
                 if timeout <= 0:
                     break
         except socket.timeout:
             # timeout is used for write support, just go reading again
             pass
         except socket.error as e:
             # connection fails -> terminate loop
             raise SerialException('connection failed (%s)' % e)
         except OSError as e:
             # this is for Python 3.x where select.error is a subclass of
             # OSError ignore EAGAIN errors. all other errors are shown
             if e.errno != errno.EAGAIN:
                 raise SerialException('read failed: %s' % (e, ))
         except select.error as e:
             # this is for Python 2.x
             # ignore EAGAIN errors. all other errors are shown
             # see also http://www.python.org/dev/peps/pep-3151/#select
             if e[0] != errno.EAGAIN:
                 raise SerialException('read failed: %s' % (e, ))
     return bytes(read)
示例#24
0
 def write(self, data):
     """Output the given byte string over the serial port."""
     if not self.is_open:
         raise portNotOpenError
     #~ if not isinstance(data, (bytes, bytearray)):
     #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))
     # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview
     data = to_bytes(data)
     if data:
         #~ win32event.ResetEvent(self._overlapped_write.hEvent)
         n = win32.DWORD()
         err = win32.WriteFile(self._port_handle, data, len(data),
                               ctypes.byref(n), self._overlapped_write)
         if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
             raise SerialException("WriteFile failed ({!r})".format(
                 ctypes.WinError()))
         if self._write_timeout != 0:  # if blocking (None) or w/ write timeout (>0)
             # Wait for the write to complete.
             #~ win32.WaitForSingleObject(self._overlapped_write.hEvent, win32.INFINITE)
             err = win32.GetOverlappedResult(self._port_handle,
                                             self._overlapped_write,
                                             ctypes.byref(n), True)
             if win32.GetLastError() == win32.ERROR_OPERATION_ABORTED:
                 return n.value  # canceled IO is no error
             if n.value != len(data):
                 raise writeTimeoutError
         return n.value
     else:
         return 0
示例#25
0
 def _set_baudrate(self, baudrate):
     '''Change the current UART baudrate.
     
     The FTDI device is not able to use an arbitrary baudrate. Its
     internal dividors are only able to achieve some baudrates.
     It attemps to find the closest configurable baudrate and if
     the deviation from the requested baudrate is too high, it rejects
     the configuration. 
     
     Parameters:
         baudrate (int): the new baudrate for the UART.
     
     Raises:
         ValueError: if deviation from selected baudrate is too large.
         SerialException: if not able to set baudrate.
     '''
     actual, value, index = self._convert_baudrate(baudrate)
     delta = 100 * abs(float(actual - baudrate)) / baudrate
     if delta > self.BAUDRATE_TOLERANCE:
         raise ValueError('Baudrate tolerance exceeded: %.02f%% '
                          '(wanted %d, achievable %d)' %
                          (delta, baudrate, actual))
     result = self._ctrl_transfer_out(self.SIO_SET_BAUDRATE, value, index)
     if result != 0:
         raise SerialException('Unable to set baudrate.')
示例#26
0
 def write(self, data):
     '''Write data to the serial port.
     
     Parameters:
         data (bytearray): data written to the serial port.
 
     Returns:
         wrote (int): the number of data bytes written. 
     '''
     if not self.is_open:
         return None
     offset = 0
     timeout = int(
         self._write_timeout * 1000 if self._write_timeout \
             else self.USB_WRITE_TIMEOUT_MILLIS
     )
     wrote = 0
     while offset < len(data):
         data_length = min(
             len(data) - offset, self.DEFAULT_WRITE_BUFFER_SIZE)
         buf = data[offset:offset + data_length]
         i = self._connection.bulkTransfer(self._write_endpoint, buf,
                                           data_length, timeout)
         if i <= 0:
             raise SerialException("Failed to write {}: {}".format(buf, i))
         offset += data_length
         wrote += i
     return wrote
示例#27
0
 def reset(self):
     '''Reset the serial port.'''
     if self._connection:
         result = self._ctrl_transfer_out(self.SIO_RESET,
                                          self.SIO_RESET_SIO, self._index)
         if result != 0:
             raise SerialException("Reset failed: result={}".format(result))
示例#28
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 not self.is_open:
         raise portNotOpenError
     data = bytearray()
     if self._timeout is not None:
         timeout = time.time() + self._timeout
     else:
         timeout = None
     while len(data) < size:
         try:
             # an implementation with internal buffer would be better
             # performing...
             block = self._socket.recv(size - len(data))
             if block:
                 data.extend(block)
             else:
                 # no data -> EOF (connection probably closed)
                 break
         except socket.timeout:
             # just need to get out of recv from time to time to check if
             # still alive and timeout did not expire
             pass
         except socket.error as e:
             # connection fails -> terminate loop
             raise SerialException('connection failed (%s)' % e)
         if timeout is not None and time.time() > timeout:
             break
     return bytes(data)
示例#29
0
 def out_waiting(self):
     """Return how many bytes the in the outgoing buffer"""
     flags = win32.DWORD()
     comstat = win32.COMSTAT()
     if not win32.ClearCommError(self._port_handle, ctypes.byref(flags), ctypes.byref(comstat)):
         raise SerialException('call to ClearCommError failed')
     return comstat.cbOutQue
示例#30
0
 def in_waiting(self):
     """Return the number of bytes currently in the input buffer."""
     flags = win32.DWORD()
     comstat = win32.COMSTAT()
     if not win32.ClearCommError(self._port_handle, ctypes.byref(flags), ctypes.byref(comstat)):
         raise SerialException('call to ClearCommError failed')
     return comstat.cbInQue