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