Skip to content

Commit 504cdd6

Browse files
committed
Power: make timerSleep fail-closed and report when the device stays awake
timerSleep powered the device off even when the wake-up alarm had not been armed, and returned void so the caller could not tell. - The three overloads return bool: if the function returns, sleep was not entered. Reasons: invalid arguments, an RTC without the needed feature (PowerHub has no timer, use the date/time overloads), a failed cleanup of the existing IRQ sources, a failed RTC setup, a failed wake-source registration, the PC build. - Everything is validated (including the driver's own limits through canSetAlarm/hasTimerIRQ) before the existing IRQ sources are touched, so a bad request changes nothing. A request whose alarm fields are all wildcards is refused: the alarm API treats that as "clear", which must not be mistaken for an armed wake-up. - The old timer and alarm are disabled and cleared (both attempted, then combined) before the new one is armed; the ESP timer wake-up is set to the period the RTC actually applied so both sources share the deadline, and an ESP timer left by an earlier light sleep is dropped before an RTC-only sleep ("not registered" counts as clean). Without an RTC the ESP timer wake-up is used as before and its registration must succeed. - _powerOff / _timerSleep report a cancelled sleep: a failed EXT0 / GPIO / EXT1 wake registration, a wake pin that cannot be released, a PowerHub that does not accept the power-off request, a light sleep that cannot be entered. On cancellation the display is woken up again, a GPIO wake-up armed here is released (only the RTC pin, the GPIO wake source may carry the application's pins), and the caller releases the RTC IRQ and the ESP timer it armed. Without an RTC the RTC IRQ pin is not registered. - Docs: timerSleep(seconds) owns the ESP timer wake source; the RTC alarm wakes only boards where its IRQ is wired to a wake route (an external RTC unit does not wake the board).
1 parent 0e61d8e commit 504cdd6

2 files changed

Lines changed: 260 additions & 37 deletions

File tree

src/utility/Power_Class.hpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,20 +246,43 @@ namespace m5
246246

247247
/// sleep and timer boot. The boot condition can be specified by the argument.
248248
/// @param seconds Number of seconds to boot.
249-
void timerSleep(int seconds);
249+
/// @return If this function returns, sleep was not entered and the result is false. Reasons include
250+
/// invalid arguments, existing RTC IRQ cleanup failure, RTC setup failure, ESP timer wakeup
251+
/// registration failure without an RTC, wake source registration failure, and PC builds.
252+
/// Does not return once sleep is entered. Without an RTC the ESP32 timer wakeup is used.
253+
/// @note This function owns the ESP timer wake source: it is set for this sleep and disabled
254+
/// again when the sleep is cancelled, a previous setting is not restored.
255+
/// @note PowerHub has no periodic RTC timer; use a date/time overload on those boards.
256+
/// @note When the ESP timer wakeup cannot be registered the RTC timer is used alone; that
257+
/// wakes only boards where the RTC IRQ is wired to a wake route (not an external RTC unit).
258+
bool timerSleep(int seconds);
250259

251260
/// sleep and timer boot. The boot condition can be specified by the argument.
252261
/// @param time Time to boot. (only minutes and hours can be specified. Ignore seconds)
262+
/// @return If this function returns, sleep was not entered and the result is false. Reasons include
263+
/// invalid arguments, existing RTC IRQ cleanup failure, RTC setup failure,
264+
/// wake source registration failure, and PC builds.
265+
/// Does not return once sleep is entered.
266+
/// @note The RTC alarm wakes only boards where its IRQ is wired to a wake route;
267+
/// an alarm from an external RTC unit does not wake the board.
268+
/// @note An ESP timer wake-up left by an earlier sleep is disabled and not restored.
253269
/// @attention CoreInk and M5Paper can't alarm boot because it can't be turned off while connected to USB.
254270
/// @attention CoreInk と M5Paper は USB接続中はRTCタイマー起動が出来ない。;
255-
void timerSleep(const rtc_time_t& time);
271+
bool timerSleep(const rtc_time_t& time);
256272

257273
/// sleep and timer boot. The boot condition can be specified by the argument.
258274
/// @param date Date to boot. (only date and weekDay can be specified. Ignore year and month)
259275
/// @param time Time to boot. (only minutes and hours can be specified. Ignore seconds)
276+
/// @return If this function returns, sleep was not entered and the result is false. Reasons include
277+
/// invalid arguments, existing RTC IRQ cleanup failure, RTC setup failure,
278+
/// wake source registration failure, and PC builds.
279+
/// Does not return once sleep is entered.
280+
/// @note The RTC alarm wakes only boards where its IRQ is wired to a wake route;
281+
/// an alarm from an external RTC unit does not wake the board.
282+
/// @note An ESP timer wake-up left by an earlier sleep is disabled and not restored.
260283
/// @attention CoreInk and M5Paper can't alarm boot because it can't be turned off while connected to USB.
261284
/// @attention CoreInk と M5Paper は USB接続中はRTCタイマー起動が出来ない。;
262-
void timerSleep(const rtc_date_t& date, const rtc_time_t& time);
285+
bool timerSleep(const rtc_date_t& date, const rtc_time_t& time);
263286

264287
/// Value for micro_seconds of deepSleep / lightSleep, meaning "sleep without a timer wakeup".
265288
/// The device sleeps until a wakeup pin or another wakeup source is triggered.
@@ -458,8 +481,11 @@ namespace m5
458481
/// that the answer is one of the advertised capabilities.
459482
charge_state_t _getChargeState(void);
460483
std::int32_t _getBatteryAdcRaw(void);
461-
void _powerOff(bool withTimer);
462-
void _timerSleep(void);
484+
bool _disableEspTimerWakeup(void);
485+
/// withTimer: wake by an RTC IRQ is expected (an RTC timer/alarm was armed).
486+
bool _powerOff(bool withTimer);
487+
/// rtc_armed: false = no RTC wake-up was armed (ESP timer only), so the RTC IRQ pin is not registered.
488+
bool _timerSleep(bool rtc_armed = true);
463489

464490
#if defined (CONFIG_IDF_TARGET_ESP32C5) || defined (CONFIG_IDF_TARGET_ESP32C61)
465491
/// Check whether a battery is actually attached (non-blocking).

0 commit comments

Comments
 (0)