#![cfg_attr(docsrs, procmacros::doc_replace)]
#, "/api-reference/peripherals/etm.html)")]
use crate::{peripherals::ETM, system::GenericPeripheralGuard};
#[non_exhaustive]
pub struct EtmChannel<const C: u8> {}
impl<const C: u8> EtmChannel<C> {
pub fn setup<'a, E, T>(self, event: &'a E, task: &'a T) -> EtmConfiguredChannel<'a, E, T, C>
where
E: EtmEvent,
T: EtmTask,
{
let etm = ETM::regs();
let guard = GenericPeripheralGuard::new();
etm.ch(C as usize)
.evt_id()
.modify(|_, w| unsafe { w.evt_id().bits(event.id()) });
etm.ch(C as usize)
.task_id()
.modify(|_, w| unsafe { w.task_id().bits(task.id()) });
if C < 32 {
etm.ch_ena_ad0_set().write(|w| w.ch_set(C).set_bit());
} else {
etm.ch_ena_ad1_set().write(|w| w.ch_set(C - 32).set_bit());
}
EtmConfiguredChannel {
_event: event,
_task: task,
_guard: guard,
}
}
}
fn disable_channel(channel: u8) {
if channel < 32 {
ETM::regs()
.ch_ena_ad0_clr()
.write(|w| w.ch_clr(channel).set_bit());
} else {
ETM::regs()
.ch_ena_ad1_clr()
.write(|w| w.ch_clr(channel - 32).set_bit());
}
}
#[non_exhaustive]
pub struct EtmConfiguredChannel<'a, E, T, const C: u8>
where
E: EtmEvent,
T: EtmTask,
{
_event: &'a E,
_task: &'a T,
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Etm as u8 }>,
}
impl<E, T, const C: u8> Drop for EtmConfiguredChannel<'_, E, T, C>
where
E: EtmEvent,
T: EtmTask,
{
fn drop(&mut self) {
debug!("Drop ETM channel {}", C);
disable_channel(C);
}
}
macro_rules! create_etm {
($($num:literal),+) => {
paste::paste! {
pub struct Etm<'d> {
_peripheral: crate::peripherals::ETM<'d>,
$(
pub [< channel $num >]: EtmChannel<$num>,
)+
}
impl<'d> Etm<'d> {
pub fn new(peripheral: crate::peripherals::ETM<'d>) -> Self {
Self {
_peripheral: peripheral,
$([< channel $num >]: EtmChannel { },)+
}
}
}
}
};
}
create_etm!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
);
#[doc(hidden)]
pub trait EtmEvent: crate::private::Sealed {
fn id(&self) -> u8;
}
#[doc(hidden)]
pub trait EtmTask: crate::private::Sealed {
fn id(&self) -> u8;
}