mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 04:10:28 +00:00
51 lines
1.4 KiB
Rust
51 lines
1.4 KiB
Rust
#[cfg_attr(riscv, path = "riscv.rs")]
|
|
#[cfg_attr(xtensa, path = "xtensa.rs")]
|
|
mod arch_specific;
|
|
|
|
pub(crate) use arch_specific::*;
|
|
use esp_hal::interrupt::{InterruptHandler, Priority};
|
|
use esp_sync::NonReentrantMutex;
|
|
|
|
use crate::TimeBase;
|
|
|
|
/// The timer responsible for time slicing.
|
|
pub(crate) static TIMER: NonReentrantMutex<Option<TimeBase>> = NonReentrantMutex::new(None);
|
|
|
|
pub(crate) fn initialized() -> bool {
|
|
TIMER.with(|timer| timer.is_some())
|
|
}
|
|
|
|
pub(crate) fn setup_timebase(mut timer: TimeBase) {
|
|
// The timer needs to tick at Priority 1 to prevent accidentally interrupting
|
|
// priority 1 limited locks.
|
|
let cb: extern "C" fn() = unsafe { core::mem::transmute(timer_tick_handler as *const ()) };
|
|
|
|
// Register the interrupt handler without nesting to satisfy the requirements of the task
|
|
// switching code
|
|
#[cfg(riscv)]
|
|
let handler = InterruptHandler::new_not_nested(cb, Priority::Priority1);
|
|
|
|
#[cfg(xtensa)]
|
|
let handler = InterruptHandler::new(cb, Priority::Priority1);
|
|
|
|
timer.set_interrupt_handler(handler);
|
|
TIMER.with(|t| {
|
|
timer.listen();
|
|
t.replace(timer);
|
|
});
|
|
}
|
|
|
|
pub(crate) fn clear_timer_interrupt() {
|
|
TIMER.with(|timer| {
|
|
unwrap!(timer.as_mut()).clear_interrupt();
|
|
});
|
|
}
|
|
|
|
pub(crate) fn disable_timebase() {
|
|
TIMER.with(|timer| {
|
|
let mut timer = unwrap!(timer.take());
|
|
timer.unlisten();
|
|
unwrap!(timer.cancel());
|
|
});
|
|
}
|