Skip to main content

stm_32/peripherals/
pwm.rs

1// ******************************************************************************
2// * File     : platforms/stm_32/src/peripherals/pwm.rs
3// * Date     : June 28, 2026
4// ******************************************************************************
5// *
6// * Copyright (c) 2023, AeroVironment, Inc.
7// * All rights reserved.
8// *
9// * Redistribution and use in source and binary forms, with or without
10// * modification, are permitted provided that the following conditions are met:
11// *
12// * 1.Redistributions of source code must retain the above copyright notice, this
13// * list of conditions and the following disclaimer.
14// *
15// * 2.Redistributions in binary form must reproduce the above copyright notice,
16// * this list of conditions and the following disclaimer in the documentation
17// * and/or other materials provided with the distribution.
18// *
19// * 3.Neither the name of the copyright holder nor the names of its
20// * contributors may be used to endorse or promote products derived from
21// * this software without specific prior written permission.
22// *
23// * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24// * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25// * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26// * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27// * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28// * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29// * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30// * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31// * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32// * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33// *
34// ******************************************************************************
35
36use embassy_futures::block_on;
37use embassy_stm32::peripherals::{
38    DMA2_CH0, DMA2_CH1, TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM12, TIM13, TIM14, TIM15, TIM16,
39    TIM17,
40};
41use embassy_stm32::time::Hertz;
42use embassy_stm32::timer::simple_pwm::SimplePwm;
43use veloxity_core::{
44    mixer::MixerOutputType,
45    pwm::{
46        DshotCommand, PwmOutputProtocol, effective_output_rate_hz, output_protocol_for_rate,
47        safe_disarmed_command,
48    },
49};
50
51const DSHOT_FRAME_WORDS: usize = DshotCommand::FRAME_BITS + 1;
52
53#[derive(Clone, Copy)]
54pub enum PwmTimerBlockKind {
55    StandardOnly,
56    DshotCapable,
57}
58
59impl PwmTimerBlockKind {
60    fn supports(self, protocol: PwmOutputProtocol) -> bool {
61        match (self, protocol) {
62            (_, PwmOutputProtocol::StandardPwm) => true,
63            (PwmTimerBlockKind::DshotCapable, PwmOutputProtocol::Dshot) => true,
64            (PwmTimerBlockKind::StandardOnly, PwmOutputProtocol::Dshot) => false,
65        }
66    }
67}
68
69pub struct ServoMonstrosity {
70    pub timers: [TimerEnum; 4],
71    pub chan_list: [(usize, TimerChannel); 12],
72    timer_kinds: [PwmTimerBlockKind; 4],
73    timer_protocols: [PwmOutputProtocol; 4],
74    output_protocols: [PwmOutputProtocol; 12],
75    output_rates_hz: [f64; 12],
76    dshot_frames: [[u16; DSHOT_FRAME_WORDS]; 12],
77}
78
79impl ServoMonstrosity {
80    pub fn new(timers: [TimerEnum; 4], chan_list: [(usize, TimerChannel); 12]) -> Self {
81        Self::with_timer_kinds(timers, chan_list, [PwmTimerBlockKind::StandardOnly; 4])
82    }
83
84    pub fn with_timer_kinds(
85        timers: [TimerEnum; 4],
86        chan_list: [(usize, TimerChannel); 12],
87        timer_kinds: [PwmTimerBlockKind; 4],
88    ) -> Self {
89        Self {
90            timers,
91            chan_list,
92            timer_kinds,
93            timer_protocols: [PwmOutputProtocol::StandardPwm; 4],
94            output_protocols: [PwmOutputProtocol::StandardPwm; 12],
95            output_rates_hz: [50.0; 12],
96            dshot_frames: [[0; DSHOT_FRAME_WORDS]; 12],
97        }
98    }
99
100    pub fn len(&mut self) -> usize {
101        self.chan_list.len()
102    }
103    pub fn enable(&mut self, ch: usize) -> Result<(), TimerError> {
104        let (ix, chan) = self.chan_list[ch];
105        self.timers[ix].enable(chan)
106    }
107    pub fn disable(&mut self, ch: usize) -> Result<(), TimerError> {
108        let (ix, chan) = self.chan_list[ch];
109        //    "PWM: Accessing index {}, array len: {}",
110        //    ix,
111        //    self.chan_list.len()
112        //);
113        self.timers[ix].disable(chan)
114    }
115    pub fn set_duty_cycle(&mut self, ch: usize, duty: u16) -> Result<(), TimerError> {
116        let (ix, chan) = self.chan_list[ch];
117        self.timers[ix].set_duty_cycle(chan, duty)
118    }
119
120    pub fn configure_output_rates(&mut self, rates_hz: &[f64]) -> Result<(), TimerError> {
121        let mut timer_configs = [None; 4];
122        for (output, rate) in rates_hz.iter().take(self.chan_list.len()).enumerate() {
123            let (timer_index, _) = self.chan_list[output];
124            let protocol = output_protocol_for_rate(*rate).map_err(|_| TimerError::InvalidRate)?;
125            let effective_rate =
126                effective_output_rate_hz(*rate).map_err(|_| TimerError::InvalidRate)?;
127            if !self.timer_kinds[timer_index].supports(protocol) {
128                return Err(TimerError::UnsupportedProtocol);
129            }
130            self.output_rates_hz[output] = effective_rate;
131            self.output_protocols[output] = protocol;
132            timer_configs[timer_index] = Some((protocol, rate_to_hz(effective_rate)?));
133        }
134
135        for (timer_index, (timer, config)) in self.timers.iter_mut().zip(timer_configs).enumerate()
136        {
137            if let Some((protocol, rate_hz)) = config {
138                self.timer_protocols[timer_index] = protocol;
139                timer.set_frequency_hz(rate_hz);
140            }
141        }
142
143        Ok(())
144    }
145
146    pub fn output_protocol(&self, ch: usize) -> Result<PwmOutputProtocol, TimerError> {
147        self.output_protocols
148            .get(ch)
149            .copied()
150            .ok_or(TimerError::ChanNotSupported)
151    }
152
153    pub fn send_normalized_commands(&mut self, commands: &[f64]) -> Result<(), TimerError> {
154        let count = commands.len().min(self.chan_list.len());
155        for output in 0..count {
156            match self.output_protocols[output] {
157                PwmOutputProtocol::StandardPwm => {
158                    let duty = self.standard_pwm_duty(output, commands[output])?;
159                    self.set_duty_cycle(output, duty)?;
160                }
161                PwmOutputProtocol::Dshot => {
162                    self.prepare_dshot_frame(output, commands[output])?;
163                    return Err(TimerError::UnsupportedProtocol);
164                }
165            }
166        }
167        Ok(())
168    }
169
170    pub fn send_disarmed_commands(
171        &mut self,
172        output_types: &[MixerOutputType],
173    ) -> Result<(), TimerError> {
174        let count = output_types.len().min(self.chan_list.len());
175        for output in 0..count {
176            match self.output_protocols[output] {
177                PwmOutputProtocol::StandardPwm => {
178                    let duty = self
179                        .standard_pwm_duty(output, safe_disarmed_command(output_types[output]))?;
180                    self.set_duty_cycle(output, duty)?;
181                }
182                PwmOutputProtocol::Dshot => {
183                    self.prepare_dshot_command(output, DshotCommand::stop())?;
184                    return Err(TimerError::UnsupportedProtocol);
185                }
186            }
187        }
188        Ok(())
189    }
190
191    fn prepare_dshot_frame(&mut self, output: usize, command: f64) -> Result<(), TimerError> {
192        self.prepare_dshot_command(output, DshotCommand::from_normalized(command))
193    }
194
195    fn prepare_dshot_command(
196        &mut self,
197        output: usize,
198        command: DshotCommand,
199    ) -> Result<(), TimerError> {
200        let (timer_index, _) = self.chan_list[output];
201        let max_duty = self.timers[timer_index].max_duty_cycle();
202        self.dshot_frames[output] = dshot_waveform(command, max_duty);
203        Ok(())
204    }
205
206    fn standard_pwm_duty(&self, output: usize, command: f64) -> Result<u16, TimerError> {
207        let (timer_index, _) = self.chan_list[output];
208        Ok(standard_pwm_duty(
209            command,
210            self.output_rates_hz[output],
211            self.timers[timer_index].max_duty_cycle(),
212        )?)
213    }
214}
215
216pub struct PixRacerProServoMonstrosity {
217    pub timers: [TimerEnum; 3],
218    pub chan_list: [(usize, TimerChannel); 7],
219    timer_kinds: [PwmTimerBlockKind; 3],
220    timer_dmas: [Option<DshotDma>; 3],
221    timer_protocols: [PwmOutputProtocol; 3],
222    output_protocols: [PwmOutputProtocol; 7],
223    output_rates_hz: [f64; 7],
224    dshot_frames: [[u16; DSHOT_FRAME_WORDS]; 7],
225}
226
227impl PixRacerProServoMonstrosity {
228    pub fn new(timers: [TimerEnum; 3], chan_list: [(usize, TimerChannel); 7]) -> Self {
229        Self::with_timer_kinds(timers, chan_list, [PwmTimerBlockKind::StandardOnly; 3])
230    }
231
232    pub fn with_timer_kinds(
233        timers: [TimerEnum; 3],
234        chan_list: [(usize, TimerChannel); 7],
235        timer_kinds: [PwmTimerBlockKind; 3],
236    ) -> Self {
237        Self::with_timer_kinds_and_dma(timers, chan_list, timer_kinds, [const { None }; 3])
238    }
239
240    pub fn with_timer_kinds_and_dma(
241        timers: [TimerEnum; 3],
242        chan_list: [(usize, TimerChannel); 7],
243        timer_kinds: [PwmTimerBlockKind; 3],
244        timer_dmas: [Option<DshotDma>; 3],
245    ) -> Self {
246        Self {
247            timers,
248            chan_list,
249            timer_kinds,
250            timer_dmas,
251            timer_protocols: [PwmOutputProtocol::StandardPwm; 3],
252            output_protocols: [PwmOutputProtocol::StandardPwm; 7],
253            output_rates_hz: [50.0; 7],
254            dshot_frames: [[0; DSHOT_FRAME_WORDS]; 7],
255        }
256    }
257
258    pub fn len(&mut self) -> usize {
259        self.chan_list.len()
260    }
261    pub fn enable(&mut self, ch: usize) -> Result<(), TimerError> {
262        let (ix, chan) = self.chan_list[ch];
263        self.timers[ix].enable(chan)
264    }
265    pub fn disable(&mut self, ch: usize) -> Result<(), TimerError> {
266        let (ix, chan) = self.chan_list[ch];
267        //    "PWM: Accessing index {}, array len: {}",
268        //    ix,
269        //    self.chan_list.len()
270        //);
271        self.timers[ix].disable(chan)
272    }
273    pub fn set_duty_cycle(&mut self, ch: usize, duty: u16) -> Result<(), TimerError> {
274        let (ix, chan) = self.chan_list[ch];
275        self.timers[ix].set_duty_cycle(chan, duty)
276    }
277
278    pub fn configure_output_rates(&mut self, rates_hz: &[f64]) -> Result<(), TimerError> {
279        let mut timer_configs = [None; 3];
280        for (output, rate) in rates_hz.iter().take(self.chan_list.len()).enumerate() {
281            let (timer_index, _) = self.chan_list[output];
282            let protocol = output_protocol_for_rate(*rate).map_err(|_| TimerError::InvalidRate)?;
283            let effective_rate =
284                effective_output_rate_hz(*rate).map_err(|_| TimerError::InvalidRate)?;
285            if !self.timer_kinds[timer_index].supports(protocol) {
286                return Err(TimerError::UnsupportedProtocol);
287            }
288            self.output_rates_hz[output] = effective_rate;
289            self.output_protocols[output] = protocol;
290            timer_configs[timer_index] = Some((protocol, rate_to_hz(effective_rate)?));
291        }
292
293        for (timer_index, (timer, config)) in self.timers.iter_mut().zip(timer_configs).enumerate()
294        {
295            if let Some((protocol, rate_hz)) = config {
296                self.timer_protocols[timer_index] = protocol;
297                timer.set_frequency_hz(rate_hz);
298            }
299        }
300
301        Ok(())
302    }
303
304    pub fn output_protocol(&self, ch: usize) -> Result<PwmOutputProtocol, TimerError> {
305        self.output_protocols
306            .get(ch)
307            .copied()
308            .ok_or(TimerError::ChanNotSupported)
309    }
310
311    pub fn send_normalized_commands(&mut self, commands: &[f64]) -> Result<(), TimerError> {
312        let count = commands.len().min(self.chan_list.len());
313        for output in 0..count {
314            match self.output_protocols[output] {
315                PwmOutputProtocol::StandardPwm => {
316                    let duty = self.standard_pwm_duty(output, commands[output])?;
317                    self.set_duty_cycle(output, duty)?;
318                }
319                PwmOutputProtocol::Dshot => {
320                    self.prepare_dshot_frame(output, commands[output])?;
321                    self.emit_dshot_frame(output)?;
322                }
323            }
324        }
325        Ok(())
326    }
327
328    pub fn send_disarmed_commands(
329        &mut self,
330        output_types: &[MixerOutputType],
331    ) -> Result<(), TimerError> {
332        let count = output_types.len().min(self.chan_list.len());
333        for output in 0..count {
334            match self.output_protocols[output] {
335                PwmOutputProtocol::StandardPwm => {
336                    let duty = self
337                        .standard_pwm_duty(output, safe_disarmed_command(output_types[output]))?;
338                    self.set_duty_cycle(output, duty)?;
339                }
340                PwmOutputProtocol::Dshot => {
341                    self.prepare_dshot_command(output, DshotCommand::stop())?;
342                    self.emit_dshot_frame(output)?;
343                }
344            }
345        }
346        Ok(())
347    }
348
349    pub fn max_duty_cycle(&self, ch: usize) -> u16 {
350        let (ix, _chan) = self.chan_list[ch];
351        self.timers[ix].max_duty_cycle()
352    }
353
354    fn prepare_dshot_frame(&mut self, output: usize, command: f64) -> Result<(), TimerError> {
355        self.prepare_dshot_command(output, DshotCommand::from_normalized(command))
356    }
357
358    fn prepare_dshot_command(
359        &mut self,
360        output: usize,
361        command: DshotCommand,
362    ) -> Result<(), TimerError> {
363        let (timer_index, _) = self.chan_list[output];
364        let max_duty = self.timers[timer_index].max_duty_cycle();
365        self.dshot_frames[output] = dshot_waveform(command, max_duty);
366        Ok(())
367    }
368
369    fn standard_pwm_duty(&self, output: usize, command: f64) -> Result<u16, TimerError> {
370        let (timer_index, _) = self.chan_list[output];
371        Ok(standard_pwm_duty(
372            command,
373            self.output_rates_hz[output],
374            self.timers[timer_index].max_duty_cycle(),
375        )?)
376    }
377
378    fn emit_dshot_frame(&mut self, output: usize) -> Result<(), TimerError> {
379        let (timer_index, channel) = self.chan_list[output];
380        let Some(dma) = self.timer_dmas[timer_index].as_mut() else {
381            return Err(TimerError::UnsupportedProtocol);
382        };
383
384        block_on(dma.emit(
385            &mut self.timers[timer_index],
386            channel,
387            &self.dshot_frames[output],
388        ))
389    }
390}
391
392pub enum DshotDma {
393    Dma2Ch0(DMA2_CH0),
394    Dma2Ch1(DMA2_CH1),
395}
396
397impl DshotDma {
398    async fn emit(
399        &mut self,
400        timer: &mut TimerEnum,
401        channel: TimerChannel,
402        waveform: &[u16],
403    ) -> Result<(), TimerError> {
404        let _ = (self, timer, channel, waveform);
405        Err(TimerError::UnsupportedProtocol)
406    }
407}
408
409pub enum TimerEnum {
410    TIM1(SimplePwm<'static, TIM1>),
411    TIM2(SimplePwm<'static, TIM2>),
412    TIM3(SimplePwm<'static, TIM3>),
413    TIM4(SimplePwm<'static, TIM4>),
414    TIM5(SimplePwm<'static, TIM5>),
415    // 6 and 7 are not PWM capable
416    TIM8(SimplePwm<'static, TIM8>),
417    TIM12(SimplePwm<'static, TIM12>),
418    TIM13(SimplePwm<'static, TIM13>),
419    TIM14(SimplePwm<'static, TIM14>),
420    TIM15(SimplePwm<'static, TIM15>),
421    TIM16(SimplePwm<'static, TIM16>),
422    TIM17(SimplePwm<'static, TIM17>),
423}
424
425#[derive(Clone, Copy)]
426pub enum TimerChannel {
427    Ch1,
428    Ch2,
429    Ch3,
430    Ch4,
431}
432
433pub enum TimerError {
434    ChanNotSupported,
435    TimerNotSupported,
436    InvalidRate,
437    UnsupportedProtocol,
438}
439
440fn rate_to_hz(rate: f64) -> Result<u32, TimerError> {
441    if !rate.is_finite() || rate <= 0.0 || rate > u32::MAX as f64 {
442        return Err(TimerError::TimerNotSupported);
443    }
444
445    Ok((rate + 0.5) as u32)
446}
447
448fn dshot_waveform(command: DshotCommand, max_duty: u16) -> [u16; DSHOT_FRAME_WORDS] {
449    let high = ((max_duty as u32 * 3) / 4) as u16;
450    let low = ((max_duty as u32 * 3) / 8) as u16;
451    let frame = command.frame();
452    let mut waveform = [0u16; DSHOT_FRAME_WORDS];
453
454    for (bit, slot) in waveform
455        .iter_mut()
456        .take(DshotCommand::FRAME_BITS)
457        .enumerate()
458    {
459        *slot = if DshotCommand::bit_is_high(frame, bit) {
460            high
461        } else {
462            low
463        };
464    }
465
466    waveform[DshotCommand::FRAME_BITS] = 0;
467    waveform
468}
469
470fn standard_pwm_duty(command: f64, rate_hz: f64, max_duty: u16) -> Result<u16, TimerError> {
471    if !rate_hz.is_finite() || rate_hz <= 0.0 {
472        return Err(TimerError::InvalidRate);
473    }
474
475    let pulse_us = command.clamp(0.0, 1.0) * 1000.0 + 1000.0;
476    let period_us = 1_000_000.0 / rate_hz;
477    let raw = pulse_us / period_us * max_duty as f64;
478    Ok(raw.clamp(0.0, max_duty as f64) as u16)
479}
480
481fn duty_to_u16(duty: u32) -> u16 {
482    duty.min(u16::MAX as u32) as u16
483}
484
485impl TimerEnum {
486    pub fn set_frequency_hz(&mut self, rate_hz: u32) {
487        match self {
488            TimerEnum::TIM1(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
489            TimerEnum::TIM2(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
490            TimerEnum::TIM3(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
491            TimerEnum::TIM4(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
492            TimerEnum::TIM5(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
493            TimerEnum::TIM8(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
494            TimerEnum::TIM12(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
495            TimerEnum::TIM13(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
496            TimerEnum::TIM14(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
497            TimerEnum::TIM15(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
498            TimerEnum::TIM16(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
499            TimerEnum::TIM17(timer) => timer.set_frequency(Hertz::hz(rate_hz)),
500        }
501    }
502
503    pub fn enable(&mut self, channel: TimerChannel) -> Result<(), TimerError> {
504        match self {
505            TimerEnum::TIM1(timer) => match channel {
506                TimerChannel::Ch1 => {
507                    timer.ch1().enable();
508                    Ok(())
509                }
510                TimerChannel::Ch2 => {
511                    timer.ch2().enable();
512                    Ok(())
513                }
514                TimerChannel::Ch3 => {
515                    timer.ch3().enable();
516                    Ok(())
517                }
518                TimerChannel::Ch4 => {
519                    timer.ch4().enable();
520                    Ok(())
521                }
522            },
523            TimerEnum::TIM2(timer) => match channel {
524                TimerChannel::Ch1 => {
525                    timer.ch1().enable();
526                    Ok(())
527                }
528                TimerChannel::Ch2 => {
529                    timer.ch2().enable();
530                    Ok(())
531                }
532                TimerChannel::Ch3 => {
533                    timer.ch3().enable();
534                    Ok(())
535                }
536                TimerChannel::Ch4 => {
537                    timer.ch4().enable();
538                    Ok(())
539                }
540            },
541            TimerEnum::TIM3(timer) => match channel {
542                TimerChannel::Ch1 => {
543                    timer.ch1().enable();
544                    Ok(())
545                }
546                TimerChannel::Ch2 => {
547                    timer.ch2().enable();
548                    Ok(())
549                }
550                TimerChannel::Ch3 => {
551                    timer.ch3().enable();
552                    Ok(())
553                }
554                TimerChannel::Ch4 => {
555                    timer.ch4().enable();
556                    Ok(())
557                }
558            },
559            TimerEnum::TIM4(timer) => match channel {
560                TimerChannel::Ch1 => {
561                    timer.ch1().enable();
562                    Ok(())
563                }
564                TimerChannel::Ch2 => {
565                    timer.ch2().enable();
566                    Ok(())
567                }
568                TimerChannel::Ch3 => {
569                    timer.ch3().enable();
570                    Ok(())
571                }
572                TimerChannel::Ch4 => {
573                    timer.ch4().enable();
574                    Ok(())
575                }
576            },
577            TimerEnum::TIM5(timer) => match channel {
578                TimerChannel::Ch1 => {
579                    timer.ch1().enable();
580                    Ok(())
581                }
582                TimerChannel::Ch2 => {
583                    timer.ch2().enable();
584                    Ok(())
585                }
586                TimerChannel::Ch3 => {
587                    timer.ch3().enable();
588                    Ok(())
589                }
590                TimerChannel::Ch4 => {
591                    timer.ch4().enable();
592                    Ok(())
593                }
594            },
595            TimerEnum::TIM8(timer) => match channel {
596                TimerChannel::Ch1 => {
597                    timer.ch1().enable();
598                    Ok(())
599                }
600                TimerChannel::Ch2 => {
601                    timer.ch2().enable();
602                    Ok(())
603                }
604                TimerChannel::Ch3 => {
605                    timer.ch3().enable();
606                    Ok(())
607                }
608                TimerChannel::Ch4 => {
609                    timer.ch4().enable();
610                    Ok(())
611                }
612            },
613            TimerEnum::TIM12(timer) => match channel {
614                TimerChannel::Ch1 => {
615                    timer.ch1().enable();
616                    Ok(())
617                }
618                TimerChannel::Ch2 => {
619                    timer.ch2().enable();
620                    Ok(())
621                }
622                _ => Err(TimerError::ChanNotSupported),
623            },
624            TimerEnum::TIM13(timer) => match channel {
625                TimerChannel::Ch1 => {
626                    timer.ch1().enable();
627                    Ok(())
628                }
629                _ => Err(TimerError::ChanNotSupported),
630            },
631            TimerEnum::TIM14(timer) => match channel {
632                TimerChannel::Ch1 => {
633                    timer.ch1().enable();
634                    Ok(())
635                }
636                _ => Err(TimerError::ChanNotSupported),
637            },
638            TimerEnum::TIM15(timer) => match channel {
639                TimerChannel::Ch1 => {
640                    timer.ch1().enable();
641                    Ok(())
642                }
643                TimerChannel::Ch2 => {
644                    timer.ch2().enable();
645                    Ok(())
646                }
647                _ => Err(TimerError::ChanNotSupported),
648            },
649            TimerEnum::TIM16(timer) => match channel {
650                TimerChannel::Ch1 => {
651                    timer.ch1().enable();
652                    Ok(())
653                }
654                _ => Err(TimerError::ChanNotSupported),
655            },
656            TimerEnum::TIM17(timer) => match channel {
657                TimerChannel::Ch1 => {
658                    timer.ch1().enable();
659                    Ok(())
660                }
661                _ => Err(TimerError::ChanNotSupported),
662            },
663        }
664    }
665    pub fn disable(&mut self, channel: TimerChannel) -> Result<(), TimerError> {
666        match self {
667            TimerEnum::TIM1(timer) => match channel {
668                TimerChannel::Ch1 => {
669                    timer.ch1().disable();
670                    Ok(())
671                }
672                TimerChannel::Ch2 => {
673                    timer.ch2().disable();
674                    Ok(())
675                }
676                TimerChannel::Ch3 => {
677                    timer.ch3().disable();
678                    Ok(())
679                }
680                TimerChannel::Ch4 => {
681                    timer.ch4().disable();
682                    Ok(())
683                }
684            },
685            TimerEnum::TIM2(timer) => match channel {
686                TimerChannel::Ch1 => {
687                    timer.ch1().disable();
688                    Ok(())
689                }
690                TimerChannel::Ch2 => {
691                    timer.ch2().disable();
692                    Ok(())
693                }
694                TimerChannel::Ch3 => {
695                    timer.ch3().disable();
696                    Ok(())
697                }
698                TimerChannel::Ch4 => {
699                    timer.ch4().disable();
700                    Ok(())
701                }
702            },
703            TimerEnum::TIM3(timer) => match channel {
704                TimerChannel::Ch1 => {
705                    timer.ch1().disable();
706                    Ok(())
707                }
708                TimerChannel::Ch2 => {
709                    timer.ch2().disable();
710                    Ok(())
711                }
712                TimerChannel::Ch3 => {
713                    timer.ch3().disable();
714                    Ok(())
715                }
716                TimerChannel::Ch4 => {
717                    timer.ch4().disable();
718                    Ok(())
719                }
720            },
721            TimerEnum::TIM4(timer) => match channel {
722                TimerChannel::Ch1 => {
723                    timer.ch1().disable();
724                    Ok(())
725                }
726                TimerChannel::Ch2 => {
727                    timer.ch2().disable();
728                    Ok(())
729                }
730                TimerChannel::Ch3 => {
731                    timer.ch3().disable();
732                    Ok(())
733                }
734                TimerChannel::Ch4 => {
735                    timer.ch4().disable();
736                    Ok(())
737                }
738            },
739            TimerEnum::TIM5(timer) => match channel {
740                TimerChannel::Ch1 => {
741                    timer.ch1().disable();
742                    Ok(())
743                }
744                TimerChannel::Ch2 => {
745                    timer.ch2().disable();
746                    Ok(())
747                }
748                TimerChannel::Ch3 => {
749                    timer.ch3().disable();
750                    Ok(())
751                }
752                TimerChannel::Ch4 => {
753                    timer.ch4().disable();
754                    Ok(())
755                }
756            },
757            TimerEnum::TIM8(timer) => match channel {
758                TimerChannel::Ch1 => {
759                    timer.ch1().disable();
760                    Ok(())
761                }
762                TimerChannel::Ch2 => {
763                    timer.ch2().disable();
764                    Ok(())
765                }
766                TimerChannel::Ch3 => {
767                    timer.ch3().disable();
768                    Ok(())
769                }
770                TimerChannel::Ch4 => {
771                    timer.ch4().disable();
772                    Ok(())
773                }
774            },
775            TimerEnum::TIM12(timer) => match channel {
776                TimerChannel::Ch1 => {
777                    timer.ch1().disable();
778                    Ok(())
779                }
780                TimerChannel::Ch2 => {
781                    timer.ch2().disable();
782                    Ok(())
783                }
784                _ => Err(TimerError::ChanNotSupported),
785            },
786            TimerEnum::TIM13(timer) => match channel {
787                TimerChannel::Ch1 => {
788                    timer.ch1().disable();
789                    Ok(())
790                }
791                _ => Err(TimerError::ChanNotSupported),
792            },
793            TimerEnum::TIM14(timer) => match channel {
794                TimerChannel::Ch1 => {
795                    timer.ch1().disable();
796                    Ok(())
797                }
798                _ => Err(TimerError::ChanNotSupported),
799            },
800            TimerEnum::TIM15(timer) => match channel {
801                TimerChannel::Ch1 => {
802                    timer.ch1().disable();
803                    Ok(())
804                }
805                TimerChannel::Ch2 => {
806                    timer.ch2().disable();
807                    Ok(())
808                }
809                _ => Err(TimerError::ChanNotSupported),
810            },
811            TimerEnum::TIM16(timer) => match channel {
812                TimerChannel::Ch1 => {
813                    timer.ch1().disable();
814                    Ok(())
815                }
816                _ => Err(TimerError::ChanNotSupported),
817            },
818            TimerEnum::TIM17(timer) => match channel {
819                TimerChannel::Ch1 => {
820                    timer.ch1().disable();
821                    Ok(())
822                }
823                _ => Err(TimerError::ChanNotSupported),
824            },
825        }
826    }
827
828    pub fn max_duty_cycle(&self) -> u16 {
829        match self {
830            TimerEnum::TIM1(timer) => duty_to_u16(timer.max_duty_cycle()),
831            TimerEnum::TIM2(timer) => duty_to_u16(timer.max_duty_cycle()),
832            TimerEnum::TIM3(timer) => duty_to_u16(timer.max_duty_cycle()),
833            TimerEnum::TIM4(timer) => duty_to_u16(timer.max_duty_cycle()),
834            TimerEnum::TIM5(timer) => duty_to_u16(timer.max_duty_cycle()),
835            TimerEnum::TIM8(timer) => duty_to_u16(timer.max_duty_cycle()),
836            TimerEnum::TIM12(timer) => duty_to_u16(timer.max_duty_cycle()),
837            TimerEnum::TIM13(timer) => duty_to_u16(timer.max_duty_cycle()),
838            TimerEnum::TIM14(timer) => duty_to_u16(timer.max_duty_cycle()),
839            TimerEnum::TIM15(timer) => duty_to_u16(timer.max_duty_cycle()),
840            TimerEnum::TIM16(timer) => duty_to_u16(timer.max_duty_cycle()),
841            TimerEnum::TIM17(timer) => duty_to_u16(timer.max_duty_cycle()),
842        }
843    }
844
845    pub fn set_duty_cycle(&mut self, channel: TimerChannel, duty: u16) -> Result<(), TimerError> {
846        match self {
847            TimerEnum::TIM1(timer) => match channel {
848                TimerChannel::Ch1 => {
849                    timer.ch1().set_duty_cycle(u32::from(duty));
850                    Ok(())
851                }
852                TimerChannel::Ch2 => {
853                    timer.ch2().set_duty_cycle(u32::from(duty));
854                    Ok(())
855                }
856                TimerChannel::Ch3 => {
857                    timer.ch3().set_duty_cycle(u32::from(duty));
858                    Ok(())
859                }
860                TimerChannel::Ch4 => {
861                    timer.ch4().set_duty_cycle(u32::from(duty));
862                    Ok(())
863                }
864            },
865            TimerEnum::TIM2(timer) => match channel {
866                TimerChannel::Ch1 => {
867                    timer.ch1().set_duty_cycle(u32::from(duty));
868                    Ok(())
869                }
870                TimerChannel::Ch2 => {
871                    timer.ch2().set_duty_cycle(u32::from(duty));
872                    Ok(())
873                }
874                TimerChannel::Ch3 => {
875                    timer.ch3().set_duty_cycle(u32::from(duty));
876                    Ok(())
877                }
878                TimerChannel::Ch4 => {
879                    timer.ch4().set_duty_cycle(u32::from(duty));
880                    Ok(())
881                }
882            },
883            TimerEnum::TIM3(timer) => match channel {
884                TimerChannel::Ch1 => {
885                    timer.ch1().set_duty_cycle(u32::from(duty));
886                    Ok(())
887                }
888                TimerChannel::Ch2 => {
889                    timer.ch2().set_duty_cycle(u32::from(duty));
890                    Ok(())
891                }
892                TimerChannel::Ch3 => {
893                    timer.ch3().set_duty_cycle(u32::from(duty));
894                    Ok(())
895                }
896                TimerChannel::Ch4 => {
897                    timer.ch4().set_duty_cycle(u32::from(duty));
898                    Ok(())
899                }
900            },
901            TimerEnum::TIM4(timer) => match channel {
902                TimerChannel::Ch1 => {
903                    timer.ch1().set_duty_cycle(u32::from(duty));
904                    Ok(())
905                }
906                TimerChannel::Ch2 => {
907                    timer.ch2().set_duty_cycle(u32::from(duty));
908                    Ok(())
909                }
910                TimerChannel::Ch3 => {
911                    timer.ch3().set_duty_cycle(u32::from(duty));
912                    Ok(())
913                }
914                TimerChannel::Ch4 => {
915                    timer.ch4().set_duty_cycle(u32::from(duty));
916                    Ok(())
917                }
918            },
919            TimerEnum::TIM5(timer) => match channel {
920                TimerChannel::Ch1 => {
921                    timer.ch1().set_duty_cycle(u32::from(duty));
922                    Ok(())
923                }
924                TimerChannel::Ch2 => {
925                    timer.ch2().set_duty_cycle(u32::from(duty));
926                    Ok(())
927                }
928                TimerChannel::Ch3 => {
929                    timer.ch3().set_duty_cycle(u32::from(duty));
930                    Ok(())
931                }
932                TimerChannel::Ch4 => {
933                    timer.ch4().set_duty_cycle(u32::from(duty));
934                    Ok(())
935                }
936            },
937            TimerEnum::TIM8(timer) => match channel {
938                TimerChannel::Ch1 => {
939                    timer.ch1().set_duty_cycle(u32::from(duty));
940                    Ok(())
941                }
942                TimerChannel::Ch2 => {
943                    timer.ch2().set_duty_cycle(u32::from(duty));
944                    Ok(())
945                }
946                TimerChannel::Ch3 => {
947                    timer.ch3().set_duty_cycle(u32::from(duty));
948                    Ok(())
949                }
950                TimerChannel::Ch4 => {
951                    timer.ch4().set_duty_cycle(u32::from(duty));
952                    Ok(())
953                }
954            },
955            TimerEnum::TIM12(timer) => match channel {
956                TimerChannel::Ch1 => {
957                    timer.ch1().set_duty_cycle(u32::from(duty));
958                    Ok(())
959                }
960                TimerChannel::Ch2 => {
961                    timer.ch2().set_duty_cycle(u32::from(duty));
962                    Ok(())
963                }
964                _ => Err(TimerError::ChanNotSupported),
965            },
966            TimerEnum::TIM13(timer) => match channel {
967                TimerChannel::Ch1 => {
968                    timer.ch1().set_duty_cycle(u32::from(duty));
969                    Ok(())
970                }
971                _ => Err(TimerError::ChanNotSupported),
972            },
973            TimerEnum::TIM14(timer) => match channel {
974                TimerChannel::Ch1 => {
975                    timer.ch1().set_duty_cycle(u32::from(duty));
976                    Ok(())
977                }
978                _ => Err(TimerError::ChanNotSupported),
979            },
980            TimerEnum::TIM15(timer) => match channel {
981                TimerChannel::Ch1 => {
982                    timer.ch1().set_duty_cycle(u32::from(duty));
983                    Ok(())
984                }
985                TimerChannel::Ch2 => {
986                    timer.ch2().set_duty_cycle(u32::from(duty));
987                    Ok(())
988                }
989                _ => Err(TimerError::ChanNotSupported),
990            },
991            TimerEnum::TIM16(timer) => match channel {
992                TimerChannel::Ch1 => {
993                    timer.ch1().set_duty_cycle(u32::from(duty));
994                    Ok(())
995                }
996                _ => Err(TimerError::ChanNotSupported),
997            },
998            TimerEnum::TIM17(timer) => match channel {
999                TimerChannel::Ch1 => {
1000                    timer.ch1().set_duty_cycle(u32::from(duty));
1001                    Ok(())
1002                }
1003                _ => Err(TimerError::ChanNotSupported),
1004            },
1005        }
1006    }
1007}