Beispiel #1
0
 def _load_eeprom(self, devdesc: dict, cfgdescs: Sequence[dict]) -> None:
     whole = self._version != 0x1000  # FT230X
     buf = self._eeprom if whole else self._eeprom[:0x100]
     chksum = self._checksum_eeprom(buf)
     if chksum:
         self.log.warning('Invalid EEPROM checksum, ignoring content')
         return
     # only apply a subset of what the EEPROM can configure for now
     devdesc['idVendor'] = sunpack('<H', self._eeprom[2:4])[0]
     devdesc['idProduct'] = sunpack('<H', self._eeprom[4:6])[0]
     devdesc['iManufacturer'] = self._decode_eeprom_string(0x0e)
     devdesc['iProduct'] = self._decode_eeprom_string(0x10)
     devdesc['iSerialNumber'] = self._decode_eeprom_string(0x12)
     for desc in cfgdescs:
         if desc.bConfigurationValue == 0:
             # only update first configuration
             desc['bMaxPower'] = self._eeprom[0x09]
             desc['bmAttributes'] = 0x80 | (self._eeprom[0x08] & 0x0F)
     cbus_dec = f'_decode_cbus_x{self._version:04x}'
     try:
         cbus_func = getattr(self._ports[0], cbus_dec)
     except AttributeError:
         self.log.debug('No CBUS support: %s', cbus_dec)
         return
     cbus_func()
Beispiel #2
0
def decode_tve_parameter(data):
    """Generic byte decoding function for TVE parameters.

    Given an array of bytes, tries to interpret a TVE parameter from the
    beginning of the array.  Returns the decoded data and the number of bytes
    it read."""

    # decode the TVE field's header (1 bit "reserved" + 7-bit type)
    (msgtype, ) = sunpack(tve_header, data[:tve_header_len])
    if not msgtype & 0b10000000:
        # not a TV-encoded param
        return None, 0
    msgtype = msgtype & 0x7f
    try:
        param_name, param_fmt = tve_param_formats[msgtype]
        logger.debug('found %s (type=%s)', param_name, msgtype)
    except KeyError as err:
        return None, 0

    # decode the body
    nbytes = scalc(param_fmt)
    end = tve_header_len + nbytes
    try:
        unpacked = sunpack(param_fmt, data[tve_header_len:end])
        return {param_name: unpacked}, end
    except serror:
        return None, 0
Beispiel #3
0
 def _decode_eeprom(self):
     cfg = self._config
     cfg.clear()
     cfg['vendor_id'] = Hex4Int(sunpack('<H', self._eeprom[0x02:0x04])[0])
     cfg['product_id'] = Hex4Int(sunpack('<H', self._eeprom[0x04:0x06])[0])
     cfg['type'] = Hex4Int(sunpack('<H', self._eeprom[0x06:0x08])[0])
     power_supply, power_max, conf = sunpack('<3B', self._eeprom[0x08:0x0b])
     cfg['self_powered'] = bool(power_supply & (1 << 6))
     cfg['remote_wakeup'] = bool(power_supply & (1 << 5))
     cfg['power_max'] = power_max << 1
     cfg['has_serial'] = bool(conf & (1 << 3))
     cfg['suspend_pull_down'] = bool(conf & (1 << 2))
     cfg['out_isochronous'] = bool(conf & (1 << 1))
     cfg['in_isochronous'] = bool(conf & (1 << 0))
     cfg['usb_version'] = Hex4Int(sunpack('<H', self._eeprom[0x0c:0x0e])[0])
     cfg['manufacturer'] = self._decode_string(0x0e)
     cfg['product'] = self._decode_string(0x10)
     cfg['serial'] = self._decode_string(0x12)
     name = None
     try:
         name = Ftdi.DEVICE_NAMES[cfg['type']].replace('-', '')
         if name.startswith('ft'):
             name = name[2:]
         func = getattr(self, '_decode_%s' % name)
     except (KeyError, AttributeError):
         self.log.warning('No EEPROM decoder for device %s', name or '?')
     else:
         func()
