#!/usr/bin/env python3 """Probe I2C EEPROM address setting on Genpix SkyWalker-1.""" import usb.core, usb.util, time dev = usb.core.find(idVendor=0x09C0, idProduct=0x0203) for cfg in dev: for intf in cfg: if dev.is_kernel_driver_active(intf.bInterfaceNumber): dev.detach_kernel_driver(intf.bInterfaceNumber) break try: dev.set_configuration() except: pass I2C_READ = 0x84 I2C_WRITE = 0x83 def vin(req, value=0, index=0, length=64): try: return dev.ctrl_transfer( usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_IN, req, value, index, length, 2000) except: return None def vout(req, value=0, index=0, data=b''): try: return dev.ctrl_transfer( usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_OUT, req, value, index, data, 2000) except Exception as e: print(f" OUT error: {e}") return None # Known first 8 bytes at offset 0: c2 c0 09 03 02 00 00 40 # Known bytes at offset 8 (from our read): 03 ff 00 00 02 18 8d 30 REF_0 = "c2 c0 09 03 02 00 00 40" REF_8 = "03 ff 00 00 02 18 8d 30" def show(label, data): if data is not None: h = bytes(data[:8]).hex(' ') match = "" if h == REF_0: match = " <-- OFFSET 0" elif h == REF_8: match = " <-- OFFSET 8" print(f" {label}: {h}{match}") else: print(f" {label}: FAILED") print("=== Approach 1: I2C_WRITE data=[addr_h, addr_l], then I2C_READ ===") vout(I2C_WRITE, 0x51, 0, bytes([0x00, 0x08])) show("After set 0x0008", vin(I2C_READ, 0x51, 0, 8)) vout(I2C_WRITE, 0x51, 0, bytes([0x00, 0x00])) show("After set 0x0000", vin(I2C_READ, 0x51, 0, 8)) print("\n=== Approach 2: wValue=addr, wIndex=slave ===") vout(I2C_WRITE, 0x0008, 0x51) show("After set 0x0008", vin(I2C_READ, 0x51, 0, 8)) vout(I2C_WRITE, 0x0000, 0x51) show("After set 0x0000", vin(I2C_READ, 0x51, 0, 8)) print("\n=== Approach 3: wValue=slave, wIndex=addr ===") vout(I2C_WRITE, 0x51, 0x0008) show("After set 0x0008", vin(I2C_READ, 0x51, 0, 8)) vout(I2C_WRITE, 0x51, 0x0000) show("After set 0x0000", vin(I2C_READ, 0x51, 0, 8)) print("\n=== Approach 4: I2C_READ with wIndex=offset ===") show("wIndex=0x0000", vin(I2C_READ, 0x51, 0x0000, 8)) show("wIndex=0x0008", vin(I2C_READ, 0x51, 0x0008, 8)) show("wIndex=0x0040", vin(I2C_READ, 0x51, 0x0040, 8)) print("\n=== Approach 5: I2C_READ with (slave<<8|offset) in wValue ===") show("wValue=0x5100", vin(I2C_READ, 0x5100, 0, 8)) show("wValue=0x5108", vin(I2C_READ, 0x5108, 0, 8)) print("\n=== Approach 6: I2C_READ with wValue=offset (no slave) ===") show("wValue=0x0000", vin(I2C_READ, 0x0000, 0, 8)) show("wValue=0x0008", vin(I2C_READ, 0x0008, 0, 8)) show("wValue=0x0040", vin(I2C_READ, 0x0040, 0, 8)) print("\n=== Approach 7: Larger reads to check page boundaries ===") data = vin(I2C_READ, 0x51, 0, 64) if data: show("First 8 of 64", data[:8]) show("Bytes 8-15", data[8:16]) show("Bytes 56-63", data[56:64]) # Check if bytes 8-15 match REF_8 if bytes(data[8:16]).hex(' ') == REF_8: print(" ** Bytes 8-15 match expected offset 8 data!") print(" ** The 64-byte read IS returning sequential EEPROM data!") # Reattach for cfg in dev: for intf in cfg: try: usb.util.release_interface(dev, intf.bInterfaceNumber) dev.attach_kernel_driver(intf.bInterfaceNumber) except: pass