Files
crosspoint-reader-mod/chat-summaries/2026-03-09_06-00-summary.md
cottongin 6cf212d12a 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
2026-03-09 05:19:48 -04:00

2.0 KiB

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