Beispiel #4
0
 def _decode_eeprom(self):
     cfg = self._config
     cfg.clear()
     cfg['vendor_id'] = Hex4Int(sunpack('<H', self._eeprom[0x02:0x04])[0])
     cfg['product_id'] = Hex4Int(sunpack('<H', self._eeprom[0x04:0x06])[0])
     cfg['type'] = Hex4Int(sunpack('<H', self._eeprom[0x06:0x08])[0])
     power_supply, power_max, conf = sunpack('<3B', self._eeprom[0x08:0x0b])
     cfg['self_powered'] = bool(power_supply & (1 << 6))
     cfg['remote_wakeup'] = bool(power_supply & (1 << 5))
     cfg['power_max'] = power_max << 1
     cfg['has_usb_version'] = bool(conf & (1 << 4))
     cfg['has_serial'] = bool(conf & (1 << 3))
     cfg['suspend_pull_down'] = bool(conf & (1 << 2))
     cfg['out_isochronous'] = bool(conf & (1 << 1))
     cfg['in_isochronous'] = bool(conf & (1 << 0))
     cfg['usb_version'] = Hex4Int(sunpack('<H', self._eeprom[0x0c:0x0e])[0])
     cfg['manufacturer'] = self._decode_string(0x0e)
     cfg['product'] = self._decode_string(0x10)
     cfg['serial'] = self._decode_string(0x12)
     try:
         name = Ftdi.DEVICE_NAMES[cfg['type']]
         func = getattr(self, '_decode_%s' % name[2:])
     except (KeyError, AttributeError):
         pass
     else:
         func()
Beispiel #5
0
 def deserialize(self):
     """Turns a sequence of bytes into a message dictionary."""
     if self.msgbytes is None:
         raise LLRPError('No message bytes to deserialize.')
     data = self.msgbytes
     msgtype, length, msgid = sunpack(self.full_hdr_fmt,
                                      data[:self.full_hdr_len])
     ver = (msgtype >> 10) & BITMASK(3)
     msgtype = msgtype & BITMASK(10)
     try:
         name = Message_Type2Name[msgtype]
         logger.debug('deserializing %s command', name)
         decoder = Message_struct[name]['decode']
     except KeyError:
         raise LLRPError('Cannot find decoder for message type '
                         '{}'.format(msgtype))
     body = data[self.full_hdr_len:length]
     try:
         self.msgdict = {name: dict(decoder(body))}
         self.msgdict[name]['Ver'] = ver
         self.msgdict[name]['Type'] = msgtype
         self.msgdict[name]['ID'] = msgid
         logger.debug('done deserializing %s command', name)
     except LLRPError:
         logger.exception('Problem with %s message format', name)
         return ''
     return ''
Beispiel #6
0
 def _decode_input_mpsse_request(self):
     if len(self._trace_tx) < 3:
         return False
     length = sunpack('<H', self._trace_tx[1:3])[0] + 1
     self._expect_resp.append(length)
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #7
0
 def _decode_input_mpsse_request(self):
     if len(self._trace_tx) < 3:
         return False
     length = sunpack('<H', self._trace_tx[1:3])[0] + 1
     self._expect_resp.append(length)
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #8
0
 def parse_options(self, tail):
     self.log.debug('Parsing DHCP options')
     dhcp_tags = {}
     padding_count = 0
     while tail:
         tag = tail[0]
         # padding
         if tag == 0:
             padding_count += 1
             if padding_count > 255:
                 raise ValueError('Padding overflow')
             continue
         padding_count = 0
         if tag == 0xff:
             return dhcp_tags
         length = tail[1]
         (value, ) = sunpack('!%ss' % length, tail[2:2+length])
         tail = tail[2+length:]
         try:
             option = DHCP_OPTIONS[tag]
             self.log.debug(" option %d: '%s', size:%d %s" %
                            (tag, option, length, hexline(value)))
         except KeyError:
             self.log.debug('  unknown option %d, size:%d %s:' %
                            (tag, length, hexline(value)))
             continue
         dhcp_tags[tag] = value
Beispiel #9
0
 def _stream_sink(cls, port, size, results):
     pos = 0
     first = None
     data = bytearray()
     sample_size = scalc('>I')
     rx_size = 0
     port.timeout = 1.0
     start = now()
     while rx_size < size:
         buf = port.read(1024)
         if not buf:
             print('T')
             break
         rx_size += len(buf)
         data.extend(buf)
         sample_count = len(data) // sample_size
         length = sample_count * sample_size
         samples = sunpack('>%dI' % sample_count, data[:length])
         data = data[length:]
         for sample in samples:
             if first is None:
                 first = sample
                 pos = sample
                 continue
             pos += 1
             if sample != pos:
                 results[1] = AssertionError('Lost byte @ %d', pos - first)
                 return
     delta = now() - start
     results[1] = (rx_size, delta)
