aboutsummaryrefslogtreecommitdiff
path: root/rtic-monotonics/src
diff options
context:
space:
mode:
Diffstat (limited to 'rtic-monotonics/src')
-rw-r--r--rtic-monotonics/src/lib.rs10
-rw-r--r--rtic-monotonics/src/rp2040.rs19
-rw-r--r--rtic-monotonics/src/systick.rs17
3 files changed, 43 insertions, 3 deletions
diff --git a/rtic-monotonics/src/lib.rs b/rtic-monotonics/src/lib.rs
index a4a1f428..6143fd0e 100644
--- a/rtic-monotonics/src/lib.rs
+++ b/rtic-monotonics/src/lib.rs
@@ -13,3 +13,13 @@ pub mod systick;
#[cfg(feature = "rp2040")]
pub mod rp2040;
+
+/// This marker is implemented on an interrupt token to enforce that the right tokens
+/// are given to the correct monotonic implementation.
+///
+/// This trait is implemented by this crate and not intended for user implementation.
+///
+/// # Safety
+///
+/// This is only safely implemented by this crate.
+pub unsafe trait InterruptToken<Periperhal> {}
diff --git a/rtic-monotonics/src/rp2040.rs b/rtic-monotonics/src/rp2040.rs
index e42c148e..039b117e 100644
--- a/rtic-monotonics/src/rp2040.rs
+++ b/rtic-monotonics/src/rp2040.rs
@@ -4,14 +4,18 @@ use super::Monotonic;
pub use super::{TimeoutError, TimerQueue};
use core::future::Future;
pub use fugit::ExtU64;
-use rp2040_pac::{timer, Interrupt, RESETS, TIMER};
+use rp2040_pac::{timer, Interrupt, NVIC, RESETS, TIMER};
/// Timer implementing `rtic_monotonic::Monotonic` which runs at 1 MHz.
pub struct Timer;
impl Timer {
/// Start a `Monotonic` based on RP2040's Timer.
- pub fn start(timer: TIMER, resets: &mut RESETS) {
+ pub fn start(
+ timer: TIMER,
+ resets: &mut RESETS,
+ _interrupt_token: impl crate::InterruptToken<Self>,
+ ) {
resets.reset.modify(|_, w| w.timer().clear_bit());
while resets.reset_done.read().timer().bit_is_clear() {}
timer.inte.modify(|_, w| w.alarm_0().set_bit());
@@ -134,10 +138,21 @@ impl embedded_hal_async::delay::DelayUs for Timer {
#[macro_export]
macro_rules! make_rp2040_monotonic_handler {
() => {
+ {
#[no_mangle]
#[allow(non_snake_case)]
unsafe extern "C" fn TIMER_IRQ_0() {
rtic_monotonics::rp2040::Timer::__tq().on_monotonic_interrupt();
}
+
+ pub struct Rp2040Token;
+
+ unsafe impl rtic_monotonics::InterruptToken<rtic_monotonics::rp2040::Timer>
+ for Rp2040Token
+ {
+ }
+
+ Rp2040Token
+ }
};
}
diff --git a/rtic-monotonics/src/systick.rs b/rtic-monotonics/src/systick.rs
index 691d7c76..feefc7ea 100644
--- a/rtic-monotonics/src/systick.rs
+++ b/rtic-monotonics/src/systick.rs
@@ -36,7 +36,11 @@ impl Systick {
/// `sysclk` and `TIMER_HZ`.
///
/// Note: Give the return value to `TimerQueue::initialize()` to initialize the timer queue.
- pub fn start(mut systick: cortex_m::peripheral::SYST, sysclk: u32) {
+ pub fn start(
+ mut systick: cortex_m::peripheral::SYST,
+ sysclk: u32,
+ _interrupt_token: impl crate::InterruptToken<Self>,
+ ) {
// + TIMER_HZ / 2 provides round to nearest instead of round to 0.
// - 1 as the counter range is inclusive [0, reload]
let reload = (sysclk + TIMER_HZ / 2) / TIMER_HZ - 1;
@@ -154,10 +158,21 @@ impl embedded_hal_async::delay::DelayUs for Systick {
#[macro_export]
macro_rules! make_systick_handler {
() => {
+ {
#[no_mangle]
#[allow(non_snake_case)]
unsafe extern "C" fn SysTick() {
rtic_monotonics::systick::Systick::__tq().on_monotonic_interrupt();
}
+
+ pub struct SystickToken;
+
+ unsafe impl rtic_monotonics::InterruptToken<rtic_monotonics::systick::Systick>
+ for SystickToken
+ {
+ }
+
+ SystickToken
+ }
};
}