stm32f1_hal/timer/
mod.rs

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 + GeneralTimerExt {}
54
55// Traits ---------------------------------------------------------------------
56
57pub trait GeneralTimerExt: GeneralTimer {
58    fn enable_preload(&mut self, b: bool);
59}
60
61pub trait MasterTimer: GeneralTimerExt {
62    type Mms;
63    fn master_mode(&mut self, mode: Self::Mms);
64}
65
66// Initialize -----------------------------------------------------------------
67
68pub trait TimerInit<TIM> {
69    fn constrain(self, mcu: &mut Mcu) -> Timer<TIM>;
70}
71
72/// Timer wrapper
73pub struct Timer<TIM> {
74    tim: TIM,
75    clk: Hertz,
76}
77
78#[allow(private_bounds)]
79impl<TIM: Instance + Steal> Timer<TIM> {
80    /// Initialize timer
81    pub fn new(tim: TIM, mcu: &mut Mcu) -> Self {
82        // Enable and reset the timer peripheral
83        TIM::enable(&mut mcu.rcc);
84        TIM::reset(&mut mcu.rcc);
85
86        Self {
87            clk: TIM::timer_clock(&mcu.rcc.clocks),
88            tim,
89        }
90    }
91
92    /// Non-blocking [Counter] with custom fixed precision
93    pub fn counter<const FREQ: u32>(self) -> Counter<TIM, FREQ> {
94        FTimer::new(self.tim, self.clk).counter()
95    }
96
97    /// Non-blocking [Counter] with fixed precision of 1 ms (1 kHz sampling)
98    ///
99    /// Can wait from 2 ms to 65 sec for 16-bit timer and from 2 ms to 49 days for 32-bit timer.
100    ///
101    /// NOTE: don't use this if your system frequency more than 65 MHz
102    pub fn counter_ms(self) -> CounterMs<TIM> {
103        self.counter::<1_000>()
104    }
105
106    /// Non-blocking [Counter] with fixed precision of 1 μs (1 MHz sampling)
107    ///
108    /// Can wait from 2 μs to 65 ms for 16-bit timer and from 2 μs to 71 min for 32-bit timer.
109    pub fn counter_us(self) -> CounterUs<TIM> {
110        self.counter::<1_000_000>()
111    }
112
113    /// Non-blocking [Counter] with dynamic precision which uses `Hertz` as Duration units
114    pub fn counter_hz(self) -> CounterHz<TIM> {
115        CounterHz {
116            tim: self.tim,
117            clk: self.clk,
118        }
119    }
120
121    /// Blocking [Delay] with custom fixed precision
122    pub fn delay<const FREQ: u32>(self) -> Delay<TIM, FREQ> {
123        FTimer::new(self.tim, self.clk).delay()
124    }
125
126    /// Blocking [Delay] with fixed precision of 1 ms (1 kHz sampling)
127    ///
128    /// Can wait from 2 ms to 49 days.
129    ///
130    /// NOTE: don't use this if your system frequency more than 65 MHz
131    pub fn delay_ms(self) -> DelayMs<TIM> {
132        self.delay::<1_000>()
133    }
134    /// Blocking [Delay] with fixed precision of 1 μs (1 MHz sampling)
135    ///
136    /// Can wait from 2 μs to 71 min.
137    pub fn delay_us(self) -> DelayUs<TIM> {
138        self.delay::<1_000_000>()
139    }
140
141    pub fn release(self) -> TIM {
142        self.tim
143    }
144
145    /// Starts listening for an `event`
146    ///
147    /// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
148    /// receiving events.
149    pub fn listen(&mut self, event: Event) {
150        self.tim.listen_interrupt(event, true);
151    }
152
153    /// Clears interrupt associated with `event`.
154    ///
155    /// If the interrupt is not cleared, it will immediately retrigger after
156    /// the ISR has finished.
157    pub fn clear_interrupt(&mut self, event: Event) {
158        self.tim.clear_interrupt_flag(event);
159    }
160
161    pub fn get_interrupt(&mut self) -> Event {
162        self.tim.get_interrupt_flag()
163    }
164
165    /// Stops listening for an `event`
166    pub fn unlisten(&mut self, event: Event) {
167        self.tim.listen_interrupt(event, false);
168    }
169
170    /// Stopping timer in debug mode can cause troubles when sampling the signal
171    pub fn stop_in_debug(&mut self, state: bool) {
172        self.tim.stop_in_debug(state);
173    }
174}
175
176impl<TIM: Instance + MasterTimer> Timer<TIM> {
177    pub fn set_master_mode(&mut self, mode: TIM::Mms) {
178        self.tim.master_mode(mode)
179    }
180}
181
182impl<TIM: Instance + TimerDirection> Timer<TIM> {
183    pub fn set_count_direction(&mut self, dir: CountDirection) {
184        self.tim.set_count_direction(dir);
185    }
186}
187
188// Initialize PWM -------------------------------------------------------------
189
190#[allow(private_bounds)]
191impl<TIM: Instance + TimerWithPwm1Ch + Steal> Timer<TIM> {
192    pub fn into_pwm1<REMAP: RemapMode<TIM>>(
193        mut self,
194        _pin: impl TimCh1Pin<REMAP>,
195        preload: bool,
196        mcu: &mut Mcu,
197    ) -> (PwmTimer<TIM>, impl PwmChannel) {
198        REMAP::remap(&mut mcu.afio);
199        self.tim.enable_preload(preload);
200
201        let c1 = PwmChannel1::new(unsafe { self.tim.steal() });
202        let t = PwmTimer::new(self.tim, self.clk);
203        (t, c1)
204    }
205}
206
207#[allow(private_bounds)]
208impl<TIM: Instance + TimerWithPwm2Ch + Steal> Timer<TIM> {
209    pub fn into_pwm2<REMAP: RemapMode<TIM>>(
210        mut self,
211        pins: (Option<impl TimCh1Pin<REMAP>>, Option<impl TimCh2Pin<REMAP>>),
212        preload: bool,
213        mcu: &mut Mcu,
214    ) -> (
215        PwmTimer<TIM>,
216        Option<impl PwmChannel>,
217        Option<impl PwmChannel>,
218    ) {
219        REMAP::remap(&mut mcu.afio);
220        self.tim.enable_preload(preload);
221
222        let c1 = pins
223            .0
224            .map(|_| PwmChannel1::new(unsafe { self.tim.steal() }));
225        let c2 = pins
226            .1
227            .map(|_| PwmChannel2::new(unsafe { self.tim.steal() }));
228        let t = PwmTimer::new(self.tim, self.clk);
229        (t, c1, c2)
230    }
231}
232
233#[allow(private_bounds)]
234impl<TIM: Instance + TimerWithPwm4Ch + Steal> Timer<TIM> {
235    pub fn into_pwm4<REMAP: RemapMode<TIM>>(
236        mut self,
237        pins: (
238            Option<impl TimCh1Pin<REMAP>>,
239            Option<impl TimCh2Pin<REMAP>>,
240            Option<impl TimCh3Pin<REMAP>>,
241            Option<impl TimCh4Pin<REMAP>>,
242        ),
243        preload: bool,
244        mcu: &mut Mcu,
245    ) -> (
246        PwmTimer<TIM>,
247        Option<impl PwmChannel>,
248        Option<impl PwmChannel>,
249        Option<impl PwmChannel>,
250        Option<impl PwmChannel>,
251    ) {
252        REMAP::remap(&mut mcu.afio);
253        self.tim.enable_preload(preload);
254
255        let c1 = pins
256            .0
257            .map(|_| PwmChannel1::new(unsafe { self.tim.steal() }));
258        let c2 = pins
259            .1
260            .map(|_| PwmChannel2::new(unsafe { self.tim.steal() }));
261        let c3 = pins
262            .2
263            .map(|_| PwmChannel3::new(unsafe { self.tim.steal() }));
264        let c4 = pins
265            .3
266            .map(|_| PwmChannel4::new(unsafe { self.tim.steal() }));
267        let t = PwmTimer::new(self.tim, self.clk);
268        (t, c1, c2, c3, c4)
269    }
270}
271
272// Fixed precision timers -----------------------------------------------------
273
274impl<TIM: Instance + MasterTimer, const FREQ: u32> FTimer<TIM, FREQ> {
275    pub fn set_master_mode(&mut self, mode: TIM::Mms) {
276        self.tim.master_mode(mode)
277    }
278}
279
280// Release --------------------------------------------------------------------
281
282pub fn release_counter_hz<TIM: GeneralTimer>(mut counter: CounterHz<TIM>) -> Timer<TIM> {
283    // stop timer
284    counter.tim.reset_config();
285    Timer {
286        tim: counter.tim,
287        clk: counter.clk,
288    }
289}
290
291// Enumerate ------------------------------------------------------------------
292
293#[derive(Clone, Copy, Debug, PartialEq, Eq)]
294#[repr(u8)]
295pub enum Ocm {
296    Frozen = 0,
297    ActiveOnMatch = 1,
298    InactiveOnMatch = 2,
299    Toggle = 3,
300    ForceInactive = 4,
301    ForceActive = 5,
302    PwmMode1 = 6,
303    PwmMode2 = 7,
304}
305
306impl From<PwmMode> for Ocm {
307    fn from(value: PwmMode) -> Self {
308        match value {
309            PwmMode::Mode1 => Ocm::PwmMode1,
310            PwmMode::Mode2 => Ocm::PwmMode2,
311        }
312    }
313}
314
315// Utilities ------------------------------------------------------------------
316
317fn freq_to_presc_arr(timer_clk: u32, count_freq: u32, update_freq: u32) -> (u32, u32) {
318    assert!(timer_clk >= count_freq);
319    assert!(count_freq > 0);
320    assert!(update_freq > 0);
321
322    let prescaler = timer_clk / count_freq - 1;
323    let arr = count_freq / update_freq - 1;
324
325    assert!(prescaler <= 0xFFFF);
326    (prescaler, arr)
327}
328
329// hal!(
330//     pac::TIM2: [Timer2, u16, dbg_tim2_stop, c: (CH4), m: tim2, d: dir,],
331//     pac::TIM3: [Timer3, u16, dbg_tim3_stop, c: (CH4), m: tim2, d: dir,],
332// );
333
334// #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
335// hal!(
336//     pac::TIM1: [Timer1, u16, dbg_tim1_stop, c: (CH4, _aoe), m: tim1, d: dir,],
337// );
338
339// #[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity"))]
340// hal! {
341//     pac::TIM6: [Timer6, u16, dbg_tim6_stop, m: tim6,],
342// }
343
344// #[cfg(any(
345//     all(feature = "high", any(feature = "stm32f101", feature = "stm32f103")),
346//     any(feature = "stm32f100", feature = "connectivity")
347// ))]
348// hal! {
349//     pac::TIM7: [Timer7, u16, dbg_tim7_stop, m: tim6,],
350// }
351
352// #[cfg(feature = "stm32f100")]
353// hal! {
354//     pac::TIM15: [Timer15, u16, dbg_tim15_stop, c: (CH2),],
355//     pac::TIM16: [Timer16, u16, dbg_tim16_stop, c: (CH1),],
356//     pac::TIM17: [Timer17, u16, dbg_tim17_stop, c: (CH1),],
357// }
358
359// #[cfg(feature = "medium")]
360// hal! {
361//     pac::TIM4: [Timer4, u16, dbg_tim4_stop, c: (CH4), m: tim2, d: dir,],
362// }
363
364// #[cfg(any(feature = "high", feature = "connectivity"))]
365// hal! {
366//     pac::TIM5: [Timer5, u16, dbg_tim5_stop, c: (CH4), m: tim2, d: dir,],
367// }
368
369// #[cfg(all(feature = "stm32f103", feature = "high"))]
370// hal! {
371//     pac::TIM8: [Timer8, u16, dbg_tim8_stop, c: (CH4, _aoe), m: tim1, d: dir,],
372// }
373
374//TODO: restore these timers once stm32-rs has been updated
375/*
376 *   dbg_tim(12-13)_stop fields missing from 103 xl in stm32-rs
377 *   dbg_tim(9-10)_stop fields missing from 101 xl in stm32-rs
378#[cfg(any(
379    feature = "xl",
380    all(
381        feature = "stm32f100",
382        feature = "high",
383)))]
384hal! {
385    TIM12: (tim12, dbg_tim12_stop),
386    TIM13: (tim13, dbg_tim13_stop),
387    TIM14: (tim14, dbg_tim14_stop),
388}
389#[cfg(feature = "xl")]
390hal! {
391    TIM9: (tim9, dbg_tim9_stop),
392    TIM10: (tim10, dbg_tim10_stop),
393    TIM11: (tim11, dbg_tim11_stop),
394}
395*/