Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTIC v2 RTC monotonic drivers #804

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion boards/metro_m0/examples/blinky_rtic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod app {
use hal::clock::{ClockGenId, ClockSource, GenericClockController};
use hal::pac::Peripherals;
use hal::prelude::*;
use hal::rtc::{Count32Mode, Duration, Rtc};
use hal::rtc::{rtic::v1::Duration, Count32Mode, Rtc};

#[local]
struct Local {}
Expand Down
41 changes: 21 additions & 20 deletions hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ rust-version = "1.77.2"
version = "0.20.2"

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

#===============================================================================
# Required depdendencies
Expand All @@ -48,7 +48,7 @@ nb = "1.1"
num-traits = {version = "0.2.19", default-features = false}
opaque-debug = "0.3.0"
paste = "1.0.15"
portable-atomic = {version = "1.9.0", optional = true, default-features = false, features = ["critical-section"]}
portable-atomic = {version = "1.10.0", optional = true, features = ["critical-section"]}
rand_core = "0.6"
seq-macro = "0.3"
typenum = "1.12.0"
Expand All @@ -69,6 +69,7 @@ jlink_rtt = {version = "0.2", optional = true}
mcan-core = {version = "0.2", optional = true}
rtic-monotonic = {version = "1.0", optional = true}
usb-device = {version = "0.3.2", optional = true}
rtic-time = {version = "2.0", optional = true}

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

atsamd11c = { version = "0.14.1", path = "../pac/atsamd11c", optional = true}
atsamd11d = { version = "0.14.1", path = "../pac/atsamd11d", optional = true}
atsamd11c = {version = "0.14.1", path = "../pac/atsamd11c", optional = true}
atsamd11d = {version = "0.14.1", path = "../pac/atsamd11d", optional = true}

atsamd21e = { version = "0.14.1", path = "../pac/atsamd21e", optional = true}
atsamd21g = { version = "0.14.1", path = "../pac/atsamd21g", optional = true}
atsamd21j = { version = "0.14.1", path = "../pac/atsamd21j", optional = true}
atsamd21e = {version = "0.14.1", path = "../pac/atsamd21e", optional = true}
atsamd21g = {version = "0.14.1", path = "../pac/atsamd21g", optional = true}
atsamd21j = {version = "0.14.1", path = "../pac/atsamd21j", optional = true}

atsamd51g = { version = "0.14.1", path = "../pac/atsamd51g", optional = true}
atsamd51j = { version = "0.14.1", path = "../pac/atsamd51j", optional = true}
atsamd51n = { version = "0.14.1", path = "../pac/atsamd51n", optional = true}
atsamd51p = { version = "0.14.1", path = "../pac/atsamd51p", optional = true}
atsamd51g = {version = "0.14.1", path = "../pac/atsamd51g", optional = true}
atsamd51j = {version = "0.14.1", path = "../pac/atsamd51j", optional = true}
atsamd51n = {version = "0.14.1", path = "../pac/atsamd51n", optional = true}
atsamd51p = {version = "0.14.1", path = "../pac/atsamd51p", optional = true}

atsame51g = { version = "0.14.1", path = "../pac/atsame51g", optional = true}
atsame51j = { version = "0.14.1", path = "../pac/atsame51j", optional = true}
atsame51n = { version = "0.14.1", path = "../pac/atsame51n", optional = true}
atsame51g = {version = "0.14.1", path = "../pac/atsame51g", optional = true}
atsame51j = {version = "0.14.1", path = "../pac/atsame51j", optional = true}
atsame51n = {version = "0.14.1", path = "../pac/atsame51n", optional = true}

atsame53j = { version = "0.14.1", path = "../pac/atsame53j", optional = true}
atsame53n = { version = "0.14.1", path = "../pac/atsame53n", optional = true}
atsame53j = {version = "0.14.1", path = "../pac/atsame53j", optional = true}
atsame53n = {version = "0.14.1", path = "../pac/atsame53n", optional = true}

atsame54n = { version = "0.14.1", path = "../pac/atsame54n", optional = true}
atsame54p = { version = "0.14.1", path = "../pac/atsame54p", optional = true}
atsame54n = {version = "0.14.1", path = "../pac/atsame54n", optional = true}
atsame54p = {version = "0.14.1", path = "../pac/atsame54p", optional = true}

#===============================================================================
# Features
Expand Down Expand Up @@ -182,11 +183,11 @@ same54p-rt = ["same54p", "atsame54p/rt"]
# These features are user-selectable and enable additional features within the
# HAL, like USB or DMA support.
can = ["mcan-core"]
dma = []
defmt = ["dep:defmt"]
dma = []
enable_unsafe_aes_newblock_cipher = []
max-channels = ["dma"]
rtic = ["rtic-monotonic"]
rtic = ["rtic-monotonic", "rtic-time", "portable-atomic"]
sdmmc = ["embedded-sdmmc"]
usb = ["usb-device"]
use_rtt = ["jlink_rtt"]
Expand Down
3 changes: 3 additions & 0 deletions hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub use embedded_hal_async as ehal_async;
#[cfg(feature = "async")]
pub use embedded_io_async;

#[cfg(feature = "rtic")]
pub use rtic_time;

pub mod typelevel;
mod util;

Expand Down
6 changes: 6 additions & 0 deletions hal/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ pub use crate::ehal_02::digital::v2::OutputPin as _atsamd_hal_embedded_hal_digit
pub use crate::ehal_02::digital::v2::ToggleableOutputPin as _atsamd_hal_embedded_hal_digital_v2_ToggleableOutputPin;

pub use crate::ehal_02::prelude::*;

#[cfg(feature = "rtic")]
pub use rtic_time::Monotonic as _;

#[cfg(feature = "rtic")]
pub use fugit::{ExtU64, ExtU64Ceil};
48 changes: 12 additions & 36 deletions hal/src/rtc.rs → hal/src/rtc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ use core::marker::PhantomData;
use embedded_sdmmc::{TimeSource, Timestamp};

#[cfg(feature = "rtic")]
pub type Instant = fugit::Instant<u32, 1, 32_768>;
#[cfg(feature = "rtic")]
pub type Duration = fugit::Duration<u32, 1, 32_768>;
mod modes;

#[cfg(feature = "rtic")]
use rtic_monotonic::Monotonic;
pub mod rtic;

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

#[hal_macro_helper]
impl<Mode: RtcMode> Rtc<Mode> {
// --- Helper Functions for M0 vs M4 targets
#[inline]
Expand All @@ -115,6 +113,7 @@ impl<Mode: RtcMode> Rtc<Mode> {
}

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

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

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

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

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

// TODO: This may not work properly because here the count sync bit is not set
// as it is in Self::into_count32_mode Maybe we can just call that to
// avoid code duplication

let mut new_rtc = Self {
rtc,
rtc_clock_freq,
Expand Down Expand Up @@ -481,34 +488,3 @@ impl TimerParams {
TimerParams { divider, cycles }
}
}

#[cfg(feature = "rtic")]
impl Monotonic for Rtc<Count32Mode> {
type Instant = Instant;
type Duration = Duration;
unsafe fn reset(&mut self) {
// Since reset is only called once, we use it to enable the interrupt generation
// bit.
self.mode0().intenset().write(|w| w.cmp0().set_bit());
}

fn now(&mut self) -> Self::Instant {
Self::Instant::from_ticks(self.count32())
}

fn zero() -> Self::Instant {
Self::Instant::from_ticks(0)
}

fn set_compare(&mut self, instant: Self::Instant) {
unsafe {
self.mode0()
.comp(0)
.write(|w| w.comp().bits(instant.ticks()))
}
}

fn clear_compare_flag(&mut self) {
self.mode0().intflag().write(|w| w.cmp0().set_bit());
}
}
Loading
Loading