diff options
Diffstat (limited to 'src/peripheral/itm.rs')
-rw-r--r-- | src/peripheral/itm.rs | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/src/peripheral/itm.rs b/src/peripheral/itm.rs deleted file mode 100644 index 7291ae0..0000000 --- a/src/peripheral/itm.rs +++ /dev/null @@ -1,216 +0,0 @@ -//! Instrumentation Trace Macrocell -//! -//! *NOTE* Not available on Armv6-M and Armv8-M Baseline. - -use core::cell::UnsafeCell; -use core::ptr; - -use volatile_register::{RO, RW, WO}; - -use crate::peripheral::ITM; -use bitfield::bitfield; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -/// Register block -#[repr(C)] -pub struct RegisterBlock { - /// Stimulus Port - pub stim: [Stim; 256], - reserved0: [u32; 640], - /// Trace Enable - pub ter: [RW<u32>; 8], - reserved1: [u32; 8], - /// Trace Privilege - pub tpr: RW<u32>, - reserved2: [u32; 15], - /// Trace Control - pub tcr: RW<Tcr>, - reserved3: [u32; 75], - /// Lock Access - pub lar: WO<u32>, - /// Lock Status - pub lsr: RO<u32>, -} - -bitfield! { - /// Trace Control Register. - #[repr(C)] - #[derive(Copy, Clone)] - pub struct Tcr(u32); - itmena, set_itmena: 0; - tsena, set_tsena: 1; - syncena, set_synena: 2; - txena, set_txena: 3; - swoena, set_swoena: 4; - u8, tsprescale, set_tsprescale: 9, 8; - u8, gtsfreq, set_gtsfreq: 11, 10; - u8, tracebusid, set_tracebusid: 22, 16; - busy, _: 23; -} - -/// Stimulus Port -pub struct Stim { - register: UnsafeCell<u32>, -} - -impl Stim { - /// Writes an `u8` payload into the stimulus port - #[inline] - pub fn write_u8(&mut self, value: u8) { - unsafe { ptr::write_volatile(self.register.get() as *mut u8, value) } - } - - /// Writes an `u16` payload into the stimulus port - #[inline] - pub fn write_u16(&mut self, value: u16) { - unsafe { ptr::write_volatile(self.register.get() as *mut u16, value) } - } - - /// Writes an `u32` payload into the stimulus port - #[inline] - pub fn write_u32(&mut self, value: u32) { - unsafe { ptr::write_volatile(self.register.get(), value) } - } - - /// Returns `true` if the stimulus port is ready to accept more data - #[cfg(not(armv8m))] - #[inline] - pub fn is_fifo_ready(&self) -> bool { - unsafe { ptr::read_volatile(self.register.get()) & 0b1 == 1 } - } - - /// Returns `true` if the stimulus port is ready to accept more data - #[cfg(armv8m)] - #[inline] - pub fn is_fifo_ready(&self) -> bool { - // ARMv8-M adds a disabled bit; we indicate that we are ready to - // proceed with a stimulus write if the port is either ready (bit 0) or - // disabled (bit 1). - unsafe { ptr::read_volatile(self.register.get()) & 0b11 != 0 } - } -} - -/// The possible local timestamp options. -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum LocalTimestampOptions { - /// Disable local timestamps. - Disabled, - /// Enable local timestamps and use no prescaling. - Enabled, - /// Enable local timestamps and set the prescaler to divide the - /// reference clock by 4. - EnabledDiv4, - /// Enable local timestamps and set the prescaler to divide the - /// reference clock by 16. - EnabledDiv16, - /// Enable local timestamps and set the prescaler to divide the - /// reference clock by 64. - EnabledDiv64, -} - -#[cfg(feature = "std")] -impl core::convert::TryFrom<u8> for LocalTimestampOptions { - type Error = (); - - /// Converts an integer value to an enabled [LocalTimestampOptions] - /// variant. Accepted values are: 1, 4, 16, 64. Any other value - /// yields `Err(())`. - #[inline] - fn try_from(value: u8) -> Result<Self, Self::Error> { - match value { - 1 => Ok(Self::Enabled), - 4 => Ok(Self::EnabledDiv4), - 16 => Ok(Self::EnabledDiv16), - 64 => Ok(Self::EnabledDiv64), - _ => Err(()), - } - } -} - -/// The possible global timestamp options. -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -pub enum GlobalTimestampOptions { - /// Disable global timestamps. - Disabled, - /// Generate a global timestamp approximately every 128 cycles. - Every128Cycles, - /// Generate a global timestamp approximately every 8921 cycles. - Every8192Cycles, - /// Generate a global timestamp after every packet, if the output FIFO is empty. - EveryPacket, -} - -/// The possible clock sources for timestamp counters. -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -pub enum TimestampClkSrc { - /// Clock timestamp counters using the system processor clock. - SystemClock, - /// Clock timestamp counters using the asynchronous clock from the - /// TPIU interface. - /// - /// NOTE: The timestamp counter is held in reset while the output - /// line is idle. - AsyncTPIU, -} - -/// Available settings for the ITM peripheral. -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -pub struct ITMSettings { - /// Whether to enable ITM. - pub enable: bool, - /// Whether DWT packets should be forwarded to ITM. - pub forward_dwt: bool, - /// The local timestamp options that should be applied. - pub local_timestamps: LocalTimestampOptions, - /// The global timestamp options that should be applied. - pub global_timestamps: GlobalTimestampOptions, - /// The trace bus ID to use when multi-trace sources are in use. - /// `None` specifies that only a single trace source is in use and - /// has the same effect as `Some(0)`. - pub bus_id: Option<u8>, - /// The clock that should increase timestamp counters. - pub timestamp_clk_src: TimestampClkSrc, -} - -impl ITM { - /// Removes the software lock on the ITM. - #[inline] - pub fn unlock(&mut self) { - // NOTE(unsafe) atomic write to a stateless, write-only register - unsafe { self.lar.write(0xC5AC_CE55) } - } - - /// Configures the ITM with the passed [ITMSettings]. - #[inline] - pub fn configure(&mut self, settings: ITMSettings) { - unsafe { - self.tcr.modify(|mut r| { - r.set_itmena(settings.enable); - r.set_tsena(settings.local_timestamps != LocalTimestampOptions::Disabled); - r.set_txena(settings.forward_dwt); - r.set_tsprescale(match settings.local_timestamps { - LocalTimestampOptions::Disabled | LocalTimestampOptions::Enabled => 0b00, - LocalTimestampOptions::EnabledDiv4 => 0b10, - LocalTimestampOptions::EnabledDiv16 => 0b10, - LocalTimestampOptions::EnabledDiv64 => 0b11, - }); - r.set_gtsfreq(match settings.global_timestamps { - GlobalTimestampOptions::Disabled => 0b00, - GlobalTimestampOptions::Every128Cycles => 0b01, - GlobalTimestampOptions::Every8192Cycles => 0b10, - GlobalTimestampOptions::EveryPacket => 0b11, - }); - r.set_swoena(match settings.timestamp_clk_src { - TimestampClkSrc::SystemClock => false, - TimestampClkSrc::AsyncTPIU => true, - }); - r.set_tracebusid(settings.bus_id.unwrap_or(0)); - - r - }); - } - } -} |