Merge pull request #1798 from aurelj/stm32_pwm_polarity

stm32: allow setting the PWM output polarity
This commit is contained in:
Dario Nieuwenhuis 2023-08-18 14:51:48 +00:00 committed by GitHub
commit 97da34595c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 0 deletions

View file

@ -108,6 +108,11 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> {
self.inner.set_compare_value(channel, duty) self.inner.set_compare_value(channel, duty)
} }
pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
self.inner.set_output_polarity(channel, polarity);
self.inner.set_complementary_output_polarity(channel, polarity);
}
/// Set the dead time as a proportion of max_duty /// Set the dead time as a proportion of max_duty
pub fn set_dead_time(&mut self, value: u16) { pub fn set_dead_time(&mut self, value: u16) {
let (ckd, value) = compute_dead_time_value(value); let (ckd, value) = compute_dead_time_value(value);

View file

@ -53,6 +53,8 @@ pub(crate) mod sealed {
fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity);
fn enable_channel(&mut self, channel: Channel, enable: bool); fn enable_channel(&mut self, channel: Channel, enable: bool);
fn set_compare_value(&mut self, channel: Channel, value: u16); fn set_compare_value(&mut self, channel: Channel, value: u16);
@ -61,6 +63,8 @@ pub(crate) mod sealed {
} }
pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance { pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance {
fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity);
fn set_dead_time_clock_division(&mut self, value: vals::Ckd); fn set_dead_time_clock_division(&mut self, value: vals::Ckd);
fn set_dead_time_value(&mut self, value: u8); fn set_dead_time_value(&mut self, value: u8);
@ -71,6 +75,8 @@ pub(crate) mod sealed {
pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance { pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance {
fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity);
fn enable_channel(&mut self, channel: Channel, enable: bool); fn enable_channel(&mut self, channel: Channel, enable: bool);
fn set_compare_value(&mut self, channel: Channel, value: u32); fn set_compare_value(&mut self, channel: Channel, value: u32);
@ -125,6 +131,21 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
} }
} }
#[derive(Clone, Copy)]
pub enum OutputPolarity {
ActiveHigh,
ActiveLow,
}
impl From<OutputPolarity> for bool {
fn from(mode: OutputPolarity) -> Self {
match mode {
OutputPolarity::ActiveHigh => false,
OutputPolarity::ActiveLow => true,
}
}
}
pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {}
pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {}
@ -265,6 +286,13 @@ macro_rules! impl_compare_capable_16bit {
.modify(|w| w.set_ocm(raw_channel % 2, mode.into())); .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
} }
fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
use sealed::GeneralPurpose16bitInstance;
Self::regs_gp16()
.ccer()
.modify(|w| w.set_ccp(channel.raw(), polarity.into()));
}
fn enable_channel(&mut self, channel: Channel, enable: bool) { fn enable_channel(&mut self, channel: Channel, enable: bool) {
use sealed::GeneralPurpose16bitInstance; use sealed::GeneralPurpose16bitInstance;
Self::regs_gp16() Self::regs_gp16()
@ -325,6 +353,13 @@ foreach_interrupt! {
Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into())); Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
} }
fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
use crate::timer::sealed::GeneralPurpose32bitInstance;
Self::regs_gp32()
.ccer()
.modify(|w| w.set_ccp(channel.raw(), polarity.into()));
}
fn enable_channel(&mut self, channel: Channel, enable: bool) { fn enable_channel(&mut self, channel: Channel, enable: bool) {
use crate::timer::sealed::GeneralPurpose32bitInstance; use crate::timer::sealed::GeneralPurpose32bitInstance;
Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable)); Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable));
@ -388,6 +423,13 @@ foreach_interrupt! {
.modify(|w| w.set_ocm(raw_channel % 2, mode.into())); .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
} }
fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
use crate::timer::sealed::AdvancedControlInstance;
Self::regs_advanced()
.ccer()
.modify(|w| w.set_ccp(channel.raw(), polarity.into()));
}
fn enable_channel(&mut self, channel: Channel, enable: bool) { fn enable_channel(&mut self, channel: Channel, enable: bool) {
use crate::timer::sealed::AdvancedControlInstance; use crate::timer::sealed::AdvancedControlInstance;
Self::regs_advanced() Self::regs_advanced()
@ -409,6 +451,13 @@ foreach_interrupt! {
} }
impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst { impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {
fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
use crate::timer::sealed::AdvancedControlInstance;
Self::regs_advanced()
.ccer()
.modify(|w| w.set_ccnp(channel.raw(), polarity.into()));
}
fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { fn set_dead_time_clock_division(&mut self, value: vals::Ckd) {
use crate::timer::sealed::AdvancedControlInstance; use crate::timer::sealed::AdvancedControlInstance;
Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); Self::regs_advanced().cr1().modify(|w| w.set_ckd(value));

View file

@ -104,4 +104,8 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
assert!(duty <= self.get_max_duty()); assert!(duty <= self.get_max_duty());
self.inner.set_compare_value(channel, duty) self.inner.set_compare_value(channel, duty)
} }
pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
self.inner.set_output_polarity(channel, polarity);
}
} }