# roro9stack A multi-app firmware for the **M5Stack Cardputer ADV** with the **Cap LoRa-1262**. It's a Meshtastic-compatible mesh messenger, plus Wi-Fi tools, IRC, GNSS and more. Licensed GPL-3.0. - Domain language: [CONTEXT.md](CONTEXT.md) - Decisions: [docs/adr/](docs/adr/) - Milestones: [docs/milestones/](docs/milestones/) ## Requirements Only **Docker** is needed. PlatformIO and the ESP32 toolchain run inside a container, and are cached in the `roro9stack-pio` Docker volume. The first build downloads about 1 GB and takes a few minutes. ## Build and test (local CI) ```sh scripts/ci.sh ``` This runs the host-side unit tests (`test/`, `native` environment), then builds the firmware. The output is `.pio/build/cardputer-adv/firmware.factory.bin`. ## Flash 1. Connect the Cardputer by USB-C. 2. Run: ```sh scripts/flash.sh # auto-detects the port; or: scripts/flash.sh /dev/ttyACM1 ``` This uploads the firmware, then opens the serial monitor. Quit the monitor with `Ctrl+C`. **If the upload can't connect,** put the device in download mode: hold **G0** (the button next to the screen) while plugging in USB, or while pressing reset. Then retry. **If you get "permission denied" on the port,** your user needs access to the serial device. Run this once, then log out and back in: ```sh sudo usermod -aG dialout "$USER" ``` ## Firmware Updates over Wi-Fi (OTA) Once the Cardputer runs an OTA-capable firmware (flashed once over USB), updates can go over Wi-Fi: ```sh scripts/ota_keygen.sh # once: creates the signing key (see ADR 0003) scripts/flash.sh --ota 10.39.39.12 # build, sign and push; or set RORO_OTA_HOST ``` The device shows the push address in **Settings → Firmware**. It installs a correctly signed update right away, restarts (waiting up to 60 s if you're typing), and runs the new firmware on **Probation**. If the new firmware crashes, or can't reconnect Wi-Fi within 3 minutes, it rolls back to the previous one and says so. To install from the SD card instead, copy the `.ota` file from `.pio/build/cardputer-adv/` into `/updates` on the card, then use **Settings → Firmware**. With the Cardputer on USB, the card can stay in: `scripts/sd_put.sh ` sends it over the serial console into `/updates` (about 30 s for 1.6 MB, checked with SHA-256 before it's renamed into place; `SD_PUT_DEBUG=1` shows the console while it runs). **The private key** lives in `~/.config/roro9stack/ota-key.pem` and must never be committed. If it's lost, generate a new pair and flash once over USB. ## Development aids `scripts/serial_log.sh [seconds] [command…]` records the serial output, and can send commands to the firmware first. For example, `scripts/serial_log.sh 30 short sleep:12 burst` sets short screen timeouts, waits 12 s, then sends a burst of Toasts. | Command | Effect | |---|---| | `burst` | Publishes 5 Notifications at once | | `key up\|down\|left\|right\|select\|back\|home`, or `key ` | Injects a key press | | `sound on` / `sound off` | Toggles the Sound setting (beep + LED) | | `short` / `normal` | Screen timeouts 5 s / 10 s, or 30 s / 60 s | | `wifi add ` | Adds a Saved Network (so credentials stay out of the repo) | | `log ` | Appends a line to a test IRC Log (`/irc/dev/#test/.log`) | | `sd list` | Lists the files of each Storage Clean-up category | | `cat ` | Prints the first ~1.2 KB of a file on the SD card | | `irc start` | Starts the IRC Service (normally done by opening the IRC App) | | `irc say ` | Types into a Buffer, commands included (`irc say 0 /join #test`) | | `irc dump` | Prints IRC status, memory, and the last lines of each Buffer | | `wifi status` | Prints Wi-Fi state, network, signal, clock and free heap | `scripts/flash.sh` stops a running serial log first, since it would hold the port.