Port real epd13in3e driver from vendor code; fix wire-raster stride bug
Build and push server image / test (push) Successful in 43s
Firmware build check / build-check (push) Successful in 2m47s
Build and push server image / build-and-push (push) Successful in 4m34s
Build and push server image / deploy (push) Failing after 1m27s

Vendored the panel's init/LUT/refresh register sequence from three
independent Waveshare reference drivers for this exact panel+controller
(RaspberryPi/c, ESP32, and the ESP32-S3-ePaper-13.3E6 ESP-IDF example),
which all agree byte-for-byte. The epd13in3e.c #error is gone; it
compiles clean and links (verified via /build-firmware ee02).

That vendor code also revealed the panel's SPI wire raster is a native
1200x1600 (portrait), not 1600x1200 as previously assumed -- rotated 90
degrees from the panel's landscape mount/marketing size. The old
assumption wasn't just a rotation bug: 1600x1200 and 1200x1600 don't
share a row stride, so packing at the wrong one would have shredded
images into a repeating diagonal garble on real hardware, not just
displayed them sideways. Fixed with a new PANEL_WIRE_TRANSPOSE in
image_pipeline.py, applied after the existing per-frame
ORIENTATION_TRANSPOSE, with a direction-agnostic regression test that
catches the stride bug specifically (a byte-count check alone can't,
since both orientations pack to the same total size).

A full ee02 build still fails, but no longer because of this driver --
main/{back,next,combo}_button.c call an ESP32-C6-only deep-sleep
GPIO-wakeup API with no ESP32-S3 fallback, a separate pre-existing gap
that was simply hidden behind the panel driver's old #error. See
docs/hardware.md for details; CI's continue-on-error on this board
stays in place until that's fixed too.
This commit is contained in:
2026-08-04 22:00:18 +00:00
parent fe5a2df074
commit 454c03586e
6 changed files with 464 additions and 160 deletions
+23 -14
View File
@@ -2,9 +2,9 @@
ESP-IDF firmware for the ESP32-C6 (devkit/xiao boards, 7.3" panel) or
ESP32-S3 (ee02 board, 13.3" panel -- see
[Building for Seeed's EE02](#building-for-seeeds-ee02-esp32-s3--133-panel-driver-not-yet-functional)
below; the driver for that panel doesn't work yet). On first boot it
provisions itself over
[Building for Seeed's EE02](#building-for-seeeds-ee02-esp32-s3--133-panel-driver-ported-board-still-doesnt-build-end-to-end)
below; the panel driver itself works now, but the board doesn't build
end-to-end yet for an unrelated reason). On first boot it provisions itself over
a WiFi captive portal; after that it wakes on a timer, fetches an
already-processed frame from the [server](../server/), streams it straight
to the panel over SPI, and goes back to deep sleep.
@@ -52,7 +52,7 @@ never clobbers the other:
(`./build_for_board.sh devkit ...` does the same for the dev board --
equivalent to a plain `idf.py`, just consistent with the XIAO invocation.)
### Building for Seeed's EE02 (ESP32-S3 + 13.3" panel, driver not yet functional)
### Building for Seeed's EE02 (ESP32-S3 + 13.3" panel, driver ported; board still doesn't build end-to-end)
EE02 is a different chip (ESP32-S3, not C6), so it needs `set-target
esp32s3` instead of `esp32c6`, and its own partition table/flash-size
@@ -64,16 +64,25 @@ Kconfig sized for its 16MB flash
./build_for_board.sh ee02 build
```
**This will fail to compile.** `firmware/components/epd13in3e`'s panel
init/LUT/refresh register sequence hasn't been ported from vendor demo
code yet (see that file's own top comment and
[`docs/hardware.md`](../docs/hardware.md#133-spectra-6-panel-on-seeeds-ee02-board-driver-not-yet-functional))
-- a deliberate `#error`, not a bug in this build path. Everything
around it (target selection, Kconfig, partition table, sdkconfig
layering, `main/CMakeLists.txt`'s component selection) is in place and
exercised by CI (`.gitea/workflows/firmware-build-check.yml`/
`firmware-release-build.yml`, both with `continue-on-error` on this
board's step until the driver is real).
**This still fails to compile, but no longer because of the panel
driver.** `firmware/components/epd13in3e`'s panel init/LUT/refresh
register sequence is now a real, vendor-confirmed port (see that
component's own top comment and
[`docs/hardware.md`](../docs/hardware.md#133-spectra-6-panel-on-seeeds-ee02-board-panel-driver-ported-board-still-doesnt-build-end-to-end)
for the vendor sources and the load-bearing native-raster-orientation
correction that came with it) -- it compiles clean on its own. The build
now fails one step later, in `main/{back,next,combo}_button.c`: they call
an ESP32-C6-only deep-sleep GPIO-wakeup API with no ESP32-S3 fallback, a
pre-existing gap that the panel driver's old `#error` simply stopped the
build before reaching. See `docs/hardware.md`'s same section for what a
real fix looks like (not a mechanical swap -- ESP32-S3's equivalent API
takes one combined mask across all three button files' independent
calls). Everything else around the panel driver (target selection,
Kconfig, partition table, sdkconfig layering, `main/CMakeLists.txt`'s
component selection) is in place and exercised by CI
(`.gitea/workflows/firmware-build-check.yml`/`firmware-release-build.yml`,
both with `continue-on-error` on this board's step until a full build is
actually green).
## Configuration (`idf.py menuconfig`)