diff --git a/src/mcpwm/comparator.rs b/src/mcpwm/comparator.rs index 2649cf322da..5495da0a066 100644 --- a/src/mcpwm/comparator.rs +++ b/src/mcpwm/comparator.rs @@ -75,9 +75,10 @@ pub struct ComparatorConfig { impl Default for ComparatorConfig { fn default() -> Self { let mut flags: mcpwm_comparator_config_t__bindgen_ty_1 = Default::default(); - flags.set_update_cmp_on_tep(todo!()); - flags.set_update_cmp_on_tez(todo!()); - flags.set_update_cmp_on_sync(todo!()); + // TODO: What should be set here? + flags.set_update_cmp_on_tep(1); + flags.set_update_cmp_on_tez(1); + flags.set_update_cmp_on_sync(1); Self { flags } } } diff --git a/src/mcpwm/generator.rs b/src/mcpwm/generator.rs index 67ac485bd91..7890fcc9deb 100644 --- a/src/mcpwm/generator.rs +++ b/src/mcpwm/generator.rs @@ -8,7 +8,7 @@ use esp_idf_sys::{ mcpwm_generator_set_actions_on_timer_event, mcpwm_new_generator, mcpwm_oper_handle_t, mcpwm_timer_direction_t_MCPWM_TIMER_DIRECTION_DOWN, mcpwm_timer_direction_t_MCPWM_TIMER_DIRECTION_UP, mcpwm_timer_event_t_MCPWM_TIMER_EVENT_EMPTY, - mcpwm_timer_event_t_MCPWM_TIMER_EVENT_FULL, + mcpwm_timer_event_t_MCPWM_TIMER_EVENT_FULL, mcpwm_generator_config_t__bindgen_ty_1, }; use crate::gpio::OutputPin; @@ -24,11 +24,11 @@ impl OptionalGen for NoGen { pub trait OptionalGen { } -impl OptionalGen for Generator +impl OptionalGen for Generator where G: GeneratorChannel, - CMP_X: OnMatchCfg, - CMP_Y: OnMatchCfg, + CMPX: OnMatchCfg, + CMPY: OnMatchCfg, P: OutputPin, { } @@ -48,19 +48,19 @@ impl GeneratorChannel for GenB { } // TODO: Allow OptionalOutputPin? -pub struct Generator { +pub struct Generator { channel: PhantomData, - cmp_x: PhantomData, - cmp_y: PhantomData, - pub(crate) handle: mcpwm_gen_handle_t, - pub(crate) pin: P, + cmp_x: PhantomData, + cmp_y: PhantomData, + pub(crate) _handle: mcpwm_gen_handle_t, + pub(crate) _pin: P, } -pub struct GeneratorConfig { +pub struct GeneratorConfig { _channel: PhantomData, - pub(crate) invert: bool, - pub(crate) on_matches_cmp_x: CMP_X, - pub(crate) on_matches_cmp_y: CMP_Y, + pub(crate) flags: mcpwm_generator_config_t__bindgen_ty_1, + pub(crate) on_matches_cmp_x: CMPX, + pub(crate) on_matches_cmp_y: CMPY, pub(crate) on_is_empty: CountingDirection, pub(crate) on_is_full: CountingDirection, pub(crate) pin: P, @@ -93,10 +93,10 @@ impl OptionalGenCfg for NoGenCfg { } } -impl OptionalGenCfg - for GeneratorConfig +impl OptionalGenCfg + for GeneratorConfig { - type Gen = Generator; + type Gen = Generator; unsafe fn init( self, @@ -106,7 +106,7 @@ impl Op ) -> Self::Gen { let cfg = mcpwm_generator_config_t { gen_gpio_num: self.pin.pin(), - flags: todo!(), //generator_config.flags, + flags: self.flags, }; let mut gen = ptr::null_mut(); unsafe { @@ -163,8 +163,8 @@ impl Op channel: PhantomData, cmp_x: PhantomData, cmp_y: PhantomData, - handle: gen, - pin: self.pin, + _handle: gen, + _pin: self.pin, } } } @@ -176,14 +176,14 @@ pub trait GenInit { unsafe fn init(self, operator_handle: mcpwm_oper_handle_t) -> Self::Gen; } -impl GenInit for (&mut CMP_X, &mut CMP_Y, NoGenCfg) +impl GenInit for (&mut CMPX, &mut CMPY, NoGenCfg) where - CMP_X: OptionalCmp, - CMP_Y: OptionalCmp, + CMPX: OptionalCmp, + CMPY: OptionalCmp, { type Gen = NoGen; - unsafe fn init(self, operator_handle: mcpwm_oper_handle_t) -> Self::Gen { + unsafe fn init(self, _operator_handle: mcpwm_oper_handle_t) -> Self::Gen { NoGen } } @@ -214,16 +214,20 @@ impl GeneratorConfig GeneratorConfig +impl GeneratorConfig where G: GeneratorChannel, - CMP_X: OnMatchCfg, - CMP_Y: OnMatchCfg, + CMPX: OnMatchCfg, + CMPY: OnMatchCfg, { fn empty(pin: P) -> Self { + let mut flags: mcpwm_generator_config_t__bindgen_ty_1 = Default::default(); + flags.set_invert_pwm(0); + flags.set_io_loop_back(0); + GeneratorConfig { _channel: PhantomData, - invert: false, + flags, on_matches_cmp_x: OnMatchCfg::empty(), on_matches_cmp_y: OnMatchCfg::empty(), on_is_empty: CountingDirection { diff --git a/src/mcpwm/operator.rs b/src/mcpwm/operator.rs index 2da02f8594f..99e47a1908c 100644 --- a/src/mcpwm/operator.rs +++ b/src/mcpwm/operator.rs @@ -1,19 +1,14 @@ use esp_idf_sys::{ - esp, mcpwm_comparator_config_t, mcpwm_comparator_config_t__bindgen_ty_1, - mcpwm_comparator_set_compare_value, mcpwm_gen_timer_event_action_t, mcpwm_generator_config_t, - mcpwm_generator_config_t__bindgen_ty_1, mcpwm_generator_set_actions_on_compare_event, - mcpwm_generator_set_actions_on_timer_event, mcpwm_new_comparator, mcpwm_new_generator, - mcpwm_oper_handle_t, mcpwm_operator_config_t, mcpwm_operator_config_t__bindgen_ty_1, - mcpwm_operator_connect_timer, mcpwm_timer_direction_t_MCPWM_TIMER_DIRECTION_DOWN, - mcpwm_timer_direction_t_MCPWM_TIMER_DIRECTION_UP, mcpwm_timer_event_t_MCPWM_TIMER_EVENT_EMPTY, - mcpwm_timer_event_t_MCPWM_TIMER_EVENT_FULL, mcpwm_timer_handle_t, EspError, + esp, mcpwm_comparator_set_compare_value, mcpwm_oper_handle_t, mcpwm_operator_config_t, + mcpwm_operator_config_t__bindgen_ty_1, mcpwm_operator_connect_timer, mcpwm_timer_handle_t, + EspError, }; use crate::mcpwm::Group; use super::{ - comparator::{Comparator, ComparatorConfig, NoCmp, OptionalCmp, OptionalCmpCfg}, - generator::{GenA, GenB, GenInit, NoGen, OptionalGen, OptionalGenCfg}, + comparator::{Comparator, OptionalCmp, OptionalCmpCfg}, + generator::{OptionalGen, OptionalGenCfg}, OperatorConfig, }; @@ -61,45 +56,46 @@ impl crate::peripheral::Peripheral for OPERATOR { pub struct Operator< const N: u8, G: Group, - CMP_X: OptionalCmp, - CMP_Y: OptionalCmp, - GEN_A: OptionalGen, - GEN_B: OptionalGen, + CMPX: OptionalCmp, + CMPY: OptionalCmp, + GENA: OptionalGen, + GENB: OptionalGen, > { _instance: OPERATOR, _handle: mcpwm_oper_handle_t, - comparator_x: CMP_X, // SOC_MCPWM_COMPARATORS_PER_OPERATOR is 2 for ESP32 and ESP32-S3 - comparator_y: CMP_Y, + comparator_x: CMPX, // SOC_MCPWM_COMPARATORS_PER_OPERATOR is 2 for ESP32 and ESP32-S3 + comparator_y: CMPY, - _generator_a: GEN_A, // One generator per pin, with a maximum of two generators per Operator - _generator_b: GEN_B, + _generator_a: GENA, // One generator per pin, with a maximum of two generators per Operator + _generator_b: GENB, //deadtime: D } -pub unsafe fn new( +pub unsafe fn new( instance: OPERATOR, timer_handle: mcpwm_timer_handle_t, - cfg: OperatorConfig, -) -> Operator + cfg: OperatorConfig, +) -> Operator where G: Group, - CMP_X: OptionalCmpCfg, - CMP_Y: OptionalCmpCfg, + CMPX: OptionalCmpCfg, + CMPY: OptionalCmpCfg, - GEN_A: OptionalGenCfg, - GEN_B: OptionalGenCfg, + GENA: OptionalGenCfg, + GENB: OptionalGenCfg, { let mut handle = ptr::null_mut(); let mut flags: mcpwm_operator_config_t__bindgen_ty_1 = Default::default(); - flags.set_update_gen_action_on_tez(todo!()); - flags.set_update_gen_action_on_tep(todo!()); - flags.set_update_gen_action_on_sync(todo!()); + // TODO: What should these be set to? + flags.set_update_gen_action_on_tez(1); + flags.set_update_gen_action_on_tep(1); + flags.set_update_gen_action_on_sync(1); - flags.set_update_dead_time_on_tez(todo!()); - flags.set_update_dead_time_on_tep(todo!()); - flags.set_update_dead_time_on_sync(todo!()); + flags.set_update_dead_time_on_tez(1); + flags.set_update_dead_time_on_tep(1); + flags.set_update_dead_time_on_sync(1); let config = mcpwm_operator_config_t { group_id: G::ID, @@ -110,8 +106,8 @@ where esp!(esp_idf_sys::mcpwm_new_operator(&config, &mut handle,)).unwrap(); } - let comparator_x = unsafe { cfg.comparator_x.init(handle) }; - let comparator_y = unsafe { cfg.comparator_y.init(handle) }; + let mut comparator_x = unsafe { cfg.comparator_x.init(handle) }; + let mut comparator_y = unsafe { cfg.comparator_y.init(handle) }; let generator_a = unsafe { cfg.generator_a.init( @@ -144,38 +140,12 @@ where } } -impl Operator { - fn cmp_x(self, config: ComparatorConfig) -> Operator { - let mut flags: mcpwm_comparator_config_t__bindgen_ty_1 = Default::default(); - flags.set_update_cmp_on_tep(todo!()); - flags.set_update_cmp_on_tez(todo!()); - flags.set_update_cmp_on_sync(todo!()); - - let cfg = mcpwm_comparator_config_t { flags }; - let mut cmp = ptr::null_mut(); - unsafe { - esp!(mcpwm_new_comparator(self._handle, &cfg, &mut cmp)).unwrap(); - } - let comparator_x = Comparator(cmp); - - Operator { - _instance: self._instance, - _handle: self._handle, - comparator_x, - comparator_y: self.comparator_y, - - _generator_a: self._generator_a, - _generator_b: self._generator_b, - } - } -} - -impl Operator +impl Operator where G: Group, - CMP_Y: OptionalCmp, - GEN_A: OptionalGen, - GEN_B: OptionalGen, + CMPY: OptionalCmp, + GENA: OptionalGen, + GENB: OptionalGen, { // TODO: Note that this is the comparator we are affecting, not the generator. Generator A may not necessarily have // anything to do with comparator A. How do we best convay that? Should we call them Generator X/Y and Comparator A/B? @@ -213,12 +183,12 @@ where } } -impl Operator +impl Operator where G: Group, - CMP_X: OptionalCmp, - GEN_A: OptionalGen, - GEN_B: OptionalGen, + CMPX: OptionalCmp, + GENA: OptionalGen, + GENB: OptionalGen, { /// Get compare value, often times same as the duty for output B. /// @@ -247,14 +217,14 @@ where } pub trait OptionalOperator {} -impl OptionalOperator - for Operator +impl OptionalOperator + for Operator where G: Group, - CMP_X: OptionalCmp, - CMP_Y: OptionalCmp, - GEN_A: OptionalGen, - GEN_B: OptionalGen, + CMPX: OptionalCmp, + CMPY: OptionalCmp, + GENA: OptionalGen, + GENB: OptionalGen, { } diff --git a/src/mcpwm/operator_config.rs b/src/mcpwm/operator_config.rs index fb2aedc8c93..5836af9c987 100644 --- a/src/mcpwm/operator_config.rs +++ b/src/mcpwm/operator_config.rs @@ -1,33 +1,31 @@ -use core::ptr; -use esp_idf_sys::{esp, mcpwm_operator_config_t__bindgen_ty_1}; +use esp_idf_sys::mcpwm_operator_config_t__bindgen_ty_1; use crate::gpio::OutputPin; use super::{ comparator::{ComparatorConfig, NoCmpCfg, OptionalCmpCfg}, generator::{GenA, GenB, GeneratorConfig, NoGenCfg, OptionalGenCfg, CountingDirection}, - OPERATOR, }; #[derive(Default)] -pub struct OperatorConfig { +pub struct OperatorConfig { // TODO: When, how and who should set the flags? // Should that be done automagically, manually or does some specific setting cover all cases? /// Flags for Operator pub(crate) flags: mcpwm_operator_config_t__bindgen_ty_1, /// Configuration for Comparator X - pub(crate) comparator_x: CMP_X, + pub(crate) comparator_x: CMPX, /// Configuration for Comparator Y - pub(crate) comparator_y: CMP_Y, + pub(crate) comparator_y: CMPY, /// Configuration for Generator A - pub(crate) generator_a: GEN_A, + pub(crate) generator_a: GENA, /// Configuration for Generator B - pub(crate) generator_b: GEN_B, + pub(crate) generator_b: GENB, } impl OperatorConfig { @@ -70,14 +68,14 @@ impl OperatorConfig { } } -impl OperatorConfig +impl OperatorConfig where - CMP_X: OptionalCmpCfg, - CMP_Y: OptionalCmpCfg, - GEN_A: OptionalGenCfg, - GEN_B: OptionalGenCfg, + CMPX: OptionalCmpCfg, + CMPY: OptionalCmpCfg, + GENA: OptionalGenCfg, + GENB: OptionalGenCfg, { - fn set_update_dead_time_on_tez(mut self, update_dead_time_on_tez: bool) -> Self { + /*fn set_update_dead_time_on_tez(mut self, update_dead_time_on_tez: bool) -> Self { self.flags .set_update_dead_time_on_tez(update_dead_time_on_tez.into()); self @@ -111,14 +109,14 @@ where self.flags .set_update_gen_action_on_sync(update_gen_action_on_sync.into()); self - } + }*/ } -impl OperatorConfig { +impl OperatorConfig { fn cmp_x( self, config: ComparatorConfig, - ) -> OperatorConfig { + ) -> OperatorConfig { /* let mut flags: mcpwm_comparator_config_t__bindgen_ty_1 = Default::default(); flags.set_update_cmp_on_tep(todo!()); @@ -144,11 +142,11 @@ impl OperatorConfig } } -impl OperatorConfig { +impl OperatorConfig { fn cmp_y( self, config: ComparatorConfig, - ) -> OperatorConfig { + ) -> OperatorConfig { /*let mut flags: mcpwm_comparator_config_t__bindgen_ty_1 = Default::default(); flags.set_update_cmp_on_tep(todo!()); flags.set_update_cmp_on_tez(todo!()); @@ -177,17 +175,17 @@ impl OperatorConfig // TODO: Is there any point in letting the user provide the comparators or should two (the only two available // for that operator in hardware) be automatically assigned in `Operator::new`? -impl - OperatorConfig +impl + OperatorConfig { fn gen_a( - mut self, - config: GeneratorConfig, + self, + config: GeneratorConfig, ) -> OperatorConfig< - CMP_X, - CMP_Y, - GeneratorConfig, - GEN_B, + CMPX, + CMPY, + GeneratorConfig, + GENB, > { OperatorConfig { flags: self.flags, @@ -200,17 +198,17 @@ impl } } -impl - OperatorConfig +impl + OperatorConfig { fn gen_b( - mut self, - config: GeneratorConfig, + self, + config: GeneratorConfig, ) -> OperatorConfig< - CMP_X, - CMP_Y, - GEN_A, - GeneratorConfig, + CMPX, + CMPY, + GENA, + GeneratorConfig, > { OperatorConfig { flags: self.flags, diff --git a/src/mcpwm/timer.rs b/src/mcpwm/timer.rs index c22e8d976d4..7a2197f5524 100644 --- a/src/mcpwm/timer.rs +++ b/src/mcpwm/timer.rs @@ -4,7 +4,7 @@ use std::ptr; use esp_idf_sys::{ esp, mcpwm_del_timer, mcpwm_new_timer, mcpwm_timer_config_t, mcpwm_timer_enable, - mcpwm_timer_handle_t, + mcpwm_timer_handle_t, mcpwm_timer_config_t__bindgen_ty_1, mcpwm_timer_sync_src_config_t__bindgen_ty_1, soc_periph_mcpwm_timer_clk_src_t_MCPWM_TIMER_CLK_SRC_DEFAULT, mcpwm_timer_count_mode_t_MCPWM_TIMER_COUNT_MODE_UP, }; use crate::mcpwm::Group; @@ -82,13 +82,19 @@ pub struct Timer { impl Timer { pub fn new(timer: TIMER, config: TimerConfig) -> Self { + let mut flags: mcpwm_timer_config_t__bindgen_ty_1 = Default::default(); + + // TODO: What should these be set to? + flags.set_update_period_on_empty(1); + flags.set_update_period_on_sync(0); + let cfg = mcpwm_timer_config_t { - group_id: todo!(), - clk_src: todo!(), - resolution_hz: todo!(), - count_mode: todo!(), - period_ticks: todo!(), - flags: todo!(), + group_id: G::ID, + clk_src: soc_periph_mcpwm_timer_clk_src_t_MCPWM_TIMER_CLK_SRC_DEFAULT, + resolution_hz: 160_000_000, // 160MHz + count_mode: mcpwm_timer_count_mode_t_MCPWM_TIMER_COUNT_MODE_UP, + period_ticks: 16_000, // 10kHz + flags, }; let mut handle: mcpwm_timer_handle_t = ptr::null_mut(); unsafe { @@ -163,6 +169,8 @@ impl Timer { } } +// TODO: Should this be done in TimerConnection instead to ensure everything is taken down +// in the correct order? impl Drop for Timer { fn drop(&mut self) { unsafe { diff --git a/src/mcpwm/timer_connection.rs b/src/mcpwm/timer_connection.rs index d5790c560a8..43a9065c8ac 100644 --- a/src/mcpwm/timer_connection.rs +++ b/src/mcpwm/timer_connection.rs @@ -1,9 +1,9 @@ use crate::mcpwm::Group; use super::{ - comparator::{OptionalCmp, OptionalCmpCfg}, - generator::{OptionalGen, GenA, GenB, GenInit, OptionalGenCfg}, - operator::{NoOperator, OptionalOperator, OPERATOR, self}, + comparator::OptionalCmpCfg, + generator::OptionalGenCfg, + operator::{self, NoOperator, OptionalOperator, OPERATOR}, timer::Timer, Operator, OperatorConfig, }; @@ -62,24 +62,18 @@ where O1: OptionalOperator<1, G>, O2: OptionalOperator<2, G>, { - pub fn attatch_operator0( + pub fn attatch_operator0( self, operator_handle: OPERATOR<0, G>, - operator_cfg: OperatorConfig< - CMP_X, - CMP_Y, - GEN_A, - GEN_B, - >, - ) -> TimerConnection, O1, O2> - where// TODO: Any ideas on how to simplify this mess? - CMP_X: OptionalCmpCfg, - CMP_Y: OptionalCmpCfg, - GEN_A: OptionalGenCfg, - GEN_B: OptionalGenCfg, + operator_cfg: OperatorConfig, + ) -> TimerConnection, O1, O2> + where + CMPX: OptionalCmpCfg, + CMPY: OptionalCmpCfg, + GENA: OptionalGenCfg, + GENB: OptionalGenCfg, { - let operator = - unsafe { operator::new(operator_handle, self.timer.timer(), operator_cfg) }; + let operator = unsafe { operator::new(operator_handle, self.timer.timer(), operator_cfg) }; TimerConnection { timer: self.timer, operator0: operator, @@ -95,22 +89,18 @@ where O0: OptionalOperator<0, G>, O2: OptionalOperator<2, G>, { - pub fn attatch_operator1( + pub fn attatch_operator1( self, operator_handle: OPERATOR<1, G>, - operator_cfg: OperatorConfig, - pin_a: PA, - pin_b: PB, - ) -> TimerConnection, O2> + operator_cfg: OperatorConfig, + ) -> TimerConnection, O2> where - CMP_X: OptionalCmp, - CMP_Y: OptionalCmp, - GEN_A: OptionalGen, - GEN_B: OptionalGen, - PA: OptionalOutputPin, - PB: OptionalOutputPin, + CMPX: OptionalCmpCfg, + CMPY: OptionalCmpCfg, + GENA: OptionalGenCfg, + GENB: OptionalGenCfg, { - let operator = todo!(); //self.init_and_attach_operator(operator_cfg, pin_a, pin_b); + let operator = unsafe { operator::new(operator_handle, self.timer.timer(), operator_cfg) }; TimerConnection { timer: self.timer, operator0: self.operator0, @@ -126,22 +116,18 @@ where O0: OptionalOperator<0, G>, O1: OptionalOperator<1, G>, { - pub fn attatch_operator2( + pub fn attatch_operator2( self, operator_handle: OPERATOR<2, G>, - operator_cfg: OperatorConfig, - pin_a: PA, - pin_b: PB, - ) -> TimerConnection> + operator_cfg: OperatorConfig, + ) -> TimerConnection> where - CMP_X: OptionalCmp, - CMP_Y: OptionalCmp, - GEN_A: OptionalGen, - GEN_B: OptionalGen, - PA: OptionalOutputPin, - PB: OptionalOutputPin, + CMPX: OptionalCmpCfg, + CMPY: OptionalCmpCfg, + GENA: OptionalGenCfg, + GENB: OptionalGenCfg, { - let operator = todo!(); //self.init_and_attach_operator(operator_cfg, pin_a, pin_b); + let operator = unsafe { operator::new(operator_handle, self.timer.timer(), operator_cfg) }; TimerConnection { timer: self.timer, operator0: self.operator0, @@ -151,8 +137,20 @@ where } } -// TODO: Should this be moved somewhere else? -pub struct NoPin; +/* +// TODO: Adding this prevents moving values out of the type as is done in attatch_operator() +// how do we make this work? +impl Drop for TimerConnection + where G: Group, + O0: OptionalOperator<0, G>, + O1: OptionalOperator<1, G>, + O2: OptionalOperator<2, G>, +{ + fn drop(&mut self) { + todo!() + } +} +*/ // TODO: Should this be moved somewhere else? pub trait OptionalOutputPin {}