@@ -26,12 +26,10 @@ use fugit::HertzU64;
2626use self :: control:: HrPwmControl ;
2727
2828use self :: deadtime:: DeadtimeConfig ;
29- use self :: output:: { HrtimChannel , ToHrOut , CH1 , CH2 } ;
29+ use self :: output:: ToHrOut ;
3030use self :: timer_eev_cfg:: EevCfgs ;
3131
32- use crate :: pwm:: {
33- self , Alignment , ComplementaryImpossible , Pins , Polarity , Pwm , PwmPinEnable , TimerType ,
34- } ;
32+ use crate :: pwm:: { self , Alignment , Polarity , TimerType } ;
3533use crate :: rcc:: { GetBusFreq , Rcc } ;
3634use crate :: time:: Hertz ;
3735
@@ -152,41 +150,23 @@ pub enum InterleavedMode {
152150 Quad ,
153151}
154152
155- // HrPwmExt trait
156- /// Allows the pwm() method to be added to the peripheral register structs from the device crate
157- pub trait HrPwmExt : Sized {
158- /// The requested frequency will be rounded to the nearest achievable frequency; the actual frequency may be higher or lower than requested.
159- fn pwm < PINS , T , U , V > (
160- self ,
161- _pins : PINS ,
162- frequency : T ,
163- control : & mut HrPwmControl ,
164- rcc : & mut Rcc ,
165- ) -> PINS :: Channel
166- where
167- PINS : Pins < Self , U , V > + ToHrOut ,
168- T : Into < Hertz > ,
169- U : HrtimChannel < Pscl128 > ;
170- }
171-
172153pub trait HrPwmAdvExt : Sized {
173154 type PreloadSource ;
174155
175- fn pwm_advanced < PINS , CHANNEL , COMP > (
156+ fn pwm_advanced < PINS > (
176157 self ,
177158 _pins : PINS ,
178159 rcc : & mut Rcc ,
179- ) -> HrPwmBuilder < Self , Pscl128 , Self :: PreloadSource , PINS :: Out < Pscl128 > >
160+ ) -> HrPwmBuilder < Self , Pscl128 , Self :: PreloadSource , PINS >
180161 where
181- PINS : Pins < Self , CHANNEL , COMP > + ToHrOut ,
182- CHANNEL : HrtimChannel < Pscl128 > ;
162+ PINS : ToHrOut < Self > ;
183163}
184164
185165/// HrPwmBuilder is used to configure advanced HrTim PWM features
186- pub struct HrPwmBuilder < TIM , PSCL , PS , OUT > {
166+ pub struct HrPwmBuilder < TIM , PSCL , PS , PINS > {
187167 _tim : PhantomData < TIM > ,
188168 _prescaler : PhantomData < PSCL > ,
189- _out : PhantomData < OUT > ,
169+ pins : PINS ,
190170 timer_mode : HrTimerMode ,
191171 counting_direction : HrCountingDirection ,
192172 base_freq : HertzU64 ,
@@ -368,6 +348,9 @@ macro_rules! hrtim_finalize_body {
368348 //let master = unsafe { &*HRTIM_MASTER::ptr() };
369349 //master.mcr.modify(|_r, w| { w.$tXcen().set_bit() });
370350
351+ // Connect pins and let HRTIM take over control over them
352+ $this. pins. connect_to_hrtim( ) ;
353+
371354 unsafe {
372355 MaybeUninit :: uninit( ) . assume_init( )
373356 }
@@ -421,17 +404,14 @@ macro_rules! hrtim_common_methods {
421404 }
422405
423406 /// Set the prescaler; PWM count runs at base_frequency/(prescaler+1)
424- pub fn prescaler<P >(
425- self ,
426- _prescaler: P ,
427- ) -> HrPwmBuilder <$TIMX, P , $PS, <OUT as ToHrOut >:: Out <P >>
407+ pub fn prescaler<P >( self , _prescaler: P ) -> HrPwmBuilder <$TIMX, P , $PS, PINS >
428408 where
429409 P : HrtimPrescaler ,
430410 {
431411 let HrPwmBuilder {
432412 _tim,
433413 _prescaler: _,
434- _out ,
414+ pins ,
435415 timer_mode,
436416 fault_enable_bits,
437417 fault1_bits,
@@ -460,7 +440,7 @@ macro_rules! hrtim_common_methods {
460440 HrPwmBuilder {
461441 _tim,
462442 _prescaler: PhantomData ,
463- _out : PhantomData ,
443+ pins ,
464444 timer_mode,
465445 fault_enable_bits,
466446 fault1_bits,
@@ -521,38 +501,16 @@ macro_rules! hrtim_hal {
521501 ( $( $TIMX: ident: ( $timXcr: ident, $timXcr2: ident, $perXr: ident, $tXcen: ident, $rep: ident, $repx: ident, $dier: ident, $repie: ident,
522502 $fltXr: ident, $eefXr1: ident, $eefXr2: ident, $Xeefr3: ident, $outXr: ident, $dtXr: ident) , ) +) => {
523503 $(
524-
525- // Implement HrPwmExt trait for hrtimer
526- impl HrPwmExt for $TIMX {
527- fn pwm<PINS , T , U , V >(
528- self ,
529- pins: PINS ,
530- frequency: T ,
531- control: & mut HrPwmControl ,
532- rcc: & mut Rcc ,
533- ) -> PINS :: Channel
534- where
535- PINS : Pins <Self , U , V > + ToHrOut ,
536- T : Into <Hertz >,
537- U : HrtimChannel <Pscl128 >,
538- {
539- let _= self . pwm_advanced( pins, rcc) . frequency( frequency) . finalize( control) ;
540-
541- unsafe { MaybeUninit :: <PINS :: Channel >:: uninit( ) . assume_init( ) }
542- }
543- }
544-
545504 impl HrPwmAdvExt for $TIMX {
546505 type PreloadSource = PreloadSource ;
547506
548- fn pwm_advanced<PINS , CHANNEL , COMP >(
507+ fn pwm_advanced<PINS >(
549508 self ,
550- _pins : PINS ,
509+ pins : PINS ,
551510 rcc: & mut Rcc ,
552- ) -> HrPwmBuilder <Self , Pscl128 , Self :: PreloadSource , PINS :: Out < Pscl128 > >
511+ ) -> HrPwmBuilder <Self , Pscl128 , Self :: PreloadSource , PINS >
553512 where
554- PINS : Pins <Self , CHANNEL , COMP > + ToHrOut ,
555- CHANNEL : HrtimChannel <Pscl128 >
513+ PINS : ToHrOut <$TIMX>,
556514 {
557515 // TODO: That 32x factor... Is that included below, or should we
558516 // do that? Also that will likely risk overflowing u32 since
@@ -562,7 +520,7 @@ macro_rules! hrtim_hal {
562520 HrPwmBuilder {
563521 _tim: PhantomData ,
564522 _prescaler: PhantomData ,
565- _out : PhantomData ,
523+ pins ,
566524 timer_mode: HrTimerMode :: Continuous ,
567525 fault_enable_bits: 0b000000 ,
568526 fault1_bits: 0b00 ,
@@ -583,11 +541,11 @@ macro_rules! hrtim_hal {
583541 }
584542 }
585543
586- impl <PSCL , OUT >
587- HrPwmBuilder <$TIMX, PSCL , PreloadSource , OUT >
544+ impl <PSCL , PINS >
545+ HrPwmBuilder <$TIMX, PSCL , PreloadSource , PINS >
588546 where
589547 PSCL : HrtimPrescaler ,
590- OUT : ToHrOut ,
548+ PINS : ToHrOut <$TIMX> ,
591549 {
592550 pub fn finalize( self , _control: & mut HrPwmControl ) -> (
593551 HrTim <$TIMX, PSCL ,
@@ -599,7 +557,7 @@ macro_rules! hrtim_hal {
599557 HrCr3 <$TIMX, PSCL >,
600558 HrCr4 <$TIMX, PSCL >
601559 ) ,
602- OUT ,
560+ PINS :: Out < PSCL > ,
603561 timer:: DmaChannel <$TIMX>,
604562 ) {
605563
@@ -702,14 +660,13 @@ macro_rules! hrtim_hal_master {
702660 impl HrPwmAdvExt for $TIMX {
703661 type PreloadSource = MasterPreloadSource ;
704662
705- fn pwm_advanced<PINS , CHANNEL , COMP >(
663+ fn pwm_advanced<PINS >(
706664 self ,
707- _pins : PINS ,
665+ pins : PINS ,
708666 rcc: & mut Rcc ,
709- ) -> HrPwmBuilder <Self , Pscl128 , Self :: PreloadSource , PINS :: Out < Pscl128 > >
667+ ) -> HrPwmBuilder <Self , Pscl128 , Self :: PreloadSource , PINS >
710668 where
711- PINS : Pins <Self , CHANNEL , COMP > + ToHrOut , // TODO: figure out
712- CHANNEL : HrtimChannel <Pscl128 >
669+ PINS : ToHrOut <$TIMX>,
713670 {
714671 // TODO: That 32x factor... Is that included below, or should we
715672 // do that? Also that will likely risk overflowing u32 since
@@ -719,7 +676,7 @@ macro_rules! hrtim_hal_master {
719676 HrPwmBuilder {
720677 _tim: PhantomData ,
721678 _prescaler: PhantomData ,
722- _out : PhantomData ,
679+ pins ,
723680 timer_mode: HrTimerMode :: Continuous ,
724681 fault_enable_bits: 0b000000 ,
725682 fault1_bits: 0b00 ,
@@ -740,11 +697,11 @@ macro_rules! hrtim_hal_master {
740697 }
741698 }
742699
743- impl <PSCL , OUT >
744- HrPwmBuilder <$TIMX, PSCL , MasterPreloadSource , OUT >
700+ impl <PSCL , PINS >
701+ HrPwmBuilder <$TIMX, PSCL , MasterPreloadSource , PINS >
745702 where
746703 PSCL : HrtimPrescaler ,
747- OUT : ToHrOut ,
704+ PINS : ToHrOut <$TIMX> ,
748705 {
749706 pub fn finalize( self , _control: & mut HrPwmControl ) -> (
750707 HrTim <$TIMX, PSCL ,
@@ -767,97 +724,6 @@ macro_rules! hrtim_hal_master {
767724 ) * }
768725}
769726
770- macro_rules! hrtim_pin_hal {
771- ( $( $TIMX: ident:
772- ( $CH: ident, $perXr: ident, $cmpXYr: ident, $cmpYx: ident, $cmpY: ident, $tXYoen: ident, $tXYodis: ident) , ) +
773- ) => {
774- $(
775- impl <PSCL , COMP , POL , NPOL > hal:: PwmPin for Pwm <$TIMX, $CH<PSCL >, COMP , POL , NPOL >
776- where Pwm <$TIMX, $CH<PSCL >, COMP , POL , NPOL >: PwmPinEnable {
777- type Duty = u16 ;
778-
779- // You may not access self in the following methods!
780- // See unsafe above
781-
782- fn disable( & mut self ) {
783- self . ccer_disable( ) ;
784- }
785-
786- fn enable( & mut self ) {
787- self . ccer_enable( ) ;
788- }
789-
790- fn get_duty( & self ) -> Self :: Duty {
791- let tim = unsafe { & * $TIMX:: ptr( ) } ;
792-
793- tim. $cmpXYr. read( ) . $cmpYx( ) . bits( )
794- }
795-
796- fn get_max_duty( & self ) -> Self :: Duty {
797- let tim = unsafe { & * $TIMX:: ptr( ) } ;
798-
799- let arr = tim. $perXr. read( ) . perx( ) . bits( ) ;
800-
801- // One PWM cycle is ARR+1 counts long
802- // Valid PWM duty cycles are 0 to ARR+1
803- // However, if ARR is 65535 on a 16-bit timer, we can't add 1
804- // In that case, 100% duty cycle is not possible, only 65535/65536
805- if arr == Self :: Duty :: MAX {
806- arr
807- }
808- else {
809- arr + 1
810- }
811- }
812-
813- /// Set duty cycle
814- ///
815- /// NOTE: Please observe limits(RM0440 "Period and compare registers min and max values"):
816- /// | Prescaler | Min duty | Max duty |
817- /// |-----------|----------|----------|
818- /// | 1 | 0x0060 | 0xFFDF |
819- /// | 2 | 0x0030 | 0xFFEF |
820- /// | 4 | 0x0018 | 0xFFF7 |
821- /// | 8 | 0x000C | 0xFFFB |
822- /// | 16 | 0x0006 | 0xFFFD |
823- /// | 32 | 0x0003 | 0xFFFD |
824- /// | 64 | 0x0003 | 0xFFFD |
825- /// | 128 | 0x0003 | 0xFFFD |
826- ///
827- /// Also, writing 0 as duty is only valid for CR1 and CR3 during a set of
828- /// specific conditions(see RM0440 "Null duty cycle exception case"):
829- /// – the output SET event is generated by the PERIOD event
830- /// – the output RESET if generated by the compare 1 (respectively compare 3) event
831- /// – the compare 1 (compare 3) event is active within the timer unit itself, and not used
832- /// for other timing units
833- fn set_duty( & mut self , duty: Self :: Duty ) {
834- let tim = unsafe { & * $TIMX:: ptr( ) } ;
835-
836- tim. $cmpXYr. write( |w| unsafe { w. $cmpYx( ) . bits( duty) } ) ;
837- }
838- }
839-
840- // Enable implementation for ComplementaryImpossible
841- impl <POL , NPOL , PSCL > PwmPinEnable for Pwm <$TIMX, $CH<PSCL >, ComplementaryImpossible , POL , NPOL > {
842- fn ccer_enable( & mut self ) {
843- // TODO: Should this part only be in Pwm::enable?
844- // Enable output Y on channel X
845- // This is a set-only register, no risk for data race
846- let common = unsafe { & * HRTIM_COMMON :: ptr( ) } ;
847- common. oenr. write( |w| { w. $tXYoen( ) . set_bit( ) } ) ;
848- }
849- fn ccer_disable( & mut self ) {
850- // TODO: Should this part only be in Pwm::disable
851- // Disable output Y on channel X
852- // This is a write only register, no risk for data race
853- let common = unsafe { & * HRTIM_COMMON :: ptr( ) } ;
854- common. odisr. write( |w| { w. $tXYodis( ) . set_bit( ) } ) ;
855- }
856- }
857- ) +
858- }
859- }
860-
861727hrtim_hal ! {
862728 HRTIM_TIMA : ( timacr, timacr2, perar, tacen, repar, repx, timadier, repie, fltar, eefar1, eefar2, aeefr3, outar, dtar) ,
863729 HRTIM_TIMB : ( timbcr, timbcr2, perbr, tbcen, repbr, repx, timbdier, repie, fltbr, eefbr1, eefbr2, beefr3, outbr, dtbr) ,
@@ -871,26 +737,6 @@ hrtim_hal_master! {
871737 HRTIM_MASTER : ( mcr, ck_psc, mper, mper, mrep, mcen, mdier, mrepie) ,
872738}
873739
874- hrtim_pin_hal ! {
875- HRTIM_TIMA : ( CH1 , perar, cmp1ar, cmp1x, cmp1, ta1oen, ta1odis) ,
876- HRTIM_TIMA : ( CH2 , perar, cmp3ar, cmp3x, cmp3, ta2oen, ta2odis) ,
877-
878- HRTIM_TIMB : ( CH1 , perbr, cmp1br, cmp1x, cmp1, tb1oen, tb1odis) ,
879- HRTIM_TIMB : ( CH2 , perbr, cmp3br, cmp3x, cmp3, tb2oen, tb2odis) ,
880-
881- HRTIM_TIMC : ( CH1 , percr, cmp1cr, cmp1x, cmp1, tc1oen, tc1odis) ,
882- HRTIM_TIMC : ( CH2 , percr, cmp3cr, cmp3x, cmp3, tc2oen, tc2odis) ,
883-
884- HRTIM_TIMD : ( CH1 , perdr, cmp1dr, cmp1x, cmp1, td1oen, td1odis) ,
885- HRTIM_TIMD : ( CH2 , perdr, cmp3dr, cmp3x, cmp3, td2oen, td2odis) ,
886-
887- HRTIM_TIME : ( CH1 , perer, cmp1er, cmp1x, cmp1, te1oen, te1odis) ,
888- HRTIM_TIME : ( CH2 , perer, cmp3er, cmp3x, cmp3, te2oen, te2odis) ,
889-
890- HRTIM_TIMF : ( CH1 , perfr, cmp1fr, cmp1x, cmp1, tf1oen, tf1odis) ,
891- HRTIM_TIMF : ( CH2 , perfr, cmp3fr, cmp3x, cmp3, tf2oen, tf2odis) ,
892- }
893-
894740/// # Safety
895741/// Only implement for valid prescalers with correct values
896742pub unsafe trait HrtimPrescaler : Default {
0 commit comments