stm32f3xx_hal/
pwm.rs

1/*!
2  # Pulse width modulation
3
4  Numerous stm32 timers can be used to output pulse width modulated
5  signals on a variety of pins.  The timers support up to 4
6  simultaneous pwm outputs in separate `Channels`.  These channels
7  share a period and resolution, but can have a different duty cycle.
8  All pins on a shared channel have the exact same output.
9
10  ## Creating the (unconfigured) channels
11
12  Before we connect any pins, we need to convert our timer peripheral
13  into a set of channels.  We may only be interested in using one or
14  two of these channels, so we can simply ignore them with `_` when we
15  destructure.
16
17  ```
18    // (Other imports omitted)
19    use stm32f3xx-hal::{pwm::tim3, time::rate::*};
20
21    let dp = stm32f303::Peripherals::take().unwrap();
22
23    let mut flash = dp.FLASH.constrain();
24    let mut rcc = dp.RCC.constrain();
25    let clocks = rcc.cfgr.freeze(&mut flash.acr);
26
27    // Set the resolution of our duty cycle to 9000 and our period to
28    // 50Hz.
29    let mut (c1_no_pins, _, _, c4_no_pins) =
30        tim3(device.TIM3, 9000, 50.Hz(), clocks);
31  ```
32
33  In this case, we're only going to use channel 1 and channel 4.
34  Currently we can't enable these timers, because they don't have any
35  pins, so the following wouldn't compile.
36
37
38  ```
39    // DOES NOT COMPILE
40    c1_no_pins.enable();
41    c4_no_pins.enable();
42  ```
43
44  ## Connecting our pins and enabling the channels
45
46  From here we can connect as many compatible pins as we like.  Once
47  the channels have pins connected they can be enabled.
48
49  ```
50    let mut gpioa = dp.GPIOB.split(&mut rcc.ahb);
51    let pa6 = gpioa.pa6.into_af2(&mut gpioa.moder, &mut gpioa.afrl);
52
53    let mut gpiob = dp.GPIOB.split(&mut rcc.ahb);
54    let pb1 = gpiob.pb1.into_af2(&mut gpiob.moder, &mut gpiob.afrl);
55    let pb4 = gpiob.pb4.into_af2(&mut gpiob.moder, &mut gpiob.afrl);
56
57    let mut ch1 = ch1_no_pins
58        .output_to_pa6(pa6)
59        .output_to_pb4(pb4);
60
61    let mut ch4 = ch4_no_pins
62        .output_to_pb1(pb1);
63
64    ch1.enable();
65    ch4.enable();
66  ```
67
68  All three pins will output a 50Hz period. PA6 and PB4 will share a
69  duty cycle, but the duty cycle for PB1 can be controlled
70  independently.
71
72  ```
73    // Affect PA6 and PB4
74    ch1.set_duty_cycle(1000);
75
76    // Affect only PB1
77    ch4.set_duty_cycle(2000);
78  ```
79
80  ## Single channel timers
81
82  Timers that only have only one channel do not return a tuple, and
83  instead return the (unconfigured) channel directly.
84
85  ```
86    // (Other imports omitted)
87    use stm32f3xx-hal::{pwm::tim16, time::rate::*};
88
89    let dp = stm32f303::Peripherals::take().unwrap();
90
91    let mut flash = dp.FLASH.constrain();
92    let mut rcc = dp.RCC.constrain();
93    let clocks = rcc.cfgr.freeze(&mut flash.acr);
94
95    // Set the resolution of our duty cycle to 9000 and our period to
96    // 50Hz.
97    let mut c1_no_pins = tim16(device.TIM3, 9000, 50.Hz(), clocks);
98  ```
99
100  ## Complementary timers
101
102  Certain timers have complementary outputs.  Currently, channels can
103  output to _either_ pins used for standard or complementary pins (and
104  do not exhibit complementary behaviors).  Most of the time this will
105  be totally invisible.
106
107  In this example, we use a complementary pin in the same way we'd use
108  any other pwm channel.
109
110  ```
111    // (Other imports omitted)
112    use stm32f3xx-hal::{pwm::tim1, time::rate::*};
113
114    let dp = stm32f303::Peripherals::take().unwrap();
115
116    let mut flash = dp.FLASH.constrain();
117    let mut rcc = dp.RCC.constrain();
118    let clocks = rcc.cfgr.freeze(&mut flash.acr);
119
120    // Set the resolution of our duty cycle to 9000 and our period to
121    // 50Hz.
122    let mut (ch1_no_pins, _, _, _) = tim1(device.TIM3, 9000, 50.Hz(), clocks);
123
124    let mut gpioa = dp.GPIOB.split(&mut rcc.ahb);
125    let pa7 = gpioa.pa7.into_af6(&mut gpioa.moder, &mut gpioa.afrl);
126
127    let mut ch1 = ch1_no_pins.output_to(pa7);
128    ch1.enable();
129  ```
130
131  We used this channel/pin exactly like any previous example.
132
133  However, we cannot use standard and complementary pins
134  simultaneously.  Luckily, typestates enforce this for us.
135
136  ```
137    ...
138
139    let mut gpioa = dp.GPIOB.split(&mut rcc.ahb);
140    let pa7 = gpioa.pa7.into_af6(&mut gpioa.moder, &mut gpioa.afrl);
141    let pa8 = gpioa.pa8.into_af6(&mut gpioa.moder, &mut gpioa.afrl);
142
143    let mut ch1 = ch1_no_pins
144        .output_to(pa7)
145        // DOES NOT COMPILE
146        .output_to(pa8);
147  ```
148
149  Once we've connected a complementary pin (PA7) we are now _only_
150  allowed to use other complementary pins.  PA8 is a valid choice if
151  we have no pins in use, but it cannot be used once we've used PA7.
152
153  A usage example can be found at [examples/pwm.rs]
154
155  [examples/pwm.rs]: https://github.com/stm32-rs/stm32f3xx-hal/blob/v0.6.1/examples/pwm.rs
156*/
157
158// FIXME: this PWM module needs refactoring to ensure that no UB / race conditiotns is caused by unsafe acces to
159// mmaped registers.
160#![allow(clippy::undocumented_unsafe_blocks)]
161
162use core::marker::PhantomData;
163
164use crate::{
165    gpio::{self, gpioa, gpiob},
166    hal::PwmPin,
167    pac::{TIM15, TIM16, TIM17, TIM2},
168    rcc::{Clocks, Enable, Reset},
169    time::{fixed_point::FixedPoint, rate::Hertz},
170};
171
172#[cfg(any(
173    feature = "stm32f302xb",
174    feature = "stm32f302xc",
175    feature = "stm32f302xd",
176    feature = "stm32f302xe",
177    feature = "stm32f303xb",
178    feature = "stm32f303xc",
179    feature = "stm32f303xd",
180    feature = "stm32f303xe",
181    feature = "stm32f373",
182    feature = "stm32f378",
183    feature = "stm32f358",
184    feature = "stm32f398",
185))]
186use crate::gpio::gpiod;
187
188#[cfg(any(
189    feature = "stm32f302xb",
190    feature = "stm32f302xc",
191    feature = "stm32f302xd",
192    feature = "stm32f302xe",
193    feature = "stm32f303xb",
194    feature = "stm32f303xc",
195    feature = "stm32f303xd",
196    feature = "stm32f303xe",
197    feature = "stm32f358",
198    feature = "stm32f398",
199))]
200use crate::gpio::gpioe;
201
202#[cfg(any(
203    feature = "stm32f318",
204    feature = "stm32f302",
205    feature = "stm32f303",
206    feature = "stm32f373",
207    feature = "stm32f378",
208    feature = "stm32f334",
209    feature = "stm32f358",
210    feature = "stm32f398",
211))]
212use crate::gpio::{gpioc, gpiof};
213
214/// Output Compare Channel 1 of Timer 1 (type state)
215#[derive(Debug)]
216#[cfg_attr(feature = "defmt", derive(defmt::Format))]
217pub struct Tim2Ch1 {}
218/// Output Compare Channel 2 of Timer 1 (type state)
219#[derive(Debug)]
220#[cfg_attr(feature = "defmt", derive(defmt::Format))]
221pub struct Tim2Ch2 {}
222/// Output Compare Channel 3 of Timer 1 (type state)
223#[derive(Debug)]
224#[cfg_attr(feature = "defmt", derive(defmt::Format))]
225pub struct Tim2Ch3 {}
226/// Output Compare Channel 4 of Timer 1 (type state)
227#[derive(Debug)]
228#[cfg_attr(feature = "defmt", derive(defmt::Format))]
229pub struct Tim2Ch4 {}
230
231/// Output Compare Channel 1 of Timer 15 (type state)
232#[derive(Debug)]
233#[cfg_attr(feature = "defmt", derive(defmt::Format))]
234pub struct Tim15Ch1 {}
235/// Output Compare Channel 2 of Timer 15 (type state)
236#[derive(Debug)]
237#[cfg_attr(feature = "defmt", derive(defmt::Format))]
238pub struct Tim15Ch2 {}
239
240/// Output Compare Channel 1 of Timer 16 (type state)
241#[derive(Debug)]
242#[cfg_attr(feature = "defmt", derive(defmt::Format))]
243pub struct Tim16Ch1 {}
244
245/// Output Compare Channel 1 of Timer 17 (type state)
246#[derive(Debug)]
247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
248pub struct Tim17Ch1 {}
249
250/// Type state used to represent a channel that has no pins yet
251#[derive(Debug)]
252#[cfg_attr(feature = "defmt", derive(defmt::Format))]
253pub struct NoPins {}
254/// Type state used to represent a channel is using regular pins
255#[derive(Debug)]
256#[cfg_attr(feature = "defmt", derive(defmt::Format))]
257pub struct WithPins {}
258/// Type state used to represent a channel is using (only) complementary pins
259#[derive(Debug)]
260#[cfg_attr(feature = "defmt", derive(defmt::Format))]
261pub struct WithNPins {}
262
263/// Representation of a Channel for an abritary timer channel,
264/// that also holds a type state for whether or not this channel
265/// is using any pins yet.
266///
267/// If there are no pins supplied, it cannot be enabled.
268#[derive(Debug)]
269#[cfg_attr(feature = "defmt", derive(defmt::Format))]
270#[allow(clippy::module_name_repetitions)]
271pub struct PwmChannel<X, T> {
272    timx_chy: PhantomData<X>,
273    pin_status: PhantomData<T>,
274}
275
276macro_rules! pwm_timer_private {
277    ($timx:ident, $TIMx:ty, $res:ty, $pclkz:ident, $enable_break_timer:expr, [$($TIMx_CHy:ident),+], [$($x:ident),+]) => {
278        /// Create one or more output channels from a TIM Peripheral
279        /// This function requires the maximum resolution of the duty cycle,
280        /// the period of the PWM signal and the frozen clock configuration.
281        ///
282        /// The resolution should be chosen to offer sufficient steps against
283        /// your target peripheral.  For example, a servo that can turn from
284        /// 0 degrees (2% duty cycle) to 180 degrees (4% duty cycle) might choose
285        /// a resolution of 9000.  This allows the servo to be set in increments
286        /// of exactly one degree.
287        #[allow(unused_parens)]
288        #[must_use]
289        #[deprecated(since = "0.10.0", note = "needs refactoring and might violate safety rules conflicting with the timer API")]
290        pub fn $timx(tim: $TIMx, res: $res, freq: Hertz, clocks: &Clocks) -> ($(PwmChannel<$TIMx_CHy, NoPins>),+) {
291            // Power the timer and reset it to ensure a clean state
292            // We use unsafe here to abstract away this implementation detail
293            // Justification: It is safe because only scopes with mutable references
294            // to TIMx should ever modify this bit.
295            unsafe {
296                <$TIMx>::enable_unchecked();
297                <$TIMx>::reset_unchecked();
298            }
299
300            // enable auto reload preloader
301            tim.cr1.modify(|_, w| w.arpe().set_bit());
302
303            // Set the "resolution" of the duty cycle (ticks before restarting at 0)
304            // Oddly this is unsafe for some timers and not others
305            //
306            // NOTE(write): not all timers are documented in stm32f3, thus marked unsafe.
307            // This write uses all bits of this register so there are no unknown side effects.
308            #[allow(unused_unsafe)]
309            tim.arr.write(|w| unsafe {
310                w.arr().bits(res)
311            });
312
313            // Set the pre-scaler
314            // TODO: This is repeated in the timer/pwm module.
315            // It might make sense to move into the clocks as a crate-only property.
316            // TODO: ppre1 is used in timer.rs (never ppre2), should this be dynamic?
317            let clock_freq = clocks.$pclkz().0 * if clocks.ppre1() == 1 { 1 } else { 2 };
318            let prescale_factor = clock_freq / res as u32 / freq.integer();
319            // NOTE(write): uses all bits of this register.
320            tim.psc.write(|w| w.psc().bits(prescale_factor as u16 - 1));
321
322            // Make the settings reload immediately
323            // NOTE(write): write to a state-less register.
324            tim.egr.write(|w| w.ug().set_bit());
325
326            // Enable outputs (STM32 Break Timer Specific)
327            #[allow(clippy::redundant_closure_call)]
328            $enable_break_timer(&tim);
329
330            // Enable the Timer
331            tim.cr1.modify(|_, w| w.cen().set_bit());
332
333            // TODO: Passing in the constructor is a bit silly,
334            // is there an alternative approach to get this to repeat,
335            // even though its not dynamic?
336            ($($x { timx_chy: PhantomData, pin_status: PhantomData }),+)
337        }
338    }
339}
340
341macro_rules! pwm_timer_basic {
342    ($timx:ident, $TIMx:ty, $res:ty, $pclkz:ident, [$($TIMx_CHy:ident),+], [$($x:ident),+]) => {
343        pwm_timer_private!(
344            $timx,
345            $TIMx,
346            $res,
347            $pclkz,
348            |_| (),
349            [$($TIMx_CHy),+],
350            [$($x),+]
351        );
352    }
353}
354
355macro_rules! pwm_timer_with_break {
356    ($timx:ident, $TIMx:ty, $res:ty, $pclkz:ident, [$($TIMx_CHy:ident),+], [$($x:ident),+]) => {
357        pwm_timer_private!(
358            $timx,
359            $TIMx,
360            $res,
361            $pclkz,
362            |tim: &$TIMx| tim.bdtr.modify(|_, w| w.moe().set_bit()),
363            [$($TIMx_CHy),+],
364            [$($x),+]
365        );
366    }
367}
368
369macro_rules! pwm_channel_pin {
370    ($resulting_state:ident, $TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>, $ccmrz_output:ident, $ocym:ident, $ocype:ident) => {
371        impl PwmChannel<$TIMx_CHy, NoPins> {
372            /// Output to a specific pin from a channel that does not yet have
373            /// any pins.  This channel cannot be enabled until this method
374            /// is called.
375            ///
376            /// The pin is consumed and cannot be returned.
377            #[must_use]
378            pub fn $output_to_pzv<Otype>(
379                self,
380                _p: $gpioz::$PZv<gpio::$AFw<Otype>>,
381            ) -> PwmChannel<$TIMx_CHy, $resulting_state> {
382                unsafe {
383                    (*$TIMx::ptr()).$ccmrz_output().modify(|_, w| {
384                        w
385                            // Select PWM Mode 1 for CHy
386                            .$ocym()
387                            .bits(0b0110)
388                            // set pre-load enable so that updates to the duty cycle
389                            // propagate but _not_ in the middle of a cycle.
390                            .$ocype()
391                            .set_bit()
392                    });
393                }
394                PwmChannel {
395                    timx_chy: PhantomData,
396                    pin_status: PhantomData,
397                }
398            }
399        }
400
401        impl PwmChannel<$TIMx_CHy, $resulting_state> {
402            /// Output to a specific pin from a channel is already configured
403            /// with output pins.  There is no limit to the number of pins that
404            /// can be used (as long as they are compatible).
405            ///
406            /// The pin is consumed and cannot be returned.
407            #[must_use]
408            pub fn $output_to_pzv<Otype>(
409                self,
410                _p: $gpioz::$PZv<gpio::$AFw<Otype>>,
411            ) -> PwmChannel<$TIMx_CHy, $resulting_state> {
412                self
413            }
414        }
415    };
416}
417
418macro_rules! pwm_channel1_pin {
419    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
420        pwm_channel_pin!(
421            WithPins,
422            $TIMx,
423            $TIMx_CHy,
424            $output_to_pzv,
425            $gpioz::$PZv<$AFw>,
426            ccmr1_output,
427            oc1m,
428            oc1pe
429        );
430    };
431}
432
433macro_rules! pwm_channel1n_pin {
434    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
435        pwm_channel_pin!(
436            WithNPins,
437            $TIMx,
438            $TIMx_CHy,
439            $output_to_pzv,
440            $gpioz::$PZv<$AFw>,
441            ccmr1_output,
442            oc1m,
443            oc1pe
444        );
445    };
446}
447
448macro_rules! pwm_channel2_pin {
449    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
450        pwm_channel_pin!(
451            WithPins,
452            $TIMx,
453            $TIMx_CHy,
454            $output_to_pzv,
455            $gpioz::$PZv<$AFw>,
456            ccmr1_output,
457            oc2m,
458            oc2pe
459        );
460    };
461}
462
463#[cfg(any(
464    feature = "stm32f318",
465    feature = "stm32f302",
466    feature = "stm32f303",
467    feature = "stm32f334",
468    feature = "stm32f358",
469    feature = "stm32f398"
470))]
471macro_rules! pwm_channel2n_pin {
472    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
473        pwm_channel_pin!(
474            WithNPins,
475            $TIMx,
476            $TIMx_CHy,
477            $output_to_pzv,
478            $gpioz::$PZv<$AFw>,
479            ccmr1_output,
480            oc2m,
481            oc2pe
482        );
483    };
484}
485
486macro_rules! pwm_channel3_pin {
487    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
488        pwm_channel_pin!(
489            WithPins,
490            $TIMx,
491            $TIMx_CHy,
492            $output_to_pzv,
493            $gpioz::$PZv<$AFw>,
494            ccmr2_output,
495            oc3m,
496            oc3pe
497        );
498    };
499}
500
501#[cfg(any(
502    feature = "stm32f318",
503    feature = "stm32f302",
504    feature = "stm32f303",
505    feature = "stm32f334",
506    feature = "stm32f358",
507    feature = "stm32f398"
508))]
509macro_rules! pwm_channel3n_pin {
510    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
511        pwm_channel_pin!(
512            WithNPins,
513            $TIMx,
514            $TIMx_CHy,
515            $output_to_pzv,
516            $gpioz::$PZv<$AFw>,
517            ccmr2_output,
518            oc3m,
519            oc3pe
520        );
521    };
522}
523
524macro_rules! pwm_channel4_pin {
525    ($TIMx:ident, $TIMx_CHy:ident, $output_to_pzv:ident, $gpioz:ident::$PZv:ident<$AFw:ident>) => {
526        pwm_channel_pin!(
527            WithPins,
528            $TIMx,
529            $TIMx_CHy,
530            $output_to_pzv,
531            $gpioz::$PZv<$AFw>,
532            ccmr2_output,
533            oc4m,
534            oc4pe
535        );
536    };
537}
538
539macro_rules! pwm_pin_for_pwm_channel_private {
540    ($state:ident, $TIMx:ident, $TIMx_CHy:ty, $res:ty, $ccx_enable:ident, $ccrx:ident, $ccrq:ident) => {
541        impl PwmPin for PwmChannel<$TIMx_CHy, $state> {
542            type Duty = $res;
543
544            fn disable(&mut self) {
545                unsafe {
546                    (*$TIMx::ptr())
547                        .ccer
548                        .modify(|_, w| w.$ccx_enable().clear_bit());
549                }
550            }
551
552            fn enable(&mut self) {
553                unsafe {
554                    (*$TIMx::ptr())
555                        .ccer
556                        .modify(|_, w| w.$ccx_enable().set_bit());
557                }
558            }
559
560            fn get_max_duty(&self) -> Self::Duty {
561                unsafe { (*$TIMx::ptr()).arr.read().arr().bits() }
562            }
563
564            fn get_duty(&self) -> Self::Duty {
565                unsafe { (*$TIMx::ptr()).$ccrx().read().$ccrq().bits() }
566            }
567
568            fn set_duty(&mut self, duty: Self::Duty) -> () {
569                unsafe {
570                    (*$TIMx::ptr()).$ccrx().modify(|_, w| w.$ccrq().bits(duty));
571                }
572            }
573        }
574    };
575}
576
577macro_rules! pwm_pin_for_pwm_channel {
578    ($TIMx:ident, $TIMx_CHy:ty, $res:ty, $ccxe:ident, $ccrx:ident, $ccrq:ident) => {
579        pwm_pin_for_pwm_channel_private!(WithPins, $TIMx, $TIMx_CHy, $res, $ccxe, $ccrx, $ccrq);
580    };
581}
582
583macro_rules! pwm_pin_for_pwm_n_channel {
584    ($TIMx:ident, $TIMx_CHy:ty, $res:ty, $ccxe:ident, $ccxne:ident, $ccrx:ident, $ccrq:ident) => {
585        pwm_pin_for_pwm_channel_private!(WithPins, $TIMx, $TIMx_CHy, $res, $ccxe, $ccrx, $ccrq);
586
587        pwm_pin_for_pwm_channel_private!(WithNPins, $TIMx, $TIMx_CHy, $res, $ccxne, $ccrx, $ccrq);
588    };
589}
590
591// TIM1
592
593#[cfg(any(
594    feature = "stm32f318",
595    feature = "stm32f302",
596    feature = "stm32f303",
597    feature = "stm32f334",
598    feature = "stm32f358",
599    feature = "stm32f398"
600))]
601macro_rules! tim1_common {
602    () => {
603        use crate::pac::TIM1;
604
605        /// Output Compare Channel 1 of Timer 1 (type state)
606        pub struct Tim1Ch1 {}
607        /// Output Compare Channel 2 of Timer 1 (type state)
608        pub struct Tim1Ch2 {}
609        /// Output Compare Channel 3 of Timer 1 (type state)
610        pub struct Tim1Ch3 {}
611        /// Output Compare Channel 4 of Timer 1 (type state)
612        pub struct Tim1Ch4 {}
613
614        pwm_timer_with_break!(
615            tim1,
616            TIM1,
617            u16,
618            pclk2,
619            [Tim1Ch1, Tim1Ch2, Tim1Ch3, Tim1Ch4],
620            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
621        );
622
623        // Channels
624        pwm_pin_for_pwm_n_channel!(TIM1, Tim1Ch1, u16, cc1e, cc1ne, ccr1, ccr);
625        pwm_pin_for_pwm_n_channel!(TIM1, Tim1Ch2, u16, cc2e, cc2ne, ccr2, ccr);
626        pwm_pin_for_pwm_n_channel!(TIM1, Tim1Ch3, u16, cc3e, cc3ne, ccr3, ccr);
627        pwm_pin_for_pwm_channel!(TIM1, Tim1Ch4, u16, cc4e, ccr4, ccr);
628
629        //Pins
630        pwm_channel1_pin!(TIM1, Tim1Ch1, output_to_pa8, gpioa::PA8<AF6>);
631
632        pwm_channel1n_pin!(TIM1, Tim1Ch1, output_to_pa7, gpioa::PA7<AF6>);
633        pwm_channel1n_pin!(TIM1, Tim1Ch1, output_to_pa11, gpioa::PA11<AF6>);
634        pwm_channel1n_pin!(TIM1, Tim1Ch1, output_to_pb13, gpiob::PB13<AF6>);
635        pwm_channel1n_pin!(TIM1, Tim1Ch1, output_to_pc13, gpioc::PC13<AF4>);
636
637        pwm_channel2_pin!(TIM1, Tim1Ch2, output_to_pa9, gpioa::PA9<AF6>);
638
639        pwm_channel2n_pin!(TIM1, Tim1Ch2, output_to_pa12, gpioa::PA12<AF6>);
640        pwm_channel2n_pin!(TIM1, Tim1Ch2, output_to_pb0, gpiob::PB0<AF6>);
641        pwm_channel2n_pin!(TIM1, Tim1Ch2, output_to_pb14, gpiob::PB14<AF6>);
642
643        pwm_channel3_pin!(TIM1, Tim1Ch3, output_to_pa10, gpioa::PA10<AF6>);
644
645        pwm_channel3n_pin!(TIM1, Tim1Ch3, output_to_pb1, gpiob::PB1<AF6>);
646        pwm_channel3n_pin!(TIM1, Tim1Ch3, output_to_pb15, gpiob::PB15<AF4>);
647        pwm_channel3n_pin!(TIM1, Tim1Ch3, output_to_pf0, gpiof::PF0<AF6>);
648
649        pwm_channel4_pin!(TIM1, Tim1Ch4, output_to_pa11, gpioa::PA11<AF11>);
650    };
651}
652
653#[cfg(any(feature = "stm32f334", feature = "stm32f398"))]
654macro_rules! tim1_ext1 {
655    () => {
656        pwm_channel1_pin!(TIM1, Tim1Ch1, output_to_pc0, gpioc::PC0<AF2>);
657
658        pwm_channel2_pin!(TIM1, Tim1Ch2, output_to_pc1, gpioc::PC1<AF2>);
659
660        pwm_channel3_pin!(TIM1, Tim1Ch3, output_to_pc2, gpioc::PC2<AF2>);
661
662        pwm_channel4_pin!(TIM1, Tim1Ch4, output_to_pc3, gpioc::PC3<AF2>);
663    };
664}
665
666#[cfg(any(
667    feature = "stm32f302xb",
668    feature = "stm32f302xc",
669    feature = "stm32f302xd",
670    feature = "stm32f302xe",
671    feature = "stm32f303xb",
672    feature = "stm32f303xc",
673    feature = "stm32f303xd",
674    feature = "stm32f303xe",
675    feature = "stm32f358",
676    feature = "stm32f398"
677))]
678macro_rules! tim1_ext2 {
679    () => {
680        pwm_channel1_pin!(TIM1, Tim1Ch1, output_to_pe9, gpioe::PE9<AF2>);
681
682        pwm_channel1n_pin!(TIM1, Tim1Ch1, output_to_pe8, gpioe::PE8<AF2>);
683
684        pwm_channel2_pin!(TIM1, Tim1Ch2, output_to_pe11, gpioe::PE11<AF2>);
685
686        pwm_channel2n_pin!(TIM1, Tim1Ch2, output_to_pe10, gpioe::PE10<AF2>);
687
688        pwm_channel3_pin!(TIM1, Tim1Ch3, output_to_pe13, gpioe::PE13<AF2>);
689
690        pwm_channel3n_pin!(TIM1, Tim1Ch3, output_to_pe12, gpioe::PE12<AF2>);
691
692        pwm_channel4_pin!(TIM1, Tim1Ch4, output_to_pe14, gpioe::PE14<AF2>);
693    };
694}
695
696// TODO: stm32f301 has TIM1 with ext1
697#[cfg(any(
698    feature = "stm32f318",
699    feature = "stm32f302",
700    feature = "stm32f303",
701    feature = "stm32f334",
702    feature = "stm32f358",
703    feature = "stm32f398"
704))]
705tim1_common!();
706
707#[cfg(any(feature = "stm32f334", feature = "stm32f398"))]
708tim1_ext1!();
709
710#[cfg(any(
711    feature = "stm32f302xb",
712    feature = "stm32f302xc",
713    feature = "stm32f302xd",
714    feature = "stm32f302xe",
715    feature = "stm32f303xb",
716    feature = "stm32f303xc",
717    feature = "stm32f303xd",
718    feature = "stm32f303xe",
719    feature = "stm32f358",
720    feature = "stm32f398"
721))]
722tim1_ext2!();
723
724// TIM2
725
726pwm_timer_basic!(
727    tim2,
728    TIM2,
729    u32,
730    pclk1,
731    [Tim2Ch1, Tim2Ch2, Tim2Ch3, Tim2Ch4],
732    [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
733);
734
735// Channels
736pwm_pin_for_pwm_channel!(TIM2, Tim2Ch1, u32, cc1e, ccr1, ccr);
737pwm_pin_for_pwm_channel!(TIM2, Tim2Ch2, u32, cc2e, ccr2, ccr);
738pwm_pin_for_pwm_channel!(TIM2, Tim2Ch3, u32, cc3e, ccr3, ccr);
739pwm_pin_for_pwm_channel!(TIM2, Tim2Ch4, u32, cc4e, ccr4, ccr);
740
741// Pins
742pwm_channel1_pin!(TIM2, Tim2Ch1, output_to_pa0, gpioa::PA0<AF1>);
743pwm_channel1_pin!(TIM2, Tim2Ch1, output_to_pa5, gpioa::PA5<AF1>);
744pwm_channel1_pin!(TIM2, Tim2Ch1, output_to_pa15, gpioa::PA15<AF1>);
745#[cfg(any(
746    feature = "stm32f302xb",
747    feature = "stm32f302xc",
748    feature = "stm32f302xd",
749    feature = "stm32f302xe",
750    feature = "stm32f303xb",
751    feature = "stm32f303xc",
752    feature = "stm32f303xd",
753    feature = "stm32f303xe",
754    feature = "stm32f358",
755    feature = "stm32f398"
756))]
757pwm_channel1_pin!(TIM2, Tim2Ch1, output_to_pd3, gpiod::PD3<AF2>);
758
759pwm_channel2_pin!(TIM2, Tim2Ch2, output_to_pa1, gpioa::PA1<AF1>);
760pwm_channel2_pin!(TIM2, Tim2Ch2, output_to_pb3, gpiob::PB3<AF1>);
761#[cfg(any(
762    feature = "stm32f302xb",
763    feature = "stm32f302xc",
764    feature = "stm32f302xd",
765    feature = "stm32f302xe",
766    feature = "stm32f303xb",
767    feature = "stm32f303xc",
768    feature = "stm32f303xd",
769    feature = "stm32f303xe",
770    feature = "stm32f358",
771    feature = "stm32f398"
772))]
773pwm_channel2_pin!(TIM2, Tim2Ch2, output_to_pd4, gpiod::PD4<AF2>);
774
775pwm_channel3_pin!(TIM2, Tim2Ch3, output_to_pa2, gpioa::PA2<AF1>);
776pwm_channel3_pin!(TIM2, Tim2Ch3, output_to_pa9, gpioa::PA9<AF10>);
777pwm_channel3_pin!(TIM2, Tim2Ch3, output_to_pb10, gpiob::PB10<AF1>);
778#[cfg(any(
779    feature = "stm32f302xb",
780    feature = "stm32f302xc",
781    feature = "stm32f302xd",
782    feature = "stm32f302xe",
783    feature = "stm32f303xb",
784    feature = "stm32f303xc",
785    feature = "stm32f303xd",
786    feature = "stm32f303xe",
787    feature = "stm32f358",
788    feature = "stm32f398"
789))]
790pwm_channel3_pin!(TIM2, Tim2Ch3, output_to_pd7, gpiod::PD7<AF2>);
791
792pwm_channel4_pin!(TIM2, Tim2Ch4, output_to_pa3, gpioa::PA3<AF1>);
793pwm_channel4_pin!(TIM2, Tim2Ch4, output_to_pa10, gpioa::PA10<AF1>);
794#[cfg(not(any(feature = "stm32f373", feature = "stm32f378")))]
795pwm_channel4_pin!(TIM2, Tim2Ch4, output_to_pb11, gpiob::PB11<AF1>);
796#[cfg(any(
797    feature = "stm32f302xb",
798    feature = "stm32f302xc",
799    feature = "stm32f302xd",
800    feature = "stm32f302xe",
801    feature = "stm32f303xb",
802    feature = "stm32f303xc",
803    feature = "stm32f303xd",
804    feature = "stm32f303xe",
805    feature = "stm32f358",
806    feature = "stm32f398"
807))]
808pwm_channel4_pin!(TIM2, Tim2Ch4, output_to_pd6, gpiod::PD6<AF2>);
809
810// TIM3
811
812#[cfg(any(
813    feature = "stm32f302",
814    feature = "stm32f303",
815    feature = "stm32f373",
816    feature = "stm32f378",
817    feature = "stm32f334",
818    feature = "stm32f328",
819    feature = "stm32f358",
820    feature = "stm32f398"
821))]
822macro_rules! tim3_common {
823    () => {
824        use crate::pac::TIM3;
825
826        /// Output Compare Channel 1 of Timer 3 (type state)
827        pub struct Tim3Ch1 {}
828        /// Output Compare Channel 2 of Timer 3 (type state)
829        pub struct Tim3Ch2 {}
830        /// Output Compare Channel 3 of Timer 3 (type state)
831        pub struct Tim3Ch3 {}
832        /// Output Compare Channel 4 of Timer 3 (type state)
833        pub struct Tim3Ch4 {}
834
835        pwm_timer_basic!(
836            tim3,
837            TIM3,
838            u16,
839            pclk1,
840            [Tim3Ch1, Tim3Ch2, Tim3Ch3, Tim3Ch4],
841            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
842        );
843
844        // Channels
845        pwm_pin_for_pwm_channel!(TIM3, Tim3Ch1, u16, cc1e, ccr1, ccr);
846        pwm_pin_for_pwm_channel!(TIM3, Tim3Ch2, u16, cc2e, ccr2, ccr);
847        pwm_pin_for_pwm_channel!(TIM3, Tim3Ch3, u16, cc3e, ccr3, ccr);
848        pwm_pin_for_pwm_channel!(TIM3, Tim3Ch4, u16, cc4e, ccr4, ccr);
849
850        // Pins
851        pwm_channel1_pin!(TIM3, Tim3Ch1, output_to_pa6, gpioa::PA6<AF2>);
852        pwm_channel1_pin!(TIM3, Tim3Ch1, output_to_pb4, gpiob::PB4<AF2>);
853
854        pwm_channel2_pin!(TIM3, Tim3Ch2, output_to_pa4, gpioa::PA4<AF2>);
855        pwm_channel2_pin!(TIM3, Tim3Ch2, output_to_pa7, gpioa::PA7<AF2>);
856        pwm_channel2_pin!(TIM3, Tim3Ch2, output_to_pb5, gpiob::PB5<AF2>);
857
858        pwm_channel3_pin!(TIM3, Tim3Ch3, output_to_pb0, gpiob::PB0<AF2>);
859
860        pwm_channel4_pin!(TIM3, Tim3Ch4, output_to_pb1, gpiob::PB1<AF2>);
861        pwm_channel4_pin!(TIM3, Tim3Ch4, output_to_pb7, gpiob::PB7<AF10>);
862    };
863}
864
865#[cfg(any(
866    feature = "stm32f302",
867    feature = "stm32f303",
868    feature = "stm32f373",
869    feature = "stm32f378",
870    feature = "stm32f334",
871    feature = "stm32f358",
872    feature = "stm32f398"
873))]
874macro_rules! tim3_ext1 {
875    () => {
876        pwm_channel1_pin!(TIM3, Tim3Ch1, output_to_pc6, gpioc::PC6<AF2>);
877
878        pwm_channel2_pin!(TIM3, Tim3Ch2, output_to_pc7, gpioc::PC7<AF2>);
879
880        pwm_channel3_pin!(TIM3, Tim3Ch3, output_to_pc8, gpioc::PC8<AF2>);
881
882        pwm_channel4_pin!(TIM3, Tim3Ch4, output_to_pc9, gpioc::PC9<AF2>);
883    };
884}
885
886#[cfg(any(
887    feature = "stm32f302xb",
888    feature = "stm32f302xc",
889    feature = "stm32f302xd",
890    feature = "stm32f302xe",
891    feature = "stm32f303xb",
892    feature = "stm32f303xc",
893    feature = "stm32f303xd",
894    feature = "stm32f303xe",
895    feature = "stm32f358",
896    feature = "stm32f398"
897))]
898macro_rules! tim3_ext2 {
899    () => {
900        pwm_channel1_pin!(TIM3, Tim3Ch1, output_to_pe2, gpioe::PE6<AF2>);
901
902        pwm_channel2_pin!(TIM3, Tim3Ch2, output_to_pe3, gpioe::PE7<AF2>);
903
904        pwm_channel3_pin!(TIM3, Tim3Ch3, output_to_pe4, gpioe::PE8<AF2>);
905
906        pwm_channel4_pin!(TIM3, Tim3Ch4, output_to_pe5, gpioe::PE9<AF2>);
907    };
908}
909
910#[cfg(any(
911    feature = "stm32f302",
912    feature = "stm32f303",
913    feature = "stm32f373",
914    feature = "stm32f378",
915    feature = "stm32f334",
916    feature = "stm32f328",
917    feature = "stm32f358",
918    feature = "stm32f398"
919))]
920tim3_common!();
921
922#[cfg(any(
923    feature = "stm32f302",
924    feature = "stm32f303",
925    feature = "stm32f373",
926    feature = "stm32f378",
927    feature = "stm32f334",
928    feature = "stm32f358",
929    feature = "stm32f398"
930))]
931tim3_ext1!();
932
933#[cfg(any(
934    feature = "stm32f302xb",
935    feature = "stm32f302xc",
936    feature = "stm32f302xd",
937    feature = "stm32f302xe",
938    feature = "stm32f303xb",
939    feature = "stm32f303xc",
940    feature = "stm32f303xd",
941    feature = "stm32f303xe",
942    feature = "stm32f358",
943    feature = "stm32f398"
944))]
945tim3_ext2!();
946
947#[cfg(feature = "stm32f373")]
948pwm_channel2_pin!(TIM3, Tim3Ch2, output_to_pb0, gpiob::PB0<AF10>);
949
950#[cfg(any(feature = "stm32f373", feature = "stm32f378"))]
951pwm_channel3_pin!(TIM3, Tim3Ch3, output_to_pb6, gpiob::PB6<AF10>);
952
953// TIM4
954
955#[cfg(any(
956    feature = "stm32f302",
957    feature = "stm32f303",
958    feature = "stm32f373",
959    feature = "stm32f378",
960    feature = "stm32f358",
961    feature = "stm32f398"
962))]
963macro_rules! tim4_common {
964    () => {
965        use crate::pac::TIM4;
966
967        /// Output Compare Channel 1 of Timer 4 (type state)
968        pub struct Tim4Ch1 {}
969        /// Output Compare Channel 2 of Timer 4 (type state)
970        pub struct Tim4Ch2 {}
971        /// Output Compare Channel 3 of Timer 4 (type state)
972        pub struct Tim4Ch3 {}
973        /// Output Compare Channel 4 of Timer 4 (type state)
974        pub struct Tim4Ch4 {}
975
976        pwm_timer_basic!(
977            tim4,
978            TIM4,
979            u16,
980            pclk1,
981            [Tim4Ch1, Tim4Ch2, Tim4Ch3, Tim4Ch4],
982            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
983        );
984
985        // Channels
986        pwm_pin_for_pwm_channel!(TIM4, Tim4Ch1, u16, cc1e, ccr1, ccr);
987        pwm_pin_for_pwm_channel!(TIM4, Tim4Ch2, u16, cc2e, ccr2, ccr);
988        pwm_pin_for_pwm_channel!(TIM4, Tim4Ch3, u16, cc3e, ccr3, ccr);
989        pwm_pin_for_pwm_channel!(TIM4, Tim4Ch4, u16, cc4e, ccr4, ccr);
990
991        // Pins
992        pwm_channel1_pin!(TIM4, Tim4Ch1, output_to_pa11, gpioa::PA11<AF10>);
993        pwm_channel1_pin!(TIM4, Tim4Ch1, output_to_pb6, gpiob::PB6<AF2>);
994
995        pwm_channel2_pin!(TIM4, Tim4Ch2, output_to_pa12, gpioa::PA12<AF10>);
996        pwm_channel2_pin!(TIM4, Tim4Ch2, output_to_pb7, gpiob::PB7<AF2>);
997
998        pwm_channel3_pin!(TIM4, Tim4Ch3, output_to_pa13, gpioa::PA13<AF10>);
999        pwm_channel3_pin!(TIM4, Tim4Ch3, output_to_pb8, gpiob::PB8<AF2>);
1000
1001        pwm_channel4_pin!(TIM4, Tim4Ch4, output_to_pb9, gpiob::PB9<AF2>);
1002    };
1003}
1004
1005#[cfg(any(
1006    feature = "stm32f302xb",
1007    feature = "stm32f302xc",
1008    feature = "stm32f302xd",
1009    feature = "stm32f302xe",
1010    feature = "stm32f303xb",
1011    feature = "stm32f303xc",
1012    feature = "stm32f303xd",
1013    feature = "stm32f303xe",
1014    feature = "stm32f373",
1015    feature = "stm32f378",
1016    feature = "stm32f358",
1017    feature = "stm32f398"
1018))]
1019macro_rules! tim4_ext {
1020    () => {
1021        pwm_channel1_pin!(TIM4, Tim4Ch1, output_to_pd12, gpiod::PD12<AF2>);
1022
1023        pwm_channel2_pin!(TIM4, Tim4Ch2, output_to_pd13, gpiod::PD13<AF2>);
1024
1025        pwm_channel3_pin!(TIM4, Tim4Ch3, output_to_pd14, gpiod::PD14<AF2>);
1026
1027        pwm_channel4_pin!(TIM4, Tim4Ch4, output_to_pd15, gpiod::PD15<AF2>);
1028        pwm_channel4_pin!(TIM4, Tim4Ch4, output_to_pf6, gpiof::PF6<AF2>);
1029    };
1030}
1031
1032#[cfg(any(
1033    feature = "stm32f302",
1034    feature = "stm32f303",
1035    feature = "stm32f373",
1036    feature = "stm32f378",
1037    feature = "stm32f358",
1038    feature = "stm32f398"
1039))]
1040tim4_common!();
1041
1042#[cfg(any(
1043    feature = "stm32f302xb",
1044    feature = "stm32f302xc",
1045    feature = "stm32f302xd",
1046    feature = "stm32f302xe",
1047    feature = "stm32f303xb",
1048    feature = "stm32f303xc",
1049    feature = "stm32f303xd",
1050    feature = "stm32f303xe",
1051    feature = "stm32f373",
1052    feature = "stm32f378",
1053    feature = "stm32f358",
1054    feature = "stm32f398"
1055))]
1056tim4_ext!();
1057
1058// TIM5
1059
1060#[cfg(feature = "stm32f373")]
1061macro_rules! tim5 {
1062    () => {
1063        use crate::pac::TIM5;
1064
1065        /// Output Compare Channel 1 of Timer 5 (type state)
1066        pub struct Tim5Ch1 {}
1067        /// Output Compare Channel 2 of Timer 5 (type state)
1068        pub struct Tim5Ch2 {}
1069        /// Output Compare Channel 3 of Timer 5 (type state)
1070        pub struct Tim5Ch3 {}
1071        /// Output Compare Channel 4 of Timer 5 (type state)
1072        pub struct Tim5Ch4 {}
1073
1074        pwm_timer_basic!(
1075            tim5,
1076            TIM5,
1077            u32,
1078            pclk1,
1079            [Tim5Ch1, Tim5Ch2, Tim5Ch3, Tim5Ch4],
1080            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
1081        );
1082
1083        // Channels
1084        pwm_pin_for_pwm_channel!(TIM5, Tim5Ch1, u32, cc1e, ccr1, ccr);
1085        pwm_pin_for_pwm_channel!(TIM5, Tim5Ch2, u32, cc2e, ccr2, ccr);
1086        pwm_pin_for_pwm_channel!(TIM5, Tim5Ch3, u32, cc3e, ccr3, ccr);
1087        pwm_pin_for_pwm_channel!(TIM5, Tim5Ch4, u32, cc4e, ccr4, ccr);
1088
1089        // Pins
1090        pwm_channel1_pin!(TIM5, Tim5Ch1, output_to_pa0, gpioa::PA0<AF2>);
1091        pwm_channel1_pin!(TIM5, Tim5Ch1, output_to_pa8, gpioa::PA8<AF2>);
1092        pwm_channel1_pin!(TIM5, Tim5Ch1, output_to_pc0, gpioc::PC0<AF2>);
1093
1094        pwm_channel2_pin!(TIM5, Tim5Ch2, output_to_pa1, gpioa::PA1<AF2>);
1095        pwm_channel2_pin!(TIM5, Tim5Ch2, output_to_pa11, gpioa::PA11<AF2>);
1096        pwm_channel2_pin!(TIM5, Tim5Ch2, output_to_pc1, gpioc::PC1<AF2>);
1097
1098        pwm_channel3_pin!(TIM5, Tim5Ch3, output_to_pa2, gpioa::PA2<AF2>);
1099        pwm_channel3_pin!(TIM5, Tim5Ch3, output_to_pa12, gpioa::PA12<AF2>);
1100        pwm_channel3_pin!(TIM5, Tim5Ch3, output_to_pc2, gpioc::PC2<AF2>);
1101
1102        pwm_channel4_pin!(TIM5, Tim5Ch4, output_to_pa3, gpioa::PA3<AF2>);
1103        pwm_channel4_pin!(TIM5, Tim5Ch4, output_to_pa13, gpioa::PA13<AF2>);
1104        pwm_channel4_pin!(TIM5, Tim5Ch4, output_to_pc3, gpioc::PC3<AF2>);
1105    };
1106}
1107
1108// TODO: This timer is also present in stm32f378
1109#[cfg(feature = "stm32f373")]
1110tim5!();
1111
1112// TIM8
1113
1114#[cfg(any(feature = "stm32f303", feature = "stm32f358", feature = "stm32f398"))]
1115macro_rules! tim8 {
1116    () => {
1117        use crate::pac::TIM8;
1118
1119        /// Output Compare Channel 1 of Timer 8 (type state)
1120        pub struct Tim8Ch1 {}
1121        /// Output Compare Channel 2 of Timer 8 (type state)
1122        pub struct Tim8Ch2 {}
1123        /// Output Compare Channel 3 of Timer 8 (type state)
1124        pub struct Tim8Ch3 {}
1125        /// Output Compare Channel 4 of Timer 8 (type state)
1126        pub struct Tim8Ch4 {}
1127
1128        pwm_timer_with_break!(
1129            tim8,
1130            TIM8,
1131            u16,
1132            pclk2,
1133            [Tim8Ch1, Tim8Ch2, Tim8Ch3, Tim8Ch4],
1134            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
1135        );
1136
1137        // Channels
1138        pwm_pin_for_pwm_n_channel!(TIM8, Tim8Ch1, u16, cc1e, cc1ne, ccr1, ccr);
1139        pwm_pin_for_pwm_n_channel!(TIM8, Tim8Ch2, u16, cc2e, cc2ne, ccr2, ccr);
1140        pwm_pin_for_pwm_n_channel!(TIM8, Tim8Ch3, u16, cc3e, cc3ne, ccr3, ccr);
1141        pwm_pin_for_pwm_channel!(TIM8, Tim8Ch4, u16, cc4e, ccr4, ccr);
1142
1143        //Pins
1144        pwm_channel1_pin!(TIM8, Tim8Ch1, output_to_pa15, gpioa::PA15<AF2>);
1145        pwm_channel1_pin!(TIM8, Tim8Ch1, output_to_pb6, gpiob::PB6<AF2>);
1146        pwm_channel1_pin!(TIM8, Tim8Ch1, output_to_pc6, gpioc::PC6<AF4>);
1147
1148        pwm_channel1n_pin!(TIM8, Tim8Ch1, output_to_pa7, gpioa::PA7<AF4>);
1149        pwm_channel1n_pin!(TIM8, Tim8Ch1, output_to_pb3, gpiob::PB3<AF4>);
1150        pwm_channel1n_pin!(TIM8, Tim8Ch1, output_to_pc10, gpioc::PC10<AF4>);
1151
1152        pwm_channel2_pin!(TIM8, Tim8Ch2, output_to_pa14, gpioa::PA14<AF5>);
1153        pwm_channel2_pin!(TIM8, Tim8Ch2, output_to_pb8, gpiob::PB8<AF10>);
1154        pwm_channel2_pin!(TIM8, Tim8Ch2, output_to_pc7, gpioc::PC7<AF4>);
1155
1156        pwm_channel2n_pin!(TIM8, Tim8Ch2, output_to_pb0, gpiob::PB0<AF4>);
1157        pwm_channel2n_pin!(TIM8, Tim8Ch2, output_to_pb4, gpiob::PB4<AF4>);
1158        pwm_channel2n_pin!(TIM8, Tim8Ch2, output_to_pc11, gpioc::PC11<AF4>);
1159
1160        pwm_channel3_pin!(TIM8, Tim8Ch3, output_to_pb9, gpiob::PB9<AF10>);
1161        pwm_channel3_pin!(TIM8, Tim8Ch3, output_to_pc8, gpioc::PC8<AF4>);
1162
1163        pwm_channel3n_pin!(TIM8, Tim8Ch3, output_to_pb1, gpiob::PB1<AF4>);
1164        pwm_channel3n_pin!(TIM8, Tim8Ch3, output_to_pb5, gpiob::PB5<AF3>);
1165        pwm_channel3n_pin!(TIM8, Tim8Ch3, output_to_pc12, gpioc::PC12<AF4>);
1166
1167        pwm_channel4_pin!(TIM8, Tim8Ch4, output_to_pc9, gpioc::PC9<AF4>);
1168    };
1169}
1170
1171#[cfg(any(feature = "stm32f303", feature = "stm32f358", feature = "stm32f398"))]
1172tim8!();
1173
1174#[cfg(any(
1175    feature = "stm32f303xb",
1176    feature = "stm32f303xc",
1177    feature = "stm32f303xd",
1178    feature = "stm32f303xe",
1179    feature = "stm32f358",
1180    feature = "stm32f398"
1181))]
1182pwm_channel4_pin!(TIM8, Tim8Ch4, output_to_pd1, gpiod::PD1<AF4>);
1183
1184// TIM12
1185
1186#[cfg(feature = "stm32f373")]
1187macro_rules! tim12 {
1188    () => {
1189        use crate::pac::TIM12;
1190
1191        /// Output Compare Channel 1 of Timer 12 (type state)
1192        pub struct Tim12Ch1 {}
1193        /// Output Compare Channel 2 of Timer 12 (type state)
1194        pub struct Tim12Ch2 {}
1195        /// Output Compare Channel 3 of Timer 12 (type state)
1196        pub struct Tim12Ch3 {}
1197        /// Output Compare Channel 4 of Timer 12 (type state)
1198        pub struct Tim12Ch4 {}
1199
1200        pwm_timer_basic!(
1201            tim12,
1202            TIM12,
1203            u16,
1204            pclk1,
1205            [Tim12Ch1, Tim12Ch2],
1206            [PwmChannel, PwmChannel]
1207        );
1208
1209        // Channels
1210        pwm_pin_for_pwm_channel!(TIM12, Tim12Ch1, u16, cc1e, ccr1, ccr);
1211        pwm_pin_for_pwm_channel!(TIM12, Tim12Ch2, u16, cc2e, ccr2, ccr);
1212
1213        // Pins
1214        pwm_channel1_pin!(TIM12, Tim12Ch1, output_to_pa4, gpioa::PA4<AF10>);
1215        pwm_channel1_pin!(TIM12, Tim12Ch1, output_to_pa14, gpioa::PA14<AF10>);
1216        pwm_channel1_pin!(TIM12, Tim12Ch1, output_to_pb14, gpiob::PB14<AF10>);
1217
1218        pwm_channel2_pin!(TIM12, Tim12Ch2, output_to_pa5, gpioa::PA5<AF10>);
1219        pwm_channel2_pin!(TIM12, Tim12Ch2, output_to_pa15, gpioa::PA15<AF10>);
1220        pwm_channel2_pin!(TIM12, Tim12Ch2, output_to_pb15, gpiob::PB15<AF10>);
1221    };
1222}
1223
1224// TODO: This timer is also present in stm32f378
1225#[cfg(feature = "stm32f373")]
1226tim12!();
1227
1228// TIM13
1229
1230#[cfg(feature = "stm32f373")]
1231macro_rules! tim13 {
1232    () => {
1233        use crate::pac::TIM13;
1234
1235        /// Output Compare Channel 1 of Timer 13 (type state)
1236        pub struct Tim13Ch1 {}
1237        /// Output Compare Channel 2 of Timer 13 (type state)
1238        pub struct Tim13Ch2 {}
1239        /// Output Compare Channel 3 of Timer 13 (type state)
1240        pub struct Tim13Ch3 {}
1241        /// Output Compare Channel 4 of Timer 13 (type state)
1242        pub struct Tim13Ch4 {}
1243
1244        pwm_timer_basic!(tim13, TIM13, u16, pclk1, [Tim13Ch1], [PwmChannel]);
1245
1246        // Channels
1247        pwm_pin_for_pwm_channel!(TIM13, Tim13Ch1, u16, cc1e, ccr1, ccr);
1248
1249        // Pins
1250        pwm_channel1_pin!(TIM13, Tim13Ch1, output_to_pa6, gpioa::PA6<AF9>);
1251        pwm_channel1_pin!(TIM13, Tim13Ch1, output_to_pa9, gpioa::PA9<AF2>);
1252        pwm_channel1_pin!(TIM13, Tim13Ch1, output_to_pb3, gpiob::PB3<AF9>);
1253        pwm_channel1_pin!(TIM13, Tim13Ch1, output_to_pc4, gpioc::PC4<AF2>);
1254    };
1255}
1256
1257#[cfg(feature = "stm32f373")]
1258tim13!();
1259
1260// TIM14
1261
1262#[cfg(feature = "stm32f373")]
1263macro_rules! tim14 {
1264    () => {
1265        use crate::pac::TIM14;
1266
1267        /// Output Compare Channel 1 of Timer 14 (type state)
1268        pub struct Tim14Ch1 {}
1269        /// Output Compare Channel 2 of Timer 14 (type state)
1270        pub struct Tim14Ch2 {}
1271        /// Output Compare Channel 3 of Timer 14 (type state)
1272        pub struct Tim14Ch3 {}
1273        /// Output Compare Channel 4 of Timer 14 (type state)
1274        pub struct Tim14Ch4 {}
1275
1276        pwm_timer_basic!(tim14, TIM14, u16, pclk1, [Tim14Ch1], [PwmChannel]);
1277
1278        // Channels
1279        pwm_pin_for_pwm_channel!(TIM14, Tim14Ch1, u16, cc1e, ccr1, ccr);
1280
1281        // Pins
1282        pwm_channel1_pin!(TIM14, Tim14Ch1, output_to_pa5, gpioa::PA5<AF9>);
1283        pwm_channel1_pin!(TIM14, Tim14Ch1, output_to_pa7, gpioa::PA7<AF9>);
1284        pwm_channel1_pin!(TIM14, Tim14Ch1, output_to_pa10, gpioa::PA10<AF9>);
1285        pwm_channel1_pin!(TIM14, Tim14Ch1, output_to_pf9, gpiof::PF9<AF2>);
1286    };
1287}
1288
1289// TODO: This timer is also present in stm32f378
1290#[cfg(feature = "stm32f373")]
1291tim14!();
1292
1293// TIM15
1294
1295pwm_timer_with_break!(
1296    tim15,
1297    TIM15,
1298    u16,
1299    pclk2,
1300    [Tim15Ch1, Tim15Ch2],
1301    [PwmChannel, PwmChannel]
1302);
1303
1304// Channels
1305pwm_pin_for_pwm_n_channel!(TIM15, Tim15Ch1, u16, cc1e, cc1ne, ccr1, ccr);
1306pwm_pin_for_pwm_channel!(TIM15, Tim15Ch2, u16, cc2e, ccr2, ccr);
1307
1308// Pins
1309pwm_channel1_pin!(TIM15, Tim15Ch1, output_to_pa2, gpioa::PA2<AF9>);
1310#[cfg(any(feature = "stm32f373", feature = "stm32f378"))]
1311pwm_channel1_pin!(TIM15, Tim15Ch1, output_to_pb6, gpiob::PB6<AF9>);
1312pwm_channel1_pin!(TIM15, Tim15Ch1, output_to_pb14, gpiob::PB14<AF1>);
1313#[cfg(any(
1314    feature = "stm32f302xb",
1315    feature = "stm32f302xc",
1316    feature = "stm32f302xd",
1317    feature = "stm32f302xe",
1318    feature = "stm32f303xb",
1319    feature = "stm32f303xc",
1320    feature = "stm32f303xd",
1321    feature = "stm32f303xe",
1322    feature = "stm32f358",
1323    feature = "stm32f398"
1324))]
1325pwm_channel1_pin!(TIM15, Tim15Ch1, output_to_pf9, gpiof::PF9<AF3>);
1326
1327pwm_channel1n_pin!(TIM15, Tim15Ch1, output_to_pa1, gpioa::PA1<AF9>);
1328pwm_channel1n_pin!(TIM15, Tim15Ch1, output_to_pb15, gpiob::PB15<AF2>);
1329pwm_channel2_pin!(TIM15, Tim15Ch2, output_to_pa3, gpioa::PA3<AF9>);
1330#[cfg(any(feature = "stm32f373", feature = "stm32f378"))]
1331pwm_channel2_pin!(TIM15, Tim15Ch2, output_to_pb7, gpiob::PB7<AF9>);
1332pwm_channel2_pin!(TIM15, Tim15Ch2, output_to_pb15, gpiob::PB15<AF2>);
1333#[cfg(any(
1334    feature = "stm32f302xb",
1335    feature = "stm32f302xc",
1336    feature = "stm32f302xd",
1337    feature = "stm32f302xe",
1338    feature = "stm32f303xb",
1339    feature = "stm32f303xc",
1340    feature = "stm32f303xd",
1341    feature = "stm32f303xe",
1342    feature = "stm32f358",
1343    feature = "stm32f398"
1344))]
1345pwm_channel2_pin!(TIM15, Tim15Ch2, output_to_pf10, gpiof::PF10<AF3>);
1346
1347// TIM16
1348
1349pwm_timer_with_break!(tim16, TIM16, u16, pclk2, [Tim16Ch1], [PwmChannel]);
1350
1351// Channels
1352pwm_pin_for_pwm_n_channel!(TIM16, Tim16Ch1, u16, cc1e, cc1ne, ccr1, ccr);
1353
1354// Pins
1355pwm_channel1_pin!(TIM16, Tim16Ch1, output_to_pa9, gpioa::PA6<AF1>);
1356pwm_channel1_pin!(TIM16, Tim16Ch1, output_to_pa12, gpioa::PA12<AF1>);
1357pwm_channel1_pin!(TIM16, Tim16Ch1, output_to_pb4, gpiob::PB4<AF1>);
1358pwm_channel1_pin!(TIM16, Tim16Ch1, output_to_pb8, gpiob::PB8<AF1>);
1359#[cfg(any(
1360    feature = "stm32f302xb",
1361    feature = "stm32f302xc",
1362    feature = "stm32f302xd",
1363    feature = "stm32f302xe",
1364    feature = "stm32f303xb",
1365    feature = "stm32f303xc",
1366    feature = "stm32f303xd",
1367    feature = "stm32f303xe",
1368    feature = "stm32f358",
1369    feature = "stm32f398"
1370))]
1371pwm_channel1_pin!(TIM16, Tim16Ch1, output_to_pe0, gpioe::PE0<AF4>);
1372
1373pwm_channel1n_pin!(TIM16, Tim16Ch1, output_to_pa13, gpioa::PA13<AF1>);
1374pwm_channel1n_pin!(TIM16, Tim16Ch1, output_to_pb6, gpiob::PB6<AF1>);
1375
1376// TIM17
1377
1378pwm_timer_with_break!(tim17, TIM17, u16, pclk2, [Tim17Ch1], [PwmChannel]);
1379
1380// Channels
1381pwm_pin_for_pwm_n_channel!(TIM17, Tim17Ch1, u16, cc1e, cc1ne, ccr1, ccr);
1382
1383// Pins
1384pwm_channel1_pin!(TIM17, Tim17Ch1, output_to_pa7, gpioa::PA7<AF1>);
1385pwm_channel1_pin!(TIM17, Tim17Ch1, output_to_pb5, gpiob::PB5<AF10>);
1386pwm_channel1_pin!(TIM17, Tim17Ch1, output_to_pb9, gpiob::PB9<AF1>);
1387#[cfg(any(
1388    feature = "stm32f302xb",
1389    feature = "stm32f302xc",
1390    feature = "stm32f302xd",
1391    feature = "stm32f302xe",
1392    feature = "stm32f303xb",
1393    feature = "stm32f303xc",
1394    feature = "stm32f303xd",
1395    feature = "stm32f303xe",
1396    feature = "stm32f358",
1397    feature = "stm32f398"
1398))]
1399pwm_channel1_pin!(TIM17, Tim17Ch1, output_to_pe1, gpioe::PE1<AF4>);
1400
1401pwm_channel1n_pin!(TIM17, Tim17Ch1, output_to_pa13, gpioa::PA13<AF1>);
1402
1403// TIM19
1404
1405#[cfg(feature = "stm32f373")]
1406macro_rules! tim19 {
1407    () => {
1408        use crate::pac::TIM19;
1409
1410        /// Output Compare Channel 1 of Timer 19 (type state)
1411        pub struct Tim19Ch1 {}
1412        /// Output Compare Channel 2 of Timer 19 (type state)
1413        pub struct Tim19Ch2 {}
1414        /// Output Compare Channel 3 of Timer 19 (type state)
1415        pub struct Tim19Ch3 {}
1416        /// Output Compare Channel 4 of Timer 19 (type state)
1417        pub struct Tim19Ch4 {}
1418
1419        pwm_timer_basic!(
1420            tim19,
1421            TIM19,
1422            u16,
1423            pclk2,
1424            [Tim19Ch1, Tim19Ch2, Tim19Ch3, Tim19Ch4],
1425            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
1426        );
1427
1428        // Channels
1429        pwm_pin_for_pwm_channel!(TIM19, Tim19Ch1, u16, cc1e, ccr1, ccr);
1430        pwm_pin_for_pwm_channel!(TIM19, Tim19Ch2, u16, cc2e, ccr2, ccr);
1431        pwm_pin_for_pwm_channel!(TIM19, Tim19Ch3, u16, cc3e, ccr3, ccr);
1432        pwm_pin_for_pwm_channel!(TIM19, Tim19Ch4, u16, cc4e, ccr4, ccr);
1433
1434        // Pins
1435        pwm_channel1_pin!(TIM19, Tim19Ch1, output_to_pa0, gpioa::PA0<AF11>);
1436        pwm_channel1_pin!(TIM19, Tim19Ch1, output_to_pb6, gpiob::PB6<AF11>);
1437        pwm_channel1_pin!(TIM19, Tim19Ch1, output_to_pc10, gpioc::PC10<AF2>);
1438
1439        pwm_channel2_pin!(TIM19, Tim19Ch2, output_to_pa1, gpioa::PA1<AF11>);
1440        pwm_channel2_pin!(TIM19, Tim19Ch2, output_to_pb7, gpiob::PB7<AF11>);
1441        pwm_channel2_pin!(TIM19, Tim19Ch2, output_to_pc11, gpioc::PC11<AF2>);
1442
1443        pwm_channel3_pin!(TIM19, Tim19Ch3, output_to_pa2, gpioa::PA2<AF11>);
1444        pwm_channel3_pin!(TIM19, Tim19Ch3, output_to_pb8, gpiob::PB8<AF11>);
1445        pwm_channel3_pin!(TIM19, Tim19Ch3, output_to_pc12, gpioc::PC12<AF2>);
1446
1447        pwm_channel4_pin!(TIM19, Tim19Ch4, output_to_pa3, gpioa::PA3<AF11>);
1448        pwm_channel4_pin!(TIM19, Tim19Ch4, output_to_pb9, gpiob::PB9<AF11>);
1449        pwm_channel4_pin!(TIM19, Tim19Ch4, output_to_pd0, gpiod::PD0<AF2>);
1450    };
1451}
1452
1453// TODO: This timer is also present in stm32f378
1454#[cfg(feature = "stm32f373")]
1455tim19!();
1456
1457// TIM20
1458//
1459#[cfg(feature = "stm32f398")]
1460macro_rules! tim20 {
1461    () => {
1462        use crate::pac::TIM20;
1463
1464        /// Output Compare Channel 1 of Timer 20 (type state)
1465        pub struct Tim20Ch1 {}
1466        /// Output Compare Channel 2 of Timer 20 (type state)
1467        pub struct Tim20Ch2 {}
1468        /// Output Compare Channel 3 of Timer 20 (type state)
1469        pub struct Tim20Ch3 {}
1470        /// Output Compare Channel 4 of Timer 20 (type state)
1471        pub struct Tim20Ch4 {}
1472
1473        pwm_timer_basic!(
1474            tim20,
1475            TIM20,
1476            u16,
1477            pclk2,
1478            [Tim20Ch1, Tim20Ch2, Tim20Ch3, Tim20Ch4],
1479            [PwmChannel, PwmChannel, PwmChannel, PwmChannel]
1480        );
1481
1482        // Channels
1483        // TODO: stm32f3 doesn't suppport registers for all 4 channels
1484        pwm_pin_for_pwm_n_channel!(TIM20, Tim20Ch1, u16, cc1e, cc1ne, ccr1, ccr);
1485
1486        //Pins
1487        pwm_channel1_pin!(TIM20, Tim20Ch1, output_to_pe2, gpioe::PE2<AF6>);
1488
1489        pwm_channel1n_pin!(TIM20, Tim20Ch1, output_to_pe4, gpioe::PE4<AF6>);
1490    };
1491}
1492
1493#[cfg(feature = "stm32f398")]
1494tim20!();