stm32g0xx_hal/timer/
delay.rs1use core::cmp;
3use cortex_m::peripheral::{syst::SystClkSource, SYST};
4use fugit::ExtU32;
5use hal::blocking::delay::{DelayMs, DelayUs};
6
7use crate::rcc::*;
8use crate::stm32::*;
9use crate::time::{Hertz, MicroSecond};
10
11pub struct Delay<TIM> {
13 clk: Hertz,
14 tim: TIM,
15}
16
17pub trait DelayExt<TIM> {
18 fn delay(self, rcc: &mut Rcc) -> Delay<TIM>;
19}
20
21impl Delay<SYST> {
22 pub fn syst(mut syst: SYST, rcc: &Rcc) -> Self {
24 let clk = match syst.get_clock_source() {
25 SystClkSource::Core => rcc.clocks.ahb_clk,
26 SystClkSource::External => rcc.clocks.core_clk,
27 };
28 Delay { tim: syst, clk }
29 }
30
31 pub fn delay(&mut self, delay: MicroSecond) {
32 let mut cycles = crate::time::cycles(delay, self.clk);
33 while cycles > 0 {
34 let reload = cmp::min(cycles, 0x00ff_ffff);
35 cycles -= reload;
36 self.tim.set_reload(reload);
37 self.tim.clear_current();
38 self.tim.enable_counter();
39 while !self.tim.has_wrapped() {}
40 self.tim.disable_counter();
41 }
42 }
43
44 pub fn release(self) -> SYST {
46 self.tim
47 }
48}
49
50impl DelayUs<u32> for Delay<SYST> {
51 fn delay_us(&mut self, us: u32) {
52 self.delay(us.micros())
53 }
54}
55
56impl DelayUs<u16> for Delay<SYST> {
57 fn delay_us(&mut self, us: u16) {
58 self.delay_us(us as u32)
59 }
60}
61
62impl DelayUs<u8> for Delay<SYST> {
63 fn delay_us(&mut self, us: u8) {
64 self.delay_us(us as u32)
65 }
66}
67
68impl DelayMs<u32> for Delay<SYST> {
69 fn delay_ms(&mut self, ms: u32) {
70 self.delay_us(ms.saturating_mul(1_000));
71 }
72}
73
74impl DelayMs<u16> for Delay<SYST> {
75 fn delay_ms(&mut self, ms: u16) {
76 self.delay_ms(ms as u32);
77 }
78}
79
80impl DelayMs<u8> for Delay<SYST> {
81 fn delay_ms(&mut self, ms: u8) {
82 self.delay_ms(ms as u32);
83 }
84}
85
86impl DelayExt<SYST> for SYST {
87 fn delay(self, rcc: &mut Rcc) -> Delay<SYST> {
88 Delay::syst(self, rcc)
89 }
90}
91
92macro_rules! delays {
93 ($($TIM:ident: $tim:ident,)+) => {
94 $(
95 impl Delay<$TIM> {
96 pub fn $tim(tim: $TIM, rcc: &mut Rcc) -> Self {
98 $TIM::enable(rcc);
99 $TIM::reset(rcc);
100
101 Delay {
102 tim,
103 clk: rcc.clocks.apb_tim_clk,
104 }
105 }
106
107 pub fn delay(&mut self, delay: MicroSecond) {
108 let mut cycles = crate::time::cycles(delay, self.clk);
109 while cycles > 0 {
110 let reload = cmp::min(cycles, 0xffff);
111 cycles -= reload;
112 self.tim.arr.write(|w| unsafe { w.bits(reload) });
113 self.tim.cnt.reset();
114 self.tim.cr1.modify(|_, w| w.cen().set_bit().urs().set_bit());
115 while self.tim.sr.read().uif().bit_is_clear() {}
116 self.tim.sr.modify(|_, w| w.uif().clear_bit());
117 self.tim.cr1.modify(|_, w| w.cen().clear_bit());
118 }
119 }
120
121 pub fn release(self) -> $TIM {
122 self.tim
123 }
124 }
125
126 impl DelayUs<u32> for Delay<$TIM> {
127 fn delay_us(&mut self, us: u32) {
128 self.delay(us.micros())
129 }
130 }
131
132 impl DelayUs<u16> for Delay<$TIM> {
133 fn delay_us(&mut self, us: u16) {
134 self.delay_us(us as u32)
135 }
136 }
137
138 impl DelayUs<u8> for Delay<$TIM> {
139 fn delay_us(&mut self, us: u8) {
140 self.delay_us(us as u32)
141 }
142 }
143
144 impl DelayMs<u32> for Delay<$TIM> {
145 fn delay_ms(&mut self, ms: u32) {
146 self.delay_us(ms.saturating_mul(1_000));
147 }
148 }
149
150 impl DelayMs<u16> for Delay<$TIM> {
151 fn delay_ms(&mut self, ms: u16) {
152 self.delay_ms(ms as u32);
153 }
154 }
155
156 impl DelayMs<u8> for Delay<$TIM> {
157 fn delay_ms(&mut self, ms: u8) {
158 self.delay_ms(ms as u32);
159 }
160 }
161
162 impl DelayExt<$TIM> for $TIM {
163 fn delay(self, rcc: &mut Rcc) -> Delay<$TIM> {
164 Delay::$tim(self, rcc)
165 }
166 }
167 )+
168 }
169}
170
171delays! {
172 TIM1: tim1,
173 TIM3: tim3,
174 TIM14: tim14,
175 TIM16: tim16,
176 TIM17: tim17,
177}
178
179#[cfg(feature = "stm32g0x1")]
180delays! {
181 TIM2: tim2,
182}
183
184#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
185delays! {
186 TIM6: tim6,
187 TIM7: tim7,
188 TIM15: tim15,
189}