mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 04:10:28 +00:00
127 lines
3.4 KiB
Rust
127 lines
3.4 KiB
Rust
//! Interrupt Test
|
|
//!
|
|
//! "Disabled" for now - see https://github.com/esp-rs/esp-hal/pull/1635#issuecomment-2137405251
|
|
|
|
//% CHIPS: esp32c2 esp32c3 esp32c6 esp32h2
|
|
//% FEATURES: unstable
|
|
|
|
#![no_std]
|
|
#![no_main]
|
|
|
|
use core::{arch::asm, cell::RefCell};
|
|
|
|
use critical_section::Mutex;
|
|
use esp_hal::{
|
|
clock::CpuClock,
|
|
interrupt::{
|
|
self,
|
|
CpuInterrupt,
|
|
Priority,
|
|
software::{SoftwareInterrupt, SoftwareInterruptControl},
|
|
},
|
|
peripherals::Interrupt,
|
|
};
|
|
use hil_test as _;
|
|
|
|
esp_bootloader_esp_idf::esp_app_desc!();
|
|
|
|
static SWINT0: Mutex<RefCell<Option<SoftwareInterrupt<0>>>> = Mutex::new(RefCell::new(None));
|
|
|
|
#[allow(unused)] // TODO: Remove attribute when interrupt latency test re-enabled
|
|
struct Context {
|
|
sw0_trigger_addr: u32,
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
fn interrupt20() {
|
|
unsafe { asm!("csrrwi x0, 0x7e1, 0 #disable timer") }
|
|
critical_section::with(|cs| {
|
|
SWINT0.borrow_ref(cs).as_ref().unwrap().reset();
|
|
});
|
|
|
|
let mut perf_counter: u32 = 0;
|
|
unsafe {
|
|
asm!(
|
|
"
|
|
csrr {x}, 0x7e2
|
|
",
|
|
options(nostack),
|
|
x = inout(reg) perf_counter,
|
|
)
|
|
};
|
|
defmt::info!("Performance counter:{}", perf_counter);
|
|
// TODO these values should be adjusted to catch smaller regressions
|
|
cfg_if::cfg_if! {
|
|
if #[cfg(any(feature = "esp32c3", feature = "esp32c2"))] {
|
|
assert!(perf_counter < 1100);
|
|
} else {
|
|
assert!(perf_counter < 750);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[embedded_test::tests(default_timeout = 3)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[init]
|
|
fn init() -> Context {
|
|
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
|
let peripherals = esp_hal::init(config);
|
|
let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
|
|
|
cfg_if::cfg_if! {
|
|
if #[cfg(any(feature = "esp32c6", feature = "esp32h2"))] {
|
|
let cpu_intr = &peripherals.INTPRI;
|
|
} else {
|
|
let cpu_intr = &peripherals.SYSTEM;
|
|
}
|
|
}
|
|
|
|
let sw0_trigger_addr = cpu_intr.register_block().cpu_intr_from_cpu_0() as *const _ as u32;
|
|
|
|
critical_section::with(|cs| {
|
|
SWINT0
|
|
.borrow_ref_mut(cs)
|
|
.replace(sw_ints.software_interrupt0)
|
|
});
|
|
interrupt::enable_direct(
|
|
Interrupt::FROM_CPU_INTR0,
|
|
Priority::Priority3,
|
|
CpuInterrupt::Interrupt20,
|
|
)
|
|
.unwrap();
|
|
|
|
Context { sw0_trigger_addr }
|
|
}
|
|
|
|
#[test]
|
|
#[rustfmt::skip]
|
|
fn interrupt_latency(_ctx: Context) {
|
|
// unsafe {
|
|
// asm!(
|
|
// "
|
|
// csrrwi x0, 0x7e0, 1 #what to count, for cycles write 1 for instructions write 2
|
|
// csrrwi x0, 0x7e1, 0 #disable counter
|
|
// csrrwi x0, 0x7e2, 0 #reset counter
|
|
// "
|
|
// );
|
|
// }
|
|
|
|
// // interrupt is raised from assembly for max timer granularity.
|
|
// unsafe {
|
|
// asm!(
|
|
// "
|
|
// li {bit}, 1 # Flip flag (bit 0)
|
|
// csrrwi x0, 0x7e1, 1 # enable timer
|
|
// sw {bit}, 0({addr}) # trigger FROM_CPU_INTR0
|
|
// ",
|
|
// options(nostack),
|
|
// addr = in(reg) ctx.sw0_trigger_addr,
|
|
// bit = out(reg) _,
|
|
// )
|
|
// }
|
|
}
|
|
}
|