| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- #pragma once
- // Drives one vendor GxEPD2 driver through the same low-level calls the
- // GxEPD2_BW/GxEPD2_3C wrapper templates make for a single non-paged full
- // update (writeImage() then refresh()) - bypassing the wrapper templates
- // themselves (and their Adafruit_GFX dependency) since we only need the
- // driver-level trace, not drawing helpers. After the full update it also
- // runs the window-encoder sweep (window_sweep.h) - adopted as the standard
- // capture step for every panel, to derive and cross-check the coordinate ->
- // window-byte math by observation rather than by hand.
- #include <cstdio>
- #include <cstring>
- #include "spy/Arduino.h"
- #include "spy/SPI.h"
- #include "trace.h"
- #include "window_sweep.h"
- // Exposes GxEPD2_EPD's protected busy_level/reset_duration without needing
- // to parse anything - a subclass can read its own base class's protected
- // members directly.
- template<typename Driver> struct Peek : Driver {
- using Driver::Driver;
- int busy_level() const { return this->_busy_level; }
- uint16_t reset_duration() const { return this->_reset_duration; }
- };
- // planes=1 for monochrome drivers (color buffer still passed - harmless,
- // see e.g. GxEPD2_290_T94::writeImage(black,color,...) which just ignores
- // a non-null color pointer's absence).
- template<typename Driver> void run_harness(const char *name) {
- printf("=== %s: WIDTH=%u HEIGHT=%u ===\n", name, (unsigned) Driver::WIDTH, (unsigned) Driver::HEIGHT);
- constexpr int16_t CS = 10, DC = 11, RST = 12, BUSY = 13;
- Trace::set_dc_pin(DC);
- Peek<Driver> driver(CS, DC, RST, BUSY);
- printf("busy_level=%d reset_duration=%u\n", driver.busy_level(), driver.reset_duration());
- // digitalRead(BUSY) should report "released" immediately - opposite of
- // busy_level - so _waitWhileBusy()'s loop exits after one check.
- Trace::last_busy_release_value = driver.busy_level() == HIGH ? LOW : HIGH;
- driver.selectSPI(SPI, SPISettings());
- printf("--- init(0) ---\n");
- driver.init(0);
- const uint32_t plane_bytes = (static_cast<uint32_t>(Driver::WIDTH) * Driver::HEIGHT) / 8;
- auto *black = new uint8_t[plane_bytes];
- auto *color = new uint8_t[plane_bytes];
- // Distinctive, non-0x00/0xFF pattern - lets a plane's invert flag be
- // read directly off the trace (does the wire byte equal 0xA5 or 0x5A).
- memset(black, 0xA5, plane_bytes);
- memset(color, 0xA5, plane_bytes);
- printf("--- writeImage(black, color, 0, 0, WIDTH, HEIGHT) ---\n");
- driver.writeImage(black, color, 0, 0, Driver::WIDTH, Driver::HEIGHT);
- printf("--- refresh(false) ---\n");
- driver.refresh(false);
- // Standard window-encoder sweep for every panel (runs after the initial
- // full refresh above, which satisfies run_window_sweep's precondition).
- run_window_sweep(driver, Driver::WIDTH, Driver::HEIGHT);
- delete[] black;
- delete[] color;
- }
|