Deduplicate SimplePwm's channel methods

This commit is contained in:
Grant Miller 2024-09-06 10:25:29 -05:00
parent 8ac758bdee
commit f7f062e0a3

View File

@ -51,7 +51,8 @@ channel_impl!(new_ch2, Ch2, Channel2Pin);
channel_impl!(new_ch3, Ch3, Channel3Pin); channel_impl!(new_ch3, Ch3, Channel3Pin);
channel_impl!(new_ch4, Ch4, Channel4Pin); channel_impl!(new_ch4, Ch4, Channel4Pin);
/// A single channel of a pwm, obtained from [`SimplePwm::split`]. /// A single channel of a pwm, obtained from [`SimplePwm::split`],
/// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc.
/// ///
/// It is not possible to change the pwm frequency because /// It is not possible to change the pwm frequency because
/// the frequency configuration is shared with all four channels. /// the frequency configuration is shared with all four channels.
@ -179,13 +180,52 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
this this
} }
fn channel(&self, channel: Channel) -> SimplePwmChannel<'_, T> { /// Get a single channel
///
/// If you need to use multiple channels, use [`Self::split`].
pub fn channel(&mut self, channel: Channel) -> SimplePwmChannel<'_, T> {
SimplePwmChannel { SimplePwmChannel {
timer: &self.inner, timer: &self.inner,
channel, channel,
} }
} }
/// Channel 1
///
/// This is just a convenience wrapper around [`Self::channel`].
///
/// If you need to use multiple channels, use [`Self::split`].
pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> {
self.channel(Channel::Ch1)
}
/// Channel 2
///
/// This is just a convenience wrapper around [`Self::channel`].
///
/// If you need to use multiple channels, use [`Self::split`].
pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> {
self.channel(Channel::Ch2)
}
/// Channel 3
///
/// This is just a convenience wrapper around [`Self::channel`].
///
/// If you need to use multiple channels, use [`Self::split`].
pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> {
self.channel(Channel::Ch3)
}
/// Channel 4
///
/// This is just a convenience wrapper around [`Self::channel`].
///
/// If you need to use multiple channels, use [`Self::split`].
pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> {
self.channel(Channel::Ch4)
}
/// Splits a [`SimplePwm`] into four pwm channels. /// Splits a [`SimplePwm`] into four pwm channels.
/// ///
/// This returns all four channels, including channels that /// This returns all four channels, including channels that
@ -193,29 +233,21 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
// TODO: I hate the name "split" // TODO: I hate the name "split"
pub fn split(&mut self) -> SimplePwmChannels<'_, T> { pub fn split(&mut self) -> SimplePwmChannels<'_, T> {
// TODO: pre-enable channels? // TODO: pre-enable channels?
// we can't use self.channel() because that takes &mut self
let ch = |channel| SimplePwmChannel {
timer: &self.inner,
channel,
};
SimplePwmChannels { SimplePwmChannels {
ch1: self.channel(Channel::Ch1), ch1: ch(Channel::Ch1),
ch2: self.channel(Channel::Ch2), ch2: ch(Channel::Ch2),
ch3: self.channel(Channel::Ch3), ch3: ch(Channel::Ch3),
ch4: self.channel(Channel::Ch4), ch4: ch(Channel::Ch4),
} }
} }
/// Enable the given channel.
pub fn enable(&mut self, channel: Channel) {
self.inner.enable_channel(channel, true);
}
/// Disable the given channel.
pub fn disable(&mut self, channel: Channel) {
self.inner.enable_channel(channel, false);
}
/// Check whether given channel is enabled
pub fn is_enabled(&self, channel: Channel) -> bool {
self.inner.get_channel_enable_state(channel)
}
/// Set PWM frequency. /// Set PWM frequency.
/// ///
/// Note: when you call this, the max duty value changes, so you will have to /// Note: when you call this, the max duty value changes, so you will have to
@ -236,31 +268,6 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
self.inner.get_max_compare_value() + 1 self.inner.get_max_compare_value() + 1
} }
/// Set the duty for a given channel.
///
/// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
pub fn set_duty(&mut self, channel: Channel, duty: u32) {
assert!(duty <= self.get_max_duty());
self.inner.set_compare_value(channel, duty)
}
/// Get the duty for a given channel.
///
/// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included.
pub fn get_duty(&self, channel: Channel) -> u32 {
self.inner.get_compare_value(channel)
}
/// Set the output polarity for a given channel.
pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) {
self.inner.set_output_polarity(channel, polarity);
}
/// Set the output compare mode for a given channel.
pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
self.inner.set_output_compare_mode(channel, mode);
}
/// Generate a sequence of PWM waveform /// Generate a sequence of PWM waveform
/// ///
/// Note: /// Note:
@ -276,8 +283,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
#[allow(clippy::let_unit_value)] // eg. stm32f334 #[allow(clippy::let_unit_value)] // eg. stm32f334
let req = dma.request(); let req = dma.request();
let original_duty_state = self.get_duty(channel); let original_duty_state = self.channel(channel).get_duty();
let original_enable_state = self.is_enabled(channel); let original_enable_state = self.channel(channel).is_enabled();
let original_update_dma_state = self.inner.get_update_dma_state(); let original_update_dma_state = self.inner.get_update_dma_state();
if !original_update_dma_state { if !original_update_dma_state {
@ -285,7 +292,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
} }
if !original_enable_state { if !original_enable_state {
self.enable(channel); self.channel(channel).enable();
} }
unsafe { unsafe {
@ -313,10 +320,10 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
// restore output compare state // restore output compare state
if !original_enable_state { if !original_enable_state {
self.disable(channel); self.channel(channel).disable();
} }
self.set_duty(channel, original_duty_state); self.channel(channel).set_duty(original_duty_state);
// Since DMA is closed before timer update event trigger DMA is turn off, // Since DMA is closed before timer update event trigger DMA is turn off,
// this can almost always trigger a DMA FIFO error. // this can almost always trigger a DMA FIFO error.
@ -346,8 +353,8 @@ macro_rules! impl_waveform_chx {
let cc_channel = Channel::$cc_ch; let cc_channel = Channel::$cc_ch;
let original_duty_state = self.get_duty(cc_channel); let original_duty_state = self.channel(cc_channel).get_duty();
let original_enable_state = self.is_enabled(cc_channel); let original_enable_state = self.channel(cc_channel).is_enabled();
let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ONUPDATE; let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ONUPDATE;
let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel);
@ -361,7 +368,7 @@ macro_rules! impl_waveform_chx {
} }
if !original_enable_state { if !original_enable_state {
self.enable(cc_channel); self.channel(cc_channel).enable();
} }
unsafe { unsafe {
@ -389,10 +396,10 @@ macro_rules! impl_waveform_chx {
// restore output compare state // restore output compare state
if !original_enable_state { if !original_enable_state {
self.disable(cc_channel); self.channel(cc_channel).disable();
} }
self.set_duty(cc_channel, original_duty_state); self.channel(cc_channel).set_duty(original_duty_state);
// Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off,
// this can almost always trigger a DMA FIFO error. // this can almost always trigger a DMA FIFO error.