Move the Arduino sketch into firmware/MEMLNaut-NISPS/ and bridge the
hardware (memllib) to the platform-agnostic nisps/ library through a
slim glue layer. Delete the legacy root-level *AudioApp.hpp,
modes/MEMLNautMode*.hpp, voicespaces/, IMLInterface.hpp, XiasriAnalysis,
and the src/memlp submodule.
Glue layout (firmware/MEMLNaut-NISPS/glue/):
audio_driver.hpp - bridge memllib block callback to Mode::process
via per-Mode templated trampoline (no virtual dispatch)
peripherals.hpp - joystick/pots/buttons -> Mode::set_input + ML primitives
midi_io.hpp - MIDI in -> mode.note_on/update_bpm/set_playing,
drains mode ControlEvent ring -> MIDI UART
mode_select.hpp - using-aliases mapping MEMLNautMode<Name> to
nisps::modes::*Mode (build script rewrites the
#define MEMLNAUT_MODE_TYPE line)
input_router.hpp / output_router.hpp - top-level wire/drain entry points
The sketch tree uses src/{memllib,daisysp,nisps} symlinks because
Arduino-CLI rejects ".." in include paths from sketch-tree headers.
mode_select.hpp #undefs Arduino's sq/min/max/abs/round macros before
including nisps headers (some nisps engines use those identifiers as
method names). The audio bridge struct is extern in the header and
defined in the .ino because inline + __not_in_flash section attribute
collide at link time.
Verification: arduino-cli compile succeeds for PAFSynth, ChannelStrip,
and BreakOr (rp2040:rp2040:solderparty_rp2350_stamp_xl:opt=Optimize3,
-std=gnu++20). Host C++ tests under nisps/build still pass (3 binaries,
110+ tests). Build script (scripts/build-firmware.sh) updated to point
at the new sketch path; mode-rewrite logic unchanged.
Closes meml-gkm.
42 lines
2.9 KiB
Markdown
42 lines
2.9 KiB
Markdown
# `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's `AudioDriver` block callback to `Mode::process(stereosample_t)`. Templated trampoline so no virtual dispatch in audio path.
|
|
- `glue/peripherals.hpp` — wires MEMLNaut joystick / pots / buttons to `Mode::set_input(idx, value)` and the ML primitives (`draw_weights`, `move_weights`, `train`, `reset`).
|
|
- `glue/midi_io.hpp` — binds incoming MIDI to `mode.note_on/note_off/update_bpm/set_playing` (where supported); drains outgoing `ControlEvent`s 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 from `loop1()`.
|
|
- `glue/mode_select.hpp` — type aliases mapping `MEMLNautMode<Name>` identifiers to `nisps::modes::<Name>Mode` C++ types. Build script rewrites `MEMLNAUT_MODE_TYPE` between the alternatives.
|
|
|
|
## Building
|
|
|
|
```bash
|
|
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:
|
|
|
|
1. `arduino-cli compile` succeeds for at least three modes (PAFSynth, ChannelStrip, BreakOr).
|
|
2. Host C++ tests in `nisps/build` still pass — the firmware refactor must not perturb the platform-agnostic library.
|
|
3. `git grep` confirms no remaining references to deleted root-level files.
|
|
|
|
## Removed
|
|
|
|
- Root-level `MEMLNaut-NISPS.ino`, `IMLInterface.hpp`, `*AudioApp.hpp`, `XiasriAnalysis.{cpp,hpp}` — replaced by `nisps/engines/*` and `firmware/MEMLNaut-NISPS.ino`.
|
|
- Root-level `modes/MEMLNautMode*.hpp` and `modes/AudioApps/` — replaced by `nisps/modes/*` and the `mode_select.hpp` type aliases.
|
|
- Root-level `voicespaces/` — replaced by static voice space data inlined into engines (`nisps/engines/paf_synth.hpp` etc.).
|
|
- `src/memlp/` submodule — replaced by `nisps/ml/`.
|