-
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 55 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?
Uh oh!
There was an error while loading. Please reload this page.