feat: Raspberry Pi 5 (aarch64) target + Pyramid Apex RS-232 bill validator #87
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/rpi5-apex-hal"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds a second reference hardware platform for bitSpire — a DIY Raspberry Pi 5 build — plus the bill-validator driver its parts need. Groundwork for the "install bitspire from these parts" build (Pi 5 + Apex 7600 acceptor + 7" touch + QR scanner + SATA SSD). Everything here is additive; the x86 fleet (sintra/douro/tejo/batm3) is byte-identically unaffected (verified
sintra-installedtoplevel unchanged).Three commits, independently reviewable:
1.
feat(hal)— Pyramid Apex RS-232 driverNeither the Apex 7600 nor the NV10 USB+ speaks id003/ebds (the only validators we shipped). The Apex speaks Pyramid RS-232; this adds a clean-room driver written from Pyramid's public protocol spec + their published Python reference host — license-clean, and it respects the lamassu-machine provenance boundary (no code sourced from that tree).
packages/hal/src/validators/apex/apex-rs232.ts— protocol layer (8-byte poll frame, XOR checksum, ACK toggle, state/event/credit response bytes). Pure, testable fns.apex-fsm.ts— status tracker →BillValidatorevents (dedupe + escrow watchdog), mirrorsEbdsFsm.denominations.ts— per-fiat channel→value table.index.ts—ApexValidator implements BillValidator, 100ms poll, mirrorsEbdsValidator.validators/index.ts— wired into the factory (ValidatorTypegains'apex').Bench-verify before trusting on real hardware: the reply-checksum range and the return-by-disable (reject) behaviour are flagged in-code as needing confirmation on an actual 7600. The NV10 USB+ (SSP/eSSP) driver is deliberately deferred — one driver now, swap later.
2.
feat(deploy)— aarch64 Pi 5 targetflake.nix—nixos-hardwareinput, aarch64 pkgs, and the Pi build machinery. Runtime mirrorsmkInstalledConfig(bitspire service, env seed, electron override) on aarch64 + Pi hardware, dropping x86-only bits (determinate, atm-tui) for first bring-up.deploy/nixos/hardware/raspberry-pi-5.nix— the aarch64 twin ofupboard.nix: extlinux boot,console=tty0(UART free for a GPIO-wired validator), vc4/v3d KMS for the kiosk display, no-suspend, and/dev/ttyValidator{0,1,2}udev symlinks for FTDI / CP210x / CH340 USB-serial bridges.3.
feat(deploy)— split rpi5 into installed + image variantsrpi5-installedoriginally bundled the sd-image module, so it could only build a flashable image — an in-placenixos-rebuild switchagainst it would drag in the image builder. Split it, mirroring the x86mkLiveConfig/mkInstalledConfigseparation:rpi5-installed→ in-place rebuild target. Declares the flashed media's own root fs (NIXOS_SD / FIRMWARE), nothing image-specific. Targeted by the aarch64 twin of the fleet deploy ritual:rpi5-image→ same runtime + the sd-image builder;packages.aarch64-linux.sd-image-rpi5points here.Also folds the aiolabs cachix substituter + trusted key into the Pi's
nix.settings, so a remote rebuild substitutes the heavy aarch64 closure instead of compiling on the Pi.Build note: any Pi target needs an aarch64 builder (native Pi / arm box / binfmt) — the app closure won't build on x86. First flash:
nix build .#packages.aarch64-linux.sd-image-rpi5→dd. Updates thereafter: thenixos-rebuild switchremote-flake command above.🤖 Generated with Claude Code
`rpi5-installed` previously bundled the sd-image-aarch64 module, so it was only good for building a flashable image — a `nixos-rebuild switch` against it (local or the git+ssh remote form) would drag in the image builder and its image-specific fs wiring. Split it, mirroring the x86 fleet's mkLiveConfig/mkInstalledConfig separation: - rpi5-installed → in-place rebuild target. Declares the flashed media's own root fs (NIXOS_SD / FIRMWARE labels), nothing image-specific. This is what sudo nixos-rebuild switch --flake \ "git+ssh://forgejo@git.atitlan.io/aiolabs/bitspire.git?ref=<branch>#rpi5-installed" targets, the aarch64 equivalent of the sintra/douro deploy ritual. - rpi5-image → same shared runtime + the sd-image builder. Its system.build.sdImage is the flashable artifact; packages.aarch64-linux .sd-image-rpi5 now points here. Shared runtime extracted into piBaseModules/mkPiRuntime; folded the aiolabs cachix substituter + trusted key into the Pi's nix.settings so a remote rebuild substitutes the heavy aarch64 closure instead of building it on the Pi (no max-jobs/timeout watchdog — the Pi 5 can build locally if it must). Verified: rpi5-installed evaluates to a valid system toplevel (root fs present), rpi5-image/sd-image-rpi5 to the .img.zst builder, and x86 sintra-installed is byte-identically unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGUJJjBDuYwRaWSkFdK3bmAdded one commit:
082f738 fix(deploy): console=tty0 was being dropped on the Pi 5.It was sitting on
feat/rpi4-target, so the fix for the bug this PR introduces only existed on an unproposed branch. If #87 had merged as it was, it would have merged with the bug. Cherry-picked here so the PR is correct on its own.The Pi 4 work is now #110, stacked on this branch. Merge this one first; #110 retargets to
devafterwards.View command line instructions
Manual merge helper
Use this merge commit message when completing the merge manually.
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.