stm32_hal2/
timer.rs

1//! Provides support for basic timer functionality. Includes initialization, interrupts,
2//! and PWM features. Also supports capture compare, output compare, burst DMA, and getting the current uptime using
3//! an overflowing wrapper. (In seconds, milliseconds, or microseconds)
4//!
5//! Low-power timers (LPTIM) and high-presolution timers (HRTIM) are not yet supported.
6
7// todo: WB and WL should support pwm features
8
9#[cfg(feature = "monotonic")]
10use core;
11#[cfg(not(any(
12    feature = "f401",
13    feature = "f410",
14    feature = "f411",
15    feature = "f413",
16    feature = "g031",
17    feature = "g041",
18    feature = "g070",
19    feature = "g030",
20    feature = "wb",
21    feature = "wl"
22)))]
23use core::ops::Deref;
24use core::{
25    sync::atomic::{AtomicU32, Ordering},
26    time::Duration,
27};
28
29use cfg_if::cfg_if;
30use num_traits::float::FloatCore; // To round floats.
31use paste::paste;
32#[cfg(feature = "monotonic")]
33use rtic_monotonic::Monotonic;
34
35#[cfg(any(feature = "f3", feature = "l4"))]
36use crate::dma::DmaInput;
37#[cfg(not(any(feature = "f4", feature = "l552")))]
38use crate::dma::{self, ChannelCfg, DmaChannel};
39#[cfg(feature = "c0")]
40use crate::pac::DMA as DMA1;
41#[cfg(not(feature = "c0"))]
42use crate::pac::DMA1;
43#[cfg(not(any(
44    feature = "f401",
45    feature = "f410",
46    feature = "f411",
47    feature = "f413",
48    feature = "g031",
49    feature = "g041",
50    feature = "g070",
51    feature = "g030",
52    feature = "g051",
53    feature = "c0",
54    feature = "wb",
55    feature = "wl"
56)))]
57use crate::util::RccPeriph;
58// todo: LPTIM (low-power timers) and HRTIM (high-resolution timers). And Advanced control functionality
59use crate::{
60    clocks::Clocks,
61    error::{Error, Result},
62    instant::Instant,
63    pac::{self, RCC},
64    util::rcc_en_reset,
65};
66
67// This `TICK_OVERFLOW_COUNT` must be incremented in firmware in the timer's update interrupt.
68pub static TICK_OVERFLOW_COUNT: AtomicU32 = AtomicU32::new(0);
69
70// todo: Low power timer enabling etc. eg on L4, RCC_APB1Enr1().LPTIM1EN
71
72#[derive(Debug, Clone, Copy, Eq, PartialEq, defmt::Format)]
73pub enum TimerError {
74    /// Used for when attempting to set a timer period that is out of range.
75    ValueError,
76}
77
78#[derive(Clone, Copy)]
79#[repr(u8)]
80/// This bit-field selects the trigger input to be used to synchronize the counter.
81/// Sets SMCR register, TS field.
82pub enum InputTrigger {
83    ///Internal Trigger 0 (ITR0)
84    Internal0 = 0b00000,
85    Internal1 = 0b00001,
86    Internal2 = 0b00010,
87    Internal3 = 0b00011,
88    /// TI1 Edge Detector (TI1F_ED)
89    Ti1Edge = 0b00100,
90    FilteredTimerInput1 = 0b00101,
91    FilteredTimerInput2 = 0b00110,
92    ExternalTriggerInput = 0b00111,
93    Internal4 = 0b01000,
94    Internal5 = 0b01001,
95    Internal6 = 0b01010,
96    Internal7 = 0b01011,
97    Internal8 = 0b01100,
98    Internal9 = 0b01101,
99    Internal10 = 0b01110,
100    Internal11 = 0b01111,
101    Internal12 = 0b10000,
102    Internal13 = 0b10001,
103}
104
105#[derive(Clone, Copy)]
106#[repr(u8)]
107/// When external signals are selected the active edge of the trigger signal (TRGI) is linked to
108/// the polarity selected on the external input (see Input Control register and Control Register
109/// description. Sets SMCR register, SMS field.
110pub enum InputSlaveMode {
111    /// Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal
112    /// clock
113    Disabled = 0b0000,
114    /// Encoder mode 1 - Counter counts up/down on TI1FP1 edge depending on TI2FP2
115    /// level
116    Encoder1 = 0b0001,
117    /// Encoder mode 2 - Counter counts up/down on TI2FP2 edge depending on TI1FP1
118    /// level.
119    Encoder2 = 0b0010,
120    /// Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges
121    /// depending on the level of the other input.
122    Encoder3 = 0b0011,
123    /// Reset mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter
124    /// and generates an update of the registers.
125    Reset = 0b0100,
126    /// Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The
127    /// counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of
128    /// the counter are controlled.
129    Gated = 0b0101,
130    /// Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not
131    /// reset). Only the start of the counter is controlled.
132    Trigger = 0b0110,
133    /// External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter.
134    ExternalClock1 = 0b0111,
135    /// Combined reset + trigger mode - Rising edge of the selected trigger input (TRGI)
136    /// reinitializes the counter, generates an update of the registers and starts the counter.
137    CombinedResetTrigger = 0b1000,
138}
139
140#[derive(Clone, Copy)]
141#[repr(u8)]
142/// These bits allow selected information to be sent in master mode to slave timers for
143/// synchronization (TRGO). Sets CR2 register, MMS field.
144pub enum MasterModeSelection {
145    /// Tthe UG bit from the TIMx_EGR register is used as trigger output (TRGO). If the
146    /// reset is generated by the trigger input (slave mode controller configured in reset mode) then
147    /// the signal on TRGO is delayed compared to the actual reset.
148    Reset = 0b000,
149    /// the Counter Enable signal CNT_EN is used as trigger output (TRGO). It is
150    /// useful to start several timers at the same time or to control a window in which a slave timer is
151    /// enable. The Counter Enable signal is generated by a logic AND between CEN control bit
152    /// and the trigger input when configured in gated mode. When the Counter Enable signal is
153    /// controlled by the trigger input, there is a delay on TRGO, except if the master/slave mode is
154    /// selected (see the MSM bit description in TIMx_SMCR register).
155    Enable = 0b001,
156    /// The update event is selected as trigger output (TRGO). For instance a master
157    /// timer can then be used as a prescaler for a slave timer.
158    Update = 0b010,
159    /// Compare Pulse - The trigger output send a positive pulse when the CC1IF flag is to be
160    /// set (even if it was already high), as soon as a capture or a compare match occurred.
161    /// (TRGO).
162    ComparePulse = 0b011,
163    /// OC1REF signal is used as trigger output (TRGO)
164    Compare1 = 0b100,
165    /// OC2REF signal is used as trigger output (TRGO)
166    Compare2 = 0b101,
167    /// OC3REF signal is used as trigger output (TRGO)
168    Compare3 = 0b110,
169    /// OC4REF signal is used as trigger output (TRGO)
170    Compare4 = 0b111,
171}
172
173/// Timer interrupt
174pub enum TimerInterrupt {
175    /// Update interrupt can be used for a timeout. DIER UIE to set, ... to clear
176    Update,
177    /// Trigger. DIER TIE to set, ... to clear
178    Trigger,
179    /// Capture/Compare. CC1IE to set, ... to clear
180    CaptureCompare1,
181    /// Capture/Compare. CC2IE to set, ... to clear
182    CaptureCompare2,
183    /// Capture/Compare. CC3IE to set, ... to clear
184    CaptureCompare3,
185    /// Capture/Compare. CC4IE to set, ... to clear
186    CaptureCompare4,
187    /// Update DMA. DIER UDE to set, ... to clear
188    UpdateDma,
189    /// Drigger. TDE to set, ... to clear
190    TriggerDma,
191    /// Capture/Compare. CC1DE to set, ... to clear
192    CaptureCompare1Dma,
193    /// Capture/Compare. CC2DE to set, ... to clear
194    CaptureCompare2Dma,
195    /// Capture/Compare. CC3DE to set, ... to clear
196    CaptureCompare3Dma,
197    /// Capture/Compare. CC4DE to set, ... to clear
198    CaptureCompare4Dma,
199}
200
201/// Output alignment. Sets `TIMx_CR1` register, `CMS` field.
202#[derive(Clone, Copy)]
203pub enum Alignment {
204    /// Edge-aligned mode. The counter counts up or down depending on the direction bit
205    /// (DIR).
206    Edge = 0b00,
207    /// Center-aligned mode 1. The counter counts up and down alternatively. Output compare
208    /// interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set
209    /// only when the counter is counting down.
210    Center1 = 0b01,
211    /// Center-aligned mode 2. The counter counts up and down alternatively. Output compare
212    /// interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set
213    /// only when the counter is counting up.
214    Center2 = 0b10,
215    /// Center-aligned mode 3. The counter counts up and down alternatively. Output compare
216    /// interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set
217    /// both when the counter is counting up or down.
218    Center3 = 0b11,
219}
220
221/// Timer channel
222#[derive(Clone, Copy)]
223pub enum TimChannel {
224    C1,
225    C2,
226    C3,
227    #[cfg(not(feature = "wl"))]
228    C4,
229}
230
231/// Timer count direction. Defaults to `Up`.
232#[repr(u8)]
233#[derive(Clone, Copy)]
234pub enum CountDir {
235    Up = 0,
236    Down = 1,
237}
238
239/// Capture/Compare selection.
240/// This field defines the direction of the channel (input/output) as well as the used input.
241/// It affects the TIMx_CCMR1 register, CCxS fields.
242///
243/// Note that the the specific timer input source varies depending on the channel.
244/// `InputTiPrimary` always matches the associated channel (e.g. TI1 for CH1, TI2 for CH2, etc),
245/// while `InputTiSecondary` is TI2 for CH1, TI1 for CH2, TI4 for CH3, and TI3 for CH4.
246#[repr(u8)]
247#[derive(Clone, Copy)]
248pub enum CaptureCompare {
249    Output = 0b00,
250    InputTiPrimary = 0b01,
251    InputTiSecondary = 0b10,
252    InputTrc = 0b11,
253}
254
255/// Capture/Compare output polarity. Defaults to `ActiveHigh` in hardware. Sets TIMx_CCER register,
256/// CCxP and CCXNP fields.
257#[derive(Clone, Copy)]
258pub enum Polarity {
259    ActiveHigh,
260    ActiveLow,
261}
262
263impl Polarity {
264    /// For use with `set_bit()`.
265    fn bit(&self) -> bool {
266        match self {
267            Self::ActiveHigh => false,
268            Self::ActiveLow => true,
269        }
270    }
271}
272
273#[derive(Clone, Copy)]
274#[repr(u8)]
275/// See F303 ref man, section 21.4.7. H745 RM, section 41.4.8. Sets TIMx_CCMR1 register, OC1M field.
276/// These bits define the behavior of the output reference signal OC1REF from which OC1 and
277/// OC1N are derived. OC1REF is active high whereas OC1 and OC1N active level depends
278/// on CC1P and CC1NP bits.
279pub enum OutputCompare {
280    /// Frozen - The comparison between the output compare register TIMx_CCR1 and the
281    /// counter TIMx_CNT has no effect on the outputs.(this mode is used to generate a timing
282    /// base).
283    Frozen = 0b0000,
284    /// Set channel 1 to active level on match. OC1REF signal is forced high when the
285    /// counter TIMx_CNT matches the capture/compare register 1 (TIMx_CCR1).
286    Active = 0b0001,
287    /// Set channel 1 to inactive level on match. OC1REF signal is forced low when the
288    /// counter TIMx_CNT matches the capture/compare register 1 (TIMx_CCR1).
289    /// 0011: Toggle - OC1REF toggles when TIMx_CNT=TIMx_CCR1.
290    Inactive = 0b0010,
291    /// tim_oc1ref toggles when TIMx_CNT=TIMx_CCR1.
292    Toggle = 0b0011,
293    /// Force inactive level - OC1REF is forced low.
294    ForceInactive = 0b0100,
295    /// Force active level - OC1REF is forced high.
296    ForceActive = 0b0101,
297    /// PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT<TIMx_CCR1
298    /// else inactive. In downcounting, channel 1 is inactive (OC1REF=‘0) as long as
299    /// TIMx_CNT>TIMx_CCR1 else active (OC1REF=1).
300    Pwm1 = 0b0110,
301    /// PWM mode 2 - In upcounting, channel 1 is inactive as long as
302    /// TIMx_CNT<TIMx_CCR1 else active. In downcounting, channel 1 is active as long as
303    /// TIMx_CNT>TIMx_CCR1 else inactive.
304    Pwm2 = 0b0111,
305    /// Retriggerable OPM mode 1 - In up-counting mode, the channel is active until a trigger
306    /// event is detected (on TRGI signal). Then, a comparison is performed as in PWM mode 1
307    /// and the channels becomes inactive again at the next update. In down-counting mode, the
308    /// channel is inactive until a trigger event is detected (on TRGI signal). Then, a comparison is
309    /// performed as in PWM mode 1 and the channels becomes inactive again at the next update.
310    RetriggerableOpmMode1 = 0b1000,
311    /// Retriggerable OPM mode 2 - In up-counting mode, the channel is inactive until a
312    /// trigger event is detected (on TRGI signal). Then, a comparison is performed as in PWM
313    /// mode 2 and the channels becomes inactive again at the next update. In down-counting
314    /// mode, the channel is active until a trigger event is detected (on TRGI signal). Then, a
315    /// comparison is performed as in PWM mode 1 and the channels becomes active again at the
316    /// next update.
317    RetriggerableOpmMode2 = 0b1001,
318    /// Combined PWM mode 1 - OC1REF has the same behavior as in PWM mode 1.
319    /// OC1REFC is the logical OR between OC1REF and OC2REF.
320    CombinedPwm1 = 0b1100,
321    /// Combined PWM mode 2 - OC1REF has the same behavior as in PWM mode 2.
322    /// OC1REFC is the logical AND between OC1REF and OC2REF.
323    CombinedPwm2 = 0b1101,
324    /// Asymmetric PWM mode 1 - OC1REF has the same behavior as in PWM mode 1.
325    /// OC1REFC outputs OC1REF when the counter is counting up, OC2REF when it is counting
326    /// down.
327    AsymmetricPwm1 = 0b1110,
328    /// Asymmetric PWM mode 2 - OC1REF has the same behavior as in PWM mode 2.
329    /// /// OC1REFC outputs OC1REF when the counter is counting up, OC2REF when it is counting
330    /// down
331    AsymmetricPwm2 = 0b1111,
332}
333
334/// Update Request source. This bit is set and cleared by software to select the UEV event sources.
335/// Sets `TIMx_CR1` register, `URS` field.
336#[derive(Clone, Copy)]
337#[repr(u8)]
338pub enum UpdateReqSrc {
339    /// Any of the following events generate an update interrupt or DMA request.
340    /// These events can be:
341    /// – Counter overflow/underflow
342    /// – Setting the UG bit
343    /// – Update generation through the slave mode controller
344    Any = 0,
345    /// Only counter overflow/underflow generates an update interrupt or DMA request.
346    OverUnderFlow = 1,
347}
348
349/// Capture/Compaer DMA selection.
350/// Sets `TIMx_CR2` register, `CCDS` field.
351#[derive(Clone, Copy)]
352#[repr(u8)]
353pub enum CaptureCompareDma {
354    /// CCx DMA request sent when CCx event occur
355    Ccx = 0,
356    /// CCx DMA request sent when update event occurs
357    Update = 1,
358}
359
360/// Initial configuration data for Timer peripherals.
361#[derive(Clone)]
362pub struct TimerConfig {
363    /// If `one_pulse_mode` is true, the counter stops counting at the next update event
364    /// (clearing the bit CEN). If false, Counter is not stopped at update event. Defaults to false.
365    /// Sets `TIMx_CR` register, `OPM` field.
366    pub one_pulse_mode: bool,
367    /// Update request source. Ie, counter overflow/underflow only, or any. defaults to any.
368    pub update_request_source: UpdateReqSrc,
369    /// Set `true` to buffer the preload. Useful when changing period and duty while the timer is running.
370    /// Default to false.
371    pub auto_reload_preload: bool,
372    /// Select center or edge alignment. Defaults to edge.
373    pub alignment: Alignment,
374    /// Sets when CCx DMA requests occur. Defaults to on CCx event.
375    pub capture_compare_dma: CaptureCompareDma,
376    /// Timer counting direction. Defaults to up.
377    pub direction: CountDir,
378}
379
380impl Default for TimerConfig {
381    fn default() -> Self {
382        Self {
383            one_pulse_mode: false,
384            update_request_source: UpdateReqSrc::Any,
385            auto_reload_preload: false,
386            alignment: Alignment::Edge,
387            capture_compare_dma: CaptureCompareDma::Ccx,
388            direction: CountDir::Up,
389        }
390    }
391}
392
393/// Represents a General Purpose or Advanced Control timer.
394pub struct Timer<TIM> {
395    /// Register block for the specific timer.
396    pub regs: TIM,
397    /// Our config stucture, for configuration that is written to the timer hardware on initialization
398    /// via the constructor.
399    pub cfg: TimerConfig,
400    /// Associated timer clock speed in Hz.
401    clock_speed: u32,
402    // #[cfg(feature = "monotonic")]
403    // /// Used to indicate the timer has expired, and running time counts (eg the `time_elapsed()` method) properly
404    // /// increment.
405    // pub wrap_count: u32,
406    // #[cfg(feature = "monotonic")]
407    /// Updated in the constructor and `set_freq` fns. Used for mapping timer ticks to time (eg in
408    /// seconds, us etc)
409    ns_per_tick: u64,
410    period: f32, // In seconds. Used for overflow tracking. Updated when `ns_per_tick` is.
411}
412
413macro_rules! make_timer {
414    ($TIMX:ident, $tim:ident, $apb:expr, $res:ident) => {
415        impl Timer<pac::$TIMX> {
416            paste! {
417                /// Initialize a Timer peripheral, including enabling and resetting
418                /// its RCC peripheral clock.
419                ///
420                /// Sets prescaler and auto-reload based on the requested frequency.
421                /// Use `new_timx_manual` to set the prescaler and auto-reload directly.
422                pub fn [<new_ $tim>](regs: pac::$TIMX, freq: f32, cfg: TimerConfig, clocks: &Clocks) -> Self {
423                    let mut result = Self::new_internal(regs, cfg, clocks);
424
425                    result.set_freq(freq).ok();
426                    result.set_dir();
427
428                    // Trigger an update event to load the prescaler value to the clock
429                    // NOTE(write): uses all bits in this register. This also clears the interrupt flag,
430                    // which the EGER update will generate.
431                    result.reinitialize();
432
433                    result
434                }
435
436                /// Initialize a Timer peripheral, including enabling and resetting
437                /// its RCC peripheral clock.
438                pub fn [<new_ $tim _manual>](regs: pac::$TIMX, psc: u16, arr: u32, cfg: TimerConfig, clocks: &Clocks) -> Self {
439                    let mut result = Self::new_internal(regs, cfg, clocks);
440
441                    result.set_prescaler(psc);
442                    result.set_auto_reload(arr);
443                    result.set_dir();
444
445                    // Trigger an update event to load the prescaler value to the clock
446                    // NOTE(write): uses all bits in this register. This also clears the interrupt flag,
447                    // which the EGER update will generate.
448                    result.reinitialize();
449
450                    result
451                }
452
453                #[inline]
454                fn new_internal(regs: pac::$TIMX, cfg: TimerConfig, clocks: &Clocks) -> Self {
455                    let rcc = unsafe { &(*RCC::ptr()) };
456
457                    // `freq` is in Hz.
458                    rcc_en_reset!([<apb $apb>], $tim, rcc);
459
460                    #[cfg(not(feature = "c0"))]
461                    let clock_speed = clocks.[<apb $apb _timer>]();
462                    #[cfg(feature = "c0")]
463                    let clock_speed = clocks.apb1_timer(); // C0 only has one APB
464
465                    regs.cr1().modify(|_, w| {
466                        #[cfg(not(feature = "f373"))]
467                        w.opm().bit(cfg.one_pulse_mode);
468                        w.urs().bit(cfg.update_request_source as u8 != 0);
469                        w.arpe().bit(cfg.auto_reload_preload)
470                    });
471
472                    #[cfg(not(any(feature = "f373", feature = "c0")))]
473                    regs.cr2().modify(|_, w| {
474                        w.ccds().bit(cfg.capture_compare_dma as u8 != 0)
475                    });
476
477                    Timer {
478                        clock_speed,
479                        cfg,
480                        regs,
481                        // #[cfg(feature = "monotonic")]
482                        // wrap_count: 0,
483                        // #[cfg(feature = "monotonic")]
484                        ns_per_tick: 0, // set in `new_timx`
485                        period: 0., // set in `new_timx`
486                    }
487                }
488            }
489
490            /// Enable a specific type of Timer interrupt.
491            pub fn enable_interrupt(&mut self, interrupt: TimerInterrupt) {
492                match interrupt {
493                    TimerInterrupt::Update => self.regs.dier().modify(|_, w| w.uie().bit(true)),
494                    // todo: Only DIER is in PAC, or some CCs. PAC BUG? Only avail on some timers/MCUs?
495                    // TimerInterrupt::Trigger => self.regs.dier().modify(|_, w| w.tie().bit(true)),
496                    // TimerInterrupt::CaptureCompare1 => self.regs.dier().modify(|_, w| w.cc1ie().bit(true)),
497                    // TimerInterrupt::CaptureCompare2 => self.regs.dier().modify(|_, w| w.cc2ie().bit(true)),
498                    // TimerInterrupt::CaptureCompare3 => self.regs.dier().modify(|_, w| w.cc3ie().bit(true)),
499                    // TimerInterrupt::CaptureCompare4 => self.regs.dier().modify(|_, w| w.cc4ie().bit(true)),
500                    #[cfg(not(feature = "f3"))] // todo: Not working on some variants
501                    TimerInterrupt::UpdateDma => self.regs.dier().modify(|_, w| w.ude().bit(true)),
502                    // TimerInterrupt::TriggerDma => self.regs.dier().modify(|_, w| w.tde().bit(true)),
503                    // TimerInterrupt::CaptureCompare1Dma => self.regs.dier().modify(|_, w| w.cc1de().bit(true)),
504                    // TimerInterrupt::CaptureCompare2Dma => self.regs.dier().modify(|_, w| w.ccd2de().bit(true)),
505                    // TimerInterrupt::CaptureCompare3Dma => self.regs.dier().modify(|_, w| w.cc3de().bit(true)),
506                    // TimerInterrupt::CaptureCompare4Dma => self.regs.dier().modify(|_, w| w.cc4de().bit(true)),
507                    _ => unimplemented!("TODO TEMP PROBLEMS"),
508                };
509            }
510
511            /// Disable a specific type of Timer interrupt.
512            pub fn disable_interrupt(&mut self, interrupt: TimerInterrupt) {
513                match interrupt {
514                    TimerInterrupt::Update => self.regs.dier().modify(|_, w| w.uie().clear_bit()),
515                    // todo: Only DIER is in PAC, or some CCs. PAC BUG? Only avail on some timers/MCUs?
516                    // TimerInterrupt::Trigger => self.regs.dier().modify(|_, w| w.tie().clear_bit()),
517                    // TimerInterrupt::CaptureCompare1 => self.regs.dier().modify(|_, w| w.cc1ie().clear_bit()),
518                    // TimerInterrupt::CaptureCompare2 => self.regs.dier().modify(|_, w| w.cc2ie().clear_bit()),
519                    // TimerInterrupt::CaptureCompare3 => self.regs.dier().modify(|_, w| w.cc3ie().clear_bit()),
520                    // TimerInterrupt::CaptureCompare4 => self.regs.dier().modify(|_, w| w.cc4ie().clear_bit()),
521                    #[cfg(not(feature = "f3"))] // todo: Not working on some variants
522                    TimerInterrupt::UpdateDma => self.regs.dier().modify(|_, w| w.ude().clear_bit()),
523                    // TimerInterrupt::TriggerDma => self.regs.dier().modify(|_, w| w.tde().clear_bit()),
524                    // TimerInterrupt::CaptureCompare1Dma => self.regs.dier().modify(|_, w| w.cc1de().clear_bit()),
525                    // TimerInterrupt::CaptureCompare2Dma => self.regs.dier().modify(|_, w| w.ccd2de().clear_bit()),
526                    // TimerInterrupt::CaptureCompare3Dma => self.regs.dier().modify(|_, w| w.cc3de().clear_bit()),
527                    // TimerInterrupt::CaptureCompare4Dma => self.regs.dier().modify(|_, w| w.cc4de().clear_bit()),
528                    _ => unimplemented!("TODO TEMP PROBLEMS"),
529                };
530            }
531
532            /// Clears interrupt associated with this timer.
533            ///
534            /// If the interrupt is not cleared, it will immediately retrigger after
535            /// the ISR has finished. For examlpe, place this at the top of your timer's
536            /// interrupt handler.
537            pub fn clear_interrupt(&mut self, interrupt: TimerInterrupt) {
538                // Note that unlike other clear interrupt functions, for this, we clear the bit instead
539                // of setting it. Due to the way our SVDs are set up not working well with this atomic clear,
540                // we need to make sure we write 1s to the rest of the bits.
541                // todo: Overcapture flags for each CC? DMA interrupts?
542                #[cfg(feature = "c0")]
543                let bits = 0xffff;
544                #[cfg(not(feature = "c0"))]
545                let bits = 0xffff_ffff;
546
547                unsafe {
548                    match interrupt {
549                        TimerInterrupt::Update => self
550                            .regs
551                            .sr()
552                            .write(|w| w.bits(bits).uif().clear_bit()),
553                        // todo: Only DIER is in PAC, or some CCs. PAC BUG? Only avail on some timers?
554                        // TimerInterrupt::Trigger => self.regs.sr().write(|w| w.bits(bits).tif().clear_bit()),
555                        // TimerInterrupt::CaptureCompare1 => self.regs.sr().write(|w| w.bits(bits).cc1if().clear_bit()),
556                        // TimerInterrupt::CaptureCompare2 => self.regs.sr().write(|w| w.bits(bits).cc2if().clear_bit()),
557                        // TimerInterrupt::CaptureCompare3 => self.regs.sr().write(|w| w.bits(bits).cc3if().clear_bit()),
558                        // TimerInterrupt::CaptureCompare4 => self.regs.sr().write(|w| w.bits(bits).cc4if().clear_bit()),
559                        _ => unimplemented!(
560                            "Clearing DMA flags is unimplemented using this function."
561                        ),
562                    };
563                }
564            }
565
566            /// Enable (start) the timer.
567            pub fn enable(&mut self) {
568                self.regs.cr1().modify(|_,w| w.cen().bit(true));
569            }
570
571            /// Disable (stop) the timer.
572            pub fn disable(&mut self) {
573                self.regs.cr1().modify(|_, w| w.cen().clear_bit());
574            }
575
576            /// Check if the timer is enabled.
577            pub fn is_enabled(&self) -> bool {
578                self.regs.cr1().read().cen().bit_is_set()
579            }
580
581            #[cfg(not(feature = "c0"))]
582            /// Print the (raw) contents of the status register.
583            pub fn read_status(&self) -> u32 {
584                unsafe { self.regs.sr().read().bits() }
585            }
586
587            #[cfg(feature = "c0")]
588            /// Print the (raw) contents of the status register.
589            pub fn read_status(&self) -> u16 {
590                unsafe { self.regs.sr().read().bits().try_into().unwrap() }
591            }
592
593            /// Set the timer frequency, in Hz. Overrides the period or frequency set
594            /// in the constructor.
595            pub fn set_freq(&mut self, mut freq: f32) -> Result<()> {
596                assert!(freq > 0.);
597                // todo: Take into account the `timxsw` bit in RCC CFGR3, which may also
598                // todo require an adjustment to freq.
599                match self.cfg.alignment {
600                    Alignment::Edge => (),
601                    _ => freq *= 2.,
602                }
603
604                let (psc, arr) = calc_freq_vals(freq, self.clock_speed)?;
605
606                self.regs.arr().write(|w| unsafe { w.bits(arr.into()) });
607                self.regs.psc().write(|w| unsafe { w.bits(psc.into()) });
608
609                // (PSC+1)*(ARR+1) = TIMclk/Updatefrequency = TIMclk * period
610                // period = (PSC+1)*(ARR+1) / TIMclk
611                // Calculate this based on our actual ARR and PSC values; don't use
612                // the requested frequency or period.
613                let arr_f32 = arr as f32;
614                let period_secs = (psc as f32 + 1.) * ( arr_f32 + 1.) / self.clock_speed as f32;
615                self.ns_per_tick = (period_secs / arr_f32 * 1_000_000_000.) as u64;
616                self.period = period_secs;
617
618                Ok(())
619            }
620
621            /// Set the timer period, in seconds. Overrides the period or frequency set
622            /// in the constructor.
623            pub fn set_period(&mut self, period: f32) -> Result<()> {
624                assert!(period > 0.);
625                self.set_freq(1. / period)
626            }
627
628            /// Set the auto-reload register value. Used for adjusting frequency.
629            pub fn set_auto_reload(&mut self, arr: u32) {
630                // todo: Could be u16 or u32 depending on timer resolution,
631                // todo but this works for now.
632                #[cfg(not(feature = "c0"))]
633                self.regs.arr().write(|w| unsafe { w.bits(arr.into()) });
634                #[cfg(feature = "c0")]
635                self.regs.arr().write(|w| unsafe { w.bits((arr as u32).try_into().unwrap()) });
636            }
637
638            /// Set the prescaler value. Used for adjusting frequency.
639            pub fn set_prescaler(&mut self, psc: u16) {
640                self.regs.psc().write(|w| unsafe { w.bits(psc.into()) });
641            }
642
643            /// Reset the countdown; set the counter to 0.
644            pub fn reset_count(&mut self) {
645                self.regs.cnt().write(|w| unsafe { w.bits(0) });
646            }
647
648            /// UIF Flag in SR register is set when CNT reg is overflow / underflow
649            ///
650            pub fn get_uif(&self ) -> bool {
651                self.regs.sr().read().uif().bit_is_set()
652            }
653
654            pub fn clear_uif(&mut self) {
655                #[cfg(feature = "c0")]
656                let bits = 0xffff;
657                #[cfg(not(feature = "c0"))]
658                let bits = 0xffff_ffff;
659
660                unsafe {
661                    self.regs
662                        .sr()
663                        .write(|w| w.bits(bits).uif().clear_bit());
664                }
665            }
666
667            /// Re-initialize the counter and generates an update of the registers. Note that the prescaler
668            /// counter is cleared too (anyway the prescaler ratio is not affected). The counter is cleared.
669            /// When changing timer frequency (or period) via PSC, you may need to run this. Alternatively, change
670            /// the freq in an update ISR.
671            /// Note from RM, PSC reg: PSC contains the value to be loaded in the active prescaler
672            /// register at each update event
673            /// (including when the counter is cleared through UG bit of TIMx_EGR register or through
674            /// trigger controller when configured in “reset mode”).'
675            /// If you're doing something where the updates can wait a cycle, this isn't required. (eg PWM
676            /// with changing duty period).
677            pub fn reinitialize(&mut self) {
678                self.regs.egr().write(|w| w.ug().bit(true));
679                self.clear_interrupt(TimerInterrupt::Update);
680            }
681
682            /// Read the current counter value.
683            pub fn read_count(&self) -> u32 {
684                // todo: This depends on resolution. We read the whole
685                // todo res and pass a u32 just in case.
686                // self.regs.cnt().read().cnt().bits()
687                self.regs.cnt().read().bits()
688            }
689
690
691            /// Enables PWM output for a given channel and output compare, with an initial duty cycle, in Hz.
692            /// Note: On TIM1 and TIM8, (And others if on C0), you must manually set the `bdtr` register,
693            /// `moe` bit.
694            pub fn enable_pwm_output(
695                &mut self,
696                channel: TimChannel,
697                compare: OutputCompare,
698                duty: f32,
699            ) {
700                self.set_capture_compare_output(channel, CaptureCompare::Output);
701                self.set_preload(channel, true);
702                self.set_output_compare(channel, compare);
703                self.set_duty(channel, (self.get_max_duty() as f32 * duty) as $res);
704                self.enable_capture_compare(channel);
705            }
706
707            /// Return the integer associated with the maximum duty period.
708            pub fn get_max_duty(&self) -> $res {
709                #[cfg(feature = "g0")]
710                return self.regs.arr().read().bits().try_into().unwrap();
711                #[cfg(not(feature = "g0"))]
712                self.regs.arr().read().arr().bits().try_into().unwrap()
713            }
714
715             /// See G4 RM, section 29.4.24: Dma burst mode. "The TIMx timers have the capability to
716             /// generate multiple DMA requests upon a single event.
717             /// The main purpose is to be able to re-program part of the timer multiple times without
718             /// software overhead, but it can also be used to read several registers in a row, at regular
719             /// intervals." This may be used to create arbitrary waveforms by modifying the CCR register
720             /// (base address = 13-16, for CCR1-4), or for implementing duty-cycle based digital protocols.
721            #[cfg(not(any(feature = "g0", feature = "f", feature = "l552", feature = "l4")))]
722            pub unsafe fn write_dma_burst(
723                &mut self,
724                buf: &[u16],
725                base_address: u8,
726                burst_len: u8,
727                dma_channel: DmaChannel,
728                channel_cfg: ChannelCfg,
729                ds_32_bits: bool,
730                dma_periph: dma::DmaPeriph,
731            ) -> Result<()> {
732                // Note: F3 and L4 are unsupported here, since I'm not sure how to select teh
733                // correct Timer channel.
734
735                // todo: Should we disable the timer here?
736
737                let (ptr, len) = (buf.as_ptr(), buf.len());
738
739                // todo: For F3 and L4, manually set channel using PAC for now. Currently
740                // todo we don't have a way here to pick the timer. Could do it with a new macro arg.
741
742                // L44 RM, Table 41. "DMA1 requests for each channel"
743                // #[cfg(any(feature = "f3", feature = "l4"))]
744                // let dma_channel = match tim_channel {
745                //     // SaiChannel::A => DmaInput::Sai1A.dma1_channel(),
746                // };
747                //
748                // #[cfg(feature = "l4")]
749                // match tim_channel {
750                //     SaiChannel::B => dma.channel_select(DmaInput::Sai1B),
751                // };
752
753                // RM:
754                // This example is for the case where every CCRx register has to be updated once. If every
755                // CCRx register is to be updated twice for example, the number of data to transfer should be
756                // 6. Let's take the example of a buffer in the RAM containing data1, data2, data3, data4, data5
757                // and data6. The data is transferred to the CCRx registers as follows: on the first update DMA
758                // request, data1 is transferred to CCR2, data2 is transferred to CCR3, data3 is transferred to
759                // CCR4 and on the second update DMA request, data4 is transferred to CCR2, data5 is
760                // transferred to CCR3 and data6 is transferred to CCR4.
761
762                // 1. Configure the corresponding DMA channel as follows:
763                // –DMA channel peripheral address is the DMAR register address
764                let periph_addr = unsafe { &self.regs.dmar() as *const _ as u32 };
765                // –DMA channel memory address is the address of the buffer in the RAM containing
766                // the data to be transferred by DMA into CCRx registers.
767
768                // Number of data to transfer is our buffer len number of registers we're editing, x
769                // number of half-words written to each reg.
770                let num_data = len as u32;
771
772                // 2.
773                // Configure the DCR register by configuring the DBA and DBL bit fields as follows:
774                // DBL = 3 transfers, DBA = 0xE.
775
776                // The DBL[4:0] bits in the TIMx_DCR register set the DMA burst length. The timer recognizes
777                // a burst transfer when a read or a write access is done to the TIMx_DMAR address), i.e. the
778                // number of transfers (either in half-words or in bytes).
779                // The DBA[4:0] bits in the TIMx_DCR registers define the DMA base address for DMA
780                // transfers (when read/write access are done through the TIMx_DMAR address). DBA is
781                // defined as an offset starting from the address of the TIMx_CR1 register:
782                // Example:
783                // 00000: TIMx_CR1
784                // 00001: TIMx_CR2
785                // 00010: TIMx_SMCR
786                self.regs.dcr().modify(|_, w| unsafe {
787                    w.dba().bits(base_address);
788                    w.dbl().bits(burst_len as u8 - 1)
789                });
790
791                // 3. Enable the TIMx update DMA request (set the UDE bit in the DIER register).
792                // note: Leaving this to application code for now.
793                // self.enable_interrupt(TimerInterrupt::UpdateDma);
794
795                // 4. Enable TIMx
796                self.enable();
797
798                // 5. Enable the DMA channel
799                match dma_periph {
800                    dma::DmaPeriph::Dma1 => {
801                        let mut regs = unsafe { &(*DMA1::ptr()) };
802                        dma::cfg_channel(
803                            &mut regs,
804                            dma_channel,
805                            periph_addr,
806                            ptr as u32,
807                            num_data,
808                            dma::Direction::ReadFromMem,
809                            // Note: This may only be relevant if modifying a reg that changes for 32-bit
810                            // timers, like AAR and CCRx
811                            if ds_32_bits { dma::DataSize::S32} else { dma::DataSize::S16 },
812                            dma::DataSize::S16,
813                            channel_cfg,
814                        )?;
815                    }
816                    #[cfg(dma2)]
817                    dma::DmaPeriph::Dma2 => {
818                        let mut regs = unsafe { &(*pac::DMA2::ptr()) };
819                        dma::cfg_channel(
820                            &mut regs,
821                            dma_channel,
822                            periph_addr,
823                            ptr as u32,
824                            num_data,
825                            dma::Direction::ReadFromMem,
826                            // Note: This may only be relevant if modifying a reg that changes for 32-bit
827                            // timers, like AAR and CCRx
828                            if ds_32_bits { dma::DataSize::S32} else { dma::DataSize::S16 },
829                            dma::DataSize::S16,
830                            channel_cfg,
831                        )?;
832                    }
833                }
834                Ok(())
835            }
836
837            #[cfg(not(any(feature = "g0", feature = "f", feature = "l552", feature = "l4")))]
838            pub unsafe fn read_dma_burst(
839                // todo: Experimenting with input capture.
840                &mut self,
841                buf: &mut [u16],
842                base_address: u8,
843                burst_len: u8,
844                dma_channel: DmaChannel,
845                channel_cfg: ChannelCfg,
846                ds_32_bits: bool,
847                dma_periph: dma::DmaPeriph,
848            ) -> Result<()> {
849                let (ptr, len) = (buf.as_mut_ptr(), buf.len());
850
851                let periph_addr = unsafe { &self.regs.dmar() as *const _ as u32 };
852
853                let num_data = len as u32;
854
855                self.regs.dcr().modify(|_, w| unsafe {
856                    w.dba().bits(base_address);
857                    w.dbl().bits(burst_len as u8 - 1)
858                });
859
860                self.enable();
861
862                match dma_periph {
863                    dma::DmaPeriph::Dma1 => {
864                        #[cfg(not(feature = "c0"))]
865                        let mut regs = unsafe { &(*pac::DMA1::ptr()) };
866                        #[cfg(feature = "c0")]
867                        let mut regs = unsafe { &(*pac::DMA::ptr()) };
868
869                        dma::cfg_channel(
870                            &mut regs,
871                            dma_channel,
872                            periph_addr,
873                            ptr as u32,
874                            num_data,
875                            dma::Direction::ReadFromPeriph,
876                            // Note: This may only be relevant if modifying a reg that changes for 32-bit
877                            // timers, like AAR and CCRx
878                            if ds_32_bits { dma::DataSize::S32} else { dma::DataSize::S16 },
879                            dma::DataSize::S16,
880                            channel_cfg,
881                        )?;
882                    }
883                    #[cfg(dma2)]
884                    dma::DmaPeriph::Dma2 => {
885                        let mut regs = unsafe { &(*pac::DMA2::ptr()) };
886                        dma::cfg_channel(
887                            &mut regs,
888                            dma_channel,
889                            periph_addr,
890                            ptr as u32,
891                            num_data,
892                            dma::Direction::ReadFromPeriph,
893                            // Note: This may only be relevant if modifying a reg that changes for 32-bit
894                            // timers, like AAR and CCRx
895                            if ds_32_bits { dma::DataSize::S32} else { dma::DataSize::S16 },
896                            dma::DataSize::S16,
897                            channel_cfg,
898                        )?;
899                    }
900                }
901                Ok(())
902            }
903
904            /// Get the time elapsed since the start of the timer, taking overflow wraps into account.
905            ///
906            /// Important: the value returned here will only be correct if the ARR and PSC are set
907            /// only using the constructor, `set_freq`, or `set_period` methods.
908            pub fn now(&mut self) -> Instant {
909                // let wrap_count = self.wrap_count;
910                let wrap_count = TICK_OVERFLOW_COUNT.load(Ordering::Acquire);
911
912                let ticks = (self.read_count() as u64 + wrap_count as u64 *
913                    self.get_max_duty() as u64);
914                let count_ns = ticks as i128 * self.ns_per_tick as i128;
915
916                Instant::new(count_ns)
917            }
918
919            pub fn elapsed(&mut self, since: Instant) -> Duration {
920                self.now() - since
921            }
922        }
923
924        #[cfg(feature = "monotonic")]
925        impl Monotonic for Timer<pac::$TIMX> {
926            type Instant = Instant;
927            type Duration = core::time::Duration;
928
929            const DISABLE_INTERRUPT_ON_EMPTY_QUEUE: bool = false;
930
931            fn now(&mut self) -> Self::Instant {
932                self.time_elapsed()
933            }
934
935            /// We use the compare 1 channel for this.
936            /// todo: Support wrapping?
937            fn set_compare(&mut self, instant: Self::Instant) {
938                self.regs
939                    .ccr1()
940                    .write(|w| unsafe { w.ccr().bits(((instant.count_ns as f32 / self.ns_per_tick) as u16).into()) });
941            }
942
943            /// We use the compare 1 channel for this.
944            /// todo: Support wrapping?
945            fn clear_compare_flag(&mut self) {
946                self.regs.sr().modify(|_, w| w.cc1if().clear_bit());
947            }
948
949            fn zero() -> Self::Instant {
950                Instant::default()
951            }
952
953            unsafe fn reset(&mut self) {
954                self.reset_count();
955                TICK_OVERFLOW_COUNT.store(0, Ordering::Release);
956            }
957
958            fn on_interrupt(&mut self) {
959                // self.wrap_count += 1;
960                TICK_OVERFLOW_COUNT.fetch_add(1, Ordering::Relaxed);
961            }
962            fn enable_timer(&mut self) {
963                self.enable();
964            }
965            fn disable_timer(&mut self) {
966                self.disable();
967            }
968
969            /// Print the (raw) contents of the status register.
970            pub fn read_status(&self) -> u32 {
971                unsafe { self.regs.isr().read().bits() }
972            }
973        }
974
975        // cfg_if! {
976        //     if #[cfg(feature = "embedded_hal")] {
977        //         // use embedded_hal::{
978        //         //     blocking::delay::{DelayMs, DelayUs},
979        //         //     timer::CountDown,
980        //         // };
981        //         // use embedded_time::{rate::Hertz, duration};
982        //         // use void::Void;
983        //     }
984        // }
985
986        // #[cfg(feature = "embedded_hal")]
987        // // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
988        // impl DelayMs<u32> for Timer<pac::$TIMX> {
989        //     fn delay_ms(&mut self, ms: u32) {
990        //         let ms_to_s = ms as f32 / 1_000.;
991        //         self.set_freq(1. / (ms_to_s)).ok();
992        //         self.reset_count();
993        //         self.enable();
994        //         while self.get_uif() == false {}
995        //         self.clear_uif();
996        //         self.disable();
997        //     }
998        // }
999        //
1000        // #[cfg(feature = "embedded_hal")]
1001        // // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
1002        // impl DelayMs<u16> for Timer<pac::$TIMX> {
1003        //     fn delay_ms(&mut self, ms: u16) {
1004        //         self.delay_ms(ms as u32)
1005        //     }
1006        // }
1007        //
1008        // #[cfg(feature = "embedded_hal")]
1009        // // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
1010        // impl DelayMs<u8> for Timer<pac::$TIMX> {
1011        //     fn delay_ms(&mut self, ms: u8) {
1012        //         self.delay_ms(ms as u32)
1013        //     }
1014        // }
1015        //
1016        // #[cfg(feature = "embedded_hal")]
1017        // // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
1018        // impl DelayUs<u32> for Timer<pac::$TIMX> {
1019        //     fn delay_us(&mut self, us: u32) {
1020        //         let us_to_s = us as f32 / 1_000_000.;
1021        //         self.set_freq(1. / (us_to_s)).ok();
1022        //         self.reset_count();
1023        //         self.enable();
1024        //         while self.get_uif() == false {}
1025        //         self.clear_uif();
1026        //         self.disable();
1027        //     }
1028        // }
1029        //
1030        // #[cfg(feature = "embedded_hal")]
1031        // // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
1032        // impl DelayUs<u16> for Timer<pac::$TIMX> {
1033        //     fn delay_us(&mut self, us: u16) {
1034        //         self.delay_us(us as u32);
1035        //     }
1036        // }
1037        //
1038        // #[cfg(feature = "embedded_hal")]
1039        // // #[cfg_attr(docsrs, doc(cfg(feature = "embedded_hal")))]
1040        // impl DelayUs<u8> for Timer<pac::$TIMX> {
1041        //     fn delay_us(&mut self, us: u8) {
1042        //         self.delay_us(us as u32);
1043        //     }
1044        // }
1045
1046        // /// Implementation of the embedded-hal CountDown trait
1047        // /// To use Countdown it is prefered to configure new timer in Oneshot mode :
1048        // ///
1049        // ///     Example :
1050        // ///     llet tim16_conf = TimerConfig {
1051        // ///             one_pulse_mode: true,
1052        // ///             ..Default::default()
1053        // ///         };
1054        // ///
1055        // ///     Creation of timer. Here the freq arg value is not important, the freq
1056        // ///         will be changed for each CountDown start timer depends on delay wanted.
1057        // ///
1058        // /// let mut tim16: Timer<TIM16> = Timer::new_tim16(dp.TIM16, 1000., tim16_conf, &clocks);
1059        // ///
1060        // ///
1061        // #[cfg(feature = "embedded_hal")]
1062        // impl CountDown for Timer<pac::$TIMX>
1063        // {
1064        //     type Time = duration::Generic<u32>;
1065        //
1066        //     fn start<T>(&mut self, timeout: T)
1067        //         where
1068        //             T: Into<Self::Time>,
1069        //     {
1070        //
1071        //         //Disable timer and clear flag uif
1072        //         self.disable();
1073        //         self.clear_uif();
1074        //
1075        //         //Get timeout
1076        //         let timeout: Self::Time = timeout.into();
1077        //
1078        //         let denom = timeout.scaling_factor().denominator();
1079        //
1080        //         //Prevent a division by zero
1081        //         if *denom != 0 {
1082        //             //Convert time to seconds
1083        //             let time_to_s = timeout.integer() as f32 / *denom as f32;
1084        //
1085        //             //Configure timer
1086        //             self.set_freq(1. / (time_to_s)).ok();
1087        //             self.reset_count();
1088        //             //Update event to setup prescale and reload registers
1089        //             self.reinitialize();
1090        //             self.clear_uif();
1091        //
1092        //             //start the timer
1093        //             self.enable();
1094        //         }
1095        //
1096        //     }
1097        //
1098        //     /// Wait until the timer has elapsed
1099        //     /// and than clear the event.
1100        //     fn wait(&mut self) -> nb::Result<(), Void> {
1101        //         if !self.get_uif() {
1102        //             Err(nb::Error::WouldBlock)
1103        //         } else {
1104        //             self.clear_uif();
1105        //             self.disable();
1106        //             Ok(())
1107        //         }
1108        //     }
1109        // }
1110    }
1111}
1112
1113macro_rules! cc_slave_mode {
1114    ($TIMX:ident) => {
1115        impl Timer<pac::$TIMX> {
1116            /// Set input slave mode and input trigger. See `InputSlaveMode` and `InputTrigger` documentation for more details.
1117            /// Use `set_input_capture` to configure input channels if required.
1118            ///
1119            /// Note: Some modes (e.g. encoder modes) are unavailable on some timers. Consult the reference manual for specifics.
1120            pub fn set_input_slave_mode(
1121                &mut self,
1122                slave_mode: InputSlaveMode,
1123                trigger: InputTrigger,
1124            ) {
1125                self.regs.smcr().modify(|_, w| unsafe {
1126                    w.sms().bits(slave_mode as u8).ts().bits(trigger as u8)
1127                });
1128            }
1129        }
1130    };
1131}
1132
1133// We use macros to support the varying number of capture compare channels available on
1134// different timers.
1135// Note that there's lots of DRY between these implementations.
1136macro_rules! cc_4_channels {
1137    ($TIMX:ident, $res:ident) => {
1138        impl Timer<pac::$TIMX> {
1139            /// Function that allows us to set direction only on timers that have this option.
1140            pub fn set_dir(&mut self) {
1141                self.regs
1142                    .cr1()
1143                    .modify(|_, w| w.dir().bit(self.cfg.direction as u8 != 0));
1144                self.regs
1145                    .cr1()
1146                    .modify(|_, w| unsafe { w.cms().bits(self.cfg.alignment as u8) });
1147            }
1148
1149            /// Set up input capture, eg for PWM input.
1150            /// L4 RM, section 26.3.8. H723 RM, section 43.3.7.
1151            ///
1152            /// Note: Does not handle TISEL (timer input selection register), ICxPS (input capture prescaler),
1153            /// and ICxF (input capture filter) - you must set these manually using the PAC if hardware defaults are not appropriate.
1154            #[cfg(not(any(
1155                feature = "f",
1156                feature = "l4x5",
1157                feature = "l5",
1158                feature = "g0",
1159                feature = "wb"
1160            )))]
1161            pub fn set_input_capture(
1162                &mut self,
1163                channel: TimChannel,
1164                mode: CaptureCompare,
1165                ccp: Polarity,
1166                ccnp: Polarity,
1167            ) {
1168                // 2. Select the active input for TIMx_CCR1: write the CC1S bits to 01 in the TIMx_CCMR1
1169                // register.
1170                self.set_capture_compare_input(channel, mode);
1171
1172                // 1. Select the proper TI1x source (internal or external) with the TI1SEL[3:0] bits in the
1173                // TIMx_TISEL register.
1174                // Leaving it at its default value of 0 selects the timer input, which we'll hard-code
1175                // for now.
1176                // let tisel = 0b0000;
1177
1178                // 3.
1179                // Program the needed input filter duration in relation with the signal connected to the
1180                // timer (when the input is one of the tim_tix (ICxF bits in the TIMx_CCMRx register). Let’s
1181                // imagine that, when toggling, the input signal is not stable during at must 5 internal clock
1182                // cycles. We must program a filter duration longer than these 5 clock cycles. We can
1183                // validate a transition on tim_ti1 when 8 consecutive samples with the new level have
1184                // been detected (sampled at fDTS frequency). Then write IC1F bits to 0011 in the
1185                // TIMx_CCMR1 register.
1186                // let filter = 0b0000;
1187
1188                match channel {
1189                    TimChannel::C1 => {
1190                        // self.regs.tisel.modify(|_, w| unsafe { w.ti1sel().bits(tisel) });
1191
1192                        // 4. Select the active polarity for TI1FP1 (used both for capture in TIMx_CCR1 and counter
1193                        // clear): write the CC1P and CC1NP bits to ‘0’ (active on rising edge).
1194                        // (Note: We could use the `set_polarity` and `set_complementary_polarity` methods, but
1195                        // this allows us to combine them in a single reg write.)
1196                        self.regs.ccer().modify(|_, w| {
1197                            w.cc1p().bit(ccp.bit());
1198                            w.cc1np().bit(ccnp.bit())
1199                        });
1200
1201                        // 5.
1202                        // Program the input prescaler. In our example, we wish the capture to be performed at
1203                        // each valid transition, so the prescaler is disabled (write IC1PS bits to 00 in the
1204                        // TIMx_CCMR1 register).
1205                        // self.regs.ccmr1_input().modify(|_, w| unsafe {
1206                        //     // todo: PAC ommission?
1207                        //     // w.ic1psc().bits(0b00);
1208                        //     w.ic1f().bits(filter)
1209                        // });
1210                    }
1211                    TimChannel::C2 => {
1212                        // self.regs.tisel.modify(|_, w| unsafe { w.ti2sel().bits(tisel) });
1213
1214                        self.regs.ccer().modify(|_, w| {
1215                            w.cc2p().bit(ccp.bit());
1216                            w.cc2np().bit(ccnp.bit())
1217                        });
1218
1219                        // self.regs.ccmr1_input().modify(|_, w| unsafe {
1220                        //     w.ic2psc().bits(0b00);
1221                        //     w.ic2f().bits(filter)
1222                        // });
1223                    }
1224                    TimChannel::C3 => {
1225                        // self.regs.tisel.modify(|_, w| unsafe { w.ti3sel().bits(tisel) });
1226
1227                        self.regs.ccer().modify(|_, w| {
1228                            w.cc3p().bit(ccp.bit());
1229                            w.cc3np().bit(ccnp.bit())
1230                        });
1231
1232                        // self.regs.ccmr2_input().modify(|_, w| unsafe {
1233                        //     w.ic3psc().bits(0b00);
1234                        //     w.ic3f().bits(filter)
1235                        // });
1236                    }
1237                    #[cfg(not(feature = "wl"))]
1238                    TimChannel::C4 => {
1239                        // self.regs.tisel.modify(|_, w| unsafe { w.ti4sel().bits(tisel) });
1240
1241                        self.regs.ccer().modify(|_, w| {
1242                            #[cfg(not(any(feature = "f4", feature = "l4")))]
1243                            w.cc4np().bit(ccnp.bit());
1244                            w.cc4p().bit(ccp.bit())
1245                        });
1246
1247                        // self.regs.ccmr2_input().modify(|_, w| unsafe {
1248                        //     w.ic4psc().bits(0b00);
1249                        //     w.ic4f().bits(filter)
1250                        // });
1251                    }
1252                }
1253
1254                // 6. Enable capture from the counter into the capture register by setting the CC1E bit in the
1255                // TIMx_CCER register.
1256                self.enable_capture_compare(channel);
1257
1258                // 7.If needed, enable the related interrupt request by setting the CC1IE bit in the
1259                // TIMx_DIER register, and/or the DMA request by setting the CC1DE bit in the
1260                // TIMx_DIER register.
1261            }
1262
1263            // todo: more advanced PWM modes. Asymmetric, combined, center-aligned etc.
1264
1265            /// Set Output Compare Mode. See docs on the `OutputCompare` enum.
1266            /// Note: On TIM1 and TIM8, (And others if on C0), you must manually set the `bdtr` register,
1267            /// `moe` bit.
1268            pub fn set_output_compare(&mut self, channel: TimChannel, mode: OutputCompare) {
1269                match channel {
1270                    TimChannel::C1 => {
1271                        self.regs.ccmr1_output().modify(|_, w| unsafe {
1272                            #[cfg(not(any(feature = "f", feature = "l5", feature = "wb")))]
1273                            w.oc1m_3().bit((mode as u8) >> 3 != 0);
1274                            w.oc1m().bits((mode as u8) & 0b111)
1275                        });
1276                    }
1277                    TimChannel::C2 => {
1278                        self.regs.ccmr1_output().modify(|_, w| unsafe {
1279                            #[cfg(not(any(feature = "f", feature = "l5", feature = "wb")))]
1280                            w.oc2m_3().bit((mode as u8) >> 3 != 0);
1281                            w.oc2m().bits((mode as u8) & 0b111)
1282                        });
1283                    }
1284                    TimChannel::C3 => {
1285                        self.regs.ccmr2_output().modify(|_, w| unsafe {
1286                            #[cfg(not(any(feature = "f", feature = "l5", feature = "wb")))]
1287                            w.oc3m_3().bit((mode as u8) >> 3 != 0);
1288                            w.oc3m().bits((mode as u8) & 0b111)
1289                        });
1290                    }
1291                    #[cfg(not(feature = "wl"))]
1292                    TimChannel::C4 => {
1293                        self.regs.ccmr2_output().modify(|_, w| unsafe {
1294                            #[cfg(not(any(
1295                                feature = "f3",
1296                                feature = "f4",
1297                                feature = "l5",
1298                                feature = "wb",
1299                                feature = "h7"
1300                            )))]
1301                            w.oc4m_3().bit((mode as u8) >> 3 != 0);
1302                            w.oc4m().bits((mode as u8) & 0b111)
1303                        });
1304                    }
1305                }
1306            }
1307
1308            /// Return the set duty period for a given channel. Divide by `get_max_duty()`
1309            /// to find the portion of the duty cycle used.
1310            pub fn get_duty(&self, channel: TimChannel) -> $res {
1311                cfg_if! {
1312                    if #[cfg(any(feature = "wb", feature = "wl"))] {
1313                        (match channel {
1314                            TimChannel::C1 => self.regs.ccr1().read().bits(),
1315                            TimChannel::C2 => self.regs.ccr2().read().bits(),
1316                            TimChannel::C3 => self.regs.ccr3().read().bits(),
1317                            #[cfg(not(feature = "wl"))]
1318                            TimChannel::C4 => self.regs.ccr4().read().bits(),
1319                        }) as $res
1320                    } else {
1321                        match channel {
1322                            TimChannel::C1 => self.regs.ccr1().read().ccr().bits().into(),
1323                            TimChannel::C2 => self.regs.ccr2().read().ccr().bits().into(),
1324                            TimChannel::C3 => self.regs.ccr3().read().ccr().bits().into(),
1325                            #[cfg(not(feature = "wl"))]
1326                            TimChannel::C4 => self.regs.ccr4().read().ccr().bits().into(),
1327                        }
1328                    }
1329                }
1330            }
1331
1332            /// Set the duty cycle, as a portion of ARR (`get_max_duty()`). Note that this
1333            /// needs to be re-run if you change ARR at any point.
1334            pub fn set_duty(&mut self, channel: TimChannel, duty: $res) {
1335                unsafe {
1336                    match channel {
1337                        TimChannel::C1 => self
1338                            .regs
1339                            .ccr1()
1340                            .write(|w| w.ccr().bits(duty.try_into().unwrap())),
1341                        TimChannel::C2 => self
1342                            .regs
1343                            .ccr2()
1344                            .write(|w| w.ccr().bits(duty.try_into().unwrap())),
1345                        TimChannel::C3 => self
1346                            .regs
1347                            .ccr3()
1348                            .write(|w| w.ccr().bits(duty.try_into().unwrap())),
1349                        #[cfg(not(feature = "wl"))]
1350                        TimChannel::C4 => self
1351                            .regs
1352                            .ccr4()
1353                            .write(|w| w.ccr().bits(duty.try_into().unwrap())),
1354                    };
1355                }
1356            }
1357
1358            /// Set timer alignment to Edge, or one of 3 center modes.
1359            /// STM32F303 ref man, section 21.4.1:
1360            /// Bits 6:5 CMS: Center-aligned mode selection
1361            /// 00: Edge-aligned mode. The counter counts up or down depending on the direction bit
1362            /// (DIR).
1363            /// 01: Center-aligned mode 1. The counter counts up and down alternatively. Output compare
1364            /// interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set
1365            /// only when the counter is counting down.
1366            /// 10: Center-aligned mode 2. The counter counts up and down alternatively. Output compare
1367            /// interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set
1368            /// only when the counter is counting up.
1369            /// 11: Center-aligned mode 3. The counter counts up and down alternatively. Output compare
1370            /// interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set
1371            /// both when the counter is counting up or down.
1372            pub fn set_alignment(&mut self, alignment: Alignment) {
1373                self.regs
1374                    .cr1()
1375                    .modify(|_, w| unsafe { w.cms().bits(alignment as u8) });
1376                self.cfg.alignment = alignment;
1377            }
1378
1379            /// Set output polarity. See docs on the `Polarity` enum.
1380            pub fn set_polarity(&mut self, channel: TimChannel, polarity: Polarity) {
1381                match channel {
1382                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1p().bit(polarity.bit())),
1383                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2p().bit(polarity.bit())),
1384                    TimChannel::C3 => self.regs.ccer().modify(|_, w| w.cc3p().bit(polarity.bit())),
1385                    #[cfg(not(feature = "wl"))]
1386                    TimChannel::C4 => self.regs.ccer().modify(|_, w| w.cc4p().bit(polarity.bit())),
1387                };
1388            }
1389
1390            /// Set complementary output polarity. See docs on the `Polarity` enum.
1391            pub fn set_complementary_polarity(&mut self, channel: TimChannel, polarity: Polarity) {
1392                match channel {
1393                    TimChannel::C1 => self
1394                        .regs
1395                        .ccer()
1396                        .modify(|_, w| w.cc1np().bit(polarity.bit())),
1397                    TimChannel::C2 => self
1398                        .regs
1399                        .ccer()
1400                        .modify(|_, w| w.cc2np().bit(polarity.bit())),
1401                    TimChannel::C3 => self
1402                        .regs
1403                        .ccer()
1404                        .modify(|_, w| w.cc3np().bit(polarity.bit())),
1405                    #[cfg(not(any(feature = "f4", feature = "wl", feature = "l4")))]
1406                    TimChannel::C4 => self
1407                        .regs
1408                        .ccer()
1409                        .modify(|_, w| w.cc4np().bit(polarity.bit())),
1410                    #[cfg(any(feature = "f4", feature = "wl", feature = "l4"))] // PAC ommission
1411                    _ => panic!(),
1412                };
1413            }
1414            /// Disables capture compare on a specific channel.
1415            pub fn disable_capture_compare(&mut self, channel: TimChannel) {
1416                match channel {
1417                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1e().clear_bit()),
1418                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2e().clear_bit()),
1419                    TimChannel::C3 => self.regs.ccer().modify(|_, w| w.cc3e().clear_bit()),
1420                    #[cfg(not(feature = "wl"))]
1421                    TimChannel::C4 => self.regs.ccer().modify(|_, w| w.cc4e().clear_bit()),
1422                };
1423            }
1424
1425            /// Enables capture compare on a specific channel.
1426            pub fn enable_capture_compare(&mut self, channel: TimChannel) {
1427                match channel {
1428                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1e().bit(true)),
1429                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2e().bit(true)),
1430                    TimChannel::C3 => self.regs.ccer().modify(|_, w| w.cc3e().bit(true)),
1431                    #[cfg(not(feature = "wl"))]
1432                    TimChannel::C4 => self.regs.ccer().modify(|_, w| w.cc4e().bit(true)),
1433                };
1434            }
1435
1436            /// Set Capture Compare mode in output mode. See docs on the `CaptureCompare` enum.
1437            pub fn set_capture_compare_output(
1438                &mut self,
1439                channel: TimChannel,
1440                mode: CaptureCompare,
1441            ) {
1442                // Note: CC1S bits are writable only when the channel is OFF (CC1E = 0 in TIMx_CCER)
1443                self.disable_capture_compare(channel);
1444
1445                match channel {
1446                    TimChannel::C1 => self
1447                        .regs
1448                        .ccmr1_output()
1449                        .modify(unsafe { |_, w| w.cc1s().bits(mode as u8) }),
1450                    TimChannel::C2 => self
1451                        .regs
1452                        .ccmr1_output()
1453                        .modify(unsafe { |_, w| w.cc2s().bits(mode as u8) }),
1454                    TimChannel::C3 => self
1455                        .regs
1456                        .ccmr2_output()
1457                        .modify(unsafe { |_, w| w.cc3s().bits(mode as u8) }),
1458                    #[cfg(not(feature = "wl"))]
1459                    TimChannel::C4 => self
1460                        .regs
1461                        .ccmr2_output()
1462                        .modify(unsafe { |_, w| w.cc4s().bits(mode as u8) }),
1463                };
1464            }
1465
1466            /// Set Capture Compare mode in input mode. See docs on the `CaptureCompare` enum.
1467            pub fn set_capture_compare_input(&mut self, channel: TimChannel, mode: CaptureCompare) {
1468                // Note: CC1S bits are writable only when the channel is OFF (CC1E = 0 in TIMx_CCER)
1469                self.disable_capture_compare(channel);
1470
1471                match channel {
1472                    TimChannel::C1 => self
1473                        .regs
1474                        .ccmr1_input()
1475                        .modify(unsafe { |_, w| w.cc1s().bits(mode as u8) }),
1476                    TimChannel::C2 => self
1477                        .regs
1478                        .ccmr1_input()
1479                        .modify(unsafe { |_, w| w.cc2s().bits(mode as u8) }),
1480                    TimChannel::C3 => self
1481                        .regs
1482                        .ccmr2_input()
1483                        .modify(unsafe { |_, w| w.cc3s().bits(mode as u8) }),
1484                    #[cfg(not(feature = "wl"))]
1485                    TimChannel::C4 => self
1486                        .regs
1487                        .ccmr2_input()
1488                        .modify(unsafe { |_, w| w.cc4s().bits(mode as u8) }),
1489                };
1490            }
1491
1492            /// Set preload mode.
1493            /// OC1PE: Output Compare 1 preload enable
1494            /// 0: Preload register on TIMx_CCR1 disabled. TIMx_CCR1 can be written at anytime, the
1495            /// new value is taken in account immediately.
1496            /// 1: Preload register on TIMx_CCR1 enabled. Read/Write operations access the preload
1497            /// register. TIMx_CCR1 preload value is loaded in the active register at each update event.
1498            /// Note: 1: These bits can not be modified as long as LOCK level 3 has been programmed
1499            /// (LOCK bits in TIMx_BDTR register) and CC1S=’00’ (the channel is configured in
1500            /// output).
1501            /// 2: The PWM mode can be used without validating the preload register only in one
1502            /// pulse mode (OPM bit set in TIMx_CR1 register). Else the behavior is not guaranteed.
1503            ///
1504            /// Setting preload is required to enable PWM.
1505            pub fn set_preload(&mut self, channel: TimChannel, value: bool) {
1506                match channel {
1507                    TimChannel::C1 => self.regs.ccmr1_output().modify(|_, w| w.oc1pe().bit(value)),
1508                    TimChannel::C2 => self.regs.ccmr1_output().modify(|_, w| w.oc2pe().bit(value)),
1509                    TimChannel::C3 => self.regs.ccmr2_output().modify(|_, w| w.oc3pe().bit(value)),
1510                    #[cfg(not(feature = "wl"))]
1511                    TimChannel::C4 => self.regs.ccmr2_output().modify(|_, w| w.oc4pe().bit(value)),
1512                };
1513
1514                // "As the preload registers are transferred to the shadow registers only when an update event
1515                // occurs, before starting the counter, you have to initialize all the registers by setting the UG
1516                // bit in the TIMx_EGR register."
1517                self.reinitialize();
1518            }
1519        }
1520    };
1521}
1522
1523#[cfg(any(feature = "g0", feature = "g4", feature = "c0"))]
1524macro_rules! cc_2_channels {
1525    ($TIMX:ident, $res:ident) => {
1526        impl Timer<pac::$TIMX> {
1527            /// Function that allows us to set direction only on timers that have this option.
1528            fn set_dir(&mut self) {
1529                // self.regs.cr1().modify(|_, w| w.dir().bit(self.cfg.direction as u8 != 0));
1530            }
1531
1532            // todo: more advanced PWM modes. Asymmetric, combined, center-aligned etc.
1533
1534            /// Set up input capture, eg for PWM input.
1535            /// L4 RM, section 26.3.8. H723 RM, section 43.3.7.
1536            ///
1537            /// Note: Does not handle TISEL (timer input selection register), ICxPS (input capture prescaler),
1538            /// and ICxF (input capture filter) - you must set these manually using the PAC if hardware defaults are not appropriate.
1539            #[cfg(not(any(feature = "f", feature = "l4x5", feature = "l5", feature = "g0")))]
1540            pub fn set_input_capture(
1541                &mut self,
1542                channel: TimChannel,
1543                mode: CaptureCompare,
1544                ccp: Polarity,
1545                ccnp: Polarity,
1546            ) {
1547                self.set_capture_compare_input(channel, mode);
1548
1549                match channel {
1550                    TimChannel::C1 => {
1551                        self.regs.ccer().modify(|_, w| {
1552                            w.cc1p().bit(ccp.bit());
1553                            w.cc1np().bit(ccnp.bit())
1554                        });
1555                    }
1556                    TimChannel::C2 => {
1557                        #[cfg(not(feature = "c0"))]
1558                        self.regs.ccer().modify(|_, w| {
1559                            w.cc2p().bit(ccp.bit());
1560                            w.cc2np().bit(ccnp.bit())
1561                        });
1562                    }
1563                    _ => panic!()
1564                }
1565
1566                // self.regs.smcr().modify(|_, w| unsafe {
1567                //     w.ts().bits(trigger as u8);
1568                //     w.sms().bits(slave_mode as u8)
1569                // });
1570
1571                self.enable_capture_compare(channel);
1572            }
1573
1574            /// Set Output Compare Mode. See docs on the `OutputCompare` enum.
1575            /// Note: On TIM1 and TIM8, (And others if on C0), you must manually set the `bdtr` register,
1576            /// `moe` bit.
1577            pub fn set_output_compare(&mut self, channel: TimChannel, mode: OutputCompare) {
1578                match channel {
1579                    TimChannel::C1 => {
1580                       self.regs.ccmr1_output().modify(|_, w| unsafe {
1581                        #[cfg(not(any(feature = "f4", feature = "l5", feature = "wb")))]
1582                           w.oc1m_3().bit((mode as u8) >> 3 != 0);
1583                           w.oc1m().bits((mode as u8) & 0b111)
1584
1585                        });
1586                    }
1587                    TimChannel::C2 => {
1588                      self.regs.ccmr1_output().modify(|_, w| unsafe {
1589                        #[cfg(not(any(feature = "f4", feature = "l5", feature = "wb")))]
1590                          w.oc2m_3().bit((mode as u8) >> 3 != 0);
1591                          w.oc2m().bits((mode as u8) & 0b111)
1592
1593                        });
1594                    }
1595                    _ => panic!()
1596                }
1597            }
1598
1599            /// Return the set duty period for a given channel. Divide by `get_max_duty()`
1600            /// to find the portion of the duty cycle used.
1601            pub fn get_duty(&self, channel: TimChannel) -> $res {
1602                cfg_if! {
1603                    if #[cfg(feature = "g0")] {
1604                        match channel {
1605                            TimChannel::C1 => self.regs.ccr1().read().bits().try_into().unwrap(),
1606                            TimChannel::C2 => self.regs.ccr2().read().bits().try_into().unwrap(),
1607                            _ => panic!()
1608                        }
1609                    } else if #[cfg(any(feature = "wb", feature = "wl", feature = "l5"))] {
1610                        match channel {
1611                            TimChannel::C1 => self.regs.ccr1().read().ccr1().bits(),
1612                            TimChannel::C2 => self.regs.ccr2().read().ccr2().bits(),
1613                            _ => panic!()
1614                        }
1615                    } else {
1616                        match channel {
1617                            TimChannel::C1 => self.regs.ccr1().read().ccr().bits().try_into().unwrap(),
1618                            TimChannel::C2 => self.regs.ccr2().read().ccr().bits().try_into().unwrap(),
1619                            _ => panic!()
1620                        }
1621                    }
1622                }
1623            }
1624
1625            /// Set the duty cycle, as a portion of ARR (`get_max_duty()`). Note that this
1626            /// needs to be re-run if you change ARR at any point.
1627            pub fn set_duty(&mut self, channel: TimChannel, duty: $res) {
1628                cfg_if! {
1629                    if #[cfg(feature = "g0")] {
1630                        match channel {
1631                            // TimChannel::C1 => self.regs.ccr1().write(|w| w.ccr1().bits(duty.try_into().unwrap())),
1632                            // TimChannel::C2 => self.regs.ccr2().write(|w| w.ccr2().bits(duty.try_into().unwrap())),
1633                            _ => panic!()
1634                        };
1635                    } else if #[cfg(any(feature = "wb", feature = "wl", feature = "l5"))] {
1636                        unsafe {
1637                            match channel {
1638                                TimChannel::C1 => self.regs.ccr1().write(|w| w.ccr1().bits(duty.try_into().unwrap())),
1639                                TimChannel::C2 => self.regs.ccr2().write(|w| w.ccr2().bits(duty.try_into().unwrap())),
1640                                _ => panic!()
1641                            };
1642                        }
1643                    } else {
1644                        unsafe {
1645                            match channel {
1646                                TimChannel::C1 => self.regs.ccr1().write(|w| w.ccr().bits(duty.try_into().unwrap())),
1647                                TimChannel::C2 => self.regs.ccr2().write(|w| w.ccr().bits(duty.try_into().unwrap())),
1648                                _ => panic!()
1649                            };
1650                        }
1651                    }
1652                }
1653            }
1654
1655            /// Set output polarity. See docs on the `Polarity` enum.
1656            pub fn set_polarity(&mut self, channel: TimChannel, polarity: Polarity) {
1657                match channel {
1658                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1p().bit(polarity.bit())),
1659                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2p().bit(polarity.bit())),
1660                    _ => panic!()
1661                };
1662            }
1663
1664            /// Set complementary output polarity. See docs on the `Polarity` enum.
1665            pub fn set_complementary_polarity(&mut self, channel: TimChannel, polarity: Polarity) {
1666                match channel {
1667                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1np().bit(polarity.bit())),
1668                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2np().bit(polarity.bit())),
1669                    _ => panic!()
1670                };
1671            }
1672            /// Disables capture compare on a specific channel.
1673            pub fn disable_capture_compare(&mut self, channel: TimChannel) {
1674                match channel {
1675                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1e().clear_bit()),
1676                    #[cfg(not(feature = "c0"))]
1677                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2e().clear_bit()),
1678                    _ => panic!()
1679                };
1680            }
1681
1682            /// Enables capture compare on a specific channel.
1683            pub fn enable_capture_compare(&mut self, channel: TimChannel) {
1684                match channel {
1685                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1e().bit(true)),
1686                    TimChannel::C2 => self.regs.ccer().modify(|_, w| w.cc2e().bit(true)),
1687                    _ => panic!()
1688                };
1689            }
1690
1691            /// Set Capture Compare mode in output mode. See docs on the `CaptureCompare` enum.
1692            pub fn set_capture_compare_output(&mut self, channel: TimChannel, mode: CaptureCompare) {
1693                self.disable_capture_compare(channel);
1694
1695                match channel {
1696                    TimChannel::C1 => self
1697                        .regs
1698                        .ccmr1_output()
1699                        .modify(unsafe { |_, w| w.cc1s().bits(mode as u8) }),
1700                    #[cfg(not(feature = "c0"))]
1701                    TimChannel::C2 => self
1702                        .regs
1703                        .ccmr1_output()
1704                        .modify(unsafe { |_, w| w.cc2s().bits(mode as u8) }),
1705                    _ => panic!()
1706                };
1707            }
1708
1709            /// Set Capture Compare mode in input mode. See docs on the `CaptureCompare` enum.
1710            pub fn set_capture_compare_input(&mut self, channel: TimChannel, mode: CaptureCompare) {
1711                self.disable_capture_compare(channel);
1712
1713                match channel {
1714                    // Note: CC1S bits are writable only when the channel is OFF (CC1E = 0 in TIMx_CCER)
1715                    TimChannel::C1 => self
1716                        .regs
1717                        .ccmr1_input()
1718                        .modify(unsafe { |_, w| w.cc1s().bits(mode as u8) }),
1719
1720                    #[cfg(not(feature = "c0"))]
1721                    TimChannel::C2 => self
1722                        .regs
1723                        .ccmr1_input()
1724                        .modify(unsafe { |_, w| w.cc2s().bits(mode as u8) }),
1725                        _ => panic!()
1726                };
1727            }
1728
1729            /// Set preload mode.
1730            /// OC1PE: Output Compare 1 preload enable
1731            /// 0: Preload register on TIMx_CCR1 disabled. TIMx_CCR1 can be written at anytime, the
1732            /// new value is taken in account immediately.
1733            /// 1: Preload register on TIMx_CCR1 enabled. Read/Write operations access the preload
1734            /// register. TIMx_CCR1 preload value is loaded in the active register at each update event.
1735            /// Note: 1: These bits can not be modified as long as LOCK level 3 has been programmed
1736            /// (LOCK bits in TIMx_BDTR register) and CC1S=’00’ (the channel is configured in
1737            /// output).
1738            /// 2: The PWM mode can be used without validating the preload register only in one
1739            /// pulse mode (OPM bit set in TIMx_CR1 register). Else the behavior is not guaranteed.
1740            ///
1741            /// Setting preload is required to enable PWM.
1742            pub fn set_preload(&mut self, channel: TimChannel, value: bool) {
1743                match channel {
1744                    TimChannel::C1 => self.regs.ccmr1_output().modify(|_, w| w.oc1pe().bit(value)),
1745                    #[cfg(not(feature = "c0"))]
1746                    TimChannel::C2 => self.regs.ccmr1_output().modify(|_, w| w.oc2pe().bit(value)),
1747                    _ => panic!()
1748                };
1749
1750                // "As the preload registers are transferred to the shadow registers only when an update event
1751                // occurs, before starting the counter, you have to initialize all the registers by setting the UG
1752                // bit in the TIMx_EGR register."
1753                self.reinitialize();
1754            }
1755
1756        }
1757    }
1758}
1759
1760macro_rules! cc_1_channel {
1761    ($TIMX:ident, $res:ident) => {
1762        impl Timer<pac::$TIMX> {
1763            /// Function that allows us to set direction only on timers that have this option.
1764            fn set_dir(&mut self) {} // N/A with these 1-channel timers.
1765
1766            // todo: more advanced PWM modes. Asymmetric, combined, center-aligned etc.
1767
1768            /// Set up input capture, eg for PWM input.
1769            /// L4 RM, section 26.3.8. H723 RM, section 43.3.7.
1770            ///
1771            /// Note: Does not handle TISEL (timer input selection register), ICxPS (input capture prescaler),
1772            /// and ICxF (input capture filter) - you must set these manually using the PAC if hardware defaults are not appropriate.
1773            #[cfg(not(any(feature = "f", feature = "l4x5", feature = "l5", feature = "g0")))]
1774            pub fn set_input_capture(
1775                &mut self,
1776                channel: TimChannel,
1777                mode: CaptureCompare,
1778                ccp: Polarity,
1779                ccnp: Polarity,
1780            ) {
1781                self.set_capture_compare_input(channel, mode);
1782
1783                match channel {
1784                    TimChannel::C1 => {
1785                        self.regs.ccer().modify(|_, w| {
1786                            w.cc1p().bit(ccp.bit());
1787                            w.cc1np().bit(ccnp.bit())
1788                        });
1789                    }
1790                    _ => panic!(),
1791                };
1792
1793                self.enable_capture_compare(channel);
1794            }
1795
1796            /// Set Output Compare Mode. See docs on the `OutputCompare` enum.
1797            /// Note: On TIM1 and TIM8, (And others if on C0), you must manually set the `bdtr` register,
1798            /// `moe` bit.
1799            pub fn set_output_compare(&mut self, channel: TimChannel, mode: OutputCompare) {
1800                match channel {
1801                    TimChannel::C1 => {
1802                        #[cfg(not(feature = "g070"))] // todo: PAC bug?
1803                        self.regs.ccmr1_output().modify(|_, w| unsafe {
1804                            // todo: L5/WB is probably due to a PAC error. Has oc1m_2.
1805                            #[cfg(not(any(
1806                                feature = "f",
1807                                feature = "l4",
1808                                feature = "l5",
1809                                feature = "wb",
1810                                feature = "g0"
1811                            )))]
1812                            w.oc1m_3().bit((mode as u8) >> 3 != 0);
1813                            w.oc1m().bits((mode as u8) & 0b111)
1814                        });
1815                    }
1816                    _ => panic!(),
1817                };
1818            }
1819
1820            /// Return the set duty period for a given channel. Divide by `get_max_duty()`
1821            /// to find the portion of the duty cycle used.
1822            pub fn get_duty(&self, channel: TimChannel) -> $res {
1823                match channel {
1824                    TimChannel::C1 => self.regs.ccr1().read().ccr().bits().try_into().unwrap(),
1825                    _ => panic!(),
1826                }
1827            }
1828
1829            /// Set the duty cycle, as a portion of ARR (`get_max_duty()`). Note that this
1830            /// needs to be re-run if you change ARR at any point.
1831            pub fn set_duty(&mut self, channel: TimChannel, duty: $res) {
1832                unsafe {
1833                    match channel {
1834                        TimChannel::C1 => self
1835                            .regs
1836                            .ccr1()
1837                            .write(|w| w.ccr().bits(duty.try_into().unwrap())),
1838                        _ => panic!(),
1839                    };
1840                }
1841            }
1842
1843            /// Set output polarity. See docs on the `Polarity` enum.
1844            pub fn set_polarity(&mut self, channel: TimChannel, polarity: Polarity) {
1845                match channel {
1846                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1p().bit(polarity.bit())),
1847                    _ => panic!(),
1848                };
1849            }
1850
1851            /// Set complementary output polarity. See docs on the `Polarity` enum.
1852            pub fn set_complementary_polarity(&mut self, channel: TimChannel, polarity: Polarity) {
1853                match channel {
1854                    TimChannel::C1 => self
1855                        .regs
1856                        .ccer()
1857                        .modify(|_, w| w.cc1np().bit(polarity.bit())),
1858                    _ => panic!(),
1859                };
1860            }
1861            /// Disables capture compare on a specific channel.
1862            pub fn disable_capture_compare(&mut self, channel: TimChannel) {
1863                match channel {
1864                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1e().clear_bit()),
1865                    _ => panic!(),
1866                };
1867            }
1868
1869            /// Enables capture compare on a specific channel.
1870            pub fn enable_capture_compare(&mut self, channel: TimChannel) {
1871                match channel {
1872                    TimChannel::C1 => self.regs.ccer().modify(|_, w| w.cc1e().bit(true)),
1873                    _ => panic!(),
1874                };
1875            }
1876
1877            /// Set Capture Compare mode in output mode. See docs on the `CaptureCompare` enum.
1878            pub fn set_capture_compare_output(
1879                &mut self,
1880                channel: TimChannel,
1881                mode: CaptureCompare,
1882            ) {
1883                self.disable_capture_compare(channel);
1884
1885                match channel {
1886                    TimChannel::C1 => self
1887                        .regs
1888                        .ccmr1_output()
1889                        .modify(unsafe { |_, w| w.cc1s().bits(mode as u8) }),
1890                    _ => panic!(),
1891                };
1892            }
1893
1894            /// Set Capture Compare mode in input mode. See docs on the `CaptureCompare` enum.
1895            pub fn set_capture_compare_input(&mut self, channel: TimChannel, mode: CaptureCompare) {
1896                self.disable_capture_compare(channel);
1897
1898                match channel {
1899                    TimChannel::C1 => self
1900                        .regs
1901                        .ccmr1_input()
1902                        .modify(unsafe { |_, w| w.cc1s().bits(mode as u8) }),
1903                    _ => panic!(),
1904                };
1905            }
1906
1907            /// Set preload mode.
1908            /// OC1PE: Output Compare 1 preload enable
1909            /// 0: Preload register on TIMx_CCR1 disabled. TIMx_CCR1 can be written at anytime, the
1910            /// new value is taken in account immediately.
1911            /// 1: Preload register on TIMx_CCR1 enabled. Read/Write operations access the preload
1912            /// register. TIMx_CCR1 preload value is loaded in the active register at each update event.
1913            /// Note: 1: These bits can not be modified as long as LOCK level 3 has been programmed
1914            /// (LOCK bits in TIMx_BDTR register) and CC1S=’00’ (the channel is configured in
1915            /// output).
1916            /// 2: The PWM mode can be used without validating the preload register only in one
1917            /// pulse mode (OPM bit set in TIMx_CR1 register). Else the behavior is not guaranteed.
1918            ///
1919            /// Setting preload is required to enable PWM.
1920            pub fn set_preload(&mut self, channel: TimChannel, value: bool) {
1921                match channel {
1922                    TimChannel::C1 => self.regs.ccmr1_output().modify(|_, w| w.oc1pe().bit(value)),
1923                    _ => panic!(),
1924                };
1925
1926                // "As the preload registers are transferred to the shadow registers only when an update event
1927                // occurs, before starting the counter, you have to initialize all the registers by setting the UG
1928                // bit in the TIMx_EGR register."
1929                self.reinitialize();
1930            }
1931        }
1932    };
1933}
1934
1935/// Calculate values required to set the timer frequency: `PSC` and `ARR`. This can be
1936/// used for initial timer setup, or changing the value later. If used in performance-sensitive
1937/// code or frequently, set ARR and PSC directly instead of using this.
1938fn calc_freq_vals(freq: f32, clock_speed: u32) -> Result<(u16, u16)> {
1939    // `period` and `clock_speed` are both in Hz.
1940
1941    // PSC and ARR range: 0 to 65535
1942    // (PSC+1)*(ARR+1) = TIMclk/Updatefrequency = TIMclk * period
1943    // APB1 (pclk1) is used by Tim2, 3, 4, 6, 7.
1944    // APB2 (pclk2) is used by Tim8, 15-20 etc.
1945
1946    // We need to factor the right-hand-side of the above equation
1947    // into integers. There are likely clever algorithms available to do this.
1948    // Some examples: https://cp-algorithms.com/algebra/factorization.html
1949    // We've chosen something that attempts to maximize ARR, for precision when
1950    // setting duty cycle. Alternative approaches might involve setting a frequency closest to the
1951    // requested one.
1952
1953    // If you work with pure floats, there are an infinite number of solutions: Ie for any value of PSC,
1954    // you can find an ARR to solve the equation.
1955    // The actual values are integers that must be between 0 and 65_536
1956    // Different combinations will result in different amounts of rounding error.
1957
1958    let max_val = 65_535.;
1959    let rhs = clock_speed as f32 / freq;
1960
1961    let psc = ((rhs - 1.) / (1 << 16) as f32).round();
1962    let arr = rhs / (psc + 1.) - 1.;
1963
1964    if arr > max_val || psc > max_val {
1965        return Err(Error::TimerError(TimerError::ValueError));
1966    }
1967
1968    Ok((psc as u16, arr as u16))
1969}
1970
1971cfg_if! {
1972    if #[cfg(not(any(
1973        feature = "f401",
1974        feature = "f410",
1975        feature = "f411",
1976        feature = "f413",
1977        feature = "g031",
1978        feature = "g041",
1979        feature = "g070",
1980        feature = "g030",
1981        feature = "g051",
1982        feature = "c0",
1983        feature = "wb",
1984        feature = "wl"
1985    )))]  {
1986        /// Represents a Basic timer, used primarily to trigger the onboard DAC. Eg Tim6 or Tim7.
1987        pub struct BasicTimer<R> {
1988            pub regs: R,
1989            clock_speed: u32,
1990        }
1991
1992        impl<R> BasicTimer<R>
1993            where
1994                R: Deref<Target = pac::tim6::RegisterBlock> + RccPeriph,
1995        {
1996            /// Initialize a Basic timer, including  enabling and resetting
1997            /// its RCC peripheral clock.
1998            pub fn new(
1999                regs: R,
2000                freq: f32,
2001                clock_cfg: &Clocks,
2002            ) -> Self {
2003                let rcc = unsafe { &(*RCC::ptr()) };
2004                R::en_reset(rcc);
2005
2006                // Self { regs, config, clock_speed: clocks.apb1_timer()  }
2007                let mut result = Self { regs, clock_speed: clock_cfg.apb1_timer()  };
2008
2009                result.set_freq(freq).ok();
2010                result
2011            }
2012
2013            // todo: These fns are DRY from GP timer code!
2014
2015            /// Enable the timer.
2016            pub fn enable(&mut self) {
2017                self.regs.cr1().modify(|_, w| w.cen().bit(true));
2018            }
2019
2020            /// Disable the timer.
2021            pub fn disable(&mut self) {
2022                self.regs.cr1().modify(|_, w| w.cen().clear_bit());
2023            }
2024
2025            /// Check if the timer is enabled.
2026            pub fn is_enabled(&self) -> bool {
2027                self.regs.cr1().read().cen().bit_is_set()
2028            }
2029
2030            /// Set the timer period, in seconds. Overrides the period or frequency set
2031            /// in the constructor.  If changing pe riod frequently, don't use this method, as
2032            /// it has computational overhead: use `set_auto_reload` and `set_prescaler` methods instead.
2033            pub fn set_period(&mut self, time: f32) -> Result<() > {
2034                assert!(time > 0.);
2035                self.set_freq(1. / time)
2036            }
2037
2038            /// Set the timer frequency, in Hz. Overrides the period or frequency set
2039            /// in the constructor. If changing frequency frequently, don't use this method, as
2040            /// it has computational overhead: use `set_auto_reload` and `set_prescaler` methods instead.
2041            pub fn set_freq(&mut self, freq: f32) -> Result<() > {
2042                assert!(freq > 0.);
2043
2044                let (psc, arr) = calc_freq_vals(freq, self.clock_speed)?;
2045
2046                self.regs.arr().write(|w| unsafe { w.bits(arr.into()) });
2047                self.regs.psc().write(|w| unsafe { w.bits(psc.into()) });
2048
2049                Ok(())
2050            }
2051
2052            /// Return the integer associated with the maximum duty period.
2053            pub fn get_max_duty(&self) -> u32 {
2054                return self.regs.arr().read().bits()
2055            }
2056
2057            /// Set the auto-reload register value. Used for adjusting frequency.
2058            pub fn set_auto_reload(&mut self, arr: u16) {
2059                self.regs.arr().write(|w| unsafe { w.bits(arr.into()) });
2060            }
2061
2062            /// Set the prescaler value. Used for adjusting frequency.
2063            pub fn set_prescaler(&mut self, psc: u16) {
2064                self.regs.psc().write(|w| unsafe { w.bits(psc.into()) });
2065            }
2066
2067            /// Reset the count; set the counter to 0.
2068            pub fn reset_count(&mut self) {
2069                self.regs.cnt().write(|w| unsafe { w.bits(0) });
2070            }
2071
2072            /// Read the current counter value.
2073            pub fn read_count(&self) -> u16 {
2074                #[cfg(feature = "l5")]
2075                return self.regs.cnt().read().bits() as u16;
2076                #[cfg(not(feature = "l5"))]
2077                self.regs.cnt().read().cnt().bits()
2078            }
2079
2080            /// Allow selected information to be sent in master mode to slave timers for
2081            /// synchronization (TRGO).
2082            pub fn set_mastermode(&self, mode: MasterModeSelection) {
2083                self.regs.cr2().modify(|_, w| unsafe { w.mms().bits(mode as u8) });
2084            }
2085        }
2086    }
2087}
2088
2089/// A freestanding function that does not require access to a `Timer` struct. Clears the Update interrupt.
2090pub fn clear_update_interrupt(tim_num: u8) {
2091    unsafe {
2092        let periphs = pac::Peripherals::steal();
2093
2094        let bits = 0xffff_ffff;
2095
2096        // Note: `.try_into().unwrap()` is for C0.
2097
2098        match tim_num {
2099            #[cfg(not(any(feature = "f373")))]
2100            1 => {
2101                periphs.TIM1.sr().write(|w| w.bits(bits).uif().clear_bit());
2102            }
2103            #[cfg(not(any(
2104                feature = "f410",
2105                feature = "g070",
2106                feature = "g030",
2107                feature = "g031",
2108                feature = "g050",
2109                feature = "g061",
2110                feature = "c011",
2111                feature = "c031",
2112            )))]
2113            2 => {
2114                periphs
2115                    .TIM2
2116                    .sr()
2117                    .write(|w| w.bits(bits.try_into().unwrap()).uif().clear_bit());
2118            }
2119            #[cfg(not(any(
2120                feature = "f301",
2121                feature = "l4x1",
2122                // feature = "l412",
2123                feature = "l4x3",
2124                feature = "l412",
2125                feature = "f410",
2126                feature = "wb",
2127                feature = "wl"
2128            )))]
2129            3 => {
2130                periphs
2131                    .TIM3
2132                    .sr()
2133                    .write(|w| w.bits(bits.try_into().unwrap()).uif().clear_bit());
2134            }
2135            #[cfg(not(any(
2136                feature = "f301",
2137                feature = "f3x4",
2138                feature = "f410",
2139                feature = "l4x1",
2140                feature = "l4x2",
2141                feature = "l412",
2142                feature = "l4x3",
2143                feature = "g0",
2144                feature = "c0",
2145                feature = "wb",
2146                feature = "wl"
2147            )))]
2148            4 => {
2149                periphs.TIM4.sr().write(|w| w.bits(bits).uif().clear_bit());
2150            }
2151            #[cfg(any(
2152                feature = "f373",
2153                feature = "l4x5",
2154                feature = "l4x6",
2155                feature = "l5",
2156                feature = "h5",
2157                feature = "h7",
2158                feature = "g473",
2159                feature = "g474",
2160                feature = "g483",
2161                feature = "g484",
2162                all(feature = "f4", not(feature = "f410")),
2163            ))]
2164            5 => {
2165                periphs.TIM5.sr().write(|w| w.bits(bits).uif().clear_bit());
2166            }
2167            #[cfg(any(
2168                feature = "f303",
2169                feature = "l4x5",
2170                feature = "l4x6",
2171                feature = "l562",
2172                feature = "h5",
2173                feature = "h7",
2174            ))]
2175            8 => {
2176                periphs.TIM8.sr().write(|w| w.bits(bits).uif().clear_bit());
2177            }
2178            #[cfg(any(feature = "h5",))]
2179            12 => {
2180                periphs.TIM12.sr().write(|w| w.bits(bits).uif().clear_bit());
2181            }
2182            #[cfg(any(feature = "h5",))]
2183            13 => {
2184                periphs.TIM13.sr().write(|w| w.bits(bits).uif().clear_bit());
2185            }
2186            #[cfg(any(feature = "h5", feature = "c0",))]
2187            14 => {
2188                periphs
2189                    .TIM14
2190                    .sr()
2191                    .write(|w| w.bits(bits.try_into().unwrap()).uif().clear_bit());
2192            }
2193            #[cfg(not(any(
2194                feature = "f4",
2195                feature = "g031",
2196                feature = "g031",
2197                feature = "g041",
2198                feature = "g030",
2199                feature = "g051",
2200                feature = "g061",
2201                feature = "wb",
2202                feature = "wl",
2203                feature = "c0",
2204            )))]
2205            15 => {
2206                periphs
2207                    .TIM15
2208                    .sr()
2209                    .write(|w| w.bits(bits.try_into().unwrap()).uif().clear_bit());
2210            }
2211            #[cfg(not(any(feature = "f4",)))]
2212            16 => {
2213                periphs
2214                    .TIM16
2215                    .sr()
2216                    .write(|w| w.bits(bits.try_into().unwrap()).uif().clear_bit());
2217            }
2218            #[cfg(not(any(
2219                feature = "l4x1",
2220                feature = "l4x2",
2221                feature = "l412",
2222                feature = "l4x3",
2223                feature = "f4",
2224            )))]
2225            17 => {
2226                periphs
2227                    .TIM17
2228                    .sr()
2229                    .write(|w| w.bits(bits.try_into().unwrap()).uif().clear_bit());
2230            }
2231            _ => unimplemented!(),
2232        }
2233    };
2234}
2235
2236// /// Experimental approach where we set frequency without taking ownership.
2237// pub fn set_freq(timer: TimerNum, mut freq: f32) -> Result<(), ValueError> {
2238//
2239// }
2240
2241// todo: Non-macro refactor base timer reg blocks:
2242
2243// GP 32-bit: Tim2
2244// 2, 3, 4, 5
2245
2246// GP 16-bit:
2247// 15, 16, 17 // (9-14 on F4) 14 on G0
2248
2249// Basic:
2250// 6, 7
2251
2252// Advanced: 1/8/20
2253
2254#[cfg(not(any(feature = "f373")))]
2255make_timer!(TIM1, tim1, 2, u16);
2256
2257#[cfg(not(any(feature = "f373")))]
2258cc_slave_mode!(TIM1);
2259
2260#[cfg(not(any(feature = "f373", feature = "g0", feature = "g4")))]
2261cc_4_channels!(TIM1, u16);
2262// todo: PAC error?
2263// TIM1 on G4 is nominally 16-bits, but has ~20 bits on ARR, with PAC showing 32 bits?
2264#[cfg(any(feature = "g0", feature = "g4"))]
2265cc_2_channels!(TIM1, u16);
2266
2267cfg_if! {
2268    if #[cfg(not(any(
2269        feature = "f410",
2270        feature = "g070",
2271        feature = "l5", // todo PAC bug?
2272        feature = "wb55", // todo PAC bug?
2273        feature = "g030",
2274        feature = "g031",
2275        feature = "g050",
2276        feature = "g061",
2277        feature = "g031",
2278        feature = "c011",
2279        feature = "c031",
2280    )))] {
2281        make_timer!(TIM2, tim2, 1, u32);
2282        cc_slave_mode!(TIM2);
2283        cc_4_channels!(TIM2, u32);
2284    }
2285}
2286
2287// todo: Note. G4, for example, has TIM2 and 5 as 32-bit, and TIM3 and 4 as 16-bit per RM,
2288// todo: But PAC shows different.
2289cfg_if! {
2290    if #[cfg(not(any(
2291        feature = "f301",
2292        feature = "l4x1",
2293        // feature = "l412",
2294        feature = "l5", // todo PAC bug?
2295        feature = "l4x3",
2296        feature = "l412",
2297        feature = "f410",
2298        feature = "wb",
2299        feature = "wl",
2300    )))] {
2301        make_timer!(TIM3, tim3, 1, u32);
2302        cc_slave_mode!(TIM3);
2303        cc_4_channels!(TIM3, u32);
2304    }
2305}
2306
2307cfg_if! {
2308    if #[cfg(not(any(
2309        feature = "f301",
2310        feature = "f3x4",
2311        feature = "f410",
2312        feature = "l4x1",
2313        feature = "l4x2",
2314        feature = "l412",
2315        feature = "l4x3",
2316        feature = "g0",
2317        feature = "c0",
2318        feature = "wb",
2319        feature = "wl"
2320    )))] {
2321        make_timer!(TIM4, tim4, 1, u32);
2322        cc_slave_mode!(TIM4);
2323        cc_4_channels!(TIM4, u32);
2324    }
2325}
2326
2327cfg_if! {
2328    if #[cfg(any(
2329       feature = "f373",
2330       feature = "l4x5",
2331       feature = "l4x6",
2332       feature = "l562",
2333       feature = "h5",
2334       feature = "h7",
2335       feature = "g473",
2336       feature = "g474",
2337       feature = "g483",
2338       feature = "g484",
2339       all(feature = "f4", not(feature = "f410")),
2340   ))] {
2341        make_timer!(TIM5, tim5, 1, u32);
2342        cc_slave_mode!(TIM5);
2343        cc_4_channels!(TIM5, u32);
2344   }
2345}
2346
2347cfg_if! {
2348    if #[cfg(any(
2349        feature = "f303",
2350        feature = "l4x5",
2351        feature = "l4x6",
2352        feature = "l562",
2353        feature = "h5",
2354        feature = "h7",
2355    ))] {
2356        make_timer!(TIM8, tim8, 2, u16);
2357        cc_slave_mode!(TIM8);
2358        cc_4_channels!(TIM8, u16);
2359    }
2360}
2361
2362// todo: G4 should be 16-bits for TIM8. Why does the PAC use 32?
2363cfg_if! {
2364    if #[cfg(feature = "g4")] {
2365        make_timer!(TIM8, tim8, 2, u32);
2366        cc_slave_mode!(TIM8);
2367        cc_4_channels!(TIM8, u32);
2368    }
2369}
2370
2371cfg_if! {
2372    if #[cfg(feature = "h5")] {
2373        make_timer!(TIM12, tim12, 1, u32);
2374        cc_slave_mode!(TIM12);
2375        cc_2_channels!(TIM12, u32);
2376
2377        make_timer!(TIM13, tim13, 1, u32);
2378        cc_2_channels!(TIM13, u32);
2379
2380        make_timer!(TIM14, tim14, 1, u32);
2381        cc_2_channels!(TIM14, u32);
2382    }
2383}
2384
2385cfg_if! {
2386    if #[cfg(not(any(
2387        feature = "f4",
2388        feature = "g031",
2389        feature = "g031",
2390        feature = "g041",
2391        feature = "g030",
2392        feature = "g051",
2393        feature = "g061",
2394        feature = "wb",
2395        feature = "wl",
2396      // todo: Tim15 is available on c091/02, but I don't see a PAC for that.
2397        feature = "c0",
2398    )))] {
2399        make_timer!(TIM15, tim15, 2, u16);
2400        cc_slave_mode!(TIM15);
2401        // todo: TIM15 on some variant has 2 channels (Eg H7). On others, like L4x3, it appears to be 1.
2402        cc_1_channel!(TIM15, u16);
2403    }
2404}
2405
2406#[cfg(not(any(feature = "f4", feature = "c0")))]
2407make_timer!(TIM16, tim16, 2, u16);
2408#[cfg(not(any(feature = "f4", feature = "c0")))]
2409cc_1_channel!(TIM16, u16);
2410
2411#[cfg(feature = "c0")]
2412make_timer!(TIM16, tim16, 2, u32);
2413#[cfg(feature = "c0")]
2414cc_1_channel!(TIM16, u32);
2415
2416cfg_if! {
2417    if #[cfg(not(any(
2418        feature = "l4x1",
2419        feature = "l4x2",
2420        feature = "l412",
2421        feature = "l4x3",
2422        feature = "f4",
2423    )))] {
2424        make_timer!(TIM17, tim17, 2, u16);
2425        cc_1_channel!(TIM17, u16);
2426    }
2427}
2428
2429cfg_if! {
2430    if #[cfg(any(feature = "f373"))] {
2431        make_timer!(TIM12, tim12, 1, u16);
2432        make_timer!(TIM13, tim13, 1, u16);
2433        make_timer!(TIM14, tim14, 1, u16);
2434        make_timer!(TIM19, tim19, 2, u16);
2435
2436        cc_slave_mode!(TIM12);
2437        cc_slave_mode!(TIM19);
2438
2439        cc_1_channel!(TIM12, u16);
2440        cc_1_channel!(TIM13, u16);
2441        cc_1_channel!(TIM14, u16);
2442        cc_1_channel!(TIM19, u16);
2443    }
2444}
2445
2446// todo: G4 (maybe not all variants?) have TIM20.
2447#[cfg(any(feature = "f303"))]
2448make_timer!(TIM20, tim20, 2, u16);
2449#[cfg(any(feature = "f303"))]
2450cc_slave_mode!(TIM20);
2451#[cfg(any(feature = "f303"))]
2452cc_4_channels!(TIM20, u16);