I asked Claude to make PiicoDev_Unified.py compatible with the Adafruit MCP2221A Breakout and the fix was surprisingly simple.
Changes to PiicoDev_Unified.py involved a new I2C class to wrap the pre-instantiated SMBus compatible class provided by the Easy MCP2221 library, and an extra few lines of logic in the create_unified_i2c method.
I’ve tested it with the buzzer, aq, and atmospheric pressure sensors so far, and it seems to work fine.
Modified code if anyone’s interested.
class I2CUnifiedSMBus(I2CBase):
"""Wraps a pre-instantiated SMBus-compatible object (e.g. EasyMCP2221.SMBus)."""
def __init__(self, bus):
self.i2c = bus
def writeto_mem(self, addr, memaddr, buf, *, addrsize=8):
if addrsize == 8:
self.i2c.write_i2c_block_data(addr, memaddr, list(buf))
elif addrsize == 16:
reg_high = (memaddr >> 8) & 0xFF
reg_low = memaddr & 0xFF
self.i2c.write_i2c_block_data(addr, reg_high, [reg_low] + list(buf))
else:
raise Exception('addrsize must be 8 or 16')
def readfrom_mem(self, addr, memaddr, nbytes, *, addrsize=8):
if addrsize == 8:
return self.i2c.read_i2c_block_data(addr, memaddr, nbytes)
elif addrsize == 16:
reg_high = (memaddr >> 8) & 0xFF
reg_low = memaddr & 0xFF
return self.i2c.read_i2c_block_data(addr, reg_high, nbytes)
else:
raise Exception('addrsize must be 8 or 16')
def write8(self, addr, reg, data):
if reg is None:
d = int.from_bytes(data, 'big')
self.i2c.write_byte(addr, d)
else:
r = int.from_bytes(reg, 'big')
d = int.from_bytes(data, 'big')
self.i2c.write_byte_data(addr, r, d)
def read16(self, addr, reg):
regInt = int.from_bytes(reg, 'big')
val = self.i2c.read_word_data(addr, regInt)
return val.to_bytes(2, byteorder='little', signed=False)
def scan(self):
pass
def create_unified_i2c(bus=None, freq=None, sda=None, scl=None, suppress_warnings=True):
if _SYSNAME == 'microbit':
i2c = I2CUnifiedMicroBit(freq=freq)
elif _SYSNAME == 'Linux':
if bus is not None and not isinstance(bus, int):
i2c = I2CUnifiedSMBus(bus)
else:
i2c = I2CUnifiedLinux(bus=bus, suppress_warnings=suppress_warnings)
else:
i2c = I2CUnifiedMachine(bus=bus, freq=freq, sda=sda, scl=scl)
return i2c