atsamd_hal/peripherals/timer/
common.rs1use core::convert::Infallible;
3use fugit::NanosDurationU32;
4
5use crate::ehal::delay::DelayNs;
6use crate::ehal_02::timer::{CountDown, Periodic};
7use crate::time::Nanoseconds;
8use crate::timer_params::TimerParams;
9use crate::timer_traits::InterruptDrivenTimer;
10
11use super::{Count16Reg, TimerCounter};
12
13pub trait Count16 {
17    fn count_16(&self) -> &Count16Reg;
18}
19
20impl<TC> InterruptDrivenTimer for TimerCounter<TC>
21where
22    TC: Count16,
23{
24    fn enable_interrupt(&mut self) {
29        self.tc.count_16().intenset().write(|w| w.ovf().set_bit());
30    }
31
32    fn start<T>(&mut self, timeout: T)
33    where
34        T: Into<NanosDurationU32>,
35    {
36        let params = TimerParams::new_ns(timeout.into(), self.freq);
37        self.start_timer(params.divider, params.check_cycles_u16());
38    }
39
40    fn wait(&mut self) -> nb::Result<(), Infallible> {
41        let count = self.tc.count_16();
42        if count.intflag().read().ovf().bit_is_set() {
43            count.intflag().modify(|_, w| w.ovf().set_bit());
45            Ok(())
46        } else {
47            Err(nb::Error::WouldBlock)
48        }
49    }
50
51    fn disable_interrupt(&mut self) {
56        self.tc.count_16().intenclr().write(|w| w.ovf().set_bit());
57    }
58}
59
60impl<TC> Periodic for TimerCounter<TC> {}
61impl<TC> CountDown for TimerCounter<TC>
62where
63    TC: Count16,
64{
65    type Time = Nanoseconds;
66
67    fn start<T>(&mut self, timeout: T)
68    where
69        T: Into<Self::Time>,
70    {
71        <Self as InterruptDrivenTimer>::start(self, timeout);
72    }
73
74    fn wait(&mut self) -> nb::Result<(), void::Void> {
75        nb::block! {
76            <Self as InterruptDrivenTimer>::wait(self)
77        }
78        .unwrap(); Ok(())
80    }
81}
82
83impl<TC> DelayNs for TimerCounter<TC>
84where
85    TC: Count16,
86{
87    fn delay_ns(&mut self, ns: u32) {
88        let ticks: u32 = (ns as u64 * self.freq.to_Hz() as u64 / 1_000_000_000_u64) as u32;
89        let params = TimerParams::new_from_ticks(ticks);
90
91        let mut cycles = params.cycles;
93        if cycles > u16::MAX as u32 {
94            self.start_timer(params.divider, u16::MAX);
95            while cycles > u16::MAX as u32 {
96                let _ = nb::block!(InterruptDrivenTimer::wait(self));
97                cycles -= u16::MAX as u32;
98            }
99        }
100
101        if cycles > 0 {
103            self.start_timer(params.divider, cycles as u16);
104            let _ = nb::block!(InterruptDrivenTimer::wait(self));
105        }
106
107        self.disable();
108    }
109}