Power/RTC: let the PowerHub STM32 arm the alarm before powering off - #369
Merged
Merged
Conversation
The PowerHub STM32 acknowledges the alarm register writes immediately but applies them to the RX8130 from its main loop (about 13 ms per iteration), behind a single "update pending" flag that it clears after each apply. A power-off request that arrives right after the alarm-enable write can overtake that step, and an update that lands while an older one is being applied can be dropped with the flag; either way the board powers off with no alarm armed and only the power button brings it back. Measured with timerSleep(time) on firmware 0xF3: 0 of 6 wake-ups with no gap, 6 of 6 with a 500 ms gap. - RTC_PowerHub: hand the alarm over as one D0..D3 block write (values and enable in a single STM32 callback) after the wake-source check, and route every alarm-register write (disable retries, block write, rollback, disableIRQ) through one helper that pauses 50 ms afterwards regardless of the result, so the main loop consumes each update before the next one. - Power: wait 500 ms before the power-off request when an alarm was armed, then stay off the I2C bus and wait up to 3 s for the power to drop instead of entering a light sleep with no wake source. The request cannot be withdrawn, so if the call still returns, timerSleep() leaves the alarm armed rather than clearing it. Documented on powerOff() and both date/time timerSleep() overloads. Verified on a PowerHub: 6 of 6 wake-ups through timerSleep(time).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On PowerHub,
Power::timerSleep(time)powered the board off before the STM32 front-end had armed the RTC alarm, so the board never woke up and only the power button brought it back.The STM32 acknowledges alarm register writes (D0..D3) immediately but applies them to the RX8130 from its main loop (about 13 ms per iteration), behind a single "update pending" flag that it clears after each apply. A power-off request (0xE0) that follows the alarm-enable write without a gap can overtake that step, and an update that lands while an older one is being applied can be dropped with the flag. Measured with
timerSleep(time): 0 of 6 wake-ups without a gap, 6 of 6 with a 500 ms gap.Changes
RTC_PowerHub_Class: the alarm is handed over as one D0..D3 block write (values and enable in a single STM32 callback) after the wake-source check, and every alarm-register write (initial disable retries, block write, rollback,disableIRQ) goes through one helper that pauses 50 ms afterwards regardless of the result, so the main loop consumes each update before the next one can race with the pending flag.Power_Class: when an alarm was armed, wait 500 ms before the power-off request; after the request is accepted, stay off the I2C bus and wait up to 3 s for the power to drop instead of entering a light sleep with no wake source. If the call still returns, the request cannot be withdrawn, sotimerSleep()leaves the alarm armed instead of clearing it (a late power-off would otherwise sleep with no wake source). Documented onpowerOff()and both date/timetimerSleep()overloads.Behaviour
timerSleep(time)/timerSleep(date, time)on PowerHub spend about 0.75 s before the power-off request (paced alarm writes, then the 0.5 s settle) and up to 3 s waiting for the power to drop.powerOff()on PowerHub returns after about 3 s if the board is still running; the board may still power off later.Rtc.setAlarmIRQ()/disableIRQ()on PowerHub block about 100-200 ms.Verification
PowerHub (STM32 firmware 0xF3),
timerSleep(now + 1 min)from a test firmware, wake-up = board reboots on the alarm:Builds: ESP32-S3 Arduino, no new warnings. Three rounds of independent adversarial review until no implementation finding remained. CI run on the ainyan03 fork before this PR.