atsam4_hal/
delay.rs

1//! Delays
2
3use cortex_m::peripheral::syst::SystClkSource;
4use cortex_m::peripheral::SYST;
5use fugit::HertzU32 as Hertz;
6pub use hal::blocking::delay::{DelayMs, DelayUs};
7
8use crate::clock::*;
9
10/// System timer (SysTick) as a delay provider
11pub struct Delay {
12    sysclock: Hertz,
13    syst: SYST,
14}
15
16impl Delay {
17    /// Configures the system timer (SysTick) as a delay provider
18    pub fn new(mut syst: SYST) -> Self {
19        syst.set_clock_source(SystClkSource::Core);
20
21        Delay {
22            syst,
23            sysclock: get_master_clock_frequency(),
24        }
25    }
26
27    /// Releases the system timer (SysTick) resource
28    pub fn free(self) -> SYST {
29        self.syst
30    }
31}
32
33impl DelayMs<u32> for Delay {
34    fn delay_ms(&mut self, ms: u32) {
35        self.delay_us(ms * 1_000);
36    }
37}
38
39impl DelayMs<u16> for Delay {
40    fn delay_ms(&mut self, ms: u16) {
41        self.delay_ms(ms as u32);
42    }
43}
44
45impl DelayMs<u8> for Delay {
46    fn delay_ms(&mut self, ms: u8) {
47        self.delay_ms(ms as u32);
48    }
49}
50
51impl DelayUs<u32> for Delay {
52    fn delay_us(&mut self, us: u32) {
53        // The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
54        const MAX_RVR: u32 = 0x00FF_FFFF;
55
56        let mut total_rvr = us * (self.sysclock.raw() / 1_000_000);
57
58        while total_rvr != 0 {
59            let current_rvr = if total_rvr <= MAX_RVR {
60                total_rvr
61            } else {
62                MAX_RVR
63            };
64
65            self.syst.set_reload(current_rvr);
66            self.syst.clear_current();
67            self.syst.enable_counter();
68
69            // Update the tracking variable while we are waiting...
70            total_rvr -= current_rvr;
71
72            while !self.syst.has_wrapped() {}
73
74            self.syst.disable_counter();
75        }
76    }
77}
78
79impl DelayUs<u16> for Delay {
80    fn delay_us(&mut self, us: u16) {
81        self.delay_us(us as u32)
82    }
83}
84
85impl DelayUs<u8> for Delay {
86    fn delay_us(&mut self, us: u8) {
87        self.delay_us(us as u32)
88    }
89}