Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _read_raw(self, read_high: bool) -> int:
if read_high:
cmd = bytes([Ftdi.GET_BITS_LOW,
Ftdi.GET_BITS_HIGH,
Ftdi.SEND_IMMEDIATE])
fmt = '
def validate_address(cls, address: int) -> None:
"""Assert an I2C slave address is in the supported range.
None is a special bypass address.
:param address: the address on the I2C bus
:raise I2cIOError: if the I2C slave address is not supported
"""
if address is None:
return
if address > cls.HIGHEST_I2C_ADDRESS:
raise I2cIOError("No such I2c slave: 0x%02x" % address)
relax: bool = True) -> None:
"""Write one or more bytes to a remote slave
:param address: the address on the I2C bus, or None to discard start
:param out: the byte buffer to send
:param relax: whether to relax the bus (emit STOP) or not
:raise I2cIOError: if device is not configured or input parameters
are invalid
Address is a logical slave address (0x7f max)
Most I2C devices require a register address to write into. It should
be added as the first (byte)s of the output buffer.
"""
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
retries = self._retry_count
do_epilog = True
with self._lock:
while True:
try:
self._do_prolog(i2caddress)
self._do_write(out)
do_epilog = relax
return
except I2cNackError:
retries -= 1
This command is useful to tell the slave what data
should be read out.
:param address: the address on the I2C bus, or None to discard start
:param out: the byte buffer to send
:param readlen: count of bytes to read out.
:param relax: whether to relax the bus (emit STOP) or not
:return: read bytes
:raise I2cIOError: if device is not configured or input parameters
are invalid
Address is a logical slave address (0x7f max)
"""
if not self.configured:
raise I2cIOError("FTDI controller not initialized")
self.validate_address(address)
if readlen < 1:
raise I2cIOError('Nothing to read')
if readlen > (self.PAYLOAD_MAX_LENGTH/3-1):
raise I2cIOError("Input payload is too large")
if address is None:
i2caddress = None
else:
i2caddress = (address << 1) & self.HIGH
retries = self._retry_count
do_epilog = True
with self._lock:
while True:
try:
self._do_prolog(i2caddress)
self._do_write(out)
# SCL low, SDA high-Z (input)
cmd.extend(self._clk_lo_data_input)
# read SDA (ack from slave)
cmd.extend(self._read_bit)
# leave SCL low, restore SDA as output
cmd.extend(self._clk_lo_data_hi)
else:
# SCL low, SDA high-Z
cmd.extend(self._clk_lo_data_hi)
# read SDA (ack from slave)
cmd.extend(self._read_bit)
cmd.extend(self._immediate)
self._ftdi.write_data(cmd)
ack = self._ftdi.read_data_bytes(1, 4)
if not ack:
raise I2cIOError('No answer from FTDI')
if ack[0] & self.BIT0:
raise I2cNackError('NACK from slave')
fcntl.ioctl(self.io.fileno(), I2C_RDWR, request)
byte_ = int(result.value)
message = "Read register 0x{:02X}, value: 0x{:02X}".format(
register, byte_
)
self.logger.debug(message)
return byte_
elif os.getenv("IS_USB_I2C_ENABLED") == "true":
device = self.io.get_port(address) # type: ignore
byte_raw = device.read_from(register, readlen=1)
byte = int(byte_raw[0])
return byte
else:
message = "Platform does not support i2c communication"
raise ReadError(message)
except (IOError, I2cIOError, I2cNackError) as e:
message = "Unable to read register 0x{:02}".format(register)
raise ReadError(message) from e
"""Read one or more bytes from a remote slave
:param address: the address on the I2C bus, or None to discard start
:param readlen: count of bytes to read out.
:param relax: not used
:return: read bytes
:raise I2cIOError: if device is not configured or input parameters
are invalid
Address is a logical slave address (0x7f max)
Most I2C devices require a register address to read out
check out the exchange() method.
"""
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
retries = self._retry_count
do_epilog = True
with self._lock:
while True:
try:
self._do_prolog(i2caddress)
data = self._do_read(readlen)
do_epilog = relax
return data
except I2cNackError:
def _set_gpio_direction(self, width: int, pins: int,
direction: int) -> None:
if pins & self._i2c_mask:
raise I2cIOError('Cannot access I2C pins as GPIO')
gpio_mask = (1 << width) - 1
gpio_mask &= ~self._i2c_mask
if (pins & gpio_mask) != pins:
raise I2cIOError('No such GPIO pin(s)')
self._gpio_dir &= ~pins
self._gpio_dir |= (pins & direction)
self._gpio_mask = gpio_mask & pins
def write(self, address: int, bytes_: bytes) -> None:
""" Writes bytes to IO stream. """
try:
if os.getenv("IS_I2C_ENABLED") == "true":
fcntl.ioctl(self.io, I2C_SLAVE, address)
self.io.write(bytes_)
elif os.getenv("IS_USB_I2C_ENABLED") == "true":
device = self.io.get_port(address) # type: ignore
device.write(bytes_)
else:
message = "Platform does not support i2c communication"
raise WriteError(message)
except (IOError, I2cIOError, I2cNackError) as e:
message = "Unable to write: {}".format(bytes_)
raise WriteError(message) from e
def configure_register(self,
bigendian: bool = False, width: int = 1) -> None:
"""Reconfigure the format of the slave address register (if any)
:param bigendian: True for a big endian encoding, False otherwise
:param width: width, in bytes, of the register
"""
try:
self._format = self.FORMATS[width]
except KeyError:
raise I2cIOError('Unsupported integer width')
self._endian = '>' if bigendian else '<'