Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate SoC/arch-specific task switching related code #284

Merged
merged 4 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions esp-wifi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,23 @@ use core::mem::MaybeUninit;

use common_adapter::RADIO_CLOCKS;
use critical_section::Mutex;

#[cfg(esp32)]
use esp32_hal as hal;
#[cfg(esp32c2)]
use esp32c2_hal as hal;
#[cfg(esp32c2)]
use esp32c2_hal::systimer::{Alarm, Target};
#[cfg(esp32c3)]
use esp32c3_hal as hal;
#[cfg(esp32c3)]
use esp32c3_hal::systimer::{Alarm, Target};
#[cfg(esp32c6)]
use esp32c6_hal as hal;
#[cfg(esp32c6)]
use esp32c6_hal::systimer::{Alarm, Target};
#[cfg(esp32s2)]
use esp32s2_hal as hal;
#[cfg(esp32s3)]
use esp32s3_hal as hal;

#[cfg(any(esp32c2, esp32c3, esp32c6))]
use hal::systimer::{Alarm, Target};

use common_adapter::init_radio_clock_control;
use hal::system::RadioClockController;

Expand All @@ -47,25 +45,13 @@ use crate::tasks::init_tasks;
use crate::timer::setup_timer_isr;
use common_adapter::chip_specific::phy_mem_init;

#[doc(hidden)]
pub mod binary {
mod binary {
pub use esp_wifi_sys::*;
}
mod compat;
mod preempt;

#[doc(hidden)]
pub mod compat;

#[doc(hidden)]
pub mod preempt;

#[doc(hidden)]
#[cfg_attr(esp32, path = "timer_esp32.rs")]
#[cfg_attr(esp32c3, path = "timer_esp32c3.rs")]
#[cfg_attr(esp32c2, path = "timer_esp32c2.rs")]
#[cfg_attr(esp32c6, path = "timer_esp32c6.rs")]
#[cfg_attr(esp32s3, path = "timer_esp32s3.rs")]
#[cfg_attr(esp32s2, path = "timer_esp32s2.rs")]
pub mod timer;
mod timer;

#[cfg(feature = "wifi")]
pub mod wifi;
Expand Down
22 changes: 22 additions & 0 deletions esp-wifi/src/timer/mod.rs
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();
}
98 changes: 98 additions & 0 deletions esp-wifi/src/timer/riscv.rs
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()
}
97 changes: 97 additions & 0 deletions esp-wifi/src/timer/timer_esp32.rs
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);
}
}
}
108 changes: 108 additions & 0 deletions esp-wifi/src/timer/timer_esp32c2.rs
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");
};
}
Loading