From 21fbecd5971576b66e0acee855f3577783a25df1 Mon Sep 17 00:00:00 2001 From: Ian Foster Date: Mon, 18 May 2026 17:14:46 -0700 Subject: [PATCH] feat(expander): call setIntOutput from begin() to set active-HIGH INT polarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MCP23017 power-on default for IOCON is 0x00 — which means INTPOL=0 (active-LOW): the INT pin drives HIGH when no interrupt is pending and only drives LOW when one fires. On Inkplate hardware (and any design that wires INT into a host MCU configured to wake on HIGH, e.g. ESP32 ESP_EXT1_WAKEUP_ANY_HIGH), this is exactly inverted from what is wanted, causing the host to see a permanently asserted wake line every time it sleeps. v11.0.1 restored the setIntOutput() API that v11.0.0 removed, but did not configure IOCON from begin(). This means each application that uses MCP- driven wake must remember to call setIntOutput() with the right parameters after display.begin(). For applications that don't, deep-sleep + MCP-driven wake is non-functional out of the box: the host wakes immediately on every sleep cycle regardless of pin activity. Call setIntOutput() from begin() with sensible Inkplate-correct defaults (active-HIGH, push-pull, ports not mirrored) so the library works correctly on standard Inkplate wiring without requiring application code to know about IOCON. Users with non-default wiring can still override by calling setIntOutput() after begin(). --- src/system/mcpExpander/mcpExpander.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/system/mcpExpander/mcpExpander.cpp b/src/system/mcpExpander/mcpExpander.cpp index c0245d35..e22db4ed 100644 --- a/src/system/mcpExpander/mcpExpander.cpp +++ b/src/system/mcpExpander/mcpExpander.cpp @@ -36,6 +36,22 @@ bool IOExpander::begin(uint8_t _addr) readMCPRegisters(); + // Configure the INT output for Inkplate-compatible defaults: active-HIGH + // polarity, push-pull driver, ports not mirrored. The MCP23017 power-on + // default for IOCON is 0x00 (INTPOL=0, active-LOW) which causes the INT + // pin to idle HIGH and only drive LOW on an interrupt — the inverse of + // what is wanted on the Inkplate boards (and on most host designs that + // use the ESP32's ESP_EXT1_WAKEUP_ANY_HIGH for deep-sleep wake). Without + // this step the host sees a permanently asserted wake line and exits + // deep sleep immediately every cycle. + // + // v11.0.1 restored the setIntOutput() API but did not call it from + // begin(). Setting a sensible default here means the library "just + // works" on Inkplate hardware without requiring application code to + // know about IOCON. Users with non-default wiring can still override by + // calling setIntOutput() after begin(). + setIntOutput(MCP23017_INT_PORTB, MCP23017_INT_NO_MIRROR, MCP23017_INT_PUSHPULL, MCP23017_INT_ACTHIGH); + #ifdef IO_INT_ADDR if (_addr == IO_INT_ADDR) {