The panel driver now splits writing a frame into its SPI buffer
(epd_write_frame(), which also computes a CRC32 as it streams) from
actually triggering the physical refresh (epd_turn_on_display()).
frame_client.c compares the new CRC against the last one that was
actually refreshed (persisted in NVS) and skips the refresh entirely
when they match -- e.g. a reboot redisplaying the same photo before the
server's refresh interval elapsed no longer causes a visible flash for
no visual change.
Also reorders the per-wake fetch cycle: the image fetch (15s timeout)
now goes before the config check (3s timeout), instead of after. The
config check's tighter timeout was intermittently tripping on
connection-setup latency that's common on the first request after
waking from a long deep sleep (e.g. stale ARP); putting the more
tolerant request first absorbs that latency, and the config check then
rides the connection it already warmed up.
- LICENSE: MIT, with attribution notes for the vendored qrcode/epaper_fonts/
dns_server code and the epd7in3e driver's transcription of Waveshare's
register sequence.
- Top-level README.md: project overview, hardware list, quick-start
pointing at firmware/ and server/, repo layout, license, Claude Code
attribution.
- firmware/README.md: full rewrite (was still the stock ESP-IDF captive
portal example's README) -- build/flash instructions, Kconfig reference
table, first-boot walkthrough, and how to reset to provisioning mode via
NVS erase (the only way in right now; a proper reconfigure trigger is a
future addition).
- docs/hardware.md: wiring table + parts list + strapping-pin/SPI-speed notes.
- docs/architecture.md: sequence diagram and walkthrough of the full
provision -> connect -> fetch -> display -> sleep cycle, plus the
reasoning behind doing image processing server-side and reusing Immich's
face detection instead of bundling a detector.
- server/README.md: fixed stale endpoint docs (missing GET /frame/config,
POST /api/config still describing removed immich_url/api_key fields).