Open
Description
The ITM can easily be enabled using OpenOCD but that requires having a debugger connected to the MCU. ITM can be used for logging or as a communication channel in a production application; in that case the MCU must take care of initializing the ITM. Right now enabling the ITM requires unsafe code; this is what it looks like:
unsafe {
// enable TPIU and ITM
cp.DCB.demcr.modify(|r| r | (1 << 24));
// prescaler
let swo_freq = 2_000_000;
cp.TPIU.acpr.write((clocks.sysclk().0 / swo_freq) - 1);
// SWO NRZ
cp.TPIU.sppr.write(2);
cp.TPIU.ffcr.modify(|r| r & !(1 << 1));
// STM32 specific: enable tracing in the DBGMCU_CR register
const DBGMCU_CR: *mut u32 = 0xe0042004 as *mut u32;
let r = ptr::read_volatile(DBGMCU_CR);
ptr::write_volatile(DBGMCU_CR, r | (1 << 5));
// unlock the ITM
cp.ITM.lar.write(0xC5ACCE55);
cp.ITM.tcr.write(
(0b000001 << 16) | // TraceBusID
(1 << 3) | // enable SWO output
(1 << 0), // enable the ITM
);
// enable stimulus port 0
cp.ITM.ter[0].write(1);
}
We should have a safe API to enable the ITM. The API could be an ITM::enable(&mut self, prescaler: u32)
method to globally enable the ITM and an ITM::{enable,disable}_port(&mut self, i: u8)
to enable / disable an individual port.