- 
                Notifications
    
You must be signed in to change notification settings  - Fork 201
 
MCPWM 5.0 #132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
MCPWM 5.0 #132
Changes from 56 commits
e47f8af
              5a86430
              bef1ea4
              208bde0
              ad91ea1
              4e3b09c
              8a1b0fd
              17a3e63
              a428ed6
              8f2f559
              d64529a
              729cb85
              15610a2
              cc8589d
              8ca34ba
              4ed2696
              490a84a
              c874e78
              9ebbeee
              d05ae44
              f5a13ca
              6bc129a
              1d779db
              8384b06
              5f01835
              5acf5fc
              a10f4f3
              12e34db
              0caf311
              451dcd9
              952a36f
              9ec6458
              ca5685e
              dc05884
              d932af4
              8d80760
              1907eef
              bb8d957
              e7e755e
              d20ae62
              7b2a929
              6e8d31e
              d3e44c1
              c15c69f
              f053be1
              326299f
              44cd1d8
              5c4738b
              7ab9357
              aa19703
              55745e6
              1c3dae4
              8bca808
              7063f05
              1bd2dfd
              d786f05
              4acbca7
              6913374
              cc76cb5
              bdcb5e4
              316f685
              66d0dde
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| /// Simple example showing how MCPWM may be used to generate two synchronized pwm signals with varying duty. | ||
| /// The duty on the pin4 will increase from 0% all the way up to 100% and repeat. At the same time the duty | ||
| /// on pin 5 will go from 100% down to 0% | ||
| /// | ||
| /// # duty = 10% | ||
| /// | ||
| /// . . | ||
| /// . . | ||
| /// .------. .------. | ||
| /// | | | | | ||
| /// pin4 | | | | | ||
| /// | | | | | ||
| /// ----- -------------------------- -------------------------- | ||
| /// . . | ||
| /// . . | ||
| /// .------------------------. .------------------------. | ||
| /// | | | | | ||
| /// pin5 | | | | | ||
| /// | | | | | ||
| /// ----- -------- -------- | ||
| /// . . | ||
| /// | ||
| /// | ||
| /// # duty = 50% | ||
| /// . . | ||
| /// . . | ||
| /// .---------------. .---------------. | ||
| /// | | | | | ||
| /// pin4 | | | | | ||
| /// | | | | | ||
| /// ----- ----------------- ----------------- | ||
| /// . . | ||
| /// . . | ||
| /// .---------------. .---------------. | ||
| /// | | | | | ||
| /// pin5 | | | | | ||
| /// | | | | | ||
| /// ----- ----------------- ----------------- | ||
| /// . . | ||
| /// | ||
| /// | ||
| /// # duty = 90% | ||
| /// . . | ||
| /// . . | ||
| /// .------------------------. .------------------------. | ||
| /// | | | | | ||
| /// pin4 | | | | | ||
| /// | | | | | ||
| /// ----- -------- -------- | ||
| /// . . | ||
| /// . . | ||
| /// .------. .------. | ||
| /// | | | | | ||
| /// pin5 | | | | | ||
| /// | | | | | ||
| /// ----- -------------------------- -------------------------- | ||
| /// . . | ||
| 
     | 
