pub struct Timer { /* private fields */ }Expand description
Free-running microsecond counter (BCM System Timer) and blocking delays built on it.
The System Timer is a plain memory-mapped 64-bit counter (as CLO + CHI) running at a fixed 1MHz, needing no configuration — it’s already counting from boot.
Of the four compare registers C0-C3, only Compare 1 is used: the GPU firmware reserves C0 and C2 for itself, and C3 is left free.
Two properties of that compare shape every deadline API below, and neither is a limitation of this driver:
- It is 32 bits wide, against a 64-bit counter. The compare only sees CLO, the low half, so a deadline can only be expressed within 2^32us (~71.6 minutes) of the present, and any value matches once per wrap whether or not anyone armed it.
- It is an equality test, not a threshold. CS.M1 is set when C1 equals CLO, so a deadline the counter has already walked past does not fire late — it fires a whole wrap later.
Implementations§
Source§impl Timer
impl Timer
Sourcepub fn new(systmr: SYSTMR) -> Self
pub fn new(systmr: SYSTMR) -> Self
Wraps the System Timer peripheral. Needs no configuration — it’s already free-running from boot.
Sourcepub fn now_micros(&self) -> u64
pub fn now_micros(&self) -> u64
Microseconds elapsed since boot.
Sourcepub fn set_compare1(&self, deadline_us: u64) -> bool
pub fn set_compare1(&self, deadline_us: u64) -> bool
Arms Compare 1 for the absolute now_micros
deadline deadline_us, raising an IRQ at that point (once routed
via crate::lic::Lic::enable_timer1_irq and unmasked via
crate::irq::enable_irq).
Returns false if the deadline was already in the past by the
time it was armed — including the narrow case where the counter
passed it between computing the target and writing it. Because
the compare is an equality test (see the module doc comment),
that deadline would otherwise not fire for another ~71.6 minutes,
so a caller that still wants a timely wake-up must recompute
against a fresh now_micros and arm again rather than assume it
is pending.
A deadline further out than ~35.8 minutes is clamped to that,
keeping the write inside the range the 32-bit compare can
express. The match then fires early, which callers must tolerate
regardless: they have to re-check their own deadline against
now_micros on every match and re-arm if it hasn’t arrived yet.
Does not clear a match already pending from a previous arm —
pair with clear_compare1_match.
Sourcepub fn compare1_matched(&self) -> bool
pub fn compare1_matched(&self) -> bool
Whether Compare 1 has matched (CS.M1) and not yet been cleared.
Sourcepub fn clear_compare1_match(&self)
pub fn clear_compare1_match(&self)
Acknowledges a fired Compare 1 match (write-1-to-clear CS.M1) without arming another. Call this from the IRQ handler — leaving the match flag set would just re-trigger the same IRQ immediately after returning.
Sourcepub fn arm_periodic_c1(&self, period_us: u32)
pub fn arm_periodic_c1(&self, period_us: u32)
Arms Compare 1 to match period_us from now.
A convenience wrapper over set_compare1
for the fixed-period case, where the deadline is always close
enough to the present that neither the clamp nor the
already-passed case can be reached by a period of more than a
couple of microseconds.
Sourcepub fn ack_c1(&self, period_us: u32)
pub fn ack_c1(&self, period_us: u32)
Acknowledges a fired Compare 1 match and rearms the next period —
clear_compare1_match followed by
arm_periodic_c1.