Two crashes found flashing to real hardware:
- epd_display_stream's 4KB SPI chunk buffer was a stack local, but the
default main task stack (3584 bytes) is smaller than that alone --
Guru Meditation stack protection fault. Made it static instead, and
bumped CONFIG_ESP_MAIN_TASK_STACK_SIZE to 8192 for headroom in the rest
of the boot call chain (provisioning -> QR render -> eventually the
HTTP fetch cycle all run in this one task).
- epd_wait_busy() polled with a 1ms vTaskDelay, which rounds down to 0
FreeRTOS ticks at the default 100Hz tick rate -- so it never actually
blocked, tight-spinning the CPU for the panel's real refresh time
(15-30+s for a full-color pass) and starving the idle task long enough
to trip the 5s task watchdog. Bumped to 20ms, safely >=1 tick regardless
of tick rate.
Also updates the EPD pin defaults to the board's actual wiring
(CLK=20 MOSI=19 CS=18 DC=9 RST=10 BUSY=11), confirmed working on hardware.
Ports Waveshare's official EPD_7in3e.c register/refresh sequence (the
panel has no public datasheet, so their reference driver is the source of
truth) to an ESP-IDF component using spi_master + gpio instead of the
bcm2835/RPi hardware abstraction the reference targets.
Unlike the reference driver, which toggles CS around every single byte,
this holds CS low for each logical command/data phase and DMAs pixel data
in 4KB chunks -- sending ~192,000 individual one-byte SPI transactions
would make a full refresh impractically slow.
Exposes a streaming API (epd_display_stream, pulling chunks from a
caller-supplied read_fn) so the eventual HTTP fetch path can feed the panel
without holding a full ~192KB frame in RAM, plus an in-memory convenience
wrapper (epd_display_buffer) for cases like the upcoming QR code screen
where buffering the whole frame is fine.
Wired into wifi_provisioning_start() as an init + white-clear for now, to
prove the driver builds/links/runs at the right point in the boot sequence
ahead of the actual QR code content.