From 29b3cfaeca3ef200ff78ffd40d2b21f3568b5685 Mon Sep 17 00:00:00 2001 From: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com> Date: Sun, 28 Jun 2026 16:27:01 -0400 Subject: [PATCH] Fix L1 E-Ink InkHUD issues (#10804) * Fixes * Update KeyboardApplet.cpp * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Ben Meadors Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../System/Keyboard/KeyboardApplet.cpp | 176 ++++++++++++++++++ .../Applets/System/Keyboard/KeyboardApplet.h | 23 +++ .../nrf52840/seeed_wio_tracker_L1/variant.cpp | 17 +- .../nrf52840/seeed_wio_tracker_L1/variant.h | 6 +- .../seeed_wio_tracker_L1_eink/platformio.ini | 15 +- .../seeed_wio_tracker_L1_eink/variant.cpp | 17 +- .../seeed_wio_tracker_L1_eink/variant.h | 6 +- 7 files changed, 245 insertions(+), 15 deletions(-) diff --git a/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.cpp index cb2b59953..ee7ceeb6b 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.cpp +++ b/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.cpp @@ -16,6 +16,12 @@ bool usePortraitKeyboardSizing() InkHUD::KeyboardApplet::KeyboardApplet() { + for (uint8_t row = 0; row < LEGACY_KBD_ROWS; row++) { + legacyRowWidths[row] = 0; + for (uint8_t col = 0; col < KBD_COLS; col++) + legacyRowWidths[row] += legacyKeyWidths[row * KBD_COLS + col]; + } + mode = MODE_TEXT; lastTypingMode = MODE_TEXT; emotePage = 0; @@ -26,6 +32,11 @@ InkHUD::KeyboardApplet::KeyboardApplet() void InkHUD::KeyboardApplet::onRender(bool full) { + if (!useTouchKeyboard()) { + renderLegacyKeyboard(full); + return; + } + const bool showSelection = showSelectionHighlight(); if (full) { @@ -39,6 +50,94 @@ void InkHUD::KeyboardApplet::onRender(bool full) prevSelectedKey = selectedKey; } +bool InkHUD::KeyboardApplet::useTouchKeyboard() const +{ + return inkhud->hasTouchEnabledProvider(); +} + +void InkHUD::KeyboardApplet::renderLegacyKeyboard(bool full) +{ + uint16_t em = fontSmall.lineHeight(); + uint16_t keyH = Y(1.0) / LEGACY_KBD_ROWS; + int16_t keyTopPadding = (keyH - fontSmall.lineHeight()) / 2; + + if (full) { + for (uint8_t row = 0; row < LEGACY_KBD_ROWS; row++) { + int16_t keyXPadding = X(1.0) - ((legacyRowWidths[row] * em) >> 4); + uint16_t xPos = 0; + for (uint8_t col = 0; col < KBD_COLS; col++) { + Color fgcolor = BLACK; + uint8_t index = row * KBD_COLS + col; + uint16_t keyX = ((xPos * em) >> 4) + ((col * keyXPadding) / (KBD_COLS - 1)); + uint16_t keyY = row * keyH; + uint16_t keyW = (legacyKeyWidths[index] * em) >> 4; + if (index == selectedKey) { + fgcolor = WHITE; + fillRect(keyX, keyY, keyW, keyH, BLACK); + } + drawLegacyKeyLabel(keyX, keyY + keyTopPadding, keyW, legacyKeys[index], fgcolor); + xPos += legacyKeyWidths[index]; + } + } + } else if (selectedKey != prevSelectedKey) { + uint8_t row = prevSelectedKey / KBD_COLS; + int16_t keyXPadding = X(1.0) - ((legacyRowWidths[row] * em) >> 4); + uint16_t xPos = 0; + for (uint8_t i = prevSelectedKey - (prevSelectedKey % KBD_COLS); i < prevSelectedKey; i++) + xPos += legacyKeyWidths[i]; + uint16_t keyX = ((xPos * em) >> 4) + (((prevSelectedKey % KBD_COLS) * keyXPadding) / (KBD_COLS - 1)); + uint16_t keyY = row * keyH; + uint16_t keyW = (legacyKeyWidths[prevSelectedKey] * em) >> 4; + fillRect(keyX, keyY, keyW, keyH, WHITE); + drawLegacyKeyLabel(keyX, keyY + keyTopPadding, keyW, legacyKeys[prevSelectedKey], BLACK); + + row = selectedKey / KBD_COLS; + keyXPadding = X(1.0) - ((legacyRowWidths[row] * em) >> 4); + xPos = 0; + for (uint8_t i = selectedKey - (selectedKey % KBD_COLS); i < selectedKey; i++) + xPos += legacyKeyWidths[i]; + keyX = ((xPos * em) >> 4) + (((selectedKey % KBD_COLS) * keyXPadding) / (KBD_COLS - 1)); + keyY = row * keyH; + keyW = (legacyKeyWidths[selectedKey] * em) >> 4; + fillRect(keyX, keyY, keyW, keyH, BLACK); + drawLegacyKeyLabel(keyX, keyY + keyTopPadding, keyW, legacyKeys[selectedKey], WHITE); + } + + prevSelectedKey = selectedKey; +} + +void InkHUD::KeyboardApplet::drawLegacyKeyLabel(uint16_t left, uint16_t top, uint16_t width, char key, Color color) +{ + if (key == '\b') { + const uint8_t bsBitmap[] = {0x0f, 0xf8, 0x18, 0x08, 0x32, 0x28, 0x61, 0x48, 0xc0, + 0x88, 0x61, 0x48, 0x32, 0x28, 0x18, 0x08, 0x0f, 0xf8}; + uint16_t leftPadding = (width - 13) >> 1; + drawBitmap(left + leftPadding, top + 1, bsBitmap, 13, 9, color); + } else if (key == '\n') { + const uint8_t doneBitmap[] = {0x00, 0x30, 0x00, 0x60, 0x00, 0xc0, 0x01, 0x80, 0x03, + 0x00, 0xc6, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00}; + uint16_t leftPadding = (width - 12) >> 1; + drawBitmap(left + leftPadding, top + 1, doneBitmap, 12, 9, color); + } else if (key == ' ') { + const uint8_t spaceBitmap[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x08, 0x80, 0x08, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00}; + uint16_t leftPadding = (width - 13) >> 1; + drawBitmap(left + leftPadding, top + 1, spaceBitmap, 13, 9, color); + } else if (key == '\x1b') { + setTextColor(color); + std::string keyText = "ESC"; + uint16_t leftPadding = (width - getTextWidth(keyText)) >> 1; + printAt(left + leftPadding, top, keyText); + } else { + setTextColor(color); + if (key >= 0x61) + key -= 32; + std::string keyText = std::string(1, key); + uint16_t leftPadding = (width - getTextWidth(keyText)) >> 1; + printAt(left + leftPadding, top, keyText); + } +} + void InkHUD::KeyboardApplet::drawKey(uint8_t index, bool selected) { uint16_t keyX = 0; @@ -104,14 +203,40 @@ void InkHUD::KeyboardApplet::onBackground() void InkHUD::KeyboardApplet::onButtonShortPress() { + if (!useTouchKeyboard()) { + handleLegacyInput(false); + return; + } + inputSelectedKey(false); } void InkHUD::KeyboardApplet::onButtonLongPress() { + if (!useTouchKeyboard()) { + handleLegacyInput(true); + return; + } + inputSelectedKey(true); } +void InkHUD::KeyboardApplet::handleLegacyInput(bool longPress) +{ + char key = legacyKeys[selectedKey]; + if (key == '\n') { + inkhud->freeTextDone(); + inkhud->closeKeyboard(); + } else if (key == '\x1b') { + inkhud->freeTextCancel(); + inkhud->closeKeyboard(); + } else { + if (longPress && key >= 0x61) + key -= 32; + inkhud->freeText(key); + } +} + void InkHUD::KeyboardApplet::onExitShort() { inkhud->freeTextCancel(); @@ -126,6 +251,17 @@ void InkHUD::KeyboardApplet::onExitLong() void InkHUD::KeyboardApplet::onNavUp() { + if (!useTouchKeyboard()) { + if (selectedKey < KBD_COLS) + selectedKey += KBD_COLS * (LEGACY_KBD_ROWS - 1); + else + selectedKey -= KBD_COLS; + + requestUpdate(EInk::UpdateTypes::FAST, false); + inkhud->forceUpdate(EInk::UpdateTypes::FAST); + return; + } + if (selectedKey < KBD_COLS) selectedKey += KBD_COLS * (KBD_ROWS - 1); else @@ -137,6 +273,14 @@ void InkHUD::KeyboardApplet::onNavUp() void InkHUD::KeyboardApplet::onNavDown() { + if (!useTouchKeyboard()) { + selectedKey += KBD_COLS; + selectedKey %= LEGACY_KBD_KEY_COUNT; + requestUpdate(EInk::UpdateTypes::FAST, false); + inkhud->forceUpdate(EInk::UpdateTypes::FAST); + return; + } + selectedKey += KBD_COLS; selectedKey %= KBD_KEY_COUNT; normalizeSelection(); @@ -145,6 +289,17 @@ void InkHUD::KeyboardApplet::onNavDown() void InkHUD::KeyboardApplet::onNavLeft() { + if (!useTouchKeyboard()) { + if (selectedKey % KBD_COLS == 0) + selectedKey += KBD_COLS - 1; + else + selectedKey--; + + requestUpdate(EInk::UpdateTypes::FAST, false); + inkhud->forceUpdate(EInk::UpdateTypes::FAST); + return; + } + if (selectedKey % KBD_COLS == 0) selectedKey += KBD_COLS - 1; else @@ -156,6 +311,17 @@ void InkHUD::KeyboardApplet::onNavLeft() void InkHUD::KeyboardApplet::onNavRight() { + if (!useTouchKeyboard()) { + if (selectedKey % KBD_COLS == KBD_COLS - 1) + selectedKey -= KBD_COLS - 1; + else + selectedKey++; + + requestUpdate(EInk::UpdateTypes::FAST, false); + inkhud->forceUpdate(EInk::UpdateTypes::FAST); + return; + } + if (selectedKey % KBD_COLS == KBD_COLS - 1) selectedKey -= KBD_COLS - 1; else @@ -418,6 +584,12 @@ bool InkHUD::KeyboardApplet::isKeyEnabledAt(uint8_t index) const void InkHUD::KeyboardApplet::normalizeSelection() { + if (!useTouchKeyboard()) { + if (selectedKey >= LEGACY_KBD_KEY_COUNT) + selectedKey = 0; + return; + } + if (selectedKey >= KBD_KEY_COUNT) selectedKey = 0; @@ -492,6 +664,10 @@ bool InkHUD::KeyboardApplet::showSelectionHighlight() const uint16_t InkHUD::KeyboardApplet::getKeyboardHeight() { + const auto *hud = NicheGraphics::InkHUD::InkHUD::getInstance(); + if (!hud || !hud->hasTouchEnabledProvider()) + return static_cast(fontSmall.lineHeight() * 1.2f) * LEGACY_KBD_ROWS; + // Keep touch keys tall and roomy for finger input. // In portrait orientation we increase row height for larger touch targets. const uint16_t rowUnit = fontSmall.lineHeight() + 8; diff --git a/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.h b/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.h index b71376459..65ddcf2a4 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.h +++ b/src/graphics/niche/InkHUD/Applets/System/Keyboard/KeyboardApplet.h @@ -37,6 +37,11 @@ class KeyboardApplet : public SystemApplet static uint16_t getKeyboardHeight(); // used to set the keyboard tile height private: + bool useTouchKeyboard() const; + void renderLegacyKeyboard(bool full); + void handleLegacyInput(bool longPress); + void drawLegacyKeyLabel(uint16_t left, uint16_t top, uint16_t width, char key, Color color); + enum KeyCode : int16_t { KEY_NONE = -1, KEY_BACKSPACE = 256, @@ -69,6 +74,8 @@ class KeyboardApplet : public SystemApplet bool showSelectionHighlight() const; static const uint8_t KBD_COLS = 11; + static const uint8_t LEGACY_KBD_ROWS = 4; + static const uint8_t LEGACY_KBD_KEY_COUNT = KBD_COLS * LEGACY_KBD_ROWS; static const uint8_t KBD_ROWS = 5; static const uint8_t KBD_KEY_COUNT = KBD_COLS * KBD_ROWS; static const uint8_t EMOTE_SLOT_COUNT = KBD_COLS * (KBD_ROWS - 1); // top 4 rows @@ -137,6 +144,22 @@ class KeyboardApplet : public SystemApplet static constexpr uint8_t KEY_GAP_X = 3; static constexpr uint8_t KEY_GAP_Y = 4; static constexpr uint8_t KEY_RADIUS = 4; + + const char legacyKeys[LEGACY_KBD_KEY_COUNT] = { + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\b', // row 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '\n', // row 1 + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '!', ' ', // row 2 + 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '?', '\x1b' // row 3 + }; + + const uint16_t legacyKeyWidths[LEGACY_KBD_KEY_COUNT] = { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, // row 0 + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, // row 1 + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, // row 2 + 16, 16, 16, 16, 16, 16, 16, 10, 10, 12, 40 // row 3 + }; + + uint16_t legacyRowWidths[LEGACY_KBD_ROWS]; }; } // namespace NicheGraphics::InkHUD diff --git a/variants/nrf52840/seeed_wio_tracker_L1/variant.cpp b/variants/nrf52840/seeed_wio_tracker_L1/variant.cpp index a045b0cf9..77d83b603 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1/variant.cpp +++ b/variants/nrf52840/seeed_wio_tracker_L1/variant.cpp @@ -22,6 +22,16 @@ #include "wiring_constants.h" #include "wiring_digital.h" +namespace +{ +void configureWakeOnPress(uint8_t digitalPin) +{ + const uint32_t gpioPin = g_ADigitalPinMap[digitalPin]; + nrf_gpio_cfg_input(gpioPin, NRF_GPIO_PIN_PULLUP); + nrf_gpio_cfg_sense_set(gpioPin, NRF_GPIO_PIN_SENSE_LOW); +} +} // namespace + /** * @brief Digital pin to GPIO port/pin mapping table * @@ -93,4 +103,9 @@ void initVariant() pinMode(PIN_LED2, OUTPUT); digitalWrite(PIN_LED2, LOW); pinMode(PIN_LED2, OUTPUT); -} \ No newline at end of file +} + +void variant_shutdown() +{ + configureWakeOnPress(CANCEL_BUTTON_PIN); +} diff --git a/variants/nrf52840/seeed_wio_tracker_L1/variant.h b/variants/nrf52840/seeed_wio_tracker_L1/variant.h index a1ec2508a..eee4c2333 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1/variant.h +++ b/variants/nrf52840/seeed_wio_tracker_L1/variant.h @@ -105,7 +105,9 @@ static const uint8_t SCL = PIN_WIRE_SCL; // Power Management // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -#define BAT_READ 30 // D30 = P0.04 Reads battery voltage from divider on signal board. +#define BAT_READ 30 // D30 = P0.04 Battery divider enable (BAT_CTL) on signal board. +#define ADC_CTRL BAT_READ +#define ADC_CTRL_ENABLED HIGH #define BATTERY_SENSE_RESOLUTION_BITS 12 #define ADC_MULTIPLIER 2.0 #define BATTERY_PIN PIN_VBAT // PIN_A7 @@ -178,4 +180,4 @@ extern "C" { } #endif -#endif // _SEEED_SOLAR_NODE_H_ \ No newline at end of file +#endif // _SEEED_TRACKER_L1_H_ diff --git a/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini b/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini index 26f4de565..cc746d017 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini +++ b/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini @@ -40,19 +40,16 @@ debug_tool = jlink [env:seeed_wio_tracker_L1_eink-inkhud] board = seeed_wio_tracker_L1 -extends = nrf52840_base, inkhud +extends = env:seeed_wio_tracker_L1_eink, inkhud build_flags = - ${nrf52840_base.build_flags} + ${env:seeed_wio_tracker_L1_eink.build_flags} ${inkhud.build_flags} - -I variants/nrf52840/seeed_wio_tracker_L1_eink - -D SEEED_WIO_TRACKER_L1 -D BUTTON_PIN=D13 -board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld -build_src_filter = - ${nrf52_base.build_src_filter} +build_src_filter = + ${env:seeed_wio_tracker_L1_eink.build_src_filter} ${inkhud.build_src_filter} - +<../variants/nrf52840/seeed_wio_tracker_L1_eink> lib_deps = ${inkhud.lib_deps} ; Before base libs_deps, so we use ZinggJM/GFXRoot instead of AdafruitGFX (saves space) - ${nrf52840_base.lib_deps} + ${env:seeed_wio_tracker_L1_eink.lib_deps} +board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld debug_tool = jlink diff --git a/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.cpp b/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.cpp index bcbe20ea5..52c9f33d5 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.cpp +++ b/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.cpp @@ -22,6 +22,16 @@ #include "wiring_constants.h" #include "wiring_digital.h" +namespace +{ +void configureWakeOnPress(uint8_t digitalPin) +{ + const uint32_t gpioPin = g_ADigitalPinMap[digitalPin]; + nrf_gpio_cfg_input(gpioPin, NRF_GPIO_PIN_PULLUP); + nrf_gpio_cfg_sense_set(gpioPin, NRF_GPIO_PIN_SENSE_LOW); +} +} // namespace + /** * @brief Digital pin to GPIO port/pin mapping table * @@ -100,4 +110,9 @@ void initVariant() digitalWrite(PIN_LED1, LOW); pinMode(PIN_LED2, OUTPUT); digitalWrite(PIN_LED2, LOW); -} \ No newline at end of file +} + +void variant_shutdown() +{ + configureWakeOnPress(CANCEL_BUTTON_PIN); +} diff --git a/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.h b/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.h index 495c4ace8..1ff18ec2f 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.h +++ b/variants/nrf52840/seeed_wio_tracker_L1_eink/variant.h @@ -113,7 +113,9 @@ static const uint8_t SCL = PIN_WIRE_SCL; // Power Management // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -#define BAT_READ 30 // D30 = P0.04 Reads battery voltage from divider on signal board. +#define BAT_READ 30 // D30 = P0.04 Battery divider enable (BAT_CTL) on signal board. +#define ADC_CTRL BAT_READ +#define ADC_CTRL_ENABLED HIGH #define BATTERY_SENSE_RESOLUTION_BITS 12 #define ADC_MULTIPLIER 2.0 #define BATTERY_PIN PIN_VBAT // PIN_A7 @@ -189,4 +191,4 @@ extern "C" { } #endif -#endif // _SEEED_TRACKER_L1_H_ \ No newline at end of file +#endif // _SEEED_TRACKER_L1_H_