probe_rs/architecture/arm/component/
itm.rsuse super::super::memory::romtable::CoresightComponent;
use super::DebugComponentInterface;
use crate::architecture::arm::ArmProbeInterface;
use crate::{Error, MemoryMappedRegister};
pub const _ITM_PID: [u8; 8] = [0x1, 0xB0, 0x3b, 0x0, 0x4, 0x0, 0x0, 0x0];
pub struct Itm<'a> {
component: &'a CoresightComponent,
interface: &'a mut dyn ArmProbeInterface,
}
const _REGISTER_OFFSET_ITM_TPR: u32 = 0xE40;
const REGISTER_OFFSET_ACCESS: u32 = 0xFB0;
impl<'a> Itm<'a> {
pub fn new(
interface: &'a mut dyn ArmProbeInterface,
component: &'a CoresightComponent,
) -> Self {
Itm {
interface,
component,
}
}
pub fn unlock(&mut self) -> Result<(), Error> {
self.component
.write_reg(self.interface, REGISTER_OFFSET_ACCESS, 0xC5AC_CE55)?;
Ok(())
}
pub fn tx_enable(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_itmena(true); tcr.set_tsena(true); tcr.set_syncena(true); tcr.set_txena(true); tcr.set_gtsfreq(0b10); tcr.set_trace_bus_id(0b1101); tcr.store(self.component, self.interface)?;
self.component.write_reg(
self.interface,
register::ITM_TER::ADDRESS_OFFSET as u32,
register::ITM_TER::enable_all().into(),
)?;
Ok(())
}
pub fn enable_stim_all(&mut self) -> Result<(), Error> {
self.component.write_reg(
self.interface,
register::ITM_TER::ADDRESS_OFFSET as u32,
register::ITM_TER::enable_all().into(),
)?;
Ok(())
}
pub fn disable_stim_all(&mut self) -> Result<(), Error> {
self.component.write_reg(
self.interface,
register::ITM_TER::ADDRESS_OFFSET as u32,
register::ITM_TER::disable_all().into(),
)?;
Ok(())
}
pub fn enable_stim(&mut self, port: u8) -> Result<(), Error> {
let mut value = self
.component
.read_reg(self.interface, register::ITM_TER::ADDRESS_OFFSET as u32)?;
value |= 1 << port;
self.component.write_reg(
self.interface,
register::ITM_TER::ADDRESS_OFFSET as u32,
value,
)?;
Ok(())
}
pub fn disable_stim(&mut self, port: u8) -> Result<(), Error> {
let mut value = self
.component
.read_reg(self.interface, register::ITM_TER::ADDRESS_OFFSET as u32)?;
value &= !(1 << port);
self.component.write_reg(
self.interface,
register::ITM_TER::ADDRESS_OFFSET as u32,
value,
)?;
Ok(())
}
pub fn enable_local_timestamps(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_tsena(true);
tcr.store(self.component, self.interface)?;
Ok(())
}
pub fn disable_local_timestamps(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_tsena(false);
tcr.store(self.component, self.interface)?;
Ok(())
}
pub fn enable_sync_pulses(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_syncena(true);
tcr.store(self.component, self.interface)?;
Ok(())
}
pub fn disable_sync_pulses(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_syncena(false);
tcr.store(self.component, self.interface)?;
Ok(())
}
pub fn enable_forward_dwt(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_txena(true);
tcr.store(self.component, self.interface)?;
Ok(())
}
pub fn disable_forward_dwt(&mut self) -> Result<(), Error> {
let mut tcr = register::ITM_TCR::load(self.component, self.interface)?;
tcr.set_txena(false);
tcr.store(self.component, self.interface)?;
Ok(())
}
}
mod register {
use crate::{
architecture::arm::component::DebugComponentInterface, memory_mapped_bitfield_register,
};
memory_mapped_bitfield_register! {
pub struct ITM_TER(u32);
0xE00,"ITM_TER",
impl From;
pub stim31, set_stim31: 31;
pub stim30, set_stim30: 30;
pub stim29, set_stim29: 29;
pub stim28, set_stim28: 28;
pub stim27, set_stim27: 27;
pub stim26, set_stim26: 26;
pub stim25, set_stim25: 25;
pub stim24, set_stim24: 24;
pub stim23, set_stim23: 23;
pub stim22, set_stim22: 22;
pub stim21, set_stim21: 21;
pub stim20, set_stim20: 20;
pub stim19, set_stim19: 19;
pub stim18, set_stim18: 18;
pub stim17, set_stim17: 17;
pub stim16, set_stim16: 16;
pub stim15, set_stim15: 15;
pub stim14, set_stim14: 14;
pub stim13, set_stim13: 13;
pub stim12, set_stim12: 12;
pub stim11, set_stim11: 11;
pub stim10, set_stim10: 10;
pub stim09, set_stim09: 9;
pub stim08, set_stim08: 8;
pub stim07, set_stim07: 7;
pub stim06, set_stim06: 6;
pub stim05, set_stim05: 5;
pub stim04, set_stim04: 4;
pub stim03, set_stim03: 3;
pub stim02, set_stim02: 2;
pub stim01, set_stim01: 1;
pub stim00, set_stim00: 0;
}
impl ITM_TER {
pub fn enable_all() -> Self {
Self(0xFFFF_FFFF)
}
pub fn disable_all() -> Self {
Self(0x0000_0000)
}
}
memory_mapped_bitfield_register! {
pub struct ITM_TCR(u32);
0xE80, "ITM_TCR",
impl From;
pub busy, set_busy: 23;
pub u8, tracebusid, set_trace_bus_id: 22, 16;
pub u8, gtsfreq, set_gtsfreq: 11, 10;
pub u8, tsprescale, set_tsprescale: 9, 8;
pub swoena, set_swoena: 4;
pub txena, set_txena: 3;
pub syncena, set_syncena: 2;
pub tsena, set_tsena: 1;
pub itmena, set_itmena: 0;
}
impl DebugComponentInterface for ITM_TCR {}
}