Files
MeshTerm/docs/hardware.md
T
Jean-Pierre MartineauandClaude Opus 5.5 9538bfedce MeshTerm drives an SPI radio itself, without the bridge service
A LoRa chip on the host's own SPI bus (the uConsole AIO) is now a
transport like serial, BLE, and TCP: --spi, an SPI profile, or the
picker's row for /dev/spidev1.0. MeshTerm starts a software node as a
child process under whichever Python has openhop-core, talks to it over
a loopback port, and ends it on disconnect; the node also exits with its
parent, so the pins are free whenever MeshTerm is not running.

The node keeps identity, prefs, channels, and contacts under
~/.meshterm/radio/<spidev>/, and on first use copies the bridge's
identity, contacts, and radio settings so it stays the same node.
Board wiring lives in a profile's spi table; radio settings are the
node's own, edited on Device config. Closes #21.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 01:48:32 -04:00

73 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MeshTerm on hardware
MeshTerm talks to a **node** — a MeshCore radio that speaks the companion protocol over
serial, Bluetooth LE or TCP. Plug a companion board into USB, or pair one over Bluetooth,
and none of this page applies: MeshTerm finds it, and the [README](../README.md) and the
[command line manual](cli.md) are all you need.
This page is for the hardware that *doesn't* present a node that way. Each such device has
its own step-by-step manual, and this page only tells you which one is yours.
## Which guide is yours
| I have… | Read |
| --- | --- |
| a ClockworkPi **PicoCalc**, stock or already running Calculinux on a Luckfox Lyra, and I want MeshTerm on its own screen | **[MeshTerm on the PicoCalc](picocalc.md)** — from the shopping list to a working machine |
| …and I want a **radio** inside it | the same manual, [Phase 3](picocalc.md#phase-3--add-the-radio) — a XIAO nRF52840 + Wio-SX1262 soldered to the Lyra's UART |
| a ClockworkPi **uConsole** with the hackergadgets AIO board — an SX1262 on the host's own SPI bus | **[MeshTerm on the uConsole](uconsole.md)** — MeshTerm drives it directly with `--spi`, or a bridge service fronts it as a companion if you want it always on |
| a MeshCore companion on USB, BLE or Wi-Fi | nothing here — the [README](../README.md) |
The two targets have nothing in common but MeshTerm itself. The device-side scripts each
manual runs live in [`scripts/`](../scripts/), one folder per handheld; the
[index below](#the-scripts) says what every file does and which machine it runs on. Read a
script before you run it; most run as root and change the machine they run on.
## The scripts
[`scripts/`](../scripts/) holds the device-side helpers, one folder per manual:
[`picocalc/`](../scripts/picocalc/) for the PicoCalc — bringing up Calculinux on the Lyra,
building its console font, and (under [`xiao-radio/`](../scripts/picocalc/xiao-radio/))
giving it a MeshCore radio over UART — and [`uconsole/`](../scripts/uconsole/) for the
always-on bridge that fronts the uConsole's SPI-attached LoRa chip as a companion (MeshTerm
can also drive that chip directly, with no script at all — the uConsole manual covers
both). The manual is the
walkthrough; each script's own header says what it assumes about the machine and why each
step is the way it is. On the Lyra, only one program may hold `/dev/ttyS1` — MeshTerm
directly, or a pump in front of it, never both.
| File | Runs on | What it does |
| --- | --- | --- |
| [`picocalc/calculinux-setup.sh`](../scripts/picocalc/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. |
| [`picocalc/calculinux-console-font-6x12.sh`](../scripts/picocalc/calculinux-console-font-6x12.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, from the pulled checkout (`/home/meshterm/MeshTerm/scripts/picocalc/`) rather than the copy made at install time. |
| [`picocalc/calculinux-console-font-6x8.sh`](../scripts/picocalc/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`](../scripts/picocalc/LICENSE.GPL-2.0) sits beside it); 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. |
| [`picocalc/calculinux-wifi-set.sh`](../scripts/picocalc/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. |
| [`picocalc/calculinux-radio-bridge.sh`](../scripts/picocalc/calculinux-radio-bridge.sh) | the Lyra (root) | **Unfinished, unsupported.** An early UART-to-TCP pump: it serves `/dev/ttyS1` on TCP port 5000 and writes a `radio` TCP profile. It does not route UART1 to the header pads. Superseded by `xiao-radio/lyra-setup.sh`, which does the routing and points MeshTerm at the serial port directly. |
| [`picocalc/xiao-radio/`](../scripts/picocalc/xiao-radio/) | see below | Everything for the XIAO nRF52840 + Wio-SX1262 radio wired to the Lyra's UART1; its [bench card](../scripts/picocalc/xiao-radio/README.md) has the wiring table. The firmware is MeshCore, MIT-licensed — [`LICENSE.MeshCore`](../scripts/picocalc/xiao-radio/LICENSE.MeshCore) sits beside the patch. |
| [`xiao-radio/build-firmware.sh`](../scripts/picocalc/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`](../scripts/picocalc/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`](../scripts/picocalc/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`](../scripts/picocalc/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`](../scripts/picocalc/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. |
| [`uconsole/meshterm-spi-bridge`](../scripts/uconsole/meshterm-spi-bridge) | the radio host (your user) | The **always-on** option: 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`, so the node stays on the mesh while MeshTerm is closed. Setup menu, preflight, optional `systemd --user` service. Runs on `openhop_core` (preferred) or its predecessor `pymc_core`; see the manual for the venv it wants on a bookworm uConsole. Most people should reach for `meshterm --spi` instead — no script, no service, MeshTerm drives the chip itself while it runs. |
## The regular and picocalc platforms
MeshTerm resolves one frozen **platform** at boot and draws everything through it. The
**regular** platform is a desktop or ssh terminal: 72 readable columns, truecolour, emoji,
a footer hint line. The **picocalc** platform is a framebuffer console: 53 columns, no
emoji, an F-key lane instead of a hint line, and sixteen colour slots rather than a colour
space. Nothing loses its colour there: the node hue and the recency heat gradient
quantise to those slots instead. It is detected from the device tree on the Lyra, and
`--platform picocalc` or `MESHTERM_PLATFORM=picocalc` forces it anywhere, which is how you
preview the handheld layout on a desktop:
```bash
meshterm --mock --platform picocalc # the whole app, simulated radio, handheld layout
meshterm specimen # the visual language on one card
meshterm platform # which platform this terminal resolved to
```
What that platform needs from the console — a font with the glyphs the interface draws,
and the stock sixteen-slot palette — is installed by the PicoCalc manual's setup script;
the details are in that manual and in the scripts' own headers.