Beispiel #10
0
    def poll_cond(self,
                  address: int,
                  fmt: str,
                  mask: int,
                  value: int,
                  count: int,
                  relax: bool = True) -> Optional[bytes]:
        """Poll a remove slave, watching for condition to satisfy.
           On each poll cycle, a repeated start condition is emitted, without
           releasing the I2C bus, and an ACK is returned to the slave.

           If relax is set, this method releases the I2C bus however it leaves.

           :param address: the address on the I2C bus, or None to discard start
           :param fmt: struct format for poll register
           :param mask: binary mask to apply on the condition register
                before testing for the value
           :param value: value to test the masked condition register
                against. Condition is satisfied when register & mask == value
           :param count: maximum poll count before raising a timeout
           :param relax: whether to relax the bus (emit STOP) or not
           :return: the polled register value, or None if poll failed
        """
        if not self.configured:
            raise I2cIOError("FTDI controller not initialized")
        self.validate_address(address)
        if address is None:
            i2caddress = None
        else:
            i2caddress = (address << 1) & self.HIGH
            i2caddress |= self.BIT0
        do_epilog = True
        with self._lock:
            try:
                retry = 0
                while retry < count:
                    retry += 1
                    size = scalc(fmt)
                    self._do_prolog(i2caddress)
                    data = self._do_read(size)
                    self.log.debug("Poll data: %s", hexlify(data).decode())
                    cond, = sunpack(fmt, data)
                    if (cond & mask) == value:
                        self.log.debug('Poll condition matched')
                        break
                    else:
                        data = None
                        self.log.debug('Poll condition not fulfilled: %x/%x',
                                       cond & mask, value)
                do_epilog = relax
                if not data:
                    self.log.warning('Poll condition failed')
                return data
            except I2cNackError:
                self.log.info('Not ready')
                return None
            finally:
                if do_epilog:
                    self._do_epilog()
Beispiel #11
0
 def _decode_eeprom_string(self, offset):
     str_offset, str_size = sunpack('<BB', self._eeprom[offset:offset + 2])
     if str_size:
         str_size -= scalc('<H')
         str_offset += scalc('<H')
         manufacturer = self._eeprom[str_offset:str_offset + str_size]
         return manufacturer.decode('utf16', errors='ignore')
     return ''
 def _cmd_drive_zero(self):
     if len(self._trace_tx) < 3:
         return False
     value, = sunpack('H', self._trace_tx[1:3])
     self.log.info(' [%d]:Open collector [15:0] %04x %s', self._if, value,
                   self.bitfmt(value, 16))
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #13
0
 def _cmd_set_bits_high(self):
     if len(self._trace_tx) < 3:
         return False
     value, direction = sunpack('BB', self._trace_tx[1:3])
     self.log.info('Set gpio[15:8] %02x %s',
                   value, self.bits2str(value, direction))
     self._trace_tx[:] = self._trace_tx[3:]
     return True
 def _cmd_set_bits_low(self):
     if len(self._trace_tx) < 3:
         return False
     value, direction = sunpack('BB', self._trace_tx[1:3])
     self.log.info(' [%d]:Set gpio[7:0]  %02x %s', self._if, value,
                   self.bm2str(value, direction))
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #15
0
 def _handle_advertisement(self, adv):
     data = adv.service_data
     if not data:
         return
     type_fmt = f'<{self.SERVICE_FMT[0]}'
     size = scalc(type_fmt)
     if len(data) < size:
         return
     service, = sunpack(type_fmt, data[:size])
     data = data[size:]
     if service != self.ESS:
         return
     data_fmt = f'>{self.SERVICE_FMT[1:]}'
     size = scalc(data_fmt)
     if len(data) < size:
         self._log.warning('to short')
         return
     macbytes, temp, humi, bat, batv, packet = sunpack(data_fmt, data)
     if packet == self._last_packet and not self._all_msgs:
         return
     self._last_packet = packet
     mac = sum([b << (o << 3) for o, b in enumerate(reversed(macbytes))])
     oui = mac >> 24
     if oui != self.XIAOMI_OUI:
         return
     temp = float(temp) / 10.0
     batv = float(batv) / 1000.0
     payload = {
         'mac': adv.address.address,
         'temperature_C': temp,
         'humidity': humi,
         'battery': bat,
         'battery_v': batv,
         'packet': packet,
         'rssi': adv.rssi,
     }
     if 'event' in self._publish:
         jstr = f'{jdumps(payload)}\n'
         jbytes = jstr.encode()
         self._mqtt.publish(f'{self._source}/events', jbytes)
     if 'device' in self._publish:
         mac = adv.address.address
         for name, val in payload.items():
             if name == 'mac':
                 continue
             self._mqtt.publish(f'{self._source}/devices/{mac}/{name}', val)
