6.5 KiB
Boot Sequence Plan A
This document captures the selected startup sequence for the "sound-first" boot experience.
Product Goal
Plan A prioritizes immediate audible feedback after power-on. The device should play the boot sound before display startup, turntable calibration, Wi-Fi bootstrap, or network workers begin.
Expected user perception:
- Power is applied.
- The boot sound starts as early as possible.
- The display comes up after the sound path has completed or timed out.
- Mechanical calibration and network startup happen after the audible boot feedback.
The tradeoff is that the user may hear the boot sound while the screen is still dark. This is accepted for this plan.
Startup Order
power-hold configuration (disabled on the current battery-sensing board)
-> audio init
-> play boot sound with timeout
-> audio deinit or idle release
-> LCD device init
-> LCD render loop start
-> request boot/default expression
-> platform/domain init
-> optional turntable calibration
-> storage prepare
-> Wi-Fi STA/AP bootstrap
-> runtime workers
-> WebSocket / fortune / LAN HTTP services
Stage Details
| Order | Stage | Wait policy | Failure policy | Notes |
|---|---|---|---|---|
| 1 | Power-hold configuration | Wait | Continue only if board power remains stable | The current board sets the hold GPIO to -1; legacy boards may configure and assert a dedicated hold output. GPIO9 is reserved for battery ADC. |
| 2 | Audio init | Wait with bounded timeout | Log and skip boot sound | Initializes the codec path needed for playback: I2C, I2S, codec, PA control, codec buffers, and decoder resources. |
| 3 | Boot sound playback | Wait for completion or timeout | Stop playback and continue boot | The sound must not block startup indefinitely. Use a short product-defined timeout. |
| 4 | Audio release | Wait for synchronous release | Continue if release reports a recoverable error | If Wi-Fi/TLS starts soon after, deinit or release idle audio resources to reduce DMA/internal heap pressure. |
| 5 | LCD device init | Wait | Continue with display disabled if init fails | Initializes SPI, ST7789 panel, direct draw buffers, render state, and backlight. |
| 6 | LCD render loop | Start and continue | Continue with display disabled if task creation fails | Needed for the default boot image or animation to appear. |
| 7 | Boot/default expression | Do not wait for animation completion | Ignore request failure when LCD is unavailable | This is the first visible boot state. |
| 8 | Platform/domain init | Wait | Stop boot on unrecoverable error | Performs stepper electrical initialization and domain direction state setup. |
| 9 | Turntable calibration | Product decision; default wait with timeout | Continue with degraded direction accuracy on timeout/failure | This is the mechanical SW1 homing/calibration process, not the stepper electrical init. |
| 10 | Storage prepare | Wait | Stop features that need persistent state | Initializes NVS before Wi-Fi credentials, identity, auth, and fortune state are read or written. |
| 11 | Wi-Fi bootstrap | Wait until STA connected or AP config mode starts | Enter config AP or keep retry policy active | Must not overlap with boot sound playback or heavy audio initialization. |
| 12 | Runtime workers | Start and continue | Stop only failed dependent feature | Starts battery monitoring, PTT, slot switch, Wi-Fi state monitor, model command worker, LCD runtime worker, and WebSocket wait worker as configured. |
| 13 | Network services | Async after network readiness | Retry using existing policy | Includes multimodal WebSocket, LAN HTTP config server, SNTP, HTTPS fortune refresh, and auth flows. |
Clarifications
Display Startup
"LCD device init" means the screen hardware is available and the backlight can be enabled. It does not guarantee that a boot image is visible.
Showing a default boot image requires the render loop to be running and a presentation/expression request to be accepted.
Stepper Startup
Stepper electrical initialization only configures the four motor phase GPIOs, creates the motion mutex, resets the internal phase state, and powers off the motor coils.
It is not the same as turntable calibration. Turntable calibration is the mechanical homing process that rotates until the SW1 calibration switch is detected, then updates the domain direction state.
Boot Sound Placement
The boot sound can run before LCD and stepper initialization because it does not depend on display, turntable, Wi-Fi, or NVS when the sound asset is embedded or otherwise available without persistent storage.
If the selected sound asset is stored in NVS or another mounted filesystem, the storage/filesystem prerequisite must be moved before audio playback.
Resource Rules
- Do not run audio init/playback concurrently with Wi-Fi STA connect, WebSocket TLS handshake, HTTPS requests, or fortune refresh.
- Prefer releasing idle audio resources before Wi-Fi bootstrap to reduce internal heap and DMA-capable memory pressure.
- Do not initialize LCD draw buffers concurrently with audio init unless memory measurements prove it is stable.
- Boot sound playback must have bounded completion semantics.
- Audio startup failure must not prevent display, calibration, or Wi-Fi startup.
Current Implementation Gap
The current voice_prompt_play_file() implementation is a stub that returns
ESP_ERR_NOT_SUPPORTED. Plan A therefore requires an audio playback
implementation before the boot sound can actually be heard.
Recommended ownership:
control_planeowns the boot-sound startup policy and timeout.domainowns the semantic boot prompt contract if the prompt is exposed across layers.platformowns the concrete audio playback primitive and hardware resource lifecycle.app_compositiononly sequences the startup stages.
Implementation Notes
The current startup path initializes LCD before control_plane_init(). Plan A
requires moving boot audio ahead of LCD startup, while keeping the logic inside
the existing layering rules:
app_composition
-> control_plane boot sound policy
-> domain semantic/runtime adapter
-> platform audio playback primitive
Avoid direct platform_* audio calls from app_composition.
The boot sound API should define:
- timeout behavior,
- whether playback is synchronous or asynchronous,
- what happens after timeout,
- whether audio resources remain initialized after playback,
- idempotent behavior for repeated boot calls.