diff --git a/lib/hal/HalPowerManager.cpp b/lib/hal/HalPowerManager.cpp index c4ca41bf..31e9a7e8 100644 --- a/lib/hal/HalPowerManager.cpp +++ b/lib/hal/HalPowerManager.cpp @@ -17,14 +17,14 @@ void HalPowerManager::setPowerSaving(bool enabled) { if (enabled && !isLowPower) { LOG_DBG("PWR", "Going to low-power mode"); if (!setCpuFrequencyMhz(LOW_POWER_FREQ)) { - LOG_ERR("PWR", "Failed to set low-power CPU frequency"); + LOG_DBG("PWR", "Failed to set CPU frequency = %d MHz", LOW_POWER_FREQ); return; } } if (!enabled && isLowPower) { LOG_DBG("PWR", "Restoring normal CPU frequency"); if (!setCpuFrequencyMhz(normalFreq)) { - LOG_ERR("PWR", "Failed to restore normal CPU frequency"); + LOG_DBG("PWR", "Failed to set CPU frequency = %d MHz", normalFreq); return; } } diff --git a/src/activities/ActivityWithSubactivity.h b/src/activities/ActivityWithSubactivity.h index 141dbbcb..3189467d 100644 --- a/src/activities/ActivityWithSubactivity.h +++ b/src/activities/ActivityWithSubactivity.h @@ -14,4 +14,6 @@ class ActivityWithSubactivity : public Activity { : Activity(std::move(name), renderer, mappedInput) {} void loop() override; void onExit() override; + bool preventAutoSleep() override { return subActivity && subActivity->preventAutoSleep(); } + bool skipLoopDelay() override { return subActivity && subActivity->skipLoopDelay(); } }; diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 044c5470..3ad7e656 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -861,6 +861,8 @@ void EpubReaderActivity::renderScreen() { } if (!section) { + loadingSection = true; + const auto filepath = epub->getSpineItem(currentSpineIndex).href; LOG_DBG("ERS", "Loading file: %s, index: %d", filepath.c_str(), currentSpineIndex); section = std::unique_ptr
(new Section(epub, currentSpineIndex, renderer)); @@ -880,6 +882,7 @@ void EpubReaderActivity::renderScreen() { viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, popupFn)) { LOG_ERR("ERS", "Failed to persist page data to SD"); section.reset(); + loadingSection = false; return; } } else { @@ -912,6 +915,8 @@ void EpubReaderActivity::renderScreen() { section->currentPage = newPage; pendingPercentJump = false; } + + loadingSection = false; } renderer.clearScreen(); diff --git a/src/activities/reader/EpubReaderActivity.h b/src/activities/reader/EpubReaderActivity.h index 937c86af..56065c7c 100644 --- a/src/activities/reader/EpubReaderActivity.h +++ b/src/activities/reader/EpubReaderActivity.h @@ -29,6 +29,7 @@ class EpubReaderActivity final : public ActivityWithSubactivity { bool pendingSubactivityExit = false; // Defer subactivity exit to avoid use-after-free bool pendingGoHome = false; // Defer go home to avoid race condition with display task bool skipNextButtonCheck = false; // Skip button processing for one frame after subactivity exit + volatile bool loadingSection = false; // True during the entire !section block (read from main loop) const std::function onGoBack; const std::function onGoHome; @@ -55,4 +56,10 @@ class EpubReaderActivity final : public ActivityWithSubactivity { void onEnter() override; void onExit() override; void loop() override; + // Defer low-power mode and auto-sleep while a section is loading/building. + // !section covers the period before the Section object is created (including + // cover prerendering in onEnter). loadingSection covers the full !section block + // in renderScreen (including createSectionFile), during which section is non-null + // but the section file is still being built. + bool preventAutoSleep() override { return !section || loadingSection; } }; diff --git a/src/activities/reader/TxtReaderActivity.h b/src/activities/reader/TxtReaderActivity.h index 41ccbfbb..74618808 100644 --- a/src/activities/reader/TxtReaderActivity.h +++ b/src/activities/reader/TxtReaderActivity.h @@ -57,4 +57,7 @@ class TxtReaderActivity final : public ActivityWithSubactivity { void onEnter() override; void onExit() override; void loop() override; + // Defer low-power mode and auto-sleep while the reader is initializing + // (cover prerendering, page index building on first open). + bool preventAutoSleep() override { return !initialized; } }; diff --git a/src/main.cpp b/src/main.cpp index d99faea5..8aa0ccaf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -440,6 +440,13 @@ void loop() { } } + // Re-check preventAutoSleep: the activity may have changed during loop() above + // (e.g., HomeActivity transitioned to EpubReaderActivity with pending section work). + if (currentActivity && currentActivity->preventAutoSleep()) { + lastActivityTime = millis(); + powerManager.setPowerSaving(false); + } + // Add delay at the end of the loop to prevent tight spinning // When an activity requests skip loop delay (e.g., webserver running), use yield() for faster response // Otherwise, use longer delay to save power