Files
gronod f47299b939
ci / test (push) Successful in 1m16s
ci / test (pull_request) Successful in 1m19s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Failing after 29s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (pull_request) Failing after 30s
ci / firmware (wroom, sdkconfig.wroom, esp32) (pull_request) Failing after 30s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Failing after 33s
Cut over WROOM main to RTOS UI and stop-safe input
input_task drops motor EN immediately on X while RUNNING, then queues
CMD_STOP. machine_task ticks at 50 Hz. startingMenu is not linked.
STATUS DONE. Notes=hw smoke pending.
2026-09-16 14:05:21 +00:00

142 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P06 — WROOM UI cutover (2004 + keypad + Stop/Resume)
STATUS: DONE
DEPENDS: P05
READ: this file, `src/menu.cpp`, `src/display.cpp`, `src/config.cpp`, `docs/TARGET_ARCHITECTURE.md` (screens + stop rules)
OUT: S3 LVGL, NVS profiles, keeping blocking `getEntEscInput` as the live path
FORBIDDEN: `while(true)` keypad wait in machine; `malloc` for mm:ss; `vTaskDelete`; WDT off
## IN
Replace live control path with `input_task` + `ui_task` + `app_ui` screens on 20×4. Legacy `src/*.cpp` may remain unlinked. `main` no longer calls `startingMenu()`.
After this phase the WROOM firmware **is** the product.
## FILES
```
components/hal_display/include/hal_display.h
components/hal_display/hal_display_lcd2004.cpp
components/hal_input/include/hal_input.h
components/hal_input/hal_input_keypad.cpp
components/app_ui/include/app_ui.h
components/app_ui/app_ui.c
components/app_ui/screens.h
```
C++ only in hal_display / hal_input.
## hal_display.h
```c
void hal_display_init(void);
void hal_display_clear(void);
void hal_display_text(int col, int row, const char *s); /* clip to 20 cols */
void hal_display_glyph_thermo(int col, int row);
void hal_display_flush(void); /* no-op */
```
LCD: I2C 21/22 addr 0x27, 20x4, createChar thermometer from `config.cpp` bytes.
mm:ss: stack buffer `char[6]`, `snprintf "%02d:%02d"`. Never malloc.
## hal_input.h
```c
typedef struct { char key; } ui_raw_key_t;
void hal_input_init(void);
bool hal_input_pop_key(ui_raw_key_t *out); /* nonblocking */
```
Keypad map **byte-identical** to `src/config.cpp`. Scan in `input_task` 25 Hz. Debounce via Keypad lib.
Map:
| key | cmd |
|---|---|
| 1..6 | SELECT_PROCESS id 0..5 |
| U/D | BROWSE_STEP ±1 |
| L/R | ADJUST_STEP_TIME ±5 |
| E | ARM if STEP_SELECT; START if ARMED; RESUME if STOPPED; ARM next if COMPLETE |
| X | CANCEL_ARMED if ARMED; STOP if RUNNING or COMPLETE; RETURN_TO_STEP_SELECT if STOPPED; ignore IDLE |
**X in RUNNING:** `hal_motor_request_stop()` **in input_task immediately**, then queue CMD_STOP. Dual-path required.
## Screens (20×4)
`ProgramSelect` (IDLE):
```
Select Programme:
1. C41 4. ECN-2
2. E6 5. Custom
3. B&W 6. B&W Rev
```
`StepSelect`:
```
Step Time Temp
<name> mm:ss nnC
Scroll / Esc / Ent
🌡 tt.tC row3 col13 thermo+temp or --
```
`Armed`: name, mm:ss, pref C, `Ent:start Esc:quit`, temp row3
`Running`: name row0, `Remaining: mm:ss` row1, temp row3. Update remaining ≥4 Hz from events, **not** by blocking. No `delay(410)`.
`Stopped`: name, remaining, `E:resume X:back`, temp row3
`Complete`: name `Done`, then alarm (nonblocking). `E` next / `X` back.
## Tasks
| task | prio |
|---|---|
| input_task | high |
| machine_task | mid-high; `handle_cmd` + `tick(esp_timer_get_time/1000)` 50 Hz |
| ui_task | mid; drain events, dirty draw |
| motor/temp/audio | as P05 |
TWDT: register tasks that run long loops or rely on idle.
## Cutover
`main.c`: init display/input, splash `AUTOFILM` + git describe 1 s **via vTaskDelay not busy Arduino delay in ui_task after scheduler start**. Unlink `src/AutoFilmESP32.cpp` from IDF (leave files on disk).
`platformio.ini` may stay; do not promise PIO still builds.
## VERIFY
Host tests pass.
WROOM idf build pass.
Hardware smoke:
1. Select Custom, Ent to arm, Ent to start 10 s step, remaining counts, temp updates
2. Mid-step X: motor stops at once, Stopped screen, E resumes remaining, X returns to list
3. Disconnect DS18B20: `--` still navigable
4. Complete alarm: X cancels and returns; UI not frozen 7.5 s
If no hardware: still land; Notes=`hw smoke pending`; do not skip the input dual-path stop.
## COMMITS
1. `Add 2004 display and keypad HAL`
2. `Add app_ui screens driven by machine events`
3. `Cut over WROOM main to RTOS UI and stop-safe input`
## DoD
- [x] Esc during run always EN-off
- [x] No malloc mm:ss
- [x] No blocking alarm on UI/machine
- [x] Legacy menus not in the IDF link
- [x] STATUS→DONE
## Notes
Notes=`hw smoke pending`. Host ctest green. WROOM `idf.py` build attempted in sandbox without ESP-IDF installed.