Add TUI documentation for F6-F8 screens and regenerate screenshots

Update tui.mdx with Device, Stream, and Config screen sections
including keyboard shortcuts, Tabs/Steps components, and safety
warnings. Update generate_screenshots.py to capture all 11 screens.
Regenerate all SVGs with current sidebar layout.
This commit is contained in:
Ryan Malloy 2026-02-14 16:24:59 -07:00
parent 567bf4d9e0
commit 0f4ba4766f
13 changed files with 2040 additions and 2939 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 86 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 81 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 85 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 92 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 85 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 86 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 80 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 596 KiB

After

Width:  |  Height:  |  Size: 474 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 86 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 95 KiB

View File

@ -1,11 +1,11 @@
--- ---
title: SkyWalker TUI title: SkyWalker TUI
description: Interactive terminal dashboard for spectrum analysis, transponder scanning, signal monitoring, L-band analysis, and carrier tracking. description: Interactive terminal dashboard for spectrum analysis, transponder scanning, signal monitoring, L-band analysis, carrier tracking, device management, transport stream analysis, and hardware configuration.
--- ---
import { Tabs, TabItem, Steps, Aside, Badge } from '@astrojs/starlight/components'; import { Tabs, TabItem, Steps, Aside, Badge } from '@astrojs/starlight/components';
The SkyWalker TUI is a full-screen terminal dashboard built on [Textual](https://textual.textualize.io/) that wraps all five RF operating modes into a single interactive interface. Sidebar navigation, F-key shortcuts, real-time widget updates, and a dark/light theme toggle replace the separate CLI subcommands with a unified experience. The SkyWalker TUI is a full-screen terminal dashboard built on [Textual](https://textual.textualize.io/) that wraps all eight operating modes into a single interactive interface. Five RF signal modes (Spectrum, Scan, Monitor, L-Band, Track) plus Device management, Transport Stream analysis, and hardware Config — all with sidebar navigation, F-key shortcuts, real-time widget updates, and a dark/light theme toggle.
<Badge text="Requires custom firmware v3.02.0+" variant="caution" /> <Badge text="Requires custom firmware v3.02.0+" variant="caution" />
@ -34,7 +34,7 @@ uv run skywalker-tui --demo
| `--demo` | Synthetic signal data — no SkyWalker-1 USB device needed | | `--demo` | Synthetic signal data — no SkyWalker-1 USB device needed |
| `--no-splash` | Skip the startup splash screen | | `--no-splash` | Skip the startup splash screen |
| `--verbose, -v` | Verbose USB logging (hardware mode only) | | `--verbose, -v` | Verbose USB logging (hardware mode only) |
| `MODE` | Initial mode: `spectrum` (default), `scan`, `monitor`, `lband`, `track` | | `MODE` | Initial mode: `spectrum` (default), `scan`, `monitor`, `lband`, `track`, `device`, `stream`, `config` |
<Aside type="tip"> <Aside type="tip">
Demo mode generates realistic-looking synthetic data for every screen, making it useful for familiarization, documentation, and development without satellite hardware. Demo mode generates realistic-looking synthetic data for every screen, making it useful for familiarization, documentation, and development without satellite hardware.
@ -51,6 +51,9 @@ Demo mode generates realistic-looking synthetic data for every screen, making it
| <kbd>F3</kbd> | Signal monitor | | <kbd>F3</kbd> | Signal monitor |
| <kbd>F4</kbd> | L-Band analyzer | | <kbd>F4</kbd> | L-Band analyzer |
| <kbd>F5</kbd> | Carrier tracker | | <kbd>F5</kbd> | Carrier tracker |
| <kbd>F6</kbd> | Device management |
| <kbd>F7</kbd> | Transport stream |
| <kbd>F8</kbd> | Hardware config |
| <kbd>d</kbd> | Toggle dark/light theme | | <kbd>d</kbd> | Toggle dark/light theme |
| <kbd>q</kbd> | Quit | | <kbd>q</kbd> | Quit |
| <kbd>Ctrl+W</kbd> | Easter egg | | <kbd>Ctrl+W</kbd> | Easter egg |
@ -127,6 +130,84 @@ Carrier/beacon tracker with timestamped logging. Tracks a single frequency and d
- Event log with timestamped lock/unlock transitions - Event log with timestamped lock/unlock transitions
- Frequency drift detection - Frequency drift detection
### Device <Badge text="F6" variant="note" />
Firmware management, EEPROM operations, and hardware diagnostics. An identity panel at the top always shows firmware version, serial number, USB speed, and config register flags.
![Device management](../../../assets/tui/device.svg)
<Tabs>
<TabItem label="Firmware">
- FX2 RAM read at arbitrary addresses rendered as scrollable hex dump
- CPU Halt / Start controls for the Cypress FX2 microcontroller
- Non-destructive — RAM contents revert on power cycle
</TabItem>
<TabItem label="EEPROM">
- Read full 16 KB EEPROM with progress bar
- One-click backup to timestamped `.bin` file
- Flash with full safety state machine:
<Steps>
1. **C2 validation** — magic byte, VID/PID match, END marker, record parsing
2. **Auto-backup** — saves current EEPROM to timestamped file before any write
3. **3-second countdown** — ABORT button auto-focused (accidental keypress = cancel)
4. **Page write** — 16-byte pages with progress bar and circuit breaker (3 consecutive errors = abort)
5. **Byte-verify** — full readback with diff highlighting in hex view
</Steps>
</TabItem>
<TabItem label="Diagnostics">
- Boot test with mode selector (0x800x85) showing stage progression
- I2C bus scan identifying BCM4500, EEPROM, tuner, and LNB controller
- BCM4500 register dump rendered as hex view
</TabItem>
</Tabs>
<Aside type="danger">
EEPROM flash is the only operation that can brick the device. The safety state machine prevents accidental writes, but a power loss during write will corrupt the boot image. The verify step detects partial writes — if it fails, **do not power cycle** until the flash is retried successfully.
</Aside>
### Stream <Badge text="F7" variant="note" />
Live MPEG-2 Transport Stream capture and analysis. Reads raw 188-byte TS packets from the SkyWalker-1 bulk endpoint, parses them in real time, and displays PID distribution statistics alongside a hierarchical PSI program structure tree.
![Stream analysis](../../../assets/tui/stream.svg)
- PID distribution table with count, percentage, CC errors, and known PID names
- PAT/PMT tree display showing transport stream ID, program numbers, PMT PIDs, and elementary stream types (video, audio, data)
- Aggregate stats: total packets, bytes, unique PIDs, CC errors, duration
- Capture-to-file mode for saving raw `.ts` files to disk
- Auto-starts monitoring in demo mode
<Aside type="tip">
The stream monitor batches UI updates at 500ms intervals to keep the interface responsive even at high packet rates. The USB bulk endpoint is always safely disarmed when monitoring stops.
</Aside>
### Config <Badge text="F8" variant="note" />
LNB power control, DiSEqC switching, and modulation/FEC configuration — all the hardware settings in one place.
![Hardware configuration](../../../assets/tui/config.svg)
<Tabs>
<TabItem label="LNB Control">
- Power On / Off toggle
- Voltage selection: 13V (vertical) / 18V (horizontal), with optional +1V boost
- 22 kHz tone toggle for high-band LNB switching
- Current draw warning (450 mA continuous max)
</TabItem>
<TabItem label="DiSEqC Switch">
- Port selector (14) sending committed commands
- Tone burst A/B for legacy switches
- Raw hex message input (36 byte DiSEqC 1.0/1.2 commands) with validation
</TabItem>
<TabItem label="Modulation / FEC">
- Modulation type dropdown: QPSK, Turbo QPSK, Turbo 8PSK, DCII Combo, DCII Split I/Q, DCII Offset QPSK, DSS
- FEC rate dropdown filtered per modulation group
- Symbol rate (256 Ksps 30 Msps) and frequency inputs
- Tune button applies settings to the BCM4500 demodulator
</TabItem>
</Tabs>
--- ---
## Easter Eggs ## Easter Eggs
@ -171,8 +252,10 @@ Use `--no-splash` to skip it.
## See Also ## See Also
- [SkyWalker RF Tool](/tools/skywalker/) — CLI version of the same 5 modes (text-only output, scriptable) - [SkyWalker RF Tool](/tools/skywalker/) — CLI version of the RF modes (text-only output, scriptable)
- [Spectrum Analysis](/tools/spectrum-analysis/) — practical how-to guides for each operating mode - [Spectrum Analysis](/tools/spectrum-analysis/) — practical how-to guides for each operating mode
- [Signal Monitoring](/bcm4500/signal-monitoring/) — SIGNAL_MONITOR register protocol and data format - [Signal Monitoring](/bcm4500/signal-monitoring/) — SIGNAL_MONITOR register protocol and data format
- [Tuning Tool](/tools/tuning/) — primary tuning, LNB control, and transport stream capture - [Tuning Tool](/tools/tuning/) — primary tuning, LNB control, and transport stream capture
- [EEPROM Utilities](/tools/eeprom-utilities/) — standalone CLI for firmware updates (same safety protocol as F6 Device screen)
- [TS Stream Analyzer](/tools/ts-analyzer/) — standalone TS packet analyzer (same engine as F7 Stream screen)
- [RF Coverage](/hardware/rf-coverage/) — frequency coverage and antenna considerations - [RF Coverage](/hardware/rf-coverage/) — frequency coverage and antenna considerations

View File

@ -5,7 +5,7 @@ Uses Textual's headless run_test() + Pilot API to programmatically navigate
each screen and export SVG renders. Requires no hardware runs entirely each screen and export SVG renders. Requires no hardware runs entirely
with DemoDevice synthetic signal data. with DemoDevice synthetic signal data.
Output: ../site/src/assets/tui/*.svg (8 screenshots) Output: ../site/src/assets/tui/*.svg (11 screenshots)
Usage: Usage:
cd tui && uv run python scripts/generate_screenshots.py cd tui && uv run python scripts/generate_screenshots.py
@ -46,7 +46,7 @@ def _save(svg: str, name: str) -> None:
async def capture_mode_screens() -> None: async def capture_mode_screens() -> None:
"""Capture F1-F5 mode screens.""" """Capture F1-F5 RF mode screens."""
app = _new_app(show_splash=False) app = _new_app(show_splash=False)
async with app.run_test(size=TERM_SIZE, headless=True) as pilot: async with app.run_test(size=TERM_SIZE, headless=True) as pilot:
@ -67,6 +67,61 @@ async def capture_mode_screens() -> None:
_save(svg, filename) _save(svg, filename)
async def capture_device_screen() -> None:
"""Capture F6 Device screen — show EEPROM tab with hex dump."""
app = _new_app(show_splash=False)
async with app.run_test(size=TERM_SIZE, headless=True) as pilot:
await pilot.pause(MOUNT_PAUSE)
# Switch to Device screen
await pilot.press("f6")
await pilot.pause(MODE_SWITCH_PAUSE)
# Wait for identity info to populate
await pilot.pause(1.0)
# Capture Firmware tab (default)
svg = app.export_screenshot(title="SkyWalker-1 — Device")
_save(svg, "device")
async def capture_stream_screen() -> None:
"""Capture F7 Stream screen — needs time for TS packets to accumulate."""
app = _new_app(show_splash=False)
async with app.run_test(size=TERM_SIZE, headless=True) as pilot:
await pilot.pause(MOUNT_PAUSE)
# Switch to Stream screen (auto-starts in demo mode)
await pilot.press("f7")
await pilot.pause(MODE_SWITCH_PAUSE)
# Wait for PID stats and PSI tree to populate
await pilot.pause(2.0)
svg = app.export_screenshot(title="SkyWalker-1 — Stream")
_save(svg, "stream")
async def capture_config_screen() -> None:
"""Capture F8 Config screen."""
app = _new_app(show_splash=False)
async with app.run_test(size=TERM_SIZE, headless=True) as pilot:
await pilot.pause(MOUNT_PAUSE)
# Switch to Config screen
await pilot.press("f8")
await pilot.pause(MODE_SWITCH_PAUSE)
# Wait for config status to load
await pilot.pause(0.5)
svg = app.export_screenshot(title="SkyWalker-1 — Config")
_save(svg, "config")
async def capture_dark_mode() -> None: async def capture_dark_mode() -> None:
"""Capture dark-mode toggle with Star Wars notification toast.""" """Capture dark-mode toggle with Star Wars notification toast."""
app = _new_app(show_splash=False) app = _new_app(show_splash=False)
@ -124,6 +179,9 @@ async def main() -> None:
captures = [ captures = [
("Mode screens (F1-F5)", capture_mode_screens), ("Mode screens (F1-F5)", capture_mode_screens),
("Device screen (F6)", capture_device_screen),
("Stream screen (F7)", capture_stream_screen),
("Config screen (F8)", capture_config_screen),
("Dark mode toggle", capture_dark_mode), ("Dark mode toggle", capture_dark_mode),
("Splash screen", capture_splash), ("Splash screen", capture_splash),
("Star Wars easter egg", capture_starwars), ("Star Wars easter egg", capture_starwars),