Source code for usb_iss.i2c

from .exceptions import UsbIssError
from . import defs

I2C_RD = 0x01


[docs]class I2C(object): """ Use the USB_ISS device to perform I2C accesses. Example: :: from usb_iss import UsbIss, defs # Configure I2C mode iss = UsbIss() iss.open("COM3") iss.setup_i2c() # Write and read back some data # NOTE: I2C methods use 7-bit device addresses (0x00 - 0x7F) iss.i2c.write(0x62, 0, [0, 1, 2]); data = iss.i2c.read(0x62, 0, 3) print(data) # [0, 1, 2] """ def __init__(self, drv): self._drv = drv
[docs] def write(self, address, register, data): """ Write multiple bytes to a device with a one-byte internal register address. This is an alias for the write_ad1 method, used by the majority of devices. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). register (int): Internal register address to write (0x00 - 0xFF). data (list of int): List of bytes to write to the device. """ self.write_ad1(address, register, data)
[docs] def read(self, address, register, byte_count): """ Read multiple bytes from a device with a one-byte internal register address. This is an alias for the read_ad1 method, used by the majority of devices. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). register (int): Internal register address to read (0x00 - 0xFF). byte_count (int): Number of bytes to read. Returns: list of int: List of bytes read from the device. """ return self.read_ad1(address, register, byte_count)
[docs] def write_single(self, address, data_byte): """ Write a single byte to an I2C device. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). data_byte (int): Data byte to write to the device. """ address_8bit = address << 1 self._drv.write_cmd(defs.Command.I2C_SGL.value, [address_8bit, data_byte]) self._drv.check_i2c_ack()
[docs] def read_single(self, address): """ Read a single byte from an I2C device. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). Returns: int: Data byte read from the device. """ address_8bit = (address << 1) | I2C_RD self._drv.write_cmd(defs.Command.I2C_SGL.value, [address_8bit]) return self._drv.read(1)[0]
[docs] def write_ad0(self, address, data): """ Write multiple bytes to a device without internal register addressing, or where the internal register address does not require resetting. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). data (list of int): List of bytes to write to the device. """ address_8bit = address << 1 self._drv.write_cmd(defs.Command.I2C_AD0.value, [address_8bit, len(data)] + data) self._drv.check_i2c_ack()
[docs] def read_ad0(self, address, byte_count): """ Read multiple bytes from a device without internal register addressing, or where the internal register address does not require resetting. Args: address (int): 7-bit I2C address of the device. byte_count (int): Number of bytes to read. Returns: list of int: List of bytes read from the device. """ address_8bit = (address << 1) | I2C_RD self._drv.write_cmd(defs.Command.I2C_AD0.value, [address_8bit, byte_count]) return self._drv.read(byte_count)
[docs] def write_ad1(self, address, register, data): """ Write multiple bytes to a device with a one-byte internal register address. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). register (int): Internal register address to write (0x00 - 0xFF). data (list of int): List of bytes to write to the device. """ if len(data) > defs.I2C_AD1_MAX_WRITE_BYTE_COUNT: raise UsbIssError( "Attempted to write %d bytes, maximum is %d" % (len(data), defs.I2C_AD1_MAX_WRITE_BYTE_COUNT)) address_8bit = address << 1 self._drv.write_cmd(defs.Command.I2C_AD1.value, [address_8bit, register, len(data)] + data) self._drv.check_i2c_ack()
[docs] def read_ad1(self, address, register, byte_count): """ Read multiple bytes from a device with a one-byte internal register address. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). register (int): Internal register address to read (0x00 - 0xFF). byte_count (int): Number of bytes to read. Returns: list of int: List of bytes read from the device. """ if byte_count > defs.I2C_AD1_MAX_READ_BYTE_COUNT: raise UsbIssError( "Attempted to read %d bytes, maximum is %d" % (byte_count, defs.I2C_AD1_MAX_READ_BYTE_COUNT)) address_8bit = (address << 1) | I2C_RD self._drv.write_cmd(defs.Command.I2C_AD1.value, [address_8bit, register, byte_count]) return self._drv.read(byte_count)
[docs] def write_ad2(self, address, register, data): """ Write multiple bytes to a device with a two-byte internal register address. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). register (int): Internal register address to write (0x0000 - 0xFFFF). data (list of int): List of bytes to write to the device. """ if len(data) > defs.I2C_AD2_MAX_WRITE_BYTE_COUNT: raise UsbIssError( "Attempted to write %d bytes, maximum is %d" % (len(data), defs.I2C_AD2_MAX_WRITE_BYTE_COUNT)) address_8bit = address << 1 reg_high = register >> 8 reg_low = register & 0xFF self._drv.write_cmd( defs.Command.I2C_AD2.value, [address_8bit, reg_high, reg_low, len(data)] + data) self._drv.check_i2c_ack()
[docs] def read_ad2(self, address, register, byte_count): """ Read multiple bytes from a device with a two-byte internal register address. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). register (int): Internal register address to read (0x0000 - 0xFFFF). byte_count (int): Number of bytes to read. Returns: list of int: List of bytes read from the device. """ if byte_count > defs.I2C_AD2_MAX_READ_BYTE_COUNT: raise UsbIssError( "Attempted to read %d bytes, maximum is %d" % (byte_count, defs.I2C_AD2_MAX_READ_BYTE_COUNT)) address_8bit = (address << 1) | I2C_RD reg_high = register >> 8 reg_low = register & 0xFF self._drv.write_cmd(defs.Command.I2C_AD2.value, [address_8bit, reg_high, reg_low, byte_count]) return self._drv.read(byte_count)
[docs] def direct(self, data): """ Send a custom I2C sequence to the device. See https://www.robot-electronics.co.uk/htm/usb_iss_i2c_tech.htm for a full set of examples. Args: data (list of defs.I2CDirect): List of :class:`~usb_iss.defs.I2CDirect` commands and data. Returns: list of int: List of bytes read from the device. Example: :: # Equivalent to iss.i2c.write_single(0x20, 0x55) iss.i2c.direct([ defs.I2CDirect.START, defs.I2CDirect.WRITE2, 0x40, 0x55, defs.I2CDirect.STOP, ]); """ # Convert any I2CDirect items to the corresponding value def convert_to_value(byte): if isinstance(byte, defs.I2CDirect): return byte.value else: return byte bytes = [convert_to_value(byte) for byte in data] self._drv.write_cmd(defs.Command.I2C_DIRECT.value, bytes) bytes_to_read = self._drv.check_ack_error_code(defs.I2CDirectError) return self._drv.read(bytes_to_read)
[docs] def test(self, address): """ Check whether a device responds at the specified I2C addresss. Args: address (int): 7-bit I2C address of the device (0x00 - 0x7F). Returns: bool: True if the device responds with an ACK. """ address_8bit = address << 1 self._drv.write_cmd(defs.Command.I2C_TEST.value, [address_8bit]) return self._drv.read(1) != [defs.ResponseCode.NACK.value]