Firmware
Cats capture physical input; the setup's Coordinator interprets it. The
Coordinator runs the Input Engine (input-engine: keymap,
Vial, pointer, settings, USB HID) and is the tower, or a cat built with the
coordinator feature; every other cat is a Satellite that sends over ESP-NOW
to the Coordinator's end of the link (coordinator-link:
pairing table, sessions, admission, routing into the engine), which a Coordinator
cat runs when it is provisioned with a pairing table
(naming). Read the composition roots
cat/main.rs and tower/main.rs, then
follow the types into their modules. Cargo.toml owns the crate
boundaries and tools/lx/firmware.sh owns supported build
configurations (./lx check --list).
The separate cat/rules, tower/rules, input-engine/rules and coordinator-link/rules
crates exist because
esp-hal prevents the firmware crates from building on a host. Put deterministic decisions and their
tests there; keep peripheral effects in the consuming firmware.
For changes crossing domains, LYNXware.toml owns physical identity, key_index.rs owns matrix conversion, vial.json owns the visual layout, and lynxgram.rs owns default bindings. The latter adapts Arno Klein's Engram layout to these finger and thumb modules.
Operation
- Build and flash
- Provision or revoke devices
- Vial settings and diagnostics
- Battery verification
- Security constraints and unresolved risks
Constraints not proved by a host build
LYNXware.tomldescribes the intended fitted modules. The session currently authenticates a cat's role, not its installed variants; role-to-variant admission remains deferred and would require a provisioning or protocol change.- Default power policy favors first-key response by keeping the radio alive.
radio-teardowntrades wake latency for idle power. Neither profile has current measured battery-current figures; do not reuse historical estimates. Light/deep sleep is not implemented on this pinned stack. - Mouse deltas stay
i16until HID delivery. The April 2026 bench found sustained ~290-count deltas at 2000 CPI and additional loss during coalescing when the wire wasi8; narrowing earlier discarded motion. The accumulator and driver own the current implementation; the PMW3389 driver's header keeps the failed burst-read experiment. - The channel candidates include 13 (
protocol::CHANNEL_CANDIDATES), permitted in the EU, the target market, but not in the US or Canada. A build for those markets needs another list; the tower cycles through it and a stranded cat scans it, so the whole set is reflashed together. - No firmware image carries a third-party blob. The PMW3389's SROM is the builder's
own copy, read from its flash sector at boot (firmware/cat/srom);
the PMW3610 driver (
bm-pmw3610, ported from RMK) needs none and is compile-checked only until its first bench run, as is the ADNS-5050's (bm-adns5050, the v3 module on the PMW wires; USB's 5 V only, so never withbattery).