1#![no_std]
2
3#[cfg(not(any(
4 feature = "stm32f334",
5 feature = "stm32h742",
6 feature = "stm32h743",
7 feature = "stm32h747cm7",
9 feature = "stm32h750",
10 feature = "stm32h753",
11 feature = "stm32g474",
14 feature = "stm32g484",
15)))]
16compile_error!(
17 "This crate requires one of the following features enabled:
18 stm32f334
19
20 stm32h742
21 stm32h743
22 #stm32h745
23 stm32h747cm7
24 stm32h750
25 stm32h753
26 #stm32h755
27 #stm32h757
28
29 stm32g474
30 stm32g484"
31);
32
33pub mod adc_trigger;
34pub mod capture;
35pub mod compare_register;
36pub mod control;
37pub mod deadtime;
38pub mod event;
39pub mod ext;
40pub mod external_event;
41pub mod fault;
42pub mod output;
43pub mod timer;
44pub mod timer_eev_cfg;
45
46#[cfg(feature = "stm32f334")]
47pub use stm32f3::stm32f3x4 as pac;
48
49#[cfg(feature = "stm32h742")]
50pub use stm32h7::stm32h742 as pac;
51
52#[cfg(feature = "stm32h743")]
53pub use stm32h7::stm32h743 as pac;
54
55#[cfg(feature = "stm32h747cm7")]
59pub use stm32h7::stm32h747cm7 as pac;
60
61#[cfg(feature = "stm32h750")]
62pub use stm32h7::stm32h750 as pac;
63
64#[cfg(feature = "stm32h753")]
65pub use stm32h7::stm32h753 as pac;
66
67#[cfg(feature = "stm32g474")]
74pub use stm32g4::stm32g474 as pac;
75
76#[cfg(feature = "stm32g484")]
77pub use stm32g4::stm32g484 as pac;
78
79use core::marker::PhantomData;
80use core::mem::MaybeUninit;
81
82use crate::compare_register::{HrCr1, HrCr2, HrCr3, HrCr4};
83use crate::fault::{FaultAction, FaultSource};
84use crate::timer::HrTim;
85#[cfg(feature = "hrtim_v2")]
86use pac::HRTIM_TIMF;
87use pac::{HRTIM_COMMON, HRTIM_MASTER, HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME};
88
89use capture::{HrCaptCh1, HrCaptCh2};
90
91use self::control::HrPwmControl;
92
93use self::deadtime::DeadtimeConfig;
94use self::output::ToHrOut;
95use self::timer_eev_cfg::EevCfgs;
96
97use timer::{Instance, InstanceX};
98enum CountSettings {
100 Period(u16),
102}
103
104#[derive(Copy, Clone, PartialEq, Debug)]
105pub enum HrTimerMode {
106 SingleShotNonRetriggerable,
107 SingleShotRetriggerable,
108 Continuous,
109}
110
111#[derive(Copy, Clone, PartialEq, Debug)]
112pub enum HrCountingDirection {
113 Up,
135
136 #[cfg(feature = "hrtim_v2")]
137 UpDown,
166}
167
168#[derive(Copy, Clone, PartialEq, Debug)]
169pub enum InterleavedMode {
170 Disabled,
171
172 Dual,
181
182 #[cfg(feature = "hrtim_v2")]
183 Triple,
194
195 #[cfg(feature = "hrtim_v2")]
196 Quad,
208}
209
210pub trait HrPwmAdvExt: Sized {
211 type PreloadSource;
212
213 fn pwm_advanced<PINS>(
214 self,
215 _pins: PINS,
216 ) -> HrPwmBuilder<Self, PsclDefault, Self::PreloadSource, PINS>
217 where
218 PINS: ToHrOut<Self>;
219}
220
221#[derive(Debug, Clone, Copy, PartialEq)]
222pub enum Polarity {
223 ActiveHigh,
224 ActiveLow,
225}
226
227pub trait DacStepTrigger {
228 const IS_CR2: bool;
229 const IS_OUT1_RST: bool;
230 const DCDS_BIT: Option<bool>;
231}
232
233pub trait DacResetTrigger {
234 const IS_TIM_RST: bool;
235 const IS_OUT1_SET: bool;
236 const DCDR_BIT: Option<bool>;
237}
238
239pub struct NoDacTrigger;
240
241impl DacStepTrigger for NoDacTrigger {
242 const IS_CR2: bool = false;
243 const IS_OUT1_RST: bool = false;
244
245 const DCDS_BIT: Option<bool> = None;
246}
247
248impl DacResetTrigger for NoDacTrigger {
249 const IS_TIM_RST: bool = false;
250 const IS_OUT1_SET: bool = false;
251
252 const DCDR_BIT: Option<bool> = None;
253}
254
255pub struct DacResetOnCounterReset;
257impl DacResetTrigger for DacResetOnCounterReset {
258 const IS_TIM_RST: bool = true;
259 const IS_OUT1_SET: bool = false;
260 const DCDR_BIT: Option<bool> = Some(false);
261}
262
263pub struct DacResetOnOut1Set;
265impl DacResetTrigger for DacResetOnOut1Set {
266 const IS_TIM_RST: bool = false;
267 const IS_OUT1_SET: bool = true;
268 const DCDR_BIT: Option<bool> = Some(true);
269}
270
271pub struct DacStepOnCmp2;
290impl DacStepTrigger for DacStepOnCmp2 {
291 const IS_CR2: bool = true;
292 const IS_OUT1_RST: bool = false;
293 const DCDS_BIT: Option<bool> = Some(false);
294}
295
296pub struct DacStepOnOut1Rst;
298impl DacStepTrigger for DacStepOnOut1Rst {
299 const IS_CR2: bool = false;
300 const IS_OUT1_RST: bool = true;
301 const DCDS_BIT: Option<bool> = Some(true);
302}
303
304pub struct HrPwmBuilder<
306 TIM,
307 PSCL,
308 PS,
309 PINS,
310 DacRst: DacResetTrigger = NoDacTrigger,
311 DacStp: DacStepTrigger = NoDacTrigger,
312> {
313 _tim: PhantomData<TIM>,
314 _prescaler: PhantomData<PSCL>,
315 pub pins: PINS,
316 timer_mode: HrTimerMode,
317 counting_direction: HrCountingDirection,
318 count: CountSettings,
320 preload_source: Option<PS>,
321 fault_enable_bits: u8,
322 fault1_bits: u8,
323 fault2_bits: u8,
324 enable_push_pull: bool,
325 interleaved_mode: InterleavedMode, repetition_counter: u8,
327 deadtime: Option<DeadtimeConfig>,
328 enable_repetition_interrupt: bool,
329 eev_cfg: EevCfgs<TIM>,
330 dac_rst_trigger: PhantomData<DacRst>,
332 dac_stp_trigger: PhantomData<DacStp>,
333 out1_polarity: Polarity,
334 out2_polarity: Polarity,
335}
336
337pub struct HrParts<
338 TIM,
339 PSCL,
340 OUT,
341 DacRst: DacResetTrigger = NoDacTrigger,
342 DacStp: DacStepTrigger = NoDacTrigger,
343> {
344 pub timer: HrTim<TIM, PSCL, HrCaptCh1<TIM, PSCL>, HrCaptCh2<TIM, PSCL>, DacRst>,
345
346 pub cr1: HrCr1<TIM, PSCL>,
347 pub cr2: HrCr2<TIM, PSCL, DacStp>,
348 pub cr3: HrCr3<TIM, PSCL>,
349 pub cr4: HrCr4<TIM, PSCL>,
350
351 pub out: OUT,
352 pub dma_channel: timer::DmaChannel<TIM>,
353}
354
355pub enum PreloadSource {
356 OnCounterReset,
358
359 OnMasterTimerUpdate,
361
362 OnRepetitionUpdate,
364}
365
366pub enum MasterPreloadSource {
367 OnMasterRepetitionUpdate,
369}
370
371macro_rules! hrtim_finalize_body {
372 ($this:expr, $PreloadSource:ident, $TIMX:ident, [$($out:ident)*]) => {{
373 let tim = unsafe { &*$TIMX::ptr() };
374 let (period, prescaler_bits) = match $this.count {
375 CountSettings::Period(period) => (period as u32, PSCL::BITS as u16),
376 };
377
378 let (half, _intlvd) = match $this.interleaved_mode {
379 InterleavedMode::Disabled => (false, 0b00),
380 InterleavedMode::Dual => (true, 0b00),
381 #[cfg(feature = "hrtim_v2")]
382 InterleavedMode::Triple => (false, 0b01),
383 #[cfg(feature = "hrtim_v2")]
384 InterleavedMode::Quad => (false, 0b10),
385 };
386
387 tim.cr().modify(|_r, w| unsafe {
389 w
390 .cont().bit($this.timer_mode == HrTimerMode::Continuous)
392 .retrig().bit($this.timer_mode == HrTimerMode::SingleShotRetriggerable)
393
394 .half().bit(half)
398
399 .ckpsc().bits(prescaler_bits as u8)
401 });
402
403 #[cfg(feature = "hrtim_v2")]
404 tim.cr().modify(|_r, w| unsafe {
405 w.intlvd().bits(_intlvd)
407 });
408
409 $(
410 #[allow(unused)]
412 let $out = ();
413
414 #[cfg(feature = "hrtim_v2")]
416 tim.cr2().modify(|_r, w| {
417 w.udm().bit($this.counting_direction == HrCountingDirection::UpDown);
419 assert!(DacRst::DCDR_BIT.is_some() == DacStp::DCDS_BIT.is_some());
420
421 if let (Some(rst), Some(stp)) = (DacRst::DCDR_BIT, DacStp::DCDS_BIT) {
422 w
423 .dcde().set_bit()
424 .dcds().bit(stp as u8 != 0)
425 .dcdr().bit(rst as u8 != 0);
426 }
427
428 w
429 });
430
431 tim.cr().modify(|_r, w|
432 w.pshpll().bit($this.enable_push_pull)
434 );
435 )*
436
437 tim.perr().write(|w| unsafe { w.per().bits(period as u16) });
439
440 $(unsafe {
442 #[allow(unused)]
444 let $out = ();
445
446 let fault_enable_bits = $this.fault_enable_bits as u32;
448 tim.fltr().write(|w| w
449 .flt1en().bit(fault_enable_bits & (1 << 0) != 0)
450 .flt2en().bit(fault_enable_bits & (1 << 1) != 0)
451 .flt3en().bit(fault_enable_bits & (1 << 2) != 0)
452 .flt4en().bit(fault_enable_bits & (1 << 3) != 0)
453 .flt5en().bit(fault_enable_bits & (1 << 4) != 0)
454 );
455 #[cfg(feature = "hrtim_v2")]
456 tim.fltr().modify(|_, w| w.flt6en().bit(fault_enable_bits & (1 << 5) != 0));
457
458 tim.fltr().modify(|_r, w| w.fltlck().set_bit());
460
461 tim.outr().modify(|_r, w| w
462 .fault1().bits($this.fault1_bits)
464 .fault2().bits($this.fault2_bits)
465
466 .pol1().bit(matches!($this.out1_polarity, Polarity::ActiveLow))
468 .pol2().bit(matches!($this.out2_polarity, Polarity::ActiveLow))
469 );
470 if let Some(deadtime) = $this.deadtime {
471 let DeadtimeConfig {
472 prescaler,
473 deadtime_rising_value,
474 deadtime_rising_sign,
475 deadtime_falling_value,
476 deadtime_falling_sign,
477 } = deadtime;
478
479 tim.dtr().modify(|_r, w| w
482 .dtprsc().bits(prescaler as u8)
483 .dtr().bits(deadtime_rising_value)
484 .sdtr().bit(deadtime_rising_sign)
485 .dtf().bits(deadtime_falling_value)
486 .sdtf().bit(deadtime_falling_sign)
487
488 .dtflk().set_bit()
490 .dtfslk().set_bit()
491 .dtrlk().set_bit()
492 .dtrslk().set_bit()
493 );
494 tim.outr().modify(|_r, w| w.dten().set_bit());
495 }
496
497 let eev_cfg = $this.eev_cfg.clone();
499 tim.eefr1().write(|w| w
500 .ee1ltch().bit(eev_cfg.eev1.latch_bit).ee1fltr().bits(eev_cfg.eev1.filter_bits)
501 .ee2ltch().bit(eev_cfg.eev2.latch_bit).ee2fltr().bits(eev_cfg.eev2.filter_bits)
502 .ee3ltch().bit(eev_cfg.eev3.latch_bit).ee3fltr().bits(eev_cfg.eev3.filter_bits)
503 .ee4ltch().bit(eev_cfg.eev4.latch_bit).ee4fltr().bits(eev_cfg.eev4.filter_bits)
504 .ee5ltch().bit(eev_cfg.eev5.latch_bit).ee5fltr().bits(eev_cfg.eev5.filter_bits)
505 );
506 tim.eefr2().write(|w| w
507 .ee6ltch().bit(eev_cfg.eev6.latch_bit).ee6fltr().bits(eev_cfg.eev6.filter_bits)
508 .ee7ltch().bit(eev_cfg.eev7.latch_bit).ee7fltr().bits(eev_cfg.eev7.filter_bits)
509 .ee8ltch().bit(eev_cfg.eev8.latch_bit).ee8fltr().bits(eev_cfg.eev8.filter_bits)
510 .ee9ltch().bit(eev_cfg.eev9.latch_bit).ee9fltr().bits(eev_cfg.eev9.filter_bits)
511 .ee10ltch().bit(eev_cfg.eev10.latch_bit).ee10fltr().bits(eev_cfg.eev10.filter_bits)
512 );
513 #[cfg(feature = "hrtim_v2")]
514 tim.eefr3().write(|w| w
515 .eevace().bit(eev_cfg.event_counter_enable_bit)
516 .eevarstm().bit(eev_cfg.event_counter_reset_mode_bit)
519 .eevasel().bits(eev_cfg.event_counter_source_bits)
520 .eevacnt().bits(eev_cfg.event_counter_threshold_bits)
521 );
522 })*
523
524
525 hrtim_finalize_body!($PreloadSource, $this, tim);
526
527 unsafe { tim.repr().write(|w| w.rep().bits($this.repetition_counter)); }
529
530 tim.dier().modify(|_r, w| w.repie().bit($this.enable_repetition_interrupt));
532
533 }};
537
538 (PreloadSource, $this:expr, $tim:expr) => {{
539 match $this.preload_source {
540 Some(PreloadSource::OnCounterReset) => {
541 $tim.cr().modify(|_r, w| w
542 .trstu().set_bit()
543 .preen().set_bit()
544 );
545 },
546 Some(PreloadSource::OnMasterTimerUpdate) => {
547 $tim.cr().modify(|_r, w| w
548 .mstu().set_bit()
549 .preen().set_bit()
550 );
551 }
552 Some(PreloadSource::OnRepetitionUpdate) => {
553 $tim.cr().modify(|_r, w| w
554 .trepu().set_bit()
555 .preen().set_bit()
556 );
557 }
558 None => ()
559 }
560 }};
561
562 (MasterPreloadSource, $this:expr, $tim:expr) => {{
563 match $this.preload_source {
564 Some(MasterPreloadSource::OnMasterRepetitionUpdate) => {
565 $tim.cr().modify(|_r, w| w
566 .mrepu().set_bit()
567 .preen().set_bit()
568 );
569 }
570 None => ()
571 }
572 }};
573}
574
575impl<TIM: Instance + HrPwmAdvExt, PSCL, PINS, DacRst: DacResetTrigger, DacStp: DacStepTrigger>
576 HrPwmBuilder<TIM, PSCL, TIM::PreloadSource, PINS, DacRst, DacStp>
577where
578 PSCL: HrtimPrescaler,
579 PINS: ToHrOut<TIM>,
580{
581 pub fn prescaler<P>(
583 self,
584 _prescaler: P,
585 ) -> HrPwmBuilder<TIM, P, TIM::PreloadSource, PINS, DacRst, DacStp>
586 where
587 P: HrtimPrescaler,
588 {
589 let HrPwmBuilder {
590 _tim,
591 _prescaler: _,
592 pins,
593 timer_mode,
594 fault_enable_bits,
595 fault1_bits,
596 fault2_bits,
597 enable_push_pull,
598 interleaved_mode,
599 counting_direction,
600 count,
602 preload_source,
603 repetition_counter,
604 deadtime,
605 enable_repetition_interrupt,
606 eev_cfg,
607 dac_rst_trigger,
608 dac_stp_trigger,
609 out1_polarity,
610 out2_polarity,
611 } = self;
612
613 let period = match count {
614 CountSettings::Period(period) => period,
615 };
616
617 let count = CountSettings::Period(period);
618
619 HrPwmBuilder {
620 _tim,
621 _prescaler: PhantomData,
622 pins,
623 timer_mode,
624 fault_enable_bits,
625 fault1_bits,
626 fault2_bits,
627 enable_push_pull,
628 interleaved_mode,
629 counting_direction,
630 count,
632 preload_source,
633 repetition_counter,
634 deadtime,
635 enable_repetition_interrupt,
636 eev_cfg,
637 dac_rst_trigger,
638 dac_stp_trigger,
639 out1_polarity,
640 out2_polarity,
641 }
642 }
643
644 pub fn timer_mode(mut self, timer_mode: HrTimerMode) -> Self {
645 self.timer_mode = timer_mode;
646 self
647 }
648
649 pub fn preload(mut self, preload_source: TIM::PreloadSource) -> Self {
651 self.preload_source = Some(preload_source);
652 self
653 }
654
655 pub fn period(mut self, period: u16) -> Self {
657 self.count = CountSettings::Period(period);
658 self
659 }
660
661 pub fn repetition_counter(mut self, repetition_counter: u8) -> Self {
664 self.repetition_counter = repetition_counter;
665 self
666 }
667
668 pub fn enable_repetition_interrupt(mut self) -> Self {
669 self.enable_repetition_interrupt = true;
670 self
671 }
672
673 pub fn eev_cfg(mut self, eev_cfg: EevCfgs<TIM>) -> Self {
674 self.eev_cfg = eev_cfg;
675 self
676 }
677
678 #[cfg(feature = "hrtim_v2")]
679 pub fn dac_trigger_cfg<R: DacResetTrigger, S: DacStepTrigger>(
729 self,
730 _rst: R,
731 _step: S,
732 ) -> HrPwmBuilder<TIM, PSCL, TIM::PreloadSource, PINS, R, S> {
733 let HrPwmBuilder {
734 _tim,
735 _prescaler: _,
736 pins,
737 timer_mode,
738 fault_enable_bits,
739 fault1_bits,
740 fault2_bits,
741 enable_push_pull,
742 interleaved_mode,
743 counting_direction,
744 count,
746 preload_source,
747 repetition_counter,
748 deadtime,
749 enable_repetition_interrupt,
750 eev_cfg,
751 dac_rst_trigger: _,
752 dac_stp_trigger: _,
753 out1_polarity,
754 out2_polarity,
755 } = self;
756
757 HrPwmBuilder {
758 _tim,
759 _prescaler: PhantomData,
760 pins,
761 timer_mode,
762 fault_enable_bits,
763 fault1_bits,
764 fault2_bits,
765 enable_push_pull,
766 interleaved_mode,
767 counting_direction,
768 count,
770 preload_source,
771 repetition_counter,
772 deadtime,
773 enable_repetition_interrupt,
774 eev_cfg,
775 dac_rst_trigger: PhantomData,
776 dac_stp_trigger: PhantomData,
777 out1_polarity,
778 out2_polarity,
779 }
780 }
781}
782
783impl HrPwmAdvExt for HRTIM_MASTER {
784 type PreloadSource = MasterPreloadSource;
785
786 fn pwm_advanced<PINS>(
787 self,
788 pins: PINS,
789 ) -> HrPwmBuilder<Self, PsclDefault, Self::PreloadSource, PINS>
790 where
791 PINS: ToHrOut<HRTIM_MASTER>,
792 {
793 HrPwmBuilder {
799 _tim: PhantomData,
800 _prescaler: PhantomData,
801 pins,
802 timer_mode: HrTimerMode::Continuous,
803 fault_enable_bits: 0b000000,
804 fault1_bits: 0b00,
805 fault2_bits: 0b00,
806 counting_direction: HrCountingDirection::Up,
807 count: CountSettings::Period(u16::MAX),
809 preload_source: None,
810 enable_push_pull: false,
811 interleaved_mode: InterleavedMode::Disabled,
812 repetition_counter: 0,
813 deadtime: None,
814 enable_repetition_interrupt: false,
815 eev_cfg: EevCfgs::default(),
816 dac_rst_trigger: PhantomData,
817 dac_stp_trigger: PhantomData,
818 out1_polarity: Polarity::ActiveHigh,
819 out2_polarity: Polarity::ActiveHigh,
820 }
821 }
822}
823
824impl<TIM: InstanceX> HrPwmAdvExt for TIM {
825 type PreloadSource = PreloadSource;
826
827 fn pwm_advanced<PINS>(
828 self,
829 pins: PINS,
830 ) -> HrPwmBuilder<Self, PsclDefault, Self::PreloadSource, PINS>
831 where
832 PINS: ToHrOut<TIM>,
833 {
834 HrPwmBuilder {
840 _tim: PhantomData,
841 _prescaler: PhantomData,
842 pins,
843 timer_mode: HrTimerMode::Continuous,
844 fault_enable_bits: 0b000000,
845 fault1_bits: 0b00,
846 fault2_bits: 0b00,
847 counting_direction: HrCountingDirection::Up,
848 count: CountSettings::Period(u16::MAX),
850 preload_source: None,
851 enable_push_pull: false,
852 interleaved_mode: InterleavedMode::Disabled,
853 repetition_counter: 0,
854 deadtime: None,
855 enable_repetition_interrupt: false,
856 eev_cfg: EevCfgs::default(),
857 dac_rst_trigger: PhantomData,
858 dac_stp_trigger: PhantomData,
859 out1_polarity: Polarity::ActiveHigh,
860 out2_polarity: Polarity::ActiveHigh,
861 }
862 }
863}
864
865impl<TIM: InstanceX, PSCL, PINS> HrPwmBuilder<TIM, PSCL, PreloadSource, PINS>
866where
867 PSCL: HrtimPrescaler,
868 PINS: ToHrOut<TIM>,
869{
870 pub fn with_fault_source<FS>(mut self, _fault_source: FS) -> Self
871 where
872 FS: FaultSource,
873 {
874 self.fault_enable_bits |= FS::ENABLE_BITS;
875
876 self
877 }
878
879 pub fn fault_action1(mut self, fault_action1: FaultAction) -> Self {
880 self.fault1_bits = fault_action1 as _;
881
882 self
883 }
884
885 pub fn fault_action2(mut self, fault_action2: FaultAction) -> Self {
886 self.fault2_bits = fault_action2 as _;
887
888 self
889 }
890
891 pub fn out1_polarity(mut self, polarity: Polarity) -> Self {
892 self.out1_polarity = polarity;
893
894 self
895 }
896
897 pub fn out2_polarity(mut self, polarity: Polarity) -> Self {
898 self.out2_polarity = polarity;
899
900 self
901 }
902
903 pub fn push_pull_mode(mut self, enable: bool) -> Self {
921 self.enable_push_pull = enable;
923
924 self
925 }
926
927 pub fn counting_direction(mut self, counting_direction: HrCountingDirection) -> Self {
931 self.counting_direction = counting_direction;
932
933 self
934 }
935
936 pub fn interleaved_mode(mut self, mode: InterleavedMode) -> Self {
940 self.interleaved_mode = mode;
941
942 self
943 }
944
945 pub fn deadtime(mut self, deadtime: DeadtimeConfig) -> Self {
946 self.deadtime = Some(deadtime);
947
948 self
949 }
950
951 }
953
954macro_rules! hrtim_hal {
956 ($($TIMX:ident: $($out:ident)*,)+) => {
957 $(
958 impl<PSCL, PINS, DacRst, DacStp>
959 HrPwmBuilder<$TIMX, PSCL, PreloadSource, PINS, DacRst, DacStp>
960 where
961 DacRst: DacResetTrigger,
962 DacStp: DacStepTrigger,
963 PSCL: HrtimPrescaler,
964 PINS: ToHrOut<$TIMX, DacRst, DacStp>,
965 {
966 pub fn _init(self, _control: &mut HrPwmControl) -> PINS {
970 hrtim_finalize_body!(self, PreloadSource, $TIMX, [$($out)*]);
971 self.pins
972 }
973 }
974 )+
975 };
976}
977
978hrtim_hal! {
979 HRTIM_TIMA: out,
980 HRTIM_TIMB: out,
981 HRTIM_TIMC: out,
982 HRTIM_TIMD: out,
983 HRTIM_TIME: out,
984}
985
986#[cfg(feature = "hrtim_v2")]
987hrtim_hal! {
988 HRTIM_TIMF: out,
989}
990
991impl<PSCL, PINS, DacRst, DacStp>
992 HrPwmBuilder<HRTIM_MASTER, PSCL, MasterPreloadSource, PINS, DacRst, DacStp>
993where
994 DacRst: DacResetTrigger,
995 DacStp: DacStepTrigger,
996 PSCL: HrtimPrescaler,
997 PINS: ToHrOut<HRTIM_MASTER>,
998{
999 pub fn finalize(self, _control: &mut HrPwmControl) -> HrParts<HRTIM_MASTER, PSCL, PINS> {
1000 hrtim_finalize_body!(self, MasterPreloadSource, HRTIM_MASTER, []);
1001
1002 unsafe { MaybeUninit::uninit().assume_init() }
1003 }
1004}
1005
1006pub unsafe trait HrtimPrescaler: Default {
1009 const BITS: u8;
1010 const VALUE: u8;
1011
1012 const MIN_CR: u16;
1016
1017 const MAX_CR: u16;
1019}
1020
1021macro_rules! impl_pscl {
1022 ($($t:ident => $b:literal, $v:literal, $min:literal, $max:literal)+) => {$(
1023 #[derive(Copy, Clone, Default)]
1024 pub struct $t;
1025 unsafe impl HrtimPrescaler for $t {
1026 const BITS: u8 = $b;
1027 const VALUE: u8 = $v;
1028 const MIN_CR: u16 = $min;
1029 const MAX_CR: u16 = $max;
1030 }
1031 )+};
1032}
1033
1034#[cfg(any(feature = "stm32f3", feature = "stm32g4"))]
1035pub type PsclDefault = Pscl128;
1036
1037#[cfg(feature = "stm32h7")]
1038pub type PsclDefault = Pscl4;
1039
1040#[cfg(any(feature = "stm32f3", feature = "stm32g4"))]
1041impl_pscl! {
1042 Pscl1 => 0b000, 1, 0x0060, 0xFFDF
1043 Pscl2 => 0b001, 2, 0x0030, 0xFFEF
1044 Pscl4 => 0b010, 4, 0x0018, 0xFFF7
1045 Pscl8 => 0b011, 8, 0x000C, 0xFFFB
1046 Pscl16 => 0b100, 16, 0x0006, 0xFFFD
1047 Pscl32 => 0b101, 32, 0x0003, 0xFFFD
1048 Pscl64 => 0b110, 64, 0x0003, 0xFFFD
1049 Pscl128 => 0b111, 128, 0x0003, 0xFFFD
1050}
1051
1052#[cfg(feature = "stm32h7")]
1053impl_pscl! {
1054 Pscl1 => 0b101, 1, 0x0003, 0xFFFD
1055 Pscl2 => 0b110, 2, 0x0003, 0xFFFD
1056 Pscl4 => 0b111, 4, 0x0003, 0xFFFD
1057}
1058
1059