@@ -119,10 +119,10 @@ impl From<CounterMode> for mcpwm_counter_type_t {
119119 }
120120}
121121
122- // TODO: Note that `red` and `fed` from the IDF's perspecitve is time as in number of clock cycles after the
123- // MCPWM modules group prescaler. How do we want to expose this? Do we expose it as just that, a cycle count?
124- // Or do we expose it as a time which we then calculate the cycle count from?
125- /// Deadtime config for MCPWM operator
122+ /// Dead time config for MCPWM operator
123+ ///
124+ /// `red` and `fed` is time as in number of clock cycles after the MCPWM modules group prescaler.
125+ ///
126126/// Note that the dead times are calculated from MCPWMXA's flanks unless explicitly stated otherwise
127127#[ derive( Copy , Clone , PartialEq , Debug ) ]
128128pub enum DeadtimeConfig {
@@ -232,10 +232,7 @@ pub enum DeadtimeConfig {
232232 /// . . . .
233233 ActiveLow { red : u16 , fed : u16 } ,
234234
235- // TODO: Is this actually true? --------
236- // |
237- // v
238- /// MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE - The most common deadtime mode
235+ /// MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE
239236 ///
240237 /// . . . .
241238 /// . . . .
@@ -467,21 +464,23 @@ pub struct Mcpwm<U: Unit> {
467464 /// Those timers in turn have their own prescalers to scale this down even further
468465 ///
469466 /// NOTE: This is only to be set by calling Self::lowest_frequency
470- operator_input_frequency : u32 ,
467+ operator_source_frequency : u32 ,
471468 _instance : MCPWM < U > ,
472469}
473470
474471impl < U : Unit > Mcpwm < U > {
475472 pub fn new ( instance : MCPWM < U > ) -> Result < Self , EspError > {
476473 let res = Self {
477474 #[ cfg( not( esp_idf_version = "4.3" ) ) ]
478- operator_input_frequency : 0 ,
475+ operator_source_frequency : 0 ,
479476 _instance : instance,
480477 } ;
481478
482479 #[ cfg( not( esp_idf_version = "4.3" ) ) ]
483480 {
484- res. lowest_frequency ( 15 . Hz ( ) )
481+ // TODO: Do we want to make this into something more builder-pattern like to
482+ // avoid this potentially redundant function call?
483+ res. operator_source_frequency ( 10 . MHz ( ) )
485484 }
486485
487486 #[ cfg( esp_idf_version = "4.3" ) ]
@@ -490,26 +489,53 @@ impl<U: Unit> Mcpwm<U> {
490489 }
491490 }
492491
492+ pub fn release ( self ) -> MCPWM < U > {
493+ // TODO: Do we need to reset any state here such as group_prescaler?
494+ self . _instance
495+ }
496+
493497 /// Specify lowest reachable frequency
494498 ///
495499 /// The lower this is set, the lower frequencies will be reachable. However, this is at the cost of worse
496500 /// resolution at higher frequencies.
497- ///
501+ ///
498502 /// Same thing goes for the other way. The higher value set here, the more resolution and so on.
499503 #[ cfg( not( esp_idf_version = "4.3" ) ) ]
500504 pub fn lowest_frequency ( mut self , lowest_frequency : Hertz ) -> Result < Self , EspError > {
501505 // TODO: Do we care about frequency < 1Hz?
502- let operator_input_frequency =
506+ let operator_source_frequency =
503507 MAX_PWM_TIMER_PRESCALE * MAX_PWM_TIMER_PERIOD * u32:: from ( lowest_frequency) ;
504- let group_pre_scale = MCPWM_CLOCK_SOURCE_FREQUENCY / operator_input_frequency ;
508+ let group_pre_scale = MCPWM_CLOCK_SOURCE_FREQUENCY / operator_source_frequency ;
505509 if !( 1 ..=256 ) . contains ( & group_pre_scale) {
506510 return Err ( EspError :: from ( ESP_ERR_INVALID_ARG ) . unwrap ( ) ) ;
507511 }
508512
509- let resolution =
510- MAX_PWM_TIMER_PRESCALE * MAX_PWM_TIMER_PERIOD * u32:: from ( lowest_frequency) ;
511- esp ! ( unsafe { mcpwm_group_set_resolution( U :: unit( ) , resolution) } ) ?;
512- self . operator_input_frequency = operator_input_frequency;
513+ esp ! ( unsafe { mcpwm_group_set_resolution( U :: unit( ) , operator_source_frequency) } ) ?;
514+ self . operator_source_frequency = operator_source_frequency;
515+
516+ Ok ( self )
517+ }
518+
519+ /// Specify frequency passed to operators timers as clock source
520+ ///
521+ /// The timers of the operators can then in turn scale this frequency down further.
522+ ///
523+ /// The lower this is set, the lower frequencies will be reachable. However, this is
524+ /// at the cost of worse resolution at higher frequencies. Same thing goes for the
525+ /// other way. The higher value set here, the more resolution and so on.
526+ #[ cfg( not( esp_idf_version = "4.3" ) ) ]
527+ pub fn operator_source_frequency ( mut self , frequency : impl Into < Hertz > ) -> Result < Self , EspError > {
528+ let frequency: Hertz = frequency. into ( ) ;
529+ let frequency: u32 = frequency. into ( ) ;
530+
531+ // TODO: Do we care about frequency < 1Hz?
532+ let group_pre_scale = MCPWM_CLOCK_SOURCE_FREQUENCY / frequency;
533+ if !( 1 ..=256 ) . contains ( & group_pre_scale) {
534+ return Err ( EspError :: from ( ESP_ERR_INVALID_ARG ) . unwrap ( ) ) ;
535+ }
536+
537+ esp ! ( unsafe { mcpwm_group_set_resolution( U :: unit( ) , frequency) } ) ?;
538+ self . operator_source_frequency = frequency;
513539
514540 Ok ( self )
515541 }
@@ -584,7 +610,7 @@ impl_operator!(
584610) ;
585611
586612// TODO: How do we want syncing to fit in to this?
587- // TODO: How do we want deadtime to fit into this?
613+ // TODO: How do we want dead time to fit into this?
588614// TODO: How do we want carrier to fit into this?
589615// TODO: How do we want capture to fit into this?
590616
@@ -597,8 +623,13 @@ pub struct Operator<U: Unit, O: HwOperator<U>, M: Borrow<Mcpwm<U>>, PA: OutputPi
597623 _pin_b : Option < PB > ,
598624}
599625
600- impl < U : Unit , O : HwOperator < U > , M : Borrow < Mcpwm < U > > , PA : OutputPin , PB : OutputPin >
601- Operator < U , O , M , PA , PB >
626+ impl < U , O , M , PA , PB > Operator < U , O , M , PA , PB >
627+ where
628+ U : Unit ,
629+ O : HwOperator < U > ,
630+ M : Borrow < Mcpwm < U > > ,
631+ PA : OutputPin ,
632+ PB : OutputPin ,
602633{
603634 pub fn new < A : Into < Option < PA > > , B : Into < Option < PB > > > (
604635 operator : O ,
@@ -616,7 +647,7 @@ impl<U: Unit, O: HwOperator<U>, M: Borrow<Mcpwm<U>>, PA: OutputPin, PB: OutputPi
616647 return Err ( EspError :: from ( ESP_ERR_INVALID_ARG ) . unwrap ( ) ) ;
617648 }
618649
619- if config. lowest_frequency > mcpwm_module. borrow ( ) . operator_input_frequency . Hz ( ) {
650+ if config. lowest_frequency > mcpwm_module. borrow ( ) . operator_source_frequency . Hz ( ) {
620651 // Can not specify a lowest_frequency larger than the corresponding value for
621652 // the parent MCPWM module. Use `Mcpwm::lowest_frequency` to enable higher frequencies
622653 return Err ( EspError :: from ( ESP_ERR_INVALID_ARG ) . unwrap ( ) ) ;
@@ -680,6 +711,31 @@ impl<U: Unit, O: HwOperator<U>, M: Borrow<Mcpwm<U>>, PA: OutputPin, PB: OutputPi
680711 } )
681712 }
682713
714+ pub fn release ( self ) -> ( O , Option < PA > , Option < PB > ) {
715+ // mcpwm_stop will only fail when invalid args are given
716+ esp ! ( unsafe { mcpwm_stop( U :: unit( ) , O :: timer( ) ) } ) . unwrap ( ) ;
717+
718+ // TODO: Test and verify if this is the right way
719+ if self . _pin_a . is_some ( ) {
720+ // TODO: How to unset pin?
721+ // let io_signal = O::signal_a();
722+ // mcpwm_gpio_init(U::unit(), io_signal, -1)
723+ // does not seem to be it...
724+ todo ! ( ) ;
725+ }
726+
727+ if self . _pin_b . is_some ( ) {
728+ // TODO: How to unset pin?
729+ // let io_signal = O::signal_b();
730+ // mcpwm_gpio_init(U::unit(), io_signal, -1)
731+ // does not seem to be it...
732+
733+ todo ! ( ) ;
734+ }
735+ // TODO: Do we need to reset any more state here such as dead time config?
736+ ( self . _instance , self . _pin_a , self . _pin_b )
737+ }
738+
683739 /// Get duty as percentage between 0.0 and 100.0
684740 pub fn get_duty_a ( & self ) -> Duty {
685741 unsafe {
0 commit comments