diff --git a/examples/mcpwm-deadtime.rs b/examples/mcpwm-deadtime.rs new file mode 100644 index 00000000000..fd40145497c --- /dev/null +++ b/examples/mcpwm-deadtime.rs @@ -0,0 +1,106 @@ +// TODO: Update those graphs with measured results + +/// # x = 10 +/// +/// . . +/// . . +/// .------. .------. +/// | | | | +/// pin4 | | | | +/// | | | | +/// ----- -------------------------- -------------------------- +/// . . +/// . . +/// .------------------------. .------------------------. +/// | | | | +/// pin5 | | | | +/// | | | | +/// ----- -------- -------- +/// . . +/// +/// +/// # x = 50 +/// . . +/// . . +/// .---------------. .---------------. +/// | | | | +/// pin4 | | | | +/// | | | | +/// ----- ----------------- ----------------- +/// . . +/// . . +/// .---------------. .---------------. +/// | | | | +/// pin5 | | | | +/// | | | | +/// ----- ----------------- ----------------- +/// . . +/// +/// +/// # x = 90 +/// . . +/// . . +/// .------------------------. .------------------------. +/// | | | | +/// pin4 | | | | +/// | | | | +/// ----- -------- -------- +/// . . +/// . . +/// .------. .------. +/// | | | | +/// pin5 | | | | +/// | | | | +/// ----- -------------------------- -------------------------- +/// . . + +#[cfg(any(esp32, esp32s3))] +fn main() -> anyhow::Result<()> { + use embedded_hal::delay::blocking::DelayUs; + + use esp_idf_hal::delay::FreeRtos; + use esp_idf_hal::mcpwm::{DeadtimeConfig, Mcpwm, Operator, OperatorConfig}; + use esp_idf_hal::prelude::Peripherals; + use esp_idf_hal::units::FromValueType; + + esp_idf_sys::link_patches(); + + println!("Configuring MCPWM"); + + let peripherals = Peripherals::take().unwrap(); + let config = OperatorConfig::default().frequency(1.kHz()).deadtime( + DeadtimeConfig::ActiveHighComplement { + rising_edge_delay: 1500, // 1500*100ns=150us or 15% of the period + falling_edge_delay: 3000, // 3000*100ns=300us or 30% of the period + }, + ); + let mcpwm = Mcpwm::new(peripherals.mcpwm0.mcpwm)?; + let mut operator = Operator::new( + peripherals.mcpwm0.operator0, + &mcpwm, + &config, + peripherals.pins.gpio4, + peripherals.pins.gpio5, + )?; + + println!("Starting duty-cycle loop"); + + for x in (0..10000u16).cycle() { + let duty = f32::from(x) * 0.01; + + if x % 100 == 0 { + println!("Duty {}%", duty); + } + + operator.set_duty_a(duty)?; + operator.set_duty_b(0.0)?; + FreeRtos.delay_ms(10)?; + } + + unreachable!() +} + +#[cfg(not(any(esp32, esp32s3)))] +fn main() { + esp_idf_sys::link_patches(); +} diff --git a/examples/mcpwm-simple.rs b/examples/mcpwm-simple.rs index 31a50eaa775..91057fc47a8 100644 --- a/examples/mcpwm-simple.rs +++ b/examples/mcpwm-simple.rs @@ -61,7 +61,7 @@ fn main() -> anyhow::Result<()> { use embedded_hal::delay::blocking::DelayUs; use esp_idf_hal::delay::FreeRtos; - use esp_idf_hal::mcpwm::{Timer, TimerConfig, Operator, OperatorConfig}; + use esp_idf_hal::mcpwm::{Operator, OperatorConfig, Timer, TimerConfig}; use esp_idf_hal::prelude::Peripherals; use esp_idf_hal::units::FromValueType; @@ -74,13 +74,12 @@ fn main() -> anyhow::Result<()> { let operator_config = OperatorConfig::default(); let timer = Timer::new(peripherals.mcpwm0.timer0, timer_config); - let mut timer = timer.into_connection() - .attatch_operator0( - peripherals.mcpwm0.operator0, - operator_config, - peripherals.pins.gpio4, - peripherals.pins.gpio5, - ); + let mut timer = timer.into_connection().attatch_operator0( + peripherals.mcpwm0.operator0, + operator_config, + peripherals.pins.gpio4, + peripherals.pins.gpio5, + ); let (timer, operator, _, _) = timer.split(); diff --git a/src/mcpwm/mod.rs b/src/mcpwm/mod.rs index 7a61e7e1680..fd59c47eb58 100644 --- a/src/mcpwm/mod.rs +++ b/src/mcpwm/mod.rs @@ -28,7 +28,7 @@ //! let timer_config = TimerConfig::default().frequency(25.kHz()); //! let operator_config = OperatorConfig::default(); //! let timer = Mcpwm::new(peripherals.mcpwm0.timer, timer_config)?; -//! +//! //! let timer = timer.into_connection() //! .attatch_operator0( //! peripherals.mcpwm0.operator0, @@ -36,7 +36,7 @@ //! peripherals.pins.gpio4, //! peripherals.pins.gpio5, //! )?; -//! +//! //! let (timer, operator, _, _) = timer.split(); //! //! println!("Starting duty-cycle loop"); @@ -51,26 +51,16 @@ //! //! See the `examples/` folder of this repository for more. -mod timer; mod operator; +mod timer; mod timer_connection; use core::ffi; pub use self::{ - operator::{ - OPERATOR, - Operator, - OperatorConfig, - }, - timer::{ - TIMER, - Timer, - TimerConfig - }, - timer_connection::{ - TimerConnection - } + operator::{Operator, OperatorConfig, OPERATOR}, + timer::{Timer, TimerConfig, TIMER}, + timer_connection::TimerConnection, }; // MCPWM clock source frequency for ESP32 and ESP32-s3 @@ -128,4 +118,4 @@ impl Group for Group0 { impl Group for Group1 { const ID: ffi::c_int = 1; -} \ No newline at end of file +} diff --git a/src/mcpwm/operator.rs b/src/mcpwm/operator.rs index 02ffdf517ab..5be42613b5b 100644 --- a/src/mcpwm/operator.rs +++ b/src/mcpwm/operator.rs @@ -67,7 +67,7 @@ where } /// Set duty as in the range 0 to timers peak value - /// + /// /// NOTE: The compare value shouldn’t exceed timer’s count peak, otherwise, the compare event will never got triggered. pub fn set_duty_a(&mut self, duty: Duty) -> Result<(), EspError> { todo!() diff --git a/src/mcpwm/timer.rs b/src/mcpwm/timer.rs index 736046bda55..e978a7835f5 100644 --- a/src/mcpwm/timer.rs +++ b/src/mcpwm/timer.rs @@ -70,12 +70,12 @@ pub struct Timer { handle: mcpwm_timer_handle_t, _timer: TIMER, /// Number of ticks within a period - /// + /// /// See `Self::get_period_ticks` for more info period_ticks: u32, /// This is the maximum value that the comparator will see - /// + /// /// See `Self::get_period_peak` for more info period_peak: u16, } @@ -111,15 +111,15 @@ impl Timer { handle, _timer: timer, period_ticks: cfg.period_ticks, - period_peak + period_peak, } } // TODO: make sure this description is accurate /// Get number of ticks per period - /// + /// /// Use this when working with the frequency or the period - /// + /// /// NOTE: This will be the same as `Self::get_period_peak` for all `CounterMode` except for /// `CounterMode::UpDown` where the period will be twice as large as the peak value since /// the timer will count from zero to peak and then down to zero again @@ -129,9 +129,9 @@ impl Timer { // TODO: make sure this description is accurate /// This is the maximum value that the comparator will see - /// + /// /// Use this working with the duty - /// + /// /// NOTE: This will not be the same as `Self::get_period_ticks` when using `CounterMode::UpDown` /// See `Self::get_period_ticks` for more info pub fn get_period_peak(&self) -> u16 { diff --git a/src/mcpwm/timer_connection.rs b/src/mcpwm/timer_connection.rs index b10e0dc9ed3..d1576116c19 100644 --- a/src/mcpwm/timer_connection.rs +++ b/src/mcpwm/timer_connection.rs @@ -1,10 +1,9 @@ use crate::mcpwm::Group; use super::{ - operator::{ - NoOperator, OperatorConfig, OptionalOperator, OPERATOR, - }, - timer::{Timer, TIMER}, Operator, + operator::{NoOperator, OperatorConfig, OptionalOperator, OPERATOR}, + timer::{Timer, TIMER}, + Operator, }; // TODO: How do we want fault module to fit into this? @@ -37,8 +36,13 @@ impl TimerConnection, O1: OptionalOperator<1, G>, O2: OptionalOperator<2, G>> - TimerConnection +impl< + const N: u8, + G: Group, + O0: OptionalOperator<0, G>, + O1: OptionalOperator<1, G>, + O2: OptionalOperator<2, G>, + > TimerConnection { pub fn split(&mut self) -> (&mut Timer, &mut O0, &mut O1, &mut O2) { ( @@ -50,7 +54,9 @@ impl, O1: OptionalOperator<1, } } // TODO: Do something more builder-pattern like for making the operator? -impl, O2: OptionalOperator<2, G>> TimerConnection { +impl, O2: OptionalOperator<2, G>> + TimerConnection +{ pub fn attatch_operator0( self, operator_handle: OPERATOR<0, G>, @@ -58,7 +64,7 @@ impl, O2: OptionalOperator<2, pin_a: PA, pin_b: PB, ) -> TimerConnection, O1, O2> { - let operator = todo!();//self.init_and_attach_operator(operator_cfg, pin_a, pin_b); + let operator = todo!(); //self.init_and_attach_operator(operator_cfg, pin_a, pin_b); TimerConnection { timer: self.timer, operator0: operator, @@ -68,7 +74,9 @@ impl, O2: OptionalOperator<2, } } -impl, O2: OptionalOperator<2, G>> TimerConnection { +impl, O2: OptionalOperator<2, G>> + TimerConnection +{ pub fn attatch_operator1( self, operator_handle: OPERATOR<1, G>, @@ -76,7 +84,7 @@ impl, O2: OptionalOperator<2, pin_a: PA, pin_b: PB, ) -> TimerConnection, O2> { - let operator = todo!();//self.init_and_attach_operator(operator_cfg, pin_a, pin_b); + let operator = todo!(); //self.init_and_attach_operator(operator_cfg, pin_a, pin_b); TimerConnection { timer: self.timer, operator0: self.operator0, @@ -86,7 +94,9 @@ impl, O2: OptionalOperator<2, } } -impl, O1: OptionalOperator<1, G>> TimerConnection { +impl, O1: OptionalOperator<1, G>> + TimerConnection +{ pub fn attatch_operator2( self, operator_handle: OPERATOR<2, G>, @@ -94,7 +104,7 @@ impl, O1: OptionalOperator<1, pin_a: PA, pin_b: PB, ) -> TimerConnection> { - let operator = todo!();//self.init_and_attach_operator(operator_cfg, pin_a, pin_b); + let operator = todo!(); //self.init_and_attach_operator(operator_cfg, pin_a, pin_b); TimerConnection { timer: self.timer, operator0: self.operator0, @@ -108,4 +118,4 @@ pub struct NoPin; pub trait OptionalOutputPin {} -impl OptionalOutputPin for P {} \ No newline at end of file +impl OptionalOutputPin for P {} diff --git a/src/peripherals.rs b/src/peripherals.rs index c0c0ee9fed0..8717258d754 100644 --- a/src/peripherals.rs +++ b/src/peripherals.rs @@ -57,9 +57,9 @@ pub struct Peripherals { #[cfg(not(feature = "riscv-ulp-hal"))] pub ledc: ledc::LEDC, #[cfg(all(any(esp32, esp32s3), not(feature = "riscv-ulp-hal")))] - pub mcpwm0: mcpwm::MCPWM::, + pub mcpwm0: mcpwm::MCPWM, #[cfg(all(any(esp32, esp32s3), not(feature = "riscv-ulp-hal")))] - pub mcpwm1: mcpwm::MCPWM::, + pub mcpwm1: mcpwm::MCPWM, #[cfg(not(feature = "riscv-ulp-hal"))] pub rmt: rmt::RMT, #[cfg(all(