Skip to main content

gd32c1x3_hal/
timer.rs

1/*!
2  # Timer
3
4  ## Alternate function remapping
5
6  This is a list of the remap settings you can use to assign pins to PWM channels
7  and the QEI peripherals
8
9  ### TIM1
10
11  Not available on STM32F101.
12
13  | Channel | Tim1NoRemap | Tim1FullRemap |
14  |:---:|:-----------:|:-------------:|
15  | CH1 |     PA8     |       PE9     |
16  | CH2 |     PA9     |       PE11    |
17  | CH3 |     PA10    |       PE13    |
18  | CH4 |     PA11    |       PE14    |
19
20  ### TIM2
21
22  | Channel | Tim2NoRemap | Tim2PartialRemap1 | Tim2PartialRemap2 | Tim2FullRemap |
23  |:---:|:-----------:|:-----------------:|:-----------------:|:-------------:|
24  | CH1 |     PA0     |        PA15       |        PA0        |      PA15     |
25  | CH2 |     PA1     |        PB3        |        PA1        |      PB3      |
26  | CH3 |     PA2     |        PA2        |        PB10       |      PB10     |
27  | CH4 |     PA3     |        PA3        |        PB11       |      PB11     |
28
29  ### TIM3
30
31  | Channel | Tim3NoRemap | Tim3PartialRemap | Tim3FullRemap |
32  |:---:|:-----------:|:----------------:|:-------------:|
33  | CH1 |     PA6     |        PB4       |      PC6      |
34  | CH2 |     PA7     |        PB5       |      PC7      |
35  | CH3 |     PB0     |        PB0       |      PC8      |
36  | CH4 |     PB1     |        PB1       |      PC9      |
37
38  ### TIM4
39
40  Not available on low density devices.
41
42  | Channel | Tim4NoRemap | Tim4Remap |
43  |:---:|:-----------:|:---------:|
44  | CH1 |     PB6     |    PD12   |
45  | CH2 |     PB7     |    PD13   |
46  | CH3 |     PB8     |    PD14   |
47  | CH4 |     PB9     |    PD15   |
48*/
49#![allow(non_upper_case_globals)]
50
51use crate::bb;
52use crate::pac::{Dbg, Rcu};
53use crate::pac;
54
55use crate::rcu::{self, Clocks};
56use cortex_m::peripheral::syst::SystClkSource;
57use cortex_m::peripheral::SYST;
58
59use crate::time::Hertz;
60
61pub(crate) mod pins;
62pub mod pwm_input;
63pub use pins::*;
64pub mod delay;
65pub use delay::*;
66pub mod counter;
67pub use counter::*;
68pub mod pwm;
69pub use pwm::*;
70
71mod hal_02;
72
73/// Timer wrapper
74pub struct Timer<TIM> {
75    pub(crate) tim: TIM,
76    pub(crate) clk: Hertz,
77}
78
79#[derive(Clone, Copy, PartialEq, Eq)]
80#[repr(u8)]
81pub enum Channel {
82    C1 = 0,
83    C2 = 1,
84    C3 = 2,
85    C4 = 3,
86}
87
88/// Interrupt events
89#[derive(Clone, Copy, PartialEq, Eq)]
90pub enum SysEvent {
91    /// [Timer] timed out / count down ended
92    Update,
93}
94
95bitflags::bitflags! {
96    pub struct Event: u32 {
97        const Update  = 1 << 0;
98        const C1 = 1 << 1;
99        const C2 = 1 << 2;
100        const C3 = 1 << 3;
101        const C4 = 1 << 4;
102    }
103}
104
105#[derive(Debug, Eq, PartialEq, Copy, Clone)]
106pub enum Error {
107    /// Timer is disabled
108    Disabled,
109    WrongAutoReload,
110}
111
112pub trait TimerExt: Sized {
113    /// Non-blocking [Counter] with custom fixed precision
114    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> Counter<Self, FREQ>;
115    /// Non-blocking [Counter] with fixed precision of 1 ms (1 kHz sampling)
116    ///
117    /// Can wait from 2 ms to 65 sec for 16-bit timer and from 2 ms to 49 days for 32-bit timer.
118    ///
119    /// NOTE: don't use this if your system frequency more than 65 MHz
120    fn counter_ms(self, clocks: &Clocks) -> CounterMs<Self> {
121        self.counter::<1_000>(clocks)
122    }
123    /// Non-blocking [Counter] with fixed precision of 1 μs (1 MHz sampling)
124    ///
125    /// Can wait from 2 μs to 65 ms for 16-bit timer and from 2 μs to 71 min for 32-bit timer.
126    fn counter_us(self, clocks: &Clocks) -> CounterUs<Self> {
127        self.counter::<1_000_000>(clocks)
128    }
129    /// Non-blocking [Counter] with dynamic precision which uses `Hertz` as Duration units
130    fn counter_hz(self, clocks: &Clocks) -> CounterHz<Self>;
131
132    /// Blocking [Delay] with custom fixed precision
133    fn delay<const FREQ: u32>(self, clocks: &Clocks) -> Delay<Self, FREQ>;
134    /// Blocking [Delay] with fixed precision of 1 ms (1 kHz sampling)
135    ///
136    /// Can wait from 2 ms to 49 days.
137    ///
138    /// NOTE: don't use this if your system frequency more than 65 MHz
139    fn delay_ms(self, clocks: &Clocks) -> DelayMs<Self> {
140        self.delay::<1_000>(clocks)
141    }
142    /// Blocking [Delay] with fixed precision of 1 μs (1 MHz sampling)
143    ///
144    /// Can wait from 2 μs to 71 min.
145    fn delay_us(self, clocks: &Clocks) -> DelayUs<Self> {
146        self.delay::<1_000_000>(clocks)
147    }
148}
149
150impl<TIM: Instance> TimerExt for TIM {
151    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> Counter<Self, FREQ> {
152        FTimer::new(self, clocks).counter()
153    }
154    fn counter_hz(self, clocks: &Clocks) -> CounterHz<Self> {
155        Timer::new(self, clocks).counter_hz()
156    }
157    fn delay<const FREQ: u32>(self, clocks: &Clocks) -> Delay<Self, FREQ> {
158        FTimer::new(self, clocks).delay()
159    }
160}
161
162pub trait SysTimerExt: Sized {
163    /// Creates timer which takes [Hertz] as Duration
164    fn counter_hz(self, clocks: &Clocks) -> SysCounterHz;
165
166    /// Creates timer with custom precision (core frequency recommended is known)
167    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> SysCounter<FREQ>;
168    /// Creates timer with precision of 1 μs (1 MHz sampling)
169    fn counter_us(self, clocks: &Clocks) -> SysCounterUs {
170        self.counter::<1_000_000>(clocks)
171    }
172    /// Blocking [Delay] with custom precision
173    fn delay(self, clocks: &Clocks) -> SysDelay;
174}
175
176impl SysTimerExt for SYST {
177    fn counter_hz(self, clocks: &Clocks) -> SysCounterHz {
178        Timer::syst(self, clocks).counter_hz()
179    }
180    fn counter<const FREQ: u32>(self, clocks: &Clocks) -> SysCounter<FREQ> {
181        Timer::syst(self, clocks).counter()
182    }
183    fn delay(self, clocks: &Clocks) -> SysDelay {
184        Timer::syst_external(self, clocks).delay()
185    }
186}
187
188impl Timer<SYST> {
189    /// Initialize SysTick timer
190    pub fn syst(mut tim: SYST, clocks: &Clocks) -> Self {
191        tim.set_clock_source(SystClkSource::Core);
192        Self {
193            tim,
194            clk: clocks.hclk(),
195        }
196    }
197
198    /// Initialize SysTick timer and set it frequency to `HCLK / 8`
199    pub fn syst_external(mut tim: SYST, clocks: &Clocks) -> Self {
200        tim.set_clock_source(SystClkSource::External);
201        Self {
202            tim,
203            clk: clocks.hclk() / 8,
204        }
205    }
206
207    pub fn configure(&mut self, clocks: &Clocks) {
208        self.tim.set_clock_source(SystClkSource::Core);
209        self.clk = clocks.hclk();
210    }
211
212    pub fn configure_external(&mut self, clocks: &Clocks) {
213        self.tim.set_clock_source(SystClkSource::External);
214        self.clk = clocks.hclk() / 8;
215    }
216
217    pub fn release(self) -> SYST {
218        self.tim
219    }
220
221    /// Starts listening for an `event`
222    pub fn listen(&mut self, event: SysEvent) {
223        match event {
224            SysEvent::Update => self.tim.enable_interrupt(),
225        }
226    }
227
228    /// Stops listening for an `event`
229    pub fn unlisten(&mut self, event: SysEvent) {
230        match event {
231            SysEvent::Update => self.tim.disable_interrupt(),
232        }
233    }
234
235    /// Resets the counter
236    pub fn reset(&mut self) {
237        // According to the Cortex-M3 Generic User Guide, the interrupt request is only generated
238        // when the counter goes from 1 to 0, so writing zero should not trigger an interrupt
239        self.tim.clear_current();
240    }
241}
242
243#[derive(Clone, Copy, Debug, PartialEq, Eq)]
244#[repr(u8)]
245pub enum Ocm {
246    Frozen = 0,
247    ActiveOnMatch = 1,
248    InactiveOnMatch = 2,
249    Toggle = 3,
250    ForceInactive = 4,
251    ForceActive = 5,
252    PwmMode1 = 6,
253    PwmMode2 = 7,
254}
255
256mod sealed {
257    use super::{Channel, Event, Ocm, Dbg};
258    pub trait General {
259        type Width: Into<u32> + From<u16>;
260        fn max_auto_reload() -> u32;
261        unsafe fn set_auto_reload_unchecked(&mut self, arr: u32);
262        fn set_auto_reload(&mut self, arr: u32) -> Result<(), super::Error>;
263        fn read_auto_reload() -> u32;
264        fn enable_preload(&mut self, b: bool);
265        fn enable_counter(&mut self);
266        fn disable_counter(&mut self);
267        fn is_counter_enabled(&self) -> bool;
268        fn reset_counter(&mut self);
269        fn set_prescaler(&mut self, psc: u16);
270        fn read_prescaler(&self) -> u16;
271        fn trigger_update(&mut self);
272        fn clear_interrupt_flag(&mut self, event: Event);
273        fn listen_interrupt(&mut self, event: Event, b: bool);
274        fn get_interrupt_flag(&self) -> Event;
275        fn read_count(&self) -> Self::Width;
276        fn start_one_pulse(&mut self);
277        fn ctl0_reset(&mut self);
278        fn stop_in_debug(&mut self, dbg: &mut Dbg, state: bool);
279    }
280
281    pub trait WithPwm: General {
282        const CH_NUMBER: u8;
283        fn read_cc_value(channel: u8) -> u32;
284        fn set_cc_value(channel: u8, value: u32);
285        fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm);
286        fn start_pwm(&mut self);
287        fn enable_channel(channel: u8, b: bool);
288    }
289
290    pub trait MasterTimer: General {
291        type Mms;
292        fn master_mode(&mut self, mode: Self::Mms);
293    }
294}
295pub(crate) use sealed::{General, MasterTimer, WithPwm};
296
297pub trait Instance:
298    crate::Sealed + rcu::Enable + rcu::Reset + rcu::BusTimerClock + General
299{
300}
301
302macro_rules! hal {
303    ($($TIM:ty: [
304        $Timer:ident,
305        $bits:ty,
306        $dbg_timX_stop:ident,
307        $(c: ($cnum:ident $(, $aoe:ident)?),)?
308        $(m: $timbase:ident,)?
309    ],)+) => {
310        $(
311            impl Instance for $TIM { }
312            pub type $Timer = Timer<$TIM>;
313
314            impl General for $TIM {
315                type Width = $bits;
316
317                #[inline(always)]
318                fn max_auto_reload() -> u32 {
319                    <$bits>::MAX as u32
320                }
321                #[inline(always)]
322                unsafe fn set_auto_reload_unchecked(&mut self, arr: u32) {
323                    self.car().write(|w| w.bits(arr))
324                }
325                #[inline(always)]
326                fn set_auto_reload(&mut self, arr: u32) -> Result<(), Error> {
327                    // Note: Make it impossible to set the ARR value to 0, since this
328                    // would cause an infinite loop.
329                    if arr > 0 && arr <= Self::max_auto_reload() {
330                        Ok(unsafe { self.set_auto_reload_unchecked(arr) })
331                    } else {
332                        Err(Error::WrongAutoReload)
333                    }
334                }
335                #[inline(always)]
336                fn read_auto_reload() -> u32 {
337                    let tim = unsafe { &*<$TIM>::ptr() };
338                    tim.car().read().bits()
339                }
340                #[inline(always)]
341                fn enable_preload(&mut self, b: bool) {
342                    self.ctl0().modify(|_, w| w.arse().bit(b));
343                }
344                #[inline(always)]
345                fn enable_counter(&mut self) {
346                    self.ctl0().modify(|_, w| w.cen().set_bit());
347                }
348                #[inline(always)]
349                fn disable_counter(&mut self) {
350                    self.ctl0().modify(|_, w| w.cen().clear_bit());
351                }
352                #[inline(always)]
353                fn is_counter_enabled(&self) -> bool {
354                    self.ctl0().read().cen().bit_is_set()
355                }
356                #[inline(always)]
357                fn reset_counter(&mut self) {
358                    self.cnt().reset();
359                }
360                #[inline(always)]
361                fn set_prescaler(&mut self, psc: u16) {
362                    self.psc().write(|w| w.psc().bits(psc));
363                }
364                #[inline(always)]
365                fn read_prescaler(&self) -> u16 {
366                    self.psc().read().psc().bits()
367                }
368                #[inline(always)]
369                fn trigger_update(&mut self) {
370                    // Sets the URS bit to prevent an interrupt from being triggered by
371                    // the UG bit
372                    self.ctl0().modify(|_, w| w.ups().set_bit());
373                    self.swevg().write(|w| w.upg().set_bit());
374                    self.ctl0().modify(|_, w| w.ups().clear_bit());
375                }
376                #[inline(always)]
377                fn clear_interrupt_flag(&mut self, event: Event) {
378                    self.intf().write(|w| unsafe { w.bits(0xffff & !event.bits()) });
379                }
380                #[inline(always)]
381                fn listen_interrupt(&mut self, event: Event, b: bool) {
382                    if b {
383                        self.dmainten().modify(|r, w| unsafe { w.bits(r.bits() | event.bits()) });
384                    } else {
385                        self.dmainten().modify(|r, w| unsafe { w.bits(r.bits() & !event.bits()) });
386                    }
387                }
388                #[inline(always)]
389                fn get_interrupt_flag(&self) -> Event {
390                    Event::from_bits_truncate(self.intf().read().bits())
391                }
392                #[inline(always)]
393                fn read_count(&self) -> Self::Width {
394                    self.cnt().read().bits() as Self::Width
395                }
396                #[inline(always)]
397                fn start_one_pulse(&mut self) {
398                    self.ctl0().write(|w| unsafe { w.bits(1 << 3) }.cen().set_bit());
399                }
400                #[inline(always)]
401                fn ctl0_reset(&mut self) {
402                    self.ctl0().reset();
403                }
404                #[inline(always)]
405                fn stop_in_debug(&mut self, dbg: &mut Dbg, state: bool) {
406                    dbg.ctl0().modify(|_, w| w.$dbg_timX_stop().bit(state));
407                }
408            }
409            $(with_pwm!($TIM: $cnum $(, $aoe)?);)?
410
411            $(impl MasterTimer for $TIM {
412                type Mms = crate::pac::$timbase::ctl1::Mmc;
413                fn master_mode(&mut self, mode: Self::Mms) {
414                    self.ctl1().modify(|_,w| w.mmc().variant(mode));
415                }
416            })?
417        )+
418    }
419}
420
421macro_rules! with_pwm {
422    ($TIM:ty: CH1) => {
423        impl WithPwm for $TIM {
424            const CH_NUMBER: u8 = 1;
425
426            #[inline(always)]
427            fn read_cc_value(channel: u8) -> u32 {
428                let tim = unsafe { &*<$TIM>::ptr() };
429                if channel < Self::CH_NUMBER {
430                    tim.ccr[channel as usize].read().bits()
431                } else {
432                    0
433                }
434            }
435
436            #[inline(always)]
437            fn set_cc_value(channel: u8, value: u32) {
438                let tim = unsafe { &*<$TIM>::ptr() };
439                #[allow(unused_unsafe)]
440                if channel < Self::CH_NUMBER {
441                    tim.ccr[channel as usize].write(|w| unsafe { w.bits(value) })
442                }
443            }
444
445            #[inline(always)]
446            fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm) {
447                match channel {
448                    Channel::C1 => {
449                        self.ccmr1_output()
450                        .modify(|_, w| w.oc1pe().set_bit().oc1m().bits(mode as _) );
451                    }
452                    _ => {},
453                }
454            }
455
456            #[inline(always)]
457            fn start_pwm(&mut self) {
458                self.ctl0.write(|w| w.cen().set_bit());
459            }
460
461            #[inline(always)]
462            fn enable_channel(c: u8, b: bool) {
463                let tim = unsafe { &*<$TIM>::ptr() };
464                if c < Self::CH_NUMBER {
465                    unsafe { bb::write(&tim.ccer, c*4, b); }
466                }
467            }
468        }
469    };
470    ($TIM:ty: CH2) => {
471        impl WithPwm for $TIM {
472            const CH_NUMBER: u8 = 2;
473
474            #[inline(always)]
475            fn read_cc_value(channel: u8) -> u32 {
476                let tim = unsafe { &*<$TIM>::ptr() };
477                if channel < Self::CH_NUMBER {
478                    tim.ccr[channel as usize].read().bits()
479                } else {
480                    0
481                }
482            }
483
484            #[inline(always)]
485            fn set_cc_value(channel: u8, value: u32) {
486                let tim = unsafe { &*<$TIM>::ptr() };
487                #[allow(unused_unsafe)]
488                if channel < Self::CH_NUMBER {
489                    tim.ccr[channel as usize].write(|w| unsafe { w.bits(value) })
490                }
491            }
492
493            #[inline(always)]
494            fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm) {
495                match channel {
496                    Channel::C1 => {
497                        self.ccmr1_output()
498                        .modify(|_, w| w.oc1pe().set_bit().oc1m().bits(mode as _) );
499                    }
500                    Channel::C2 => {
501                        self.ccmr1_output()
502                        .modify(|_, w| w.oc2pe().set_bit().oc2m().bits(mode as _) );
503                    }
504                    _ => {},
505                }
506            }
507
508            #[inline(always)]
509            fn start_pwm(&mut self) {
510                self.ctl0.write(|w| w.cen().set_bit());
511            }
512
513            #[inline(always)]
514            fn enable_channel(c: u8, b: bool) {
515                let tim = unsafe { &*<$TIM>::ptr() };
516                if c < Self::CH_NUMBER {
517                    unsafe { bb::write(&tim.ccer, c*4, b); }
518                }
519            }
520        }
521    };
522    ($TIM:ty: CH4 $(, $aoe:ident)?) => {
523        impl WithPwm for $TIM {
524            const CH_NUMBER: u8 = 4;
525
526            #[inline(always)]
527            fn read_cc_value(channel: u8) -> u32 {
528                let tim = unsafe { &*<$TIM>::ptr() };
529                match channel {
530                    0 => tim.ch0cv().read().bits(),
531                    1 => tim.ch1cv().read().bits(),
532                    2 => tim.ch2cv().read().bits(),
533                    3 => tim.ch3cv().read().bits(),
534                    _ => 0,
535                }
536            }
537
538            #[inline(always)]
539            fn set_cc_value(channel: u8, value: u32) {
540                let tim = unsafe { &*<$TIM>::ptr() };
541                match channel {
542                    0 => tim.ch0cv().write(|w| unsafe { w.bits(value) }),
543                    1 => tim.ch1cv().write(|w| unsafe { w.bits(value) }),
544                    2 => tim.ch2cv().write(|w| unsafe { w.bits(value) }),
545                    3 => tim.ch3cv().write(|w| unsafe { w.bits(value) }),
546                    _ => {}
547                }
548            }
549
550            #[inline(always)]
551            fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm) {
552                match channel {
553                    Channel::C1 => {
554                        self.chctl0_output()
555                        .modify(|_, w| w.ch0comsen().set_bit().ch0comctl().bits(mode as _));
556                    }
557                    Channel::C2 => {
558                        self.chctl0_output()
559                        .modify(|_, w| w.ch1comsen().set_bit().ch1comctl().bits(mode as _));
560                    }
561                    Channel::C3 => {
562                        self.chctl1_output()
563                        .modify(|_, w| w.ch2comsen().set_bit().ch2comctl().bits(mode as _));
564                    }
565                    Channel::C4 => {
566                        self.chctl1_output()
567                        .modify(|_, w| w.ch3comsen().set_bit().ch3comctl().bits(mode as _));
568                    }
569                }
570            }
571
572            #[inline(always)]
573            fn start_pwm(&mut self) {
574                $(let $aoe = self.cchp().modify(|_, w| w.oaen().set_bit());)?
575                self.ctl0().write(|w| w.cen().set_bit());
576            }
577
578            #[inline(always)]
579            fn enable_channel(c: u8, b: bool) {
580                let tim = unsafe { &*<$TIM>::ptr() };
581                if c < Self::CH_NUMBER {
582                    unsafe { bb::write(&tim.chctl2(), c*4, b); }
583                }
584            }
585        }
586    }
587}
588
589impl<TIM: Instance> Timer<TIM> {
590    /// Initialize timer
591    pub fn new(tim: TIM, clocks: &Clocks) -> Self {
592        unsafe {
593            //NOTE(unsafe) this reference will only be used for atomic writes with no side effects
594            let rcu = &(*Rcu::ptr());
595            // Enable and reset the timer peripheral
596            TIM::enable(rcu);
597            TIM::reset(rcu);
598        }
599
600        Self {
601            clk: TIM::timer_clock(clocks),
602            tim,
603        }
604    }
605
606    pub fn configure(&mut self, clocks: &Clocks) {
607        self.clk = TIM::timer_clock(clocks);
608    }
609
610    pub fn counter_hz(self) -> CounterHz<TIM> {
611        CounterHz(self)
612    }
613
614    pub fn release(self) -> TIM {
615        self.tim
616    }
617
618    /// Starts listening for an `event`
619    ///
620    /// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
621    /// receiving events.
622    pub fn listen(&mut self, event: Event) {
623        self.tim.listen_interrupt(event, true);
624    }
625
626    /// Clears interrupt associated with `event`.
627    ///
628    /// If the interrupt is not cleared, it will immediately retrigger after
629    /// the ISR has finished.
630    pub fn clear_interrupt(&mut self, event: Event) {
631        self.tim.clear_interrupt_flag(event);
632    }
633
634    pub fn get_interrupt(&mut self) -> Event {
635        self.tim.get_interrupt_flag()
636    }
637
638    /// Stops listening for an `event`
639    pub fn unlisten(&mut self, event: Event) {
640        self.tim.listen_interrupt(event, false);
641    }
642
643    /// Stopping timer in debug mode can cause troubles when sampling the signal
644    pub fn stop_in_debug(&mut self, dbg: &mut Dbg, state: bool) {
645        self.tim.stop_in_debug(dbg, state);
646    }
647}
648
649impl<TIM: Instance + MasterTimer> Timer<TIM> {
650    pub fn set_master_mode(&mut self, mode: TIM::Mms) {
651        self.tim.master_mode(mode)
652    }
653}
654
655/// Timer wrapper for fixed precision timers.
656///
657/// Uses `fugit::TimerDurationU32` for most of operations
658pub struct FTimer<TIM, const FREQ: u32> {
659    tim: TIM,
660}
661
662/// `FTimer` with precision of 1 μs (1 MHz sampling)
663pub type FTimerUs<TIM> = FTimer<TIM, 1_000_000>;
664
665/// `FTimer` with precision of 1 ms (1 kHz sampling)
666///
667/// NOTE: don't use this if your system frequency more than 65 MHz
668pub type FTimerMs<TIM> = FTimer<TIM, 1_000>;
669impl<TIM: Instance, const FREQ: u32> FTimer<TIM, FREQ> {
670    /// Initialize timer
671    pub fn new(tim: TIM, clocks: &Clocks) -> Self {
672        unsafe {
673            //NOTE(unsafe) this reference will only be used for atomic writes with no side effects
674            let rcu = &(*Rcu::ptr());
675            // Enable and reset the timer peripheral
676            TIM::enable(rcu);
677            TIM::reset(rcu);
678        }
679
680        let mut t = Self { tim };
681        t.configure(clocks);
682        t
683    }
684
685    /// Calculate prescaler depending on `Clocks` state
686    pub fn configure(&mut self, clocks: &Clocks) {
687        let clk = TIM::timer_clock(clocks);
688        assert!(clk.raw() % FREQ == 0);
689        let psc = clk.raw() / FREQ;
690        self.tim.set_prescaler(u16::try_from(psc - 1).unwrap());
691    }
692
693    /// Creates `Counter` that imlements [embedded_hal::timer::CountDown]
694    pub fn counter(self) -> Counter<TIM, FREQ> {
695        Counter(self)
696    }
697
698    /// Creates `Delay` that imlements [embedded_hal::blocking::delay] traits
699    pub fn delay(self) -> Delay<TIM, FREQ> {
700        Delay(self)
701    }
702
703    /// Releases the TIM peripheral
704    pub fn release(self) -> TIM {
705        self.tim
706    }
707
708    /// Starts listening for an `event`
709    ///
710    /// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
711    /// receiving events.
712    pub fn listen(&mut self, event: Event) {
713        self.tim.listen_interrupt(event, true);
714    }
715
716    /// Clears interrupt associated with `event`.
717    ///
718    /// If the interrupt is not cleared, it will immediately retrigger after
719    /// the ISR has finished.
720    pub fn clear_interrupt(&mut self, event: Event) {
721        self.tim.clear_interrupt_flag(event);
722    }
723
724    pub fn get_interrupt(&mut self) -> Event {
725        self.tim.get_interrupt_flag()
726    }
727
728    /// Stops listening for an `event`
729    pub fn unlisten(&mut self, event: Event) {
730        self.tim.listen_interrupt(event, false);
731    }
732
733    /// Stopping timer in debug mode can cause troubles when sampling the signal
734    pub fn stop_in_debug(&mut self, dbg: &mut Dbg, state: bool) {
735        self.tim.stop_in_debug(dbg, state);
736    }
737}
738
739impl<TIM: Instance + MasterTimer, const FREQ: u32> FTimer<TIM, FREQ> {
740    pub fn set_master_mode(&mut self, mode: TIM::Mms) {
741        self.tim.master_mode(mode)
742    }
743}
744
745#[inline(always)]
746const fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u32) {
747    let ticks = clock / freq;
748    let psc = (ticks - 1) / (1 << 16);
749    let arr = ticks / (psc + 1) - 1;
750    (psc as u16, arr)
751}
752
753hal!(
754    pac::Timer1: [Timer1, u16, timer1_hold, c: (CH4), m: timer1,],
755    pac::Timer2: [Timer2, u16, timer2_hold, c: (CH4), m: timer1,],
756    pac::Timer3: [Timer3, u16, timer3_hold, c: (CH4), m: timer1,],
757    pac::Timer4: [Timer4, u16, timer4_hold, c: (CH4), m: timer1,],
758);
759
760hal!(
761    pac::Timer0: [Timer0, u16, timer0_hold, c: (CH4, _aoe), m: timer0,],
762    pac::Timer7: [Timer7, u16, timer7_hold, c: (CH4, _aoe), m: timer0,],
763
764);
765
766hal! {
767    pac::Timer5: [Timer5, u16, timer5_hold, m: timer5,],
768    pac::Timer6: [Timer6, u16, timer6_hold, m: timer5,],
769
770}
771
772
773//TODO: restore these timers once stm32-rs has been updated
774/*
775 *   dbg_tim(12-13)_stop fields missing from 103 xl in stm32-rs
776 *   dbg_tim(9-10)_stop fields missing from 101 xl in stm32-rs
777#[cfg(any(
778    feature = "xl",
779    all(
780        feature = "stm32f100",
781        feature = "high",
782)))]
783hal! {
784    TIM12: (tim12, dbg_tim12_stop),
785    TIM13: (tim13, dbg_tim13_stop),
786    TIM14: (tim14, dbg_tim14_stop),
787}
788*/
789// hal! {
790//     gd32c103::TIMER9: (tim9, timer9_halt),
791//     gd32c103::TIMER10: (tim10, dbg_tim10_stop),
792//     gd32c103::TIMER11: (tim11, dbg_tim11_stop),
793// }