Adding a way to deinitialize the WiFi stack. (#2187)
* WIP * cleanup * WIP (BLE) * WIP (BLE) * c2 ble deinit doesn't work with ble alone, works in coex (WIP) * fmt * cleanup * changelog entry changelog entry * WIP (do not check it) it's just to save things before weekend! * polishing, refactor * cleanup * lint * Addressing reviews * address reviews * utilize `EspWifiInitialization` in deinit * example -> description * reviews * reviews * fix memory leak + rebase * typo * fix * init -> initialize screwed up after rebase * make esp32c6/h2 buildable again * edit safety comment
This commit is contained in:
parent
00ad9b5eed
commit
a4fe5e6e63
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Added
|
||||
|
||||
- Added `have-strchr` feature to disable including `strchr` (#2096)
|
||||
- Adding a way to deinitialize the WiFi stack (#2187)
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -316,8 +316,15 @@ unsafe extern "C" fn task_create(
|
||||
1
|
||||
}
|
||||
|
||||
unsafe extern "C" fn task_delete(_task: *const ()) {
|
||||
todo!();
|
||||
unsafe extern "C" fn task_delete(task: *const ()) {
|
||||
trace!("task delete called for {:?}", task);
|
||||
|
||||
let task = if task.is_null() {
|
||||
crate::preempt::current_task()
|
||||
} else {
|
||||
task as *mut _
|
||||
};
|
||||
crate::preempt::schedule_task_deletion(task);
|
||||
}
|
||||
|
||||
#[ram]
|
||||
@ -514,6 +521,17 @@ pub(crate) fn ble_init() {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn ble_deinit() {
|
||||
extern "C" {
|
||||
fn btdm_controller_deinit();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
btdm_controller_deinit();
|
||||
crate::common_adapter::chip_specific::phy_disable();
|
||||
}
|
||||
}
|
||||
|
||||
static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256];
|
||||
static mut BLE_HCI_READ_DATA_INDEX: usize = 0;
|
||||
static mut BLE_HCI_READ_DATA_LEN: usize = 0;
|
||||
|
||||
@ -204,6 +204,15 @@ extern "C" {
|
||||
#[cfg(esp32c2)]
|
||||
pub(crate) fn ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
pub(crate) fn r_ble_controller_disable() -> i32;
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
pub(crate) fn r_ble_controller_deinit() -> i32;
|
||||
|
||||
#[cfg(esp32c2)]
|
||||
pub(crate) fn ble_controller_deinit() -> i32;
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
pub(crate) fn r_ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
|
||||
|
||||
@ -213,10 +222,14 @@ extern "C" {
|
||||
#[cfg(not(esp32c2))]
|
||||
pub(crate) fn r_ble_controller_enable(mode: u8) -> i32;
|
||||
|
||||
pub(crate) fn esp_unregister_ext_funcs();
|
||||
|
||||
pub(crate) fn esp_register_ext_funcs(funcs: *const ExtFuncsT) -> i32;
|
||||
|
||||
pub(crate) fn esp_register_npl_funcs(funcs: *const npl_funcs_t) -> i32;
|
||||
|
||||
pub(crate) fn esp_unregister_npl_funcs();
|
||||
|
||||
#[cfg(esp32c2)]
|
||||
pub(crate) fn ble_get_npl_element_info(
|
||||
cfg: *const esp_bt_controller_config_t,
|
||||
@ -406,8 +419,15 @@ unsafe extern "C" fn task_create(
|
||||
1
|
||||
}
|
||||
|
||||
unsafe extern "C" fn task_delete(_: *const c_void) {
|
||||
todo!();
|
||||
unsafe extern "C" fn task_delete(task: *const c_void) {
|
||||
trace!("task delete called for {:?}", task);
|
||||
|
||||
let task = if task.is_null() {
|
||||
crate::preempt::current_task()
|
||||
} else {
|
||||
task as *mut _
|
||||
};
|
||||
crate::preempt::schedule_task_deletion(task);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn osi_assert(ln: u32, fn_name: *const c_void, param1: u32, param2: u32) {
|
||||
@ -795,8 +815,18 @@ unsafe extern "C" fn ble_npl_event_reset(event: *const ble_npl_event) {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn ble_npl_event_deinit(_event: *const ble_npl_event) {
|
||||
todo!()
|
||||
unsafe extern "C" fn ble_npl_event_deinit(event: *const ble_npl_event) {
|
||||
trace!("ble_npl_event_deinit {:?}", event);
|
||||
|
||||
let event = event.cast_mut();
|
||||
|
||||
if (*event).dummy == 0 {
|
||||
panic!("Trying to deinitialize an uninitialized event");
|
||||
} else {
|
||||
let idx = ((*event).dummy - 1) as usize;
|
||||
EVENTS[idx] = None;
|
||||
(*event).dummy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn ble_npl_event_init(
|
||||
@ -908,8 +938,23 @@ unsafe extern "C" fn ble_npl_eventq_get(
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn ble_npl_eventq_deinit(_queue: *const ble_npl_eventq) {
|
||||
todo!()
|
||||
unsafe extern "C" fn ble_npl_eventq_deinit(queue: *const ble_npl_eventq) {
|
||||
trace!("ble_npl_eventq_deinit {:?}", queue);
|
||||
|
||||
let queue = queue.cast_mut();
|
||||
if (*queue).dummy == 0 {
|
||||
panic!("Trying to deinitialize an uninitialized queue");
|
||||
} else {
|
||||
critical_section::with(|_| {
|
||||
while let Some(event_idx) = EVENT_QUEUE.dequeue() {
|
||||
if let Some(event) = EVENTS[event_idx - 1].as_mut() {
|
||||
event.queued = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
(*queue).dummy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn ble_npl_callout_init(
|
||||
@ -1179,6 +1224,36 @@ pub(crate) fn ble_init() {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn ble_deinit() {
|
||||
unsafe {
|
||||
// HCI deinit
|
||||
npl::r_ble_hci_trans_cfg_hs(None, core::ptr::null(), None, core::ptr::null());
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
npl::r_ble_controller_disable();
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
let res = npl::r_ble_controller_deinit();
|
||||
|
||||
#[cfg(esp32c2)]
|
||||
let res = npl::ble_controller_deinit();
|
||||
|
||||
if res != 0 {
|
||||
panic!("ble_controller_deinit returned {}", res);
|
||||
}
|
||||
|
||||
npl::esp_unregister_npl_funcs();
|
||||
|
||||
npl::esp_unregister_ext_funcs();
|
||||
|
||||
crate::common_adapter::chip_specific::phy_disable();
|
||||
|
||||
CALLOUTS.iter_mut().for_each(|item| {
|
||||
item.take();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(esp32c2)]
|
||||
fn os_msys_buf_alloc() -> bool {
|
||||
unsafe {
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
use super::*;
|
||||
use crate::binary::include::esp_bt_controller_config_t;
|
||||
use crate::{
|
||||
binary::include::esp_bt_controller_config_t,
|
||||
hal::{interrupt, peripherals::Interrupt},
|
||||
};
|
||||
|
||||
pub static mut ISR_INTERRUPT_5: (
|
||||
*mut crate::binary::c_types::c_void,
|
||||
@ -292,13 +295,22 @@ pub(crate) fn create_ble_config() -> esp_bt_controller_config_t {
|
||||
|
||||
pub(crate) unsafe extern "C" fn interrupt_on(intr_num: i32) -> i32 {
|
||||
trace!("interrupt_on {}", intr_num);
|
||||
unwrap!(interrupt::enable(
|
||||
Interrupt::try_from(intr_num as u16).unwrap(),
|
||||
interrupt::Priority::Priority1,
|
||||
));
|
||||
|
||||
// NO-OP
|
||||
0
|
||||
}
|
||||
|
||||
pub(crate) unsafe extern "C" fn interrupt_off(_intr_num: i32) -> i32 {
|
||||
todo!();
|
||||
pub(crate) unsafe extern "C" fn interrupt_off(intr_num: i32) -> i32 {
|
||||
trace!("interrupt_off {}", intr_num);
|
||||
interrupt::disable(
|
||||
crate::hal::Cpu::ProCpu,
|
||||
Interrupt::try_from(intr_num as u16).unwrap(),
|
||||
);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub(crate) fn btdm_controller_mem_init() {
|
||||
|
||||
@ -39,6 +39,10 @@ pub(crate) fn init_radio_clock_control(rcc: hal::peripherals::RADIO_CLK) {
|
||||
unsafe { RADIO_CLOCKS = Some(rcc) };
|
||||
}
|
||||
|
||||
pub(crate) fn deinit_radio_clock_control() -> Option<hal::peripherals::RADIO_CLK> {
|
||||
unsafe { RADIO_CLOCKS.take() }
|
||||
}
|
||||
|
||||
/// **************************************************************************
|
||||
/// Name: esp_semphr_create
|
||||
///
|
||||
|
||||
@ -105,7 +105,12 @@ extern crate alloc;
|
||||
// MUST be the first module
|
||||
mod fmt;
|
||||
|
||||
use common_adapter::{chip_specific::phy_mem_init, init_radio_clock_control, RADIO_CLOCKS};
|
||||
use common_adapter::{
|
||||
chip_specific::phy_mem_init,
|
||||
deinit_radio_clock_control,
|
||||
init_radio_clock_control,
|
||||
RADIO_CLOCKS,
|
||||
};
|
||||
use esp_config::*;
|
||||
use esp_hal as hal;
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
@ -117,9 +122,18 @@ use hal::{
|
||||
timer::{timg::Timer as TimgTimer, AnyTimer, PeriodicTimer},
|
||||
};
|
||||
#[cfg(feature = "wifi")]
|
||||
use wifi::WifiError;
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
use crate::{common_adapter::init_rng, tasks::init_tasks, timer::setup_timer_isr};
|
||||
#[cfg(feature = "wifi")]
|
||||
use crate::{
|
||||
binary::include::{self, esp_supplicant_deinit, esp_wifi_deinit_internal, esp_wifi_stop},
|
||||
wifi::WifiError,
|
||||
};
|
||||
use crate::{
|
||||
common_adapter::init_rng,
|
||||
tasks::init_tasks,
|
||||
timer::{setup_timer_isr, shutdown_timer_isr},
|
||||
};
|
||||
|
||||
mod binary {
|
||||
pub use esp_wifi_sys::*;
|
||||
@ -396,14 +410,13 @@ pub fn initialize(
|
||||
}
|
||||
|
||||
info!("esp-wifi configuration {:?}", crate::CONFIG);
|
||||
|
||||
crate::common_adapter::chip_specific::enable_wifi_power_domain();
|
||||
|
||||
phy_mem_init();
|
||||
init_radio_clock_control(radio_clocks);
|
||||
init_rng(rng);
|
||||
init_tasks();
|
||||
setup_timer_isr(timer.timer())?;
|
||||
|
||||
wifi_set_log_verbose();
|
||||
init_clocks();
|
||||
|
||||
@ -441,15 +454,80 @@ pub fn initialize(
|
||||
}
|
||||
}
|
||||
|
||||
/// Deinitializes WiFi and/or BLE
|
||||
///
|
||||
/// After user calls this function, WiFi and/or BLE (depending on what has been
|
||||
/// initialized) are fully stopped and deinitialized. After that, they should
|
||||
/// not be used until they have been reinitialized with the `init` function.
|
||||
///
|
||||
/// The function also disables the corresponding interrupts, deinitializes
|
||||
/// the timer and radio clock, freeing these resources and returning them.
|
||||
///
|
||||
/// Calling this while still using WiFi/BLE will cause crashes or undefined
|
||||
/// behavior.
|
||||
///
|
||||
/// # Safety
|
||||
/// Actual implementation assumes that the user takes responsibility for how the
|
||||
/// function is used. For example, after using this function, user should not
|
||||
/// use BLE or WiFi stack or controller instances (it is possible to
|
||||
/// reinitialize communication using the `init` function), not to call
|
||||
/// `deinit_unsafe` before the first initialization, and so on. Also, there is
|
||||
/// currently no way to track whether a peripheral has been initialized,
|
||||
/// so deinitialization is done based on the activated feature (`wifi`, `ble`
|
||||
/// and/or `coex`).
|
||||
/// Before deinitializing, chips with NPL bluetooth (esp32c2, esp32c6, esp32h2)
|
||||
/// users must make sure to stop BLE advertising before.
|
||||
pub unsafe fn deinit_unchecked(
|
||||
init: EspWifiInitialization,
|
||||
) -> Result<(TimeBase, hal::peripherals::RADIO_CLK), InitializationError> {
|
||||
// Disable coexistence
|
||||
#[cfg(coex)]
|
||||
{
|
||||
unsafe { crate::wifi::os_adapter::coex_disable() };
|
||||
unsafe { crate::wifi::os_adapter::coex_deinit() };
|
||||
}
|
||||
|
||||
// Deinitialize WiFi
|
||||
#[cfg(feature = "wifi")]
|
||||
if init.is_wifi() {
|
||||
esp_wifi_result!(unsafe { esp_wifi_stop() })?;
|
||||
esp_wifi_result!(unsafe { esp_wifi_deinit_internal() })?;
|
||||
esp_wifi_result!(esp_supplicant_deinit())?;
|
||||
}
|
||||
|
||||
// Deinitialize BLE
|
||||
#[cfg(feature = "ble")]
|
||||
if init.is_ble() {
|
||||
#[cfg(any(esp32, esp32c3, esp32s3))]
|
||||
crate::ble::btdm::ble_deinit();
|
||||
|
||||
#[cfg(any(esp32c2, esp32c6, esp32h2))]
|
||||
crate::ble::npl::ble_deinit();
|
||||
}
|
||||
|
||||
shutdown_timer_isr().unwrap();
|
||||
crate::preempt::delete_all_tasks();
|
||||
|
||||
let timer = critical_section::with(|cs| crate::timer::TIMER.borrow_ref_mut(cs).take())
|
||||
.ok_or(InitializationError::TimerUnavailable)?;
|
||||
|
||||
let radio_clocks =
|
||||
deinit_radio_clock_control().ok_or(InitializationError::RadioClockUnavailable)?;
|
||||
|
||||
Ok((timer, radio_clocks))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
/// Error which can be returned during [`initialize`].
|
||||
/// Error which can be returned during [`init`].
|
||||
pub enum InitializationError {
|
||||
General(i32),
|
||||
#[cfg(feature = "wifi")]
|
||||
WifiError(WifiError),
|
||||
WrongClockConfig,
|
||||
Timer(hal::timer::Error),
|
||||
TimerUnavailable,
|
||||
RadioClockUnavailable,
|
||||
}
|
||||
|
||||
impl From<hal::timer::Error> for InitializationError {
|
||||
|
||||
@ -54,7 +54,7 @@ fn next_task() {
|
||||
/// Delete the given task.
|
||||
///
|
||||
/// This will also free the memory (stack and context) allocated for it.
|
||||
fn delete_task(task: *mut Context) {
|
||||
pub(crate) fn delete_task(task: *mut Context) {
|
||||
critical_section::with(|cs| unsafe {
|
||||
let mut ptr = *CTX_NOW.borrow_ref_mut(cs);
|
||||
let initial = ptr;
|
||||
@ -78,11 +78,40 @@ fn delete_task(task: *mut Context) {
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn delete_all_tasks() {
|
||||
critical_section::with(|cs| unsafe {
|
||||
let mut ctx_now_ref = CTX_NOW.borrow_ref_mut(cs);
|
||||
let current_task = *ctx_now_ref;
|
||||
|
||||
if current_task.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut task_to_delete = current_task;
|
||||
|
||||
loop {
|
||||
let next_task = (*task_to_delete).next;
|
||||
|
||||
free((*task_to_delete).allocated_stack as *mut u8);
|
||||
free(task_to_delete as *mut u8);
|
||||
|
||||
if next_task == current_task {
|
||||
break;
|
||||
}
|
||||
|
||||
task_to_delete = next_task;
|
||||
}
|
||||
|
||||
*ctx_now_ref = core::ptr::null_mut();
|
||||
|
||||
memory_fence();
|
||||
});
|
||||
}
|
||||
|
||||
pub fn current_task() -> *mut Context {
|
||||
critical_section::with(|cs| unsafe { *CTX_NOW.borrow_ref(cs) })
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
pub fn schedule_task_deletion(task: *mut Context) {
|
||||
use crate::timer::yield_task;
|
||||
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
|
||||
#[cfg_attr(esp32, path = "timer_esp32.rs")]
|
||||
#[cfg_attr(esp32c2, path = "timer_esp32c2.rs")]
|
||||
#[cfg_attr(esp32c3, path = "timer_esp32c3.rs")]
|
||||
@ -16,6 +20,8 @@ pub use chip_specific::*;
|
||||
|
||||
use crate::TimeBase;
|
||||
|
||||
pub(crate) static TIMER: Mutex<RefCell<Option<TimeBase>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
pub fn setup_timer_isr(timebase: TimeBase) -> Result<(), esp_hal::timer::Error> {
|
||||
setup_radio_isr();
|
||||
|
||||
@ -27,6 +33,15 @@ pub fn setup_timer_isr(timebase: TimeBase) -> Result<(), esp_hal::timer::Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn shutdown_timer_isr() -> Result<(), esp_hal::timer::Error> {
|
||||
shutdown_radio_isr();
|
||||
|
||||
disable_timer()?;
|
||||
|
||||
disable_multitasking();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn micros_to_ticks(us: u64) -> u64 {
|
||||
us * (TICKS_PER_SECOND / 1_000_000)
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp_hal::interrupt::InterruptHandler;
|
||||
#[cfg(any(feature = "esp32c6", feature = "esp32h2"))]
|
||||
use peripherals::INTPRI as SystemPeripheral;
|
||||
@ -18,13 +15,14 @@ use crate::{
|
||||
};
|
||||
|
||||
/// The timer responsible for time slicing.
|
||||
static ALARM0: Mutex<RefCell<Option<TimeBase>>> = Mutex::new(RefCell::new(None));
|
||||
const TIMESLICE_FREQUENCY: fugit::HertzU64 =
|
||||
fugit::HertzU64::from_raw(crate::CONFIG.tick_rate_hz as u64);
|
||||
|
||||
// Time keeping
|
||||
pub const TICKS_PER_SECOND: u64 = 1_000_000;
|
||||
|
||||
use super::TIMER;
|
||||
|
||||
pub fn setup_timer(mut alarm0: TimeBase) -> Result<(), esp_hal::timer::Error> {
|
||||
// make sure the scheduling won't start before everything is setup
|
||||
riscv::interrupt::disable();
|
||||
@ -34,7 +32,16 @@ pub fn setup_timer(mut alarm0: TimeBase) -> Result<(), esp_hal::timer::Error> {
|
||||
alarm0.start(TIMESLICE_FREQUENCY.into_duration())?;
|
||||
critical_section::with(|cs| {
|
||||
alarm0.enable_interrupt(true);
|
||||
ALARM0.borrow_ref_mut(cs).replace(alarm0);
|
||||
TIMER.borrow_ref_mut(cs).replace(alarm0);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn disable_timer() -> Result<(), esp_hal::timer::Error> {
|
||||
critical_section::with(|cs| {
|
||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
|
||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel().unwrap();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -51,10 +58,14 @@ pub fn setup_multitasking() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disable_multitasking() {
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::FROM_CPU_INTR3);
|
||||
}
|
||||
|
||||
extern "C" fn handler(trap_frame: &mut TrapFrame) {
|
||||
// clear the systimer intr
|
||||
critical_section::with(|cs| {
|
||||
unwrap!(ALARM0.borrow_ref_mut(cs).as_mut()).clear_interrupt();
|
||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).clear_interrupt();
|
||||
});
|
||||
|
||||
task_switch(trap_frame);
|
||||
@ -70,7 +81,7 @@ extern "C" fn FROM_CPU_INTR3(trap_frame: &mut TrapFrame) {
|
||||
}
|
||||
|
||||
critical_section::with(|cs| {
|
||||
let mut alarm0 = ALARM0.borrow_ref_mut(cs);
|
||||
let mut alarm0 = TIMER.borrow_ref_mut(cs);
|
||||
let alarm0 = unwrap!(alarm0.as_mut());
|
||||
alarm0.clear_interrupt();
|
||||
});
|
||||
|
||||
@ -22,6 +22,14 @@ pub fn setup_radio_isr() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::RWBT);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::BT_BB);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ble")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
|
||||
@ -20,6 +20,14 @@ pub fn setup_radio_isr() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::LP_TIMER);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::BT_MAC);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
#[no_mangle]
|
||||
extern "C" fn WIFI_MAC() {
|
||||
|
||||
@ -24,6 +24,15 @@ pub fn setup_radio_isr() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::RWBT);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::RWBLE);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::BT_BB);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
#[no_mangle]
|
||||
extern "C" fn WIFI_MAC() {
|
||||
|
||||
@ -33,6 +33,14 @@ pub fn setup_radio_isr() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::LP_TIMER);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::BT_MAC);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
#[no_mangle]
|
||||
extern "C" fn WIFI_MAC() {
|
||||
|
||||
@ -18,6 +18,14 @@ pub fn setup_radio_isr() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::LP_BLE_TIMER);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::BT_MAC);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ble")]
|
||||
#[no_mangle]
|
||||
extern "C" fn LP_BLE_TIMER() {
|
||||
|
||||
@ -7,6 +7,10 @@ pub fn setup_radio_isr() {
|
||||
// ble not supported
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
// ble not supported
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
#[no_mangle]
|
||||
extern "C" fn WIFI_MAC() {
|
||||
|
||||
@ -1,22 +1,30 @@
|
||||
#[cfg(any(feature = "wifi", feature = "ble"))]
|
||||
#[allow(unused_imports)]
|
||||
use crate::hal::{interrupt, peripherals};
|
||||
use crate::hal::{interrupt, peripherals::Interrupt};
|
||||
|
||||
pub fn setup_radio_isr() {
|
||||
// wifi enabled in set_isr
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
unwrap!(interrupt::enable(
|
||||
peripherals::Interrupt::BT_BB,
|
||||
Interrupt::BT_BB,
|
||||
interrupt::Priority::Priority1,
|
||||
));
|
||||
unwrap!(interrupt::enable(
|
||||
peripherals::Interrupt::RWBLE,
|
||||
Interrupt::RWBLE,
|
||||
interrupt::Priority::Priority1,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown_radio_isr() {
|
||||
#[cfg(feature = "ble")]
|
||||
{
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::BT_BB);
|
||||
interrupt::disable(crate::hal::Cpu::ProCpu, Interrupt::RWBLE);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
#[no_mangle]
|
||||
extern "C" fn WIFI_MAC() {
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp_hal::interrupt::InterruptHandler;
|
||||
|
||||
use crate::{
|
||||
@ -10,10 +7,11 @@ use crate::{
|
||||
};
|
||||
|
||||
/// The timer responsible for time slicing.
|
||||
static TIMER1: Mutex<RefCell<Option<TimeBase>>> = Mutex::new(RefCell::new(None));
|
||||
const TIMESLICE_FREQUENCY: fugit::HertzU64 =
|
||||
fugit::HertzU64::from_raw(crate::CONFIG.tick_rate_hz as u64);
|
||||
|
||||
use super::TIMER;
|
||||
|
||||
// Time keeping
|
||||
pub const TICKS_PER_SECOND: u64 = 1_000_000;
|
||||
|
||||
@ -31,11 +29,20 @@ pub fn setup_timer(mut timer1: TimeBase) -> Result<(), esp_hal::timer::Error> {
|
||||
timer1.start(TIMESLICE_FREQUENCY.into_duration())?;
|
||||
critical_section::with(|cs| {
|
||||
timer1.enable_interrupt(true);
|
||||
TIMER1.borrow_ref_mut(cs).replace(timer1);
|
||||
TIMER.borrow_ref_mut(cs).replace(timer1);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn disable_timer() -> Result<(), esp_hal::timer::Error> {
|
||||
critical_section::with(|cs| {
|
||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
|
||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel().unwrap();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn setup_multitasking() {
|
||||
unsafe {
|
||||
let enabled = xtensa_lx::interrupt::disable();
|
||||
@ -47,9 +54,15 @@ pub fn setup_multitasking() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disable_multitasking() {
|
||||
xtensa_lx::interrupt::disable_mask(
|
||||
1 << 29, // Disable Software1
|
||||
);
|
||||
}
|
||||
|
||||
fn do_task_switch(context: &mut TrapFrame) {
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER1.borrow_ref_mut(cs);
|
||||
let mut timer = TIMER.borrow_ref_mut(cs);
|
||||
let timer = unwrap!(timer.as_mut());
|
||||
timer.clear_interrupt();
|
||||
});
|
||||
|
||||
@ -1704,7 +1704,10 @@ pub unsafe extern "C" fn wifi_delete_queue(queue: *mut crate::binary::c_types::c
|
||||
///
|
||||
/// *************************************************************************
|
||||
pub unsafe extern "C" fn coex_deinit() {
|
||||
warn!("coex_deinit - not implemented");
|
||||
trace!("coex_deinit");
|
||||
|
||||
#[cfg(coex)]
|
||||
crate::binary::include::coex_deinit();
|
||||
}
|
||||
|
||||
/// **************************************************************************
|
||||
|
||||
@ -53,10 +53,10 @@ fn main() -> ! {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let wifi = peripherals.WIFI;
|
||||
let mut wifi = peripherals.WIFI;
|
||||
let mut socket_set_entries: [SocketStorage; 3] = Default::default();
|
||||
let (iface, device, mut controller, sockets) =
|
||||
create_network_interface(&init, wifi, WifiApDevice, &mut socket_set_entries).unwrap();
|
||||
create_network_interface(&init, &mut wifi, WifiApDevice, &mut socket_set_entries).unwrap();
|
||||
let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
|
||||
|
||||
let client_config = Configuration::AccessPoint(AccessPointConfiguration {
|
||||
|
||||
@ -72,10 +72,10 @@ fn main() -> ! {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let wifi = peripherals.WIFI;
|
||||
let mut wifi = peripherals.WIFI;
|
||||
let mut socket_set_entries: [SocketStorage; 3] = Default::default();
|
||||
let (iface, device, mut controller, sockets) =
|
||||
create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
create_network_interface(&init, &mut wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
|
||||
|
||||
let client_config = Configuration::Client(ClientConfiguration {
|
||||
|
||||
@ -84,12 +84,12 @@ fn main() -> ! {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let wifi = peripherals.WIFI;
|
||||
let mut wifi = peripherals.WIFI;
|
||||
let bluetooth = peripherals.BT;
|
||||
|
||||
let mut socket_set_entries: [SocketStorage; 2] = Default::default();
|
||||
let (iface, device, mut controller, sockets) =
|
||||
create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
create_network_interface(&init, &mut wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
|
||||
|
||||
let client_config = Configuration::Client(ClientConfiguration {
|
||||
|
||||
@ -61,10 +61,10 @@ fn main() -> ! {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let wifi = peripherals.WIFI;
|
||||
let mut wifi = peripherals.WIFI;
|
||||
let mut socket_set_entries: [SocketStorage; 3] = Default::default();
|
||||
let (iface, device, mut controller, sockets) =
|
||||
create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
create_network_interface(&init, &mut wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
|
||||
|
||||
let client_config = Configuration::Client(ClientConfiguration {
|
||||
|
||||
@ -59,10 +59,10 @@ fn main() -> ! {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let wifi = peripherals.WIFI;
|
||||
let mut wifi = peripherals.WIFI;
|
||||
let mut socket_set_entries: [SocketStorage; 3] = Default::default();
|
||||
let (iface, device, mut controller, sockets) =
|
||||
create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
create_network_interface(&init, &mut wifi, WifiStaDevice, &mut socket_set_entries).unwrap();
|
||||
let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
|
||||
|
||||
let client_config = Configuration::Client(ClientConfiguration {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user