|
|
@@ -0,0 +1,61 @@
|
|
|
+#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.
|
|
|
+
|
|
|
+#include <cstdio>
|
|
|
+#include <cstring>
|
|
|
+
|
|
|
+#include "spy/Arduino.h"
|
|
|
+#include "spy/SPI.h"
|
|
|
+#include "trace.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);
|
|
|
+
|
|
|
+ delete[] black;
|
|
|
+ delete[] color;
|
|
|
+}
|