diff options
| author | Vincenzo Marturano <[email protected]> | 2024-10-24 15:12:04 +0200 |
|---|---|---|
| committer | Vincenzo Marturano <[email protected]> | 2024-10-24 15:12:04 +0200 |
| commit | 1fed8ac5dbb239e53cdc51b10c27a0c58ea92aeb (patch) | |
| tree | 767928d9de2dd3f755a9ae5b0822ffafc687720c /embassy-rp | |
| parent | 8803128707b8bd9fc9dcea392a62dfd42aa822d2 (diff) | |
Allow separate control of duty cycle for each channel in a pwm slice by splitting the Pwm driver.
Diffstat (limited to 'embassy-rp')
| -rw-r--r-- | embassy-rp/src/pwm.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index cfb99c569..4f11eb8f7 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs | |||
| @@ -344,6 +344,58 @@ impl<'d> Pwm<'d> { | |||
| 344 | fn bit(&self) -> u32 { | 344 | fn bit(&self) -> u32 { |
| 345 | 1 << self.slice as usize | 345 | 1 << self.slice as usize |
| 346 | } | 346 | } |
| 347 | |||
| 348 | #[inline] | ||
| 349 | /// Split Pwm driver to allow separate duty cycle control of each channel | ||
| 350 | pub fn split(&self) -> (PwmOutput,PwmOutput){ | ||
| 351 | (PwmOutput::new(PwmChannel::A,self.slice.clone()),PwmOutput::new(PwmChannel::B,self.slice.clone())) | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | enum PwmChannel{ | ||
| 356 | A, | ||
| 357 | B | ||
| 358 | } | ||
| 359 | |||
| 360 | /// Single channel of Pwm driver. | ||
| 361 | pub struct PwmOutput { | ||
| 362 | channel: PwmChannel, | ||
| 363 | slice: usize | ||
| 364 | } | ||
| 365 | |||
| 366 | impl PwmOutput { | ||
| 367 | fn new(channel: PwmChannel,slice: usize) -> Self{ | ||
| 368 | Self { channel, slice } | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | impl SetDutyCycle for PwmOutput { | ||
| 373 | fn max_duty_cycle(&self) -> u16 { | ||
| 374 | pac::PWM.ch(self.slice).top().read().top() | ||
| 375 | } | ||
| 376 | |||
| 377 | fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> { | ||
| 378 | let max_duty = self.max_duty_cycle(); | ||
| 379 | if duty > max_duty { | ||
| 380 | return Err(PwmError::InvalidDutyCycle); | ||
| 381 | } | ||
| 382 | |||
| 383 | let p = pac::PWM.ch(self.slice); | ||
| 384 | match self.channel { | ||
| 385 | PwmChannel::A => { | ||
| 386 | p.cc().modify(|w| { | ||
| 387 | w.set_a(duty); | ||
| 388 | }); | ||
| 389 | }, | ||
| 390 | PwmChannel::B => { | ||
| 391 | p.cc().modify(|w| { | ||
| 392 | w.set_b(duty); | ||
| 393 | }); | ||
| 394 | }, | ||
| 395 | } | ||
| 396 | |||
| 397 | Ok(()) | ||
| 398 | } | ||
| 347 | } | 399 | } |
| 348 | 400 | ||
| 349 | /// Batch representation of PWM slices. | 401 | /// Batch representation of PWM slices. |
