From 7326c2a4784b8c95f123fa851ba9f51fe332b818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Fri, 4 Feb 2022 15:12:05 +0100 Subject: [PATCH] don't own DWT 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. --- src/lib.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 91e6f80..2efb457 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! # `Monotonic` implementation based on DWT and SysTick +//! # `Monotonic` implementation based on DWT cycle counter and SysTick #![no_std] @@ -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 { - dwt: DWT, systick: SYST, #[cfg(feature = "extend")] last: u64, @@ -34,18 +35,15 @@ impl DwtSystick { /// 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, @@ -63,7 +61,7 @@ impl Monotonic for DwtSystick { #[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. @@ -76,7 +74,7 @@ impl Monotonic for DwtSystick { 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 { @@ -90,12 +88,13 @@ impl Monotonic for DwtSystick { } 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) {