1use 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 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 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 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}