//! Data Watchpoint and Trace unit #[cfg(not(armv6m))] use volatile_register::WO; use volatile_register::{RO, RW}; use crate::peripheral::DWT; /// Register block #[repr(C)] pub struct RegisterBlock { /// Control pub ctrl: RW, /// Cycle Count #[cfg(not(armv6m))] pub cyccnt: RW, /// CPI Count #[cfg(not(armv6m))] pub cpicnt: RW, /// Exception Overhead Count #[cfg(not(armv6m))] pub exccnt: RW, /// Sleep Count #[cfg(not(armv6m))] pub sleepcnt: RW, /// LSU Count #[cfg(not(armv6m))] pub lsucnt: RW, /// Folded-instruction Count #[cfg(not(armv6m))] pub foldcnt: RW, /// Cortex-M0(+) does not have these parts #[cfg(armv6m)] reserved: [u32; 6], /// Program Counter Sample pub pcsr: RO, /// Comparators #[cfg(armv6m)] pub c: [Comparator; 2], #[cfg(not(armv6m))] /// Comparators pub c: [Comparator; 16], #[cfg(not(armv6m))] reserved: [u32; 932], /// Lock Access #[cfg(not(armv6m))] pub lar: WO, /// Lock Status #[cfg(not(armv6m))] pub lsr: RO, } /// Comparator #[repr(C)] pub struct Comparator { /// Comparator pub comp: RW, /// Comparator Mask pub mask: RW, /// Comparator Function pub function: RW, reserved: u32, } impl DWT { /// Enables the cycle counter #[cfg(not(armv6m))] #[inline] pub fn enable_cycle_counter(&mut self) { unsafe { self.ctrl.modify(|r| r | 1) } } /// Returns the current clock cycle count #[cfg(not(armv6m))] #[inline] pub fn get_cycle_count() -> u32 { // NOTE(unsafe) atomic read with no side effects unsafe { (*Self::ptr()).cyccnt.read() } } /// Removes the software lock on the DWT /// /// Some devices, like the STM32F7, software lock the DWT after a power cycle. #[cfg(not(armv6m))] #[inline] pub fn unlock() { // NOTE(unsafe) atomic write to a stateless, write-only register unsafe { (*Self::ptr()).lar.write(0xC5AC_CE55) } } }