1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
//! In-tree implementations of the [`rtic_time::Monotonic`] (reexported) trait for
//! timers & clocks found on commonly used microcontrollers.
//!
//! If you are using a microcontroller where CAS operations are not available natively, you might
//! have to enable the `critical-section` or `unsafe-assume-single-core` feature of the
//! [`portable-atomic`](https://docs.rs/portable-atomic/latest/portable_atomic/) dependency
//! yourself for this dependency to compile.
//!
//! To enable the implementations, you must enable a feature for the specific MCU you're targeting.
//!
//! # Cortex-M Systick
//! The `systick` monotonic works on all Arm Cortex-M parts, and requires that the feature `cortex-m-systick` is enabled.
//!
//! # RP2040
//! The RP2040 monotonics require that the `rp2040` feature is enabled.
//!
//! # RP2350
//! The RP2350 monotonics require that the `rp235x` feature is enabled.
//!
//! # i.MX RT
//! The i.MX RT monotonics require that the feature `imxrt_gpt1` or `imxrt_gpt2` is enabled.
//!
//! # nRF
//! nRF monotonics require that one of the available `nrf52*` features is enabled. Monotonic
//! implementations are available for both high-resolution TIMER and low-resolution RTC peripherals.
//!
//! All implementations of timers for the nRF52 family are documented here. Monotonics that
//! are not available on all parts in this family will have an `Available on crate features X only`
//! tag, describing what parts _do_ support that monotonic. Monotonics without an
//! `Available on crate features X only` tag are available on any `nrf52*` feature.
//!
//! # ESP32C3 and ESP32C6
//! Enable either the `esp32c3-systimer` or `esp32c6-systimer` feature, as appropriate.
//!
//! # STM32
//! Enable one of the `stm32*` features, as appropriate. Implementations are available for
//! a selection of STM32 timers.
//!
//! # ATSAMD
//! Monotonics for the ATSAMD family of parts using the real time clock (RTC) are provided in the
//! [`atsamd-hal`](https://docs.rs/atsamd-hal/latest/atsamd_hal/rtc/rtic/index.html)
//! crate with the `rtic` feature enabled.
//! # Priority of interrupt handlers
//!
//! The priority of timer interrupts are based on `RTIC_ASYNC_MAX_LOGICAL_PRIO` generated by RTIC.
//! It is calculated to be 1 less than the maximum hardware task priority (to not have impact on
//! hardware tasks), or, if no hardware task is available, is set to the maximum priority in the
//! system.
// To build these docs correctly:
// RUSTFLAGS="--cfg docsrs" cargo +nightly doc --features thumbv7-backend,cortex-m-systick,rp2040,nrf52840,imxrt_gpt1,imxrt_gpt2,imxrt-ral/imxrt1011,stm32h725ag,stm32_tim2,stm32_tim3,stm32_tim4,stm32_tim5,stm32_tim15
#![no_std]
#![deny(missing_docs)]
#![allow(incomplete_features)]
#![cfg_attr(docsrs, feature(doc_cfg))]
pub use fugit;
pub use rtic_time::{
self, monotonic::TimerQueueBasedMonotonic, timer_queue::TimerQueueBackend, Monotonic,
TimeoutError,
};
#[cfg(feature = "esp32c3-systimer")]
pub mod esp32c3;
#[cfg(feature = "esp32c6-systimer")]
pub mod esp32c6;
#[cfg(feature = "cortex-m-systick")]
pub mod systick;
#[cfg(feature = "rp2040")]
pub mod rp2040;
#[cfg(feature = "rp235x")]
pub mod rp235x;
#[cfg(feature = "imxrt")]
pub mod imxrt;
#[cfg(any(
feature = "nrf52805",
feature = "nrf52810",
feature = "nrf52811",
feature = "nrf52832",
feature = "nrf52833",
feature = "nrf52840",
feature = "nrf5340-app",
feature = "nrf5340-net",
feature = "nrf9160",
))]
pub mod nrf;
// Notice that `stm32` is not a feature, it is a compilation flag set in build.rs.
#[cfg(stm32)]
pub mod stm32;
#[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 = "rp235x",
feature = "rp2040",
feature = "nrf52805",
feature = "nrf52810",
feature = "nrf52811",
feature = "nrf52832",
feature = "nrf52833",
feature = "nrf52840",
feature = "nrf5340-app",
feature = "nrf5340-net",
feature = "nrf9160",
feature = "imxrt",
stm32,
))]
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);
}
|