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