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