+class I2C(Lockable):
+ def __init__(self, scl, sda, frequency=400000):
+ self.init(scl, sda, frequency)
+
+ def init(self, scl, sda, frequency):
+ self.deinit()
+ from machine import I2C as _I2C
+ from microcontroller.pin import i2cPorts
+ for portId, portScl, portSda in i2cPorts:
+ if scl == portScl and sda == portSda:
+ self._i2c = I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
+ break
+ else:
+ raise NotImplementedError("No Hardware I2C on (scl,sda)={}\nValid UART ports".format(
+ (scl, sda), i2cPorts))
+
+ def deinit(self):
+ try:
+ del self._i2c
+ except AttributeError:
+ pass
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.deinit()
+
+ def scan(self):
+ return self._i2c.scan()
+
+ def readfrom_into(self, address, buffer, start=0, end=None):
+ if start is not 0 or end is not None:
+ if end is None:
+ end = len(buffer)
+ buffer = memoryview(buffer)[start:end]
+ stop = True # remove for efficiency later
+ return self._i2c.readfrom_into(address, buffer, stop)
+
+ def writeto(self, address, buffer, start=0, end=None, stop=True):
+ if start is not 0 or end is not None:
+ if end is None:
+ return self._i2c.writeto(address, memoryview(buffer)[start:], stop)
+ else:
+ return self._i2c.writeto(address, memoryview(buffer)[start:end], stop)
+ return self._i2c.writeto(address, buffer, stop)
+