mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-24 15:52:34 +00:00
Merge pull request #3454 from vivi202/embassy-rpSplitPwm
Embassy-rp Split Pwm driver to allow separate duty cycle control of each channel.
This commit is contained in:
commit
6bcd05ac83
@ -344,6 +344,119 @@ impl<'d> Pwm<'d> {
|
|||||||
fn bit(&self) -> u32 {
|
fn bit(&self) -> u32 {
|
||||||
1 << self.slice as usize
|
1 << self.slice as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Splits the PWM driver into separate `PwmOutput` instances for channels A and B.
|
||||||
|
#[inline]
|
||||||
|
pub fn split(mut self) -> (Option<PwmOutput<'d>>, Option<PwmOutput<'d>>) {
|
||||||
|
(
|
||||||
|
self.pin_a
|
||||||
|
.take()
|
||||||
|
.map(|pin| PwmOutput::new(PwmChannelPin::A(pin), self.slice.clone(), true)),
|
||||||
|
self.pin_b
|
||||||
|
.take()
|
||||||
|
.map(|pin| PwmOutput::new(PwmChannelPin::B(pin), self.slice.clone(), true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/// Splits the PWM driver by reference to allow for separate duty cycle control
|
||||||
|
/// of each channel (A and B) without taking ownership of the PWM instance.
|
||||||
|
#[inline]
|
||||||
|
pub fn split_by_ref(&mut self) -> (Option<PwmOutput<'_>>, Option<PwmOutput<'_>>) {
|
||||||
|
(
|
||||||
|
self.pin_a
|
||||||
|
.as_mut()
|
||||||
|
.map(|pin| PwmOutput::new(PwmChannelPin::A(pin.reborrow()), self.slice.clone(), false)),
|
||||||
|
self.pin_b
|
||||||
|
.as_mut()
|
||||||
|
.map(|pin| PwmOutput::new(PwmChannelPin::B(pin.reborrow()), self.slice.clone(), false)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PwmChannelPin<'d> {
|
||||||
|
A(PeripheralRef<'d, AnyPin>),
|
||||||
|
B(PeripheralRef<'d, AnyPin>),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Single channel of Pwm driver.
|
||||||
|
pub struct PwmOutput<'d> {
|
||||||
|
//pin that can be ether ChannelAPin or ChannelBPin
|
||||||
|
channel_pin: PwmChannelPin<'d>,
|
||||||
|
slice: usize,
|
||||||
|
is_owned: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> PwmOutput<'d> {
|
||||||
|
fn new(channel_pin: PwmChannelPin<'d>, slice: usize, is_owned: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
channel_pin,
|
||||||
|
slice,
|
||||||
|
is_owned,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for PwmOutput<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.is_owned {
|
||||||
|
let p = pac::PWM.ch(self.slice);
|
||||||
|
match &self.channel_pin {
|
||||||
|
PwmChannelPin::A(pin) => {
|
||||||
|
p.cc().modify(|w| {
|
||||||
|
w.set_a(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
pin.gpio().ctrl().write(|w| w.set_funcsel(31));
|
||||||
|
//Enable pin PULL-DOWN
|
||||||
|
pin.pad_ctrl().modify(|w| {
|
||||||
|
w.set_pde(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
PwmChannelPin::B(pin) => {
|
||||||
|
p.cc().modify(|w| {
|
||||||
|
w.set_b(0);
|
||||||
|
});
|
||||||
|
pin.gpio().ctrl().write(|w| w.set_funcsel(31));
|
||||||
|
//Enable pin PULL-DOWN
|
||||||
|
pin.pad_ctrl().modify(|w| {
|
||||||
|
w.set_pde(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> ErrorType for PwmOutput<'d> {
|
||||||
|
type Error = PwmError;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d> SetDutyCycle for PwmOutput<'d> {
|
||||||
|
fn max_duty_cycle(&self) -> u16 {
|
||||||
|
pac::PWM.ch(self.slice).top().read().top()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
|
||||||
|
let max_duty = self.max_duty_cycle();
|
||||||
|
if duty > max_duty {
|
||||||
|
return Err(PwmError::InvalidDutyCycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = pac::PWM.ch(self.slice);
|
||||||
|
match self.channel_pin {
|
||||||
|
PwmChannelPin::A(_) => {
|
||||||
|
p.cc().modify(|w| {
|
||||||
|
w.set_a(duty);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
PwmChannelPin::B(_) => {
|
||||||
|
p.cc().modify(|w| {
|
||||||
|
w.set_b(duty);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Batch representation of PWM slices.
|
/// Batch representation of PWM slices.
|
||||||
|
Loading…
Reference in New Issue
Block a user