Beispiel #16
0
 def _cmd_set_bits_high(self):
     if len(self._trace_tx) < 3:
         return False
     value, direction = sunpack('BB', self._trace_tx[1:3])
     self.log.info('Set gpio[15:8] %02x %s', value,
                   self.bits2str(value, direction))
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #17
0
 def _cmd_set_tck_divisor(self):
     if len(self._trace_tx) < 3:
         return False
     value, = sunpack('<H', self._trace_tx[1:3])
     base = self._clkdiv5 and 12E6 or 60E6
     freq = base / ((1 + value) * 2)
     self.log.info('Set frequency %.3fMHZ', freq/1E6)
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #18
0
 def find_interface(address: str) -> Optional[str]:
     iaddress = sunpack('!I', inet_aton(address))[0]
     for iface in interfaces():
         for confs in ifaddresses(iface).values():
             for conf in confs:
                 if all([x in conf for x in ('addr', 'netmask')]):
                     address = conf['addr']
                     if ':' in address:
                         # IPv6
                         continue
                     netmask = conf['netmask']
                     iaddr = sunpack('!I', inet_aton(address))[0]
                     inet = sunpack('!I', inet_aton(netmask))[0]
                     inic = iaddr & inet
                     ires = iaddress & inet
                     if inic == ires:
                         return iface
     return None
Beispiel #19
0
 def _cmd_set_tck_divisor(self):
     if len(self._trace_tx) < 3:
         return False
     value, = sunpack('<H', self._trace_tx[1:3])
     base = self._clkdiv5 and 12E6 or 60E6
     freq = base / ((1 + value) * 2)
     self.log.info('Set frequency %.3fMHZ', freq / 1E6)
     self._trace_tx[:] = self._trace_tx[3:]
     return True
Beispiel #20
0
 def poll_modem_status(self):
     """Poll modem status information
        This function allows the retrieve the two status bytes of the
        device.
     """
     value = self._ctrl_transfer_in(Ftdi.SIO_POLL_MODEM_STATUS, 2)
     if not value or len(value) != 2:
         raise FtdiError('Unable to get modem status')
     status, = sunpack('<H', value)
     return status
Beispiel #21
0
    def poll_cond(self, address, fmt, mask, value, count, relax=True):
        """Poll a remove slave, watching for condition to satisfy.
           On each poll cycle, a repeated start condition is emitted, without
           releasing the I2C bus, and an ACK is returned to the slave.

           If relax is set, this method releases the I2C bus however it leaves.

           :param address: the address on the I2C bus, or None to discard start
           :type address: int or None
           :param str fmt: struct format for poll register
           :param int mask: binary mask to apply on the condition register
                before testing for the value
           :param int value: value to test the masked condition register
                against. Condition is satisfied when register & mask == value
           :param int count: maximum poll count before raising a timeout
           :param bool relax: whether to relax the bus (emit STOP) or not
           :return: the polled register value, or None if poll failed
           :rtype: array or None
        """
        if not self.configured:
            raise I2cIOError("FTDI controller not initialized")
        self.validate_address(address)
        if address is None:
            i2caddress = None
        else:
            i2caddress = (address << 1) & self.HIGH
            i2caddress |= self.BIT0
        do_epilog = True
        try:
            retry = 0
            while retry < count:
                retry += 1
                size = scalc(fmt)
                self._do_prolog(i2caddress)
                data = self._do_read(size)
                self.log.debug("Poll data: %s", hexlify(data).decode())
                cond, = sunpack(fmt, data)
                if (cond & mask) == value:
                    self.log.debug('Poll condition matched')
                    break
                else:
                    data = None
                    self.log.debug('Poll condition not fulfilled: %x/%x',
                                   cond & mask, value)
            do_epilog = relax
            if not data:
                self.log.warning('Poll condition failed')
            return data
        except I2cNackError:
            self.log.info('Not ready')
            return None
        finally:
            if do_epilog:
                self._do_epilog()
