From 11aaf9be797511baaa7396ad146e97cf9b5d4b4e Mon Sep 17 00:00:00 2001 From: contradict Date: Sat, 23 Oct 2021 04:47:08 -0700 Subject: [PATCH] API to enable/disable interrupts for each PWM channel. (#175) * API to enable/disable interrupts for each PWM channel. * Better name for overflow check. --- rp2040-hal/src/pwm/mod.rs | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/rp2040-hal/src/pwm/mod.rs b/rp2040-hal/src/pwm/mod.rs index 15beaa8..a206e01 100644 --- a/rp2040-hal/src/pwm/mod.rs +++ b/rp2040-hal/src/pwm/mod.rs @@ -92,6 +92,8 @@ use eh1_0_alpha::pwm::blocking as eh1; use embedded_hal::PwmPin; use pac::PWM; +use crate::atomic_register_access::{write_bitmask_clear, write_bitmask_set}; + pub mod dyn_slice; pub use dyn_slice::*; @@ -371,6 +373,45 @@ where pub fn set_top(&mut self, value: u16) { self.regs.write_top(value) } + + /// Create the interrupt bitmask corresponding to this slice + #[inline] + fn bitmask(&self) -> u32 { + 1 << I::DYN.num + } + + /// Enable the PWM_IRQ_WRAP interrupt when this slice overflows. + #[inline] + pub fn enable_interrupt(&mut self) { + unsafe { + let pwm = &(*pac::PWM::ptr()); + let reg = (&pwm.inte).as_ptr(); + write_bitmask_set(reg, self.bitmask()); + } + } + + /// Disable the PWM_IRQ_WRAP interrupt for this slice. + #[inline] + pub fn disable_interrupt(&mut self) { + unsafe { + let pwm = &(*pac::PWM::ptr()); + let reg = (&pwm.inte).as_ptr(); + write_bitmask_clear(reg, self.bitmask()); + }; + } + + /// Did this slice trigger an overflow interrupt? + #[inline] + pub fn has_overflown(&self) -> bool { + let mask = self.bitmask(); + unsafe { (*pac::PWM::ptr()).ints.read().bits() & mask == mask } + } + + /// Mark the interrupt handled for this slice. + #[inline] + pub fn clear_interrupt(&mut self) { + unsafe { (*pac::PWM::ptr()).intr.write(|w| w.bits(self.bitmask())) }; + } } macro_rules! pwm {