KN-86 Deckline — Pi Zero Build Specification
Spec hygiene (CLAUDE.md rule 1). This document does not restate concrete hardware values (display resolution, grid dimensions, battery capacity, current draw, clock speeds, case dimensions, etc.). Those live in CLAUDE.md’s Canonical Hardware Specification table. When a value is needed here, it is referenced as “see CLAUDE.md Canonical Hardware Specification.” If a number ever appears inline in this doc, it is a bug — file an issue and fix it.
1. Pi Zero 2 W Overview
Section titled “1. Pi Zero 2 W Overview”The KN-86 Deckline runs on the Raspberry Pi Zero 2 W as its sole production and prototype compute platform. The Zero 2 W is a full ARM Cortex-A53 Linux single-board computer small enough to mount inside the Pelican 1170 hardcase’s foam-lined interior, yet capable of driving the Elecrow 7” IPS display over HDMI, running a Linux userspace nOSh process, and handling all audio synthesis and peripheral I/O through off-the-shelf USB and I2S modules. For the exact display resolution, text grid, and other canonical device-spec values, see CLAUDE.md.
For the canonical processor specification, RAM, connectivity summary, display driver target, audio chain, peripherals, case dimensions, battery capacity, runtime, and ship target, see CLAUDE.md Canonical Hardware Specification. This document references those values; it does not restate them.
The Zero 2 W platform replaces an earlier microcontroller-based exploration that was archived in April 2026. That work lives under docs/_archive/hardware/ and docs/_archive/adr/ADR-0003-firmware-update-mechanism.md — retained for historical context only. The earlier target was dropped because the Elecrow 7” IPS display we settled on uses HDMI rather than a dedicated LCD bus, and the Zero 2 W’s Linux userspace model makes the system image update path, USB HID keyboard integration, and cartridge filesystem all dramatically simpler than they would have been on a bare-metal platform.
Why Zero 2 W and not Zero W / Pi 4 / Zero 2 W variants
Section titled “Why Zero 2 W and not Zero W / Pi 4 / Zero 2 W variants”- Zero W (original): Insufficient compute for the desktop emulator path; nOSh’s UI animations and PSG synthesis benefit meaningfully from the Cortex-A53 quad core.
- Pi 4: Overpowered and too physically large to fit the Pelican 1170’s interior envelope. Power draw would also compromise the battery runtime target.
- Zero 2 WH (pre-soldered header variant): Functionally identical to Zero 2 W for our purposes; either is acceptable at bench-rig scale. The build uses whichever is available.
2. Hardware Topology
Section titled “2. Hardware Topology”The KN-86 is a collection of off-the-shelf modules wired into the Pi Zero 2 W through standard interfaces. There is no custom main-board PCB — the build is constructed on a small interconnect plate with screw terminals and JST-PH harnesses. This is deliberate: it keeps the v0.1 build accessible to anyone with basic soldering skills and avoids the lead-time risk of PCB fabrication.
+----------------------------------------------------------------------+| KN-86 DECKLINE || || Elecrow 7" IPS <--HDMI-- Pi Zero 2 W <--USB OTG--> internal hub || (primary disp) (Linux + nOSh) | || +--+ || | | | || | v v || | QMK Kbd Controller || | (custom mech keeb, || | ADR-0018, 30-key) || | | || | v || | USB-to-SD bridge IC || | + push-push SD socket || | (cartridge interface, || | ADR-0019) || | || UART0 @ 1 Mbps (per ADR-0017) || v || Pi Pico 2 (RP2350) || realtime I/O coprocessor || (ADR-0017; cart-bus role removed by ADR-0019) || / | || SPI I2S || v v || SSD1322 OLED MAX98357A || (CIPHER-LINE, (I2S DAC, || ADR-0015) class-D amp) || | || speaker / 3.5mm TRS || || LiPo <-- USB-C --> TP4056 --> PowerBoost 1000C --> 5V rail || (3000mAh, see CLAUDE.md) || |+----------------------------------------------------------------------+The topology was revised on 2026-04-24 per ADR-0017 to introduce the Pi Pico 2 coprocessor between the Pi and the realtime peripherals (originally: DMG cartridge bus, I2S audio, SSD1322 OLED). Later that same day, ADR-0019 superseded ADR-0013’s DMG cartridge format with a full-size SD card carried in a custom clamshell sled — read by the Pi via USB mass storage through a card reader bridge IC on the internal USB hub, not through the Pico 2. The Pico 2 retains its audio (I2S to MAX98357A) and CIPHER-LINE OLED responsibilities under ADR-0017; only the cart-bus responsibility moved off the Pico. Pre-ADR-0017 history: the Pi drove SPI0 to the OLED and I2S to the MAX98357A directly. See docs/software/api-reference/grammars/coprocessor-protocol.md for the UART command protocol byte-level spec; the cart-related frame types in that protocol (CART_DETECT, CART_READ_BANK, CART_READ_SRAM, CART_WRITE_SRAM, CART_RESET) are now obsolete under ADR-0019 and are subject to a follow-up cleanup.
Subsystem roles
Section titled “Subsystem roles”| Subsystem | Module | Role | Interface |
|---|---|---|---|
| Compute (primary) | Pi Zero 2 W | Linux userspace, nOSh process, SDL2 rendering, mission board, deck state, Fe VM execution. Sends realtime-I/O commands to the Pico 2 coprocessor over UART0. | Host |
| Coprocessor (realtime I/O) | Pi Pico 2 (RP2350) | Owns YM2149 PSG synthesis with I2S out to MAX98357A and the SSD1322 CIPHER-LINE OLED driver. Accepts high-level commands from Pi over UART0. See ADR-0017 and docs/software/api-reference/grammars/coprocessor-protocol.md. The DMG cartridge bus responsibility originally assigned to the Pico 2 in ADR-0017 was removed by ADR-0019 (cartridge interface moves to a USB-mass-storage SD card via the internal hub bridge IC; the Pico 2 no longer touches the cartridge bus). | UART0 @ 1 Mbps from Pi |
| Display (primary) | Elecrow 7” IPS | Framebuffer surface for SDL2 output | HDMI (mini-HDMI adapter) |
| Display (auxiliary) — CIPHER-LINE | 3.12” SSD1322 OLED (see CLAUDE.md Aux Display row) | Cipher voice surface (exclusive) + utility surfaces (battery, timer, mode, TERM hint, seed capture, mission meta). See ADR-0015. Driven from the Pico 2 SPI bus, not Pi SPI0, per ADR-0017. | 4-wire SPI from Pico 2 |
| Input | Custom mech keeb (QMK-compatible controller — Pro Micro, RP2040-class, or equivalent) on a custom-fab unified 30-key PCB (preferred) or split-layout PCB reconnected under a single keyplate (fallback). See ADR-0018. | 30-key matrix scanner, USB HID keyboard | USB HID → internal USB hub → Pi OTG |
| USB hub (internal) | TUSB2036 / FE1.1s or equivalent 2-to-4 port USB 2.0 hub IC on the interior plate | Fans Pi OTG out to keyboard controller (ADR-0018) + USB-to-SD card reader bridge IC (ADR-0019, the cartridge interface) + future internal USB peripherals | USB 2.0 |
| Cartridge interface | Full-size SD card via USB mass storage. Push-push surface-mount SD socket + USB-to-SD card reader bridge IC (e.g., Genesys GL3224 / GL3232, Realtek RTS5129 — specific part TBD per ADR-0019 Open Q §1) on a small internal PCB at the back of the slot. See ADR-0019. | Loads .kn86 cartridges as files from the SD filesystem; per-cartridge save data lives as a file on the same SD. Replaces the v0.1 microSD-resident cartridges and the (now superseded) ADR-0013 DMG/MBC5/edge-connector path. ADR-0019 also removes the cart-bus responsibility from the Pico 2 (ADR-0017 partially superseded). | USB mass storage via internal hub |
| Audio synthesis | Pi Pico 2 (firmware) | YM2149 PSG emulation, envelope generation, atomic register writes (PSG_REG_WRITE / PSG_BULK_WRITE). Pre-ADR-0017 baseline ran on the Pi (emu2149 port, on-CPU); moved to the Pico 2 for deterministic 44.1 kHz output independent of Linux scheduler jitter. Audio + OLED responsibilities remain on the Pico 2 under ADR-0017 even after ADR-0019 removed the cart bus from the Pico’s scope. | Pico 2 firmware → I2S |
| Audio output | MAX98357A | I2S digital-to-analog conversion + class-D amplification | I2S from Pico 2 (was Pi GPIO pre-ADR-0017) |
| Speaker | Round driver (see CLAUDE.md for size / impedance / wattage) | Mono speaker; collapses directional audio when headphones absent | Amp output |
| Audio jack | 3.5mm TRS | Switched jack; inserting a plug disconnects the internal speaker | Amp output passthrough |
| Power | LiPo (see CLAUDE.md) + TP4056 charger + PowerBoost 1000C | Battery + USB-C charging + 5V rail up-conversion | USB-C input, 5V rail to Pi |
| Storage | microSD | A/B slot layout per ADR-0011, cartridge filesystem, deckstate, saves | microSD socket |
| Case | Pelican 1170 Protector Case + 3D-printed inset panels | See CLAUDE.md for dimensions and material. Off-the-shelf black polypropylene shell; printed PLA/PETG insets carry primary display bezel, CIPHER-LINE bezel (above key plate, per ADR-0015), key plate, cartridge-slot retainer, and port cutouts; Pelican foam is cut to seat components. | — |
Why a USB HID keyboard over direct GPIO matrix
Section titled “Why a USB HID keyboard over direct GPIO matrix”The Zero 2 W’s GPIO header is usable for a key matrix but introduces three problems: (1) it monopolises pins we’d otherwise reserve for I2S and future peripherals; (2) it requires userspace debounce, key-repeat, and hold-detection code that is already solved in stock QMK on any QMK-compatible keyboard controller; (3) it couples key scanning latency to Linux userspace scheduling. Routing the matrix through a QMK-compatible controller that presents as a USB HID keyboard lets us buy all of that for free, and gives us a consistent input surface between the emulator (where a desktop keyboard is the input) and the device (where the keyboard controller enumerates as a keyboard). Per ADR-0018 the keyboard is built as a custom mechanical keyboard using the mech-keeb DIY ecosystem — hot-swap Choc v1 sockets, stock QMK firmware, a QMK-compatible controller (Pro Micro, RP2040-class, or equivalent), and an internal USB hub IC to fan the Pi’s single OTG port out to the keyboard plus the cartridge bridge (ADR-0011). No external USB cables.
Per ADR-0011, the USB HID choice pushes one constraint onto the system image update system: the attention gesture (SYS+LINK held at boot) cannot be detected by an early-boot GPIO scan because the keys are USB HID, not GPIO. The system-image-update gate waits for USB enumeration before scanning. See ADR-0011 “Early-boot key-scan timing” for the full treatment.
Cartridge system
Section titled “Cartridge system”For v0.1 bench-rig builds, cartridges are filesystem entries on the device’s boot microSD — physical cartridges are not yet wired up. The committed cartridge physical format for production is ADR-0019: a full-size SD card carried in a custom two-piece clamshell shell (~58 × 65 × 8 mm), read by the Pi as USB mass storage through a card reader bridge IC on the internal USB hub planned in ADR-0018. Per-cartridge save data lives as a file on the cart’s own SD filesystem; Universal Deck State remains on the device’s microSD per ADR-0011. The .kn86 container format (ADR-0006) and the capability model (ADR-0001, docs/software/runtime/orchestration.md) are unchanged regardless of physical container. ADR-0019 supersedes the earlier ADR-0013 (DMG 32-pin pinout + MBC5 mapper + CR2032-backed on-cart SRAM); the bring-up tasks for the SD-sled cartridge interface are listed in ADR-0019 as CART-01 through CART-07.
CIPHER-LINE auxiliary display (driven via Pi Pico 2 per ADR-0017)
Section titled “CIPHER-LINE auxiliary display (driven via Pi Pico 2 per ADR-0017)”Per ADR-0015, the KN-86 has a second, smaller display — the CIPHER-LINE — mounted above the key plate. It is an SSD1322-driven 256×64 yellow OLED that carries the Cipher voice exclusively (no Cipher glyphs ever render on the primary 80×25 grid) plus a fixed set of utility surfaces (battery, timer, mode chip, TERM hint, seed capture, mission meta). Canonical module values are in CLAUDE.md’s Auxiliary Display row.
Per ADR-0017 (2026-04-24), the SSD1322 panel’s 4-wire SPI bus is driven by the Pi Pico 2 coprocessor — not by the Pi Zero 2 W’s SPI0. The Pi sends high-level OLED commands (OLED_SET_ROW, OLED_SCROLL_ROW, OLED_FILL, OLED_CLEAR) to the Pico over UART0; the Pico runs the SPI bus to the panel and executes the ticker scroll animation autonomously. This keeps the OLED cadence rock-steady regardless of Pi rendering load. The Pi’s SPI0 and SPI1 are freed up for future peripherals.
The Pico’s SPI pin assignment to the SSD1322 is finalised at F2 firmware bring-up (kn86-pico/); the Pico has 26 usable GPIOs and ample SPI flexibility, so any consistent set works. Same applies to the DC and RST control lines.
| Signal | Pico GPIO | Notes |
|---|---|---|
| MOSI | TBD at F2 bring-up | One of Pico’s SPI MOSI-capable pins. |
| SCLK | TBD at F2 bring-up | One of Pico’s SPI SCLK-capable pins. |
| CS | TBD at F2 bring-up | Any GPIO; tied to the Pico’s selected SPI peripheral. |
| DC (data/command) | TBD at F2 bring-up | Any GPIO. |
| RST (reset) | TBD at F2 bring-up | Any GPIO. |
| VCC | 3.3 V | From Pico’s 3V3(OUT) pin. |
| GND | GND | — |
The Pi Zero 2 W and the Pico 2 both have 3.3 V rails, but the SSD1322 module is powered from the Pico’s 3.3 V output now that the SPI lines also originate from the Pico — keeping all OLED-related signals and power on a single ground domain.
3. Power and Battery
Section titled “3. Power and Battery”The KN-86 runs on a single-cell LiPo with USB-C charging. Runtime, battery capacity, and typical current draw values are canonical — see CLAUDE.md Canonical Hardware Specification for the specific numbers. This section covers only the topology.
Power path
Section titled “Power path”USB-C input -> TP4056 charger -> LiPo cell -> PowerBoost 1000C -> 5V rail | +-------------------------+ | | v v Pi Zero 2 W MAX98357A (5V VIN pin) (5V VIN pin) | v 3.3 V GPIO rail -> CIPHER-LINE OLED (ADR-0015)The TP4056 with USB-C input handles charge regulation and cell protection (over-charge, over-discharge, over-current cut-offs). The PowerBoost 1000C steps LiPo voltage up to a stable 5V rail capable of passing through USB input power to the load — this is important for the ADR-0011 update flow, where the device is cable-attached during flashing.
Pi Pico 2 coprocessor (per ADR-0017, post-ADR-0019 scope): the Pico draws from the 5 V rail via VBUS, regulates internally, and drives the CIPHER-LINE OLED off its own 3.3 V output. Active draw at 150 MHz with the realtime workload (PIO state machines for I2S audio output + main-loop OLED ticker; the DMG cart-bus role from ADR-0017 was removed by ADR-0019) is ~25–55 mA typical, dropping to <5 mA in dormant mode. Add to the pre-coprocessor Pi typical draw cited in CLAUDE.md baseline and the post-coprocessor envelope is ~145–235 mA typical. Runtime band shifts from ~20 h (pre-coprocessor) to ~13–17 h (post-coprocessor) — see CLAUDE.md Battery row. This is a real envelope hit accepted by Josh on 2026-04-24; ADR-0017’s Trade-off Analysis enumerates mitigations (Pico dormant-mode gating during idle, larger battery, Pico underclock when audio inactive). Bring-up measurement at Stage 1c (§4 below) validates the post-coprocessor draw against the ~25–55 mA estimate.
CIPHER-LINE OLED (per ADR-0015 + ADR-0017): the SSD1322 module pulls ~10–30 mA typical and ~40 mA peak (high-brightness, full-field update). Per ADR-0017 the OLED is now powered from the Pico’s 3.3 V output rather than the Pi’s 3.3 V GPIO rail (the SPI lines also originated on the Pi pre-ADR-0017 and now originate on the Pico, so power and signal stay on a single ground domain). The OLED’s own draw is unchanged; only the source rail changed.
Low-battery behaviour
Section titled “Low-battery behaviour”The Zero 2 W has no built-in fuel gauge. A resistor-divider on one of the Pi’s GPIO-capable ADC paths (via an external MCP3008 or equivalent I2C ADC if ADC isn’t available natively) samples pack voltage at ~1 Hz. nOSh displays a low-battery glyph in the status bar (Row 0) below a threshold, writes a best-effort deckstate checkpoint near the end of useful capacity, and initiates a clean shutdown before the protection circuit cuts power.
Idle behaviour
Section titled “Idle behaviour”Idle power savings on Zero 2 W are modest compared to a bare-metal MCU — the Linux kernel cannot reach deep sleep without framebuffer and USB-gadget teardown. nOSh implements a soft idle: dim the Elecrow backlight, pause PSG audio output, reduce the SDL render cadence, and let the kernel idle the CPU. Any HID event wakes the full rendering path.
4. Assembly Plan
Section titled “4. Assembly Plan”v0.1 is a bench-rig build, not a production-grade assembly. The plan is deliberately linear — no parallelised workstreams, no custom fab dependencies.
Stage 0 — Bring-up
Section titled “Stage 0 — Bring-up”- Flash a blank microSD per the ADR-0011 partition layout (use
tools/sd-provision/provision.shonce Wave 2 lands; manually partition otherwise). - Boot the Zero 2 W headless, verify network over Wi-Fi, SSH in.
- Install the kn86 userspace (scp from dev box, per ADR-0011 “Dev ergonomics”).
Stage 1 — Display (primary)
Section titled “Stage 1 — Display (primary)”- Power the Elecrow 7” IPS from its own USB-C supply (it is not battery-powered off the KN-86 pack in v0.1; see “Future work” below).
- Connect mini-HDMI from the Pi to the Elecrow input.
- Edit
/boot/config.txtto force HDMI at the native resolution (see CLAUDE.md for the target) and disable HDMI compensation modes. - Boot, verify SDL2 can render at the intended framebuffer size, and verify the text grid lays out correctly with the Row 0 / Row 24 firmware-reserved rows as specified in CLAUDE.md Canonical Hardware Specification.
Stage 1b — Display (auxiliary, CIPHER-LINE)
Section titled “Stage 1b — Display (auxiliary, CIPHER-LINE)”Added per ADR-0015. Per ADR-0017 (2026-04-24), the SSD1322 SPI bus is now driven by the Pi Pico 2 coprocessor — not by the Pi’s SPI0. Run Stage 1c (below) first to bring up the Pico, then complete this stage with the OLED wired to the Pico’s SPI pins (TBD at F2 firmware bring-up). The validation goals below — panel wakes, glyph rendering, layout test, brightness measurement — are unchanged; only the SPI host and the device-tree-overlay step are obsolete.
- Wire the SSD1322 3.12” 256×64 OLED module to the Pi Pico 2’s SPI header (per ADR-0017; specific Pico GPIOs finalised at F2 firmware bring-up). Use short jumper leads with Dupont header connectors for v0.1; a JST-PH harness is a later polish pass. The pre-ADR-0017 wiring (Pi GPIO10/11/8/25/24) is no longer applicable.
- Pi-side SPI0 device-tree-overlay enablement is no longer required for CIPHER-LINE — the Pi does not drive the OLED bus. Free SPI0 on the Pi remains available for a future peripheral.
- Run the SSD1322 init sequence from the driver shipped with nOSh — confirms the panel wakes, accepts the oscillator / GPIO / segment-remap configuration, and responds to a framebuffer write. v0.1 uses 8 bpp grayscale mode on the SSD1322 with a single-level palette (monochrome yellow, matching the amber aesthetic); later firmware revisions may exploit the SSD1322’s 16-level grayscale for CIPHER-LINE typewriter fade transitions.
- Render the four-row test layout described in ADR-0015 §Layout: status strip on Row 1, Cipher scrollback on Rows 2–3, contextual surface on Row 4. Verify the Press Start 2P 8×8 glyphs read at normal sight distance from the operator’s typical hand position.
- Measure the 3.3 V rail current with CIPHER-LINE idle and with a full-field update cycle. Record the measurement against the 10–30 mA typical / 40 mA peak estimate in §3 Power. If real draw exceeds the peak estimate by a material margin, flag the CLAUDE.md Battery row for re-evaluation per ADR-0015 Known Unknown #3.
- With CIPHER-LINE physically in hand, measure the bezel cutout dimensions against the printed inset panel CAD; update the panel CAD as needed. Bezel cutout dimensions are flagged TBD in ADR-0015 Known Unknown #2 until this step completes.
Stage 1c — Coprocessor (Pi Pico 2)
Section titled “Stage 1c — Coprocessor (Pi Pico 2)”Added per ADR-0017. Although this stage is presented after Stage 1b for chronological reasons (1b landed with ADR-0015, 1c lands with ADR-0017), the Pi Pico 2 must be flashed and the UART handshake verified BEFORE Stage 1b’s OLED bring-up can complete post-ADR-0017. Run 1c first in practice.
- Mount the Pi Pico 2 (RP2350) on the internal sub-board alongside the Pi Zero 2 W. Power the Pico from the 5 V rail via its VBUS pin; common ground with the Pi.
- Wire UART0 between Pi and Pico: Pi GPIO14 (TX) → Pico GPIO1 (RX); Pi GPIO15 (RX) ← Pico GPIO0 (TX); common ground. Wire Pi GPIO22 → Pico BOOTSEL and Pi GPIO23 → Pico RESET for the Pi-mediated firmware update flow (per ADR-0017 §6).
- Wire the Pico’s peripheral pins (specific GPIOs finalised at F2 firmware bring-up, see
kn86-pico/):- SPI bus to the SSD1322 OLED — see Stage 1b above.
- I2S output to the MAX98357A — overrides the Pi-side I2S routing referenced in Stage 2 below.
- (Cart-bus pins are not used.) Per ADR-0019, the cartridge interface is a USB-MSC SD card reader on the internal hub — not on the Pico. The DMG-cart-bus role originally assigned to the Pico in ADR-0017 was removed by ADR-0019; the Pico’s PIO state machines and GPIO budget cover I2S + OLED with comfortable headroom.
- Flash the Pico firmware (
kn86-pico/, F2 deliverable) using the Pi-mediated bootmode flow described in ADR-0017 §6: the Pi pulses BOOTSEL, asserts RESET, releases RESET, copies the UF2 image to the Pico’s USB-MSC mount, then resets into the new firmware. The first prototype build can also use direct USB-attachedpicotool loadfrom the dev box for faster iteration. - Verify the UART handshake. Power-cycle the Pi; nOSh sends
HELLOand expects aHELLOreply with the Pico’s role byte set, followed byVERSION_QUERY/VERSION_RESPONSE. If the handshake fails within 1 s of nOSh start, debug per the §5.3 bootstrap sequence indocs/software/api-reference/grammars/coprocessor-protocol.md. Successful handshake leaves the linkoperational; nOSh begins periodic heartbeats per Coprocessor Protocol §5.2. - Joint power measurement. Measure the 5 V rail draw with the Pico active, audio output enabled (e.g. PSG playing a steady tone via
PSG_REG_WRITE), and the CIPHER-LINE OLED ticker animating. Record against the ~25–55 mA Pico-side estimate in §3 Power. If joint draw exceeds the post-coprocessor envelope (~235 mA typical) by a material margin, escalate to Josh — the CLAUDE.md Battery row and ADR-0017’s Trade-off Analysis get revisited. - Cartridge bus verification at this stage is no longer applicable — the cartridge is a USB-MSC SD card mounted by the Pi via the internal hub bridge IC (ADR-0019), not driven by the Pico. End-to-end cartridge bring-up is covered by the SD-sled stage (
udevinsertion event → mount →.kn86cart load) called out in the cartridge-interface row of the §2 Subsystem Roles table; see ADR-0019 CART-01 through CART-07 for the bring-up checklist.
Stage 2 — Audio
Section titled “Stage 2 — Audio”Per ADR-0017, the MAX98357A I2S DAC/amp is driven by the Pi Pico 2 coprocessor — not the Pi. Run Stage 1c first to bring up the Pico; this stage’s wiring and validation use the Pico-side I2S.
- Solder the MAX98357A breakout to three Pico 2 GPIO pins for I2S (BCK / LRCK / DIN) plus 5 V (from the shared 5 V rail) and GND. Specific Pico GPIOs are finalised at F2 firmware bring-up — the Pico has dedicated PIO state machines for the I2S output. Pre-ADR-0017 wiring (Pi GPIO I2S pins +
hifiberry-dacdevice-tree overlay) is no longer applicable. - Pi-side device-tree audio overlay is no longer required — the Pi does not generate audio. The
hifiberry-dacoverlay step from earlier revisions is obsolete. - Wire the speaker and 3.5 mm TRS jack to the amp’s differential outputs. The TRS jack has a normally-closed contact that disconnects the speaker when a plug is inserted. Unchanged from pre-ADR-0017.
- Test-play a YM2149 reference pattern: have nOSh issue
PSG_REG_WRITEframes over UART to set up channel A with a steady tone (e.g. 440 Hz square), thenPSG_RESETto silence. The full synth-to-speaker chain is validated by clean audio output and clean silence on reset. End-to-end audio latency target is <30 ms (per ADR-0017 §Known Unknowns #5; Coprocessor Protocol §7).
Stage 3 — Input
Section titled “Stage 3 — Input”Per ADR-0018, the 30-key input is built as a custom mechanical keyboard. The exact controller part, PCB path (unified custom-fab vs. split-reconnected), and internal USB hub IC are selected by the hardware agent during bring-up; the steps below apply to either PCB path.
- Fab or acquire the 30-key PCB per ADR-0018 Option B (custom-fab unified) or Option C (split-reconnected). Populate with Kailh Choc v1 hot-swap sockets, 1N4148 diodes, and a QMK-compatible controller (Pro Micro, Sea-Picro, KB2040, or equivalent — chosen during bring-up).
- Flash stock QMK with the 30-key keymap (
firmware/kn86-keyboard/keymap.cor the controller’s equivalent) perdocs/software/runtime/input-dispatch.md§3. - Mount the internal USB hub IC (TUSB2036, FE1.1s, or equivalent) on the interior plate. Wire the hub’s upstream port to the Pi Zero 2 W’s OTG port and a downstream port to the keyboard controller.
- Install 30 Choc v1 switches in the hot-swap sockets; install MBK keycaps (blank in v0.1; legends are a polish pass).
- Verify
/dev/input/event*enumerates on the Pi and all 30 keys register correctly. Confirm debounce behaviour and the 3U EVAL bar registers on a single switch event.
Stage 4 — Power
Section titled “Stage 4 — Power”- Wire the LiPo to the TP4056 input, charger output to PowerBoost input, PowerBoost output to the Pi and amp 5V rails.
- Expose USB-C on the Pelican shell edge via a panel-mount pigtail, wired to the TP4056 USB-C input. The Pelican wall is drilled only for the panel-mount connector; no structural modification.
- Install the latching slide power switch between PowerBoost output and the loads.
- Measure current under typical draw; confirm the result falls within the CLAUDE.md “typical” band.
Stage 5 — Enclosure
Section titled “Stage 5 — Enclosure”- Design and print the inset panels in PLA or PETG (material TBD during bring-up; both are cheap enough to test): a lid panel carrying the Elecrow display bezel and a Kinoshita wordmark deboss; a base panel carrying the key plate, the CIPHER-LINE bezel cutout mounted above the key plate (per ADR-0015), the cartridge-slot opening sized for the SD-sled shell (~60 × 10 mm per ADR-0019, with an internal pocket for the SD-socket PCB at the back of the slot), and port cutouts; and any interior brackets needed to seat the Pi, amp board, battery, CIPHER-LINE OLED module, and SD-socket PCB. Panels fit the Pelican 1170 interior envelope (see CLAUDE.md for dimensions). Slot depth budget: shell depth (~65 mm) + SD socket depth + PCB clearance, against the 80 mm interior depth — verify against the rest of the component layout (battery, speaker, amp, Pi mounting pocket).
- Cut the Pelican foam to seat the Pi Zero, PowerBoost 1000C, TP4056, amp, speaker, and LiPo in the base; cut the lid foam to accept the primary display module behind the bezel panel. The CIPHER-LINE module seats in a base-panel-side pocket behind its bezel cutout. The Pelican shell itself is never machined or modified.
- Heat-set M2.5 brass inserts into the printed inset panels for screw mounts.
- Fit components into the foam cavities and fasten the panels over them. Route the HDMI ribbon, audio leads, and the CIPHER-LINE SPI harness between base and lid along the Pelican hinge line with service slack so the case can open and close without strain.
- Latch the case closed and run a full first-boot sequence end-to-end — verify both the primary display and CIPHER-LINE come up cleanly.
What v0.1 intentionally defers
Section titled “What v0.1 intentionally defers”- Custom PCB. All interconnects are off-the-shelf modules on an interior plate with JST-PH harnesses.
- Keycap legends. v0.1 can ship with blank MBK keycaps; UV-printed legends are a polish pass.
- Elecrow power integration. The display runs off its own supply in v0.1 to decouple the display power budget from the build bring-up. A future build merges it onto the main 5V rail.
- Cartridge physical format. Cartridges are microSD-resident filesystem objects in v0.1; the production cartridge format (full-size SD card in a custom two-piece clamshell shell, read via USB mass storage through a card reader bridge IC on the ADR-0018 internal hub) is committed as ADR-0019 and lands in a future bring-up wave (see ADR-0019 §“Follow-on work” — CART-01 through CART-07).
5. Developer-mode vs. Production-mode
Section titled “5. Developer-mode vs. Production-mode”Both modes ship the same nOSh binary and the same kn86 filesystem. The difference is a single boot-time flag read from /boot/kn86-mode.txt (FAT32 partition p1 per ADR-0011), with these effects:
| Concern | Developer mode | Production mode |
|---|---|---|
| nEmacs REPL access | Enabled. The on-device Lisp REPL and structural editor are reachable through the nEmacs UX described in ADR-0008. | Disabled. The REPL is unreachable from normal navigation; editing is read-only. |
| Filesystem access from nEmacs | Read and write access to /home/shared and any mounted cartridge. | Read-only on everything except the deckstate writer path (owned by nOSh, not by the Lisp surface). |
| Serial console on GPIO UART | Enabled. Easy debugging from the bench rig. | Disabled. Header pins are still present but no getty is attached. |
| SSH access over Wi-Fi | Enabled. This is the daily driver for dev iteration — see ADR-0011 “Dev ergonomics”. | Disabled. SSH service is masked; Wi-Fi is still used for time sync and OTA updates. |
| Firmware update system | Same as production. ADR-0011 update flow (USB-MSC, A/B tryboot, desktop flasher) works identically. | Same as production. |
| Power / audio / display topology | Identical. | Identical. |
Why a single binary
Section titled “Why a single binary”Two binaries (debug and release) would drift. The mode flag is a narrow, well-audited boundary: nOSh reads it once at start-up, clamps a handful of privileged operations behind it, and never re-reads it during the session. Mode transitions happen only at power-cycle.
Switching modes
Section titled “Switching modes”- Dev → Prod: edit
/boot/kn86-mode.txt(either in-place on a mounted SD or via the updater MSC mount). Reboot. - Prod → Dev: physically access the SD, edit the file, reboot. No in-device path — production mode cannot re-enable itself into dev mode without SD access. That physical-access barrier is deliberate.
6. References
Section titled “6. References”- CLAUDE.md Canonical Hardware Specification — single source of truth for all concrete hardware values (processor, primary display, auxiliary display, text grid, font, colour, display modes, keys, audio chip, speaker, battery, case, ship target). Every spec value in this document is a reference to that table.
docs/adr/ADR-0011-device-firmware-update-system.md— system image update architecture (Draft; scheduled for Wave 2 implementation). Covers SD partition layout,.kn86fwformat, updater image, attention gesture, A/B tryboot, and desktop flasher.docs/adr/ADR-0015-cipher-line-auxiliary-display.md— CIPHER-LINE auxiliary OLED (SSD1322 3.12” 256×64), Cipher-exclusivity boundary, NoshAPI primitives. Source for this document’s Stage 1b and the §2 CIPHER-LINE subsection. (Per ADR-0017, the SPI driver path moved from Pi to Pico — see ADR-0017 reference below.)docs/adr/ADR-0017-realtime-io-coprocessor.md— Pi Pico 2 (RP2350) realtime I/O coprocessor for YM2149 PSG synthesis and SSD1322 OLED driver. (The DMG cartridge bus role originally part of ADR-0017 was removed by ADR-0019; cartridges are now USB-MSC SD cards on the internal hub.) Source for the post-coprocessor topology diagram in §2, the Coprocessor row in the Subsystem Roles table, the §3 power-draw delta, and Stage 1c. Companion:docs/software/api-reference/grammars/coprocessor-protocol.md(UART command protocol byte-level spec).docs/software/api-reference/grammars/coprocessor-protocol.md— Pi ↔ Pico UART wire-format spec. Frame layouts, error codes, session lifecycle, audio latency budget. F1 deliverable of ADR-0017.docs/adr/ADR-0018-custom-mechanical-keyboard-build.md— custom mechanical keyboard build for the 30-key input subsystem; source for the Input row in the Subsystem Roles table and the keyboard-controller / hub references in this doc.docs/device/hardware/sourcing-guide.md— BOM, suppliers, lead times, cost summary, sourcing risks.docs/software/runtime/input-dispatch.md— 30-key layout, matrix, event model, hold detection.docs/software/runtime/orchestration.md— software model that the hardware hosts.docs/_archive/hardware/KN-86-Modern-Build-Specification.md— archived prior-era build spec (superseded by this document; retained for historical context only, do not edit).docs/_archive/adr/ADR-0003-firmware-update-mechanism.md— archived prior-era system image update exploration (superseded by ADR-0011; retained for historical context only).