Beispiel #22
0
 def _handle_advertisement(self, adv):
     data = adv.service_data
     if not data:
         return
     type_fmt = f'<{self.SERVICE_FMT[0]}'
     size = scalc(type_fmt)
     if len(data) < size:
         return
     service, = sunpack(type_fmt, data[:size])
     data = data[size:]
     if service != self.ESS:
         return
     data_fmt = f'>{self.SERVICE_FMT[1:]}'
     size = scalc(data_fmt)
     if len(data) < size:
         self._log.warning('to short')
         return
     macbytes, temp, humi, bat, batv, packet = sunpack(data_fmt, data)
     mac = sum([b << (o << 3) for o, b in enumerate(reversed(macbytes))])
     oui = mac >> 24
     if oui != self.XIAOMI_OUI:
         return
     temp = float(temp) / 10.0
     batv = float(batv) / 1000.0
     json = {
         'mac': adv.address.address,
         'temperature': temp,
         'humidity': humi,
         'battery': bat,
         'battery_v': batv,
         'packet': packet,
         'rssi': adv.rssi,
     }
     jstr = f'{jdumps(json)}\n'
     jbytes = jstr.encode()
     with self._qlock:
         if self._channels:
             self._log.debug('Notify %d clients', len(self._channels))
         for channel in self._channels:
             channel.queue.append(jbytes)
             channel.event.set()
Beispiel #23
0
 def _decode_mpsse_bytes(self):
     caller = stack()[1].function
     if len(self._trace_tx) < 4:
         return False
     length = sunpack('<H', self._trace_tx[1:3])[0] + 1
     if len(self._trace_tx) < 4 + length:
         return False
     payload = self._trace_tx[3:3 + length]
     funcname = caller[5:].title().replace('_', ' ')
     self.log.info('%s (%d) %s', funcname, length,
                   hexlify(payload).decode('utf8'))
     self._trace_tx[:] = self._trace_tx[3 + length:]
     return True
Beispiel #24
0
 def _cmd_set_bits_low(self):
     buf = self._trace_tx[1:3]
     if not super()._cmd_set_bits_low():
         return False
     port = self._port
     byte, direction = sunpack('BB', buf)
     gpi = port.gpio & ~direction & self._mask
     gpo = byte & direction & self._mask
     msb = port.gpio & ~0xFF
     gpio = gpi | gpo | msb
     port.update_gpio(self, False, direction, gpio)
     self.log.debug('. bbwl %04x: %s', port.gpio, f'{port.gpio:016b}')
     return True
 def _decode_output_mpsse_bytes(self, caller, expect_rx=False):
     if len(self._trace_tx) < 4:
         return False
     length = sunpack('<H', self._trace_tx[1:3])[0] + 1
     if len(self._trace_tx) < 4 + length:
         return False
     if expect_rx:
         self._expect_resp.append(length)
     payload = self._trace_tx[3:3 + length]
     funcname = caller[5:].title().replace('_', '')
     self.log.info(' [%d]:%s> (%d) %s', self._if, funcname, length,
                   hexlify(payload).decode('utf8'))
     self._trace_tx[:] = self._trace_tx[3 + length:]
     return True
Beispiel #26
0
 def _read_raw(self, read_high):
     if read_high:
         cmd = bytearray(
             [Ftdi.GET_BITS_LOW, Ftdi.GET_BITS_HIGH, Ftdi.SEND_IMMEDIATE])
         fmt = '<H'
     else:
         cmd = bytearray([Ftdi.GET_BITS_LOW, Ftdi.SEND_IMMEDIATE])
         fmt = 'B'
     self._ftdi.write_data(cmd)
     size = scalc(fmt)
     data = self._ftdi.read_data_bytes(size, 4)
     if len(data) != size:
         raise SpiIOError('Cannot read GPIO')
     value, = sunpack(fmt, data)
     return value
