diff --git a/esp-wifi/src/ble/btdm.rs b/esp-wifi/src/ble/btdm.rs index 3c8a90d43cd..dc6436bf32a 100644 --- a/esp-wifi/src/ble/btdm.rs +++ b/esp-wifi/src/ble/btdm.rs @@ -519,6 +519,7 @@ pub(crate) fn ble_init() { API_vhci_host_register_callback(&VHCI_HOST_CALLBACK); } + crate::flags::BLE.store(true, Ordering::Release); } pub(crate) fn ble_deinit() { @@ -530,6 +531,7 @@ pub(crate) fn ble_deinit() { btdm_controller_deinit(); crate::common_adapter::chip_specific::phy_disable(); } + crate::flags::BLE.store(false, Ordering::Release); } static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256]; diff --git a/esp-wifi/src/ble/controller/mod.rs b/esp-wifi/src/ble/controller/mod.rs index 9ca3cc76177..2eeced9ecb1 100644 --- a/esp-wifi/src/ble/controller/mod.rs +++ b/esp-wifi/src/ble/controller/mod.rs @@ -3,7 +3,7 @@ use embedded_io::{Error, ErrorType, Read, Write}; use super::{read_hci, read_next, send_hci}; use crate::{ hal::peripheral::{Peripheral, PeripheralRef}, - EspWifiInitialization, + EspWifiController, }; /// A blocking HCI connector @@ -11,14 +11,18 @@ pub struct BleConnector<'d> { _device: PeripheralRef<'d, crate::hal::peripherals::BT>, } +impl<'d> Drop for BleConnector<'d> { + fn drop(&mut self) { + crate::ble::ble_deinit(); + } +} + impl<'d> BleConnector<'d> { pub fn new( - init: &EspWifiInitialization, + _init: &'d EspWifiController<'d>, device: impl Peripheral

