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