Beispiel #27
0
 def _decode_output_mpsse_bytes(self, expect_rx=False):
     caller = stack()[1].function
     if len(self._trace_tx) < 4:
         return False
     length = sunpack('<H', self._trace_tx[1:3])[0] + 1
     if len(self._trace_tx) < 4 + length:
         return False
     if expect_rx:
         self._expect_resp.append(length)
     payload = self._trace_tx[3:3+length]
     funcname = caller[5:].title().replace('_', '')
     self.log.info('%s> (%d) %s',
                   funcname, length, hexlify(payload).decode('utf8'))
     self._trace_tx[:] = self._trace_tx[3+length:]
     return True
Beispiel #28
0
    def data_received(self, data):
        logger.debug('got %d bytes from reader: %s', len(data),
                     hexlify(data).decode())

        if self.expectingRemainingBytes:
            if len(data) >= self.expectingRemainingBytes:
                data = self.partialData + data
                self.partialData = ''
                self.expectingRemainingBytes -= len(data)
            else:
                # still not enough; wait until next time
                self.partialData += data
                self.expectingRemainingBytes -= len(data)
                return

        while data:
            # parse the message header to grab its length
            if len(data) >= LLRPMessage.full_hdr_len:
                msg_type, msg_len, message_id = \
                    sunpack(LLRPMessage.full_hdr_fmt,
                            data[:LLRPMessage.full_hdr_len])
            else:
                logger.warning('Too few bytes (%d) to unpack message header',
                               len(data))
                self.partialData = data
                self.expectingRemainingBytes = \
                    LLRPMessage.full_hdr_len - len(data)
                break

            logger.debug('expect %d bytes (have %d)', msg_len, len(data))

            if len(data) < msg_len:
                # got too few bytes
                self.partialData = data
                self.expectingRemainingBytes = msg_len - len(data)
                break
            else:
                # got at least the right number of bytes
                self.expectingRemainingBytes = 0
                try:
                    lmsg = LLRPMessage(msgbytes=data[:msg_len])
                    self.handleMessage(lmsg)
                    data = data[msg_len:]
                except LLRPError:
                    logger.exception(
                        'Failed to decode LLRPMessage; '
                        'will not decode %d remaining bytes', len(data))
                    break
Beispiel #29
0
 def _read_raw(self, read_high: bool) -> int:
     if not self._ftdi.is_connected:
         raise SpiIOError("FTDI controller not initialized")
     if read_high:
         cmd = bytes(
             [Ftdi.GET_BITS_LOW, Ftdi.GET_BITS_HIGH, Ftdi.SEND_IMMEDIATE])
         fmt = '<H'
     else:
         cmd = bytes([Ftdi.GET_BITS_LOW, Ftdi.SEND_IMMEDIATE])
         fmt = 'B'
     self._ftdi.write_data(cmd)
     size = scalc(fmt)
     data = self._ftdi.read_data_bytes(size, 4)
     if len(data) != size:
         raise SpiIOError('Cannot read GPIO')
     value, = sunpack(fmt, data)
     return value
Beispiel #30
0
 def _read_raw(self, read_high):
     if read_high:
         cmd = array('B', [Ftdi.GET_BITS_LOW,
                           Ftdi.GET_BITS_HIGH,
                           Ftdi.SEND_IMMEDIATE])
         fmt = '<H'
     else:
         cmd = array('B', [Ftdi.GET_BITS_LOW,
                           Ftdi.SEND_IMMEDIATE])
         fmt = 'B'
     self._ftdi.write_data(cmd)
     size = scalc(fmt)
     data = self._ftdi.read_data_bytes(size, 4)
     if len(data) != size:
         raise SpiIOError('Cannot read GPIO')
     value, = sunpack(fmt, data)
     return value
Beispiel #31
0
    def _read_raw(self, read_high):
        if read_high:
            cmd = array(
                'B',
                [Ftdi.GET_BITS_LOW, Ftdi.GET_BITS_HIGH, Ftdi.SEND_IMMEDIATE])
            fmt = '<H'
            self._ftdi.write_data(cmd)
            size = scalc(fmt)
            data = self._ftdi.read_data_bytes(size, 4)
            if len(data) != size:
                raise GpioException('Cannot read GPIO')
            value, = sunpack(fmt, data)
        else:
            # If not using read_high method, then also means this is
            # BIT BANG and not MPSSE, so just use read_pins()
            value = self._ftdi.read_pins()

        return value
