New testing/docs surface for grabbing the active LVGL screen as a
PNG over USB-CDC. Useful both for documentation (round-trip capture
of every public screen via T:SHOW <name> + T:SCREENSHOT) and
automated UI regression tests.
On-device:
- lib/lv_conf.h — enable LV_USE_SNAPSHOT (~5 KB code; uses PSRAM
via the existing hybrid allocator so internal RAM is unaffected)
- src/main.cpp — T:SCREENSHOT handler takes an lv_snapshot_take()
of lv_scr_act() under LVGL_LOCK(), dumps a delimited base64
stream over CDC. Inlines a tiny base64 encoder (no new dep).
- src/main.cpp — T:SHOW <name> dispatches to UIManager::show_*()
for the six publicly-navigable screens (conversation_list,
compose, announces, status, settings, propagation_nodes).
Wire format:
T:SCREENSHOT BEGIN W=320 H=240 FMT=rgb565<be|le> BYTES=153600
<base64 line, 76 chars>
...
T:SCREENSHOT END
Host side:
- screenshot.py — auto-detects the pyxis port via T:ID probe,
sends T:SCREENSHOT, reads until END, filters out interleaved
log lines (heap heartbeats / BLE stats can splice in
mid-dump), validates byte count matches header, decodes RGB565
with the documented byte order, expands channels via 5→8 / 6→8
high-bit replication, saves PNG. Pillow + pyserial.
Catalog:
- docs/serial_commands.md — full reference for all T:* commands
accumulated so far (identity/paths/send/receive, propagation,
voice, BLE, UI). New commands should land here when added.
Throughput: ~205 KB base64 over CDC at 115200 → ~18 s/shot. Fine
for docs and automated tests, not video. Bumping baud or zlib-
compressing on-device is queued in the doc as future work.
GitHub release download URLs redirect to release-assets.githubusercontent.com
which doesn't return Access-Control-Allow-Origin headers. The browser blocks
cross-origin fetches from the GitHub Pages flasher, causing "Failed to fetch"
for any versioned release while the latest dev build (same-origin) works fine.
Fix: Deploy versioned firmware binaries to GitHub Pages alongside the dev
build at firmware/releases/{tag}/, so all versions are fetched same-origin.
The CI workflow now downloads existing release assets and deploys them to
Pages with keep_files: true to preserve across deploys.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lets users choose between the latest dev build and tagged GitHub releases.
The dropdown queries the GitHub Releases API on page load and swaps
firmware fetch paths between Pages-relative and release-asset URLs.
CI now attaches all 4 firmware files to releases (bootloader, partitions,
boot_app0, firmware) so full installs work from any release version.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite release-firmware.yml to build the tdeck (NimBLE) env on pushes to
main (versioned as dev-<sha>) and on v* tags. Remove checked-in firmware
binaries from git tracking — CI now generates and deploys them to Pages.
Release creation is conditional on v* tags only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual DTR toggle with esploader's built-in hardReset() which
uses RTS (EN pin) to properly reset the ESP32-S3 after flashing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Transport tracing and missing enableTracing flag caused timing issues
with ESP32-S3 USB-Serial/JTAG during bootloader sync. Also fixes
flashMode/flashFreq format, routes esptool output to on-page log,
and adds firmware binaries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split T-Deck firmware from microReticulum examples/lxmf_tdeck/ into its
own repo. microReticulum is consumed as a git submodule dependency pinned
to feat/t-deck. All include paths updated from relative symlinks to bare
includes resolved via library build flags.
Both tdeck (NimBLE) and tdeck-bluedroid environments compile successfully.
Licensed under AGPLv3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>