| 1 | //! Instrumentation Trace Macrocell |
| 2 | //! |
| 3 | //! *NOTE* Not available on Armv6-M and Armv8-M Baseline. |
| 4 | |
| 5 | use core::cell::UnsafeCell; |
| 6 | use core::ptr; |
| 7 | |
| 8 | use volatile_register::{RO, RW, WO}; |
| 9 | |
| 10 | /// Register block |
| 11 | #[repr (C)] |
| 12 | pub struct RegisterBlock { |
| 13 | /// Stimulus Port |
| 14 | pub stim: [Stim; 256], |
| 15 | reserved0: [u32; 640], |
| 16 | /// Trace Enable |
| 17 | pub ter: [RW<u32>; 8], |
| 18 | reserved1: [u32; 8], |
| 19 | /// Trace Privilege |
| 20 | pub tpr: RW<u32>, |
| 21 | reserved2: [u32; 15], |
| 22 | /// Trace Control |
| 23 | pub tcr: RW<u32>, |
| 24 | reserved3: [u32; 75], |
| 25 | /// Lock Access |
| 26 | pub lar: WO<u32>, |
| 27 | /// Lock Status |
| 28 | pub lsr: RO<u32>, |
| 29 | } |
| 30 | |
| 31 | /// Stimulus Port |
| 32 | pub struct Stim { |
| 33 | register: UnsafeCell<u32>, |
| 34 | } |
| 35 | |
| 36 | impl Stim { |
| 37 | /// Writes an `u8` payload into the stimulus port |
| 38 | #[inline ] |
| 39 | pub fn write_u8(&mut self, value: u8) { |
| 40 | unsafe { ptr::write_volatile(self.register.get() as *mut u8, value) } |
| 41 | } |
| 42 | |
| 43 | /// Writes an `u16` payload into the stimulus port |
| 44 | #[inline ] |
| 45 | pub fn write_u16(&mut self, value: u16) { |
| 46 | unsafe { ptr::write_volatile(self.register.get() as *mut u16, value) } |
| 47 | } |
| 48 | |
| 49 | /// Writes an `u32` payload into the stimulus port |
| 50 | #[inline ] |
| 51 | pub fn write_u32(&mut self, value: u32) { |
| 52 | unsafe { ptr::write_volatile(self.register.get(), value) } |
| 53 | } |
| 54 | |
| 55 | /// Returns `true` if the stimulus port is ready to accept more data |
| 56 | #[cfg (not(armv8m))] |
| 57 | #[inline ] |
| 58 | pub fn is_fifo_ready(&self) -> bool { |
| 59 | unsafe { ptr::read_volatile(self.register.get()) & 0b1 == 1 } |
| 60 | } |
| 61 | |
| 62 | /// Returns `true` if the stimulus port is ready to accept more data |
| 63 | #[cfg (armv8m)] |
| 64 | #[inline ] |
| 65 | pub fn is_fifo_ready(&self) -> bool { |
| 66 | // ARMv8-M adds a disabled bit; we indicate that we are ready to |
| 67 | // proceed with a stimulus write if the port is either ready (bit 0) or |
| 68 | // disabled (bit 1). |
| 69 | unsafe { ptr::read_volatile(self.register.get()) & 0b11 != 0 } |
| 70 | } |
| 71 | } |
| 72 | |