The BOX-3 touch gamebook had several blocking bugs that made the
voiced+foley story packs unusable. This fixes them end to end.
- Stack overflow on story start: gb_play_task kept a 2 KB buffer on
its 4 KB stack and rebooted the board. Buffers are now static (the
task is a singleton) and the stack is 6 KB.
- No sound at all: the ES8311 codec was never initialised — main.c
wrote raw I2S to a muted DAC. Output (and the mic) now go through
the BSP esp_codec_dev (bsp_audio_codec_speaker/microphone_init,
esp_codec_dev_write/read). The power amplifier (GPIO46) is also
forced on and volume set to 100, as the es8311 pa_pin handling did
not drive it in practice.
- First passage silent: gb_play re-mounted the SD that the gamebook
had already mounted; the failed second bsp_sdcard_mount tore down
the VFS so the first fopen failed. Now we open the file first and
only mount if that fails. A short silence lead-in also primes the
codec/PA ramp.
- No accents: the gamebook used ASCII-only lv_font_montserrat_14/24.
Added custom Montserrat fonts (font_fr_14/24, Latin-1 + œŒŸ « » ’ …,
uncompressed so they render without LV_USE_FONT_COMPRESSED).
- Mic/voice streaming gated behind CONFIG_BOX3_VOICE_STREAMING
(default off): as a gamebook the BOX-3 needs no mic, and the
constant codec reads + bridge reconnects interfered with playback
and flooded the log.
plip_virtual + cmd_exec handle types switched from i2s_chan_handle_t
to esp_codec_dev_handle_t accordingly.
plip_ui.{h,c}: LVGL phone on the BOX-3 LCD driven by the plip_virtual
hook state. Idle/ringing shows a phone glyph + status ("Appel
entrant…"); off-hook shows a 3x4 dial keypad (1-9,*,0,#) with a live
number field. A fixed bottom touch button toggles the hook —
"Décrocher" (green) while ringing, "Raccrocher" (red) off-hook,
disabled when idle. Dialed digits are reported to the master
(reason "dial:<n>") and surfaced in GET /status.
plip_virtual gains the public pickup/hangup/dial API, a state
callback for the UI, and a state getter; enables Montserrat 24/48.
Build green; flashed and verified on a real ESP32-S3-BOX-3.
New main/plip_virtual.{h,c}: implements the PLIP REST contract on the
existing port-80 httpd (POST /ring {duration_ms} with French cadence
1.5s/3.5s 440 Hz on the speaker, POST /stop, GET /status, POST /play
501 — audio flows through the WS TTS path). The BOOT button becomes
the virtual hook switch when ringing/off-hook (falls back to the
streaming toggle otherwise) and every transition is reported to the
master POST <ZACUS_MASTER_URL>/voice/hook {state,reason}, the exact
zacus_hook_client contract — the master cannot tell the annexes apart.
New Kconfig ZACUS_MASTER_URL (default 10.2.5.42). scenario_server
exposes its httpd handle for co-registration.
Build green (zacus-box3-voice.bin).