stm32f4xx_hal/
timer.rs

1//! Timers
2//!
3//! Pins can be used for PWM output in both push-pull mode (`Alternate`) and open-drain mode
4//! (`AlternateOD`).
5#![allow(non_upper_case_globals)]
6
7use core::convert::TryFrom;
8use cortex_m::peripheral::syst::SystClkSource;
9use cortex_m::peripheral::SYST;
10use enumflags2::BitFlags;
11
12use crate::bb;
13use crate::pac;
14
15use crate::dma::traits::PeriAddress;
16use crate::rcc::{self, Clocks};
17use fugit::HertzU32 as Hertz;
18
19pub mod counter;
20pub use counter::*;
21pub mod delay;
22pub use delay::*;
23pub mod pwm;
24pub use pwm::*;
25#[cfg(not(feature = "gpio-f410"))]
26pub mod pwm_input;
27#[cfg(not(feature = "gpio-f410"))]
28pub use pwm_input::PwmInput;
29#[cfg(feature = "rtic1")]
30pub mod monotonic;
31#[cfg(feature = "rtic1")]
32pub use monotonic::*;
33#[cfg(feature = "rtic2")]
34#[cfg(any(
35    feature = "rtic-tim2",
36    feature = "rtic-tim3",
37    feature = "rtic-tim4",
38    feature = "rtic-tim5"
39))]
40pub mod monotonics;
41#[cfg(feature = "rtic2")]
42#[cfg(any(
43    feature = "rtic-tim2",
44    feature = "rtic-tim3",
45    feature = "rtic-tim4",
46    feature = "rtic-tim5"
47))]
48pub use monotonics::*;
49
50mod hal_02;
51mod hal_1;
52
53/// Timer wrapper.
54///
55/// This wrapper can be used both for the system timer (SYST) or the
56/// general-purpose timers (TIMx).
57///
58/// Note: If you want to use the timer to sleep a certain amount of time, use
59/// [`Delay`](`crate::timer::delay::Delay`).
60pub struct Timer<TIM> {
61    pub(crate) tim: TIM,
62    pub(crate) clk: Hertz,
63}
64
65#[derive(Clone, Copy, PartialEq, Eq)]
66#[cfg_attr(feature = "defmt", derive(defmt::Format))]
67#[repr(u8)]
68pub enum Channel {
69    C1 = 0,
70    C2 = 1,
71    C3 = 2,
72    C4 = 3,
73}
74
75pub use crate::gpio::alt::TimCPin as CPin;
76pub use crate::gpio::alt::TimNCPin as NCPin;
77
78/// Channel wrapper
79pub struct Ch<const C: u8, const COMP: bool>;
80pub const C1: u8 = 0;
81pub const C2: u8 = 1;
82pub const C3: u8 = 2;
83pub const C4: u8 = 3;
84
85/// Enum for IO polarity
86#[derive(Clone, Copy, Debug, PartialEq, Eq)]
87pub enum Polarity {
88    ActiveHigh,
89    ActiveLow,
90}
91
92/// Output Idle state
93#[derive(Clone, Copy, Debug, PartialEq, Eq)]
94pub enum IdleState {
95    Reset,
96    Set,
97}
98
99/// SysTick interrupt events
100#[derive(Clone, Copy, PartialEq, Eq)]
101#[cfg_attr(feature = "defmt", derive(defmt::Format))]
102pub enum SysEvent {
103    /// [Timer] timed out / count down ended
104    Update,
105}
106
107/// TIM interrupt events
108#[enumflags2::bitflags]
109#[repr(u32)]
110#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
111#[cfg_attr(feature = "defmt", derive(defmt::Format))]
112pub enum Event {
113    /// Update interrupt enable
114    Update = 1 << 0,
115    /// Capture/Compare 1 interrupt enable
116    C1 = 1 << 1,
117    /// Capture/Compare 2 interrupt enable
118    C2 = 1 << 2,
119    /// Capture/Compare 3 interrupt enable
120    C3 = 1 << 3,
121    /// Capture/Compare 4 interrupt enable
122    C4 = 1 << 4,
123    /// COM interrupt enable
124    COM = 1 << 5,
125    /// Trigger interrupt enable
126    Trigger = 1 << 6,
127    /// Break interrupt enable
128    Break = 1 << 7,
129}
130
131/// TIM status flags
132#[enumflags2::bitflags]
133#[repr(u32)]
134#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
135#[cfg_attr(feature = "defmt", derive(defmt::Format))]
136pub enum Flag {
137    /// Update interrupt flag
138    Update = 1 << 0,
139    /// Capture/Compare 1 interrupt flag
140    C1 = 1 << 1,
141    /// Capture/Compare 2 interrupt flag
142    C2 = 1 << 2,
143    /// Capture/Compare 3 interrupt flag
144    C3 = 1 << 3,
145    /// Capture/Compare 4 interrupt flag
146    C4 = 1 << 4,
147    /// COM interrupt flag
148    COM = 1 << 5,
149    /// Trigger interrupt flag
150    Trigger = 1 << 6,
151    /// Break interrupt flag
152    Break = 1 << 7,
153    /// Capture/Compare 1 overcapture flag
154    C1Overcapture = 1 << 9,
155    /// Capture/Compare 2 overcapture flag
156    C2Overcapture = 1 << 10,
157    /// Capture/Compare 3 overcapture flag
158    C3Overcapture = 1 << 11,
159    /// Capture/Compare 4 overcapture flag
160    C4Overcapture = 1 << 12,
161}
162
163#[derive(Debug, Eq, PartialEq, Copy, Clone)]
164#[cfg_attr(feature = "defmt", derive(defmt::Format))]
165pub enum Error {
166    /// Timer is disabled
167    Disabled,
168    WrongAutoReload,
169}
170
171pub trait TimerExt: Sized {
172    /// Non-blocking [Counter] with custom fixed precision
173    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> Counter<Self, FREQ>;
174    /// Non-blocking [Counter] with fixed precision of 1 ms (1 kHz sampling)
175    ///
176    /// Can wait from 2 ms to 65 sec for 16-bit timer and from 2 ms to 49 days for 32-bit timer.
177    ///
178    /// NOTE: don't use this if your system frequency more than 65 MHz
179    fn counter_ms(self, clocks: &Clocks) -> CounterMs<Self> {
180        self.counter::<1_000>(clocks)
181    }
182    /// Non-blocking [Counter] with fixed precision of 1 μs (1 MHz sampling)
183    ///
184    /// Can wait from 2 μs to 65 ms for 16-bit timer and from 2 μs to 71 min for 32-bit timer.
185    fn counter_us(self, clocks: &Clocks) -> CounterUs<Self> {
186        self.counter::<1_000_000>(clocks)
187    }
188    /// Non-blocking [Counter] with dynamic precision which uses `Hertz` as Duration units
189    fn counter_hz(self, clocks: &Clocks) -> CounterHz<Self>;
190
191    /// Blocking [Delay] with custom fixed precision
192    fn delay<const FREQ: u32>(self, clocks: &Clocks) -> Delay<Self, FREQ>;
193    /// Blocking [Delay] with fixed precision of 1 ms (1 kHz sampling)
194    ///
195    /// Can wait from 2 ms to 49 days.
196    ///
197    /// NOTE: don't use this if your system frequency more than 65 MHz
198    fn delay_ms(self, clocks: &Clocks) -> DelayMs<Self> {
199        self.delay::<1_000>(clocks)
200    }
201    /// Blocking [Delay] with fixed precision of 1 μs (1 MHz sampling)
202    ///
203    /// Can wait from 2 μs to 71 min.
204    fn delay_us(self, clocks: &Clocks) -> DelayUs<Self> {
205        self.delay::<1_000_000>(clocks)
206    }
207}
208
209impl<TIM: Instance> TimerExt for TIM {
210    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> Counter<Self, FREQ> {
211        FTimer::new(self, clocks).counter()
212    }
213    fn counter_hz(self, clocks: &Clocks) -> CounterHz<Self> {
214        Timer::new(self, clocks).counter_hz()
215    }
216    fn delay<const FREQ: u32>(self, clocks: &Clocks) -> Delay<Self, FREQ> {
217        FTimer::new(self, clocks).delay()
218    }
219}
220
221pub trait SysTimerExt: Sized {
222    /// Creates timer which takes [Hertz] as Duration
223    fn counter_hz(self, clocks: &Clocks) -> SysCounterHz;
224
225    /// Creates timer with custom precision (core frequency recommended is known)
226    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> SysCounter<FREQ>;
227    /// Creates timer with precision of 1 μs (1 MHz sampling)
228    fn counter_us(self, clocks: &Clocks) -> SysCounterUs {
229        self.counter::<1_000_000>(clocks)
230    }
231    /// Blocking [Delay] with custom precision
232    fn delay(self, clocks: &Clocks) -> SysDelay;
233}
234
235impl SysTimerExt for SYST {
236    fn counter_hz(self, clocks: &Clocks) -> SysCounterHz {
237        Timer::syst(self, clocks).counter_hz()
238    }
239    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> SysCounter<FREQ> {
240        Timer::syst(self, clocks).counter()
241    }
242    fn delay(self, clocks: &Clocks) -> SysDelay {
243        Timer::syst_external(self, clocks).delay()
244    }
245}
246
247impl Timer<SYST> {
248    /// Initialize SysTick timer
249    pub fn syst(mut tim: SYST, clocks: &Clocks) -> Self {
250        tim.set_clock_source(SystClkSource::Core);
251        Self {
252            tim,
253            clk: clocks.hclk(),
254        }
255    }
256
257    /// Initialize SysTick timer and set it frequency to `HCLK / 8`
258    pub fn syst_external(mut tim: SYST, clocks: &Clocks) -> Self {
259        tim.set_clock_source(SystClkSource::External);
260        Self {
261            tim,
262            clk: clocks.hclk() / 8,
263        }
264    }
265
266    pub fn configure(&mut self, clocks: &Clocks) {
267        self.tim.set_clock_source(SystClkSource::Core);
268        self.clk = clocks.hclk();
269    }
270
271    pub fn configure_external(&mut self, clocks: &Clocks) {
272        self.tim.set_clock_source(SystClkSource::External);
273        self.clk = clocks.hclk() / 8;
274    }
275
276    pub fn release(self) -> SYST {
277        self.tim
278    }
279
280    /// Starts listening for an `event`
281    pub fn listen(&mut self, event: SysEvent) {
282        match event {
283            SysEvent::Update => self.tim.enable_interrupt(),
284        }
285    }
286
287    /// Stops listening for an `event`
288    pub fn unlisten(&mut self, event: SysEvent) {
289        match event {
290            SysEvent::Update => self.tim.disable_interrupt(),
291        }
292    }
293}
294
295#[derive(Clone, Copy, Debug, PartialEq, Eq)]
296#[cfg_attr(feature = "defmt", derive(defmt::Format))]
297#[repr(u8)]
298pub enum Ocm {
299    Frozen = 0,
300    ActiveOnMatch = 1,
301    InactiveOnMatch = 2,
302    Toggle = 3,
303    ForceInactive = 4,
304    ForceActive = 5,
305    PwmMode1 = 6,
306    PwmMode2 = 7,
307}
308
309// Center-aligned mode selection
310pub use pac::tim1::cr1::CMS as CenterAlignedMode;
311
312/// Wrapper type that indicates which register of the contained timer to use for DMA.
313pub struct CCR<T, const C: u8>(T);
314pub type CCR1<T> = CCR<T, 0>;
315pub type CCR2<T> = CCR<T, 1>;
316pub type CCR3<T> = CCR<T, 2>;
317pub type CCR4<T> = CCR<T, 3>;
318
319/// Wrapper type that indicates which register of the contained timer to use for DMA.
320pub struct DMAR<T>(T);
321
322mod sealed {
323    use super::{BitFlags, CenterAlignedMode, Event, Flag, IdleState, Ocm, Polarity};
324    pub trait General {
325        type Width: Into<u32> + From<u16>;
326        fn max_auto_reload() -> u32;
327        unsafe fn set_auto_reload_unchecked(&mut self, arr: u32);
328        fn set_auto_reload(&mut self, arr: u32) -> Result<(), super::Error>;
329        fn read_auto_reload() -> u32;
330        fn enable_preload(&mut self, b: bool);
331        fn enable_counter(&mut self, b: bool);
332        fn is_counter_enabled(&self) -> bool;
333        fn reset_counter(&mut self);
334        fn set_prescaler(&mut self, psc: u16);
335        fn read_prescaler(&self) -> u16;
336        fn trigger_update(&mut self);
337        fn listen_event(
338            &mut self,
339            disable: Option<BitFlags<Event>>,
340            enable: Option<BitFlags<Event>>,
341        );
342        fn clear_interrupt_flag(&mut self, event: BitFlags<Flag>);
343        fn get_interrupt_flag(&self) -> BitFlags<Flag>;
344        fn read_count(&self) -> Self::Width;
345        fn write_count(&mut self, value: Self::Width);
346        fn start_one_pulse(&mut self);
347        fn start_free(&mut self, update: bool);
348        fn cr1_reset(&mut self);
349        fn cnt_reset(&mut self);
350    }
351
352    pub trait WithPwmCommon: General {
353        const CH_NUMBER: u8;
354        const COMP_CH_NUMBER: u8;
355        fn read_cc_value(channel: u8) -> u32;
356        fn set_cc_value(channel: u8, value: u32);
357        fn enable_channel(channel: u8, b: bool);
358        fn set_channel_polarity(channel: u8, p: Polarity);
359        fn set_nchannel_polarity(channel: u8, p: Polarity);
360    }
361
362    pub trait Advanced: WithPwmCommon {
363        fn enable_nchannel(channel: u8, b: bool);
364        fn set_dtg_value(value: u8);
365        fn read_dtg_value() -> u8;
366        fn idle_state(channel: u8, comp: bool, s: IdleState);
367        fn set_cms(mode: CenterAlignedMode);
368    }
369
370    pub trait WithPwm: WithPwmCommon {
371        fn preload_output_channel_in_mode(&mut self, c: u8, mode: Ocm);
372        fn freeze_output_channel(&mut self, c: u8);
373        fn start_pwm(&mut self);
374    }
375
376    pub trait MasterTimer: General {
377        type Mms;
378        fn master_mode(&mut self, mode: Self::Mms);
379    }
380
381    pub trait Split {
382        type Channels;
383        fn split() -> Self::Channels;
384    }
385}
386pub(crate) use sealed::{Advanced, General, MasterTimer, WithPwm, WithPwmCommon};
387
388pub trait Instance:
389    crate::Sealed + rcc::Enable + rcc::Reset + rcc::BusTimerClock + General
390{
391}
392
393use sealed::Split;
394macro_rules! split {
395    ($TIM:ty: 1) => {
396        split!($TIM, C1);
397    };
398    ($TIM:ty: 2) => {
399        split!($TIM, C1, C2);
400    };
401    ($TIM:ty: 4) => {
402        split!($TIM, C1, C2, C3, C4);
403    };
404    ($TIM:ty, $($C:ident),+) => {
405        impl Split for $TIM {
406            type Channels = ($(PwmChannelDisabled<$TIM, $C>,)+);
407            fn split() -> Self::Channels {
408                ($(PwmChannelDisabled::<_, $C>::new(),)+)
409            }
410        }
411    };
412}
413
414macro_rules! hal {
415    ($TIM:ty: [
416        $Timer:ident,
417        $bits:ty,
418        $(dmar: $memsize:ty,)?
419        $(c: ($cnum:tt $(, $aoe:ident)?),)?
420        $(m: $timbase:ident,)?
421    ]) => {
422        impl Instance for $TIM { }
423        impl crate::Steal for $TIM {
424            unsafe fn steal() -> Self {
425                Self::steal()
426            }
427        }
428        pub type $Timer = Timer<$TIM>;
429
430        impl General for $TIM {
431            type Width = $bits;
432
433            #[inline(always)]
434            fn max_auto_reload() -> u32 {
435                <$bits>::MAX as u32
436            }
437            #[inline(always)]
438            unsafe fn set_auto_reload_unchecked(&mut self, arr: u32) {
439                self.arr().write(|w| w.bits(arr))
440            }
441            #[inline(always)]
442            fn set_auto_reload(&mut self, arr: u32) -> Result<(), Error> {
443                // Note: Make it impossible to set the ARR value to 0, since this
444                // would cause an infinite loop.
445                if arr > 0 && arr <= Self::max_auto_reload() {
446                    Ok(unsafe { self.set_auto_reload_unchecked(arr) })
447                } else {
448                    Err(Error::WrongAutoReload)
449                }
450            }
451            #[inline(always)]
452            fn read_auto_reload() -> u32 {
453                let tim = unsafe { &*<$TIM>::ptr() };
454                tim.arr().read().bits()
455            }
456            #[inline(always)]
457            fn enable_preload(&mut self, b: bool) {
458                self.cr1().modify(|_, w| w.arpe().bit(b));
459            }
460            #[inline(always)]
461            fn enable_counter(&mut self, b: bool) {
462                self.cr1().modify(|_, w| w.cen().bit(b));
463            }
464            #[inline(always)]
465            fn is_counter_enabled(&self) -> bool {
466                self.cr1().read().cen().is_enabled()
467            }
468            #[inline(always)]
469            fn reset_counter(&mut self) {
470                self.cnt().reset();
471            }
472            #[inline(always)]
473            fn set_prescaler(&mut self, psc: u16) {
474                self.psc().write(|w| w.psc().set(psc) );
475            }
476            #[inline(always)]
477            fn read_prescaler(&self) -> u16 {
478                self.psc().read().psc().bits()
479            }
480            #[inline(always)]
481            fn trigger_update(&mut self) {
482                self.cr1().modify(|_, w| w.urs().set_bit());
483                self.egr().write(|w| w.ug().set_bit());
484                self.cr1().modify(|_, w| w.urs().clear_bit());
485            }
486            #[inline(always)]
487            fn listen_event(&mut self, disable: Option<BitFlags<Event>>, enable: Option<BitFlags<Event>>) {
488                self.dier().modify(|r, w| unsafe { w.bits({
489                    let mut bits = r.bits();
490                    if let Some(d) = disable {
491                        bits &= !(d.bits() as u32);
492                    }
493                    if let Some(e) = enable {
494                        bits |= e.bits() as u32;
495                    }
496                    bits
497                }) });
498            }
499            #[inline(always)]
500            fn clear_interrupt_flag(&mut self, event: BitFlags<Flag>) {
501                self.sr().write(|w| unsafe { w.bits(0xffff & !(event.bits() as u32)) });
502            }
503            #[inline(always)]
504            fn get_interrupt_flag(&self) -> BitFlags<Flag> {
505                BitFlags::from_bits_truncate(self.sr().read().bits())
506            }
507            #[inline(always)]
508            fn read_count(&self) -> Self::Width {
509                self.cnt().read().bits() as Self::Width
510            }
511            #[inline(always)]
512            fn write_count(&mut self, value:Self::Width) {
513                self.cnt().write(|w| unsafe { w.cnt().bits(value) });
514            }
515            #[inline(always)]
516            fn start_one_pulse(&mut self) {
517                self.cr1().modify(|_, w| unsafe { w.bits(1 << 3) }.cen().set_bit());
518            }
519            #[inline(always)]
520            fn start_free(&mut self, update: bool) {
521                self.cr1().modify(|_, w| w.cen().set_bit().udis().bit(!update));
522            }
523            #[inline(always)]
524            fn cr1_reset(&mut self) {
525                self.cr1().reset();
526            }
527            #[inline(always)]
528            fn cnt_reset(&mut self) {
529                self.cnt().reset();
530            }
531        }
532
533        $(with_dmar!($TIM, $memsize);)?
534
535        $(
536            impl WithPwmCommon for $TIM {
537                const CH_NUMBER: u8 = $cnum;
538                const COMP_CH_NUMBER: u8 = $cnum;
539
540                #[inline(always)]
541                fn read_cc_value(c: u8) -> u32 {
542                    let tim = unsafe { &*<$TIM>::ptr() };
543                    if c < Self::CH_NUMBER {
544                        tim.ccr(c as usize).read().bits()
545                    } else {
546                        0
547                    }
548                }
549
550                #[inline(always)]
551                fn set_cc_value(c: u8, value: u32) {
552                    let tim = unsafe { &*<$TIM>::ptr() };
553                    if c < Self::CH_NUMBER {
554                        tim.ccr(c as usize).write(|w| unsafe { w.bits(value) })
555                    }
556                }
557
558                #[inline(always)]
559                fn enable_channel(c: u8, b: bool) {
560                    let tim = unsafe { &*<$TIM>::ptr() };
561                    if c < Self::CH_NUMBER {
562                        unsafe { bb::write(tim.ccer(), c*4, b); }
563                    }
564                }
565
566                #[inline(always)]
567                fn set_channel_polarity(c: u8, p: Polarity) {
568                    let tim = unsafe { &*<$TIM>::ptr() };
569                    if c < Self::CH_NUMBER {
570                        unsafe { bb::write(tim.ccer(), c*4 + 1, p == Polarity::ActiveLow); }
571                    }
572                }
573
574                #[inline(always)]
575                fn set_nchannel_polarity(c: u8, p: Polarity) {
576                    let tim = unsafe { &*<$TIM>::ptr() };
577                    if c < Self::COMP_CH_NUMBER {
578                        unsafe { bb::write(tim.ccer(), c*4 + 3, p == Polarity::ActiveLow); }
579                    }
580                }
581            }
582
583            $(
584                impl Advanced for $TIM {
585                    fn enable_nchannel(c: u8, b: bool) {
586                        let $aoe = ();
587                        let tim = unsafe { &*<$TIM>::ptr() };
588                        if c < Self::COMP_CH_NUMBER {
589                            unsafe { bb::write(tim.ccer(), c*4 + 2, b); }
590                        }
591                    }
592                    fn set_dtg_value(value: u8) {
593                        let tim = unsafe { &*<$TIM>::ptr() };
594                        tim.bdtr().modify(|_,w| w.dtg().set(value));
595                    }
596                    fn read_dtg_value() -> u8 {
597                        let tim = unsafe { &*<$TIM>::ptr() };
598                        tim.bdtr().read().dtg().bits()
599                    }
600                    fn idle_state(c: u8, comp: bool, s: IdleState) {
601                        let tim = unsafe { &*<$TIM>::ptr() };
602                        if !comp {
603                            if c < Self::CH_NUMBER {
604                                unsafe { bb::write(tim.cr2(), c*2 + 8, s == IdleState::Set); }
605                            }
606                        } else {
607                            if c < Self::COMP_CH_NUMBER {
608                                unsafe { bb::write(tim.cr2(), c*2 + 9, s == IdleState::Set); }
609                            }
610                        }
611                    }
612                    #[inline(always)]
613                    fn set_cms(cms: CenterAlignedMode) {
614                        let tim = unsafe { &*<$TIM>::ptr() };
615                        tim.cr1().write(|w| w.cms().variant(cms));
616                    }
617                }
618            )?
619
620            with_pwm!($TIM: $cnum $(, $aoe)?);
621            split!($TIM: $cnum);
622            unsafe impl<const C: u8> PeriAddress for CCR<$TIM, C> {
623                #[inline(always)]
624                fn address(&self) -> u32 {
625                    self.0.ccr(C as usize).as_ptr() as u32
626                }
627
628                type MemSize = $bits;
629            }
630        )?
631
632        $(impl MasterTimer for $TIM {
633            type Mms = pac::$timbase::cr2::MMS;
634            fn master_mode(&mut self, mode: Self::Mms) {
635                self.cr2().modify(|_,w| w.mms().variant(mode));
636            }
637        })?
638    };
639}
640use hal;
641
642macro_rules! with_dmar {
643    ($TIM:ty, $memsize:ty) => {
644        unsafe impl PeriAddress for DMAR<$TIM> {
645            #[inline(always)]
646            fn address(&self) -> u32 {
647                self.0.dmar().as_ptr() as u32
648            }
649
650            type MemSize = $memsize;
651        }
652    };
653}
654
655macro_rules! with_pwm {
656    ($TIM:ty: [$($Cx:literal, $ccmrx_output:ident, $ocxpe:ident, $ocxm:ident;)+] $(, $aoe:ident)?) => {
657        impl WithPwm for $TIM {
658            #[inline(always)]
659            fn preload_output_channel_in_mode(&mut self, c: u8, mode: Ocm) {
660                match c {
661                    $(
662                        $Cx => {
663                            self.$ccmrx_output()
664                            .modify(|_, w| w.$ocxpe().set_bit().$ocxm().set(mode as _) );
665                        }
666                    )+
667                    #[allow(unreachable_patterns)]
668                    _ => {},
669                }
670            }
671            fn freeze_output_channel(&mut self, c: u8) {
672                match c {
673                        $(
674                            $Cx => {
675                                self.$ccmrx_output()
676                                .modify(|_, w| w.$ocxpe().clear_bit().$ocxm().set(Ocm::Frozen as _) );
677                            }
678                        )+
679                        #[allow(unreachable_patterns)]
680                        _ => {},
681                    }
682            }
683
684            #[inline(always)]
685            fn start_pwm(&mut self) {
686                $(let $aoe = self.bdtr().modify(|_, w| w.aoe().set_bit());)?
687                self.cr1().modify(|_, w| w.cen().set_bit());
688            }
689        }
690    };
691    ($TIM:ty: 1) => {
692        with_pwm!($TIM: [
693            0, ccmr1_output, oc1pe, oc1m;
694        ]);
695    };
696    ($TIM:ty: 2) => {
697        with_pwm!($TIM: [
698            0, ccmr1_output, oc1pe, oc1m;
699            1, ccmr1_output, oc2pe, oc2m;
700        ]);
701    };
702    ($TIM:ty: 4 $(, $aoe:ident)?) => {
703        with_pwm!($TIM: [
704            0, ccmr1_output, oc1pe, oc1m;
705            1, ccmr1_output, oc2pe, oc2m;
706            2, ccmr2_output, oc3pe, oc3m;
707            3, ccmr2_output, oc4pe, oc4m;
708        ] $(, $aoe)?);
709    };
710}
711
712impl<TIM: Instance> Timer<TIM> {
713    /// Initialize timer
714    pub fn new(tim: TIM, clocks: &Clocks) -> Self {
715        unsafe {
716            // Enable and reset the timer peripheral
717            TIM::enable_unchecked();
718            TIM::reset_unchecked();
719        }
720
721        Self {
722            clk: TIM::timer_clock(clocks),
723            tim,
724        }
725    }
726
727    pub fn configure(&mut self, clocks: &Clocks) {
728        self.clk = TIM::timer_clock(clocks);
729    }
730
731    pub fn counter_hz(self) -> CounterHz<TIM> {
732        CounterHz(self)
733    }
734
735    pub fn release(self) -> TIM {
736        self.tim
737    }
738}
739
740impl<TIM: Instance + MasterTimer> Timer<TIM> {
741    pub fn set_master_mode(&mut self, mode: TIM::Mms) {
742        self.tim.master_mode(mode)
743    }
744}
745
746/// Timer wrapper for fixed precision timers.
747///
748/// Uses `fugit::TimerDurationU32` for most of operations
749pub struct FTimer<TIM, const FREQ: u32> {
750    tim: TIM,
751}
752
753/// `FTimer` with precision of 1 μs (1 MHz sampling)
754pub type FTimerUs<TIM> = FTimer<TIM, 1_000_000>;
755
756/// `FTimer` with precision of 1 ms (1 kHz sampling)
757///
758/// NOTE: don't use this if your system frequency more than 65 MHz
759pub type FTimerMs<TIM> = FTimer<TIM, 1_000>;
760
761impl<TIM: Instance, const FREQ: u32> FTimer<TIM, FREQ> {
762    /// Initialize timer
763    pub fn new(tim: TIM, clocks: &Clocks) -> Self {
764        unsafe {
765            // Enable and reset the timer peripheral
766            TIM::enable_unchecked();
767            TIM::reset_unchecked();
768        }
769
770        let mut t = Self { tim };
771        t.configure(clocks);
772        t
773    }
774
775    /// Calculate prescaler depending on `Clocks` state
776    pub fn configure(&mut self, clocks: &Clocks) {
777        let clk = TIM::timer_clock(clocks);
778        assert!(clk.raw() % FREQ == 0);
779        let psc = clk.raw() / FREQ;
780        self.tim.set_prescaler(u16::try_from(psc - 1).unwrap());
781    }
782
783    /// Creates `Counter` that implements [embedded_hal_02::timer::CountDown]
784    pub fn counter(self) -> Counter<TIM, FREQ> {
785        Counter(self)
786    }
787
788    /// Creates `Delay` that implements [embedded_hal_02::blocking::delay] traits
789    pub fn delay(self) -> Delay<TIM, FREQ> {
790        Delay(self)
791    }
792
793    /// Releases the TIM peripheral
794    pub fn release(self) -> TIM {
795        self.tim
796    }
797}
798
799impl<TIM: Instance + MasterTimer, const FREQ: u32> FTimer<TIM, FREQ> {
800    pub fn set_master_mode(&mut self, mode: TIM::Mms) {
801        self.tim.master_mode(mode)
802    }
803}
804
805#[inline(always)]
806pub(crate) const fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u32) {
807    let ticks = clock / freq;
808    let psc = (ticks - 1) / (1 << 16);
809    let arr = ticks / (psc + 1) - 1;
810    (psc as u16, arr)
811}
812
813impl<TIM: Instance> crate::Listen for Timer<TIM> {
814    type Event = Event;
815    fn listen(&mut self, event: impl Into<BitFlags<Event>>) {
816        self.tim.listen_event(None, Some(event.into()));
817    }
818    fn listen_only(&mut self, event: impl Into<BitFlags<Event>>) {
819        self.tim
820            .listen_event(Some(BitFlags::ALL), Some(event.into()));
821    }
822    fn unlisten(&mut self, event: impl Into<BitFlags<Event>>) {
823        self.tim.listen_event(Some(event.into()), None);
824    }
825}
826
827impl<TIM: Instance, const FREQ: u32> crate::Listen for FTimer<TIM, FREQ> {
828    type Event = Event;
829    fn listen(&mut self, event: impl Into<BitFlags<Event>>) {
830        self.tim.listen_event(None, Some(event.into()));
831    }
832    fn listen_only(&mut self, event: impl Into<BitFlags<Event>>) {
833        self.tim
834            .listen_event(Some(BitFlags::ALL), Some(event.into()));
835    }
836    fn unlisten(&mut self, event: impl Into<BitFlags<Event>>) {
837        self.tim.listen_event(Some(event.into()), None);
838    }
839}
840
841impl<TIM: Instance> crate::ClearFlags for Timer<TIM> {
842    type Flag = Flag;
843    fn clear_flags(&mut self, event: impl Into<BitFlags<Flag>>) {
844        self.tim.clear_interrupt_flag(event.into());
845    }
846}
847
848impl<TIM: Instance> crate::ReadFlags for Timer<TIM> {
849    type Flag = Flag;
850    fn flags(&self) -> BitFlags<Flag> {
851        self.tim.get_interrupt_flag()
852    }
853}
854
855impl<TIM: Instance, const FREQ: u32> crate::ClearFlags for FTimer<TIM, FREQ> {
856    type Flag = Flag;
857    fn clear_flags(&mut self, event: impl Into<BitFlags<Flag>>) {
858        self.tim.clear_interrupt_flag(event.into());
859    }
860}
861
862impl<TIM: Instance, const FREQ: u32> crate::ReadFlags for FTimer<TIM, FREQ> {
863    type Flag = Flag;
864    fn flags(&self) -> BitFlags<Flag> {
865        self.tim.get_interrupt_flag()
866    }
867}
868
869#[cfg(not(feature = "gpio-f410"))]
870#[cfg(feature = "tim1")]
871hal!(pac::TIM1: [Timer1, u16, dmar: u32, c: (4, _aoe), m: tim1,]);
872#[cfg(feature = "tim2")]
873hal!(pac::TIM2: [Timer2, u32, dmar: u16, c: (4), m: tim2,]);
874#[cfg(feature = "tim3")]
875hal!(pac::TIM3: [Timer3, u16, dmar: u16, c: (4), m: tim3,]);
876#[cfg(feature = "tim4")]
877hal!(pac::TIM4: [Timer4, u16, dmar: u16, c: (4), m: tim3,]);
878#[cfg(not(feature = "gpio-f410"))]
879#[cfg(feature = "tim5")]
880hal!(pac::TIM5: [Timer5, u32, dmar: u16, c: (4), m: tim5,]);
881
882// TIM5 on F410 is 16-bit
883#[cfg(feature = "gpio-f410")]
884#[cfg(feature = "tim1")]
885hal!(pac::TIM1: [Timer1, u16, dmar: u16, c: (4, _aoe), m: tim1,]);
886#[cfg(feature = "gpio-f410")]
887#[cfg(feature = "tim5")]
888hal!(pac::TIM5: [Timer5, u16, dmar: u16, c: (4), m: tim5,]);
889
890#[cfg(feature = "tim6")]
891hal!(pac::TIM6: [Timer6, u16, m: tim6,]);
892#[cfg(feature = "tim7")]
893hal!(pac::TIM7: [Timer7, u16, m: tim7,]);
894#[cfg(feature = "tim8")]
895hal!(pac::TIM8: [Timer8, u16, dmar: u32, c: (4, _aoe), m: tim8,]);
896#[cfg(feature = "tim9")]
897hal!(pac::TIM9: [Timer9, u16, c: (2),]);
898#[cfg(feature = "tim10")]
899hal!(pac::TIM10: [Timer10, u16, c: (1),]);
900#[cfg(feature = "tim11")]
901hal!(pac::TIM11: [Timer11, u16, c: (1),]);
902#[cfg(feature = "tim12")]
903hal!(pac::TIM12: [Timer12, u16, c: (2),]);
904#[cfg(feature = "tim13")]
905hal!(pac::TIM13: [Timer13, u16, c: (1),]);
906#[cfg(feature = "tim14")]
907hal!(pac::TIM14: [Timer14, u16, c: (1),]);