A Linux VT loads one font for the whole console, so asking for the 6x8 build (53x40, fourteen rows more) changes what the shell is drawn in too. The new console_font preference (6x12 default, 6x8 the alternative, offered on the PicoCalc only, round-tripping through preferences.yaml on every platform) therefore comes with services/consolefont.py: remember the font the shell had with `setfont -O`, apply the one the preference names, and restore it on every way out -- the menu's finally and an atexit hook, since ^Q and an unhandled error leave by other doors. Verified on the device that setfont -O captures the current font with its unicode table and that feeding it back reproduces it exactly, with no sudo, because the VT is the process's own controlling terminal. Only the interactive menu switches; a scripted run never touches the console it was invited into. Changing the preference on its page applies live. Shipping both fonts needed the licence untangled: the 6x8 base is the Linux kernel's font_6x8 bitmap, GPL-2.0, so its build moves into calculinux-console-font-6x8.sh under that licence with the GPLv2 text beside it in scripts/LICENSE.GPL-2.0. The shared generator stays in the 6x12 script between BEGIN/END markers and the 6x8 script executes that block, so the marks, donors and aliases the font contract pins exist in one place. The produced PSF is a data file the kernel console reads; MeshTerm never links or bundles it, and NOTICE and the hardware manual say so. PrefSpec gains a platforms gate for the page; the labels use an ASCII x because U+00D7 is not in the console font. The 6x8 base has no Cyrillic; the manual says so and the owner accepts it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
scripts
Device-side helpers that put MeshTerm on real hardware: bringing up a ClockworkPi PicoCalc (Luckfox Lyra, Calculinux) and building its console font, giving that handheld a real MeshCore radio over UART, and fronting an SPI-attached LoRa chip as if it were a companion device. They run on the device, most of them as root, and they are meant to be read before they are run.
docs/hardware.md is the manual — what each target is, what the
scripts assume about the machine, why each step is the way it is, and what has only ever
been proven on one bench. Start there and pick your target; the table below is the index.
| File | Runs on | What it does |
|---|---|---|
calculinux-setup.sh |
the Lyra (root) | One-time bring-up: python packages, the Wi-Fi boot-scan kick, a boot clock sync (there is no RTC), the deploy user, the checkout, the venv and pip install -e ., the login PATH, and the console font. Idempotent. |
calculinux-console-font.sh |
the Lyra (root) | Just the console font: builds, installs and persists the 512-glyph meshterm PSF (braille, node marks, rounded frame corners, the list cursor) and restores the stock 16-slot palette. Calls the 6×8 build below when it sits alongside. Run it alone after a MeshTerm update. |
calculinux-console-font-6x8.sh |
the Lyra (root) | The shorter-cell companion font, meshterm8 (6×8 → 53×40), for anyone who wants more rows than the 6×12 default gives. Its base bitmap is the kernel's font_6x8, so this one file and the PSF it builds are GPL-2.0-only (LICENSE.GPL-2.0); it reads the donor/alias/keeper tables out of the script above rather than keeping a second copy. Pick between the two fonts from MeshTerm's Preferences page. |
calculinux-wifi-set.sh |
the Lyra (sudo) | Interactive Wi-Fi join: prompts for an SSID and passphrase, writes iwd's credentials, connects now. This is how a network becomes known to the boot kick. |
calculinux-radio-bridge.sh |
the Lyra (root) | Unfinished, unsupported. An early UART-to-TCP pump, superseded by xiao-radio/lyra-setup.sh; its header describes routing it does not contain. See the manual before reading it. |
meshterm-spi-bridge |
the radio host (your user) | Runs a mesh node in software over an SPI-attached SX1262 (uConsole AIO, Waveshare HATs) and serves the companion protocol on 127.0.0.1:5000. Setup menu, preflight, optional systemd --user service. Written for pymc_core 1.0.x — see the manual's rename note before installing. |
xiao-radio/ |
see below | Everything for the XIAO nRF52840 + Wio-SX1262 radio wired to the Lyra's UART1. |
xiao-radio/build-firmware.sh |
dev machine | Clones and patches MeshCore, builds the Xiao_nrf52_companion_radio_serial environment, emits the .uf2. |
xiao-radio/flash.py |
dev machine | Flashes the .uf2 to the XIAO over its UF2 bootloader, refusing the wrong board or SoftDevice; prints the serial-DFU command when the bootloader offers no drive. |
xiao-radio/meshcore-uart1.patch |
— | The two firmware hunks: the companion on nRF52 Serial1, and I²C moved off the UART pads. Not upstream yet. |
xiao-radio/lyra-setup.sh |
the Lyra (root) | Boot-persistent UART1 → GP4/GP5 mux service, dialout membership, and a default MeshTerm serial profile for /dev/ttyS1. |
xiao-radio/uart1-mux.py |
the Lyra (root) | The matrix-IO register poke that routes UART1 to the header pads, run once per boot by the service above. |
The PicoCalc scripts and the SPI bridge belong to different machines and share nothing but
MeshTerm. On the Lyra, only one program may hold /dev/ttyS1 — MeshTerm directly, or a pump
in front of it, never both.