Found by actually building the firmware, which nothing in this repo does: CI
skips it, run-all-tests.sh skips it, and lint skips it (S9). The SelfTest
variant did not compile:
glue/selftest.hpp:650: error: 'class DisplayDriver' has no member named
'NavigateToView'
Pre-existing, not caused by this audit's work: no commit in this series touched
selftest.hpp, and `NavigateToView` appears nowhere in memllib at the pinned
commit. DisplayDriver's actual surface is AddView / InsertViewAfter /
ChangeView(delta) over a carousel.
The call was redundant as well as wrong. DisplayDriver::Setup() leaves
currentViewIndex_ at 0 and the selftest adds exactly one view, so that view is
already the one on screen. Deleting the call restores the build with no
behavioural change on device; a comment records why, since the intent
("navigate to my view") reads as necessary.
Worth noting against Phase 1: SineOsc was KEPT there specifically because "the
firmware selftest uses it". That was still the right call — deleting it would
have added a second breakage to a variant that already had one — but the
justification was weaker than it looked, because the selftest had not compiled
for some time.
Verified by building three variants end to end with arduino-cli, which also
constitutes the first real check of this audit's firmware-side deletions
(daisysp, input_router.hpp, the perf macros, the peripherals helper extraction):
SLPWorkshop flash 145028 B RAM 87384 B (16%)
PAFSynth flash 144988 B RAM 107056 B (20%)
SelfTest flash 141520 B RAM 12024 B (2%)
Those numbers are also the first per-variant size baseline this project has had
(plan §6.5f wants exactly this as a gate).
Incidentally confirms A6 live: `scripts/build-firmware.sh` rewrote the committed
.ino to select each variant, and the working tree had to be restored after every
build. That is what the PlatformIO migration deletes.
|
||
|---|---|---|
| .. | ||
| MEMLNaut-NISPS | ||
| useq-celium | ||
| README.md | ||
firmware/ — Arduino sketch + hardware glue
Thin shell around nisps/. The platform-agnostic ML / DSP / engines / modes live there; this directory contains:
MEMLNaut-NISPS.ino— entry point. Picks one mode at compile time, hosts the dual-core lifecycle (Core 0: ML + UI, Core 1: audio + MIDI), and connects glue to mode.glue/audio_driver.hpp— bridges memllib'sAudioDriverblock callback toMode::process(stereosample_t). Templated trampoline so no virtual dispatch in audio path.glue/peripherals.hpp— wires MEMLNaut joystick / pots / buttons toMode::set_input(idx, value)and the ML primitives (draw_weights,move_weights,train,reset).glue/midi_io.hpp— binds incoming MIDI tomode.note_on/note_off/update_bpm/set_playing(where supported); drains outgoingControlEvents from the mode's ring buffer to the MIDI UART.glue/output_router.hpp— drains engine events + mode events; called fromloop1().glue/mode_select.hpp— type aliases mappingMEMLNautMode<Name>identifiers tonisps::modes::<Name>ModeC++ types. Build script rewritesMEMLNAUT_MODE_TYPEbetween the alternatives.
Building
scripts/build-firmware.sh # interactive variant prompt
scripts/build-firmware.sh PAFSynth # build a specific variant
scripts/build-and-flash-firmware.sh # build + flash via UF2
Target: rp2040:rp2040:solderparty_rp2350_stamp_xl:opt=Optimize3 with compiler.cpp.extra_flags=-std=gnu++20.
Include paths
Arduino-CLI compiles every *.cpp / *.hpp reachable from the sketch directory and from any submodule under src/. Headers under nisps/ are included via relative path (#include "../../nisps/..."). No -I flag injection needed.
src/memllib is the only git submodule; the firmware-common.sh wrapper rejects builds when it drifts from the recorded revision.
Verification
You cannot test on hardware from a sandbox. We verify three things:
arduino-cli compilesucceeds for at least three modes (PAFSynth, ChannelStrip, BreakOr).- Host C++ tests in
nisps/buildstill pass — the firmware refactor must not perturb the platform-agnostic library. git grepconfirms no remaining references to deleted root-level files.
Removed
- Root-level
MEMLNaut-NISPS.ino,IMLInterface.hpp,*AudioApp.hpp,XiasriAnalysis.{cpp,hpp}— replaced bynisps/engines/*andfirmware/MEMLNaut-NISPS.ino. - Root-level
modes/MEMLNautMode*.hppandmodes/AudioApps/— replaced bynisps/modes/*and themode_select.hpptype aliases. - Root-level
voicespaces/— replaced by static voice space data inlined into engines (nisps/engines/paf_synth.hppetc.). src/memlp/submodule — replaced bynisps/ml/.