Vial settings and diagnostics
In Vial's Keymap → User group, assign a settings keycode to a physical key
on any layer, then press it. Settings persist in the Coordinator's flash (the tower's, or a
Coordinator cat's); the tower resends colors when a cat reconnects. The setup page
(./lx setup ui, its Sensors and LEDs step) writes the sensors' settings and the layer colours into the same record before
the Coordinator's firmware, or later on their own (cargo provision settings,
provisioning); what it does not name stays as stored. A Coordinator cat has no
radio and no link counters: on it, CH>, CH?, ST? and BAT? do nothing.
| Label | Operation |
|---|---|
MS+ / MS− | Adjust mouse speed |
SC+ / SC− | Adjust scroll speed |
LC> / LC< | Cycle the currently active layer's LED color |
RST | Reset speeds and colors, keeping the radio channel, the motion yaw and the gyro modes |
CH> | Move to the next radio-channel candidate |
CH? | Type the applied channel into the focused text field |
ST? | Type a STATS? diagnostic line into the focused text field |
BAT? | Type each hand's presence and battery into the focused text field |
YL> / YL< | Turn the left hand's mouse motion (or its gyro's axes) 5° clockwise / anticlockwise |
YR> / YR< | The same for the right hand |
GY | The gyro air mouse: held or tapped, as each hand's gyro mode says (below) |
SVC | Held 2 s: service mode, for saving settings without BOOT |
The bottom module sits fixed in its lid; the Coordinator turns each hand's motion by
the angle the lid seats the sensor at, plus the YL/YR trim. Push the hand
straight forward: if the cursor leans right, tap <; if it leans left, tap >.
A breakout on the bench, outside a lid, reads right lying with its +y end
pointing away from you (mechanical/dimensions.json bottom_module); trim
any other way it lies.
Focus a text editor before using readouts. ST? can take 5–20 seconds and types
HID characters directly, bypassing the keymap; it uses only characters that come out
the same on a US and a German host (a–x, digits, space, comma). l, r, t
identify left, right and tower counters; l none or r none means no snapshot yet.
Each field is its name followed by its value (rtx12), and a pair is split by a comma
(tx1234,3). Counters restart at that device's boot.
BAT? types one section per hand: l present bat85,3870,12 r silent bat none is
the left hand heard, at 85 % and 3870 mV as of 12 s ago, and the right hand not heard
for 75 s (two and a half of its 30 s telemetry reports) with no battery report ever (no
battery, or none yet). stale follows a reading older than 75 s, low one at or under
15 %. On the T-Dongle the same status is the screen's top strip (L 85%, L 85%? when
stale, L on for a hand without a battery, L x for a silent one, blinking red when
low) with the voltages or a charge left warning along the bottom; its backlight lights
for 30 s on a layer, lock or presence change and on a low cell, not on a routine report.
For diagnosis: growing rtx with tower rep suggests lost acknowledgements;
with ooo, lost key frames. ovf means a filled key queue, kbto a stalled
keyboard channel, and rec snapshot reconciliation. Persistent ssf
indicates settings flash-write failures. Unexpectedly increasing ses suggests repeated
session recovery; hign can indicate mismatched provisioned masters.
Definitions and the exact output format live in
telemetry.rs, with cat counters in
protocol/telemetry.rs.
Keycode labels and steps are owned by settings.rs and checked against vial.json. The default Engram-derived bindings live in lynxgram.rs; customize them in Vial.
Gyro air mouse
A hand with the gyro bottom module (bg) moves the pointer when it turns: sideways for a
turn about the vertical, up and down for a tilt of the fingertips; a roll does nothing. Its
mode and speed are set per hand on the setup page; no key changes them, and RST resets
its speed, not its mode. The modes, for the GY key:
| Mode | The gyro moves the pointer |
|---|---|
| off | never (the firmware's default) |
| while held | while a GY key is held |
| toggle | from one GY tap to the next |
| always | always; holding GY pauses it, to bring the hand back to a comfortable pose |
The cat measures the gyro's zero-rate error itself: keep the hand still for a second after
it starts (its log says calibrated), and it re-measures at every later rest. If a tilt
moves the pointer sideways, trim the hand with YL/YR; the gyro's mounting angle is
derived from the lid's drawing and not yet checked on a built module
(gyro.rs).
Service mode
Holding SVC for 2 s takes the Coordinator off the keyboard: it writes any pending
setting, stops RMK and gives its USB port back to the serial unit, which the host sees as
the board's serial port again, by its MAC. Every cat blinks both LEDs blue, the Coordinator cat and the
Satellites alike: the keyboard state the Coordinator keeps sending carries it. The setup
page's Save the settings to the Coordinator (or cargo provision settings) then writes
over that port: espflash resets the board into its bootloader itself and, after the write,
into its firmware, so neither BOOT nor RST is pressed and a closed case stays closed. With no
write, the board restarts as a keyboard after 2 minutes. Read from the Coordinator first
shows what it stores, the Vial keys' changes included, and keeps it in its bootloader with no
time limit until the save; a save writes only what changed on the page. Reflash the
Coordinator flashes its firmware the same way, keeping its pairing and settings. The why and the timings are in
service.rs.
LYNXgram binds SVC on layer 1 at Lp5; a lone right cat reaches it on layer 3 (both layer
keys), at Rp5. A keymap stored before SVC existed keeps its own bindings
(keymap persistence): bind SVC in Vial once. Only a running
firmware has the key: a board's first flash, and a board whose firmware does not start, still
take BOOT.
One hand
A setup with one cat starts from that hand's one-hand keymap: a cat Coordinator with no paired cat, or a tower paired with one cat. Both hands get LYNXgram as before. The hand keeps its own LYNXgram keys and reaches the other hand's at the mirrored keys:
| Hold | The hand types |
|---|---|
| nothing | its own LYNXgram keys |
t25 | the other hand's keys, index for index and thumb for thumb |
t15 | its own LYNXgram layer 1 (numbers, symbols) |
t25 + t15 | the other hand's layer 1 |
The two thumb keys this takes are the left's GUI and Alt in LYNXgram: on one hand GUI sits on
i7 and Alt on m0 (the right's wheel push). Vial unlocks with that hand's i4 + i1, on a
tower too. The rule and its check that every LYNXgram binding stays reachable are in
keymap_profile.rs.
Keymap persistence
Vial edits live in the Coordinator's rmk_storage partition (the tower's, or a Coordinator cat's); the settings above have a partition
of their own. RMK erases its storage at boot when the stored hash differs from the
firmware's, and it computes that hash from the build time whenever its build script runs:
- A rebuild or reflash from the same
target/keeps the Vial edits. - The first build after
target/was cleaned, the container image or toolchain changed, or the RMK version changed erases them once, at the first boot of that firmware. Note your keymap in Vial (or save it to a file there) before such a change. - A changed default keymap in lynxgram.rs, or a changed default behaviour setting, does not reach a tower whose storage survived. RMK stores the whole keymap at its first boot, and the stored keymap wins over the code's defaults.
- A changed setup does: when the Coordinator's hands change (a lone cat gets a partner, a tower is paired with one cat instead of two), its next boot replaces the stored keymap with the new setup's default, Vial edits included. The settings record keeps which default the stored keymap came from. Save your keymap in Vial before pairing differently.
To apply new defaults to such a tower, set clear_layout: true in storage_config() in
usb.rs, flash, then remove it and flash again. It rewrites the keymap
and behaviour settings from the defaults. clear_storage: true erases all of RMK's storage
instead. Either takes effect at every boot while set, so Vial edits made meanwhile are lost
at the next boot.
Vial integration gotchas
The pinned integration uses custom keycodes because it does not expose arbitrary preferences menus. Keep their order stable so saved bindings retain their meaning.
For an empty layout, compare with the minimal KLE properties in the shipped
vial.json; decorative properties have broken rendering in past tests. For an
empty Matrix Tester, check RMK's host_lock feature. The tested unlock pair is
VIAL_UNLOCK_CELLS in key_index.rs — i4 + i1 of the
left hand on a tower, of its own hand on a Coordinator cat; do not replace it with an untested
same-row pair. build.rs owns compression and host tests check matrix labels.