From e55afed173f33c3467ad35032f45ea9e46f8e132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 12 Oct 2023 15:09:19 +0200 Subject: [PATCH 1/4] Clean up imports, refer to crate-relative hal --- esp-wifi/src/lib.rs | 24 ++++++++-------------- esp-wifi/src/timer_esp32.rs | 17 ++++++++-------- esp-wifi/src/timer_esp32c2.rs | 37 +++++++++++++++++++--------------- esp-wifi/src/timer_esp32c3.rs | 38 +++++++++++++++++++---------------- esp-wifi/src/timer_esp32c6.rs | 38 +++++++++++++++++++---------------- esp-wifi/src/timer_esp32s2.rs | 33 +++++++++++++++--------------- esp-wifi/src/timer_esp32s3.rs | 37 +++++++++++++++++----------------- 7 files changed, 113 insertions(+), 111 deletions(-) diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index b8a27d80..a570408d 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -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; @@ -47,25 +45,19 @@ 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; diff --git a/esp-wifi/src/timer_esp32.rs b/esp-wifi/src/timer_esp32.rs index 23a9252e..ea128a5d 100644 --- a/esp-wifi/src/timer_esp32.rs +++ b/esp-wifi/src/timer_esp32.rs @@ -1,18 +1,17 @@ use core::cell::RefCell; -use atomic_polyfill::{AtomicU32, Ordering}; -use critical_section::Mutex; -use esp32_hal::trapframe::TrapFrame; -use esp32_hal::{ +use crate::hal::{ interrupt, + macros::interrupt, peripherals::{self, TIMG1}, + preempt::preempt::task_switch, prelude::*, timer::{Timer, Timer0}, + trapframe::TrapFrame, xtensa_lx, xtensa_lx_rt, }; - -use crate::preempt::preempt::task_switch; -use esp32_hal::macros::interrupt; +use atomic_polyfill::{AtomicU32, Ordering}; +use critical_section::Mutex; pub const TICKS_PER_SECOND: u64 = 40_000_000; @@ -68,8 +67,8 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { // 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(esp32_hal::Cpu::ProCpu, peripherals::Interrupt::ETH_MAC); - interrupt::disable(esp32_hal::Cpu::ProCpu, peripherals::Interrupt::UART0); + interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::ETH_MAC); + interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::UART0); } timer1.listen(); diff --git a/esp-wifi/src/timer_esp32c2.rs b/esp-wifi/src/timer_esp32c2.rs index 581d792b..1ca056cd 100644 --- a/esp-wifi/src/timer_esp32c2.rs +++ b/esp-wifi/src/timer_esp32c2.rs @@ -1,13 +1,18 @@ use core::cell::RefCell; -use crate::hal::interrupt::{self, TrapFrame}; -use crate::hal::peripherals::{self, Interrupt}; -use crate::hal::prelude::*; -use crate::hal::riscv; -use crate::hal::systimer::{Alarm, Periodic, SystemTimer, Target}; use critical_section::Mutex; -use crate::{binary, preempt::preempt::task_switch}; +use crate::{ + binary, + hal::{ + interrupt::{self, TrapFrame}, + peripherals::{self, Interrupt}, + prelude::*, + riscv, + systimer::{Alarm, Periodic, SystemTimer, Target}, + }, + preempt::preempt::task_switch, +}; pub const TICKS_PER_SECOND: u64 = 16_000_000; @@ -31,16 +36,16 @@ pub fn setup_timer_isr(systimer: Alarm) { )); #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - Interrupt::WIFI_MAC, - interrupt::Priority::Priority1 - )); - - #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - Interrupt::WIFI_PWR, - interrupt::Priority::Priority1 - )); + { + unwrap!(interrupt::enable( + Interrupt::WIFI_MAC, + interrupt::Priority::Priority1 + )); + unwrap!(interrupt::enable( + Interrupt::WIFI_PWR, + interrupt::Priority::Priority1 + )); + } #[cfg(feature = "ble")] { diff --git a/esp-wifi/src/timer_esp32c3.rs b/esp-wifi/src/timer_esp32c3.rs index bd05624b..90c63481 100644 --- a/esp-wifi/src/timer_esp32c3.rs +++ b/esp-wifi/src/timer_esp32c3.rs @@ -2,13 +2,17 @@ use core::cell::RefCell; use critical_section::Mutex; -use crate::hal::interrupt::{self, TrapFrame}; -use crate::hal::peripherals::{self, Interrupt}; -use crate::hal::prelude::*; -use crate::hal::riscv; -use crate::hal::systimer::{Alarm, Periodic, SystemTimer, Target}; - -use crate::{binary, preempt::preempt::task_switch}; +use crate::{ + binary, + hal::{ + interrupt::{self, TrapFrame}, + peripherals::{self, Interrupt}, + prelude::*, + riscv, + systimer::{Alarm, Periodic, SystemTimer, Target}, + }, + preempt::preempt::task_switch, +}; pub const TICKS_PER_SECOND: u64 = 16_000_000; @@ -32,16 +36,16 @@ pub fn setup_timer_isr(systimer: Alarm) { )); #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - Interrupt::WIFI_MAC, - interrupt::Priority::Priority1 - )); - - #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - Interrupt::WIFI_PWR, - interrupt::Priority::Priority1 - )); + { + unwrap!(interrupt::enable( + Interrupt::WIFI_MAC, + interrupt::Priority::Priority1 + )); + unwrap!(interrupt::enable( + Interrupt::WIFI_PWR, + interrupt::Priority::Priority1 + )); + } #[cfg(feature = "ble")] { diff --git a/esp-wifi/src/timer_esp32c6.rs b/esp-wifi/src/timer_esp32c6.rs index 81496f44..ade8c449 100644 --- a/esp-wifi/src/timer_esp32c6.rs +++ b/esp-wifi/src/timer_esp32c6.rs @@ -2,13 +2,17 @@ use core::cell::RefCell; use critical_section::Mutex; -use crate::hal::interrupt::{self, TrapFrame}; -use crate::hal::peripherals::{self, Interrupt}; -use crate::hal::prelude::*; -use crate::hal::riscv; -use crate::hal::systimer::{Alarm, Periodic, SystemTimer, Target}; - -use crate::{binary, preempt::preempt::task_switch}; +use crate::{ + binary, + hal::{ + interrupt::{self, TrapFrame}, + peripherals::{self, Interrupt}, + prelude::*, + riscv, + systimer::{Alarm, Periodic, SystemTimer, Target}, + }, + preempt::preempt::task_switch, +}; pub const TICKS_PER_SECOND: u64 = 16_000_000; @@ -32,16 +36,16 @@ pub fn setup_timer_isr(systimer: Alarm) { )); #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - Interrupt::WIFI_MAC, - interrupt::Priority::Priority1 - )); - - #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - Interrupt::WIFI_PWR, - interrupt::Priority::Priority1 - )); + { + unwrap!(interrupt::enable( + Interrupt::WIFI_MAC, + interrupt::Priority::Priority1 + )); + unwrap!(interrupt::enable( + Interrupt::WIFI_PWR, + interrupt::Priority::Priority1 + )); + } // make sure to disable WIFI_BB/MODEM_PERI_TIMEOUT by mapping it to CPU interrupt 31 which is masked by default // for some reason for this interrupt, mapping it to 0 doesn't deactivate it diff --git a/esp-wifi/src/timer_esp32s2.rs b/esp-wifi/src/timer_esp32s2.rs index c7f8e908..cc982f14 100644 --- a/esp-wifi/src/timer_esp32s2.rs +++ b/esp-wifi/src/timer_esp32s2.rs @@ -1,18 +1,17 @@ use core::cell::RefCell; -use atomic_polyfill::{AtomicU32, Ordering}; -use critical_section::Mutex; -use esp32s2_hal::trapframe::TrapFrame; -use esp32s2_hal::{ +use crate::hal::{ interrupt, + macros::interrupt, peripherals::{self, TIMG1}, + preempt::preempt::task_switch, prelude::*, timer::{Timer, Timer0}, + trapframe::TrapFrame, xtensa_lx, xtensa_lx_rt, }; - -use crate::preempt::preempt::task_switch; -use esp32s2_hal::macros::interrupt; +use atomic_polyfill::{AtomicU32, Ordering}; +use critical_section::Mutex; pub const TICKS_PER_SECOND: u64 = 40_000_000; @@ -50,16 +49,16 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { )); #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - - #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_PWR, - interrupt::Priority::Priority1, - )); + { + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_MAC, + interrupt::Priority::Priority1, + )); + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_PWR, + interrupt::Priority::Priority1, + )); + } timer1.listen(); timer1.start(TIMER_DELAY.into_duration()); diff --git a/esp-wifi/src/timer_esp32s3.rs b/esp-wifi/src/timer_esp32s3.rs index 85673ab6..b526dc4c 100644 --- a/esp-wifi/src/timer_esp32s3.rs +++ b/esp-wifi/src/timer_esp32s3.rs @@ -1,18 +1,17 @@ use core::cell::RefCell; -use atomic_polyfill::{AtomicU32, Ordering}; -use critical_section::Mutex; -use esp32s3_hal::trapframe::TrapFrame; -use esp32s3_hal::{ +use crate::hal::{ interrupt, + macros::interrupt, peripherals::{self, TIMG1}, + preempt::preempt::task_switch, prelude::*, timer::{Timer, Timer0}, + trapframe::TrapFrame, xtensa_lx, xtensa_lx_rt, }; - -use crate::preempt::preempt::task_switch; -use esp32s3_hal::macros::interrupt; +use atomic_polyfill::{AtomicU32, Ordering}; +use critical_section::Mutex; pub const TICKS_PER_SECOND: u64 = 40_000_000; @@ -50,16 +49,16 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { )); #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - - #[cfg(feature = "wifi")] - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_PWR, - interrupt::Priority::Priority1, - )); + { + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_MAC, + interrupt::Priority::Priority1, + )); + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_PWR, + interrupt::Priority::Priority1, + )); + } #[cfg(feature = "ble")] { @@ -79,7 +78,7 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { TIMER1.borrow_ref_mut(cs).replace(timer1); }); - esp32s3_hal::xtensa_lx::timer::set_ccompare0(0xffffffff); + xtensa_lx::timer::set_ccompare0(0xffffffff); unsafe { let enabled = xtensa_lx::interrupt::disable(); @@ -99,7 +98,7 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { fn Timer0(_level: u32) { TIMER_OVERFLOWS.fetch_add(1, Ordering::Relaxed); - esp32s3_hal::xtensa_lx::timer::set_ccompare0(0xffffffff); + xtensa_lx::timer::set_ccompare0(0xffffffff); } #[cfg(feature = "wifi")] From 49238e8af3f996ee53c83889e38c55a6f490910a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 12 Oct 2023 15:27:32 +0200 Subject: [PATCH 2/4] Move timer* files to submodule, split out common code --- esp-wifi/src/lib.rs | 6 - esp-wifi/src/timer/mod.rs | 13 ++ esp-wifi/src/timer/riscv.rs | 97 ++++++++ esp-wifi/src/timer/timer_esp32.rs | 109 +++++++++ esp-wifi/src/{ => timer}/timer_esp32c2.rs | 81 +------ esp-wifi/src/{ => timer}/timer_esp32c3.rs | 81 +------ esp-wifi/src/{ => timer}/timer_esp32c6.rs | 81 +------ esp-wifi/src/timer/timer_esp32s2.rs | 63 ++++++ esp-wifi/src/timer/timer_esp32s3.rs | 96 ++++++++ .../src/{timer_esp32s2.rs => timer/xtensa.rs} | 74 ++---- esp-wifi/src/timer_esp32.rs | 213 ------------------ esp-wifi/src/timer_esp32s3.rs | 200 ---------------- 12 files changed, 407 insertions(+), 707 deletions(-) create mode 100644 esp-wifi/src/timer/mod.rs create mode 100644 esp-wifi/src/timer/riscv.rs create mode 100644 esp-wifi/src/timer/timer_esp32.rs rename esp-wifi/src/{ => timer}/timer_esp32c2.rs (56%) rename esp-wifi/src/{ => timer}/timer_esp32c3.rs (59%) rename esp-wifi/src/{ => timer}/timer_esp32c6.rs (60%) create mode 100644 esp-wifi/src/timer/timer_esp32s2.rs create mode 100644 esp-wifi/src/timer/timer_esp32s3.rs rename esp-wifi/src/{timer_esp32s2.rs => timer/xtensa.rs} (70%) delete mode 100644 esp-wifi/src/timer_esp32.rs delete mode 100644 esp-wifi/src/timer_esp32s3.rs diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index a570408d..ab293bb2 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -51,12 +51,6 @@ mod binary { mod compat; mod preempt; -#[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")] mod timer; #[cfg(feature = "wifi")] diff --git a/esp-wifi/src/timer/mod.rs b/esp-wifi/src/timer/mod.rs new file mode 100644 index 00000000..6d037f1b --- /dev/null +++ b/esp-wifi/src/timer/mod.rs @@ -0,0 +1,13 @@ +#[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 chip_specific::*; diff --git a/esp-wifi/src/timer/riscv.rs b/esp-wifi/src/timer/riscv.rs new file mode 100644 index 00000000..6e588a7f --- /dev/null +++ b/esp-wifi/src/timer/riscv.rs @@ -0,0 +1,97 @@ +use core::cell::RefCell; + +use critical_section::Mutex; + +use crate::{ + binary, + 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 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>>> = Mutex::new(RefCell::new(None)); + +pub fn setup_timer(systimer: Alarm) { + 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() +} diff --git a/esp-wifi/src/timer/timer_esp32.rs b/esp-wifi/src/timer/timer_esp32.rs new file mode 100644 index 00000000..0e357883 --- /dev/null +++ b/esp-wifi/src/timer/timer_esp32.rs @@ -0,0 +1,109 @@ +use crate::hal::{ + interrupt, + macros::interrupt, + peripherals::{self, TIMG1}, + timer::{Timer, Timer0}, +}; + +pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; +use super::arch_specific::{setup_multitasking, setup_timer}; + +pub fn setup_timer_isr(timg1_timer0: Timer>) { + #[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); + } + + setup_timer(timg1_timer0); + + setup_multitasking(); +} + +#[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); + } + } +} diff --git a/esp-wifi/src/timer_esp32c2.rs b/esp-wifi/src/timer/timer_esp32c2.rs similarity index 56% rename from esp-wifi/src/timer_esp32c2.rs rename to esp-wifi/src/timer/timer_esp32c2.rs index 1ca056cd..4308c103 100644 --- a/esp-wifi/src/timer_esp32c2.rs +++ b/esp-wifi/src/timer/timer_esp32c2.rs @@ -1,7 +1,3 @@ -use core::cell::RefCell; - -use critical_section::Mutex; - use crate::{ binary, hal::{ @@ -11,29 +7,13 @@ use crate::{ riscv, systimer::{Alarm, Periodic, SystemTimer, Target}, }, - preempt::preempt::task_switch, }; -pub const TICKS_PER_SECOND: u64 = 16_000_000; - -pub const COUNTER_BIT_MASK: u64 = 0x000F_FFFF_FFFF_FFFF; - -const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); - -static ALARM0: Mutex>>> = Mutex::new(RefCell::new(None)); +pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; +use super::arch_specific::{setup_multitasking, setup_timer}; pub fn setup_timer_isr(systimer: Alarm) { - 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, - )); + setup_timer(systimer); #[cfg(feature = "wifi")] { @@ -59,16 +39,7 @@ pub fn setup_timer_isr(systimer: Alarm) { )); } - 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) } {} + setup_multitasking(); } #[cfg(feature = "wifi")] @@ -148,47 +119,3 @@ fn BT_MAC() { trace!("interrupt BT_MAC done"); }; } - -#[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 ETS_FROM_CPU_INTR3 - (&*peripherals::SYSTEM::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 { - (&*peripherals::SYSTEM::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() -} diff --git a/esp-wifi/src/timer_esp32c3.rs b/esp-wifi/src/timer/timer_esp32c3.rs similarity index 59% rename from esp-wifi/src/timer_esp32c3.rs rename to esp-wifi/src/timer/timer_esp32c3.rs index 90c63481..5848d909 100644 --- a/esp-wifi/src/timer_esp32c3.rs +++ b/esp-wifi/src/timer/timer_esp32c3.rs @@ -1,7 +1,3 @@ -use core::cell::RefCell; - -use critical_section::Mutex; - use crate::{ binary, hal::{ @@ -11,29 +7,13 @@ use crate::{ riscv, systimer::{Alarm, Periodic, SystemTimer, Target}, }, - preempt::preempt::task_switch, }; -pub const TICKS_PER_SECOND: u64 = 16_000_000; - -pub const COUNTER_BIT_MASK: u64 = 0x000F_FFFF_FFFF_FFFF; - -const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); - -static ALARM0: Mutex>>> = Mutex::new(RefCell::new(None)); +pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; +use super::arch_specific::{setup_multitasking, setup_timer}; pub fn setup_timer_isr(systimer: Alarm) { - 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, - )); + setup_timer(systimer); #[cfg(feature = "wifi")] { @@ -63,16 +43,7 @@ pub fn setup_timer_isr(systimer: Alarm) { )); } - 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) } {} + setup_multitasking(); } #[cfg(feature = "wifi")] @@ -159,47 +130,3 @@ fn BT_BB(_trap_frame: &mut TrapFrame) { trace!("interrupt 8 done"); }; } - -#[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 - (&*peripherals::SYSTEM::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 { - (&*peripherals::SYSTEM::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() -} diff --git a/esp-wifi/src/timer_esp32c6.rs b/esp-wifi/src/timer/timer_esp32c6.rs similarity index 60% rename from esp-wifi/src/timer_esp32c6.rs rename to esp-wifi/src/timer/timer_esp32c6.rs index ade8c449..57727ede 100644 --- a/esp-wifi/src/timer_esp32c6.rs +++ b/esp-wifi/src/timer/timer_esp32c6.rs @@ -1,7 +1,3 @@ -use core::cell::RefCell; - -use critical_section::Mutex; - use crate::{ binary, hal::{ @@ -11,29 +7,13 @@ use crate::{ riscv, systimer::{Alarm, Periodic, SystemTimer, Target}, }, - preempt::preempt::task_switch, }; -pub const TICKS_PER_SECOND: u64 = 16_000_000; - -pub const COUNTER_BIT_MASK: u64 = 0x000F_FFFF_FFFF_FFFF; - -const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); - -static ALARM0: Mutex>>> = Mutex::new(RefCell::new(None)); +pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; +use super::arch_specific::{setup_multitasking, setup_timer}; pub fn setup_timer_isr(systimer: Alarm) { - 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, - )); + setup_timer(systimer); #[cfg(feature = "wifi")] { @@ -69,16 +49,7 @@ pub fn setup_timer_isr(systimer: Alarm) { )); } - 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) } {} + setup_multitasking(); } #[cfg(feature = "wifi")] @@ -158,47 +129,3 @@ fn BT_MAC() { trace!("interrupt BT_MAC done"); }; } - -#[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 - (&*peripherals::INTPRI::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 { - (&*peripherals::INTPRI::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() -} diff --git a/esp-wifi/src/timer/timer_esp32s2.rs b/esp-wifi/src/timer/timer_esp32s2.rs new file mode 100644 index 00000000..971ac702 --- /dev/null +++ b/esp-wifi/src/timer/timer_esp32s2.rs @@ -0,0 +1,63 @@ +use crate::hal::{ + interrupt, + macros::interrupt, + peripherals::{self, TIMG1}, + timer::{Timer, Timer0}, +}; + +pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; +use super::arch_specific::{setup_multitasking, setup_timer}; + +pub fn setup_timer_isr(timg1_timer0: Timer>) { + unwrap!(interrupt::enable( + peripherals::Interrupt::TG1_T0_LEVEL, + interrupt::Priority::Priority2, + )); + + #[cfg(feature = "wifi")] + { + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_MAC, + interrupt::Priority::Priority1, + )); + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_PWR, + interrupt::Priority::Priority1, + )); + } + + setup_timer(timg1_timer0); + + setup_multitasking(); +} + +#[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 = "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 crate::binary::c_types::c_void) = core::mem::transmute(fnc); + fnc(arg); + } + + trace!("interrupt 1 done"); + }; +} diff --git a/esp-wifi/src/timer/timer_esp32s3.rs b/esp-wifi/src/timer/timer_esp32s3.rs new file mode 100644 index 00000000..cc82f648 --- /dev/null +++ b/esp-wifi/src/timer/timer_esp32s3.rs @@ -0,0 +1,96 @@ +use crate::hal::{ + interrupt, + macros::interrupt, + peripherals::{self, TIMG1}, + timer::{Timer, Timer0}, +}; + +pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; +use super::arch_specific::{setup_multitasking, setup_timer}; + +pub fn setup_timer_isr(timg1_timer0: Timer>) { + #[cfg(feature = "wifi")] + { + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_MAC, + interrupt::Priority::Priority1, + )); + unwrap!(interrupt::enable( + peripherals::Interrupt::WIFI_PWR, + interrupt::Priority::Priority1, + )); + } + + #[cfg(feature = "ble")] + { + unwrap!(interrupt::enable( + peripherals::Interrupt::BT_BB, + interrupt::Priority::Priority1, + )); + unwrap!(interrupt::enable( + peripherals::Interrupt::RWBLE, + interrupt::Priority::Priority1, + )); + } + + setup_timer(timg1_timer0); + + setup_multitasking(); +} + +#[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 = "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 crate::binary::c_types::c_void) = core::mem::transmute(fnc); + fnc(arg); + } + + trace!("interrupt 1 done"); + }; +} + +#[cfg(feature = "ble")] +#[interrupt] +fn RWBLE() { + critical_section::with(|_| 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() { + critical_section::with(|_| unsafe { + let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_8; + 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); + } + }); +} diff --git a/esp-wifi/src/timer_esp32s2.rs b/esp-wifi/src/timer/xtensa.rs similarity index 70% rename from esp-wifi/src/timer_esp32s2.rs rename to esp-wifi/src/timer/xtensa.rs index cc982f14..dc024e40 100644 --- a/esp-wifi/src/timer_esp32s2.rs +++ b/esp-wifi/src/timer/xtensa.rs @@ -1,27 +1,27 @@ use core::cell::RefCell; -use crate::hal::{ - interrupt, - macros::interrupt, - peripherals::{self, TIMG1}, +use crate::{ + hal::{ + interrupt, + macros::interrupt, + peripherals::{self, TIMG1}, + prelude::*, + timer::{Timer, Timer0}, + trapframe::TrapFrame, + xtensa_lx, xtensa_lx_rt, + }, preempt::preempt::task_switch, - prelude::*, - timer::{Timer, Timer0}, - trapframe::TrapFrame, - xtensa_lx, xtensa_lx_rt, }; use atomic_polyfill::{AtomicU32, Ordering}; use critical_section::Mutex; -pub const TICKS_PER_SECOND: u64 = 40_000_000; +static TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); -pub const COUNTER_BIT_MASK: u64 = 0xFFFF_FFFF_FFFF_FFFF; +static TIMER_OVERFLOWS: AtomicU32 = AtomicU32::new(0); const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); -static TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); - -static TIMER_OVERFLOWS: AtomicU32 = AtomicU32::new(0); +pub const TICKS_PER_SECOND: u64 = 40_000_000; /// This function must not be called in a critical section. Doing so may return an incorrect value. pub fn get_systimer_count() -> u64 { @@ -41,25 +41,14 @@ pub fn get_systimer_count() -> u64 { (((overflow as u64) << 32) + counter_after as u64) * 40_000_000 / 240_000_000 } -pub fn setup_timer_isr(timg1_timer0: Timer>) { +pub fn setup_timer(timg1_timer0: Timer>) { let mut timer1 = timg1_timer0; + unwrap!(interrupt::enable( peripherals::Interrupt::TG1_T0_LEVEL, interrupt::Priority::Priority2, )); - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_PWR, - interrupt::Priority::Priority1, - )); - } - timer1.listen(); timer1.start(TIMER_DELAY.into_duration()); critical_section::with(|cs| { @@ -67,7 +56,9 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { }); xtensa_lx::timer::set_ccompare0(0xffffffff); +} +pub fn setup_multitasking() { unsafe { let enabled = xtensa_lx::interrupt::disable(); xtensa_lx::interrupt::enable_mask( @@ -89,37 +80,6 @@ fn Timer0(_level: u32) { xtensa_lx::timer::set_ccompare0(0xffffffff); } -#[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 = "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 crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - #[interrupt] fn TG1_T0_LEVEL(context: &mut TrapFrame) { task_switch(context); diff --git a/esp-wifi/src/timer_esp32.rs b/esp-wifi/src/timer_esp32.rs deleted file mode 100644 index ea128a5d..00000000 --- a/esp-wifi/src/timer_esp32.rs +++ /dev/null @@ -1,213 +0,0 @@ -use core::cell::RefCell; - -use crate::hal::{ - interrupt, - macros::interrupt, - peripherals::{self, TIMG1}, - preempt::preempt::task_switch, - prelude::*, - timer::{Timer, Timer0}, - trapframe::TrapFrame, - xtensa_lx, xtensa_lx_rt, -}; -use atomic_polyfill::{AtomicU32, Ordering}; -use critical_section::Mutex; - -pub const TICKS_PER_SECOND: u64 = 40_000_000; - -pub const COUNTER_BIT_MASK: u64 = 0xFFFF_FFFF_FFFF_FFFF; - -const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); - -static TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); - -static TIMER_OVERFLOWS: AtomicU32 = AtomicU32::new(0); - -/// This function must not be called in a critical section. Doing so may return an incorrect value. -pub fn get_systimer_count() -> u64 { - // We read the cycle counter twice to detect overflows. - // If we don't detect an overflow, we use the TIMER_OVERFLOWS count we read between. - // If we detect an overflow, we read the TIMER_OVERFLOWS count again to make sure we use the - // value after the overflow has been handled. - - let counter_before = xtensa_lx::timer::get_cycle_count(); - let mut overflow = TIMER_OVERFLOWS.load(Ordering::Relaxed); - let counter_after = xtensa_lx::timer::get_cycle_count(); - - if counter_after < counter_before { - overflow = TIMER_OVERFLOWS.load(Ordering::Relaxed); - } - - (((overflow as u64) << 32) + counter_after as u64) * 40_000_000 / 240_000_000 -} - -pub fn setup_timer_isr(timg1_timer0: Timer>) { - let mut timer1 = timg1_timer0; - unwrap!(interrupt::enable( - peripherals::Interrupt::TG1_T0_LEVEL, - interrupt::Priority::Priority2, - )); - - #[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); - } - - timer1.listen(); - timer1.start(TIMER_DELAY.into_duration()); - critical_section::with(|cs| { - TIMER1.borrow_ref_mut(cs).replace(timer1); - }); - - xtensa_lx::timer::set_ccompare0(0xffffffff); - - unsafe { - let enabled = xtensa_lx::interrupt::disable(); - xtensa_lx::interrupt::enable_mask( - 1 << 6 // Timer0 - | 1 << 29 // Software1 - | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level2.mask() - | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level6.mask() | enabled, - ); - } - - while unsafe { crate::preempt::FIRST_SWITCH.load(core::sync::atomic::Ordering::Relaxed) } {} -} - -#[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); - } - } -} - -#[allow(non_snake_case)] -#[no_mangle] -fn Timer0(_level: u32) { - TIMER_OVERFLOWS.fetch_add(1, Ordering::Relaxed); - - xtensa_lx::timer::set_ccompare0(0xffffffff); -} - -#[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); - } - } -} - -#[interrupt] -fn TG1_T0_LEVEL(context: &mut TrapFrame) { - task_switch(context); - - critical_section::with(|cs| { - crate::memory_fence::memory_fence(); - - let mut timer = TIMER1.borrow_ref_mut(cs); - let timer = unwrap!(timer.as_mut()); - timer.clear_interrupt(); - timer.start(TIMER_DELAY.into_duration()); - }); -} - -#[allow(non_snake_case)] -#[no_mangle] -fn Software1(_level: u32, context: &mut TrapFrame) { - let intr = 1 << 29; - unsafe { - core::arch::asm!("wsr.intclear {0}", in(reg) intr, options(nostack)); - } - - task_switch(context); - - critical_section::with(|cs| { - crate::memory_fence::memory_fence(); - - let mut timer = TIMER1.borrow_ref_mut(cs); - let timer = unwrap!(timer.as_mut()); - timer.clear_interrupt(); - timer.start(TIMER_DELAY.into_duration()); - }); -} - -pub fn yield_task() { - let intr = 1 << 29; - unsafe { - core::arch::asm!("wsr.intset {0}", in(reg) intr, options(nostack)); - } -} diff --git a/esp-wifi/src/timer_esp32s3.rs b/esp-wifi/src/timer_esp32s3.rs deleted file mode 100644 index b526dc4c..00000000 --- a/esp-wifi/src/timer_esp32s3.rs +++ /dev/null @@ -1,200 +0,0 @@ -use core::cell::RefCell; - -use crate::hal::{ - interrupt, - macros::interrupt, - peripherals::{self, TIMG1}, - preempt::preempt::task_switch, - prelude::*, - timer::{Timer, Timer0}, - trapframe::TrapFrame, - xtensa_lx, xtensa_lx_rt, -}; -use atomic_polyfill::{AtomicU32, Ordering}; -use critical_section::Mutex; - -pub const TICKS_PER_SECOND: u64 = 40_000_000; - -pub const COUNTER_BIT_MASK: u64 = 0xFFFF_FFFF_FFFF_FFFF; - -const TIMER_DELAY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); - -static TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); - -static TIMER_OVERFLOWS: AtomicU32 = AtomicU32::new(0); - -/// This function must not be called in a critical section. Doing so may return an incorrect value. -pub fn get_systimer_count() -> u64 { - // We read the cycle counter twice to detect overflows. - // If we don't detect an overflow, we use the TIMER_OVERFLOWS count we read between. - // If we detect an overflow, we read the TIMER_OVERFLOWS count again to make sure we use the - // value after the overflow has been handled. - - let counter_before = xtensa_lx::timer::get_cycle_count(); - let mut overflow = TIMER_OVERFLOWS.load(Ordering::Relaxed); - let counter_after = xtensa_lx::timer::get_cycle_count(); - - if counter_after < counter_before { - overflow = TIMER_OVERFLOWS.load(Ordering::Relaxed); - } - - (((overflow as u64) << 32) + counter_after as u64) * 40_000_000 / 240_000_000 -} - -pub fn setup_timer_isr(timg1_timer0: Timer>) { - let mut timer1 = timg1_timer0; - unwrap!(interrupt::enable( - peripherals::Interrupt::TG1_T0_LEVEL, - interrupt::Priority::Priority2, - )); - - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_PWR, - interrupt::Priority::Priority1, - )); - } - - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::BT_BB, - interrupt::Priority::Priority1, - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::RWBLE, - interrupt::Priority::Priority1, - )); - } - - timer1.listen(); - timer1.start(TIMER_DELAY.into_duration()); - critical_section::with(|cs| { - TIMER1.borrow_ref_mut(cs).replace(timer1); - }); - - xtensa_lx::timer::set_ccompare0(0xffffffff); - - unsafe { - let enabled = xtensa_lx::interrupt::disable(); - xtensa_lx::interrupt::enable_mask( - 1 << 6 // Timer0 - | 1 << 29 // Software1 - | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level2.mask() - | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level6.mask() | enabled, - ); - } - - while unsafe { crate::preempt::FIRST_SWITCH.load(core::sync::atomic::Ordering::Relaxed) } {} -} - -#[allow(non_snake_case)] -#[no_mangle] -fn Timer0(_level: u32) { - TIMER_OVERFLOWS.fetch_add(1, Ordering::Relaxed); - - xtensa_lx::timer::set_ccompare0(0xffffffff); -} - -#[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 = "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 crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "ble")] -#[interrupt] -fn RWBLE() { - critical_section::with(|_| 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() { - critical_section::with(|_| unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_8; - 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); - } - }); -} - -#[interrupt] -fn TG1_T0_LEVEL(context: &mut TrapFrame) { - task_switch(context); - - critical_section::with(|cs| { - crate::memory_fence::memory_fence(); - - let mut timer = TIMER1.borrow_ref_mut(cs); - let timer = unwrap!(timer.as_mut()); - timer.clear_interrupt(); - timer.start(TIMER_DELAY.into_duration()); - }); -} - -#[allow(non_snake_case)] -#[no_mangle] -fn Software1(_level: u32, context: &mut TrapFrame) { - let intr = 1 << 29; - unsafe { - core::arch::asm!("wsr.intclear {0}", in(reg) intr, options(nostack)); - } - - task_switch(context); - - critical_section::with(|cs| { - crate::memory_fence::memory_fence(); - - let mut timer = TIMER1.borrow_ref_mut(cs); - let timer = unwrap!(timer.as_mut()); - timer.clear_interrupt(); - timer.start(TIMER_DELAY.into_duration()); - }); -} - -pub fn yield_task() { - let intr = 1 << 29; - unsafe { - core::arch::asm!("wsr.intset {0}", in(reg) intr, options(nostack)); - } -} From 1f67e5e67ef32c4d7bee5ac3ec696aede98dbf32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 12 Oct 2023 15:41:44 +0200 Subject: [PATCH 3/4] Deduplicate time-based task switching --- esp-wifi/src/timer/xtensa.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/esp-wifi/src/timer/xtensa.rs b/esp-wifi/src/timer/xtensa.rs index dc024e40..a155c8a4 100644 --- a/esp-wifi/src/timer/xtensa.rs +++ b/esp-wifi/src/timer/xtensa.rs @@ -80,8 +80,7 @@ fn Timer0(_level: u32) { xtensa_lx::timer::set_ccompare0(0xffffffff); } -#[interrupt] -fn TG1_T0_LEVEL(context: &mut TrapFrame) { +fn do_task_switch(context: &mut TrapFrame) { task_switch(context); critical_section::with(|cs| { @@ -94,6 +93,11 @@ fn TG1_T0_LEVEL(context: &mut TrapFrame) { }); } +#[interrupt] +fn TG1_T0_LEVEL(context: &mut TrapFrame) { + do_task_switch(context); +} + #[allow(non_snake_case)] #[no_mangle] fn Software1(_level: u32, context: &mut TrapFrame) { @@ -102,16 +106,7 @@ fn Software1(_level: u32, context: &mut TrapFrame) { core::arch::asm!("wsr.intclear {0}", in(reg) intr, options(nostack)); } - task_switch(context); - - critical_section::with(|cs| { - crate::memory_fence::memory_fence(); - - let mut timer = TIMER1.borrow_ref_mut(cs); - let timer = unwrap!(timer.as_mut()); - timer.clear_interrupt(); - timer.start(TIMER_DELAY.into_duration()); - }); + do_task_switch(context); } pub fn yield_task() { From c48c69d5b80faddc90b3c382505519b035a14b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 12 Oct 2023 16:03:27 +0200 Subject: [PATCH 4/4] Extract common setup fn --- esp-wifi/src/timer/mod.rs | 9 +++++++++ esp-wifi/src/timer/riscv.rs | 5 +++-- esp-wifi/src/timer/timer_esp32.rs | 16 ++-------------- esp-wifi/src/timer/timer_esp32c2.rs | 17 ++--------------- esp-wifi/src/timer/timer_esp32c3.rs | 19 +++---------------- esp-wifi/src/timer/timer_esp32c6.rs | 15 +++------------ esp-wifi/src/timer/timer_esp32s2.rs | 21 +++------------------ esp-wifi/src/timer/timer_esp32s3.rs | 16 ++-------------- esp-wifi/src/timer/xtensa.rs | 11 ++++++----- 9 files changed, 33 insertions(+), 96 deletions(-) diff --git a/esp-wifi/src/timer/mod.rs b/esp-wifi/src/timer/mod.rs index 6d037f1b..2a30228b 100644 --- a/esp-wifi/src/timer/mod.rs +++ b/esp-wifi/src/timer/mod.rs @@ -10,4 +10,13 @@ mod chip_specific; #[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(); +} diff --git a/esp-wifi/src/timer/riscv.rs b/esp-wifi/src/timer/riscv.rs index 6e588a7f..c278fa0a 100644 --- a/esp-wifi/src/timer/riscv.rs +++ b/esp-wifi/src/timer/riscv.rs @@ -3,7 +3,6 @@ use core::cell::RefCell; use critical_section::Mutex; use crate::{ - binary, hal::{ interrupt::{self, TrapFrame}, peripherals::{self, Interrupt}, @@ -19,13 +18,15 @@ use peripherals::INTPRI as SystemPeripheral; #[cfg(not(feature = "esp32c6"))] use peripherals::SYSTEM as SystemPeripheral; +pub type TimeBase = Alarm; + 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>>> = Mutex::new(RefCell::new(None)); -pub fn setup_timer(systimer: Alarm) { +pub fn setup_timer(systimer: TimeBase) { let alarm0 = systimer.into_periodic(); alarm0.set_period(TIMER_DELAY.into()); alarm0.clear_interrupt(); diff --git a/esp-wifi/src/timer/timer_esp32.rs b/esp-wifi/src/timer/timer_esp32.rs index 0e357883..c2a4848e 100644 --- a/esp-wifi/src/timer/timer_esp32.rs +++ b/esp-wifi/src/timer/timer_esp32.rs @@ -1,14 +1,6 @@ -use crate::hal::{ - interrupt, - macros::interrupt, - peripherals::{self, TIMG1}, - timer::{Timer, Timer0}, -}; +use crate::hal::{interrupt, macros::interrupt, peripherals}; -pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; -use super::arch_specific::{setup_multitasking, setup_timer}; - -pub fn setup_timer_isr(timg1_timer0: Timer>) { +pub fn setup_radio_isr() { #[cfg(feature = "wifi")] unwrap!(interrupt::enable( peripherals::Interrupt::WIFI_MAC, @@ -31,10 +23,6 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::ETH_MAC); interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::UART0); } - - setup_timer(timg1_timer0); - - setup_multitasking(); } #[cfg(feature = "ble")] diff --git a/esp-wifi/src/timer/timer_esp32c2.rs b/esp-wifi/src/timer/timer_esp32c2.rs index 4308c103..6495ff6f 100644 --- a/esp-wifi/src/timer/timer_esp32c2.rs +++ b/esp-wifi/src/timer/timer_esp32c2.rs @@ -1,20 +1,9 @@ use crate::{ binary, - hal::{ - interrupt::{self, TrapFrame}, - peripherals::{self, Interrupt}, - prelude::*, - riscv, - systimer::{Alarm, Periodic, SystemTimer, Target}, - }, + hal::{interrupt, macros::interrupt, peripherals::Interrupt}, }; -pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; -use super::arch_specific::{setup_multitasking, setup_timer}; - -pub fn setup_timer_isr(systimer: Alarm) { - setup_timer(systimer); - +pub fn setup_radio_isr() { #[cfg(feature = "wifi")] { unwrap!(interrupt::enable( @@ -38,8 +27,6 @@ pub fn setup_timer_isr(systimer: Alarm) { interrupt::Priority::Priority1 )); } - - setup_multitasking(); } #[cfg(feature = "wifi")] diff --git a/esp-wifi/src/timer/timer_esp32c3.rs b/esp-wifi/src/timer/timer_esp32c3.rs index 5848d909..fffd55dc 100644 --- a/esp-wifi/src/timer/timer_esp32c3.rs +++ b/esp-wifi/src/timer/timer_esp32c3.rs @@ -1,20 +1,9 @@ use crate::{ binary, - hal::{ - interrupt::{self, TrapFrame}, - peripherals::{self, Interrupt}, - prelude::*, - riscv, - systimer::{Alarm, Periodic, SystemTimer, Target}, - }, + hal::{interrupt, macros::interrupt, peripherals::Interrupt}, }; -pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; -use super::arch_specific::{setup_multitasking, setup_timer}; - -pub fn setup_timer_isr(systimer: Alarm) { - setup_timer(systimer); - +pub fn setup_radio_isr() { #[cfg(feature = "wifi")] { unwrap!(interrupt::enable( @@ -42,8 +31,6 @@ pub fn setup_timer_isr(systimer: Alarm) { interrupt::Priority::Priority1 )); } - - setup_multitasking(); } #[cfg(feature = "wifi")] @@ -116,7 +103,7 @@ fn RWBLE() { #[cfg(feature = "ble")] #[interrupt] -fn BT_BB(_trap_frame: &mut TrapFrame) { +fn BT_BB(_trap_frame: &mut crate::hal::interrupt::TrapFrame) { unsafe { let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::BT_INTERRUPT_FUNCTION8; diff --git a/esp-wifi/src/timer/timer_esp32c6.rs b/esp-wifi/src/timer/timer_esp32c6.rs index 57727ede..2a033455 100644 --- a/esp-wifi/src/timer/timer_esp32c6.rs +++ b/esp-wifi/src/timer/timer_esp32c6.rs @@ -1,20 +1,13 @@ use crate::{ binary, hal::{ - interrupt::{self, TrapFrame}, + interrupt, + macros::interrupt, peripherals::{self, Interrupt}, - prelude::*, - riscv, - systimer::{Alarm, Periodic, SystemTimer, Target}, }, }; -pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; -use super::arch_specific::{setup_multitasking, setup_timer}; - -pub fn setup_timer_isr(systimer: Alarm) { - setup_timer(systimer); - +pub fn setup_radio_isr() { #[cfg(feature = "wifi")] { unwrap!(interrupt::enable( @@ -48,8 +41,6 @@ pub fn setup_timer_isr(systimer: Alarm) { interrupt::Priority::Priority1 )); } - - setup_multitasking(); } #[cfg(feature = "wifi")] diff --git a/esp-wifi/src/timer/timer_esp32s2.rs b/esp-wifi/src/timer/timer_esp32s2.rs index 971ac702..25708203 100644 --- a/esp-wifi/src/timer/timer_esp32s2.rs +++ b/esp-wifi/src/timer/timer_esp32s2.rs @@ -1,19 +1,6 @@ -use crate::hal::{ - interrupt, - macros::interrupt, - peripherals::{self, TIMG1}, - timer::{Timer, Timer0}, -}; - -pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; -use super::arch_specific::{setup_multitasking, setup_timer}; - -pub fn setup_timer_isr(timg1_timer0: Timer>) { - unwrap!(interrupt::enable( - peripherals::Interrupt::TG1_T0_LEVEL, - interrupt::Priority::Priority2, - )); +use crate::hal::{interrupt, macros::interrupt, peripherals}; +pub fn setup_radio_isr() { #[cfg(feature = "wifi")] { unwrap!(interrupt::enable( @@ -26,9 +13,7 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { )); } - setup_timer(timg1_timer0); - - setup_multitasking(); + // ble not supported } #[cfg(feature = "wifi")] diff --git a/esp-wifi/src/timer/timer_esp32s3.rs b/esp-wifi/src/timer/timer_esp32s3.rs index cc82f648..ade3bc62 100644 --- a/esp-wifi/src/timer/timer_esp32s3.rs +++ b/esp-wifi/src/timer/timer_esp32s3.rs @@ -1,14 +1,6 @@ -use crate::hal::{ - interrupt, - macros::interrupt, - peripherals::{self, TIMG1}, - timer::{Timer, Timer0}, -}; +use crate::hal::{interrupt, macros::interrupt, peripherals}; -pub use super::arch_specific::{get_systimer_count, yield_task, TICKS_PER_SECOND}; -use super::arch_specific::{setup_multitasking, setup_timer}; - -pub fn setup_timer_isr(timg1_timer0: Timer>) { +pub fn setup_radio_isr() { #[cfg(feature = "wifi")] { unwrap!(interrupt::enable( @@ -32,10 +24,6 @@ pub fn setup_timer_isr(timg1_timer0: Timer>) { interrupt::Priority::Priority1, )); } - - setup_timer(timg1_timer0); - - setup_multitasking(); } #[cfg(feature = "wifi")] diff --git a/esp-wifi/src/timer/xtensa.rs b/esp-wifi/src/timer/xtensa.rs index a155c8a4..afce7ad8 100644 --- a/esp-wifi/src/timer/xtensa.rs +++ b/esp-wifi/src/timer/xtensa.rs @@ -1,5 +1,7 @@ use core::cell::RefCell; +use critical_section::Mutex; + use crate::{ hal::{ interrupt, @@ -13,9 +15,10 @@ use crate::{ preempt::preempt::task_switch, }; use atomic_polyfill::{AtomicU32, Ordering}; -use critical_section::Mutex; -static TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); +pub type TimeBase = Timer>; + +static TIMER1: Mutex>> = Mutex::new(RefCell::new(None)); static TIMER_OVERFLOWS: AtomicU32 = AtomicU32::new(0); @@ -41,9 +44,7 @@ pub fn get_systimer_count() -> u64 { (((overflow as u64) << 32) + counter_after as u64) * 40_000_000 / 240_000_000 } -pub fn setup_timer(timg1_timer0: Timer>) { - let mut timer1 = timg1_timer0; - +pub fn setup_timer(mut timer1: TimeBase) { unwrap!(interrupt::enable( peripherals::Interrupt::TG1_T0_LEVEL, interrupt::Priority::Priority2,