Beispiel #32
0
 def _read_mpsse(self, count: int) -> Tuple[int]:
     if self._width > 8:
         cmd = bytearray([Ftdi.GET_BITS_LOW, Ftdi.GET_BITS_HIGH] * count)
         fmt = '<%dH' % count
     else:
         cmd = bytearray([Ftdi.GET_BITS_LOW] * count)
         fmt = None
     cmd.append(Ftdi.SEND_IMMEDIATE)
     if len(cmd) > self.MPSSE_PAYLOAD_MAX_LENGTH:
         raise ValueError('Too many samples')
     self._ftdi.write_data(cmd)
     size = scalc(fmt) if fmt else count
     data = self._ftdi.read_data_bytes(size, 4)
     if len(data) != size:
         raise FtdiError('Cannot read GPIO')
     if fmt:
         return sunpack(fmt, data)
     return data
Beispiel #33
0
 def _decode_230x(self):
     cfg = self._config
     misc, = sunpack('<H', self._eeprom[0x00:0x02])
     cfg['channel_a_driver'] = 'VCP' if misc & (1 << 7) else 'D2XX'
     for bit in self.INVERT:
         value = self._eeprom[0x0B]
         cfg['invert_%s' % self.INVERT(bit).name] = bool(value & bit)
     max_drive = self.DRIVE.LOW | self.DRIVE.HIGH
     value = self._eeprom[0x0c]
     for grp in range(2):
         conf = value &0xF
         cfg['group_%d_drive' % grp] = bool((conf & max_drive) == max_drive)
         cfg['group_%d_schmitt' % grp] = conf & self.DRIVE.SCHMITT
         cfg['group_%d_slew' % grp] = conf & self.DRIVE.SLOW_SLEW
         value >>= 4
     for bix in range(4):
         value = self._eeprom[0x1A + bix]
         cfg['cbus_func_%d' % bix] = self.CBUSX(value).name
     cfg['chip'] = Hex2Int(self._eeprom[0x1E])
Beispiel #34
0
 def _decode_x(self):
     # FT-X series
     cfg = self._config
     misc, = sunpack('<H', self._eeprom[0x00:0x02])
     cfg['channel_a_driver'] = 'VCP' if misc & (1 << 7) else 'D2XX'
     for bit in self.UART_BITS:
         value = self._eeprom[0x0B]
         cfg['invert_%s' % self.UART_BITS(bit).name] = bool(value & bit)
     max_drive = self.DRIVE.LOW.value | self.DRIVE.HIGH.value
     value = self._eeprom[0x0c]
     for grp in range(2):
         conf = value & 0xF
         bus = 'c' if grp else 'd'
         cfg['%sbus_drive' % bus] = 4 * (1+(conf & max_drive))
         cfg['%sbus_schmitt' % bus] = bool(conf & self.DRIVE.SCHMITT)
         cfg['%sbus_slow_slew' % bus] = bool(conf & self.DRIVE.SLOW_SLEW)
         value >>= 4
     for bix in range(4):
         value = self._eeprom[0x1A + bix]
         try:
             cfg['cbus_func_%d' % bix] = self.CBUSX(value).name
         except ValueError:
             pass
Beispiel #35
0
    def handle(self):
        while True:
            chunk = self.connection.recv(4)
            if len(chunk) < 4:
                break
            slen = sunpack('>L', chunk)[0]
            chunk = self.connection.recv(slen)
            while len(chunk) < slen:
                chunk = chunk + self.connection.recv(slen - len(chunk))

            record = self.unpickle(chunk)
            logger = logging.getLogger(record.name)
            if not logger.handlers:
                if config_dict.get("is_detail"):
                    formatter = logging.Formatter(config_dict["dfmt"])
                else:
                    formatter = logging.Formatter(config_dict["fmt"])
                handler = TimedRotatingFileHandler(
                    record.name,
                    when=config_dict["when"],
                    backupCount=config_dict["backup_count"])
                handler.setFormatter(formatter)
                logger.addHandler(handler)
            logger.handle(record)
Beispiel #36
0
def iptoint(ipstr):
    return sunpack('!I', inet_aton(ipstr))[0]