One cut, no dual path. Closes ALIGNMENT defect 3 ("Arduino-CLI build
machinery is actively hostile") and vision bullet 4.
platformio.ini carries 16 [env:], one per variant, each passing
-DMEMLNAUT_MODE_TYPE; selftest passes -DNISPS_SELFTEST=1 instead. The env list
IS the registry now — the .ino comment-registry and the NISPS_ST_* token-paste
table are deleted rather than migrated. L12 noted that table was already
silently missing the currently-shipped SLPWorkshop variant, which is the whole
argument against having a second list.
Also deleted: the Python/sed machinery that rewrote the COMMITTED .ino on every
build, the sketch symlink forest, the global TFT_eSPI User_Setup.h mutation
(now -D flags — TFT_eSPI's own documented PlatformIO recipe), the UF2
boot-mount detection stack (upload_protocol=picotool talks to the bootloader
directly), and build-firmware-arch.sh entirely. Scripts 683 -> 435 lines.
memllib is vendored at lib/memllib/ from upstream e291192; no submodules
remain. VENDORED.md records provenance and the re-sync procedure.
S9: a firmware-build CI job compiles three representative envs against a cached
toolchain and reports per-variant flash/RAM. Firmware is in an automated gate
for the FIRST time. The old ci.yml comment justified excluding it as "low
verification value" — an assessment that did not survive contact, since the
SelfTest variant sat broken for an unknown period calling a DisplayDriver
method that did not exist at the pinned memllib commit, and nothing noticed
because nothing built it.
Verified: all 16 envs build from an empty cache, each within ~520 bytes of the
arduino-cli binary it replaces, flash and RAM. Measured as .text+.rodata /
.data+.bss+vector+uninitialized — NOT PlatformIO's console line, which
double-counts .data on this board. This does not prove the hardware boots; no
flash+smoke test was possible and that stays an operator chokepoint.
slpworkshop 248232/145028 pafsynth 256880/149716 selftest 216228/17960
(all 16 in the CI log format; none exceeds 2% of a 16 MB flash)
Two traps recorded so nobody rediscovers them: vendoring memllib's subdirs
without a src/ wrapper makes PlatformIO's library builder silently compile
NOTHING while still linking; and project build_flags land BEFORE the
framework's own -std=gnu++17 -Os, so build_unflags is required.
CORRECTION carried in this commit: the firmware sizes in c19d846's message and
the first version of the memllib recon doc were wrong — SLPWorkshop 145348,
PAFSynth 145300, SelfTest 141840. They came from building variants in sequence
through a SHARED incremental arduino-cli build directory, which reused stale
objects and under-reported by ~75 KB. Clean-cache rebuilds of the identical
commit give 216736/18492 for SelfTest. The real cost of the memllib upstream
bump is +216 bytes flash, not +316. Never measure firmware size through a
reused build dir.
HISTORY NOTE: this commit and the docs commit before it were rebuilt (force-push,
2026-07-21) so that each contains only what its message describes. The first
versions had the firmware deletions stranded in the docs commit by a shared-index
race between concurrent agents; content is byte-identical to the originals.
Gates: run-all-tests.sh ALL GREEN (nisps/ untouched by this change beyond
include paths); 16/16 pio envs build.
64 lines
2.7 KiB
C++
64 lines
2.7 KiB
C++
// glue/settings_view.hpp — on-device settings menu views (TFT + rotary encoder).
|
|
//
|
|
// Adds entries to the MEMLNaut display carousel (the same DisplayDriver the
|
|
// SystemView and SelfTest use). Navigation: rotate to move between views;
|
|
// press to focus a view; rotate-while-focused to change its value; press
|
|
// again to unfocus. See lib/memllib/hardware/memlnaut/display/DisplayDriver.hpp.
|
|
//
|
|
// Currently provides:
|
|
// * Joystick: Dual / Single — for the 4-input ("two 2-D joystick") modes,
|
|
// toggles whether the SECOND joystick (input channels 2,3) feeds the ML
|
|
// engine. "Single" pins those channels to the neutral value (0.5) via the
|
|
// platform-agnostic ModeBase pin mechanism, so the network is never
|
|
// rebuilt and trained state survives toggling. Default is Dual (the 4-D
|
|
// variant naturally uses both joysticks).
|
|
//
|
|
// Only registered for modes whose input arity is exactly 4 (the two-joystick
|
|
// modes); other modes (e.g. SoundAnalysisMIDI, whose joystick channels are not
|
|
// 2,3) get no joystick toggle.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <span>
|
|
|
|
#include "hardware/memlnaut/MEMLNaut.hpp"
|
|
#include "hardware/memlnaut/display/SingleSelectView.hpp"
|
|
|
|
namespace nisps_firmware {
|
|
|
|
// The second 2-D joystick maps to ML input channels 2 and 3 (joy_z / joy_w).
|
|
inline constexpr std::size_t kSecondJoystickCh0 = 2u;
|
|
inline constexpr std::size_t kSecondJoystickCh1 = 3u;
|
|
|
|
// Add the settings views for `mode` to the display carousel. Must run AFTER
|
|
// MEMLNaut::Initialize() (so the display + TFT exist) and after
|
|
// addSystemInfoView(), on core 0.
|
|
template <typename ModeT>
|
|
inline void wire_settings(ModeT& mode) {
|
|
if constexpr (ModeT::input_channel_count() == 4u) {
|
|
MEMLNaut* meml = MEMLNaut::Instance();
|
|
if (!meml || !meml->disp) return;
|
|
|
|
// Kept alive for the program lifetime (the carousel holds a shared_ptr
|
|
// too, but this guarantees ownership regardless of view churn).
|
|
static std::shared_ptr<SingleSelectView> joystick_view;
|
|
joystick_view = std::make_shared<SingleSelectView>("Joystick");
|
|
meml->disp->AddView(joystick_view); // calls Setup() → creates the selector
|
|
|
|
// Index 0 = Dual (default, no pinning); index 1 = Single.
|
|
std::array<String, 2u> options = { String("Dual"), String("Single") };
|
|
joystick_view->setOptions(std::span<String>(options.data(), options.size()));
|
|
joystick_view->setNewVoiceCallback([&mode](std::size_t idx) {
|
|
const bool single = (idx == 1u);
|
|
mode.set_input_pinned(kSecondJoystickCh0, single);
|
|
mode.set_input_pinned(kSecondJoystickCh1, single);
|
|
});
|
|
} else {
|
|
(void)mode;
|
|
}
|
|
}
|
|
|
|
} // namespace nisps_firmware
|