Project overview
Spangap is built out of straddles — self-contained modules that each bundle their metadata, an ESP-IDF firmware component and (where relevant) a browser NPM package. The build system stitches the ones you select into a single firmware image and a single web app. The platform straddles below are the foundation every device gets; this is the map of which straddle owns what.
The build system
spangap — the build system and command-line tool itself. A single-file
launcher that provisions a Docker build container, resolves straddle
dependencies, stages the firmware/browser/LCD halves, gates Kconfig, generates
the boot glue, and drives flashing and the serial monitor from a small Python
venv. All the host needs is Docker, git and Python 3.
The base runtime
spangap-core — the firmware runtime every device links; its symbols read as
language primitives (empty prefix). It owns the platform subsystems:
init— the boot dispatcher that brings straddles up in ordered bands, from build-generated glue (no hand-writtenapp_main).storage— the hierarchical value store that synchronizes device (cJSON) ↔ browser (Pinia):set net.wifi.enable=1in the CLI moves the toggle in the web UI and on the LCD.its— Inter-Task Streaming, the notification-based IPC that lets tasks exchange streams and queues without polling. The primitive the whole platform is built on.fs— the flash/SD filesystem service (LittleFS), run on a DRAM-stacked task so other tasks can keep their stacks in PSRAM.cli— the unix-like command line, reachable over serial, web and SSH.auth— credential/session realms (such as theadminpassword) that the CLI, web and SSH gates enforce.cron— the scheduled/periodic job runner.logging— the device log and its relay/paste plumbing.power-management— RTOS-integrated tickless idle, so the chip sleeps while tasks are blocked.memory— the central allocator and heap tooling.idf-tweaks,ota(signed firmware updates), plus cross-cutting flash-partitions and remote-access handling.
Networking and the browser
spangap-net — the IP stack, pulled in by anything needing WiFi or the
Internet. Subsystems: net (WiFi STA/AP state machine, TCP/UDP relay, event
bus, wget), tls (shared mbedTLS server with hot cert reload), ntp
(time sync, date) and mdns (<host>.local). Owns the well-known port
config keys, and bundles the remote-access services below by default.
spangap-web — the device web stack and browser shell. Subsystems: web
(HTTPS server, file serving, WebDAV, cookie-session auth), webrtc (the
DataChannel plumbing carrying every device↔browser path) and the
browser-shell SPA (Dock launcher, generated settings panels, config sync,
login/setup). At build time it folds every other straddle’s browser/ half into
one web app.
spangap-lcd — the on-device phone-style UI (LVGL v9): status bar, scrolling
launcher, recents switcher, and built-in Settings, Log and CLI apps,
plus a libvterm VT100 terminal. Straddles register their own LCD apps and
settings panes through its API; input stays board-specific via an lcd_input_t
HAL.
Built on those five
viewer — a tiny HTML/Markdown document reader (READMEs, help, CHANGELOGs),
with an LCD “Info” app and a Web “Viewer” app.
audio — a generic I2S full-duplex audio engine and packet server (live-mic
streaming, mixing, WAV playback) exposed over a browser DataChannel.
tinylcd — the small-display counterpart to spangap-lcd: a paged status
display on a monochrome OLED/LCD over u8g2, one page per straddle, advanced by a
button. For a board with a screen too small for a phone-style UI.
Generic peripheral straddles
Each owns one part and couples to everything else only over the storage bus. A board stages the ones it has and supplies their pins as Kconfig.
gps— a GNSS receiver (u-blox M10 or Quectel L76K, told apart by autobaud): NMEA parsing, receiver power management, and clock discipline as a time authority.spangap-rtc— a PCF8563 battery-backed wall clock: adopted at boot, mirrored from the system clock while a live time authority is running, and keeping time once that authority goes quiet.imu— a QMI8658 accelerometer in Wake-on-Motion, answering one question: is this device moving? Its first consumer isgps, which stops tracking a device that is standing still.
Board support
hw-lilygo-tdeck — the board-support (HAL) straddle for the LilyGo T-Deck
Plus: power/CS bring-up, the input HAL, battery monitor, microSD and pin maps
(the GNSS receiver itself is the gps straddle, which this board stages). It is
non-buildable — it makes the board usable but decides nothing about what the
device does. The hw-* family covers the other supported boards the same way;
they are listed with their radios and peripherals on the
Reticulous site.
Remote-access services
Bundled by spangap-net by default, each independent.
acme— ACMEv2 client that fetches and renews publicly-trusted TLS certs (Let’s Encrypt) via DNS-01 or HTTP-01.duckdns— DuckDNS dynamic-DNS updater; also publishes the TXT recordacmeneeds for DNS-01.upnp— UPnP-IGD port mapping so the HTTPS and WebRTC ports are reachable through NAT.wg— a WireGuard client tunnel, the CG-NAT-friendly alternative toupnp+duckdns+acme.sshd— an SSH-2 server and client that bridge into thecliandlog(post-quantum key exchange, publickey or password auth).
And the mesh stack
The mesh-networking straddles — the Reticulum stack (rns), the LoRa, TCP,
ESP-NOW and Auto interfaces, LXMF messaging, Nomad browsing and more — live in
the sibling Reticulous project, the reference
application built on this platform.