From 148f9c513e614b29df6bb5e8afb30d12b29bda29 Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Thu, 16 Jul 2026 23:10:50 -0400 Subject: [PATCH] =?UTF-8?q?tasks(ESP-045):=20one=20physical=20transport=20?= =?UTF-8?q?button=20on=20the=20Mini=20=E2=80=94=20press=3Dplay/stop,=20hol?= =?UTF-8?q?d=3Drealign?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Files the v1 firmware half of the Mini's live surface: a single button on the headless Super Mini (short press toggles play/stop, ~600ms hold posts realign), reusing the existing HAS_BUTTONS mailbox path and ESP-043 onboard RGB for status. Input-only — no new transport logic. Pairs with ESP-021 (enclosure + panel-mount button/TRS). Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6 --- tasks/ESP-045.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tasks/ESP-045.md diff --git a/tasks/ESP-045.md b/tasks/ESP-045.md new file mode 100644 index 0000000..3613dee --- /dev/null +++ b/tasks/ESP-045.md @@ -0,0 +1,85 @@ +--- +id: ESP-045 +title: "Mini: one physical transport button on the Super Mini — press=play/stop, hold=realign" +status: todo +assignee: null +priority: high +tags: + - kitchensynctouch + - hardware + - transport + - product-v1 +depends_on: + - ESP-043 + - ESP-042 +created_at: 2026-07-16 +updated_at: 2026-07-16 +--- + +## Why (the Mini's one live action needs to be physical) + +The v1 product is the cheap MIDI-only "Mini" (headless S3 Super Mini, 1 DIN out, app for config). +The office-hours design locks **one physical button** as its live-performance surface: everything +else is the app, but *play/stop and realign must be a real button you can hit mid-set* without +reaching for a phone. Today the Super Mini has **no button** — transport comes only over +`/transport` + `/live` from the app. That's fine for config, not for performance. + +The firmware is most of the way there and it is NOT new logic: + +- `KitchenSyncTouch.ino` already has a `#ifdef HAS_BUTTONS` block (the ESP-025 bench rig): debounced + `Button` inputs post the SAME `TransportLaunchIntent` into the SAME `ktouch_transport` mailbox the + touch UI uses, so the 1 ms writer is identical — what the bench proved is what the Mini runs. +- `buttons.c` gives `button_reset` / `button_update` (debounce). +- Intents exist: `TL_INTENT_PLAY`, `TL_INTENT_STOP`, `TL_INTENT_REALIGN`. +- Status feedback already exists: **ESP-043** drives the onboard WS2812 (GPIO48) via + `ktouch_status_rgb` (dark stopped / amber armed / green running / cyan Link-locked). So the box + can already *show* armed — this ticket only adds the *input*. + +So this is a **wiring + config-flag + one-button-gesture** job, not a new transport path. + +## The gap vs. what exists + +The bench `HAS_BUTTONS` block is **two** buttons (transport + realign) on **GPIO32/33** — a +classic-ESP32 DevKit pinout. The Mini is different in two ways: + +1. **One button, two gestures.** Product decision: a single button. **Short press = play/stop** + (quantized, arms on the bar line), **hold (~600 ms) = realign**. Needs hold-detection on top of + `button_update` (short vs long press), which the bench two-button block does not have. +2. **S3 GPIOs, not classic-ESP32.** GPIO32/33 don't exist the same way; pick a **safe exposed S3 + input**. Avoid: 0/3/45/46 (strapping), 19/20 (USB), 43/44 (UART0), **48 (onboard RGB — ESP-043)**, + **11 (DIN MIDI TX — `din_midi_out.h`)**. Use an exposed non-strapping pin with a real internal + pull-up, wired button→GND, `INPUT_PULLUP` (pressed = LOW), matching the bench convention. + +## Scope + +- Define `HAS_BUTTONS` (or a narrower `HAS_TRANSPORT_BUTTON`) for the **Super Mini** build in + `tools/build-supermini.sh` / `config.h`, without dragging in the two-button/LED-pin bench rig. +- Add a **single-button transport gesture**: debounce → short-press posts PLAY/STOP (toggle on + `ktouch_transport_state()`), long-press posts `TL_INTENT_REALIGN`. Keep the mailbox post exactly + as the bench does — never touch the wire from `loop()`; the writer fires on the grid. +- Status stays on the **onboard RGB (ESP-043)** — no new LED wiring for the plain-button build. + (If a ChromaTek 19mm WS2812 button is used instead, its LED can chain as pixel #2 off the WS2812 + line and mirror the same `ktouch_status_rgb` — an enclosure-dependent option, not required here.) + +## Acceptance criteria + +- [ ] Short press on the Super Mini arms/stops transport (quantized), identical to an app + `/transport` PLAY/STOP — verified by the armed→running transition being the device's, not + client-predicted. +- [ ] Hold (~600 ms) posts a realign (`0xFC`+`0xFA` on the bar line), distinct from a short press. +- [ ] The chosen GPIO is a safe S3 input (not strapping/USB/UART0/48/11); button→GND + `INPUT_PULLUP`. +- [ ] Onboard RGB (ESP-043) reflects the resulting state (armed blink → running). +- [ ] Product build (Touch) unaffected: `HAS_BUTTONS`-for-Mini does not pull LED pins or the + two-button block into the Touch. +- [ ] A pure test for the short-vs-long gesture decision (mirror `test_status_rgb`) — the timing + threshold is logic, not glue. + +## Notes + +- Pairs with **ESP-021** (enclosure + panel-mount button + TRS out) — this is the firmware half of + the same "make the Mini a real box" story. +- Gesture grammar comes from the office-hours doc: press = play/stop, hold = realign. Keep it to + one button; more controls belong in the app or a later "Performance" tier (arcade buttons). +- The quantized-press blink is load-bearing (a press does nothing for up to a bar; without the + armed blink it reads as a dead button) — ESP-043 already provides it, which is why this ticket + is input-only.