skywalker-1/tools/test_boot.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

172 lines
5.5 KiB
Python

#!/usr/bin/env python3
"""Test BOOT_8PSK on SkyWalker-1 with custom firmware v3.01.0"""
import usb.core
import usb.util
import sys
import time
def find_device():
dev = usb.core.find(idVendor=0x09C0, idProduct=0x0203)
if not dev:
print("Device not found!")
sys.exit(1)
return dev
def setup_device(dev):
"""Detach kernel driver and set configuration."""
try:
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
print("Detached kernel driver from interface 0")
except Exception as e:
print(f"Driver detach note: {e}")
try:
dev.set_configuration()
except usb.core.USBError:
# Already configured, that's fine
pass
def main():
dev = find_device()
setup_device(dev)
# GET_FW_VERS (0x92)
print("=" * 50)
ret = dev.ctrl_transfer(0xC0, 0x92, 0, 0, 6)
major, minor, patch = ret[2], ret[1], ret[0]
day, month, year = ret[3], ret[4], ret[5] + 2000
print(f"Firmware: v{major}.{minor:02d}.{patch} ({year}-{month:02d}-{day:02d})")
# GET_8PSK_CONFIG (0x80)
ret = dev.ctrl_transfer(0xC0, 0x80, 0, 0, 1)
print(f"Config before boot: 0x{ret[0]:02X}")
# BOOT_8PSK (0x89) with wValue=1
print()
print("=" * 50)
print("Sending BOOT_8PSK(1)...")
print(" (This triggers: P0.5 reset, power on, 3-block register init)")
print()
try:
ret = dev.ctrl_transfer(0xC0, 0x89, 1, 0, 3, timeout=10000)
except usb.core.USBError as e:
print(f"BOOT_8PSK USB error: {e}")
print("The device may have timed out during init.")
print("Trying to read config status anyway...")
try:
ret = dev.ctrl_transfer(0xC0, 0x80, 0, 0, 1)
print(f"Config after attempted boot: 0x{ret[0]:02X}")
except:
print("Device not responding. May need power cycle.")
sys.exit(1)
status = ret[0]
stage = ret[1] if len(ret) > 1 else 0
stage_names = {
0: "NOT_STARTED", 1: "GPIO_SETUP", 2: "PWR_SETTLED",
3: "I2C_PROBE", 4: "INIT_BLK0", 5: "INIT_BLK1",
6: "INIT_BLK2", 0xFF: "COMPLETE"
}
flags = []
if status & 0x01: flags.append("STARTED")
if status & 0x02: flags.append("FW_LOADED")
if status & 0x04: flags.append("INTERSIL")
if status & 0x08: flags.append("DVB_MODE")
if status & 0x10: flags.append("22KHZ")
if status & 0x20: flags.append("SEL18V")
if status & 0x40: flags.append("DC_TUNED")
if status & 0x80: flags.append("ARMED")
print(f"BOOT_8PSK response: 0x{status:02X} [{' | '.join(flags) if flags else 'none'}]")
print(f"Boot stage: 0x{stage:02X} [{stage_names.get(stage, 'UNKNOWN')}]")
if status & 0x03 == 0x03:
print()
print("*** BCM4500 BOOT SUCCESS! ***")
print()
# Read direct I2C registers
print("BCM4500 direct registers (via I2C_RAW_READ 0xB5):")
for reg in [0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8]:
try:
r = dev.ctrl_transfer(0xC0, 0xB5, 0x08, reg, 1)
print(f" Reg 0x{reg:02X} = 0x{r[0]:02X}")
except Exception as e:
print(f" Reg 0x{reg:02X}: ERROR {e}")
# Read indirect registers through our protocol
print()
print("BCM4500 indirect registers (via RAW_DEMOD_READ 0xB1):")
for page in range(16):
try:
r = dev.ctrl_transfer(0xC0, 0xB1, page, 0, 1)
print(f" Page 0x{page:02X} = 0x{r[0]:02X}")
except Exception as e:
print(f" Page 0x{page:02X}: ERROR {e}")
# I2C diagnostic
print()
print("I2C diagnostic (0xB6) for page 0x00:")
try:
r = dev.ctrl_transfer(0xC0, 0xB6, 0x00, 0, 8)
labels = ["wr_A6", "rb_A6", "wr_A8", "rb_A8",
"rb_A7", "fin_A6", "fin_A7", "fin_A8"]
for i, lab in enumerate(labels):
print(f" {lab}: 0x{r[i]:02X}")
except Exception as e:
print(f" ERROR: {e}")
# Signal strength
print()
try:
r = dev.ctrl_transfer(0xC0, 0x87, 0, 0, 6)
print(f"Signal strength: {' '.join(f'{b:02X}' for b in r)}")
except Exception as e:
print(f"Signal strength ERROR: {e}")
# Signal lock
try:
r = dev.ctrl_transfer(0xC0, 0x90, 0, 0, 1)
print(f"Signal lock: 0x{r[0]:02X}")
except Exception as e:
print(f"Signal lock ERROR: {e}")
else:
print()
print("*** BOOT FAILED ***")
print()
# I2C bus scan
print("I2C bus scan:")
try:
r = dev.ctrl_transfer(0xC0, 0xB4, 0, 0, 16)
addrs = []
for bi in range(16):
for bit in range(8):
if r[bi] & (1 << bit):
addrs.append(bi * 8 + bit)
if addrs:
print(f" Found devices at: {[f'0x{a:02X}' for a in addrs]}")
else:
print(" No I2C devices found!")
except Exception as e:
print(f" Scan error: {e}")
# Try raw I2C reads anyway
print()
print("Raw I2C reads to BCM4500 (0x08):")
for reg in [0xA2, 0xA4, 0xA6, 0xA7, 0xA8]:
try:
r = dev.ctrl_transfer(0xC0, 0xB5, 0x08, reg, 1)
print(f" Reg 0x{reg:02X} = 0x{r[0]:02X}")
except Exception as e:
print(f" Reg 0x{reg:02X}: ERROR {e}")
print()
print("=" * 50)
if __name__ == "__main__":
main()