diff --git a/src/graphics/niche/Inputs/TwoButton.cpp b/src/graphics/niche/Inputs/TwoButton.cpp index 10d89ef41..b270d56cf 100644 --- a/src/graphics/niche/Inputs/TwoButton.cpp +++ b/src/graphics/niche/Inputs/TwoButton.cpp @@ -2,6 +2,7 @@ #include "./TwoButton.h" +#include "NodeDB.h" // For the helper function TwoButton::getUserButtonPin #include "PowerFSM.h" #include "sleep.h" @@ -57,14 +58,47 @@ void TwoButton::stop() detachInterrupt(buttons[1].pin); } +// Attempt to resolve a GPIO pin for the user button, honoring userPrefs.jsonc and device settings +// This helper method isn't used by the TweButton class itself, it could be moved elsewhere. +// Intention is to pass this value to TwoButton::setWiring in the setupNicheGraphics method. +uint8_t TwoButton::getUserButtonPin() +{ + uint8_t pin = 0xFF; // Unset + + // Use default pin for variant, if no better source +#ifdef BUTTON_PIN + pin = BUTTON_PIN; +#endif + + // From userPrefs.jsonc, if set +#ifdef USERPREFS_BUTTON_PIN + pin = USERPREFS_BUTTON_PIN; +#endif + + // From user's override in device settings, if set + if (config.device.button_gpio) + pin = config.device.button_gpio; + + return pin; +} + // Configures the wiring and logic of either button // Called when outlining your NicheGraphics implementation, in variant/nicheGraphics.cpp void TwoButton::setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup) { + // Prevent the same GPIO being assigned to multiple buttons + // Allows an edge case when the user remaps hardware buttons using device settings, due to a broken user button + for (uint8_t i = 0; i < whichButton; i++) { + if (buttons[i].pin == pin) { + LOG_WARN("Attempted reuse of GPIO %d. Ignoring assignment whichButton=%d", pin, whichButton); + return; + } + } + assert(whichButton < 2); buttons[whichButton].pin = pin; - buttons[whichButton].activeLogic = LOW; - buttons[whichButton].mode = internalPullup ? INPUT_PULLUP : INPUT; // fix me + buttons[whichButton].activeLogic = LOW; // Unimplemented + buttons[whichButton].mode = internalPullup ? INPUT_PULLUP : INPUT; pinMode(buttons[whichButton].pin, buttons[whichButton].mode); } diff --git a/src/graphics/niche/Inputs/TwoButton.h b/src/graphics/niche/Inputs/TwoButton.h index 1e1576256..f1e18dd89 100644 --- a/src/graphics/niche/Inputs/TwoButton.h +++ b/src/graphics/niche/Inputs/TwoButton.h @@ -30,6 +30,8 @@ class TwoButton : protected concurrency::OSThread public: typedef std::function Callback; + static uint8_t getUserButtonPin(); // Resolve the GPIO, considering the various possible source of definition + static TwoButton *getInstance(); // Create or get the singleton instance void start(); // Start handling button input void stop(); // Stop handling button input (disconnect ISRs for sleep) @@ -62,7 +64,7 @@ class TwoButton : protected concurrency::OSThread public: // Per-button config uint8_t pin = 0xFF; // 0xFF: unset - bool activeLogic = LOW; // Active LOW by default. Todo: remove, unused + bool activeLogic = LOW; // Active LOW by default. Currently unimplemented. uint8_t mode = INPUT; // Whether to use internal pull up / pull down resistors uint32_t debounceLength = 50; // Minimum length for shortpress, in ms uint32_t longpressLength = 500; // How long after button down to fire longpress, in ms diff --git a/variants/heltec_vision_master_e213/nicheGraphics.h b/variants/heltec_vision_master_e213/nicheGraphics.h index 75e4423be..d6983bafe 100644 --- a/variants/heltec_vision_master_e213/nicheGraphics.h +++ b/variants/heltec_vision_master_e213/nicheGraphics.h @@ -95,7 +95,7 @@ void setupNicheGraphics() constexpr uint8_t AUX_BUTTON = 1; // Setup the main user button - buttons->setWiring(MAIN_BUTTON, BUTTON_PIN); + buttons->setWiring(MAIN_BUTTON, Inputs::TwoButton::getUserButtonPin()); buttons->setHandlerShortPress(MAIN_BUTTON, []() { InkHUD::InkHUD::getInstance()->shortpress(); }); buttons->setHandlerLongPress(MAIN_BUTTON, []() { InkHUD::InkHUD::getInstance()->longpress(); }); diff --git a/variants/heltec_vision_master_e290/nicheGraphics.h b/variants/heltec_vision_master_e290/nicheGraphics.h index 2674436b8..c2f26c7ff 100644 --- a/variants/heltec_vision_master_e290/nicheGraphics.h +++ b/variants/heltec_vision_master_e290/nicheGraphics.h @@ -19,7 +19,7 @@ Different NicheGraphics UIs and different hardware variants will each have their // InkHUD-specific components // --------------------------- -#include "graphics/niche/InkHUD/WindowManager.h" +#include "graphics/niche/InkHUD/InkHUD.h" // Applets #include "graphics/niche/InkHUD/Applets/User/AllMessage/AllMessageApplet.h" @@ -113,7 +113,7 @@ void setupNicheGraphics() Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // A shared NicheGraphics component // Setup the main user button (0) - buttons->setWiring(0, BUTTON_PIN); + buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin()); buttons->setHandlerShortPress(0, []() { InkHUD::InkHUD::getInstance()->shortpress(); }); buttons->setHandlerLongPress(0, []() { InkHUD::InkHUD::getInstance()->longpress(); }); diff --git a/variants/heltec_wireless_paper/nicheGraphics.h b/variants/heltec_wireless_paper/nicheGraphics.h index ece4225d0..5e938fa64 100644 --- a/variants/heltec_wireless_paper/nicheGraphics.h +++ b/variants/heltec_wireless_paper/nicheGraphics.h @@ -93,7 +93,7 @@ void setupNicheGraphics() constexpr uint8_t MAIN_BUTTON = 0; // Setup the main user button - buttons->setWiring(MAIN_BUTTON, BUTTON_PIN); + buttons->setWiring(MAIN_BUTTON, Inputs::TwoButton::getUserButtonPin()); buttons->setHandlerShortPress(MAIN_BUTTON, []() { InkHUD::InkHUD::getInstance()->shortpress(); }); buttons->setHandlerLongPress(MAIN_BUTTON, []() { InkHUD::InkHUD::getInstance()->longpress(); }); diff --git a/variants/t-echo/nicheGraphics.h b/variants/t-echo/nicheGraphics.h index e8a9232f1..f5dde6b19 100644 --- a/variants/t-echo/nicheGraphics.h +++ b/variants/t-echo/nicheGraphics.h @@ -104,7 +104,7 @@ void setupNicheGraphics() constexpr uint8_t TOUCH_BUTTON = 1; // Setup the main user button - buttons->setWiring(MAIN_BUTTON, BUTTON_PIN, LOW); + buttons->setWiring(MAIN_BUTTON, Inputs::TwoButton::getUserButtonPin()); buttons->setTiming(MAIN_BUTTON, 75, 500); buttons->setHandlerShortPress(MAIN_BUTTON, []() { InkHUD::InkHUD::getInstance()->shortpress(); }); buttons->setHandlerLongPress(MAIN_BUTTON, []() { InkHUD::InkHUD::getInstance()->longpress(); });