||
| #[cfg(all(any(esp32, esp32s3), esp_idf_version_major = "5"))] | ||
| fn main() -> anyhow::Result<()> { | ||
| use embedded_hal::delay::DelayUs; | ||
| 
     | 
||
| use esp_idf_hal::delay::FreeRtos; | ||
| use esp_idf_hal::mcpwm::{OperatorConfig, Timer, TimerConfig}; | ||
| use esp_idf_hal::prelude::Peripherals; | ||
| 
     | 
||
| esp_idf_sys::link_patches(); | ||
| 
     | 
||
| println!("Configuring MCPWM"); | ||
| 
     | 
||
| let peripherals = Peripherals::take().unwrap(); | ||
| let timer_config = TimerConfig::default().period_ticks(8_000); // 10kHz | ||
| let operator_config = OperatorConfig::default(peripherals.pins.gpio4, peripherals.pins.gpio5); | ||
| let timer = Timer::new(peripherals.mcpwm0.timer0, timer_config); | ||
| 
     | 
||
| let mut timer = timer | ||
| .into_connection() | ||
| .attatch_operator0(peripherals.mcpwm0.operator0, operator_config); | ||
| 
     | 
||
| // Borrow references to the contained timer and operator | ||
| let (timer, operator, _, _) = timer.split(); | ||
| 
     | 
||
| println!("Starting duty-cycle loop"); | ||
| 
     | 
||
| let period_ticks = timer.get_period_peak(); | ||
| 
     | 
||
| // TODO: Will this work as expected in UP_DOWN counter mode? | ||
| for duty in (0..period_ticks).step_by(10).cycle() { | ||
| if duty % 100 == 0 { | ||
| println!( | ||
| "cmp: {}, duty {}%", | ||
| duty, | ||
| 100 * u32::from(duty) / u32::from(period_ticks) | ||
| ); | ||
| } | ||
| 
     | 
||
| operator.set_compare_value_x(duty)?; // In this configuration this controls the duty on pin4 | ||
| operator.set_compare_value_y(period_ticks - duty)?; // and this controls pin5 | ||
| FreeRtos.delay_ms(10)?; | ||
| } | ||
| 
     | 
||
| unreachable!() | ||
| } | ||
| 
     | 
||
| #[cfg(not(all(any(esp32, esp32s3), esp_idf_version_major = "5")))] | ||
| fn main() { | ||
| esp_idf_sys::link_patches(); | ||
| 
     | 
||
| println!("Sorry MCPWM is only supported on ESP32 and ESP32-S3"); | ||
| } | 
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,127 @@ | ||||||||||
| use core::ptr; | ||||||||||
| 
     | 
||||||||||
| use esp_idf_sys::{ | ||||||||||
| esp, mcpwm_cmpr_handle_t, mcpwm_comparator_config_t, mcpwm_comparator_config_t__bindgen_ty_1, | ||||||||||
| mcpwm_gen_compare_event_action_t, mcpwm_gen_handle_t, mcpwm_gen_t, mcpwm_new_comparator, | ||||||||||
| mcpwm_oper_handle_t, mcpwm_timer_direction_t_MCPWM_TIMER_DIRECTION_DOWN, | ||||||||||
| mcpwm_timer_direction_t_MCPWM_TIMER_DIRECTION_UP, | ||||||||||
| }; | ||||||||||
| 
     | 
||||||||||
| use super::generator::{CountingDirection, NoCmpMatchConfig, OnMatchCfg}; | ||||||||||
| 
     | 
||||||||||
| trait ComparatorChannel {} | ||||||||||
| 
     | 
||||||||||
| pub struct CmpX; | ||||||||||
| impl ComparatorChannel for CmpX {} | ||||||||||
| 
     | 
||||||||||
| pub struct CmpY; | ||||||||||
| impl ComparatorChannel for CmpY {} | ||||||||||
| 
     | 
||||||||||
| pub trait OptionalCmp { | ||||||||||
                
       | 
||||||||||
| impl<const N: u8, G, GENA, GENB, CMPY> Operator<N, G, Comparator, CMPY, GENA, GENB> | 
I personally do not quite like a method doing that check at runtime. I will hower change it if you would.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not have time the time to check right now but I believe, if I am not mistaken, there was also something similar when building the generator config. The generator config should not depend on events from comparators that are not provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, perhaps both comparators should be obligatory since they can not be used for anything else outside their operator anyways...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just remembered espressif/esp-idf#9904 . Do you think tep should also be set to 1 to avoid that? I have not tested this PR for that problem yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| flags.set_update_cmp_on_tep(0); | |
| flags.set_update_cmp_on_tez(1); | |
| flags.set_update_cmp_on_tep(1); | |
| flags.set_update_cmp_on_tez(1); | 
        
          
              
                Outdated
          
        
      There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here. Why are we hiding simple Options behind traits with just two implementations: none and an actual one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation uses lot's of traits which results in a heavy utilization of generics, making the code difficult to comprehend and probably difficult to use.
I don't mind generics and traits, if they cannot be avoided, but I'm questioning the utility of almost all traits in this module. Most of them can be replaced with alternatives: enums or simple options.
I'll comment on each trait below.
For
ComparatorChannelspecifically: why not just