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 + GeneralTimer {}
54
55// Initialize -----------------------------------------------------------------
56
57pub trait TimerInit<TIM> {
58    fn constrain(self, mcu: &mut Mcu) -> Timer<TIM>;
59}
60
61/// Timer wrapper
62pub struct Timer<TIM> {
63    tim: TIM,
64    clk: Hertz,
65}
66
67impl<TIM: Instance + Steal> Timer<TIM> {
68    /// Initialize timer
69    pub fn new(tim: TIM, mcu: &mut Mcu) -> Self {
70        // Enable and reset the timer peripheral
71        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    /// Non-blocking [Counter] with custom fixed precision
81    pub fn counter<const FREQ: u32>(self) -> Counter<TIM, FREQ> {
82        FTimer::new(self.tim, self.clk).counter()
83    }
84
85    /// Non-blocking [Counter] with fixed precision of 1 ms (1 kHz sampling)
86    ///
87    /// Can wait from 2 ms to 65 sec for 16-bit timer and from 2 ms to 49 days for 32-bit timer.
88    ///
89    /// NOTE: don't use this if your system frequency more than 65 MHz
90    pub fn counter_ms(self) -> CounterMs<TIM> {
91        self.counter::<1_000>()
92    }
93
94    /// Non-blocking [Counter] with fixed precision of 1 μs (1 MHz sampling)
95    ///
96    /// Can wait from 2 μs to 65 ms for 16-bit timer and from 2 μs to 71 min for 32-bit timer.
97    pub fn counter_us(self) -> CounterUs<TIM> {
98        self.counter::<1_000_000>()
99    }
100
101    /// Non-blocking [Counter] with dynamic precision which uses `Hertz` as Duration units
102    pub fn counter_hz(self) -> CounterHz<TIM> {
103        CounterHz {
104            tim: self.tim,
105            clk: self.clk,
106        }
107    }
108
109    /// Blocking [Delay] with custom fixed precision
110    pub fn delay<const FREQ: u32>(self) -> Delay<TIM, FREQ> {
111        FTimer::new(self.tim, self.clk).delay()
112    }
113
114    /// Blocking [Delay] with fixed precision of 1 ms (1 kHz sampling)
115    ///
116    /// Can wait from 2 ms to 49 days.
117    ///
118    /// NOTE: don't use this if your system frequency more than 65 MHz
119    pub fn delay_ms(self) -> DelayMs<TIM> {
120        self.delay::<1_000>()
121    }
122    /// Blocking [Delay] with fixed precision of 1 μs (1 MHz sampling)
123    ///
124    /// Can wait from 2 μs to 71 min.
125    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    /// Starts listening for an `event`
134    ///
135    /// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
136    /// receiving events.
137    pub fn listen(&mut self, event: Event) {
138        self.tim.listen_interrupt(event, true);
139    }
140
141    /// Clears interrupt associated with `event`.
142    ///
143    /// If the interrupt is not cleared, it will immediately retrigger after
144    /// the ISR has finished.
145    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    /// Stops listening for an `event`
154    pub fn unlisten(&mut self, event: Event) {
155        self.tim.listen_interrupt(event, false);
156    }
157
158    /// Stopping timer in debug mode can cause troubles when sampling the signal
159    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
176// Initialize PWM -------------------------------------------------------------
177
178impl<'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
263// Destroy --------------------------------------------------------------------
264
265pub fn destroy_counter_hz<TIM: GeneralTimer>(mut counter: CounterHz<TIM>) -> Timer<TIM> {
266    // stop timer
267    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// Enumerate ------------------------------------------------------------------
283
284#[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
306// Utilities ------------------------------------------------------------------
307
308const 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}