aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincenzo Marturano <[email protected]>2024-10-25 12:57:10 +0200
committerGitHub <[email protected]>2024-10-25 12:57:10 +0200
commit7d9d2f8459bfe08f16254c3154d8c6e483e429f5 (patch)
treef382ec95a9a5e45e28f42b9dace3cdc807a8765b
parent336ef01b05e87e6b2b3c9b98e9bdca0c7d78a6af (diff)
parent71fe8a7b90abc7b625d0f5b822508b350f3444d2 (diff)
Merge pull request #1 from vivi202/fixOwnedSplit
Merge Proposal.
-rw-r--r--embassy-rp/src/pwm.rs82
1 files changed, 63 insertions, 19 deletions
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs
index 5fea0901a..18d476ed4 100644
--- a/embassy-rp/src/pwm.rs
+++ b/embassy-rp/src/pwm.rs
@@ -347,40 +347,84 @@ impl<'d> Pwm<'d> {
347 347
348 #[inline] 348 #[inline]
349 /// Split Pwm driver to allow separate duty cycle control of each channel 349 /// Split Pwm driver to allow separate duty cycle control of each channel
350 pub fn split(self) -> (Option<PwmOutput>, Option<PwmOutput>) { 350 pub fn split(mut self) -> (Option<PwmOutput<'d>>, Option<PwmOutput<'d>>) {
351 351 (
352 let pwm_output_a = if let Some(pin_a) = self.pin_a { 352 self.pin_a
353 Some(PwmOutput::new(PwmChannelPin::A(pin_a), self.slice.clone())) 353 .take()
354 }; 354 .map(|pin| PwmOutput::new(PwmChannelPin::A(pin), self.slice.clone(), true)),
355 355 self.pin_b
356 let pwm_output_b = if let Some(pin_b) = self.pin_b { 356 .take()
357 Some(PwmOutput::new(PwmChannelPin::B(pin_b), self.slice.clone())) 357 .map(|pin| PwmOutput::new(PwmChannelPin::B(pin), self.slice.clone(), true)),
358 }; 358 )
359
360 (pwm_output_a,pwm_output_b)
361 } 359 }
362 360
361 pub fn split_by_ref(&mut self) -> (Option<PwmOutput<'_>>, Option<PwmOutput<'_>>) {
362 (
363 self.pin_a
364 .as_mut()
365 .map(|pin| PwmOutput::new(PwmChannelPin::A(pin.reborrow()), self.slice.clone(), false)),
366 self.pin_b
367 .as_mut()
368 .map(|pin| PwmOutput::new(PwmChannelPin::B(pin.reborrow()), self.slice.clone(), false)),
369 )
370 }
363} 371}
364 372
365enum PwmChannelPin<'d> { 373enum PwmChannelPin<'d> {
366 A(PeripheralRef<'d, AnyPin>), 374 A(PeripheralRef<'d, AnyPin>),
367 B(PeripheralRef<'d, AnyPin>) 375 B(PeripheralRef<'d, AnyPin>),
368} 376}
369 377
370/// Single channel of Pwm driver. 378/// Single channel of Pwm driver.
371pub struct PwmOutput<'d> { 379pub struct PwmOutput<'d> {
372 //pin that can be ether ChannelAPin or ChannelBPin 380 //pin that can be ether ChannelAPin or ChannelBPin
373 channel_pin: PwmChannelPin<'d> , 381 channel_pin: PwmChannelPin<'d>,
374 slice: usize, 382 slice: usize,
383 is_owned: bool,
384}
385
386impl<'d> PwmOutput<'d> {
387 fn new(channel_pin: PwmChannelPin<'d>, slice: usize, is_owned: bool) -> Self {
388 Self {
389 channel_pin,
390 slice,
391 is_owned,
392 }
393 }
375} 394}
376 395
377impl <'d> PwmOutput<'d> { 396impl<'d> Drop for PwmOutput<'d> {
378 fn new(channel_pin: PwmChannelPin<'d>, slice: usize) -> Self { 397 fn drop(&mut self) {
379 Self { channel_pin ,slice } 398 if self.is_owned {
399 let p = pac::PWM.ch(self.slice);
400 match &self.channel_pin {
401 PwmChannelPin::A(pin) => {
402 p.cc().modify(|w| {
403 w.set_a(0);
404 });
405
406 pin.gpio().ctrl().write(|w| w.set_funcsel(31));
407 ///Enable pin PULL-DOWN
408 pin.pad_ctrl().modify(|w| {
409 w.set_pde(true);
410 });
411 }
412 PwmChannelPin::B(pin) => {
413 p.cc().modify(|w| {
414 w.set_b(0);
415 });
416 pin.gpio().ctrl().write(|w| w.set_funcsel(31));
417 ///Enable pin PULL-DOWN
418 pin.pad_ctrl().modify(|w| {
419 w.set_pde(true);
420 });
421 }
422 }
423 }
380 } 424 }
381} 425}
382 426
383impl ErrorType for PwmOutput { 427impl<'d> ErrorType for PwmOutput<'d> {
384 type Error = PwmError; 428 type Error = PwmError;
385} 429}
386 430
@@ -397,12 +441,12 @@ impl<'d> SetDutyCycle for PwmOutput<'d> {
397 441
398 let p = pac::PWM.ch(self.slice); 442 let p = pac::PWM.ch(self.slice);
399 match self.channel_pin { 443 match self.channel_pin {
400 PwmChannelPin::A => { 444 PwmChannelPin::A(_) => {
401 p.cc().modify(|w| { 445 p.cc().modify(|w| {
402 w.set_a(duty); 446 w.set_a(duty);
403 }); 447 });
404 } 448 }
405 PwmChannelPin::B => { 449 PwmChannelPin::B(_) => {
406 p.cc().modify(|w| { 450 p.cc().modify(|w| {
407 w.set_b(duty); 451 w.set_b(duty);
408 }); 452 });