From f82ff3fdf6c43449ee9c134067e0a033a840650d Mon Sep 17 00:00:00 2001 From: arturo182 Date: Sun, 22 May 2022 18:23:29 +0200 Subject: [PATCH] Add the vendor python library --- etc/i2c_puppet.py | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 etc/i2c_puppet.py diff --git a/etc/i2c_puppet.py b/etc/i2c_puppet.py new file mode 100644 index 0000000..ba6d370 --- /dev/null +++ b/etc/i2c_puppet.py @@ -0,0 +1,130 @@ +import usb + + +_REG_VER = 0x01 # fw version +_REG_CFG = 0x02 # config +_REG_INT = 0x03 # interrupt status +_REG_KEY = 0x04 # key status +_REG_BKL = 0x05 # backlight +_REG_DEB = 0x06 # debounce cfg +_REG_FRQ = 0x07 # poll freq cfg +_REG_RST = 0x08 # reset +_REG_FIF = 0x09 # fifo +_REG_BK2 = 0x0A # backlight 2 +_REG_DIR = 0x0B # gpio direction +_REG_PUE = 0x0C # gpio input pull enable +_REG_PUD = 0x0D # gpio input pull direction +_REG_GIO = 0x0E # gpio value +_REG_GIC = 0x0F # gpio interrupt config +_REG_GIN = 0x10 # gpio interrupt status +_REG_HLD = 0x11 # key hold time cfg (in 10ms units) +_REG_ADR = 0x12 # i2c puppet address +_REG_IND = 0x13 # interrupt pin assert duration +_REG_CF2 = 0x14 # config 2 +_REG_TOX = 0x15 # touch delta x since last read, at most (-128 to 127) +_REG_TOY = 0x16 # touch delta y since last read, at most (-128 to 127) + +_WRITE_MASK = 1 << 7 + +CFG_OVERFLOW_ON = 1 << 0 +CFG_OVERFLOW_INT = 1 << 1 +CFG_CAPSLOCK_INT = 1 << 2 +CFG_NUMLOCK_INT = 1 << 3 +CFG_KEY_INT = 1 << 4 +CFG_PANIC_INT = 1 << 5 +CFG_REPORT_MODS = 1 << 6 +CFG_USE_MODS = 1 << 7 + +CF2_TOUCH_INT = 1 << 0 +CF2_USB_KEYB_ON = 1 << 1 +CF2_USB_MOUSE_ON = 1 << 2 + +INT_OVERFLOW = 1 << 0 +INT_CAPSLOCK = 1 << 1 +INT_NUMLOCK = 1 << 2 +INT_KEY = 1 << 3 +INT_PANIC = 1 << 4 +INT_GPIO = 1 << 5 +INT_TOUCH = 1 << 6 + +KEY_CAPSLOCK = 1 << 5 +KEY_NUMLOCK = 1 << 6 +KEY_COUNT_MASK = 0x1F + +DIR_OUTPUT = 0 +DIR_INPUT = 1 + +PUD_DOWN = 0 +PUD_UP = 1 + + +class I2CPuppet: + def __init__(self, vid=0x1209, pid=0xB182): + self._buffer = bytearray(2) + self._dev = usb.core.find(idVendor=vid, idProduct=pid) + + if self._dev is None: + raise Exception('Device with vid:pid %04X:%04X not found!' % (vid, pid)) + + conf = self._dev.get_active_configuration() + itf = usb.util.find_descriptor(conf, bInterfaceClass=usb.CLASS_VENDOR_SPEC) + + self._ep_out = usb.util.find_descriptor(itf, custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT) + self._ep_in = usb.util.find_descriptor(itf, custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN) + + if (self._ep_out is None) or (self._ep_in is None): + raise Exception('Vendor IN or OUT endpoint not found!') + + @property + def version(self): + ver = self._read_register(_REG_VER) + return (ver >> 4, ver & 0x0F) + + @property + def status(self): + return self._read_register(_REG_KEY) + + @property + def backlight(self): + return self._read_register(_REG_BKL) / 255 + + @backlight.setter + def backlight(self, value): + self._write_register(_REG_BKL, int(255 * value)) + + @property + def address(self): + return self._read_register(_REG_ADR) + + @address.setter + def address(self, value): + self._write_register(_REG_ADR, value) + + def _read_register(self, reg): + self._buffer[0] = reg + self._dev.write(self._ep_out, self._buffer[:1]) + + return self._dev.read(self._ep_in, 1)[0] + + def _write_register(self, reg, value): + self._buffer[0] = reg | _WRITE_MASK + self._buffer[1] = value + self._dev.write(self._ep_out, self._buffer) + + def _update_register_bit(self, reg, bit, value): + + reg_val = self._read_register(reg) + old_val = reg_val + + if value: + reg_val |= (1 << bit) + else: + reg_val &= ~(1 << bit) + + if reg_val != old_val: + self._write_register(reg, reg_val) + + def _get_register_bit(self, reg, bit): + return self._read_register(reg) & (1 << bit) != 0 + + keyboard_backlight = backlight