1use cast::u32;
4use cortex_m::asm;
5use cortex_m::peripheral::syst::SystClkSource;
6use cortex_m::peripheral::SYST;
7
8use crate::hal::blocking::delay::{DelayMs, DelayUs};
9use crate::rcc::Clocks;
10use crate::time::Hertz;
11
12pub struct Delay {
14 clocks: Clocks,
15 syst: SYST,
16}
17
18impl Delay {
19 pub fn new(mut syst: SYST, clocks: Clocks) -> Self {
21 syst.set_clock_source(SystClkSource::Core);
22
23 Delay { syst, clocks }
24 }
25
26 pub fn free(self) -> SYST {
28 self.syst
29 }
30}
31
32impl 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(u32(ms));
42 }
43}
44
45impl DelayMs<u8> for Delay {
46 fn delay_ms(&mut self, ms: u8) {
47 self.delay_ms(u32(ms));
48 }
49}
50
51impl DelayUs<u32> for Delay {
52 fn delay_us(&mut self, us: u32) {
53 const MAX_RVR: u32 = 0x00FF_FFFF;
55
56 let mut total_rvr = us * (self.clocks.hclk().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 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(u32(us))
82 }
83}
84
85impl DelayUs<u8> for Delay {
86 fn delay_us(&mut self, us: u8) {
87 self.delay_us(u32(us))
88 }
89}
90
91#[derive(Clone, Copy)]
93pub struct DelayCM {
94 sysclk: Hertz,
95}
96
97impl DelayCM {
98 pub fn new(clocks: Clocks) -> Self {
100 DelayCM {
101 sysclk: clocks.sysclk(),
102 }
103 }
104
105 pub unsafe fn new_unchecked(sysclk: Hertz) -> Self {
110 DelayCM { sysclk }
111 }
112}
113
114impl DelayMs<u32> for DelayCM {
115 fn delay_ms(&mut self, ms: u32) {
116 self.delay_us(ms * 1_000);
117 }
118}
119
120impl DelayMs<u16> for DelayCM {
121 fn delay_ms(&mut self, ms: u16) {
122 self.delay_ms(u32(ms));
123 }
124}
125
126impl DelayMs<u8> for DelayCM {
127 fn delay_ms(&mut self, ms: u8) {
128 self.delay_ms(u32(ms));
129 }
130}
131
132impl DelayUs<u32> for DelayCM {
133 fn delay_us(&mut self, us: u32) {
134 let ticks = self.sysclk.raw() / 1_000_000;
136
137 asm::delay(ticks * us);
138 }
139}
140
141impl DelayUs<u16> for DelayCM {
142 fn delay_us(&mut self, us: u16) {
143 self.delay_us(u32(us))
144 }
145}
146
147impl DelayUs<u8> for DelayCM {
148 fn delay_us(&mut self, us: u8) {
149 self.delay_us(u32(us))
150 }
151}