Skip to content

Commit b6fc085

Browse files
kyp44Dan WhitmanDan Whitman
authored
feat!: Add support for RTIC v2.0 monotonic drivers using RTC peripheral (#804)
Implement `rtic_time::Monotonic` (RTIC v2.0) trait for RTC peripheral on all platforms --------- Co-authored-by: Dan Whitman <[email protected]> Co-authored-by: Dan Whitman <[email protected]>
1 parent d0f2f5c commit b6fc085

File tree

9 files changed

+1120
-57
lines changed

9 files changed

+1120
-57
lines changed

boards/metro_m0/examples/blinky_rtic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mod app {
1919
use hal::clock::{ClockGenId, ClockSource, GenericClockController};
2020
use hal::pac::Peripherals;
2121
use hal::prelude::*;
22-
use hal::rtc::{Count32Mode, Duration, Rtc};
22+
use hal::rtc::{rtic::v1::Duration, Count32Mode, Rtc};
2323

2424
#[local]
2525
struct Local {}

hal/Cargo.toml

+21-20
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ rust-version = "1.77.2"
2323
version = "0.20.2"
2424

2525
[package.metadata.docs.rs]
26-
features = ["samd21g", "samd21g-rt", "usb", "dma", "async"]
26+
features = ["samd21g", "samd21g-rt", "usb", "dma", "async", "rtic"]
2727

2828
#===============================================================================
2929
# Required depdendencies
@@ -48,7 +48,7 @@ nb = "1.1"
4848
num-traits = {version = "0.2.19", default-features = false}
4949
opaque-debug = "0.3.0"
5050
paste = "1.0.15"
51-
portable-atomic = {version = "1.9.0", optional = true, default-features = false, features = ["critical-section"]}
51+
portable-atomic = {version = "1.10.0", optional = true, features = ["critical-section"]}
5252
rand_core = "0.6"
5353
seq-macro = "0.3"
5454
typenum = "1.12.0"
@@ -69,6 +69,7 @@ jlink_rtt = {version = "0.2", optional = true}
6969
mcan-core = {version = "0.2", optional = true}
7070
rtic-monotonic = {version = "1.0", optional = true}
7171
usb-device = {version = "0.3.2", optional = true}
72+
rtic-time = {version = "2.0", optional = true}
7273

7374
#===============================================================================
7475
# PACs
@@ -80,27 +81,27 @@ usb-device = {version = "0.3.2", optional = true}
8081
# users should specify a corresponding variant (see below). The variant features
8182
# will select the correct PAC, as well as other configuration features.
8283

83-
atsamd11c = { version = "0.14.1", path = "../pac/atsamd11c", optional = true}
84-
atsamd11d = { version = "0.14.1", path = "../pac/atsamd11d", optional = true}
84+
atsamd11c = {version = "0.14.1", path = "../pac/atsamd11c", optional = true}
85+
atsamd11d = {version = "0.14.1", path = "../pac/atsamd11d", optional = true}
8586

86-
atsamd21e = { version = "0.14.1", path = "../pac/atsamd21e", optional = true}
87-
atsamd21g = { version = "0.14.1", path = "../pac/atsamd21g", optional = true}
88-
atsamd21j = { version = "0.14.1", path = "../pac/atsamd21j", optional = true}
87+
atsamd21e = {version = "0.14.1", path = "../pac/atsamd21e", optional = true}
88+
atsamd21g = {version = "0.14.1", path = "../pac/atsamd21g", optional = true}
89+
atsamd21j = {version = "0.14.1", path = "../pac/atsamd21j", optional = true}
8990

90-
atsamd51g = { version = "0.14.1", path = "../pac/atsamd51g", optional = true}
91-
atsamd51j = { version = "0.14.1", path = "../pac/atsamd51j", optional = true}
92-
atsamd51n = { version = "0.14.1", path = "../pac/atsamd51n", optional = true}
93-
atsamd51p = { version = "0.14.1", path = "../pac/atsamd51p", optional = true}
91+
atsamd51g = {version = "0.14.1", path = "../pac/atsamd51g", optional = true}
92+
atsamd51j = {version = "0.14.1", path = "../pac/atsamd51j", optional = true}
93+
atsamd51n = {version = "0.14.1", path = "../pac/atsamd51n", optional = true}
94+
atsamd51p = {version = "0.14.1", path = "../pac/atsamd51p", optional = true}
9495

95-
atsame51g = { version = "0.14.1", path = "../pac/atsame51g", optional = true}
96-
atsame51j = { version = "0.14.1", path = "../pac/atsame51j", optional = true}
97-
atsame51n = { version = "0.14.1", path = "../pac/atsame51n", optional = true}
96+
atsame51g = {version = "0.14.1", path = "../pac/atsame51g", optional = true}
97+
atsame51j = {version = "0.14.1", path = "../pac/atsame51j", optional = true}
98+
atsame51n = {version = "0.14.1", path = "../pac/atsame51n", optional = true}
9899

99-
atsame53j = { version = "0.14.1", path = "../pac/atsame53j", optional = true}
100-
atsame53n = { version = "0.14.1", path = "../pac/atsame53n", optional = true}
100+
atsame53j = {version = "0.14.1", path = "../pac/atsame53j", optional = true}
101+
atsame53n = {version = "0.14.1", path = "../pac/atsame53n", optional = true}
101102

102-
atsame54n = { version = "0.14.1", path = "../pac/atsame54n", optional = true}
103-
atsame54p = { version = "0.14.1", path = "../pac/atsame54p", optional = true}
103+
atsame54n = {version = "0.14.1", path = "../pac/atsame54n", optional = true}
104+
atsame54p = {version = "0.14.1", path = "../pac/atsame54p", optional = true}
104105

105106
#===============================================================================
106107
# Features
@@ -182,11 +183,11 @@ same54p-rt = ["same54p", "atsame54p/rt"]
182183
# These features are user-selectable and enable additional features within the
183184
# HAL, like USB or DMA support.
184185
can = ["mcan-core"]
185-
dma = []
186186
defmt = ["dep:defmt"]
187+
dma = []
187188
enable_unsafe_aes_newblock_cipher = []
188189
max-channels = ["dma"]
189-
rtic = ["rtic-monotonic"]
190+
rtic = ["rtic-monotonic", "rtic-time", "portable-atomic"]
190191
sdmmc = ["embedded-sdmmc"]
191192
usb = ["usb-device"]
192193
use_rtt = ["jlink_rtt"]

hal/src/interrupt.rs

+9
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ pub enum Priority {
4242
}
4343

4444
impl Priority {
45+
/// Creates the `Priority` from a numeric priority if possible.
46+
pub const fn from_numeric(prio: u8) -> Option<Self> {
47+
if prio >= 1 && prio <= 8 {
48+
Some(unsafe { core::mem::transmute::<u8, Self>(prio) })
49+
} else {
50+
None
51+
}
52+
}
53+
4554
/// Convert a logical priority (where higher priority number = higher
4655
/// priority level) to a hardware priority level (where lower priority
4756
/// number = higher priority level).

hal/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ pub use embedded_hal_async as ehal_async;
1414
#[cfg(feature = "async")]
1515
pub use embedded_io_async;
1616

17+
#[cfg(feature = "rtic")]
18+
pub use rtic_time;
19+
1720
pub mod typelevel;
1821
mod util;
1922

hal/src/prelude.rs

+6
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ pub use crate::ehal_02::digital::v2::OutputPin as _atsamd_hal_embedded_hal_digit
1111
pub use crate::ehal_02::digital::v2::ToggleableOutputPin as _atsamd_hal_embedded_hal_digital_v2_ToggleableOutputPin;
1212

1313
pub use crate::ehal_02::prelude::*;
14+
15+
#[cfg(feature = "rtic")]
16+
pub use rtic_time::Monotonic as _;
17+
18+
#[cfg(feature = "rtic")]
19+
pub use fugit::{ExtU64, ExtU64Ceil};

hal/src/rtc.rs hal/src/rtc/mod.rs

+12-36
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ use core::marker::PhantomData;
1515
use embedded_sdmmc::{TimeSource, Timestamp};
1616

1717
#[cfg(feature = "rtic")]
18-
pub type Instant = fugit::Instant<u32, 1, 32_768>;
19-
#[cfg(feature = "rtic")]
20-
pub type Duration = fugit::Duration<u32, 1, 32_768>;
18+
mod modes;
19+
2120
#[cfg(feature = "rtic")]
22-
use rtic_monotonic::Monotonic;
21+
pub mod rtic;
2322

2423
// SAMx5x imports
2524
#[hal_cfg("rtc-d5x")]
@@ -101,7 +100,6 @@ pub struct Rtc<Mode: RtcMode> {
101100
_mode: PhantomData<Mode>,
102101
}
103102

104-
#[hal_macro_helper]
105103
impl<Mode: RtcMode> Rtc<Mode> {
106104
// --- Helper Functions for M0 vs M4 targets
107105
#[inline]
@@ -115,6 +113,7 @@ impl<Mode: RtcMode> Rtc<Mode> {
115113
}
116114

117115
#[inline]
116+
#[hal_macro_helper]
118117
fn mode0_ctrla(&self) -> &Mode0CtrlA {
119118
#[hal_cfg("rtc-d5x")]
120119
return self.mode0().ctrla();
@@ -123,6 +122,7 @@ impl<Mode: RtcMode> Rtc<Mode> {
123122
}
124123

125124
#[inline]
125+
#[hal_macro_helper]
126126
fn mode2_ctrla(&self) -> &Mode2CtrlA {
127127
#[hal_cfg("rtc-d5x")]
128128
return self.mode2().ctrla();
@@ -131,6 +131,7 @@ impl<Mode: RtcMode> Rtc<Mode> {
131131
}
132132

133133
#[inline]
134+
#[hal_macro_helper]
134135
fn sync(&self) {
135136
#[hal_cfg("rtc-d5x")]
136137
while self.mode2().syncbusy().read().bits() != 0 {}
@@ -167,6 +168,7 @@ impl<Mode: RtcMode> Rtc<Mode> {
167168
}
168169

169170
/// Reonfigures the peripheral for 32bit counter mode.
171+
#[hal_macro_helper]
170172
pub fn into_count32_mode(mut self) -> Rtc<Count32Mode> {
171173
self.enable(false);
172174
self.sync();
@@ -193,6 +195,7 @@ impl<Mode: RtcMode> Rtc<Mode> {
193195

194196
/// Reconfigures the peripheral for clock/calendar mode. Requires the source
195197
/// clock to be running at 1024 Hz.
198+
#[hal_macro_helper]
196199
pub fn into_clock_mode(mut self) -> Rtc<ClockMode> {
197200
// The max divisor is 1024, so to get 1 Hz, we need a 1024 Hz source.
198201
assert_eq!(
@@ -238,6 +241,10 @@ impl Rtc<Count32Mode> {
238241
pub fn count32_mode(rtc: pac::Rtc, rtc_clock_freq: Hertz, pm: &mut Pm) -> Self {
239242
pm.apbamask().modify(|_, w| w.rtc_().set_bit());
240243

244+
// TODO: This may not work properly because here the count sync bit is not set
245+
// as it is in Self::into_count32_mode Maybe we can just call that to
246+
// avoid code duplication
247+
241248
let mut new_rtc = Self {
242249
rtc,
243250
rtc_clock_freq,
@@ -481,34 +488,3 @@ impl TimerParams {
481488
TimerParams { divider, cycles }
482489
}
483490
}
484-
485-
#[cfg(feature = "rtic")]
486-
impl Monotonic for Rtc<Count32Mode> {
487-
type Instant = Instant;
488-
type Duration = Duration;
489-
unsafe fn reset(&mut self) {
490-
// Since reset is only called once, we use it to enable the interrupt generation
491-
// bit.
492-
self.mode0().intenset().write(|w| w.cmp0().set_bit());
493-
}
494-
495-
fn now(&mut self) -> Self::Instant {
496-
Self::Instant::from_ticks(self.count32())
497-
}
498-
499-
fn zero() -> Self::Instant {
500-
Self::Instant::from_ticks(0)
501-
}
502-
503-
fn set_compare(&mut self, instant: Self::Instant) {
504-
unsafe {
505-
self.mode0()
506-
.comp(0)
507-
.write(|w| w.comp().bits(instant.ticks()))
508-
}
509-
}
510-
511-
fn clear_compare_flag(&mut self) {
512-
self.mode0().intflag().write(|w| w.cmp0().set_bit());
513-
}
514-
}

0 commit comments

Comments
 (0)