aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmil Fresk <emil.fresk@gmail.com>2023-04-02 20:32:10 +0200
committerEmil Fresk <emil.fresk@gmail.com>2023-04-04 21:40:19 +0200
commitaeec8bd41bdf3d57098902407ec320f59365641a (patch)
tree024dbdb94cb5537312c5c34f121257265c165bea
parenta2f153249f926876e7169016f3dc8e861a9ef065 (diff)
Add setting of priority to interrupts
-rw-r--r--rtic-monotonics/Cargo.toml18
-rw-r--r--rtic-monotonics/src/lib.rs36
-rw-r--r--rtic-monotonics/src/nrf/rtc.rs31
-rw-r--r--rtic-monotonics/src/nrf/timer.rs31
-rw-r--r--rtic-monotonics/src/rp2040.rs30
-rw-r--r--rtic-monotonics/src/systick.rs23
6 files changed, 116 insertions, 53 deletions
diff --git a/rtic-monotonics/Cargo.toml b/rtic-monotonics/Cargo.toml
index 503c22d..728e171 100644
--- a/rtic-monotonics/Cargo.toml
+++ b/rtic-monotonics/Cargo.toml
@@ -48,14 +48,14 @@ systick-100hz = []
systick-10khz = []
# Timer peripheral on the RP2040
-rp2040 = ["dep:rp2040-pac"]
+rp2040 = ["dep:cortex-m", "dep:rp2040-pac"]
# nRF Timers and RTC
-nrf52810 = ["dep:nrf52810-pac", "dep:critical-section"]
-nrf52811 = ["dep:nrf52811-pac", "dep:critical-section"]
-nrf52832 = ["dep:nrf52832-pac", "dep:critical-section"]
-nrf52833 = ["dep:nrf52833-pac", "dep:critical-section"]
-nrf52840 = ["dep:nrf52840-pac", "dep:critical-section"]
-nrf5340-app = ["dep:nrf5340-app-pac", "dep:critical-section"]
-nrf5340-net = ["dep:nrf5340-net-pac", "dep:critical-section"]
-nrf9160 = ["dep:nrf9160-pac", "dep:critical-section"]
+nrf52810 = ["dep:cortex-m", "dep:nrf52810-pac", "dep:critical-section"]
+nrf52811 = ["dep:cortex-m", "dep:nrf52811-pac", "dep:critical-section"]
+nrf52832 = ["dep:cortex-m", "dep:nrf52832-pac", "dep:critical-section"]
+nrf52833 = ["dep:cortex-m", "dep:nrf52833-pac", "dep:critical-section"]
+nrf52840 = ["dep:cortex-m", "dep:nrf52840-pac", "dep:critical-section"]
+nrf5340-app = ["dep:cortex-m", "dep:nrf5340-app-pac", "dep:critical-section"]
+nrf5340-net = ["dep:cortex-m", "dep:nrf5340-net-pac", "dep:critical-section"]
+nrf9160 = ["dep:cortex-m", "dep:nrf9160-pac", "dep:critical-section"]
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;