Keep the RX8130 timer /IRQ pulse catchable and follow the datasheet re-arm sequence - #339
Merged
Merged
Conversation
…e-arm sequence The RX8130 wakeup timer releases /IRQ automatically after tRTN2, which is only 122us with the 4096Hz source clock but 7.57ms with the other clocks (Table 16). setTimerIRQ() picked 4096Hz for every period below 16s, so boards whose RTC /IRQ is routed through a scanning PMIC or IO expander (e.g. the M5PM1 GPIO IRQ path) missed the interrupt for common requests such as 1s or 10s. Clock selection now tries 64Hz, 1Hz, 1/60Hz and 1/3600Hz in that order and takes the first whose rounded count keeps the period within 1/256 and has at least 16 counts (the first countdown can be short by up to one source clock - 1s for the two slowest clocks - so this bounds that error to ~6% or less); 4096Hz is used only for periods no other clock can represent (below ~2s). The arithmetic stays in 32 bits: each clock carries its 65535-count range so msec*div cannot overflow, and the period error is the division remainder. When a finer clock runs out of range the coarser one rounds up, so the returned period never steps backwards as the request grows. The re-arm sequence follows the datasheet example flow: TE=0 (+TSEL) -> clear TF -> TIE=1 -> preset -> TE=1 last, so the first event can never precede the interrupt enable. The old code rewrote the counter with TE still set, which the datasheet does not allow and which left the timer running with the stale preset. The preset is read back while TE=0 and rewritten if it does not match. Every access in the arming path is checked; on failure the timer is stopped (TE=0/TIE=0, verified by read-back, retried) and 0 is returned - the return value cannot distinguish that from a requested stop, which the API comment now states. Flags in 0x1D are write-0-to-clear, so TF (and AF in clearIRQ/disableIRQ) is cleared with a single constant write instead of a read-modify-write that could drop a flag raised in between. The returned period is rounded to the nearest ms and is never 0 while the timer runs.
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.
Problem
RX8130_Class::setTimerIRQ()selected the 4096Hz source clock for every period below 16s. The RX8130 releases /IRQ automatically after tRTN2, which is only 122us for the 4096Hz clock but 7.57ms for all the other clocks (datasheet Table 16). Boards that route the RTC /IRQ through a scanning PMIC or IO expander (e.g. M5PaperMono: RX8130 → M5PM1 GPIO0 → PM1 IRQ → MCU) miss such a short pulse, so common requests likesetTimerIRQ(1000)or(10000)never reached the MCU.Changes (
src/utility/rtc/RX8130_Class.cpp)TFnever set after a re-arm).@returncomment now states that 0 means either disabled or "could not be set".clearIRQ/disableIRQ) is cleared with a single constant write instead of a read-modify-write that could drop a flag raised in between.Alarm interrupts are unaffected (their /IRQ is held until cleared).
Verification
Host-side sweep of the selection over the full
uint32_trange: max period error 0.39%, no non-monotonic point, 4096Hz only used for requests ≤ 1961ms.On M5PaperMono (RTC /IRQ observed through the PM1 IRQ line):
setTimerIRQ(1000)setTimerIRQ(16000)Fork CI (ArduinoBuild / IDFBuild) passed on this branch.