diff options
| author | Emil Fresk <emil.fresk@gmail.com> | 2023-04-02 20:32:10 +0200 |
|---|---|---|
| committer | Emil Fresk <emil.fresk@gmail.com> | 2023-04-04 21:40:19 +0200 |
| commit | aeec8bd41bdf3d57098902407ec320f59365641a (patch) | |
| tree | 024dbdb94cb5537312c5c34f121257265c165bea /rtic-monotonics/src | |
| parent | a2f153249f926876e7169016f3dc8e861a9ef065 (diff) | |
Add setting of priority to interrupts
Diffstat (limited to 'rtic-monotonics/src')
| -rw-r--r-- | rtic-monotonics/src/lib.rs | 36 | ||||
| -rw-r--r-- | rtic-monotonics/src/nrf/rtc.rs | 31 | ||||
| -rw-r--r-- | rtic-monotonics/src/nrf/timer.rs | 31 | ||||
| -rw-r--r-- | rtic-monotonics/src/rp2040.rs | 30 | ||||
| -rw-r--r-- | rtic-monotonics/src/systick.rs | 23 |
5 files changed, 107 insertions, 44 deletions
diff --git a/rtic-monotonics/src/lib.rs b/rtic-monotonics/src/lib.rs index fab0b2d..04ce4e2 100644 --- a/rtic-monotonics/src/lib.rs +++ b/rtic-monotonics/src/lib.rs @@ -26,6 +26,42 @@ pub mod rp2040; ))] pub mod nrf; +#[allow(dead_code)] +pub(crate) const fn cortex_logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 { + ((1 << nvic_prio_bits) - logical) << (8 - nvic_prio_bits) +} + +#[cfg(any( + feature = "rp2040", + feature = "nrf52810", + feature = "nrf52811", + feature = "nrf52832", + feature = "nrf52833", + feature = "nrf52840", + feature = "nrf5340-app", + feature = "nrf5340-net", + feature = "nrf9160", +))] +pub(crate) unsafe fn set_monotonic_prio( + prio_bits: u8, + interrupt: impl cortex_m::interrupt::InterruptNumber, +) { + extern "C" { + static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8; + } + + let max_prio = RTIC_ASYNC_MAX_LOGICAL_PRIO.max(1).min(1 << prio_bits); + + let hw_prio = crate::cortex_logical2hw(max_prio, prio_bits); + + // We take ownership of the entire IRQ and all settings to it, we only change settings + // for the IRQ we control. + // This will also compile-error in case the NVIC changes in size. + let mut nvic: cortex_m::peripheral::NVIC = core::mem::transmute(()); + + nvic.set_priority(interrupt, hw_prio); +} + /// This marker is implemented on an interrupt token to enforce that the right tokens /// are given to the correct monotonic implementation. /// diff --git a/rtic-monotonics/src/nrf/rtc.rs b/rtic-monotonics/src/nrf/rtc.rs index 724c477..03610c0 100644 --- a/rtic-monotonics/src/nrf/rtc.rs +++ b/rtic-monotonics/src/nrf/rtc.rs @@ -5,19 +5,22 @@ //! ``` //! use rtic_monotonics::nrf::rtc::*; //! -//! # async fn usage() { -//! # let rtc = unsafe { core::mem::transmute(()) }; -//! // Generate the required token -//! let token = rtic_monotonics::create_nrf_rtc0_monotonic_token!(); +//! fn init() { +//! # // This is normally provided by the selected PAC +//! # let rtc = unsafe { core::mem::transmute(()) }; +//! // Generate the required token +//! let token = rtic_monotonics::create_nrf_rtc0_monotonic_token!(); //! -//! // Start the monotonic -//! Rtc0::start(rtc, token); +//! // Start the monotonic +//! Rtc0::start(rtc, token); +//! } //! -//! loop { -//! // Use the monotonic -//! Rtc0::delay(100.millis()).await; +//! async fn usage() { +//! loop { +//! // Use the monotonic +//! Rtc0::delay(100.millis()).await; +//! } //! } -//! # } //! ``` #[cfg(feature = "nrf52810")] @@ -106,7 +109,13 @@ macro_rules! make_rtc { $tq.initialize(Self {}); - unsafe { pac::NVIC::unmask(Interrupt::$rtc) }; + // SAFETY: We take full ownership of the peripheral and interrupt vector, + // plus we are not using any external shared resources so we won't impact + // basepri/source masking based critical sections. + unsafe { + crate::set_monotonic_prio(pac::NVIC_PRIO_BITS, Interrupt::$rtc); + pac::NVIC::unmask(Interrupt::$rtc); + } } /// Used to access the underlying timer queue diff --git a/rtic-monotonics/src/nrf/timer.rs b/rtic-monotonics/src/nrf/timer.rs index ad490cc..db5316f 100644 --- a/rtic-monotonics/src/nrf/timer.rs +++ b/rtic-monotonics/src/nrf/timer.rs @@ -5,19 +5,22 @@ //! ``` //! use rtic_monotonics::nrf::timer::*; //! -//! # async fn usage() { -//! # let timer = unsafe { core::mem::transmute(()) }; -//! // Generate the required token -//! let token = rtic_monotonics::create_nrf_timer0_monotonic_token!(); +//! fn init() { +//! # // This is normally provided by the selected PAC +//! # let timer = unsafe { core::mem::transmute(()) }; +//! // Generate the required token +//! let token = rtic_monotonics::create_nrf_timer0_monotonic_token!(); //! -//! // Start the monotonic -//! Timer0::start(timer, token); +//! // Start the monotonic +//! Timer0::start(timer, token); +//! } //! -//! loop { -//! // Use the monotonic -//! Timer0::delay(100.millis()).await; +//! async fn usage() { +//! loop { +//! // Use the monotonic +//! Timer0::delay(100.millis()).await; +//! } //! } -//! # } //! ``` use super::super::Monotonic; @@ -135,7 +138,13 @@ macro_rules! make_timer { timer.events_compare[0].write(|w| w); timer.events_compare[1].write(|w| w); - unsafe { pac::NVIC::unmask(Interrupt::$timer) }; + // SAFETY: We take full ownership of the peripheral and interrupt vector, + // plus we are not using any external shared resources so we won't impact + // basepri/source masking based critical sections. + unsafe { + crate::set_monotonic_prio(pac::NVIC_PRIO_BITS, Interrupt::$timer); + pac::NVIC::unmask(Interrupt::$timer); + } } /// Used to access the underlying timer queue diff --git a/rtic-monotonics/src/rp2040.rs b/rtic-monotonics/src/rp2040.rs index 5e880cd..c656afc 100644 --- a/rtic-monotonics/src/rp2040.rs +++ b/rtic-monotonics/src/rp2040.rs @@ -5,20 +5,23 @@ //! ``` //! use rtic_monotonics::rp2040::*; //! -//! # async fn usage() { -//! # let timer = unsafe { core::mem::transmute(()) }; -//! # let mut resets = unsafe { core::mem::transmute(()) }; -//! // Generate the required token -//! let token = rtic_monotonics::create_rp2040_monotonic_token!(); +//! fn init() { +//! # // This is normally provided by the selected PAC +//! # let timer = unsafe { core::mem::transmute(()) }; +//! # let mut resets = unsafe { core::mem::transmute(()) }; +//! // Generate the required token +//! let token = rtic_monotonics::create_rp2040_monotonic_token!(); //! -//! // Start the monotonic -//! Timer::start(timer, &mut resets, token); +//! // Start the monotonic +//! Timer::start(timer, &mut resets, token); +//! } //! -//! loop { -//! // Use the monotonic -//! Timer::delay(100.millis()).await; +//! async fn usage() { +//! loop { +//! // Use the monotonic +//! Timer::delay(100.millis()).await; +//! } //! } -//! # } //! ``` use super::Monotonic; @@ -43,7 +46,10 @@ impl Timer { TIMER_QUEUE.initialize(Self {}); - unsafe { NVIC::unmask(Interrupt::TIMER_IRQ_0) }; + unsafe { + crate::set_monotonic_prio(rp2040_pac::NVIC_PRIO_BITS, Interrupt::TIMER_IRQ_0); + NVIC::unmask(Interrupt::TIMER_IRQ_0); + } } fn timer() -> &'static timer::RegisterBlock { diff --git a/rtic-monotonics/src/systick.rs b/rtic-monotonics/src/systick.rs index f1d49da..6a28a11 100644 --- a/rtic-monotonics/src/systick.rs +++ b/rtic-monotonics/src/systick.rs @@ -6,19 +6,22 @@ //! ``` //! use rtic_monotonics::systick::*; //! -//! # async fn usage() { -//! # let systick = unsafe { core::mem::transmute(()) }; -//! // Generate the required token -//! let systick_token = rtic_monotonics::create_systick_token!(); +//! fn init() { +//! # // This is normally provided by the selected PAC +//! # let systick = unsafe { core::mem::transmute(()) }; +//! // Generate the required token +//! let systick_token = rtic_monotonics::create_systick_token!(); //! -//! // Start the monotonic -//! Systick::start(systick, 12_000_000, systick_token); +//! // Start the monotonic +//! Systick::start(systick, 12_000_000, systick_token); +//! } //! -//! loop { -//! // Use the monotonic -//! Systick::delay(100.millis()).await; +//! async fn usage() { +//! loop { +//! // Use the monotonic +//! Systick::delay(100.millis()).await; +//! } //! } -//! # } //! ``` use super::Monotonic; |
