nrf52_hal_common/
delay.rs

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