Navigate tileview to the watch face tile before blanking so the
time is always visible when the display wakes. Without this, the
display would wake to whatever screen was last active.
LVGL 9.5.0 integration replacing direct framebuffer rendering.
Watch face with time, date, status bar (mode/battery), and three
complications (LoRa/GPS/Steps). Tileview swipe navigation between
five screens: watch face, radio status, GPS, messages, settings.
Haptic feedback on screen transitions via DRV2605.
Radio status screen shows frequency, LoRa params, RSSI bar gauge,
channel utilization, BLE state, and packet counts. GPS screen shows
coordinates, fix quality, altitude/speed, and beacon status.
Serial screenshot tool (scripts/screenshot.py) captures display
contents over USB CDC by sending trigger bytes and receiving the
shadow framebuffer as raw RGB565.
Build changes:
- FlashSize=16M in FQBN (bootloader embeds flash size, defaults 4MB)
- PSRAM=enabled for LVGL draw buffers and screenshot shadow buffer
- Custom 8MB app partition (partition_twatch.csv) for 16MB flash
- flash-twatch_ultra-full make target for full bootloader+partition+app flash
Architecture notes in code:
- display_init() must run BEFORE xl9555_init() (display power gate
defaults high at power-on, reordering causes black screen)
- LVGL draw buffers use separate swap buffer for RGB565 byte-order
conversion to avoid corrupting LVGL's internal buffer state
- Touch input registered via function pointer to decouple Gui.h from
touch library include order
Touch driver via SensorLib TouchDrvCST92xx on I2C 0x1A with interrupt
on GPIO 12. Touch events unblank the display and reset the blanking
timer. Display blanks after 10 seconds of inactivity.
XL9555 TOUCH_RST now explicitly released at boot. Touch init runs
with explicit I2C_SDA/I2C_SCL pins (same fix as XPowersLib).
Display now shows time (00:00 from reset RTC) and status line with
radio state, battery percentage, GPS satellites, and uptime counter.
Display blanking disabled until button input is implemented.
QSPI display driver confirmed working after I2C pin fix.
Standalone GPS beacon mode: when no KISS host is connected for 15s,
the RNode transmits position and battery telemetry over LoRa.
Two beacon paths:
- LXMF (recommended): encrypted per-packet messages with announces,
compatible with Sideband and any LXMF application. Supports IFAC
network authentication.
- Legacy JSON: plaintext or encrypted raw packets for simple collectors.
Key changes:
- GPS support for T-Beam Supreme S3 (L76K) and Heltec V4 (external)
- SX1262 radio fixes: IQ polarity, DCD preamble lockup, RX reliability
- LXMF identity management with NVS-backed Ed25519/X25519 keys
- IFAC authentication (CMD_IFAC_KEY 0x89) for private networks
- Per-channel serial isolation (USB, BLE, WiFi)
- GPS status page in OLED display rotation
- Provisioning via rnlog: provision-lxmf, provision-ifac
- Documentation in Documentation/BEACON.md