Add glue/settings_view.hpp: wire_settings(mode) registers a "Joystick" SingleSelectView on the MEMLNaut display carousel (TFT + rotary encoder, same DisplayDriver as SystemView/SelfTest). For the 4-input two-joystick modes, "Single" pins ML input channels 2,3 (the second joystick) to neutral via ModeBase::set_input_pinned — the network is never rebuilt and trained state survives toggling. Default is Dual. Only registered when input arity == 4. Called from MEMLNaut-NISPS.ino setup() after addSystemInfoView(). MAP.md + CLAUDE.md glue listings updated. NOTE: compile-unverified — no arduino-cli/RP2350 toolchain on this host and no hardware; needs scripts/build-firmware.sh + a flash test (chokepoint A). |
||
|---|---|---|
| .. | ||
| MEMLNaut-NISPS | ||
| 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/input_router.hpp—wire_inputs()entry point, currently a thin re-export over peripherals. Will grow into a schema-aware router.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 and src/daisysp are git submodules; the firmware-common.sh wrapper rejects builds when submodules drift 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/.