stm32_hal2/
timer.rs

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