From 354ff3bac31a910598a6e350499262b3163d50ef Mon Sep 17 00:00:00 2001 From: Vincenzo Marturano Date: Thu, 24 Oct 2024 19:46:23 +0200 Subject: [PATCH 1/3] Fix missing lifetime --- embassy-rp/src/pwm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 5fea0901a..2df2cfad3 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -347,7 +347,7 @@ impl<'d> Pwm<'d> { #[inline] /// Split Pwm driver to allow separate duty cycle control of each channel - pub fn split(self) -> (Option, Option) { + pub fn split(self) -> (Option>, Option>) { let pwm_output_a = if let Some(pin_a) = self.pin_a { Some(PwmOutput::new(PwmChannelPin::A(pin_a), self.slice.clone())) @@ -380,7 +380,7 @@ impl <'d> PwmOutput<'d> { } } -impl ErrorType for PwmOutput { +impl<'d> ErrorType for PwmOutput<'d> { type Error = PwmError; } From 874dbec5a4d11c57c3683a27ac09584e728694c2 Mon Sep 17 00:00:00 2001 From: Vincenzo Marturano Date: Thu, 24 Oct 2024 19:52:09 +0200 Subject: [PATCH 2/3] Fixed mistakes. --- embassy-rp/src/pwm.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 2df2cfad3..443308158 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -351,10 +351,14 @@ impl<'d> Pwm<'d> { let pwm_output_a = if let Some(pin_a) = self.pin_a { Some(PwmOutput::new(PwmChannelPin::A(pin_a), self.slice.clone())) + }else{ + None }; let pwm_output_b = if let Some(pin_b) = self.pin_b { Some(PwmOutput::new(PwmChannelPin::B(pin_b), self.slice.clone())) + }else { + None }; (pwm_output_a,pwm_output_b) @@ -397,12 +401,12 @@ impl<'d> SetDutyCycle for PwmOutput<'d> { let p = pac::PWM.ch(self.slice); match self.channel_pin { - PwmChannelPin::A => { + PwmChannelPin::A(_) => { p.cc().modify(|w| { w.set_a(duty); }); } - PwmChannelPin::B => { + PwmChannelPin::B(_) => { p.cc().modify(|w| { w.set_b(duty); }); From 71fe8a7b90abc7b625d0f5b822508b350f3444d2 Mon Sep 17 00:00:00 2001 From: Vincenzo Marturano Date: Fri, 25 Oct 2024 12:54:06 +0200 Subject: [PATCH 3/3] Fixed owned split and implemented split_by_ref. --- embassy-rp/src/pwm.rs | 80 ++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 443308158..18d476ed4 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -347,40 +347,80 @@ impl<'d> Pwm<'d> { #[inline] /// Split Pwm driver to allow separate duty cycle control of each channel - pub fn split(self) -> (Option>, Option>) { - - let pwm_output_a = if let Some(pin_a) = self.pin_a { - Some(PwmOutput::new(PwmChannelPin::A(pin_a), self.slice.clone())) - }else{ - None - }; - - let pwm_output_b = if let Some(pin_b) = self.pin_b { - Some(PwmOutput::new(PwmChannelPin::B(pin_b), self.slice.clone())) - }else { - None - }; - - (pwm_output_a,pwm_output_b) + pub fn split(mut self) -> (Option>, Option>) { + ( + 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)), + ) } + pub fn split_by_ref(&mut self) -> (Option>, Option>) { + ( + 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>) + 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> , + channel_pin: PwmChannelPin<'d>, slice: usize, + is_owned: bool, } -impl <'d> PwmOutput<'d> { - fn new(channel_pin: PwmChannelPin<'d>, slice: usize) -> Self { - Self { channel_pin ,slice } +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); + }); + } + } + } } }