Skip to content

Commit

Permalink
feat(rtic-v2-rtc-monotonics): Extends the MIN_COMPARE_TICKS to addr…
Browse files Browse the repository at this point in the history
…ess a freezing issue in release builds.
  • Loading branch information
Dan Whitman committed Dec 22, 2024
1 parent b81f752 commit d05b300
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 27 deletions.
9 changes: 0 additions & 9 deletions hal/src/rtc/modes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,6 @@ macro_rules! create_rtc_interrupt {
pub trait RtcMode {
/// The type of the COUNT register.
type Count: Copy + PartialEq + Eq;
/// The COUNT value representing a half period.
const HALF_PERIOD: Self::Count;
/// The minimum number of ticks that compares need to be ahead of the COUNT
/// in order to trigger.
const MIN_COMPARE_TICKS: Self::Count;

/// Sets this mode in the CTRL register.
unsafe fn set_mode(rtc: &Rtc);
Expand Down Expand Up @@ -219,8 +214,6 @@ pub mod mode0 {

impl RtcMode for RtcMode0 {
type Count = u32;
const HALF_PERIOD: Self::Count = 0x8000_0000;
const MIN_COMPARE_TICKS: Self::Count = 5;

#[inline]
unsafe fn set_mode(rtc: &Rtc) {
Expand Down Expand Up @@ -286,8 +279,6 @@ pub mod mode1 {

impl RtcMode for RtcMode1 {
type Count = u16;
const HALF_PERIOD: Self::Count = 0x8000;
const MIN_COMPARE_TICKS: Self::Count = 5;

#[inline]
unsafe fn set_mode(rtc: &Rtc) {
Expand Down
31 changes: 15 additions & 16 deletions hal/src/rtc/rtic/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ macro_rules! __internal_backend_methods {
) -> bool {
let d = a.wrapping_sub(b);

d >= <$mode as RtcModeMonotonic>::HALF_PERIOD
d >= <$mode>::HALF_PERIOD
}

// Ensure that the COUNT is at least the compare value
Expand All @@ -38,6 +38,7 @@ macro_rules! __internal_backend_methods {
// before `RtcBackend::on_interrupt` is called.
if <$mode>::check_interrupt_flag::<$rtic_int>(&rtc) {
let compare = <$mode>::get_compare(&rtc, 0);

while less_than_with_wrap(<$mode>::count(&rtc), compare) {}
}

Expand Down Expand Up @@ -129,7 +130,6 @@ macro_rules! __internal_basic_backend {
impl TimerQueueBackend for $name {
type Ticks = <$mode as RtcMode>::Count;

#[hal_macro_helper]
fn now() -> Self::Ticks {
<$mode>::count(unsafe { &pac::Rtc::steal() })
}
Expand All @@ -154,9 +154,9 @@ macro_rules! __internal_basic_backend {
// This is not mentioned in the documentation or errata, but is known to be an
// issue for other microcontrollers as well (e.g. nRF family).
if instant.saturating_sub(Self::now())
< <$mode as RtcModeMonotonic>::MIN_COMPARE_TICKS
< <$mode>::MIN_COMPARE_TICKS
{
instant = instant.wrapping_add(<$mode as RtcModeMonotonic>::MIN_COMPARE_TICKS)
instant = instant.wrapping_add(<$mode>::MIN_COMPARE_TICKS)
}

unsafe { <$mode>::set_compare(&rtc, 0, instant) };
Expand Down Expand Up @@ -215,7 +215,7 @@ macro_rules! __internal_half_period_counting_backend {
init_compares = {
// Configure the compare registers
<$mode>::set_compare(&rtc, 0, 0);
<$mode>::set_compare(&rtc, 1, <$mode as RtcModeMonotonic>::HALF_PERIOD);
<$mode>::set_compare(&rtc, 1, <$mode>::HALF_PERIOD);
}
statics = {
// Make sure period counter is synced with the timer value
Expand All @@ -236,7 +236,6 @@ macro_rules! __internal_half_period_counting_backend {
impl TimerQueueBackend for RtcBackend {
type Ticks = u64;

#[hal_macro_helper]
fn now() -> Self::Ticks {
calculate_now(
|| RTC_PERIOD_COUNT.load(Ordering::Relaxed),
Expand All @@ -263,7 +262,7 @@ macro_rules! __internal_half_period_counting_backend {

// Ensure that the COUNT has crossed
// Due to syncing delay this may not be the case initially
while <$mode>::count(&rtc) < <$mode as RtcModeMonotonic>::HALF_PERIOD {}
while <$mode>::count(&rtc) < <$mode>::HALF_PERIOD {}
}
if <$mode>::check_interrupt_flag::<$overflow_int>(&rtc) {
<$mode>::clear_interrupt_flag::<$overflow_int>(&rtc);
Expand All @@ -272,7 +271,7 @@ macro_rules! __internal_half_period_counting_backend {

// Ensure that the COUNT has wrapped
// Due to syncing delay this may not be the case initially
while <$mode>::count(&rtc) > <$mode as RtcModeMonotonic>::HALF_PERIOD {}
while <$mode>::count(&rtc) > <$mode>::HALF_PERIOD {}
}
}

Expand All @@ -293,19 +292,19 @@ macro_rules! __internal_half_period_counting_backend {
let val = if diff <= MAX {
// Now we know `instant` will happen within one `MAX` time duration.

// Evidently the compare interrupt will not trigger if the instant is within
// a couple of ticks, so delay it a bit if it is too
// close. This is not mentioned in the documentation
// or errata, but is known to be an issue for other
// microcontrollers as well (e.g. nRF family).
if diff < <$mode as RtcModeMonotonic>::MIN_COMPARE_TICKS.into() {
// Evidently the compare interrupt will not trigger if the instant is within a
// couple of ticks, so delay it a bit if it is too close.
// This is not mentioned in the documentation or errata, but is known to be an
// issue for other microcontrollers as well (e.g. nRF family).
if diff < <$mode>::MIN_COMPARE_TICKS.into() {
instant = instant
.wrapping_add(<$mode as RtcModeMonotonic>::MIN_COMPARE_TICKS.into())
.wrapping_add(<$mode>::MIN_COMPARE_TICKS.into());
}

(instant & MAX) as <$mode as RtcMode>::Count
} else {
0
// Just wait a full hardware counter period
<$mode>::count(&rtc).wrapping_sub(1)
};

unsafe { <$mode>::set_compare(&rtc, 0, val) };
Expand Down
4 changes: 2 additions & 2 deletions hal/src/rtc/rtic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ trait RtcModeMonotonic: RtcMode {
}
impl RtcModeMonotonic for RtcMode0 {
const HALF_PERIOD: Self::Count = 0x8000_0000;
const MIN_COMPARE_TICKS: Self::Count = 5;
const MIN_COMPARE_TICKS: Self::Count = 8;
}
impl RtcModeMonotonic for RtcMode1 {
const HALF_PERIOD: Self::Count = 0x8000;
const MIN_COMPARE_TICKS: Self::Count = 5;
const MIN_COMPARE_TICKS: Self::Count = 8;
}

#[hal_macro_helper]
Expand Down

0 comments on commit d05b300

Please sign in to comment.