+ 'd, ) -> BleConnector<'d> { - if !init.is_ble() { - panic!("Not initialized for BLE use"); - } + crate::ble::ble_init(); Self { _device: device.into_ref(), @@ -113,7 +117,7 @@ pub mod asynch { impl<'d> BleConnector<'d> { pub fn new( - init: &EspWifiInitialization, + init: &'d EspWifiController<'d>, device: impl Peripheral

+ 'd, ) -> BleConnector<'d> { if !init.is_ble() { diff --git a/esp-wifi/src/ble/mod.rs b/esp-wifi/src/ble/mod.rs index bf26fc3d913..54f47383b85 100644 --- a/esp-wifi/src/ble/mod.rs +++ b/esp-wifi/src/ble/mod.rs @@ -8,7 +8,7 @@ pub(crate) mod npl; use core::mem::MaybeUninit; -pub(crate) use ble::{ble_init, read_hci, read_next, send_hci}; +pub(crate) use ble::{ble_deinit, ble_init, read_hci, read_next, send_hci}; #[cfg(any(esp32, esp32c3, esp32s3))] use self::btdm as ble; diff --git a/esp-wifi/src/ble/npl.rs b/esp-wifi/src/ble/npl.rs index 8deaadc5bc3..ecd9463eba2 100644 --- a/esp-wifi/src/ble/npl.rs +++ b/esp-wifi/src/ble/npl.rs @@ -1222,6 +1222,7 @@ pub(crate) fn ble_init() { debug!("The ble_controller_init was initialized"); } + crate::flags::BLE.store(true, Ordering::Release); } pub(crate) fn ble_deinit() { @@ -1252,6 +1253,7 @@ pub(crate) fn ble_deinit() { item.take(); }); } + crate::flags::BLE.store(false, Ordering::Release); } #[cfg(esp32c2)] diff --git a/esp-wifi/src/esp_now/mod.rs b/esp-wifi/src/esp_now/mod.rs index 5099fe78cd4..15317534d81 100644 --- a/esp-wifi/src/esp_now/mod.rs +++ b/esp-wifi/src/esp_now/mod.rs @@ -612,7 +612,7 @@ pub struct EspNow<'d> { impl<'d> EspNow<'d> { /// Creates an `EspNow` instance. pub fn new( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl Peripheral

+ 'd, ) -> Result, EspNowError> { EspNow::new_internal(inited, Some(device.into_ref())) @@ -620,7 +620,7 @@ impl<'d> EspNow<'d> { /// Creates an `EspNow` instance with support for Wi-Fi coexistence. pub fn new_with_wifi( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, _token: EspNowWithWifiCreateToken, ) -> Result, EspNowError> { EspNow::new_internal( @@ -630,7 +630,7 @@ impl<'d> EspNow<'d> { } fn new_internal( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: Option>, ) -> Result, EspNowError> { if !inited.is_wifi() { diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index 55d60a9c3fa..674763c3c7c 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -93,6 +93,8 @@ extern crate alloc; // MUST be the first module mod fmt; +use core::marker::PhantomData; + use common_adapter::{ chip_specific::phy_mem_init, deinit_radio_clock_control, @@ -101,6 +103,7 @@ use common_adapter::{ }; use esp_config::*; use esp_hal as hal; +use esp_hal::peripheral::Peripheral; #[cfg(not(feature = "esp32"))] use esp_hal::timer::systimer::Alarm; use fugit::MegahertzU32; @@ -109,14 +112,10 @@ use hal::{ system::RadioClockController, timer::{timg::Timer as TimgTimer, AnyTimer, PeriodicTimer}, }; -#[cfg(feature = "wifi")] -use num_traits::FromPrimitive; +use portable_atomic::Ordering; #[cfg(feature = "wifi")] -use crate::{ - binary::include::{self, esp_supplicant_deinit, esp_wifi_deinit_internal, esp_wifi_stop}, - wifi::WifiError, -}; +use crate::wifi::WifiError; use crate::{ common_adapter::init_rng, tasks::init_tasks, @@ -239,73 +238,47 @@ const _: () = { type TimeBase = PeriodicTimer<'static, AnyTimer>; -#[derive(Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[non_exhaustive] -/// An internal struct designed to make [`EspWifiInitialization`] uncreatable -/// outside of this crate. -pub struct EspWifiInitializationInternal; +pub(crate) mod flags { + use portable_atomic::AtomicBool; + + pub(crate) static INITD: AtomicBool = AtomicBool::new(false); + pub(crate) static WIFI: AtomicBool = AtomicBool::new(false); + pub(crate) static BLE: AtomicBool = AtomicBool::new(false); +} #[derive(Debug, PartialEq, PartialOrd)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Initialized the driver for WiFi, Bluetooth or both. -pub enum EspWifiInitialization { - #[cfg(feature = "wifi")] - Wifi(EspWifiInitializationInternal), - #[cfg(feature = "ble")] - Ble(EspWifiInitializationInternal), - #[cfg(coex)] - WifiBle(EspWifiInitializationInternal), +pub struct EspWifiController<'d> { + _inner: PhantomData<&'d ()>, } -impl EspWifiInitialization { - #[allow(unused)] - fn is_wifi(&self) -> bool { - match self { - #[cfg(feature = "ble")] - EspWifiInitialization::Ble(_) => false, - _ => true, - } +impl<'d> EspWifiController<'d> { + /// Is the WiFi part of the radio running + pub fn wifi(&self) -> bool { + crate::flags::WIFI.load(Ordering::Acquire) } - #[allow(unused)] - fn is_ble(&self) -> bool { - match self { - #[cfg(feature = "wifi")] - EspWifiInitialization::Wifi(_) => false, - _ => true, - } + /// Is the BLE part of the radio running + pub fn ble(&self) -> bool { + crate::flags::BLE.load(Ordering::Acquire) } -} - -#[derive(Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Initialize the driver for WiFi, Bluetooth or both. -pub enum EspWifiInitFor { - #[cfg(feature = "wifi")] - Wifi, - #[cfg(feature = "ble")] - Ble, - #[cfg(coex)] - WifiBle, -} -impl EspWifiInitFor { - #[allow(unused)] - fn is_wifi(&self) -> bool { - match self { - #[cfg(feature = "ble")] - EspWifiInitFor::Ble => false, - _ => true, + /// De-initialize the radio + pub fn deinit(self) -> Result<(), InitializationError> { + if crate::flags::INITD.load(Ordering::Acquire) { + // safety: no other driver can be using this if this is callable + unsafe { deinit_unchecked() } + } else { + Ok(()) } } +} - #[allow(unused)] - fn is_ble(&self) -> bool { - match self { - #[cfg(feature = "wifi")] - EspWifiInitFor::Wifi => false, - _ => true, +impl<'d> Drop for EspWifiController<'d> { + fn drop(&mut self) { + if crate::flags::INITD.load(Ordering::Acquire) { + // safety: no other driver can be using this if this is callable + unsafe { deinit_unchecked().ok() }; } } } @@ -386,12 +359,11 @@ impl EspWifiTimerSource for TimeBase { /// .unwrap(); /// # } /// ``` -pub fn init( - init_for: EspWifiInitFor, - timer: impl EspWifiTimerSource, +pub fn init<'d, T: EspWifiTimerSource>( + mut timer: impl Peripheral

+ 'd, rng: hal::rng::Rng, - radio_clocks: hal::peripherals::RADIO_CLK, -) -> Result { + _radio_clocks: impl Peripheral

+ 'd, +) -> Result, InitializationError> { // A minimum clock of 80MHz is required to operate WiFi module. const MIN_CLOCK: u32 = 80; let clocks = Clocks::get(); @@ -402,10 +374,10 @@ pub fn init( 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_radio_clock_control(unsafe { hal::peripherals::RADIO_CLK::steal() }); init_rng(rng); init_tasks(); - setup_timer_isr(timer.timer())?; + setup_timer_isr(unsafe { timer.clone_unchecked() }.timer()); wifi_set_log_verbose(); init_clocks(); @@ -416,60 +388,23 @@ pub fn init( error => return Err(InitializationError::General(error)), } - #[cfg(feature = "wifi")] - if init_for.is_wifi() { - debug!("wifi init"); - // wifi init - crate::wifi::wifi_init()?; - } - - #[cfg(feature = "ble")] - if init_for.is_ble() { - // ble init - // for some reason things don't work when initializing things the other way - // around while the original implementation in NuttX does it like that - debug!("ble init"); - crate::ble::ble_init(); - } + crate::flags::INITD.store(true, Ordering::Release); - match init_for { - #[cfg(feature = "wifi")] - EspWifiInitFor::Wifi => Ok(EspWifiInitialization::Wifi(EspWifiInitializationInternal)), - #[cfg(feature = "ble")] - EspWifiInitFor::Ble => Ok(EspWifiInitialization::Ble(EspWifiInitializationInternal)), - #[cfg(coex)] - EspWifiInitFor::WifiBle => Ok(EspWifiInitialization::WifiBle( - EspWifiInitializationInternal, - )), - } + Ok(EspWifiController { + _inner: PhantomData, + }) } -/// 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. +/// Deinitializes the entire radio stack /// -/// Calling this while still using WiFi/BLE will cause crashes or undefined -/// behavior. +/// This can be useful to shutdown the stack before going to sleep for example. /// /// # 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> { +/// +/// The user must ensure that any use of the radio via the WIFI/BLE/ESP-NOW +/// drivers are complete, else undefined behavour may occur within those +/// drivers. +pub unsafe fn deinit_unchecked() -> Result<(), InitializationError> { // Disable coexistence #[cfg(coex)] { @@ -477,34 +412,16 @@ pub unsafe fn deinit_unchecked( 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(); + shutdown_timer_isr(); crate::preempt::delete_all_tasks(); - let timer = critical_section::with(|cs| crate::timer::TIMER.borrow_ref_mut(cs).take()) - .ok_or(InitializationError::TimerUnavailable)?; + critical_section::with(|cs| crate::timer::TIMER.borrow_ref_mut(cs).take()); - let radio_clocks = - deinit_radio_clock_control().ok_or(InitializationError::RadioClockUnavailable)?; + deinit_radio_clock_control(); - Ok((timer, radio_clocks)) + crate::flags::INITD.store(false, Ordering::Release); + + Ok(()) } #[derive(Debug, Clone, Copy)] @@ -515,15 +432,6 @@ pub enum InitializationError { #[cfg(feature = "wifi")] WifiError(WifiError), WrongClockConfig, - Timer(hal::timer::Error), - TimerUnavailable, - RadioClockUnavailable, -} - -impl From for InitializationError { - fn from(value: hal::timer::Error) -> Self { - InitializationError::Timer(value) - } } #[cfg(feature = "wifi")] diff --git a/esp-wifi/src/timer/mod.rs b/esp-wifi/src/timer/mod.rs index f6531158ac9..d806fd9111a 100644 --- a/esp-wifi/src/timer/mod.rs +++ b/esp-wifi/src/timer/mod.rs @@ -22,24 +22,22 @@ use crate::TimeBase; pub(crate) static TIMER: Mutex>> = Mutex::new(RefCell::new(None)); -pub(crate) fn setup_timer_isr(timebase: TimeBase) -> Result<(), esp_hal::timer::Error> { +pub(crate) fn setup_timer_isr(timebase: TimeBase) { setup_radio_isr(); - setup_timer(timebase)?; + setup_timer(timebase); setup_multitasking(); yield_task(); - Ok(()) } -pub(crate) fn shutdown_timer_isr() -> Result<(), esp_hal::timer::Error> { +pub(crate) fn shutdown_timer_isr() { shutdown_radio_isr(); - disable_timer()?; + disable_timer(); disable_multitasking(); - Ok(()) } #[allow(unused)] diff --git a/esp-wifi/src/timer/riscv.rs b/esp-wifi/src/timer/riscv.rs index 46eafa16220..c8a499e5fe8 100644 --- a/esp-wifi/src/timer/riscv.rs +++ b/esp-wifi/src/timer/riscv.rs @@ -23,28 +23,24 @@ pub const TICKS_PER_SECOND: u64 = 1_000_000; use super::TIMER; -pub(crate) fn setup_timer(mut alarm0: TimeBase) -> Result<(), esp_hal::timer::Error> { +pub(crate) fn setup_timer(mut alarm0: TimeBase) { // make sure the scheduling won't start before everything is setup riscv::interrupt::disable(); let cb: extern "C" fn() = unsafe { core::mem::transmute(handler as *const ()) }; alarm0.set_interrupt_handler(InterruptHandler::new(cb, interrupt::Priority::Priority1)); - alarm0.start(TIMESLICE_FREQUENCY.into_duration())?; + alarm0.start(TIMESLICE_FREQUENCY.into_duration()).unwrap(); critical_section::with(|cs| { alarm0.enable_interrupt(true); TIMER.borrow_ref_mut(cs).replace(alarm0); }); - - Ok(()) } -pub(crate) fn disable_timer() -> Result<(), esp_hal::timer::Error> { +pub(crate) fn disable_timer() { 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(crate) fn setup_multitasking() { diff --git a/esp-wifi/src/timer/xtensa.rs b/esp-wifi/src/timer/xtensa.rs index 6c123edaefb..1a757707895 100644 --- a/esp-wifi/src/timer/xtensa.rs +++ b/esp-wifi/src/timer/xtensa.rs @@ -21,26 +21,23 @@ pub(crate) fn get_systimer_count() -> u64 { esp_hal::time::now().ticks() } -pub(crate) fn setup_timer(mut timer1: TimeBase) -> Result<(), esp_hal::timer::Error> { +pub(crate) fn setup_timer(mut timer1: TimeBase) { timer1.set_interrupt_handler(InterruptHandler::new( unsafe { core::mem::transmute::<*const (), extern "C" fn()>(handler as *const ()) }, interrupt::Priority::Priority2, )); - timer1.start(TIMESLICE_FREQUENCY.into_duration())?; + timer1.start(TIMESLICE_FREQUENCY.into_duration()).unwrap(); critical_section::with(|cs| { timer1.enable_interrupt(true); TIMER.borrow_ref_mut(cs).replace(timer1); }); - Ok(()) } -pub(crate) fn disable_timer() -> Result<(), esp_hal::timer::Error> { +pub(crate) fn disable_timer() { 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(crate) fn setup_multitasking() { diff --git a/esp-wifi/src/wifi/mod.rs b/esp-wifi/src/wifi/mod.rs index 16d92c0d2bb..801e1a0e1f0 100644 --- a/esp-wifi/src/wifi/mod.rs +++ b/esp-wifi/src/wifi/mod.rs @@ -68,7 +68,7 @@ use crate::{ macros::ram, peripheral::{Peripheral, PeripheralRef}, }, - EspWifiInitialization, + EspWifiController, }; const ETHERNET_FRAME_HEADER_SIZE: usize = 18; @@ -90,8 +90,10 @@ use crate::{ esp_err_t, esp_interface_t_ESP_IF_WIFI_AP, esp_interface_t_ESP_IF_WIFI_STA, + esp_supplicant_deinit, esp_supplicant_init, esp_wifi_connect, + esp_wifi_deinit_internal, esp_wifi_disconnect, esp_wifi_get_mode, esp_wifi_init_internal, @@ -1595,6 +1597,14 @@ pub(crate) fn wifi_init() -> Result<(), WifiError> { } } +pub(crate) fn wifi_deinit() -> Result<(), crate::InitializationError> { + esp_wifi_result!(unsafe { esp_wifi_stop() })?; + esp_wifi_result!(unsafe { esp_wifi_deinit_internal() })?; + esp_wifi_result!(unsafe { esp_supplicant_deinit() })?; + crate::flags::WIFI.store(false, Ordering::Release); + Ok(()) +} + unsafe extern "C" fn recv_cb_sta( buffer: *mut c_types::c_void, len: u16, @@ -1872,7 +1882,7 @@ pub(crate) fn wifi_start_scan( /// /// If you want to use AP-STA mode, use `[new_ap_sta]`. pub fn new_with_config<'d, MODE: WifiDeviceMode>( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl Peripheral

+ 'd, config: MODE::Config, ) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> { @@ -1890,7 +1900,7 @@ pub fn new_with_config<'d, MODE: WifiDeviceMode>( /// This function will panic if the mode is [`WifiMode::ApSta`]. /// If you want to use AP-STA mode, use `[new_ap_sta]`. pub fn new_with_mode<'d, MODE: WifiDeviceMode>( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl crate::hal::peripheral::Peripheral

+ 'd, _mode: MODE, ) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> { @@ -1902,7 +1912,7 @@ pub fn new_with_mode<'d, MODE: WifiDeviceMode>( /// /// Returns a tuple of `(AP device, STA device, controller)`. pub fn new_ap_sta<'d>( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl Peripheral

+ 'd, ) -> Result< ( @@ -1919,7 +1929,7 @@ pub fn new_ap_sta<'d>( /// /// Returns a tuple of `(AP device, STA device, controller)`. pub fn new_ap_sta_with_config<'d>( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl Peripheral

+ 'd, sta_config: crate::wifi::ClientConfiguration, ap_config: crate::wifi::AccessPointConfiguration, @@ -2496,15 +2506,21 @@ pub struct WifiController<'d> { sniffer_taken: AtomicBool, } +impl<'d> Drop for WifiController<'d> { + fn drop(&mut self) { + if let Err(e) = crate::wifi::wifi_deinit() { + warn!("Failed to cleanly deinit wifi: {:?}", e); + } + } +} + impl<'d> WifiController<'d> { pub(crate) fn new_with_config( - inited: &EspWifiInitialization, + _inited: &'d EspWifiController<'d>, _device: PeripheralRef<'d, crate::hal::peripherals::WIFI>, config: Configuration, ) -> Result { - if !inited.is_wifi() { - return Err(WifiError::NotInitialized); - } + wifi_init()?; // We set up the controller with the default config because we need to call // `set_configuration` to apply the actual configuration, and it will update the diff --git a/esp-wifi/src/wifi/utils.rs b/esp-wifi/src/wifi/utils.rs index 1eb5da3a247..3c2968c9355 100644 --- a/esp-wifi/src/wifi/utils.rs +++ b/esp-wifi/src/wifi/utils.rs @@ -8,7 +8,7 @@ use smoltcp::{ }; use super::{WifiApDevice, WifiController, WifiDevice, WifiDeviceMode, WifiError, WifiStaDevice}; -use crate::{timestamp, EspWifiInitialization}; +use crate::{current_millis, EspWifiController}; fn setup_iface<'a, MODE: WifiDeviceMode>( device: &mut WifiDevice<'_, MODE>, @@ -38,7 +38,7 @@ fn setup_iface<'a, MODE: WifiDeviceMode>( /// You can use the provided macros to create and pass a suitable backing /// storage. pub fn create_network_interface<'a, 'd, MODE: WifiDeviceMode>( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl crate::hal::peripheral::Peripheral

+ 'd, mode: MODE, storage: &'a mut [SocketStorage<'a>], @@ -69,7 +69,7 @@ pub struct ApStaInterface<'a, 'd> { } pub fn create_ap_sta_network_interface<'a, 'd>( - inited: &EspWifiInitialization, + inited: &'d EspWifiController<'d>, device: impl crate::hal::peripheral::Peripheral

+ 'd, ap_storage: &'a mut [SocketStorage<'a>], sta_storage: &'a mut [SocketStorage<'a>], diff --git a/examples/Cargo.toml b/examples/Cargo.toml index d3aeba47443..c9af3773735 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -30,7 +30,7 @@ esp-hal-embassy = { path = "../esp-hal-embassy", optional = true } esp-ieee802154 = { path = "../esp-ieee802154", optional = true } esp-println = { path = "../esp-println", features = ["log"] } esp-storage = { path = "../esp-storage", optional = true } -esp-wifi = { path = "../esp-wifi", optional = true } +esp-wifi = { path = "../esp-wifi", features = ["log"], optional = true } fugit = "0.3.7" heapless = "0.8.0" hmac = { version = "0.12.1", default-features = false }