stm32l1xx_hal/
delay.rs

1//! Delays
2use crate::rcc::Clocks;
3use crate::time::MicroSeconds;
4use cast::u32;
5use cortex_m::peripheral::syst::SystClkSource;
6use cortex_m::peripheral::SYST;
7use hal::blocking::delay::{DelayMs, DelayUs};
8
9pub trait DelayExt {
10    fn delay(self, clocks: Clocks) -> Delay;
11}
12
13impl DelayExt for SYST {
14    fn delay(self, clocks: Clocks) -> Delay {
15        Delay::new(self, clocks)
16    }
17}
18
19/// System timer (SysTick) as a delay provider
20pub struct Delay {
21    ticks_per_us: u32,
22    syst: SYST,
23}
24
25impl Delay {
26    /// Configures the system timer (SysTick) as a delay provider
27    pub fn new(mut syst: SYST, clocks: Clocks) -> Self {
28        syst.set_clock_source(SystClkSource::Core);
29        let freq = clocks.sys_clk().0;
30        assert!(freq > 1_000_000_u32);
31        let ticks_per_us = freq / 1_000_000_u32;
32        Delay { syst, ticks_per_us }
33    }
34    pub fn delay<T>(&mut self, delay: T)
35    where
36        T: Into<MicroSeconds>,
37    {
38        self.delay_us(delay.into().0)
39    }
40
41    /// Releases the system timer (SysTick) resource
42    pub fn free(self) -> SYST {
43        self.syst
44    }
45}
46
47impl DelayMs<u32> for Delay {
48    fn delay_ms(&mut self, ms: u32) {
49        self.delay_us(ms * 1_000);
50    }
51}
52
53impl DelayMs<u16> for Delay {
54    fn delay_ms(&mut self, ms: u16) {
55        self.delay_ms(u32(ms));
56    }
57}
58
59impl DelayMs<u8> for Delay {
60    fn delay_ms(&mut self, ms: u8) {
61        self.delay_ms(u32(ms));
62    }
63}
64
65impl DelayUs<u32> for Delay {
66    fn delay_us(&mut self, us: u32) {
67        const MAX_RVR: u32 = 0x00FF_FFFF;
68        let mut total_rvr = self.ticks_per_us * us;
69        while total_rvr > 0 {
70            let current_rvr = if total_rvr <= MAX_RVR {
71                total_rvr
72            } else {
73                MAX_RVR
74            };
75            self.syst.set_reload(current_rvr);
76            self.syst.clear_current();
77            self.syst.enable_counter();
78            total_rvr -= current_rvr;
79            while !self.syst.has_wrapped() {}
80            self.syst.disable_counter();
81        }
82    }
83}
84
85impl DelayUs<u16> for Delay {
86    fn delay_us(&mut self, us: u16) {
87        self.delay_us(u32(us))
88    }
89}
90
91impl DelayUs<u8> for Delay {
92    fn delay_us(&mut self, us: u8) {
93        self.delay_us(u32(us))
94    }
95}