From 9a414d9c77327f6030c050d2e0dbb8877241ae78 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 12 Oct 2020 08:13:32 +0800 Subject: [PATCH 1/2] fix my breakage of screen waking --- src/graphics/Screen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 96e18ac5..e4007aea 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -202,7 +202,7 @@ class Screen : public concurrency::OSThread return true; // claim success if our display is not in use else { bool success = cmdQueue.enqueue(cmd, 0); - setInterval(0); // handle ASAP + enabled = true; // handle ASAP (we are the registered reader for cmdQueue, but might have been disabled) return success; } } From a8e4bbbe656c950b5478fb46772c70f5c7e86957 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 12 Oct 2020 08:25:17 +0800 Subject: [PATCH 2/2] fix my breaking of button press behavior --- platformio.ini | 2 +- src/concurrency/InterruptableDelay.cpp | 22 ++--- src/main.cpp | 106 +++++++++++++++---------- 3 files changed, 72 insertions(+), 58 deletions(-) diff --git a/platformio.ini b/platformio.ini index dbdf1051..8109bf0e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -60,7 +60,7 @@ debug_tool = jlink lib_deps = https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306 - 1260 ; OneButton library for non-blocking button debounce + https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39 https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad diff --git a/src/concurrency/InterruptableDelay.cpp b/src/concurrency/InterruptableDelay.cpp index e7538235..80743cc2 100644 --- a/src/concurrency/InterruptableDelay.cpp +++ b/src/concurrency/InterruptableDelay.cpp @@ -4,30 +4,22 @@ namespace concurrency { -InterruptableDelay::InterruptableDelay() -{ -} +InterruptableDelay::InterruptableDelay() {} -InterruptableDelay::~InterruptableDelay() -{ -} +InterruptableDelay::~InterruptableDelay() {} /** * Returns false if we were interrupted */ bool InterruptableDelay::delay(uint32_t msec) { - if (msec) { - // DEBUG_MSG("delay %u ", msec); + // DEBUG_MSG("delay %u ", msec); - // sem take will return false if we timed out (i.e. were not interrupted) - bool r = semaphore.take(msec); + // sem take will return false if we timed out (i.e. were not interrupted) + bool r = semaphore.take(msec); - // DEBUG_MSG("interrupt=%d\n", r); - return !r; - } else { - return true; - } + // DEBUG_MSG("interrupt=%d\n", r); + return !r; } void InterruptableDelay::interrupt() diff --git a/src/main.cpp b/src/main.cpp index 175fbc60..21805e60 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -129,30 +129,11 @@ class PowerFSMThread : public OSThread /// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake /// cpu for serial rx - FIXME) canSleep = (powerFSM.getState() != &statePOWER); - + return 10; } }; -static Periodic *ledPeriodic; -static OSThread *powerFSMthread; - -// Prepare for button presses -#ifdef BUTTON_PIN -OneButton userButton; -#endif -#ifdef BUTTON_PIN_ALT -OneButton userButtonAlt; -#endif -void userButtonPressed() -{ - powerFSM.trigger(EVENT_PRESS); -} -void userButtonPressedLong() -{ - screen->adjustBrightness(); -} - /** * Watch a GPIO and if we get an IRQ, wake the main thread. * Use to add wake on button press @@ -168,6 +149,65 @@ void wakeOnIrq(int irq, int mode) FALLING); } +class ButtonThread : public OSThread +{ +// Prepare for button presses +#ifdef BUTTON_PIN + OneButton userButton; +#endif +#ifdef BUTTON_PIN_ALT + OneButton userButtonAlt; +#endif + + public: + // callback returns the period for the next callback invocation (or 0 if we should no longer be called) + ButtonThread() : OSThread("Button") + { +#ifdef BUTTON_PIN + userButton = OneButton(BUTTON_PIN, true, true); + userButton.attachClick(userButtonPressed); + userButton.attachDuringLongPress(userButtonPressedLong); + wakeOnIrq(BUTTON_PIN, FALLING); +#endif +#ifdef BUTTON_PIN_ALT + userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true); + userButtonAlt.attachClick(userButtonPressed); + userButton.attachDuringLongPress(userButtonPressedLong); + wakeOnIrq(BUTTON_PIN_ALT, FALLING); +#endif + } + + protected: + /// If the button is pressed we suppress CPU sleep until release + int32_t runOnce() + { + canSleep = true; // Assume we should not keep the board awake + +#ifdef BUTTON_PIN + userButton.tick(); + canSleep &= userButton.isIdle(); +#endif +#ifdef BUTTON_PIN_ALT + userButtonAlt.tick(); + canSleep &= userButton.isIdle(); +#endif + // if(!canSleep) DEBUG_MSG("Supressing sleep!\n"); + + return 5; + } + + private: + static void userButtonPressed() + { + // DEBUG_MSG("press!\n"); + powerFSM.trigger(EVENT_PRESS); + } + static void userButtonPressedLong() { screen->adjustBrightness(); } +}; + +static Periodic *ledPeriodic; +static OSThread *powerFSMthread, *buttonThread; + RadioInterface *rIf = NULL; void setup() @@ -210,18 +250,7 @@ void setup() #endif // Buttons & LED -#ifdef BUTTON_PIN - userButton = OneButton(BUTTON_PIN, true, true); - userButton.attachClick(userButtonPressed); - userButton.attachDuringLongPress(userButtonPressedLong); - wakeOnIrq(BUTTON_PIN, FALLING); -#endif -#ifdef BUTTON_PIN_ALT - userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true); - userButtonAlt.attachClick(userButtonPressed); - userButton.attachDuringLongPress(userButtonPressedLong); - wakeOnIrq(BUTTON_PIN_ALT, FALLING); -#endif + buttonThread = new ButtonThread(); #ifdef LED_PIN pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, 1 ^ LED_INVERTED); // turn on for now @@ -410,13 +439,6 @@ void loop() esp32Loop(); #endif -#ifdef BUTTON_PIN - userButton.tick(); -#endif -#ifdef BUTTON_PIN_ALT - userButtonAlt.tick(); -#endif - // For debugging // if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving(); @@ -437,9 +459,9 @@ void loop() /* if (mainController.nextThread && delayMsec) DEBUG_MSG("Next %s in %ld\n", mainController.nextThread->ThreadName.c_str(), - mainController.nextThread->tillRun(millis())); - */ - + mainController.nextThread->tillRun(millis())); */ + // We want to sleep as long as possible here - because it saves power mainDelay.delay(delayMsec); + // if (didWake) DEBUG_MSG("wake!\n"); }