diff --git a/lib/hal/HalGPIO.cpp b/lib/hal/HalGPIO.cpp index 9e93deb8..e603eccf 100644 --- a/lib/hal/HalGPIO.cpp +++ b/lib/hal/HalGPIO.cpp @@ -24,12 +24,13 @@ bool HalGPIO::wasAnyReleased() const { return inputMgr.wasAnyReleased(); } unsigned long HalGPIO::getHeldTime() const { return inputMgr.getHeldTime(); } void HalGPIO::startDeepSleep() { - esp_deep_sleep_enable_gpio_wakeup(1ULL << InputManager::POWER_BUTTON_PIN, ESP_GPIO_WAKEUP_GPIO_LOW); // Ensure that the power button has been released to avoid immediately turning back on if you're holding it while (inputMgr.isPressed(BTN_POWER)) { delay(50); inputMgr.update(); } + // Arm the wakeup trigger *after* the button is released + esp_deep_sleep_enable_gpio_wakeup(1ULL << InputManager::POWER_BUTTON_PIN, ESP_GPIO_WAKEUP_GPIO_LOW); // Enter Deep Sleep esp_deep_sleep_start(); } @@ -44,16 +45,24 @@ bool HalGPIO::isUsbConnected() const { return digitalRead(UART0_RXD) == HIGH; } -bool HalGPIO::isWakeupByPowerButton() const { +HalGPIO::WakeupReason HalGPIO::getWakeupReason() const { const bool usbConnected = isUsbConnected(); const auto wakeupCause = esp_sleep_get_wakeup_cause(); const auto resetReason = esp_reset_reason(); - return ((wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && resetReason == ESP_RST_POWERON && !usbConnected) || - (wakeupCause == ESP_SLEEP_WAKEUP_GPIO && resetReason == ESP_RST_DEEPSLEEP && usbConnected)); -} -bool HalGPIO::isWakeUpAfterFlash() const { - return esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_UNDEFINED && - esp_reset_reason() == ESP_RST_UNKNOWN && - isUsbConnected(); + if ((wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && resetReason == ESP_RST_POWERON && !usbConnected) || + (wakeupCause == ESP_SLEEP_WAKEUP_GPIO && resetReason == ESP_RST_DEEPSLEEP && usbConnected)) { + return WakeupReason::PowerButton; + } + if (wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && + resetReason == ESP_RST_UNKNOWN && + usbConnected) { + return WakeupReason::AfterFlash; + } + if (wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && + resetReason == ESP_RST_POWERON && + usbConnected) { + return WakeupReason::AfterUSBPower; + } + return WakeupReason::Other; } \ No newline at end of file diff --git a/lib/hal/HalGPIO.h b/lib/hal/HalGPIO.h index 99254aec..53ef8785 100644 --- a/lib/hal/HalGPIO.h +++ b/lib/hal/HalGPIO.h @@ -47,11 +47,14 @@ class HalGPIO { // Check if USB is connected bool isUsbConnected() const; - // Check if wakeup was caused by power button press - bool isWakeupByPowerButton() const; + enum class WakeupReason { + PowerButton, + AfterFlash, + AfterUSBPower, + Other + }; - // Check if wakeup was caused by flashing (hard reset via RTS pin) - bool isWakeUpAfterFlash() const; + WakeupReason getWakeupReason() const; // Button indices static constexpr uint8_t BTN_BACK = 0; diff --git a/src/main.cpp b/src/main.cpp index c020df77..e1d7a6c0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -294,18 +294,22 @@ void setup() { SETTINGS.loadFromFile(); KOREADER_STORE.loadFromFile(); - if (gpio.isWakeupByPowerButton()) { - // For normal wakeups, verify power button press duration - Serial.printf("[%lu] [ ] Verifying power button press duration\n", millis()); - verifyPowerButtonDuration(); - } else if (gpio.isWakeUpAfterFlash()) { - // After flashing, just proceed to boot - Serial.printf("[%lu] [ ] Wake up after flash detected, proceeding to boot\n", millis()); - } else { - // If USB power caused a cold boot, go back to sleep - Serial.printf("[%lu] [ ] No valid wakeup detected, entering deep sleep\n", millis()); - gpio.startDeepSleep(); - // This should never be hit as `startDeepSleep` calls esp_deep_sleep_start + switch (gpio.getWakeupReason()) { + case HalGPIO::WakeupReason::PowerButton: + // For normal wakeups, verify power button press duration + Serial.printf("[%lu] [ ] Verifying power button press duration\n", millis()); + verifyPowerButtonDuration(); + break; + case HalGPIO::WakeupReason::AfterUSBPower: + // If USB power caused a cold boot, go back to sleep + Serial.printf("[%lu] [ ] Wakeup reason: After USB Power\n", millis()); + gpio.startDeepSleep(); + break; + case HalGPIO::WakeupReason::AfterFlash: + // After flashing, just proceed to boot + case HalGPIO::WakeupReason::Other: + default: + break; } // First serial output only here to avoid timing inconsistencies for power button press duration verification @@ -313,6 +317,46 @@ void setup() { setupDisplayAndFonts(); + // log reset reason and wakeup cause + // log enum names as strings for easier reading in logs + // Convert enum values to readable strings for logs + auto resetReasonStr = [resetReason]() { + switch (resetReason) { + case ESP_RST_UNKNOWN: return "UNKNOWN"; + case ESP_RST_POWERON: return "POWERON"; + case ESP_RST_EXT: return "EXT"; + case ESP_RST_SW: return "SW"; + case ESP_RST_PANIC: return "PANIC"; + case ESP_RST_INT_WDT: return "INT_WDT"; + case ESP_RST_TASK_WDT:return "TASK_WDT"; + case ESP_RST_WDT: return "WDT"; + case ESP_RST_DEEPSLEEP: return "DEEPSLEEP"; + case ESP_RST_BROWNOUT: return "BROWNOUT"; + case ESP_RST_SDIO: return "SDIO"; + default: return "OTHER"; + } + }(); + + auto wakeupCauseStr = [wakeupCause]() { + switch (wakeupCause) { + case ESP_SLEEP_WAKEUP_UNDEFINED: return "UNDEFINED"; + case ESP_SLEEP_WAKEUP_EXT0: return "EXT0"; + case ESP_SLEEP_WAKEUP_EXT1: return "EXT1"; + case ESP_SLEEP_WAKEUP_TIMER: return "TIMER"; + case ESP_SLEEP_WAKEUP_TOUCHPAD: return "TOUCHPAD"; + case ESP_SLEEP_WAKEUP_ULP: return "ULP"; + case ESP_SLEEP_WAKEUP_GPIO: return "GPIO"; + case ESP_SLEEP_WAKEUP_UART: return "UART"; + default: return "OTHER"; + } + }(); + + const std::string resetInfo = + std::string("Reset: ") + resetReasonStr + " Wakeup: " + wakeupCauseStr + " USB: " + (usbConnected ? "Yes" : "No"); + enterNewActivity( + new FullScreenMessageActivity(renderer, mappedInputManager, resetInfo, EpdFontFamily::REGULAR)); + delay(10000); + exitActivity(); enterNewActivity(new BootActivity(renderer, mappedInputManager));