Apply .gitattributes normalization to convert all CRLF line endings inherited from Windows-origin source files to Unix LF. 175 files, zero content changes.
172 lines
5.5 KiB
Python
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()
|