fix: prevent idle freeze by hardening NTP and clock power management
BootNtpSync now acquires a HalPowerManager::Lock for the entire WiFi/NTP task lifecycle, keeping the CPU at full speed during scan, connect, sync, and teardown. The clock refresh logic in the main loop now explicitly restores CPU frequency and resets the activity timer before requesting a render, preventing display SPI operations from running at 10 MHz. Made-with: Cursor
This commit is contained in:
28
chat-summaries/2026-03-09_06-00-summary.md
Normal file
28
chat-summaries/2026-03-09_06-00-summary.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Fix Idle Freeze: NTP Power Lock and Clock Refresh Hardening
|
||||||
|
|
||||||
|
**Date**: 2026-03-09
|
||||||
|
|
||||||
|
## Task Description
|
||||||
|
|
||||||
|
Fix device freeze during idle, where the device stops responding to button presses after idling on the Home screen and requires a hard reset. Root cause was the mod-specific clock refresh logic in the main loop triggering a display render while the CPU is at reduced frequency (10 MHz low-power mode), combined with the background BootNtpSync task running WiFi/NTP operations without holding a power lock.
|
||||||
|
|
||||||
|
## Root Cause
|
||||||
|
|
||||||
|
The freeze coincides with the clock minute boundary. The mod's clock refresh code detects the minute change and calls `activityManager.requestUpdate()`, triggering a Home screen render while the CPU is at 10 MHz. SPI display operations at reduced APB frequency can deadlock the display communication. Additionally, `BootNtpSync` runs WiFi/NTP on a background task with no power lock, risking instability during WiFi teardown when the main loop may enter low-power mode.
|
||||||
|
|
||||||
|
## Changes Made
|
||||||
|
|
||||||
|
### 1. `src/util/BootNtpSync.cpp`
|
||||||
|
- Added `#include <HalPowerManager.h>`
|
||||||
|
- Added `HalPowerManager::Lock powerLock;` at the top of `taskFunc()` to keep the CPU at full speed for the entire duration of WiFi scanning, connection, NTP sync, and teardown
|
||||||
|
|
||||||
|
### 2. `src/main.cpp` (clock refresh block, ~lines 408-428)
|
||||||
|
- In the `sawInvalidTime` branch: added `lastActivityTime = millis()` and `powerManager.setPowerSaving(false)` before calling `requestUpdate()`
|
||||||
|
- In the minute-change branch: added `lastActivityTime = millis()` and `powerManager.setPowerSaving(false)` before calling `requestUpdate()`
|
||||||
|
- This ensures the CPU is restored to 160 MHz before any render-related code executes and prevents immediate re-entry into low-power mode
|
||||||
|
|
||||||
|
## Follow-up Items
|
||||||
|
|
||||||
|
- Verify on device that the freeze no longer occurs after idling for extended periods
|
||||||
|
- Monitor heap usage to confirm the power lock doesn't introduce memory issues
|
||||||
|
- Test that NTP sync still completes successfully with the power lock in place
|
||||||
@@ -416,9 +416,13 @@ void loop() {
|
|||||||
if (lastRenderedMinute < 0) {
|
if (lastRenderedMinute < 0) {
|
||||||
lastRenderedMinute = currentMinute;
|
lastRenderedMinute = currentMinute;
|
||||||
if (sawInvalidTime) {
|
if (sawInvalidTime) {
|
||||||
|
lastActivityTime = millis();
|
||||||
|
powerManager.setPowerSaving(false);
|
||||||
activityManager.requestUpdate();
|
activityManager.requestUpdate();
|
||||||
}
|
}
|
||||||
} else if (currentMinute != lastRenderedMinute) {
|
} else if (currentMinute != lastRenderedMinute) {
|
||||||
|
lastActivityTime = millis();
|
||||||
|
powerManager.setPowerSaving(false);
|
||||||
activityManager.requestUpdate();
|
activityManager.requestUpdate();
|
||||||
lastRenderedMinute = currentMinute;
|
lastRenderedMinute = currentMinute;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "CrossPointSettings.h"
|
#include "CrossPointSettings.h"
|
||||||
#include "WifiCredentialStore.h"
|
#include "WifiCredentialStore.h"
|
||||||
|
#include <HalPowerManager.h>
|
||||||
#include "util/TimeSync.h"
|
#include "util/TimeSync.h"
|
||||||
|
|
||||||
namespace BootNtpSync {
|
namespace BootNtpSync {
|
||||||
@@ -93,6 +94,7 @@ static bool tryConnectToSavedNetwork(const TaskParams& params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void taskFunc(void* param) {
|
static void taskFunc(void* param) {
|
||||||
|
HalPowerManager::Lock powerLock;
|
||||||
auto* params = static_cast<TaskParams*>(param);
|
auto* params = static_cast<TaskParams*>(param);
|
||||||
|
|
||||||
bool connected = tryConnectToSavedNetwork(*params);
|
bool connected = tryConnectToSavedNetwork(*params);
|
||||||
|
|||||||
Reference in New Issue
Block a user