esp_wifi/preempt_builtin/timer/
riscv.rs
1use esp_hal::interrupt::InterruptHandler;
2#[cfg(any(feature = "esp32c6", feature = "esp32h2"))]
3use peripherals::INTPRI as SystemPeripheral;
4#[cfg(not(any(feature = "esp32c6", feature = "esp32h2")))]
5use peripherals::SYSTEM as SystemPeripheral;
6
7use crate::{
8 hal::{
9 interrupt::{self, TrapFrame},
10 peripherals::{self, Interrupt},
11 riscv,
12 time::Rate,
13 },
14 preempt_builtin::task_switch,
15 TimeBase,
16};
17
18const TIMESLICE_FREQUENCY: Rate = Rate::from_hz(crate::CONFIG.tick_rate_hz);
20
21use super::TIMER;
22
23pub(crate) fn setup_timer(mut alarm0: TimeBase) {
24 riscv::interrupt::disable();
26
27 let cb: extern "C" fn() = unsafe { core::mem::transmute(handler as *const ()) };
28 alarm0.set_interrupt_handler(InterruptHandler::new(cb, interrupt::Priority::Priority1));
29 unwrap!(alarm0.start(TIMESLICE_FREQUENCY.as_duration()));
30 TIMER.with(|timer| {
31 alarm0.enable_interrupt(true);
32 timer.replace(alarm0);
33 });
34}
35
36pub(crate) fn disable_timer() {
37 TIMER.with(|timer| {
38 let timer = unwrap!(timer.as_mut());
39 timer.enable_interrupt(false);
40 unwrap!(timer.cancel());
41 });
42}
43
44pub(crate) fn setup_multitasking() {
45 unwrap!(interrupt::enable(
46 Interrupt::FROM_CPU_INTR3,
47 interrupt::Priority::Priority1,
48 ));
49
50 unsafe {
51 riscv::interrupt::enable();
52 }
53}
54
55pub(crate) fn disable_multitasking() {
56 interrupt::disable(crate::hal::system::Cpu::ProCpu, Interrupt::FROM_CPU_INTR3);
57}
58
59extern "C" fn handler(trap_frame: &mut TrapFrame) {
60 TIMER.with(|timer| {
62 unwrap!(timer.as_mut()).clear_interrupt();
63 });
64
65 task_switch(trap_frame);
66}
67
68#[no_mangle]
69extern "C" fn FROM_CPU_INTR3(trap_frame: &mut TrapFrame) {
70 SystemPeripheral::regs()
72 .cpu_intr_from_cpu_3()
73 .modify(|_, w| w.cpu_intr_from_cpu_3().clear_bit());
74
75 TIMER.with(|alarm0| {
76 let alarm0 = unwrap!(alarm0.as_mut());
77 alarm0.clear_interrupt();
78 });
79
80 task_switch(trap_frame);
81}
82
83pub(crate) fn yield_task() {
84 SystemPeripheral::regs()
85 .cpu_intr_from_cpu_3()
86 .modify(|_, w| w.cpu_intr_from_cpu_3().set_bit());
87}