Textual's ContentSwitcher expects regular Widget/Container children,
not Screen subclasses. Screen's on_mount fires for all children at
once regardless of visibility, so demo workers for all 5 modes
started simultaneously and competed for the bridge.
Container children get proper on_show/on_hide from ContentSwitcher's
visibility toggling — only the active panel's worker runs.
Separate entry point (skywalker-tui) that reuses skywalker_lib.py
unchanged. Five RF modes: spectrum, scan, monitor, lband, track —
each with threaded USB bridge workers for non-blocking I/O.
Includes --demo mode with synthetic signal generation (Gaussian
peaks, noise floor, AGC simulation) for development without hardware.
Custom widgets: spectrum bar chart, rolling waterfall, signal gauge,
sparkline history, transponder table, device status bar.
The 1711-line master reference was 100% duplicated across the existing
37 Starlight pages. Trimmed to bibliography only (Ghidra port numbers,
driver source paths, analysis reports, community links).
Salvaged FX2 USB controller registers (SETUPDAT, CPUCS, EP0BUF, etc.)
into bcm4500/register-map.mdx before removal. Sidebar label updated
from "Master Reference" to "Sources".
New page: bcm4500/register-map.mdx consolidates all register
addresses (direct, indirect page 0, FX2 XRAM/IRAM, I2C controller)
into a single lookup reference with cross-reference index.
Expanded sections:
- fw213-variants: hardware detection mechanism, distinguishing
characteristics table, FW1 demod type detection signatures
- demodulator: probe logic (3x3 retry, INT0 40-iteration boot probe
at 0x7F/0x3F, no_demod_flag graceful degradation)
- version-comparison: version ID gap aside (v2.07.04 is a kernel
constant, not a real firmware release)
Cross-links added to signal-monitoring and tuning-protocol pages.
Firmware v3.02.0 adds three new vendor commands:
- 0xB7 SIGNAL_MONITOR: fast 8-byte combined signal read
- 0xB8 TUNE_MONITOR: tune + dwell + read in one round-trip
- 0xB9 MULTI_REG_READ: batch read up to 64 indirect registers
New tools/skywalker.py provides five modes that use the BCM4500's
AGC registers as a crude power detector across 950-2150 MHz IF,
even without demodulator lock:
- spectrum: sweep analyzer with ASCII/waterfall/matplotlib display
- scan: automated transponder scanner (sweep + peak detect + blind scan)
- monitor: real-time signal strength for dish alignment
- lband: direct input analyzer with L-band allocation annotations
- track: carrier/beacon tracker with CSV/JSON logging and drift detection
Extracts shared SkyWalker1 class and constants into skywalker_lib.py;
tune.py now imports from the shared library.
Astro 5 + Starlight 0.37 site at site/ with teal/steel theme.
Content sourced from 14 reverse engineering docs, master reference,
and custom firmware source. Includes Tabs, Badge, Steps, Aside,
FileTree, and CardGrid components throughout. DiSEqC SVGs with
click-to-zoom via starlight-image-zoom. All internal links validated.
Pagefind search indexes all 32 pages.
Merges 11 separate analysis documents into a single 1700-line
authoritative reference covering hardware, USB, vendor commands,
BCM4500 demodulator, tuning protocol, GPIF streaming, LNB/DiSEqC,
GPIO map, firmware versions, I2C bus architecture, and all known
quirks/errata. Corrects BCM4500 I2C address to 0x08 (7-bit)
throughout.
Removed I2CS bmSTOP "bus reset" from bcm4500_boot() and debug modes.
Sending STOP with no active transaction puts the FX2 I2C controller
into an inconsistent state where subsequent START+ACK detection fails.
Root cause identified through incremental debug modes (wValue 0x80-0x85)
on live hardware: mode 0x82 (with bmSTOP) fails, mode 0x85 (identical
but without bmSTOP) succeeds. Raw I2C reads confirm BCM4500 is alive
the entire time -- only the controller state is corrupted.
BCM4500 now boots successfully in ~90ms. Three I2C devices found on
bus: 0x08 (BCM4500), 0x10 (tuner/LNB), 0x51 (EEPROM).
Also in this commit:
- Timeout-protected I2C functions replacing fx2lib bare while loops
- I2C bus scan and debug mode infrastructure
- Kernel driver blacklist for dvb_usb_gp8psk
- Test tools for incremental boot debugging
- Technical findings documented in docs/boot-debug-findings.md
Correct BCM4500 I2C address from 0x10 (8-bit wire) to 0x08 (7-bit)
since fx2lib shifts internally. Add i2c_combined_read() with repeated
START for proper BCM4500 register access. Add I2C bus scan (0xB4),
raw read (0xB5), and indirect protocol diagnostic (0xB6) commands.
Single-transaction indirect reads/writes for BCM4500 register protocol.
Verified on hardware: BCM4500 ACKs at 0x08, BOOT_8PSK returns config
0x03. Register reads still return zeros — BCM4500 needs DSP firmware
loaded via LOAD_BCM4500 (0x88) before registers become functional.
Custom firmware (SDCC + fx2lib) implements all stock vendor commands
(0x80-0x94) plus new commands for spectrum sweep (0xB0), raw BCM4500
register access (0xB1/0xB2), and blind scan (0xB3). Compiles to 6.3KB
of code with healthy RAM margins.
RAM loader (fw_load.py) uses the FX2 0xA0 vendor request to load
firmware into RAM without touching EEPROM -- power cycle restores
factory firmware. Supports Intel HEX and raw binary formats.
New tools:
- tools/eeprom_write.py: EEPROM firmware flash with backup, verify, dry-run
- tools/ts_analyze.py: MPEG-2 transport stream analyzer with PAT/PMT parsing
DVB-S2 investigation confirms BCM4500 hardware limitation (no LDPC/BCH silicon).
Fix --json flag on tune.py subcommands (argparse parent/child scoping).
All tools verified against live SkyWalker-1 hardware.
Python tool (tools/tune.py) implements all vendor USB control
commands for tuning, LNB control, DiSEqC switching, and MPEG-2
transport stream capture via pyusb. Includes CLI subcommands for
status, tune, stream, diseqc, and lnb operations.
Consolidated hardware reference merges all Phase 1 analysis into
a single 12-section document covering the complete USB interface,
all 30 vendor commands, BCM4500 demodulator protocol, GPIF
streaming path, DiSEqC timing, and cross-version firmware
comparison.
Complete reverse engineering of all unknown vendor commands (0x8F,
0x91-0x98) across v2.06, v2.13, and Rev.2 firmware versions. Full
TUNE_8PSK (cmd 0x86) protocol analysis including EP0BUF format,
modulation dispatch jump table, BCM4500 I2C indirect register
sequences, and FEC lookup tables.
Major correction: All firmware versions use GPIO bit-banging for DiSEqC,
NOT I2C-based control as previously reported. Deep decompilation of the
sub-functions (byte transmit, bit symbol, tone burst) across v2.06, Rev.2,
and v2.13 reveals identical Manchester encoding algorithms with only the
data GPIO pin changed per PCB revision:
- v2.06: P0.7, Rev.2: P0.4, v2.13: P0.0
- P0.3 (22kHz carrier gate) unchanged across all versions
New section 7: Complete DiSEqC timing chain analysis including:
- Timer2 configuration (RCAP2=0xF82F, 4MHz clock, 500us tick)
- Manchester encoding waveforms (3 ticks/bit, 1.5ms/bit, 667 baud)
- Byte transmission (8 data + odd parity = 13.5ms)
- Tone burst timing (25 ticks = 12.5ms)
- CPU clock compensation in delay function
- External 22kHz oscillator architecture
Maps all vendor USB control commands (0x80-0x9D) used by the kernel driver
against firmware implementations across all 4 extracted versions.
Key findings:
- PID 0x0203 confirmed in kernel 6.16.5 module aliases (our device)
- PID 0x0204 is a separate SkyWalker-1 hardware revision
- LOAD_BCM4500 (0x88) intentionally STALLs on Rev.2/SkyWalker hardware
- BCM4500 firmware loading protocol documented (64-byte chunked via EP0)
- Complete boot, tuning, DiSEqC, and streaming sequences mapped
Updater EXEs are packed (RWX sections, near-random entropy) with anti-debug
protection (IsDebuggerPresent/SoftICE check). Bypassed by running under plain
Wine and reading /proc/PID/mem with elevated privileges.
SW1 v2.13.x updater contains 3 firmware variants (likely .1/.2/.3):
- All use LJMP 0x170D entry, 9322-9377 bytes, 10 C2 records each
- FW2 vs FW3 differ by 1525 bytes (most similar pair)
Rev.2 v2.10.4 updater contains 1 firmware image:
- PID=0x0202 (vs SW1's 0x0203), LJMP 0x155F, 8843 bytes, 9 C2 records
All images use standard Cypress C2 EEPROM format with entry at 0xE600 (CPUCS).
Previous RAM dumps via 0xA0 vendor request turned out to be live FIFO
data, not firmware - the Genpix FX2 firmware overrides the standard
0xA0 handler. Discovered that I2C_READ (0x84) with wValue=0x51 and
wIndex=offset reads the boot EEPROM directly.
EEPROM contents (Cypress C2 format):
- VID:PID 09C0:0203, config 0x40 (400kHz I2C)
- 9,472 bytes of 8051 firmware in 10 load records
- Code range 0x0000-0x24FF, entry at LJMP 0x188D
- Ghidra auto-analysis finds 61 functions
Tools: eeprom_dump.py (full dump), eeprom_probe.py (I2C protocol discovery)
Dumped 8KB internal RAM and 64KB external RAM from SkyWalker-1
serial #00857 via Cypress FX2 vendor request 0xA0. Device reports
FW v2.06.4 (build 2007-07-13). Tool also scans all vendor USB
commands and probes device status registers.
Includes original BDA driver source (headers, C++ implementation, INF
installer files), DiSEqC implementation PDF with extracted markdown
and SVG vector graphics.