forked from esp-rs/esp-hal
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deduplicate SoC/arch-specific task switching related code (esp-rs#284)
* Clean up imports, refer to crate-relative hal * Move timer* files to submodule, split out common code * Deduplicate time-based task switching * Extract common setup fn
- Loading branch information
Showing
14 changed files
with
631 additions
and
997 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#[cfg_attr(esp32, path = "timer_esp32.rs")] | ||
#[cfg_attr(esp32c2, path = "timer_esp32c2.rs")] | ||
#[cfg_attr(esp32c3, path = "timer_esp32c3.rs")] | ||
#[cfg_attr(esp32c6, path = "timer_esp32c6.rs")] | ||
#[cfg_attr(esp32s3, path = "timer_esp32s3.rs")] | ||
#[cfg_attr(esp32s2, path = "timer_esp32s2.rs")] | ||
mod chip_specific; | ||
|
||
#[cfg_attr(any(esp32, esp32s2, esp32s3), path = "xtensa.rs")] | ||
#[cfg_attr(any(esp32c2, esp32c3, esp32c6), path = "riscv.rs")] | ||
mod arch_specific; | ||
|
||
pub use arch_specific::*; | ||
pub use chip_specific::*; | ||
|
||
pub fn setup_timer_isr(timebase: TimeBase) { | ||
setup_radio_isr(); | ||
|
||
setup_timer(timebase); | ||
|
||
setup_multitasking(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use core::cell::RefCell; | ||
|
||
use critical_section::Mutex; | ||
|
||
use crate::{ | ||
hal::{ | ||
interrupt::{self, TrapFrame}, | ||
peripherals::{self, Interrupt}, | ||
prelude::*, | ||
riscv, | ||
systimer::{Alarm, Periodic, SystemTimer, Target}, | ||
}, | ||
preempt::preempt::task_switch, | ||
}; | ||
|
||
#[cfg(feature = "esp32c6")] | ||
use peripherals::INTPRI as SystemPeripheral; | ||
#[cfg(not(feature = "esp32c6"))] | ||
use peripherals::SYSTEM as SystemPeripheral; | ||
|
||
pub type TimeBase = Alarm<Target, 0>; | ||
|
||
pub const TICKS_PER_SECOND: u64 = 16_000_000; | ||
|
||
const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); | ||
|
||
static ALARM0: Mutex<RefCell<Option<Alarm<Periodic, 0>>>> = Mutex::new(RefCell::new(None)); | ||
|
||
pub fn setup_timer(systimer: TimeBase) { | ||
let alarm0 = systimer.into_periodic(); | ||
alarm0.set_period(TIMER_DELAY.into()); | ||
alarm0.clear_interrupt(); | ||
alarm0.interrupt_enable(true); | ||
|
||
critical_section::with(|cs| ALARM0.borrow_ref_mut(cs).replace(alarm0)); | ||
|
||
unwrap!(interrupt::enable( | ||
Interrupt::SYSTIMER_TARGET0, | ||
interrupt::Priority::Priority1, | ||
)); | ||
} | ||
|
||
pub fn setup_multitasking() { | ||
unwrap!(interrupt::enable( | ||
Interrupt::FROM_CPU_INTR3, | ||
interrupt::Priority::Priority1, | ||
)); | ||
|
||
unsafe { | ||
riscv::interrupt::enable(); | ||
} | ||
|
||
while unsafe { crate::preempt::FIRST_SWITCH.load(core::sync::atomic::Ordering::Relaxed) } {} | ||
} | ||
|
||
#[interrupt] | ||
fn SYSTIMER_TARGET0(trap_frame: &mut TrapFrame) { | ||
// clear the systimer intr | ||
critical_section::with(|cs| { | ||
unwrap!(ALARM0.borrow_ref_mut(cs).as_mut()).clear_interrupt(); | ||
}); | ||
|
||
task_switch(trap_frame); | ||
} | ||
|
||
#[interrupt] | ||
fn FROM_CPU_INTR3(trap_frame: &mut TrapFrame) { | ||
unsafe { | ||
// clear FROM_CPU_INTR3 | ||
(&*SystemPeripheral::PTR) | ||
.cpu_intr_from_cpu_3 | ||
.modify(|_, w| w.cpu_intr_from_cpu_3().clear_bit()); | ||
} | ||
|
||
critical_section::with(|cs| { | ||
let mut alarm0 = ALARM0.borrow_ref_mut(cs); | ||
let alarm0 = unwrap!(alarm0.as_mut()); | ||
|
||
alarm0.set_period(TIMER_DELAY.into()); | ||
alarm0.clear_interrupt(); | ||
}); | ||
|
||
task_switch(trap_frame); | ||
} | ||
|
||
pub fn yield_task() { | ||
unsafe { | ||
(&*SystemPeripheral::PTR) | ||
.cpu_intr_from_cpu_3 | ||
.modify(|_, w| w.cpu_intr_from_cpu_3().set_bit()); | ||
} | ||
} | ||
|
||
/// Current systimer count value | ||
/// A tick is 1 / 16_000_000 seconds | ||
pub fn get_systimer_count() -> u64 { | ||
SystemTimer::now() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
use crate::hal::{interrupt, macros::interrupt, peripherals}; | ||
|
||
pub fn setup_radio_isr() { | ||
#[cfg(feature = "wifi")] | ||
unwrap!(interrupt::enable( | ||
peripherals::Interrupt::WIFI_MAC, | ||
interrupt::Priority::Priority1, | ||
)); | ||
|
||
#[cfg(feature = "ble")] | ||
{ | ||
unwrap!(interrupt::enable( | ||
peripherals::Interrupt::RWBT, | ||
interrupt::Priority::Priority1 | ||
)); | ||
unwrap!(interrupt::enable( | ||
peripherals::Interrupt::BT_BB, | ||
interrupt::Priority::Priority1, | ||
)); | ||
|
||
// It's a mystery why these interrupts are enabled now since it worked without this before | ||
// Now at least without disabling these nothing will work | ||
interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::ETH_MAC); | ||
interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::UART0); | ||
} | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
#[allow(non_snake_case)] | ||
#[no_mangle] | ||
fn Software0(_level: u32) { | ||
unsafe { | ||
let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_7; | ||
trace!("interrupt Software0 {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
} | ||
} | ||
|
||
#[cfg(feature = "wifi")] | ||
#[interrupt] | ||
fn WIFI_MAC() { | ||
unsafe { | ||
let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; | ||
trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
} | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
#[interrupt] | ||
fn RWBT() { | ||
unsafe { | ||
let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_5; | ||
trace!("interrupt RWBT {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
} | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
#[interrupt] | ||
fn RWBLE() { | ||
unsafe { | ||
let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_5; | ||
trace!("interrupt RWBLE {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
} | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
#[interrupt] | ||
fn BT_BB() { | ||
unsafe { | ||
let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_8; | ||
trace!("interrupt BT_BB {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use crate::{ | ||
binary, | ||
hal::{interrupt, macros::interrupt, peripherals::Interrupt}, | ||
}; | ||
|
||
pub fn setup_radio_isr() { | ||
#[cfg(feature = "wifi")] | ||
{ | ||
unwrap!(interrupt::enable( | ||
Interrupt::WIFI_MAC, | ||
interrupt::Priority::Priority1 | ||
)); | ||
unwrap!(interrupt::enable( | ||
Interrupt::WIFI_PWR, | ||
interrupt::Priority::Priority1 | ||
)); | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
{ | ||
unwrap!(interrupt::enable( | ||
Interrupt::LP_TIMER, | ||
interrupt::Priority::Priority1 | ||
)); | ||
unwrap!(interrupt::enable( | ||
Interrupt::BT_MAC, | ||
interrupt::Priority::Priority1 | ||
)); | ||
} | ||
} | ||
|
||
#[cfg(feature = "wifi")] | ||
#[interrupt] | ||
fn WIFI_MAC() { | ||
unsafe { | ||
let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; | ||
|
||
trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
|
||
trace!("interrupt 1 done"); | ||
}; | ||
} | ||
|
||
#[cfg(feature = "wifi")] | ||
#[interrupt] | ||
fn WIFI_PWR() { | ||
unsafe { | ||
let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; | ||
|
||
trace!("interrupt WIFI_PWR {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
} | ||
|
||
trace!("interrupt 1 done"); | ||
}; | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
#[interrupt] | ||
fn LP_TIMER() { | ||
unsafe { | ||
trace!("LP_TIMER interrupt"); | ||
|
||
let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_7; | ||
|
||
trace!("interrupt LP_TIMER {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
trace!("interrupt LP_TIMER call"); | ||
|
||
let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
trace!("LP_TIMER done"); | ||
} | ||
|
||
trace!("interrupt LP_TIMER done"); | ||
}; | ||
} | ||
|
||
#[cfg(feature = "ble")] | ||
#[interrupt] | ||
fn BT_MAC() { | ||
unsafe { | ||
trace!("BT_MAC interrupt"); | ||
|
||
let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_4; | ||
|
||
trace!("interrupt BT_MAC {:?} {:?}", fnc, arg); | ||
|
||
if !fnc.is_null() { | ||
trace!("interrupt BT_MAC call"); | ||
|
||
let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); | ||
fnc(arg); | ||
trace!("BT_MAC done"); | ||
} | ||
|
||
trace!("interrupt BT_MAC done"); | ||
}; | ||
} |
Oops, something went wrong.