| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- #pragma once
- // Reusable window-encoder sweep, shared by run_harness.h (every panel) and
- // run_partial_harness.h. Calls the driver's PUBLIC refresh(x,y,w,h) at
- // several distinct in-bounds rects, with x/w kept multiples of 8 so the
- // driver's own coordinate rounding is a no-op and the window bytes in each
- // trace are exactly the rect. Diff the per-rect traces to DERIVE the
- // coordinate -> window-byte encoder by observation, instead of hand-
- // computing it (the latter produced the GDEQ0583T31 0x8F-vs-0x87 smear).
- //
- // Not fast-partial-specific: every panel sets a RAM window from
- // coordinates, so this works for any driver. On a panel whose refresh
- // ignores the rect and always refreshes full, every sweep point simply
- // emits the same (full) window - itself the informative result ("no
- // coordinate-parameterized window here"). The full (0,0,W,H) point is a
- // built-in cross-check against the window the normal full-refresh capture
- // already records.
- //
- // Precondition: run AFTER an initial full refresh - some drivers force the
- // very first refresh to be full regardless of the rect (e.g. the
- // _initial_refresh gate in GxEPD2_290_T94::refresh).
- #include <cstdint>
- #include <cstdio>
- template<typename Driver> void run_window_sweep(Driver &d, uint16_t W, uint16_t H) {
- auto align8_down = [](uint16_t v) -> uint16_t { return v & ~uint16_t(7); }; // to multiple of 8
- struct Rect {
- uint16_t x, y, w, h;
- const char *label;
- };
- const Rect rects[] = {
- {0, 0, W, H, "full (0,0,W,H) - cross-check vs full-refresh window"},
- {0, 0, 8, 8, "origin-unit (0,0,8,8)"},
- {8, 3, 8, 5, "small-offset (x/8=1, non-round y/h -> inclusive-end math)"},
- {align8_down(static_cast<uint16_t>(W / 2)), static_cast<uint16_t>(H / 2), 16, 24, "mid block"},
- {align8_down(static_cast<uint16_t>(W - 8)), static_cast<uint16_t>(H - 8), 8, 8, "far-corner - high bytes"},
- };
- printf("\n--- [WINDOW SWEEP] refresh(x,y,w,h) per rect (window bytes precede each refresh trigger) ---\n");
- for (const auto &r : rects) {
- if (r.w == 0 || r.h == 0 || r.x + r.w > W || r.y + r.h > H) {
- printf(">>> SWEEP skip %s = (%u,%u,%u,%u) - out of bounds for %ux%u\n", r.label, r.x, r.y, r.w, r.h, W, H);
- continue;
- }
- printf(">>> SWEEP %s = (%u,%u,%u,%u)\n", r.label, r.x, r.y, r.w, r.h);
- d.refresh(r.x, r.y, r.w, r.h);
- }
- }
|