gd32e2_hal/timer.rs
1//! Timers: the counter core shared by every TIMER peripheral.
2//!
3//! A timer counts `CK_TIMERx` ticks divided by `PSC + 1`, and restarts from zero
4//! once the count reaches `CAR`. Everything else a timer can do — PWM, input
5//! capture, triggering other peripherals — is built on top of that core.
6//!
7//! ```ignore
8//! let timer = dp.timer5.constrain(&mut rcu);
9//! let mut timer = timer.start_interval(500.millis());
10//! timer.wait();
11//! ```
12
13use core::convert::Infallible;
14
15use embedded_hal::delay::DelayNs;
16use embedded_hal::pwm::{ErrorType, SetDutyCycle};
17
18use crate::gpio::{Alternate, Pin};
19use crate::pac;
20use crate::rcu::{Clocks, Enable, Rcu, Reset};
21use crate::time::{Duration, Hertz, NanosDuration};
22
23/// Counts one prescaler or counter cycle can span, both fields being 16-bit.
24const MAX_COUNT: u32 = 1 << 16;
25
26/// Splits a tick count into the `PSC` and `CAR` values whose cycle spans it.
27///
28/// The prescaler is kept as small as the counter width allows, since the
29/// counter's step is the resolution everything inherits. Truncating division, so
30/// the interval is at most one prescaler cycle short. Zero is raised to one.
31fn dividers(ticks: u32) -> (u16, u16) {
32 let ticks = ticks.max(1);
33 let psc = ticks.div_ceil(MAX_COUNT);
34 let car = ticks / psc;
35 ((psc - 1) as u16, (car - 1) as u16)
36}
37
38/// Converts an interval of any scale into ticks of `clock`.
39///
40/// One `Duration` tick is `NOM / DENOM` seconds, so ticks are
41/// `as_ticks() * NOM * clock / DENOM`. The division comes last, or every scale
42/// finer than a second floors to zero. Saturating throughout: past `u32::MAX`
43/// ticks is beyond what the dividers span anyway.
44fn interval_to_ticks<const NOM: u64, const DENOM: u64>(
45 interval: Duration<u32, NOM, DENOM>,
46 clock: Hertz,
47) -> u32 {
48 let raw_time = u64::from(interval.as_ticks());
49 let raw_freq = u64::from(clock.to_Hz());
50 (raw_time.saturating_mul(raw_freq).saturating_mul(NOM) / DENOM).min(u32::MAX.into()) as u32
51}
52
53/// Converts a tick count of `clock`, divided by `psc`, into a duration.
54///
55/// The inverse of [`interval_to_ticks`]: one tick is `psc + 1` clock cycles, so
56/// the duration is `ticks * (psc + 1) * DENOM / (clock * NOM)`. Division last,
57/// in `u64`, saturating.
58fn ticks_to_interval<const NOM: u64, const DENOM: u64>(
59 ticks: u16,
60 psc: u16,
61 clock: Hertz,
62) -> Duration<u32, NOM, DENOM> {
63 let ticks = u64::from(ticks);
64 let psc = u64::from(psc);
65 let clock = u64::from(clock.to_Hz());
66 Duration::<u32, NOM, DENOM>::from_ticks(
67 (ticks.saturating_mul(psc + 1).saturating_mul(DENOM) / clock.saturating_mul(NOM))
68 .min(u32::MAX.into()) as u32,
69 )
70}
71
72/// Loads the dividers and sets the counter running.
73///
74/// `UPG` loads them out of their shadow registers; the update event it raises is
75/// consumed here, so the first wait afterwards sees a real rollover.
76fn start_counter<TIMERX: Instance>(timer: &mut TIMERX, psc: u16, car: u16) {
77 timer.set_psc(psc);
78 timer.set_car(car);
79 timer.set_ups(true);
80 timer.gen_update();
81 timer.set_cen(true);
82}
83
84/// Blocks until the counter rolls over, then clears the flag it raised —
85/// hardware never clears `UPIF` itself, so the next wait measures a fresh cycle.
86fn wait_update<TIMERX: Instance>(timer: &mut TIMERX) {
87 while !timer.read_upif() {}
88 timer.clear_upif();
89}
90
91/// A timer event that can raise an interrupt.
92///
93/// Taken by [`CountDownTimer`], [`Pwm`] and [`Capture`] alike. Channel events
94/// are not here: a channel's `listen` takes no argument.
95#[derive(Clone, Copy, PartialEq, Eq)]
96#[cfg_attr(feature = "defmt", derive(defmt::Format))]
97pub enum Event {
98 /// The counter rolled over, ending one interval.
99 Update,
100}
101
102// Every role of a timer answers the same way about its events, so the mapping
103// from `Event` to registers lives here once rather than in each of them.
104fn set_listening<TIMERX: Instance>(timer: &mut TIMERX, event: Event, on: bool) {
105 match event {
106 Event::Update => timer.set_upie(on),
107 }
108}
109
110fn is_listening<TIMERX: Instance>(timer: &TIMERX, event: Event) -> bool {
111 match event {
112 Event::Update => timer.read_upie(),
113 }
114}
115
116fn is_pending<TIMERX: Instance>(timer: &TIMERX, event: Event) -> bool {
117 match event {
118 Event::Update => timer.read_upif(),
119 }
120}
121
122fn clear_pending<TIMERX: Instance>(timer: &mut TIMERX, event: Event) {
123 match event {
124 Event::Update => timer.clear_upif(),
125 }
126}
127
128/// A timer peripheral, tying it to the bus that clocks it.
129pub trait Instance: Enable + Reset {
130 /// The `CK_TIMERx` branch feeding this timer, taken from a frozen tree.
131 fn clk(clocks: &Clocks) -> Hertz;
132 /// Writes the prescaler, which reaches the counter on the next update event.
133 fn set_psc(&mut self, psc: u16);
134 /// Reads back the prescaler dividing the clock into counter ticks.
135 fn read_psc(&self) -> u16;
136 /// Writes the auto-reload value the counter rolls over at.
137 fn set_car(&mut self, car: u16);
138 /// Reads back the auto-reload value the counter rolls over at.
139 fn read_car(&self) -> u16;
140 /// Reads the counter, which advances on its own while the timer runs.
141 fn read_cnt(&self) -> u16;
142 /// Raises an update event in software, loading the shadowed dividers.
143 fn gen_update(&mut self);
144 /// Runs or halts the counter.
145 fn set_cen(&mut self, on: bool);
146 /// Restricts what counts as an update event to overflow/underflow — `UPG` no
147 /// longer raises `UPIF`, only the counter rolling over does.
148 fn set_ups(&mut self, on: bool);
149 /// Lets the update event through to the NVIC. The flag is raised either way.
150 fn set_upie(&mut self, on: bool);
151 /// Whether the update event reaches the NVIC.
152 fn read_upie(&self) -> bool;
153 /// Update flag — set by hardware on every rollover, never cleared by it.
154 fn read_upif(&self) -> bool;
155 /// Clears the update flag.
156 fn clear_upif(&mut self);
157 /// Produces a second handle to the same peripheral.
158 ///
159 /// # Safety
160 ///
161 /// The HAL's typestate rests on one handle meaning one configuration in
162 /// flight. Keeping two handles from contradicting each other is on the
163 /// caller — disjoint registers, or no reconfiguration through both.
164 #[must_use]
165 unsafe fn steal(&self) -> Self;
166}
167
168macro_rules! timer_instance {
169 ($($TIMERX:ty => $clk:ident,)+) => {
170 $(
171 impl Instance for $TIMERX {
172 #[inline]
173 fn clk(clocks: &Clocks) -> Hertz {
174 clocks.$clk()
175 }
176 #[inline]
177 fn set_psc(&mut self, psc: u16) {
178 self.psc().write(|w| w.psc().bits(psc));
179 }
180 #[inline]
181 fn read_psc(&self) -> u16 {
182 self.psc().read().psc().bits()
183 }
184 // The `CAR` writer is unsafe on TIMER2 only (unconstrained field
185 // in the SVD), safe on the other six; one macro body serves all.
186 #[allow(unused_unsafe)]
187 #[inline]
188 fn set_car(&mut self, car: u16) {
189 // SAFETY: every `u16` is a legal reload value in counting mode.
190 self.car().write(|w| unsafe { w.car().bits(car) });
191 }
192 #[inline]
193 fn read_car(&self) -> u16 {
194 self.car().read().car().bits()
195 }
196 #[inline]
197 fn read_cnt(&self) -> u16 {
198 self.cnt().read().cnt().bits()
199 }
200 #[inline]
201 fn gen_update(&mut self) {
202 self.swevg().write(|w| w.upg().set_bit());
203 }
204 #[inline]
205 fn set_cen(&mut self, on: bool) {
206 self.ctl0().modify(|_, w| w.cen().bit(on));
207 }
208 #[inline]
209 fn set_ups(&mut self, on: bool) {
210 self.ctl0().modify(|_, w| w.ups().bit(on));
211 }
212 #[inline]
213 fn set_upie(&mut self, on: bool) {
214 self.dmainten().modify(|_, w| w.upie().bit(on));
215 }
216 #[inline]
217 fn read_upie(&self) -> bool {
218 self.dmainten().read().upie().bit_is_set()
219 }
220 #[inline]
221 fn read_upif(&self) -> bool {
222 self.intf().read().upif().bit_is_set()
223 }
224 // In `INTF` zero clears and one leaves alone, and its reset value
225 // is zero — so `write` would clear every flag it does not name.
226 #[inline]
227 fn clear_upif(&mut self) {
228 self.intf().modify(|_, w| w.upif().clear());
229 }
230 unsafe fn steal(&self) -> Self {
231 // SAFETY: forwarded — this method's caller takes on the PAC's
232 // contract along with its own.
233 unsafe { Self::steal() }
234 }
235 }
236 )+
237 };
238}
239
240timer_instance! {
241 pac::Timer2 => pclk1_tim,
242 pac::Timer5 => pclk1_tim,
243 pac::Timer13 => pclk1_tim,
244 pac::Timer0 => pclk2_tim,
245 pac::Timer15 => pclk2_tim,
246 pac::Timer16 => pclk2_tim,
247}
248
249// TIMER14 is the one peripheral whose presence the flash code does not decide: it
250// is absent from the 20- and 24-pin parts even at 64K (datasheet Table 1-1), so the
251// gate comes from the part's own row in build.rs. Its every impl is gated, not just
252// the pin table — the PAC has the register block regardless, and a timer needs no
253// pins, so ungated it would configure silicon that isn't there.
254#[cfg(has_timer14)]
255timer_instance! {
256 pac::Timer14 => pclk2_tim,
257}
258
259/// A stopped timer, holding the peripheral and the frequency feeding it.
260///
261/// Clocked and reset on construction, but the counter is not running.
262pub struct Timer<TIMERX> {
263 timer: TIMERX,
264 clk: Hertz,
265}
266
267impl<TIMERX: Instance> Timer<TIMERX> {
268 /// Returns the peripheral with its clock stopped.
269 pub fn release(self, rcu: &mut Rcu) -> TIMERX {
270 TIMERX::disable(rcu);
271 self.timer
272 }
273
274 /// Starts the counter, which then rolls over every `car + 1` ticks of
275 /// `clk / (psc + 1)`.
276 ///
277 /// The dividers reach the counter before it runs, so the first
278 /// [`wait`](CountDownTimer::wait) already measures the full interval.
279 pub fn start(mut self, psc: u16, car: u16) -> CountDownTimer<TIMERX> {
280 start_counter(&mut self.timer, psc, car);
281 CountDownTimer {
282 timer: self.timer,
283 clk: self.clk,
284 }
285 }
286 /// Starts the counter, which then rolls over once per `interval`.
287 ///
288 /// Any scale works with no conversion at the call site — `5.secs()`,
289 /// `500.millis()`, `100.micros()`. Truncating, so the realised interval is at
290 /// most one prescaler cycle short. Intervals past what the 16-bit dividers
291 /// span (just under a minute at 72 MHz) saturate; zero becomes one tick.
292 pub fn start_interval<const NOM: u64, const DENOM: u64>(
293 self,
294 interval: Duration<u32, NOM, DENOM>,
295 ) -> CountDownTimer<TIMERX> {
296 let (psc, car) = dividers(interval_to_ticks(interval, self.clk));
297 self.start(psc, car)
298 }
299 /// Hands the timer over to blocking delays; every [`delay`](Delay::delay)
300 /// sets up its own interval and tears it down again.
301 pub fn into_delay(self) -> Delay<TIMERX> {
302 Delay {
303 timer: self.timer,
304 clk: self.clk,
305 }
306 }
307 /// Hands the timer over to PWM and starts it on the given period.
308 ///
309 /// The counter cycle is shared by every channel, and `car + 1` is also their
310 /// duty resolution: a larger reload buys finer steps at a lower frequency.
311 pub fn into_pwm(mut self, psc: u16, car: u16) -> Pwm<TIMERX> {
312 start_counter(&mut self.timer, psc, car);
313 Pwm {
314 timer: self.timer,
315 clk: self.clk,
316 channels: 0,
317 }
318 }
319 /// Hands the timer over to PWM, taking the period as a duration.
320 ///
321 /// Splits it like [`start_interval`](Self::start_interval), keeping the
322 /// reload large — here that is what leaves the duty the most steps.
323 pub fn into_pwm_interval<const NOM: u64, const DENOM: u64>(
324 self,
325 interval: Duration<u32, NOM, DENOM>,
326 ) -> Pwm<TIMERX> {
327 let (psc, car) = dividers(interval_to_ticks(interval, self.clk));
328 self.into_pwm(psc, car)
329 }
330 /// Sets the counter free running and hands out the input capture role.
331 ///
332 /// Only the prescaler is a choice: it trades resolution against the longest
333 /// interval that still fits between two rollovers. The reload is pinned to
334 /// the maximum.
335 pub fn into_capture(mut self, psc: u16) -> Capture<TIMERX> {
336 start_counter(&mut self.timer, psc, u16::MAX);
337 Capture {
338 timer: self.timer,
339 clk: self.clk,
340 channels: 0,
341 }
342 }
343}
344
345/// A running timer, counting down the interval [`Timer::start`] was given.
346///
347/// Free-running: the counter reloads and starts over on every rollover, so the
348/// interval repeats until the timer is stopped.
349pub struct CountDownTimer<TIMERX> {
350 timer: TIMERX,
351 clk: Hertz,
352}
353
354impl<TIMERX: Instance> CountDownTimer<TIMERX> {
355 /// Returns the current counter value, in timer ticks.
356 ///
357 /// Says where inside the current interval the timer is, not how many
358 /// intervals passed. One tick is `psc() + 1` cycles of the timer clock.
359 pub fn cnt(&self) -> u16 {
360 self.timer.read_cnt()
361 }
362 /// Returns the value the counter rolls over at, in timer ticks.
363 ///
364 /// Read back from the hardware, so it holds for a raw
365 /// [`start`](Timer::start) too. One interval is `car() + 1` ticks: `cnt()`
366 /// reaching this value is the last tick before a rollover, not the rollover.
367 pub fn car(&self) -> u16 {
368 self.timer.read_car()
369 }
370 /// Returns the prescaler the counter is running on.
371 ///
372 /// One tick is `psc() + 1` cycles of the timer clock — what turns a
373 /// [`cnt`](Self::cnt) reading into time. Read back from the hardware.
374 pub fn psc(&self) -> u16 {
375 self.timer.read_psc()
376 }
377 /// Returns how far into the current interval the counter is, as a duration.
378 ///
379 /// Restarts from zero at every rollover and never exceeds one interval;
380 /// counting intervals is the caller's business. The scale comes from the
381 /// binding (`let t: MillisDuration = timer.elapsed();`) — coarser than one
382 /// tick floors to zero, finer than `u32` spans saturates. Resolution is one
383 /// tick.
384 pub fn elapsed<const NOM: u64, const DENOM: u64>(&self) -> Duration<u32, NOM, DENOM> {
385 ticks_to_interval(self.cnt(), self.psc(), self.clk)
386 }
387
388 /// Lets `event` raise an interrupt. Unmasking the line in the NVIC is the
389 /// caller's.
390 pub fn listen(&mut self, event: Event) {
391 set_listening(&mut self.timer, event, true);
392 }
393 /// Stops `event` from raising an interrupt. Leaves the NVIC alone.
394 pub fn unlisten(&mut self, event: Event) {
395 set_listening(&mut self.timer, event, false);
396 }
397 /// Whether `event` reaches the NVIC.
398 pub fn is_listening(&self, event: Event) -> bool {
399 is_listening(&self.timer, event)
400 }
401 /// Whether the flag `event` raises is standing.
402 ///
403 /// The enable and the flag are independent: this reports rollovers whether
404 /// or not anything is listening for them.
405 pub fn is_pending(&self, event: Event) -> bool {
406 is_pending(&self.timer, event)
407 }
408 /// Clears the flag `event` raised.
409 ///
410 /// A handler must call this, first thing: the request is the flag being set,
411 /// and hardware never clears it, so returning with it still set re-enters
412 /// the handler at once and starves everything else.
413 pub fn clear_interrupt(&mut self, event: Event) {
414 clear_pending(&mut self.timer, event);
415 }
416
417 /// Blocks until the counter rolls over, then clears the update flag.
418 ///
419 /// Leaves the timer running, so calling this in a loop yields one full
420 /// interval per call.
421 pub fn wait(&mut self) {
422 wait_update(&mut self.timer);
423 }
424
425 /// Halts the counter, stops listening and hands the timer back in its
426 /// stopped form.
427 ///
428 /// The counter keeps its current value; a later [`start`](Timer::start)
429 /// reloads the dividers and restarts from zero.
430 pub fn stop(mut self) -> Timer<TIMERX> {
431 self.unlisten(Event::Update);
432 self.timer.set_cen(false);
433 Timer {
434 timer: self.timer,
435 clk: self.clk,
436 }
437 }
438 /// Halts the counter and returns the peripheral with its clock stopped,
439 /// skipping the stopped form.
440 pub fn release(self, rcu: &mut Rcu) -> TIMERX {
441 self.stop().release(rcu)
442 }
443}
444
445/// A timer given over to blocking delays.
446///
447/// Unlike [`CountDownTimer`] it promises no interval: each call configures the
448/// dividers, waits, and stops the counter again, so any length can be asked for
449/// at any time.
450pub struct Delay<TIMERX> {
451 timer: TIMERX,
452 clk: Hertz,
453}
454
455impl<TIMERX: Instance> Delay<TIMERX> {
456 /// Blocks for `interval`, in whatever scale the caller wrote it in.
457 ///
458 /// Rounding and the saturation ceiling are the same as in
459 /// [`Timer::start_interval`], the dividers being derived the same way.
460 pub fn delay<const NOM: u64, const DENOM: u64>(&mut self, interval: Duration<u32, NOM, DENOM>) {
461 let (psc, car) = dividers(interval_to_ticks(interval, self.clk));
462 start_counter(&mut self.timer, psc, car);
463 wait_update(&mut self.timer);
464 self.timer.set_cen(false);
465 }
466
467 /// Takes the timer back out of delay duty, stopped and ready to be started.
468 pub fn into_timer(self) -> Timer<TIMERX> {
469 Timer {
470 timer: self.timer,
471 clk: self.clk,
472 }
473 }
474
475 /// Returns the peripheral with its clock stopped.
476 pub fn release(self, rcu: &mut Rcu) -> TIMERX {
477 self.into_timer().release(rcu)
478 }
479}
480
481/// A timer running as the period behind one or more PWM channels.
482///
483/// Owns the counter the channels compare against: channels carry their own duty,
484/// the frequency they all share is set here.
485pub struct Pwm<TIMERX> {
486 timer: TIMERX,
487 clk: Hertz,
488 /// Channels handed out and not yet taken back.
489 channels: u8,
490}
491
492impl<TIMERX: Instance> Pwm<TIMERX> {
493 /// Configures one channel of this timer and hands it out on the given pin.
494 ///
495 /// Which channel it is follows from the pin — the silicon routes each pin to
496 /// one channel of one timer. The channel comes out configured but not
497 /// enabled, with no duty set, and holds the pin until
498 /// [`release_channel`](Self::release_channel) takes it back.
499 ///
500 /// Several pins can reach one channel (`TIMER2` channel 0 answers on `PA6`
501 /// and `PB4`), and handing over both yields two channels writing one compare
502 /// register: same signal on both pins, and the last duty written wins.
503 pub fn channel<PIN, const C: u8>(&mut self, pin: PIN) -> PwmChannel<TIMERX, PIN, C>
504 where
505 PIN: ChannelPin<TIMERX, C>,
506 TIMERX: PwmOps<C>,
507 {
508 self.timer.apply_pwm_mode();
509 self.channels += 1;
510 PwmChannel {
511 // SAFETY: each channel reaches its own compare register and its own
512 // bits of the shared ones — the obligation `steal` places on the
513 // caller.
514 timer: unsafe { self.timer.steal() },
515 pin,
516 }
517 }
518 /// Takes a channel back, disabled and no longer listening, and returns its
519 /// pin.
520 pub fn release_channel<PIN, const C: u8>(
521 &mut self,
522 mut channel: PwmChannel<TIMERX, PIN, C>,
523 ) -> PIN
524 where
525 PIN: ChannelPin<TIMERX, C>,
526 TIMERX: PwmOps<C>,
527 {
528 channel.unlisten();
529 channel.disable();
530 self.channels -= 1;
531 channel.pin
532 }
533
534 /// Lets `event` raise an interrupt.
535 ///
536 /// The counter's own event, shared by every channel: `Update` marks the
537 /// period boundary, where the duties written since the last one take
538 /// effect. Channels raise their own, through
539 /// [`PwmChannel::listen`]. Unmasking the line in the NVIC is the caller's.
540 pub fn listen(&mut self, event: Event) {
541 set_listening(&mut self.timer, event, true);
542 }
543 /// Stops `event` from raising an interrupt. Leaves the NVIC alone.
544 pub fn unlisten(&mut self, event: Event) {
545 set_listening(&mut self.timer, event, false);
546 }
547 /// Whether `event` reaches the NVIC.
548 pub fn is_listening(&self, event: Event) -> bool {
549 is_listening(&self.timer, event)
550 }
551 /// Whether the flag `event` raises is standing.
552 pub fn is_pending(&self, event: Event) -> bool {
553 is_pending(&self.timer, event)
554 }
555 /// Clears the flag `event` raised, which hardware never does on its own.
556 pub fn clear_interrupt(&mut self, event: Event) {
557 clear_pending(&mut self.timer, event);
558 }
559
560 /// Changes the period without disturbing the running counter.
561 ///
562 /// Channels keep the duty they were given **in ticks**, so a new reload moves
563 /// what fraction that is: half of a thousand ticks is all of five hundred.
564 /// Set the duties again, or scale them by the new
565 /// [`max_duty`](PwmChannel::max_duty). The prescaler reaches the counter at
566 /// the next update event, so the cycle in flight runs on the old one.
567 pub fn set_period(&mut self, psc: u16, car: u16) {
568 self.timer.set_psc(psc);
569 self.timer.set_car(car);
570 }
571 /// Changes the period, taking it as a duration.
572 ///
573 /// Splits it like [`into_pwm_interval`](Timer::into_pwm_interval).
574 pub fn set_period_interval<const NOM: u64, const DENOM: u64>(
575 &mut self,
576 interval: Duration<u32, NOM, DENOM>,
577 ) {
578 let (psc, car) = dividers(interval_to_ticks(interval, self.clk));
579 self.set_period(psc, car);
580 }
581
582 /// Halts the counter, stops listening and takes the timer back out of PWM
583 /// duty.
584 ///
585 /// # Panics
586 ///
587 /// If a channel is still out — hand each one back through
588 /// [`release_channel`](Self::release_channel) first.
589 pub fn into_timer(mut self) -> Timer<TIMERX> {
590 assert!(self.channels == 0, "PWM channels still handed out");
591 self.unlisten(Event::Update);
592 self.timer.set_cen(false);
593 Timer {
594 timer: self.timer,
595 clk: self.clk,
596 }
597 }
598 /// Halts the counter and returns the peripheral with its clock stopped,
599 /// skipping the stopped form.
600 ///
601 /// # Panics
602 ///
603 /// As for [`into_timer`](Self::into_timer).
604 pub fn release(self, rcu: &mut Rcu) -> TIMERX {
605 self.into_timer().release(rcu)
606 }
607 /// Same as [`release`](Self::release), but hands `self` back instead of
608 /// panicking.
609 ///
610 /// # Errors
611 ///
612 /// Returns `self` untouched while a channel is still out.
613 pub fn try_release(self, rcu: &mut Rcu) -> Result<TIMERX, Self> {
614 if self.channels == 0 {
615 Ok(self.release(rcu))
616 } else {
617 Err(self)
618 }
619 }
620}
621
622impl<TIMERX> Pwm<TIMERX>
623where
624 TIMERX: PrimaryOutput,
625{
626 /// Lets the channels reach their pins.
627 ///
628 /// Timers with a `CCHP` register keep their outputs behind this switch, and
629 /// it starts off — such a channel stays silent however it is configured until
630 /// this is called. Timers without the register need nothing.
631 pub fn enable_output(&mut self) {
632 self.timer.set_poen(true);
633 }
634 /// Cuts every channel off from its pin at once, keeping them configured.
635 pub fn disable_output(&mut self) {
636 self.timer.set_poen(false);
637 }
638}
639
640/// A free running timer whose channels timestamp edges on their pins.
641///
642/// The counter is only a time base: it runs to `u16::MAX` and wraps, while each
643/// channel latches the count when its edge arrives. Intervals are differences
644/// between latched values, so this role carries no period of its own.
645pub struct Capture<TIMERX> {
646 timer: TIMERX,
647 clk: Hertz,
648 /// Channels handed out and not yet taken back.
649 channels: u8,
650}
651
652impl<TIMERX: Instance> Capture<TIMERX> {
653 /// Points one channel of this timer at the given pin and hands it out.
654 ///
655 /// Which channel it is follows from the pin, as in [`Pwm::channel`]. The
656 /// channel comes out configured but not enabled, latches nothing until it is,
657 /// and holds the pin until [`release_channel`](Self::release_channel) takes
658 /// it back. The edge is set here; [`select_edge`](CaptureChannel::select_edge)
659 /// changes it later.
660 pub fn channel<PIN, const C: u8>(
661 &mut self,
662 pin: PIN,
663 edge: Edge,
664 ) -> CaptureChannel<TIMERX, PIN, C>
665 where
666 PIN: ChannelPin<TIMERX, C>,
667 TIMERX: CaptureOps<C>,
668 {
669 self.timer.apply_capture_mode();
670 self.timer.select_edge(edge);
671 self.channels += 1;
672 CaptureChannel {
673 // SAFETY: each channel reaches its own capture register and its own
674 // bits of the shared ones — the obligation `steal` places on the
675 // caller.
676 timer: unsafe { self.timer.steal() },
677 pin,
678 clk: self.clk,
679 }
680 }
681 /// Takes a channel back, disabled and no longer listening, and returns its
682 /// pin.
683 pub fn release_channel<PIN, const C: u8>(
684 &mut self,
685 mut channel: CaptureChannel<TIMERX, PIN, C>,
686 ) -> PIN
687 where
688 PIN: ChannelPin<TIMERX, C>,
689 TIMERX: CaptureOps<C>,
690 {
691 channel.unlisten();
692 channel.disable();
693 self.channels -= 1;
694 channel.pin
695 }
696
697 /// Lets `event` raise an interrupt.
698 ///
699 /// The time base's own event, shared by every channel. `Update` is what
700 /// extends the range here: the counter is only 16 bits wide, so an interval
701 /// longer than one cycle needs the rollovers counted alongside the
702 /// timestamps — [`interval`](CaptureChannel::interval) sees the latched
703 /// values alone and cannot know how many cycles passed between them.
704 /// Captures raise their own event, through [`CaptureChannel::listen`].
705 /// Unmasking the line in the NVIC is the caller's.
706 pub fn listen(&mut self, event: Event) {
707 set_listening(&mut self.timer, event, true);
708 }
709 /// Stops `event` from raising an interrupt. Leaves the NVIC alone.
710 pub fn unlisten(&mut self, event: Event) {
711 set_listening(&mut self.timer, event, false);
712 }
713 /// Whether `event` reaches the NVIC.
714 pub fn is_listening(&self, event: Event) -> bool {
715 is_listening(&self.timer, event)
716 }
717 /// Whether the flag `event` raises is standing.
718 pub fn is_pending(&self, event: Event) -> bool {
719 is_pending(&self.timer, event)
720 }
721 /// Clears the flag `event` raised, which hardware never does on its own.
722 pub fn clear_interrupt(&mut self, event: Event) {
723 clear_pending(&mut self.timer, event);
724 }
725
726 /// Halts the counter, stops listening and takes the timer back out of
727 /// capture duty.
728 ///
729 /// # Panics
730 ///
731 /// If a channel is still out — hand each one back through
732 /// [`release_channel`](Self::release_channel) first.
733 pub fn into_timer(mut self) -> Timer<TIMERX> {
734 assert!(self.channels == 0, "capture channels still handed out");
735 self.unlisten(Event::Update);
736 self.timer.set_cen(false);
737 Timer {
738 timer: self.timer,
739 clk: self.clk,
740 }
741 }
742 /// Halts the counter and returns the peripheral with its clock stopped,
743 /// skipping the stopped form.
744 ///
745 /// # Panics
746 ///
747 /// As for [`into_timer`](Self::into_timer).
748 pub fn release(self, rcu: &mut Rcu) -> TIMERX {
749 self.into_timer().release(rcu)
750 }
751 /// Same as [`release`](Self::release), but hands `self` back instead of
752 /// panicking.
753 ///
754 /// # Errors
755 ///
756 /// Returns `self` untouched while a channel is still out.
757 pub fn try_release(self, rcu: &mut Rcu) -> Result<TIMERX, Self> {
758 if self.channels == 0 {
759 Ok(self.release(rcu))
760 } else {
761 Err(self)
762 }
763 }
764}
765
766/// Blocking delays for portable drivers, delegating to [`Delay::delay`].
767///
768/// Resolution is one timer tick — around 20 ns at 48 MHz — so a finer request is
769/// served as a single tick. `delay_us`/`delay_ms` are the trait's own defaults,
770/// splitting long waits into chunks of at most `u32::MAX` nanoseconds, well
771/// inside what the dividers span.
772impl<TIMERX: Instance> DelayNs for Delay<TIMERX> {
773 fn delay_ns(&mut self, ns: u32) {
774 self.delay(NanosDuration::from_nanos(ns));
775 }
776}
777
778/// Entry point on the raw peripheral.
779pub trait TimerExt: Sized {
780 /// Clocks the peripheral, resets it, and records the clock feeding it.
781 ///
782 /// The counter is left stopped.
783 fn constrain(self, rcu: &mut Rcu) -> Timer<Self>;
784}
785
786impl<TIMERX: Instance> TimerExt for TIMERX {
787 fn constrain(self, rcu: &mut Rcu) -> Timer<Self> {
788 let clocks = rcu.clocks();
789 TIMERX::enable(rcu);
790 TIMERX::reset(rcu);
791 Timer {
792 timer: self,
793 clk: TIMERX::clk(&clocks),
794 }
795 }
796}
797
798/// The switch turning channel `C` on, whichever direction it points.
799///
800/// `CHxEN` releases the output on a compare channel and arms the latch on a
801/// capture one. Implemented for the timer/channel pairs that exist: `TIMER13`
802/// has channel 0 alone, `TIMER5` none at all.
803pub trait ChannelEnable<const C: u8>: Instance {
804 /// Enables or disables the channel, leaving its setup in place.
805 fn set_chxen(&mut self, on: bool);
806 /// Lets this channel's event through to the NVIC. The flag is raised either
807 /// way, and every channel shares the timer's one interrupt line.
808 fn set_chxie(&mut self, on: bool);
809 /// Whether this channel's event reaches the NVIC.
810 fn read_chxie(&self) -> bool;
811 /// Channel flag — a capture latched or a compare matched, depending on the
812 /// role the channel is in. Set by hardware, never cleared by it.
813 fn read_chxif(&self) -> bool;
814 /// Clears the channel flag.
815 fn clear_chxif(&mut self);
816}
817
818macro_rules! channel_enable {
819 {$($Timer:ty => [$($Ch:literal$(,)?)+]$(,)?)+} => {
820 paste::paste! { $($(impl ChannelEnable<$Ch> for $Timer {
821 fn set_chxen(&mut self, on: bool) {
822 self.chctl2().modify(|_, w| match on {
823 true => w.[<ch $Ch en>]().enabled(),
824 false => w.[<ch $Ch en>]().disabled(),
825 })
826 }
827 fn set_chxie(&mut self, on: bool) {
828 self.dmainten().modify(|_, w| w.[<ch $Ch ie>]().bit(on));
829 }
830 fn read_chxie(&self) -> bool {
831 self.dmainten().read().[<ch $Ch ie>]().bit_is_set()
832 }
833 fn read_chxif(&self) -> bool {
834 self.intf().read().[<ch $Ch if>]().bit_is_set()
835 }
836 // `INTF` is rc_w0, as for `UPIF`: `write` would clear the flags of
837 // every other channel along with this one.
838 fn clear_chxif(&mut self) {
839 self.intf().modify(|_, w| w.[<ch $Ch if>]().clear())
840 }
841 })+)+ }
842 };
843}
844
845channel_enable! {
846 pac::Timer0 => [0, 1, 2, 3],
847 pac::Timer2 => [0, 1, 2, 3],
848 pac::Timer13 => [0],
849 pac::Timer15 => [0],
850 pac::Timer16 => [0]
851}
852
853#[cfg(has_timer14)]
854channel_enable! {
855 pac::Timer14 => [0, 1]
856}
857
858/// Register operations on compare channel `C` of a timer.
859pub trait PwmOps<const C: u8>: ChannelEnable<C> {
860 /// Configures the channel as a PWM output and readies it for a duty value.
861 ///
862 /// Covers direction, compare mode and polarity at once: a channel in PWM mode
863 /// while still pointed at its input drives nothing.
864 fn apply_pwm_mode(&mut self);
865 /// Writes the compare value the channel switches its output at.
866 ///
867 /// The output stays active while the counter is below this value, so one
868 /// full period is `car() + 1` and duty is the ratio between the two.
869 fn set_chxcv(&mut self, cv: u16);
870}
871
872macro_rules! pwm {
873 {$($Timer:ty => [
874 $(
875 ($Ch:literal, $chctl_reg:ident)$(,)?
876 )+]$(,)?)+
877 } => {
878 paste::paste! { $($(impl PwmOps<$Ch> for $Timer {
879 fn apply_pwm_mode(&mut self) {
880 self.chctl2().modify(|_, w| w.[<ch $Ch p>]().not_inverted());
881 self.$chctl_reg().modify(|_, w| {
882 w.[<ch $Ch ms>]()
883 .output()
884 .[<ch $Ch comctl>]()
885 .pwm_mode0()
886 .[<ch $Ch comsen>]()
887 .enabled()
888 });
889 }
890 #[allow(unused_unsafe)]
891 fn set_chxcv(&mut self, cv: u16) {
892 // SAFETY: every `u16` is a legal compare value.
893 self.[<ch $Ch cv>]().write(|w| unsafe { w.[<ch $Ch val>]().bits(cv) });
894 }
895 })+)+ }
896 };
897}
898
899// Channels 0 and 1 live in `CHCTL0`, 2 and 3 in `CHCTL1`, which is the one name
900// that does not follow from the channel number.
901pwm! {
902 pac::Timer0 => [(0, chctl0_output), (1, chctl0_output),
903 (2, chctl1_output), (3, chctl1_output)],
904 pac::Timer2 => [(0, chctl0_output), (1, chctl0_output),
905 (2, chctl1_output), (3, chctl1_output)],
906 pac::Timer13 => [(0, chctl0_output)],
907 pac::Timer15 => [(0, chctl0_output)],
908 pac::Timer16 => [(0, chctl0_output)]
909}
910
911#[cfg(has_timer14)]
912pwm! {
913 pac::Timer14 => [(0, chctl0_output), (1, chctl0_output)]
914}
915
916/// The output switch shared by every channel of a timer that has one.
917///
918/// Only the timers carrying a `CCHP` register implement this: `TIMER0`,
919/// `TIMER15`, `TIMER16`, and `TIMER14` where the part has it. It sits above the
920/// per-channel enables —
921/// with it off, the channels stay configured and the counter keeps running
922/// while the pins show nothing.
923pub trait PrimaryOutput: Instance {
924 /// Enables or disables the outputs of all channels at once.
925 fn set_poen(&mut self, on: bool);
926}
927
928macro_rules! poen {
929 ($($Timer:ty$(,)?)+) => {
930 $(impl PrimaryOutput for $Timer {
931 fn set_poen(&mut self, on: bool) {
932 self.cchp().modify(|_, w| match on {
933 true => w.poen().enabled(),
934 false => w.poen().disabled(),
935 });
936 }
937 })+
938 };
939}
940
941poen!(pac::Timer0, pac::Timer15, pac::Timer16);
942#[cfg(has_timer14)]
943poen!(pac::Timer14);
944
945/// Marks a pin the silicon routes to channel `C` of `TIMERX`, in the right
946/// alternate function.
947pub trait ChannelPin<TIMERX, const C: u8> {}
948
949macro_rules! channel_pins {
950 ( $( $TIMERX:ty: $( $C:literal: [ $($(#[$cfg:meta])? $p:literal $n:literal : $af:literal),* $(,)? ] )* ),* $(,)? ) => {
951 $($($( $(#[$cfg])? impl ChannelPin<$TIMERX, $C> for Pin<$p, $n, Alternate<$af>> {} )*)*)*
952 };
953}
954
955// Complementary outputs (`CHx_ON`), break inputs and `ETI` share these same
956// pins at other alternate functions; only the plain compare outputs are listed.
957//
958// The `pads_ge_*` gates say the package bonds the pin at all, and match the ones in
959// `gpio::Parts`.
960channel_pins! {
961 pac::Timer0:
962 0: [ #[cfg(pads_ge_24)] 'A' 8:2 ]
963 1: [ 'A' 9:2 ]
964 2: [ 'A' 10:2 ]
965 3: [ #[cfg(pads_ge_lqfp32)] 'A' 11:2 ],
966 pac::Timer2:
967 0: [ 'A' 6:1, #[cfg(pads_ge_28)] 'B' 4:1 ]
968 1: [ 'A' 7:1, #[cfg(pads_ge_28)] 'B' 5:1 ]
969 2: [ #[cfg(pads_ge_24)] 'B' 0:1 ]
970 3: [ 'B' 1:1 ],
971 pac::Timer13:
972 0: [ 'A' 4:4, 'A' 7:4, 'B' 1:2 ],
973 pac::Timer15:
974 0: [ 'A' 6:5, #[cfg(pads_ge_qfn32)] 'B' 8:2 ],
975 pac::Timer16:
976 0: [ 'A' 7:5, #[cfg(pads_ge_48)] 'B' 9:2 ],
977}
978
979#[cfg(has_timer14)]
980channel_pins! {
981 pac::Timer14:
982 0: [ 'A' 2:0, #[cfg(pads_ge_48)] 'B' 14:1 ]
983 1: [ 'A' 3:0, #[cfg(pads_ge_48)] 'B' 15:1 ],
984}
985
986/// One PWM output of a timer, configured and ready to take a duty value.
987///
988/// Channels of one timer share the period (`PSC`/`CAR` belong to their common
989/// counter); duty is the channel's own.
990///
991/// Duties reach separate registers, but all the enables live in one: enabling a
992/// channel while another is enabled elsewhere — from an interrupt, say — can
993/// lose one of the writes.
994pub struct PwmChannel<TIMERX, PIN, const C: u8> {
995 timer: TIMERX,
996 pin: PIN,
997}
998
999impl<TIMERX: PwmOps<C>, PIN: ChannelPin<TIMERX, C>, const C: u8> PwmChannel<TIMERX, PIN, C> {
1000 /// Drives the pin from the comparison, keeping the duty already set.
1001 pub fn enable(&mut self) {
1002 self.timer.set_chxen(true);
1003 }
1004 /// Stops driving the pin, leaving the channel configured.
1005 pub fn disable(&mut self) {
1006 self.timer.set_chxen(false);
1007 }
1008
1009 /// Sets the duty, in timer ticks of the period.
1010 ///
1011 /// Active for `cv` ticks out of [`max_duty`](Self::max_duty): zero is a
1012 /// permanently inactive pin, `max_duty` and above a permanently active one.
1013 /// The value reaches the output at the next rollover, not mid-period.
1014 pub fn set_duty(&mut self, cv: u16) {
1015 self.timer.set_chxcv(cv);
1016 }
1017 /// Returns the duty that corresponds to a fully active output.
1018 ///
1019 /// The period the counter runs on, `car() + 1` ticks, which is also the
1020 /// resolution. A period spanning the whole counter reports one tick short,
1021 /// being the only value that does not fit `u16`.
1022 pub fn max_duty(&self) -> u16 {
1023 self.timer.read_car().saturating_add(1)
1024 }
1025
1026 /// Lets the compare match raise an interrupt.
1027 ///
1028 /// Fires at the point in the period where the output flips, not at the
1029 /// rollover — that one is [`CountDownTimer::listen`].
1030 ///
1031 /// The whole timer shares one NVIC line, so a handler serving several
1032 /// channels tells them apart by [`is_listening`](Self::is_listening) and
1033 /// [`is_pending`](Self::is_pending) together. The flag alone will not do:
1034 /// after reset an untouched channel compares against zero and raises its
1035 /// flag once per rollover. Unmasking the line is the caller's.
1036 pub fn listen(&mut self) {
1037 self.timer.set_chxie(true);
1038 }
1039 /// Stops the compare match from raising an interrupt. Leaves the NVIC alone.
1040 pub fn unlisten(&mut self) {
1041 self.timer.set_chxie(false);
1042 }
1043 /// Whether this channel's compare match reaches the NVIC.
1044 pub fn is_listening(&self) -> bool {
1045 self.timer.read_chxie()
1046 }
1047 /// Whether this channel's flag is raised.
1048 pub fn is_pending(&self) -> bool {
1049 self.timer.read_chxif()
1050 }
1051 /// Clears this channel's flag.
1052 ///
1053 /// A handler must call this: a compare match yields no value to consume, so
1054 /// unlike a capture there is nothing else that acknowledges it, and hardware
1055 /// never clears the flag on its own.
1056 pub fn clear_interrupt(&mut self) {
1057 self.timer.clear_chxif();
1058 }
1059}
1060
1061/// What can go wrong while reading a capture.
1062#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1063#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1064#[non_exhaustive]
1065pub enum Error {
1066 /// An edge landed on a value that had not been read yet (`CHxOF`).
1067 ///
1068 /// The register holds the newer timestamp and the older one is gone, so an
1069 /// interval measured across this is wrong rather than merely late.
1070 Overcapture,
1071}
1072
1073/// One capture input of a timer, configured and ready to be armed.
1074///
1075/// Channels of one timer share the time base (`PSC` belongs to their common
1076/// counter); the edge and the latched value are the channel's own.
1077///
1078/// Latching reaches separate registers, but all the enables live in one:
1079/// enabling a channel while another is enabled elsewhere — from an interrupt,
1080/// say — can lose one of the writes.
1081pub struct CaptureChannel<TIMERX, PIN, const C: u8> {
1082 timer: TIMERX,
1083 pin: PIN,
1084 clk: Hertz,
1085}
1086
1087impl<TIMERX: CaptureOps<C>, PIN: ChannelPin<TIMERX, C>, const C: u8>
1088 CaptureChannel<TIMERX, PIN, C>
1089{
1090 /// Arms the channel, from here on latching the counter on every edge.
1091 pub fn enable(&mut self) {
1092 self.timer.set_chxen(true);
1093 }
1094 /// Stops latching, leaving the channel configured and its last value intact.
1095 pub fn disable(&mut self) {
1096 self.timer.set_chxen(false);
1097 }
1098
1099 /// Changes which edge the channel latches on.
1100 ///
1101 /// Takes effect immediately, so an edge arriving during the switch belongs to
1102 /// whichever setting won the race; discard measurements spanning the change.
1103 pub fn select_edge(&mut self, edge: Edge) {
1104 self.timer.select_edge(edge);
1105 }
1106
1107 /// Lets a capture raise an interrupt.
1108 ///
1109 /// Turns waiting for an edge from a busy loop into a wake-up, and shrinks
1110 /// the window in which the next edge could overwrite an unread timestamp —
1111 /// see [`Error::Overcapture`].
1112 ///
1113 /// No separate clear: [`read`](Self::read) takes the flag down, being the
1114 /// same call a handler makes to collect the timestamp. The whole timer
1115 /// shares one NVIC line, so a handler serving several channels tells them
1116 /// apart by [`is_listening`](Self::is_listening) and
1117 /// [`is_pending`](Self::is_pending) together — the flag alone will not do,
1118 /// since an untouched channel still compares against zero after reset and
1119 /// raises its flag once per rollover. Unmasking the line is the caller's.
1120 pub fn listen(&mut self) {
1121 self.timer.set_chxie(true);
1122 }
1123 /// Stops captures from raising an interrupt. Leaves the NVIC alone.
1124 pub fn unlisten(&mut self) {
1125 self.timer.set_chxie(false);
1126 }
1127 /// Whether this channel's captures reach the NVIC.
1128 pub fn is_listening(&self) -> bool {
1129 self.timer.read_chxie()
1130 }
1131 /// Whether a timestamp is waiting to be read.
1132 pub fn is_pending(&self) -> bool {
1133 self.timer.read_chxif()
1134 }
1135
1136 /// Takes the timestamp of the last edge, if one has arrived.
1137 ///
1138 /// Returns [`WouldBlock`](nb::Error::WouldBlock) while no edge has been
1139 /// latched since the previous read, so it can be polled or waited on with
1140 /// [`nb::block!`]. Flags are cleared on the way out. The value is the counter
1141 /// at the moment of the edge, not an interval — those come from feeding two
1142 /// of these to [`interval`](Self::interval).
1143 ///
1144 /// # Errors
1145 ///
1146 /// [`Error::Overcapture`] when a further edge arrived before this read: the
1147 /// timestamp belongs to the later edge, the earlier one is lost. The next
1148 /// read is sound again.
1149 pub fn read(&mut self) -> nb::Result<u16, Error> {
1150 if !self.timer.read_chxif() {
1151 return Err(nb::Error::WouldBlock);
1152 }
1153 let cv = self.timer.read_chxcv();
1154 let lost = self.timer.read_chxof();
1155 // Hardware only raises these flags; left standing, `CHxIF` would report
1156 // the same edge for ever.
1157 self.timer.clear_chxif();
1158 if lost {
1159 self.timer.clear_chxof();
1160 Err(nb::Error::Other(Error::Overcapture))
1161 } else {
1162 Ok(cv)
1163 }
1164 }
1165
1166 /// Converts the span between two timestamps into a duration.
1167 ///
1168 /// Takes them in capture order and counts forward from the first, so a
1169 /// rollover in between costs nothing — the subtraction wraps exactly as the
1170 /// counter does. Spans longer than one counter cycle come back wrong; keep
1171 /// the prescaler large enough that the signal fits. The scale comes from the
1172 /// binding, as in [`elapsed`](CountDownTimer::elapsed).
1173 pub fn interval<const NOM: u64, const DENOM: u64>(
1174 &self,
1175 from: u16,
1176 to: u16,
1177 ) -> Duration<u32, NOM, DENOM> {
1178 ticks_to_interval(to.wrapping_sub(from), self.timer.read_psc(), self.clk)
1179 }
1180}
1181
1182/// Writing a duty cannot fail: the value goes straight into a compare register
1183/// the hardware always accepts.
1184impl<TIMERX: PwmOps<C>, PIN: ChannelPin<TIMERX, C>, const C: u8> ErrorType
1185 for PwmChannel<TIMERX, PIN, C>
1186{
1187 type Error = Infallible;
1188}
1189
1190/// Duty control for portable drivers, delegating to [`PwmChannel::set_duty`].
1191///
1192/// `set_duty_cycle_percent` and friends are the trait's own defaults over these
1193/// two, scaled against the period the timer currently runs on.
1194impl<TIMERX: PwmOps<C>, PIN: ChannelPin<TIMERX, C>, const C: u8> SetDutyCycle
1195 for PwmChannel<TIMERX, PIN, C>
1196{
1197 fn max_duty_cycle(&self) -> u16 {
1198 self.max_duty()
1199 }
1200 fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
1201 self.set_duty(duty);
1202 Ok(())
1203 }
1204}
1205
1206/// Which edge on the pin makes a channel take its snapshot.
1207///
1208/// Capturing on both edges is not offered — that encoding is reserved on every
1209/// timer of this part.
1210#[derive(Clone, Copy, PartialEq, Eq)]
1211#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1212#[allow(missing_docs)]
1213pub enum Edge {
1214 Rising,
1215 Falling,
1216}
1217
1218/// The input capture half of one channel, numbered by `C` like [`PwmOps`].
1219pub trait CaptureOps<const C: u8>: ChannelEnable<C> {
1220 /// Points the channel at its pin and readies it to latch the counter.
1221 ///
1222 /// Covers direction, input filter and capture prescaler at once: a channel
1223 /// still pointing at its comparator captures nothing.
1224 fn apply_capture_mode(&mut self);
1225 /// Chooses the edge the channel takes its snapshot on.
1226 fn select_edge(&mut self, edge: Edge);
1227 /// Reads the counter value the last edge latched.
1228 ///
1229 /// Says nothing about whether an edge arrived — the value means something
1230 /// only once [`read_chxif`](ChannelEnable::read_chxif) confirms a capture.
1231 fn read_chxcv(&self) -> u16;
1232 /// Overcapture flag — set when an edge lands on a value not yet read.
1233 fn read_chxof(&self) -> bool;
1234 /// Clears the overcapture flag.
1235 fn clear_chxof(&mut self);
1236}
1237
1238macro_rules! capture {
1239 {$($Timer:ty => [
1240 $(
1241 ($Ch:literal, $chctl_reg:ident $(, $chnp:ident)?)$(,)?
1242 )+]$(,)?)+
1243 } => {
1244 paste::paste! { $($(impl CaptureOps<$Ch> for $Timer {
1245 fn apply_capture_mode(&mut self) {
1246 // `CHxNP` exists only on channels with a complementary output;
1247 // channel 3 has neither.
1248 $(self.chctl2().modify(|_, w| w.$chnp().not_inverted());)?
1249 // `ci0` is the channel's own input on every channel — the PAC
1250 // names the variants relative to the channel, not by line number.
1251 self.$chctl_reg().modify(|_, w| {
1252 w.[<ch $Ch ms>]()
1253 .ci0()
1254 .[<ch $Ch capflt>]()
1255 .no_filter()
1256 .[<ch $Ch cappsc>]()
1257 .div1()
1258 })
1259 }
1260 fn select_edge(&mut self, edge: Edge) {
1261 self.chctl2().modify(|_, w| match edge {
1262 Edge::Rising => w.[<ch $Ch p>]().not_inverted(),
1263 Edge::Falling => w.[<ch $Ch p>]().inverted()
1264 })
1265 }
1266 fn read_chxcv(&self) -> u16 {
1267 self.[<ch $Ch cv>]().read().[<ch $Ch val>]().bits()
1268 }
1269 fn read_chxof(&self) -> bool {
1270 self.intf().read().[<ch $Ch of>]().bit_is_set()
1271 }
1272 fn clear_chxof(&mut self) {
1273 self.intf().modify(|_, w| w.[<ch $Ch of>]().clear())
1274 }
1275 })+)+ }
1276 };
1277}
1278
1279// As in `pwm!`, the `CHCTL0`/`CHCTL1` split is the one name the channel number
1280// does not give. `CHxNP` is passed where the channel has one; channel 3 does not.
1281capture! {
1282 pac::Timer0 => [(0, chctl0_input, ch0np), (1, chctl0_input, ch1np),
1283 (2, chctl1_input, ch2np), (3, chctl1_input)],
1284 pac::Timer2 => [(0, chctl0_input, ch0np), (1, chctl0_input, ch1np),
1285 (2, chctl1_input, ch2np), (3, chctl1_input)],
1286 pac::Timer13 => [(0, chctl0_input, ch0np)],
1287 pac::Timer15 => [(0, chctl0_input, ch0np)],
1288 pac::Timer16 => [(0, chctl0_input, ch0np)]
1289}
1290
1291#[cfg(has_timer14)]
1292capture! {
1293 pac::Timer14 => [(0, chctl0_input, ch0np), (1, chctl0_input, ch1np)]
1294}