diff options
| author | Vincenzo Marturano <[email protected]> | 2024-10-25 12:57:10 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-10-25 12:57:10 +0200 |
| commit | 7d9d2f8459bfe08f16254c3154d8c6e483e429f5 (patch) | |
| tree | f382ec95a9a5e45e28f42b9dace3cdc807a8765b | |
| parent | 336ef01b05e87e6b2b3c9b98e9bdca0c7d78a6af (diff) | |
| parent | 71fe8a7b90abc7b625d0f5b822508b350f3444d2 (diff) | |
Merge pull request #1 from vivi202/fixOwnedSplit
Merge Proposal.
| -rw-r--r-- | embassy-rp/src/pwm.rs | 82 |
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 | ||
| 365 | enum PwmChannelPin<'d> { | 373 | enum 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. |
| 371 | pub struct PwmOutput<'d> { | 379 | pub 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 | |||
| 386 | impl<'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 | ||
| 377 | impl <'d> PwmOutput<'d> { | 396 | impl<'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 | ||
| 383 | impl ErrorType for PwmOutput { | 427 | impl<'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 | }); |
