feat(eink): bulk SPI row writes for the GDEQ0426T82, at 8 MHz

GxEPD2 sends the panel RAM a byte at a time; on the nRF52's SPIM the
per-call overhead dominates, and an 800x480 partial refresh writes the
whole 48 KB several times. GxEPD2_426_GDEQ0426T82_Fast overrides the three
image writes to send each row in one transfer() call, falling back to the
stock path for the cases it doesn't cover (first write, mirror_y, PROGMEM).
Byte-for-byte the same data as the stock driver.

Opt-in per env: -D EINK_FAST_WRITES=1, and EINK_SPI_HZ (default 4 MHz,
8 MHz here, SPIM2's ceiling).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KxAZVAbhhYr18Dd4guTQM1
This commit is contained in:
pmow
2026-10-09 08:47:35 -10:00
co-authored by Claude Opus 5.5
parent cc4774436f
commit da5ff56cff
4 changed files with 133 additions and 3 deletions
+9 -1
View File
@@ -14,8 +14,16 @@
SPIClass SPI1 = SPIClass(FSPI);
#endif
// SPI clock for the panel. 4 MHz is the conservative default every board has
// always used; a short FPC run can go faster (SSD16xx-family controllers are
// rated ~20 MHz for writes). On nRF52840 the Adafruit core puts SPI1 on SPIM2,
// which caps at 8 MHz -- higher requests are silently clamped to 8 MHz there.
#ifndef EINK_SPI_HZ
#define EINK_SPI_HZ 4000000
#endif
bool GxEPDDisplay::begin() {
display.epd2.selectSPI(SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
display.epd2.selectSPI(SPI1, SPISettings(EINK_SPI_HZ, MSBFIRST, SPI_MODE0));
#ifdef ESP32
SPI1.begin(PIN_DISPLAY_SCLK, PIN_DISPLAY_MISO, PIN_DISPLAY_MOSI, PIN_DISPLAY_CS);
#else