1use crate::{
2 Mcu, Steal,
3 afio::{RemapMode, timer_remap::*},
4 pac::DBGMCU as DBG,
5 rcc,
6 time::Hertz,
7};
8
9pub use crate::common::timer::*;
10
11#[cfg(feature = "rtic")]
12pub mod monotonic;
13#[cfg(feature = "rtic")]
14pub use monotonic::*;
15pub mod syst;
16pub use syst::*;
17#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
18pub mod timer1;
19#[cfg(feature = "xl")]
20pub mod timer10;
21#[cfg(feature = "xl")]
22pub mod timer11;
23#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high",)))]
24pub mod timer12;
25#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high",)))]
26pub mod timer13;
27#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high",)))]
28pub mod timer14;
29#[cfg(feature = "stm32f100")]
30pub mod timer15;
31#[cfg(feature = "stm32f100")]
32pub mod timer16;
33#[cfg(feature = "stm32f100")]
34pub mod timer17;
35pub mod timer2;
36pub mod timer3;
37#[cfg(feature = "medium")]
38pub mod timer4;
39#[cfg(any(feature = "high", feature = "connectivity"))]
40pub mod timer5;
41#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity"))]
42pub mod timer6;
43#[cfg(any(
44 all(feature = "high", any(feature = "stm32f101", feature = "stm32f103")),
45 any(feature = "stm32f100", feature = "connectivity")
46))]
47pub mod timer7;
48#[cfg(all(feature = "stm32f103", feature = "high"))]
49pub mod timer8;
50#[cfg(feature = "xl")]
51pub mod timer9;
52
53pub trait Instance: rcc::Enable + rcc::Reset + rcc::BusTimerClock + GeneralTimer {}
54
55pub trait TimerInit<TIM> {
58 fn constrain(self, mcu: &mut Mcu) -> Timer<TIM>;
59}
60
61pub struct Timer<TIM> {
63 tim: TIM,
64 clk: Hertz,
65}
66
67impl<TIM: Instance + Steal> Timer<TIM> {
68 pub fn new(tim: TIM, mcu: &mut Mcu) -> Self {
70 mcu.rcc.enable(&tim);
72 mcu.rcc.reset(&tim);
73
74 Self {
75 clk: mcu.rcc.get_timer_clock(&tim),
76 tim,
77 }
78 }
79
80 pub fn counter<const FREQ: u32>(self) -> Counter<TIM, FREQ> {
82 FTimer::new(self.tim, self.clk).counter()
83 }
84
85 pub fn counter_ms(self) -> CounterMs<TIM> {
91 self.counter::<1_000>()
92 }
93
94 pub fn counter_us(self) -> CounterUs<TIM> {
98 self.counter::<1_000_000>()
99 }
100
101 pub fn counter_hz(self) -> CounterHz<TIM> {
103 CounterHz {
104 tim: self.tim,
105 clk: self.clk,
106 }
107 }
108
109 pub fn delay<const FREQ: u32>(self) -> Delay<TIM, FREQ> {
111 FTimer::new(self.tim, self.clk).delay()
112 }
113
114 pub fn delay_ms(self) -> DelayMs<TIM> {
120 self.delay::<1_000>()
121 }
122 pub fn delay_us(self) -> DelayUs<TIM> {
126 self.delay::<1_000_000>()
127 }
128
129 pub fn release(self) -> TIM {
130 self.tim
131 }
132
133 pub fn listen(&mut self, event: Event) {
138 self.tim.listen_interrupt(event, true);
139 }
140
141 pub fn clear_interrupt(&mut self, event: Event) {
146 self.tim.clear_interrupt_flag(event);
147 }
148
149 pub fn get_interrupt(&mut self) -> Event {
150 self.tim.get_interrupt_flag()
151 }
152
153 pub fn unlisten(&mut self, event: Event) {
155 self.tim.listen_interrupt(event, false);
156 }
157
158 pub fn stop_in_debug(&mut self, state: bool) {
160 self.tim.stop_in_debug(state);
161 }
162}
163
164impl<TIM: Instance + MasterTimer> Timer<TIM> {
165 pub fn set_master_mode(&mut self, mode: MasterMode) {
166 self.tim.master_mode(mode)
167 }
168}
169
170impl<TIM: Instance + TimerDirection> Timer<TIM> {
171 pub fn set_count_direction(&mut self, dir: CountDirection) {
172 self.tim.set_count_direction(dir);
173 }
174}
175
176impl<'a, TIM: Instance + TimerWithPwm1Ch + Steal + 'a> Timer<TIM> {
179 pub fn into_pwm1<REMAP: RemapMode<TIM>>(
180 mut self,
181 _pin: impl TimCh1Pin<REMAP>,
182 update_freq: Hertz,
183 preload: bool,
184 mcu: &mut Mcu,
185 ) -> (PwmTimer<TIM>, impl PwmChannel + 'a) {
186 REMAP::remap(&mut mcu.afio);
187 self.tim.enable_preload(preload);
188 self.tim.config_freq(self.clk, update_freq);
189
190 let c1 = PwmChannel1::new(unsafe { self.tim.steal() });
191 let t = PwmTimer::new(self.tim, self.clk);
192 (t, c1)
193 }
194}
195
196impl<'a, TIM: Instance + TimerWithPwm2Ch + Steal + 'a> Timer<TIM> {
197 pub fn into_pwm2<REMAP: RemapMode<TIM>>(
198 mut self,
199 pins: (Option<impl TimCh1Pin<REMAP>>, Option<impl TimCh2Pin<REMAP>>),
200 update_freq: Hertz,
201 preload: bool,
202 mcu: &mut Mcu,
203 ) -> (
204 PwmTimer<TIM>,
205 Option<impl PwmChannel + 'a>,
206 Option<impl PwmChannel + 'a>,
207 ) {
208 REMAP::remap(&mut mcu.afio);
209 self.tim.enable_preload(preload);
210 self.tim.config_freq(self.clk, update_freq);
211
212 let c1 = pins
213 .0
214 .map(|_| PwmChannel1::new(unsafe { self.tim.steal() }));
215 let c2 = pins
216 .1
217 .map(|_| PwmChannel2::new(unsafe { self.tim.steal() }));
218 let t = PwmTimer::new(self.tim, self.clk);
219 (t, c1, c2)
220 }
221}
222
223impl<'a, TIM: Instance + TimerWithPwm4Ch + Steal + 'a> Timer<TIM> {
224 pub fn into_pwm4<REMAP: RemapMode<TIM>>(
225 mut self,
226 pins: (
227 Option<impl TimCh1Pin<REMAP>>,
228 Option<impl TimCh2Pin<REMAP>>,
229 Option<impl TimCh3Pin<REMAP>>,
230 Option<impl TimCh4Pin<REMAP>>,
231 ),
232 update_freq: Hertz,
233 preload: bool,
234 mcu: &mut Mcu,
235 ) -> (
236 PwmTimer<TIM>,
237 Option<impl PwmChannel + 'a>,
238 Option<impl PwmChannel + 'a>,
239 Option<impl PwmChannel + 'a>,
240 Option<impl PwmChannel + 'a>,
241 ) {
242 REMAP::remap(&mut mcu.afio);
243 self.tim.enable_preload(preload);
244 self.tim.config_freq(self.clk, update_freq);
245
246 let c1 = pins
247 .0
248 .map(|_| PwmChannel1::new(unsafe { self.tim.steal() }));
249 let c2 = pins
250 .1
251 .map(|_| PwmChannel2::new(unsafe { self.tim.steal() }));
252 let c3 = pins
253 .2
254 .map(|_| PwmChannel3::new(unsafe { self.tim.steal() }));
255 let c4 = pins
256 .3
257 .map(|_| PwmChannel4::new(unsafe { self.tim.steal() }));
258 let t = PwmTimer::new(self.tim, self.clk);
259 (t, c1, c2, c3, c4)
260 }
261}
262
263pub fn destroy_counter_hz<TIM: GeneralTimer>(mut counter: CounterHz<TIM>) -> Timer<TIM> {
266 counter.tim.reset_config();
268 Timer {
269 tim: counter.tim,
270 clk: counter.clk,
271 }
272}
273
274#[cfg(feature = "rtic")]
275pub fn destroy_mono_timer<TIM: GeneralTimer, const FREQ: u32>(
276 mut timer: MonoTimer<TIM, FREQ>,
277) -> FTimer<TIM, FREQ> {
278 timer.tim.reset_config();
279 timer.timer
280}
281
282#[derive(Clone, Copy, Debug, PartialEq, Eq)]
285#[repr(u8)]
286pub enum Ocm {
287 Frozen = 0,
288 ActiveOnMatch = 1,
289 InactiveOnMatch = 2,
290 Toggle = 3,
291 ForceInactive = 4,
292 ForceActive = 5,
293 PwmMode1 = 6,
294 PwmMode2 = 7,
295}
296
297impl From<PwmMode> for Ocm {
298 fn from(value: PwmMode) -> Self {
299 match value {
300 PwmMode::Mode1 => Ocm::PwmMode1,
301 PwmMode::Mode2 => Ocm::PwmMode2,
302 }
303 }
304}
305
306const fn compute_prescaler_arr(timer_clk: u32, update_freq: u32) -> (u32, u32) {
309 let ticks = timer_clk / update_freq;
310 let prescaler = (ticks - 1) / (1 << 16);
311 let arr = ticks / (prescaler + 1) - 1;
312 (prescaler, arr)
313}