mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 04:10:25 +00:00
Merge pull request #4522 from WattStep/complementary_pwm_idle_state
Add methods for idle-state control in STM32 Complementary PWM
This commit is contained in:
commit
e2921be35c
@ -2,7 +2,7 @@
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use stm32_metapac::timer::vals::Ckd;
|
||||
pub use stm32_metapac::timer::vals::{Ckd, Ossi, Ossr};
|
||||
|
||||
use super::low_level::{CountingMode, OutputPolarity, Timer};
|
||||
use super::simple_pwm::PwmPin;
|
||||
@ -43,6 +43,15 @@ pub struct ComplementaryPwm<'d, T: AdvancedInstance4Channel> {
|
||||
inner: Timer<'d, T>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
/// Determines which outputs are active when PWM is in idle mode
|
||||
pub enum IdlePolarity {
|
||||
/// Normal channels are forced active and complementary channels are forced inactive
|
||||
OisActive,
|
||||
/// Normal channels are forced inactive and complementary channels are forced active
|
||||
OisnActive,
|
||||
}
|
||||
|
||||
impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
|
||||
/// Create a new complementary PWM driver.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -82,6 +91,50 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
|
||||
this
|
||||
}
|
||||
|
||||
/// Sets the idle output state for the given channels.
|
||||
pub fn set_output_idle_state(&mut self, channels: &[Channel], polarity: IdlePolarity) {
|
||||
let ois_active = matches!(polarity, IdlePolarity::OisActive);
|
||||
for &channel in channels {
|
||||
self.inner.set_ois(channel, ois_active);
|
||||
self.inner.set_oisn(channel, !ois_active);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set state of OSSI-bit in BDTR register
|
||||
pub fn set_off_state_selection_idle(&mut self, val: Ossi) {
|
||||
self.inner.set_ossi(val);
|
||||
}
|
||||
|
||||
/// Get state of OSSI-bit in BDTR register
|
||||
pub fn get_off_state_selection_idle(&self) -> Ossi {
|
||||
self.inner.get_ossi()
|
||||
}
|
||||
|
||||
/// Set state of OSSR-bit in BDTR register
|
||||
pub fn set_off_state_selection_run(&mut self, val: Ossr) {
|
||||
self.inner.set_ossr(val);
|
||||
}
|
||||
|
||||
/// Get state of OSSR-bit in BDTR register
|
||||
pub fn get_off_state_selection_run(&self) -> Ossr {
|
||||
self.inner.get_ossr()
|
||||
}
|
||||
|
||||
/// Trigger break input from software
|
||||
pub fn trigger_software_break(&mut self, n: usize) {
|
||||
self.inner.trigger_software_break(n);
|
||||
}
|
||||
|
||||
/// Set Master Output Enable
|
||||
pub fn set_master_output_enable(&mut self, enable: bool) {
|
||||
self.inner.set_moe(enable);
|
||||
}
|
||||
|
||||
/// Get Master Output Enable
|
||||
pub fn get_master_output_enable(&self) -> bool {
|
||||
self.inner.get_moe()
|
||||
}
|
||||
|
||||
/// Enable the given channel.
|
||||
pub fn enable(&mut self, channel: Channel) {
|
||||
self.inner.enable_channel(channel, true);
|
||||
|
@ -686,10 +686,35 @@ impl<'d, T: AdvancedInstance1Channel> Timer<'d, T> {
|
||||
self.regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value));
|
||||
}
|
||||
|
||||
/// Set state of OSSI-bit in BDTR register
|
||||
pub fn set_ossi(&self, val: vals::Ossi) {
|
||||
self.regs_1ch_cmp().bdtr().modify(|w| w.set_ossi(val));
|
||||
}
|
||||
|
||||
/// Get state of OSSI-bit in BDTR register
|
||||
pub fn get_ossi(&self) -> vals::Ossi {
|
||||
self.regs_1ch_cmp().bdtr().read().ossi()
|
||||
}
|
||||
|
||||
/// Set state of OSSR-bit in BDTR register
|
||||
pub fn set_ossr(&self, val: vals::Ossr) {
|
||||
self.regs_1ch_cmp().bdtr().modify(|w| w.set_ossr(val));
|
||||
}
|
||||
|
||||
/// Get state of OSSR-bit in BDTR register
|
||||
pub fn get_ossr(&self) -> vals::Ossr {
|
||||
self.regs_1ch_cmp().bdtr().read().ossr()
|
||||
}
|
||||
|
||||
/// Set state of MOE-bit in BDTR register to en-/disable output
|
||||
pub fn set_moe(&self, enable: bool) {
|
||||
self.regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable));
|
||||
}
|
||||
|
||||
/// Get state of MOE-bit in BDTR register
|
||||
pub fn get_moe(&self) -> bool {
|
||||
self.regs_1ch_cmp().bdtr().read().moe()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stm32l0))]
|
||||
@ -725,4 +750,19 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> {
|
||||
.ccer()
|
||||
.modify(|w| w.set_ccne(channel.index(), enable));
|
||||
}
|
||||
|
||||
/// Set Output Idle State
|
||||
pub fn set_ois(&self, channel: Channel, val: bool) {
|
||||
self.regs_advanced().cr2().modify(|w| w.set_ois(channel.index(), val));
|
||||
}
|
||||
/// Set Output Idle State Complementary Channel
|
||||
pub fn set_oisn(&self, channel: Channel, val: bool) {
|
||||
self.regs_advanced().cr2().modify(|w| w.set_oisn(channel.index(), val));
|
||||
}
|
||||
|
||||
/// Trigger software break 1 or 2
|
||||
/// Setting this bit generates a break event. This bit is automatically cleared by the hardware.
|
||||
pub fn trigger_software_break(&self, n: usize) {
|
||||
self.regs_advanced().egr().write(|r| r.set_bg(n, true));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user