1#![doc = include_str!("../README.md")]
2#![no_std]
3
4#[cfg(not(any(
5 feature = "stm32f334",
6 feature = "stm32h742",
7 feature = "stm32h743",
8 feature = "stm32h747cm7",
10 feature = "stm32h750",
11 feature = "stm32h753",
12 feature = "stm32g474",
15 feature = "stm32g484",
16)))]
17compile_error!(
18 "This crate requires one of the following features enabled:
19 stm32f334
20
21 stm32h742
22 stm32h743
23 #stm32h745
24 stm32h747cm7
25 stm32h750
26 stm32h753
27 #stm32h755
28 #stm32h757
29
30 stm32g474
31 stm32g484"
32);
33
34pub mod adc_trigger;
35pub mod capture;
36pub mod compare_register;
37pub mod control;
38pub mod deadtime;
39pub mod event;
40pub mod ext;
41pub mod external_event;
42pub mod fault;
43pub mod output;
44pub mod timer;
45pub mod timer_eev_cfg;
46
47#[cfg(feature = "stm32f334")]
48pub use stm32f3::stm32f3x4 as pac;
49
50#[cfg(feature = "stm32h742")]
51pub use stm32h7::stm32h742 as pac;
52
53#[cfg(feature = "stm32h743")]
54pub use stm32h7::stm32h743 as pac;
55
56#[cfg(feature = "stm32h747cm7")]
60pub use stm32h7::stm32h747cm7 as pac;
61
62#[cfg(feature = "stm32h750")]
63pub use stm32h7::stm32h750 as pac;
64
65#[cfg(feature = "stm32h753")]
66pub use stm32h7::stm32h753 as pac;
67
68#[cfg(feature = "stm32g474")]
75pub use stm32g4::stm32g474 as pac;
76
77#[cfg(feature = "stm32g484")]
78pub use stm32g4::stm32g484 as pac;
79
80use core::marker::PhantomData;
81use core::mem::MaybeUninit;
82
83use crate::compare_register::{HrCr1, HrCr2, HrCr3, HrCr4};
84use crate::fault::{FaultAction, FaultSource};
85use crate::output::{HrOut1, HrOut2, Output1Pin, Output2Pin};
86use crate::timer::HrTim;
87#[cfg(feature = "hrtim_v2")]
88use pac::HRTIM_TIMF;
89use pac::{HRTIM_COMMON, HRTIM_MASTER, HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME};
90
91use capture::{HrCaptCh1, HrCaptCh2};
92
93use self::control::HrPwmControl;
94
95use self::deadtime::DeadtimeConfig;
96use self::timer_eev_cfg::EevCfgs;
97
98use timer::{Instance, InstanceX};
99enum CountSettings {
101 Period(u16),
103}
104
105#[cfg_attr(feature = "defmt", derive(defmt::Format))]
106#[derive(Copy, Clone, PartialEq, Debug)]
107pub enum HrTimerMode {
108 SingleShotNonRetriggerable,
109 SingleShotRetriggerable,
110 Continuous,
111}
112
113#[cfg_attr(feature = "defmt", derive(defmt::Format))]
114#[derive(Copy, Clone, PartialEq, Debug)]
115pub enum HrCountingDirection {
116 Up,
138
139 #[cfg(feature = "hrtim_v2")]
140 UpDown,
169}
170
171#[cfg_attr(feature = "defmt", derive(defmt::Format))]
172#[derive(Copy, Clone, PartialEq, Debug)]
173pub enum InterleavedMode {
174 Disabled,
175
176 Dual,
185
186 #[cfg(feature = "hrtim_v2")]
187 Triple,
198
199 #[cfg(feature = "hrtim_v2")]
200 Quad,
212}
213
214pub trait HrPwmAdvExt: Sized {
215 type PreloadSource;
216
217 fn pwm_advanced<P1, P2>(
218 self,
219 pin1: P1,
220 pin2: P2,
221 ) -> HrPwmBuilder<Self, PsclDefault, Self::PreloadSource, P1, P2>
222 where
223 P1: Output1Pin<Self>,
224 P2: Output2Pin<Self>;
225}
226
227#[cfg_attr(feature = "defmt", derive(defmt::Format))]
228#[derive(Debug, Clone, Copy, PartialEq)]
229pub enum Polarity {
230 ActiveHigh,
231 ActiveLow,
232}
233
234pub trait DacStepTrigger {
235 const IS_CR2: bool;
236 const IS_OUT1_RST: bool;
237 const DCDS_BIT: Option<bool>;
238}
239
240pub trait DacResetTrigger {
241 const IS_TIM_RST: bool;
242 const IS_OUT1_SET: bool;
243 const DCDR_BIT: Option<bool>;
244}
245
246#[cfg_attr(feature = "defmt", derive(defmt::Format))]
247#[derive(Debug, Clone, Copy, PartialEq)]
248pub struct NoDacTrigger;
249
250impl DacStepTrigger for NoDacTrigger {
251 const IS_CR2: bool = false;
252 const IS_OUT1_RST: bool = false;
253
254 const DCDS_BIT: Option<bool> = None;
255}
256
257impl DacResetTrigger for NoDacTrigger {
258 const IS_TIM_RST: bool = false;
259 const IS_OUT1_SET: bool = false;
260
261 const DCDR_BIT: Option<bool> = None;
262}
263
264#[cfg_attr(feature = "defmt", derive(defmt::Format))]
266#[derive(Debug, Clone, Copy, PartialEq)]
267pub struct DacResetOnCounterReset;
268impl DacResetTrigger for DacResetOnCounterReset {
269 const IS_TIM_RST: bool = true;
270 const IS_OUT1_SET: bool = false;
271 const DCDR_BIT: Option<bool> = Some(false);
272}
273
274#[cfg_attr(feature = "defmt", derive(defmt::Format))]
276#[derive(Debug, Clone, Copy, PartialEq)]
277pub struct DacResetOnOut1Set;
278impl DacResetTrigger for DacResetOnOut1Set {
279 const IS_TIM_RST: bool = false;
280 const IS_OUT1_SET: bool = true;
281 const DCDR_BIT: Option<bool> = Some(true);
282}
283
284#[cfg_attr(feature = "defmt", derive(defmt::Format))]
303#[derive(Debug, Clone, Copy, PartialEq)]
304pub struct DacStepOnCmp2;
305impl DacStepTrigger for DacStepOnCmp2 {
306 const IS_CR2: bool = true;
307 const IS_OUT1_RST: bool = false;
308 const DCDS_BIT: Option<bool> = Some(false);
309}
310
311#[cfg_attr(feature = "defmt", derive(defmt::Format))]
313#[derive(Debug, Clone, Copy, PartialEq)]
314pub struct DacStepOnOut1Rst;
315impl DacStepTrigger for DacStepOnOut1Rst {
316 const IS_CR2: bool = false;
317 const IS_OUT1_RST: bool = true;
318 const DCDS_BIT: Option<bool> = Some(true);
319}
320
321pub struct HrPwmBuilder<
323 TIM,
324 PSCL,
325 PS,
326 P1,
327 P2,
328 DacRst: DacResetTrigger = NoDacTrigger,
329 DacStp: DacStepTrigger = NoDacTrigger,
330> {
331 _tim: PhantomData<TIM>,
332 _prescaler: PhantomData<PSCL>,
333 pin1: P1,
334 pin2: P2,
335 timer_mode: HrTimerMode,
336 counting_direction: HrCountingDirection,
337 count: CountSettings,
339 preload_source: Option<PS>,
340 fault_enable_bits: u8,
341 fault1_bits: u8,
342 fault2_bits: u8,
343 enable_push_pull: bool,
344 interleaved_mode: InterleavedMode, repetition_counter: u8,
346 deadtime: Option<DeadtimeConfig>,
347 enable_repetition_interrupt: bool,
348 eev_cfg: EevCfgs<TIM>,
349 dac_rst_trigger: PhantomData<DacRst>,
351 dac_stp_trigger: PhantomData<DacStp>,
352 out1_polarity: Polarity,
353 out2_polarity: Polarity,
354}
355
356pub struct HrParts<
357 TIM,
358 PSCL,
359 DacRst: DacResetTrigger = NoDacTrigger,
360 DacStp: DacStepTrigger = NoDacTrigger,
361> {
362 pub timer: HrTim<TIM, PSCL, HrCaptCh1<TIM, PSCL>, HrCaptCh2<TIM, PSCL>, DacRst>,
363
364 pub cr1: HrCr1<TIM, PSCL>,
365 pub cr2: HrCr2<TIM, PSCL, DacStp>,
366 pub cr3: HrCr3<TIM, PSCL>,
367 pub cr4: HrCr4<TIM, PSCL>,
368
369 pub out1: HrOut1<TIM, PSCL, DacRst, DacStp>,
370 pub out2: HrOut2<TIM, PSCL, DacRst, DacStp>,
371 pub dma_channel: timer::DmaChannel<TIM>,
372}
373
374#[cfg_attr(feature = "defmt", derive(defmt::Format))]
375#[derive(Debug, Clone, Copy)]
376pub enum PreloadSource {
377 OnCounterReset,
379
380 OnMasterTimerUpdate,
382
383 OnRepetitionUpdate,
385}
386
387#[cfg_attr(feature = "defmt", derive(defmt::Format))]
388#[derive(Debug, Clone, Copy)]
389pub enum MasterPreloadSource {
390 OnMasterRepetitionUpdate,
392}
393
394macro_rules! hrtim_finalize_body {
395 ($this:expr, $PreloadSource:ident, $TIMX:ident, [$($out:ident)*]) => {{
396 let tim = unsafe { &*$TIMX::ptr() };
397 let (period, prescaler_bits) = match $this.count {
398 CountSettings::Period(period) => (period as u32, PSCL::BITS as u16),
399 };
400
401 let (half, _intlvd) = match $this.interleaved_mode {
402 InterleavedMode::Disabled => (false, 0b00),
403 InterleavedMode::Dual => (true, 0b00),
404 #[cfg(feature = "hrtim_v2")]
405 InterleavedMode::Triple => (false, 0b01),
406 #[cfg(feature = "hrtim_v2")]
407 InterleavedMode::Quad => (false, 0b10),
408 };
409
410 tim.cr().modify(|_r, w| unsafe {
412 w
413 .cont().bit($this.timer_mode == HrTimerMode::Continuous)
415 .retrig().bit($this.timer_mode == HrTimerMode::SingleShotRetriggerable)
416
417 .half().bit(half)
421
422 .ckpsc().bits(prescaler_bits as u8)
424 });
425
426 #[cfg(feature = "hrtim_v2")]
427 tim.cr().modify(|_r, w| unsafe {
428 w.intlvd().bits(_intlvd)
430 });
431
432 $(
433 #[allow(unused)]
435 let $out = ();
436
437 #[cfg(feature = "hrtim_v2")]
439 tim.cr2().modify(|_r, w| {
440 w.udm().bit($this.counting_direction == HrCountingDirection::UpDown);
442 assert!(DacRst::DCDR_BIT.is_some() == DacStp::DCDS_BIT.is_some());
443
444 if let (Some(rst), Some(stp)) = (DacRst::DCDR_BIT, DacStp::DCDS_BIT) {
445 w
446 .dcde().set_bit()
447 .dcds().bit(stp as u8 != 0)
448 .dcdr().bit(rst as u8 != 0);
449 }
450
451 w
452 });
453
454 tim.cr().modify(|_r, w|
455 w.pshpll().bit($this.enable_push_pull)
457 );
458 )*
459
460 tim.perr().write(|w| unsafe { w.per().bits(period as u16) });
462
463 $(unsafe {
465 #[allow(unused)]
467 let $out = ();
468
469 let fault_enable_bits = $this.fault_enable_bits as u32;
471 tim.fltr().write(|w| w
472 .flt1en().bit(fault_enable_bits & (1 << 0) != 0)
473 .flt2en().bit(fault_enable_bits & (1 << 1) != 0)
474 .flt3en().bit(fault_enable_bits & (1 << 2) != 0)
475 .flt4en().bit(fault_enable_bits & (1 << 3) != 0)
476 .flt5en().bit(fault_enable_bits & (1 << 4) != 0)
477 );
478 #[cfg(feature = "hrtim_v2")]
479 tim.fltr().modify(|_, w| w.flt6en().bit(fault_enable_bits & (1 << 5) != 0));
480
481 tim.fltr().modify(|_r, w| w.fltlck().set_bit());
483
484 tim.outr().modify(|_r, w| w
485 .fault1().bits($this.fault1_bits)
487 .fault2().bits($this.fault2_bits)
488
489 .pol1().bit(matches!($this.out1_polarity, Polarity::ActiveLow))
491 .pol2().bit(matches!($this.out2_polarity, Polarity::ActiveLow))
492 );
493 if let Some(deadtime) = $this.deadtime {
494 let DeadtimeConfig {
495 prescaler,
496 deadtime_rising_value,
497 deadtime_rising_sign,
498 deadtime_falling_value,
499 deadtime_falling_sign,
500 } = deadtime;
501
502 tim.dtr().modify(|_r, w| w
505 .dtprsc().bits(prescaler as u8)
506 .dtr().bits(deadtime_rising_value)
507 .sdtr().bit(deadtime_rising_sign)
508 .dtf().bits(deadtime_falling_value)
509 .sdtf().bit(deadtime_falling_sign)
510
511 .dtflk().set_bit()
513 .dtfslk().set_bit()
514 .dtrlk().set_bit()
515 .dtrslk().set_bit()
516 );
517 tim.outr().modify(|_r, w| w.dten().set_bit());
518 }
519
520 let eev_cfg = $this.eev_cfg.clone();
522 tim.eefr1().write(|w| w
523 .ee1ltch().bit(eev_cfg.eev1.latch_bit).ee1fltr().bits(eev_cfg.eev1.filter_bits)
524 .ee2ltch().bit(eev_cfg.eev2.latch_bit).ee2fltr().bits(eev_cfg.eev2.filter_bits)
525 .ee3ltch().bit(eev_cfg.eev3.latch_bit).ee3fltr().bits(eev_cfg.eev3.filter_bits)
526 .ee4ltch().bit(eev_cfg.eev4.latch_bit).ee4fltr().bits(eev_cfg.eev4.filter_bits)
527 .ee5ltch().bit(eev_cfg.eev5.latch_bit).ee5fltr().bits(eev_cfg.eev5.filter_bits)
528 );
529 tim.eefr2().write(|w| w
530 .ee6ltch().bit(eev_cfg.eev6.latch_bit).ee6fltr().bits(eev_cfg.eev6.filter_bits)
531 .ee7ltch().bit(eev_cfg.eev7.latch_bit).ee7fltr().bits(eev_cfg.eev7.filter_bits)
532 .ee8ltch().bit(eev_cfg.eev8.latch_bit).ee8fltr().bits(eev_cfg.eev8.filter_bits)
533 .ee9ltch().bit(eev_cfg.eev9.latch_bit).ee9fltr().bits(eev_cfg.eev9.filter_bits)
534 .ee10ltch().bit(eev_cfg.eev10.latch_bit).ee10fltr().bits(eev_cfg.eev10.filter_bits)
535 );
536 #[cfg(feature = "hrtim_v2")]
537 tim.eefr3().write(|w| w
538 .eevace().bit(eev_cfg.event_counter_enable_bit)
539 .eevarstm().bit(eev_cfg.event_counter_reset_mode_bit)
542 .eevasel().bits(eev_cfg.event_counter_source_bits)
543 .eevacnt().bits(eev_cfg.event_counter_threshold_bits)
544 );
545 })*
546
547
548 hrtim_finalize_body!($PreloadSource, $this, tim);
549
550 unsafe { tim.repr().write(|w| w.rep().bits($this.repetition_counter)); }
552
553 tim.dier().modify(|_r, w| w.repie().bit($this.enable_repetition_interrupt));
555
556 }};
560
561 (PreloadSource, $this:expr, $tim:expr) => {{
562 match $this.preload_source {
563 Some(PreloadSource::OnCounterReset) => {
564 $tim.cr().modify(|_r, w| w
565 .trstu().set_bit()
566 .preen().set_bit()
567 );
568 },
569 Some(PreloadSource::OnMasterTimerUpdate) => {
570 $tim.cr().modify(|_r, w| w
571 .mstu().set_bit()
572 .preen().set_bit()
573 );
574 }
575 Some(PreloadSource::OnRepetitionUpdate) => {
576 $tim.cr().modify(|_r, w| w
577 .trepu().set_bit()
578 .preen().set_bit()
579 );
580 }
581 None => ()
582 }
583 }};
584
585 (MasterPreloadSource, $this:expr, $tim:expr) => {{
586 match $this.preload_source {
587 Some(MasterPreloadSource::OnMasterRepetitionUpdate) => {
588 $tim.cr().modify(|_r, w| w
589 .mrepu().set_bit()
590 .preen().set_bit()
591 );
592 }
593 None => ()
594 }
595 }};
596}
597
598impl<
599 TIM: Instance + HrPwmAdvExt,
600 PSCL,
601 P1,
602 P2,
603 DacRst: DacResetTrigger,
604 DacStp: DacStepTrigger,
605 > HrPwmBuilder<TIM, PSCL, TIM::PreloadSource, P1, P2, DacRst, DacStp>
606where
607 PSCL: HrtimPrescaler,
608 P1: Output1Pin<TIM>,
609 P2: Output2Pin<TIM>,
610{
611 pub fn prescaler<P>(
613 self,
614 _prescaler: P,
615 ) -> HrPwmBuilder<TIM, P, TIM::PreloadSource, P1, P2, DacRst, DacStp>
616 where
617 P: HrtimPrescaler,
618 {
619 let HrPwmBuilder {
620 _tim,
621 _prescaler: _,
622 pin1,
623 pin2,
624 timer_mode,
625 fault_enable_bits,
626 fault1_bits,
627 fault2_bits,
628 enable_push_pull,
629 interleaved_mode,
630 counting_direction,
631 count,
633 preload_source,
634 repetition_counter,
635 deadtime,
636 enable_repetition_interrupt,
637 eev_cfg,
638 dac_rst_trigger,
639 dac_stp_trigger,
640 out1_polarity,
641 out2_polarity,
642 } = self;
643
644 let period = match count {
645 CountSettings::Period(period) => period,
646 };
647
648 let count = CountSettings::Period(period);
649
650 HrPwmBuilder {
651 _tim,
652 _prescaler: PhantomData,
653 pin1,
654 pin2,
655 timer_mode,
656 fault_enable_bits,
657 fault1_bits,
658 fault2_bits,
659 enable_push_pull,
660 interleaved_mode,
661 counting_direction,
662 count,
664 preload_source,
665 repetition_counter,
666 deadtime,
667 enable_repetition_interrupt,
668 eev_cfg,
669 dac_rst_trigger,
670 dac_stp_trigger,
671 out1_polarity,
672 out2_polarity,
673 }
674 }
675
676 pub fn timer_mode(mut self, timer_mode: HrTimerMode) -> Self {
677 self.timer_mode = timer_mode;
678 self
679 }
680
681 pub fn preload(mut self, preload_source: TIM::PreloadSource) -> Self {
683 self.preload_source = Some(preload_source);
684 self
685 }
686
687 pub fn period(mut self, period: u16) -> Self {
689 self.count = CountSettings::Period(period);
690 self
691 }
692
693 pub fn repetition_counter(mut self, repetition_counter: u8) -> Self {
696 self.repetition_counter = repetition_counter;
697 self
698 }
699
700 pub fn enable_repetition_interrupt(mut self) -> Self {
701 self.enable_repetition_interrupt = true;
702 self
703 }
704
705 pub fn eev_cfg(mut self, eev_cfg: EevCfgs<TIM>) -> Self {
706 self.eev_cfg = eev_cfg;
707 self
708 }
709
710 #[cfg(feature = "hrtim_v2")]
711 pub fn dac_trigger_cfg<R: DacResetTrigger, S: DacStepTrigger>(
761 self,
762 _rst: R,
763 _step: S,
764 ) -> HrPwmBuilder<TIM, PSCL, TIM::PreloadSource, P1, P2, R, S> {
765 let HrPwmBuilder {
766 _tim,
767 _prescaler: _,
768 pin1,
769 pin2,
770 timer_mode,
771 fault_enable_bits,
772 fault1_bits,
773 fault2_bits,
774 enable_push_pull,
775 interleaved_mode,
776 counting_direction,
777 count,
779 preload_source,
780 repetition_counter,
781 deadtime,
782 enable_repetition_interrupt,
783 eev_cfg,
784 dac_rst_trigger: _,
785 dac_stp_trigger: _,
786 out1_polarity,
787 out2_polarity,
788 } = self;
789
790 HrPwmBuilder {
791 _tim,
792 _prescaler: PhantomData,
793 pin1,
794 pin2,
795 timer_mode,
796 fault_enable_bits,
797 fault1_bits,
798 fault2_bits,
799 enable_push_pull,
800 interleaved_mode,
801 counting_direction,
802 count,
804 preload_source,
805 repetition_counter,
806 deadtime,
807 enable_repetition_interrupt,
808 eev_cfg,
809 dac_rst_trigger: PhantomData,
810 dac_stp_trigger: PhantomData,
811 out1_polarity,
812 out2_polarity,
813 }
814 }
815}
816
817impl HrPwmAdvExt for HRTIM_MASTER {
818 type PreloadSource = MasterPreloadSource;
819
820 fn pwm_advanced<P1, P2>(
821 self,
822 pin1: P1,
823 pin2: P2,
824 ) -> HrPwmBuilder<Self, PsclDefault, Self::PreloadSource, P1, P2>
825 where
826 P1: Output1Pin<Self>,
827 P2: Output2Pin<Self>,
828 {
829 HrPwmBuilder {
835 _tim: PhantomData,
836 _prescaler: PhantomData,
837 pin1,
838 pin2,
839 timer_mode: HrTimerMode::Continuous,
840 fault_enable_bits: 0b000000,
841 fault1_bits: 0b00,
842 fault2_bits: 0b00,
843 counting_direction: HrCountingDirection::Up,
844 count: CountSettings::Period(u16::MAX),
846 preload_source: None,
847 enable_push_pull: false,
848 interleaved_mode: InterleavedMode::Disabled,
849 repetition_counter: 0,
850 deadtime: None,
851 enable_repetition_interrupt: false,
852 eev_cfg: EevCfgs::default(),
853 dac_rst_trigger: PhantomData,
854 dac_stp_trigger: PhantomData,
855 out1_polarity: Polarity::ActiveHigh,
856 out2_polarity: Polarity::ActiveHigh,
857 }
858 }
859}
860
861impl<TIM: InstanceX> HrPwmAdvExt for TIM {
862 type PreloadSource = PreloadSource;
863
864 fn pwm_advanced<P1, P2>(
865 self,
866 pin1: P1,
867 pin2: P2,
868 ) -> HrPwmBuilder<Self, PsclDefault, Self::PreloadSource, P1, P2>
869 where
870 P1: Output1Pin<TIM>,
871 P2: Output2Pin<TIM>,
872 {
873 HrPwmBuilder {
879 _tim: PhantomData,
880 _prescaler: PhantomData,
881 pin1,
882 pin2,
883 timer_mode: HrTimerMode::Continuous,
884 fault_enable_bits: 0b000000,
885 fault1_bits: 0b00,
886 fault2_bits: 0b00,
887 counting_direction: HrCountingDirection::Up,
888 count: CountSettings::Period(u16::MAX),
890 preload_source: None,
891 enable_push_pull: false,
892 interleaved_mode: InterleavedMode::Disabled,
893 repetition_counter: 0,
894 deadtime: None,
895 enable_repetition_interrupt: false,
896 eev_cfg: EevCfgs::default(),
897 dac_rst_trigger: PhantomData,
898 dac_stp_trigger: PhantomData,
899 out1_polarity: Polarity::ActiveHigh,
900 out2_polarity: Polarity::ActiveHigh,
901 }
902 }
903}
904
905impl<TIM: InstanceX, PSCL, P1, P2> HrPwmBuilder<TIM, PSCL, PreloadSource, P1, P2>
906where
907 PSCL: HrtimPrescaler,
908 P1: Output1Pin<TIM>,
909 P2: Output2Pin<TIM>,
910{
911 pub fn with_fault_source<FS>(mut self, _fault_source: FS) -> Self
912 where
913 FS: FaultSource,
914 {
915 self.fault_enable_bits |= FS::ENABLE_BITS;
916
917 self
918 }
919
920 pub fn fault_action1(mut self, fault_action1: FaultAction) -> Self {
921 self.fault1_bits = fault_action1 as _;
922
923 self
924 }
925
926 pub fn fault_action2(mut self, fault_action2: FaultAction) -> Self {
927 self.fault2_bits = fault_action2 as _;
928
929 self
930 }
931
932 pub fn out1_polarity(mut self, polarity: Polarity) -> Self {
933 self.out1_polarity = polarity;
934
935 self
936 }
937
938 pub fn out2_polarity(mut self, polarity: Polarity) -> Self {
939 self.out2_polarity = polarity;
940
941 self
942 }
943
944 pub fn push_pull_mode(mut self, enable: bool) -> Self {
962 self.enable_push_pull = enable;
964
965 self
966 }
967
968 pub fn counting_direction(mut self, counting_direction: HrCountingDirection) -> Self {
972 self.counting_direction = counting_direction;
973
974 self
975 }
976
977 pub fn interleaved_mode(mut self, mode: InterleavedMode) -> Self {
981 self.interleaved_mode = mode;
982
983 self
984 }
985
986 pub fn deadtime(mut self, deadtime: DeadtimeConfig) -> Self {
987 self.deadtime = Some(deadtime);
988
989 self
990 }
991
992 }
994
995macro_rules! hrtim_hal {
997 ($($TIMX:ident: $($out:ident)*,)+) => {
998 $(
999 impl<PSCL, P1, P2, DacRst, DacStp>
1000 HrPwmBuilder<$TIMX, PSCL, PreloadSource, P1, P2, DacRst, DacStp>
1001 where
1002 DacRst: DacResetTrigger,
1003 DacStp: DacStepTrigger,
1004 PSCL: HrtimPrescaler,
1005 P1: Output1Pin<$TIMX>,
1006 P2: Output2Pin<$TIMX>,
1007 {
1008 pub fn _init(self, _control: &mut HrPwmControl) -> (P1, P2) {
1012 hrtim_finalize_body!(self, PreloadSource, $TIMX, [$($out)*]);
1013 (self.pin1, self.pin2)
1014 }
1015 }
1016 )+
1017 };
1018}
1019
1020hrtim_hal! {
1021 HRTIM_TIMA: out,
1022 HRTIM_TIMB: out,
1023 HRTIM_TIMC: out,
1024 HRTIM_TIMD: out,
1025 HRTIM_TIME: out,
1026}
1027
1028#[cfg(feature = "hrtim_v2")]
1029hrtim_hal! {
1030 HRTIM_TIMF: out,
1031}
1032
1033impl<PSCL, P1, P2, DacRst, DacStp>
1034 HrPwmBuilder<HRTIM_MASTER, PSCL, MasterPreloadSource, P1, P2, DacRst, DacStp>
1035where
1036 DacRst: DacResetTrigger,
1037 DacStp: DacStepTrigger,
1038 PSCL: HrtimPrescaler,
1039 P1: Output1Pin<HRTIM_MASTER>,
1040 P2: Output1Pin<HRTIM_MASTER>,
1041{
1042 pub fn finalize(self, _control: &mut HrPwmControl) -> HrParts<HRTIM_MASTER, PSCL> {
1043 hrtim_finalize_body!(self, MasterPreloadSource, HRTIM_MASTER, []);
1044
1045 unsafe { MaybeUninit::uninit().assume_init() }
1046 }
1047}
1048
1049pub unsafe trait HrtimPrescaler: Default {
1052 const BITS: u8;
1053 const VALUE: u8;
1054
1055 const MIN_CR: u16;
1059
1060 const MAX_CR: u16;
1062}
1063
1064macro_rules! impl_pscl {
1065 ($($t:ident => $b:literal, $v:literal, $min:literal, $max:literal)+) => {$(
1066 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
1067 #[derive(Copy, Clone, Default)]
1068 pub struct $t;
1069 unsafe impl HrtimPrescaler for $t {
1070 const BITS: u8 = $b;
1071 const VALUE: u8 = $v;
1072 const MIN_CR: u16 = $min;
1073 const MAX_CR: u16 = $max;
1074 }
1075 )+};
1076}
1077
1078#[cfg(any(feature = "stm32f3", feature = "stm32g4"))]
1079pub type PsclDefault = Pscl128;
1080
1081#[cfg(feature = "stm32h7")]
1082pub type PsclDefault = Pscl4;
1083
1084#[cfg(any(feature = "stm32f3", feature = "stm32g4"))]
1085impl_pscl! {
1086 Pscl1 => 0b000, 1, 0x0060, 0xFFDF
1087 Pscl2 => 0b001, 2, 0x0030, 0xFFEF
1088 Pscl4 => 0b010, 4, 0x0018, 0xFFF7
1089 Pscl8 => 0b011, 8, 0x000C, 0xFFFB
1090 Pscl16 => 0b100, 16, 0x0006, 0xFFFD
1091 Pscl32 => 0b101, 32, 0x0003, 0xFFFD
1092 Pscl64 => 0b110, 64, 0x0003, 0xFFFD
1093 Pscl128 => 0b111, 128, 0x0003, 0xFFFD
1094}
1095
1096#[cfg(feature = "stm32h7")]
1097impl_pscl! {
1098 Pscl1 => 0b101, 1, 0x0003, 0xFFFD
1099 Pscl2 => 0b110, 2, 0x0003, 0xFFFD
1100 Pscl4 => 0b111, 4, 0x0003, 0xFFFD
1101}
1102
1103