Skip to main content

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}