1use 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
19pub struct Delay {
21 ticks_per_us: u32,
22 syst: SYST,
23}
24
25impl Delay {
26 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 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}