stm32f1_hal/timer/
mod.rs

1#[cfg(feature = "rtic")]
2mod monotonic;
3mod syst;
4#[cfg(any(feature = "f100", feature = "f103", feature = "connectivity"))]
5mod timer1;
6#[cfg(feature = "xl")]
7mod timer10;
8#[cfg(feature = "xl")]
9mod timer11;
10#[cfg(any(feature = "xl", all(feature = "f100", feature = "high",)))]
11mod timer12;
12#[cfg(any(feature = "xl", all(feature = "f100", feature = "high",)))]
13mod timer13;
14#[cfg(any(feature = "xl", all(feature = "f100", feature = "high",)))]
15mod timer14;
16#[cfg(feature = "f100")]
17mod timer15;
18#[cfg(feature = "f100")]
19mod timer16;
20#[cfg(feature = "f100")]
21mod timer17;
22mod timer2;
23mod timer3;
24#[cfg(feature = "medium")]
25mod timer4;
26#[cfg(any(feature = "high", feature = "connectivity"))]
27mod timer5;
28#[cfg(any(feature = "f100", feature = "high", feature = "connectivity"))]
29mod timer6;
30#[cfg(any(
31    all(feature = "high", any(feature = "f101", feature = "f103")),
32    any(feature = "f100", feature = "connectivity")
33))]
34mod timer7;
35#[cfg(all(feature = "f103", feature = "high"))]
36mod timer8;
37#[cfg(feature = "xl")]
38mod timer9;
39
40pub use crate::common::timer::*;
41#[cfg(feature = "rtic")]
42pub use monotonic::*;
43pub use syst::*;
44
45use crate::{
46    Mcu, Steal,
47    afio::{RemapMode, timer_remap::*},
48    pac::DBGMCU as DBG,
49    rcc::{Enable, GetTimerClock, Reset},
50    time::HertzU32,
51};
52
53pub trait TimerConfig: Enable + Reset + GetTimerClock + GeneralTimer {}
54
55// Initialize -----------------------------------------------------------------
56
57pub trait TimerInit<TIM> {
58    fn init(self, mcu: &mut Mcu) -> Timer<TIM>;
59}
60
61/// Timer wrapper
62pub struct Timer<TIM> {
63    tim: TIM,
64    clk: HertzU32,
65}
66
67impl<TIM: TimerConfig + 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: tim.get_timer_clock(),
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 `HertzU32` 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    pub fn release(self) -> TIM {
110        self.tim
111    }
112
113    /// Starts listening for an `event`
114    ///
115    /// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
116    /// receiving events.
117    pub fn listen(&mut self, event: Event) {
118        self.tim.listen_interrupt(event, true);
119    }
120
121    /// Clears interrupt associated with `event`.
122    ///
123    /// If the interrupt is not cleared, it will immediately retrigger after
124    /// the ISR has finished.
125    pub fn clear_interrupt(&mut self, event: Event) {
126        self.tim.clear_interrupt_flag(event);
127    }
128
129    pub fn get_interrupt(&mut self) -> Event {
130        self.tim.get_interrupt_flag()
131    }
132
133    /// Stops listening for an `event`
134    pub fn unlisten(&mut self, event: Event) {
135        self.tim.listen_interrupt(event, false);
136    }
137
138    /// Stopping timer in debug mode can cause troubles when sampling the signal
139    pub fn stop_in_debug(&mut self, state: bool) {
140        self.tim.stop_in_debug(state);
141    }
142}
143
144impl<TIM: TimerConfig + MasterTimer> Timer<TIM> {
145    pub fn set_master_mode(&mut self, mode: MasterMode) {
146        self.tim.master_mode(mode)
147    }
148}
149
150impl<TIM: TimerConfig + TimerDirection> Timer<TIM> {
151    pub fn set_count_direction(&mut self, dir: CountDirection) {
152        self.tim.set_count_direction(dir);
153    }
154}
155
156// Initialize PWM -------------------------------------------------------------
157
158impl<'a, TIM: TimerConfig + TimerWithPwm1Ch + Steal + 'a> Timer<TIM> {
159    pub fn into_pwm1<REMAP: RemapMode<TIM>>(
160        mut self,
161        _pin: impl TimCh1Pin<REMAP>,
162        update_freq: HertzU32,
163        preload: bool,
164        mcu: &mut Mcu,
165    ) -> (PwmTimer<TIM>, impl PwmChannel + 'a) {
166        REMAP::remap(&mut mcu.afio);
167        self.tim.enable_preload(preload);
168        self.tim.config_freq(self.clk, update_freq);
169
170        let c1 = PwmChannel1::new(unsafe { self.tim.steal() });
171        let t = PwmTimer::new(self.tim, self.clk);
172        (t, c1)
173    }
174}
175
176impl<'a, TIM: TimerConfig + TimerWithPwm2Ch + Steal + 'a> Timer<TIM> {
177    pub fn into_pwm2<REMAP: RemapMode<TIM>>(
178        mut self,
179        pins: (impl TimCh1Pin<REMAP>, impl TimCh2Pin<REMAP>),
180        update_freq: HertzU32,
181        preload: bool,
182        mcu: &mut Mcu,
183    ) -> (
184        PwmTimer<TIM>,
185        Option<impl PwmChannel + 'a>,
186        Option<impl PwmChannel + 'a>,
187    ) {
188        REMAP::remap(&mut mcu.afio);
189        self.tim.enable_preload(preload);
190        self.tim.config_freq(self.clk, update_freq);
191
192        let c1 = if pins.0.is_pin() {
193            Some(PwmChannel1::new(unsafe { self.tim.steal() }))
194        } else {
195            None
196        };
197        let c2 = if pins.1.is_pin() {
198            Some(PwmChannel2::new(unsafe { self.tim.steal() }))
199        } else {
200            None
201        };
202        let t = PwmTimer::new(self.tim, self.clk);
203        (t, c1, c2)
204    }
205}
206
207impl<'a, TIM: TimerConfig + TimerWithPwm4Ch + Steal + 'a> Timer<TIM> {
208    pub fn into_pwm4<REMAP: RemapMode<TIM>>(
209        mut self,
210        pins: (
211            impl TimCh1Pin<REMAP>,
212            impl TimCh2Pin<REMAP>,
213            impl TimCh3Pin<REMAP>,
214            impl TimCh4Pin<REMAP>,
215        ),
216        update_freq: HertzU32,
217        preload: bool,
218        mcu: &mut Mcu,
219    ) -> (
220        PwmTimer<TIM>,
221        Option<impl PwmChannel + 'a>,
222        Option<impl PwmChannel + 'a>,
223        Option<impl PwmChannel + 'a>,
224        Option<impl PwmChannel + 'a>,
225    ) {
226        REMAP::remap(&mut mcu.afio);
227        self.tim.enable_preload(preload);
228        self.tim.config_freq(self.clk, update_freq);
229
230        let c1 = if pins.0.is_pin() {
231            Some(PwmChannel1::new(unsafe { self.tim.steal() }))
232        } else {
233            None
234        };
235        let c2 = if pins.1.is_pin() {
236            Some(PwmChannel2::new(unsafe { self.tim.steal() }))
237        } else {
238            None
239        };
240        let c3 = if pins.2.is_pin() {
241            Some(PwmChannel3::new(unsafe { self.tim.steal() }))
242        } else {
243            None
244        };
245        let c4 = if pins.3.is_pin() {
246            Some(PwmChannel4::new(unsafe { self.tim.steal() }))
247        } else {
248            None
249        };
250        let t = PwmTimer::new(self.tim, self.clk);
251        (t, c1, c2, c3, c4)
252    }
253}
254
255// Destroy --------------------------------------------------------------------
256
257pub fn destroy_counter_hz<TIM: GeneralTimer>(mut counter: CounterHz<TIM>) -> Timer<TIM> {
258    // stop timer
259    counter.tim.reset_config();
260    Timer {
261        tim: counter.tim,
262        clk: counter.clk,
263    }
264}
265
266#[cfg(feature = "rtic")]
267pub fn destroy_mono_timer<TIM: GeneralTimer, const FREQ: u32>(
268    mut timer: MonoTimer<TIM, FREQ>,
269) -> FTimer<TIM, FREQ> {
270    timer.tim.reset_config();
271    timer.timer
272}
273
274// Enumerate ------------------------------------------------------------------
275
276#[derive(Clone, Copy, Debug, PartialEq, Eq)]
277#[repr(u8)]
278pub enum Ocm {
279    Frozen = 0,
280    ActiveOnMatch = 1,
281    InactiveOnMatch = 2,
282    Toggle = 3,
283    ForceInactive = 4,
284    ForceActive = 5,
285    PwmMode1 = 6,
286    PwmMode2 = 7,
287}
288
289impl From<PwmMode> for Ocm {
290    fn from(value: PwmMode) -> Self {
291        match value {
292            PwmMode::Mode1 => Ocm::PwmMode1,
293            PwmMode::Mode2 => Ocm::PwmMode2,
294        }
295    }
296}
297
298// Utilities ------------------------------------------------------------------
299
300const fn compute_prescaler_arr(timer_clk: u32, update_freq: u32) -> (u32, u32) {
301    let ticks = timer_clk / update_freq;
302    let prescaler = (ticks - 1) / (1 << 16);
303    let arr = ticks / (prescaler + 1) - 1;
304    (prescaler, arr)
305}