Skip to content

Commit

Permalink
don't own DWT
Browse files Browse the repository at this point in the history
This is fine as long as the user does not change or disable the cycle
counter. It allows the other DWT features to be used freely by the
application.
  • Loading branch information
jordens committed Feb 4, 2022
1 parent 2303279 commit 7326c2a
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! # `Monotonic` implementation based on DWT and SysTick
//! # `Monotonic` implementation based on DWT cycle counter and SysTick

#![no_std]

Expand All @@ -18,10 +18,11 @@ use rtic_monotonic::Monotonic;
/// Note that the SysTick interrupt must not be disabled longer than half the
/// cycle counter overflow period (typically a couple seconds).
///
/// Note(Safety): Do not disable/enable or set/reset the DWT cycle counter.
///
/// When the `extend` feature is enabled, the cycle counter width is extended to
/// `u64` by detecting and counting overflows.
pub struct DwtSystick<const TIMER_HZ: u32> {
dwt: DWT,
systick: SYST,
#[cfg(feature = "extend")]
last: u64,
Expand All @@ -34,18 +35,15 @@ impl<const TIMER_HZ: u32> DwtSystick<TIMER_HZ> {
/// so the speed calculated at runtime and the declared speed (generic parameter
/// `TIMER_HZ`) can be compared.
#[inline(always)]
pub fn new(dcb: &mut DCB, dwt: DWT, systick: SYST, sysclk: u32) -> Self {
pub fn new(dcb: &mut DCB, systick: SYST, sysclk: u32) -> Self {
assert!(TIMER_HZ == sysclk);

dcb.enable_trace();
DWT::unlock();

unsafe { dwt.cyccnt.write(0) };

// We do not start the counter here, it is started in `reset`.

DwtSystick {
dwt,
systick,
#[cfg(feature = "extend")]
last: 0,
Expand All @@ -63,7 +61,7 @@ impl<const TIMER_HZ: u32> Monotonic for DwtSystick<TIMER_HZ> {

#[inline(always)]
fn now(&mut self) -> Self::Instant {
Self::Instant::from_ticks(self.dwt.cyccnt.read())
Self::Instant::from_ticks(DWT::cycle_count())
}
} else {
// Need to detect and track overflows.
Expand All @@ -76,7 +74,7 @@ impl<const TIMER_HZ: u32> Monotonic for DwtSystick<TIMER_HZ> {
fn now(&mut self) -> Self::Instant {
let mut high = (self.last >> 32) as u32;
let low = self.last as u32;
let now = self.dwt.cyccnt.read();
let now = DWT::cycle_count();

// Detect CYCCNT overflow
if now < low {
Expand All @@ -90,12 +88,13 @@ impl<const TIMER_HZ: u32> Monotonic for DwtSystick<TIMER_HZ> {
}

unsafe fn reset(&mut self) {
self.dwt.enable_cycle_counter();
// dwt.enable_cycle_counter();
(*DWT::PTR).ctrl.modify(|r| r | 1);

self.systick.set_clock_source(SystClkSource::Core);
self.systick.enable_counter();

self.dwt.cyccnt.write(0);
(*DWT::PTR).cyccnt.write(0);
}

fn set_compare(&mut self, val: Self::Instant) {
Expand Down

0 comments on commit 7326c2a

Please sign in to comment.