ZiB 026fa19eec Add CONTRIBUTING.md; point component docs at it instead of claude/DESIGN.md 3 週間 前
..
spy 4300e0fe93 Restructure: ship only the component; move dev-only trees out 3 週間 前
README.md 026fa19eec Add CONTRIBUTING.md; point component docs at it instead of claude/DESIGN.md 3 週間 前
emit_descriptor.h 030494b661 Add GDEY0213F52 (JD79676) via vendor update + emitter 3 週間 前
probe_plane_invert.h db1cd5b6ec harness: fold plane_invert + 1bpp/packed detection into the emitter 3 週間 前
run_154_z90c.cpp 42c87bb88d Add a dynamic-tracing harness for extracting GxEPD2 per-panel protocol data 1 ヶ月 前
run_154_z90c_emit.cpp 5acc8432c4 Add GDEH0154Z90 3-color panel descriptor (emitter-derived) 3 週間 前
run_213_z98c.cpp 42c87bb88d Add a dynamic-tracing harness for extracting GxEPD2 per-panel protocol data 1 ヶ月 前
run_213_z98c_diag.cpp d6e65922fb harness: diagnostic-fill Pattern A (row/byte ordering) 3 週間 前
run_213_z98c_probe.cpp 54022b2ea1 harness: derive plane_invert by capture (probe) 3 週間 前
run_213c_gdey0213f52_emit.cpp 02c21cbeb0 harness: F52 emit main + bump vendor marker to +zib.2 3 週間 前
run_290_t94.cpp 42c87bb88d Add a dynamic-tracing harness for extracting GxEPD2 per-panel protocol data 1 ヶ月 前
run_290_t94_diag.cpp d6e65922fb harness: diagnostic-fill Pattern A (row/byte ordering) 3 週間 前
run_290_t94_partial.cpp 560f5e9fbe harness: add fast-partial capture program (GxEPD2_290_T94) 3 週間 前
run_290_t94_wrapper.cpp 42c87bb88d Add a dynamic-tracing harness for extracting GxEPD2 per-panel protocol data 1 ヶ月 前
run_290c_gdey029f51.cpp a4ac4b79e4 Add harness runners for the four panels on the bench today 1 ヶ月 前
run_290c_gdey029f51_diagB.cpp 15cc4d5a3d harness: diagnostic-fill Pattern B (pixel packing + codes) 3 週間 前
run_290c_gdey029f51_diagN.cpp ca79e6cea3 harness: native-path row ordering for packed panels 3 週間 前
run_290c_gdey029f51_emit.cpp b3d1b32e22 harness: prototype descriptor emitter (single-plane panels) 3 週間 前
run_426_gdeq0426t82.cpp a4ac4b79e4 Add harness runners for the four panels on the bench today 1 ヶ月 前
run_426_gdeq0426t82_diag.cpp d6e65922fb harness: diagnostic-fill Pattern A (row/byte ordering) 3 週間 前
run_565c_diagB.cpp 9491ec9d41 harness: extend Pattern B to 7-colour ACeP 3 週間 前
run_579c_gdey0579f51.cpp a4ac4b79e4 Add harness runners for the four panels on the bench today 1 ヶ月 前
run_579c_gdey0579f51_diagN.cpp ca79e6cea3 harness: native-path row ordering for packed panels 3 週間 前
run_583_gdeq0583t31.cpp a4ac4b79e4 Add harness runners for the four panels on the bench today 1 ヶ月 前
run_583_gdeq0583t31_diag.cpp d6e65922fb harness: diagnostic-fill Pattern A (row/byte ordering) 3 週間 前
run_diagB_harness.h 9491ec9d41 harness: extend Pattern B to 7-colour ACeP 3 週間 前
run_diagN_harness.h ca79e6cea3 harness: native-path row ordering for packed panels 3 週間 前
run_diag_harness.h d6e65922fb harness: diagnostic-fill Pattern A (row/byte ordering) 3 週間 前
run_harness.h c0c21c11cd harness: make the window-encoder sweep a standard capture step 3 週間 前
run_partial_harness.h c0c21c11cd harness: make the window-encoder sweep a standard capture step 3 週間 前
run_wrapper_harness.h 42c87bb88d Add a dynamic-tracing harness for extracting GxEPD2 per-panel protocol data 1 ヶ月 前
trace.h b3d1b32e22 harness: prototype descriptor emitter (single-plane panels) 3 週間 前
window_sweep.h c0c21c11cd harness: make the window-encoder sweep a standard capture step 3 週間 前

README.md

gxepd2 capture harness

Host-side tooling that generates a panel descriptor by observing a real GxEPD2 driver run, instead of hand-writing one. See ../../CONTRIBUTING.md for the full model; this is the how-to.

The vendored GxEPD2 source it compiles against lives in third_party/GxEPD2/. Everything here runs on a dev machine with plain g++ — no ESP toolchain.

Emit a descriptor

One command (from the code/ root) resolves the driver, builds+runs the harness, and prints a candidate descriptor:

tools/capture.py --list                      # capturable driver classes
tools/capture.py GxEPD2_154_Z90c             # candidate -> stdout
tools/capture.py GxEPD2_154_Z90c -o /tmp/panel_154_z90c.h
tools/capture.py GxEPD2_154_Z90c --debug     # also dump the capture structure

It finds the driver in catalog.json (or by globbing third_party/GxEPD2/ for one the catalog doesn't list), so there's no build line to hand-write. Under the hood it does exactly:

VSRC=third_party/GxEPD2/src
g++ -std=c++17 -I tools/gxepd2_harness/spy -I $VSRC -I tools/gxepd2_harness \
    <generated emit main>.cpp \
    $VSRC/GxEPD2_EPD.cpp $VSRC/<subdir>/GxEPD2_<Class>.cpp \
    -o /tmp/emit_<panel>

emit_descriptor.h phase-segments the captured command stream into the init / window / refresh sequences + plane-write command(s), reads resolution / busy-polarity / timeout from the driver, and derives plane_invert and 1bpp-vs-packed from a fill probe. Review the result, add any packed-format fields the diag passes own (bits_per_pixel / palette for packed panels; plane_width / row_interleave for dual-region), then save it as components/gxepd2/panel_<panel>.h and wire it into display.py's MODELS.

EMIT_DEBUG=1 /tmp/emit_<panel> dumps the image-stage command/burst structure.

Regression check (CI)

tools/check_descriptors.py re-emits every shipped panel from its GxEPD2 driver and structurally diffs the result against the committed panel_*.h (command sequences + plane layout only, not the hand/diag-filled fields). It exits non-zero on any unexpected mismatch, so wire it into CI as a plain step:

tools/check_descriptors.py        # all panels; -v shows the diff on a mismatch

A DIFF means either an emitter regression or GxEPD2 upstream drift (a vendor bump changed that driver — review the panel). Dual-region panels the emitter doesn't fully model yet are listed in its KNOWN_DIFF and reported as XFAIL; panels with no GxEPD2 driver source (the synthetic MASTER_ONLY variant) are skipped. Run it after any third_party/GxEPD2/ update.

Other programs

  • run_<panel>.cpp + run_harness.h — bare-driver capture plus the window-encoder sweep (window_sweep.h), for deriving the coordinate → window-byte mapping.
  • run_<panel>_probe.cpp + probe_plane_invert.h — print the plane_invert probe result on its own.
  • run_*diag*.cpp — the diagnostic-fill passes that derive pixel packing, palette codes, and row order for packed / multi-region panels.
  • spy/ — the host stand-ins for the Arduino/SPI APIs a GxEPD2 driver calls; trace.h records what the driver does.