skywalker-1/tools/eeprom_probe.py
Ryan Malloy bbdcb243dc Normalize line endings to LF across entire repository
Apply .gitattributes normalization to convert all CRLF line
endings inherited from Windows-origin source files to Unix LF.
175 files, zero content changes.
2026-02-20 10:55:50 -07:00

102 lines
3.3 KiB
Python

#!/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