esp-hal/hil-test/tests/esp_wifi_floats.rs
Kirill Mikhailov 8d948ba017
Mark unstable modules, make macros private (#2900)
* Mark unstable APIs + make `macros` private

* address reviews

* use `instability` instead of feature

* fix dependencies

* More tagging

* `Persistable` and `procmacros` - unstable

* Adjust for changes

* sure...
2025-01-10 14:32:34 +00:00

183 lines
5.4 KiB
Rust

//! Cp0Disable exception regression test
//% CHIPS: esp32 esp32s2 esp32s3
//% FEATURES: unstable esp-wifi esp-alloc
#![no_std]
#![no_main]
use core::cell::RefCell;
use critical_section::Mutex;
use esp_hal::{
clock::CpuClock,
delay::Delay,
handler,
interrupt::software::{SoftwareInterrupt, SoftwareInterruptControl},
peripherals::Peripherals,
rng::Rng,
timer::timg::TimerGroup,
};
use hil_test as _;
#[inline(never)]
fn run_float_calc(x: f32) -> f32 {
let result = core::hint::black_box(x) * 2.0;
defmt::info!("{}", defmt::Display2Format(&result));
result
}
static SWINT0: Mutex<RefCell<Option<SoftwareInterrupt<0>>>> = Mutex::new(RefCell::new(None));
#[handler]
fn wait() {
// Ensure esp-wifi interrupts this handler.
Delay::new().delay_millis(100);
critical_section::with(|cs| {
SWINT0.borrow_ref(cs).as_ref().unwrap().reset();
});
}
cfg_if::cfg_if! {
if #[cfg(multi_core)] {
use core::sync::atomic::{AtomicBool, Ordering};
use esp_hal::cpu_control::CpuControl;
static DONE: AtomicBool = AtomicBool::new(false);
static mut APP_CORE_STACK: esp_hal::cpu_control::Stack<8192> =
esp_hal::cpu_control::Stack::new();
}
}
#[cfg(test)]
#[embedded_test::tests(default_timeout = 3)]
mod tests {
use super::*;
#[init]
fn test_init() -> Peripherals {
esp_alloc::heap_allocator!(72 * 1024);
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
esp_hal::init(config)
}
#[test]
fn fpu_is_enabled() {
let result = super::run_float_calc(2.0);
assert_eq!(result, 4.0);
}
#[cfg(multi_core)]
#[test]
fn fpu_is_enabled_on_core1(peripherals: Peripherals) {
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
let _guard = cpu_control
.start_app_core(
unsafe { &mut *core::ptr::addr_of_mut!(APP_CORE_STACK) },
|| {
let result = super::run_float_calc(2.0);
assert_eq!(result, 4.0);
DONE.store(true, Ordering::Relaxed);
loop {}
},
)
.unwrap();
core::mem::forget(_guard);
while !DONE.load(Ordering::Relaxed) {}
let result = super::run_float_calc(2.0);
assert_eq!(result, 4.0);
}
#[test]
fn fpu_stays_enabled_with_wifi(peripherals: Peripherals) {
let timg0 = TimerGroup::new(peripherals.TIMG0);
let _init = esp_wifi::init(
timg0.timer1,
Rng::new(peripherals.RNG),
peripherals.RADIO_CLK,
)
.unwrap();
let mut sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
critical_section::with(|cs| {
sw_ints.software_interrupt0.set_interrupt_handler(wait);
SWINT0
.borrow_ref_mut(cs)
.replace(sw_ints.software_interrupt0);
// Fire a low-priority interrupt to ensure the FPU is disabled while
// esp-wifi switches tasks
SWINT0.borrow_ref(cs).as_ref().unwrap().raise();
});
Delay::new().delay_millis(100);
let result = super::run_float_calc(2.0);
assert_eq!(result, 4.0);
}
#[cfg(multi_core)]
#[test]
fn fpu_stays_enabled_with_wifi_on_core1(peripherals: Peripherals) {
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
let _guard = cpu_control
.start_app_core(
unsafe { &mut *core::ptr::addr_of_mut!(APP_CORE_STACK) },
move || {
let timg0 = TimerGroup::new(peripherals.TIMG0);
let _init = esp_wifi::init(
timg0.timer1,
Rng::new(peripherals.RNG),
peripherals.RADIO_CLK,
)
.unwrap();
let mut sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
critical_section::with(|cs| {
sw_ints.software_interrupt0.set_interrupt_handler(wait);
SWINT0
.borrow_ref_mut(cs)
.replace(sw_ints.software_interrupt0);
// Fire a low-priority interrupt to ensure the FPU is disabled while
// esp-wifi switches tasks
SWINT0.borrow_ref(cs).as_ref().unwrap().raise();
});
Delay::new().delay_millis(100);
let result = super::run_float_calc(2.0);
assert_eq!(result, 4.0);
DONE.store(true, Ordering::Relaxed);
loop {}
},
)
.unwrap();
core::mem::forget(_guard);
while !DONE.load(Ordering::Relaxed) {}
let result = super::run_float_calc(2.0);
assert_eq!(result, 4.0);
}
}
// Here is a random test that doesn't fit anywhere else - and since it's alone,
// creating a new test suite is not necessary as we don't want to flash/run
// anything.
#[allow(unused)] // compile test
fn esp_wifi_can_be_initialized_with_any_timer(
timer: esp_hal::timer::AnyTimer,
rng: esp_hal::rng::Rng,
radio_clocks: esp_hal::peripherals::RADIO_CLK,
) {
esp_wifi::init(timer, rng, radio_clocks);
}