Remove EspWifiInitFor & more granular init/deinit per driver (#2301)
* More granular init and deinit per driver - Rework EspWifiInit - No longer require EspWifiInitFor - Add Drop impls for each driver, and add Drop for EspWifiController to fully deinit the stack * unwrap! more stuff * fixup examples and esp-now * unwrap less stuff * review feedback * seal wifi traits, allow rng or trng to init esp-wifi * changelog and migration guide * return wifi error in esp now constructor instead of panic
This commit is contained in:
parent
f9ba299f2e
commit
c717f04d4d
@ -130,10 +130,7 @@ impl rand_core::RngCore for Rng {
|
|||||||
/// the randomness from the hardware RNG and an ADC. This struct provides
|
/// the randomness from the hardware RNG and an ADC. This struct provides
|
||||||
/// methods to generate random numbers and fill buffers with random bytes.
|
/// methods to generate random numbers and fill buffers with random bytes.
|
||||||
/// Due to pulling the entropy source from the ADC, it uses the associated
|
/// Due to pulling the entropy source from the ADC, it uses the associated
|
||||||
/// regiters, so to use TRNG we need to "occupy" the ADC peripheral.
|
/// registers, so to use TRNG we need to "occupy" the ADC peripheral.
|
||||||
///
|
|
||||||
/// For now, even after calling `core::mem::drop()` on `TRNG` ADC1 will not be
|
|
||||||
/// usable (details in esp-hal/#1750)
|
|
||||||
///
|
///
|
||||||
/// ```rust, no_run
|
/// ```rust, no_run
|
||||||
#[doc = crate::before_snippet!()]
|
#[doc = crate::before_snippet!()]
|
||||||
|
|||||||
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- `esp_wifi::init` no longer requires `EspWifiInitFor`, and now returns `EspWifiController`, see the migration guide for more details (#2301)
|
||||||
- No need to add `rom_functions.x` manually anymore (#2374)
|
- No need to add `rom_functions.x` manually anymore (#2374)
|
||||||
- esp-now: Data is now private in `ReceivedData` - use `data()`(#2396)
|
- esp-now: Data is now private in `ReceivedData` - use `data()`(#2396)
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,7 @@ libm = "0.2.8"
|
|||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
portable-atomic = { version = "1.9.0", default-features = false }
|
portable-atomic = { version = "1.9.0", default-features = false }
|
||||||
portable_atomic_enum = { version = "0.3.1", features = ["portable-atomic"] }
|
portable_atomic_enum = { version = "0.3.1", features = ["portable-atomic"] }
|
||||||
|
rand_core = "0.6.4"
|
||||||
|
|
||||||
bt-hci = { version = "0.1.1", optional = true }
|
bt-hci = { version = "0.1.1", optional = true }
|
||||||
esp-config = { version = "0.1.0", path = "../esp-config" }
|
esp-config = { version = "0.1.0", path = "../esp-config" }
|
||||||
|
|||||||
@ -1,5 +1,22 @@
|
|||||||
# Migration Guide from 0.10.x to v0.11.x
|
# Migration Guide from 0.10.x to v0.11.x
|
||||||
|
|
||||||
|
## Initialization changes
|
||||||
|
|
||||||
|
`EspWifiInitFor` has been removed, individual drivers such as `Wifi` and `BleConnector` handle the initialization and de-initialization of the radio stack.
|
||||||
|
|
||||||
|
`EspWifiInit` has been removed in favour of `EspWifiController`, each radio driver takes reference to this object. If no driver is borrowing `EspWifiController`,
|
||||||
|
you can safely call `EspWifiController::deinit()` to completely deinit the stack and return the peripherals used in `esp_wifi::init`.
|
||||||
|
|
||||||
|
`esp-wifi::init` now takes all peripherals using the `PeripheralRef` pattern, with the exception of the rng source.
|
||||||
|
|
||||||
|
`esp_wifi::init` now accepts `esp_hal::rng::Rng` or `esp_hal::rng::Trng`.
|
||||||
|
|
||||||
|
The following error enum variants have been removed from `InitializationError`:
|
||||||
|
|
||||||
|
- `Timer(hal::timer::Error)`
|
||||||
|
- `TimerUnavailable`
|
||||||
|
- `RadioClockUnavailable`
|
||||||
|
|
||||||
## No need to include `rom_functions.x` manually
|
## No need to include `rom_functions.x` manually
|
||||||
|
|
||||||
Don't include `rom_functions.x` from esp-wifi
|
Don't include `rom_functions.x` from esp-wifi
|
||||||
|
|||||||
@ -442,6 +442,7 @@ pub(crate) fn ble_init() {
|
|||||||
|
|
||||||
API_vhci_host_register_callback(&VHCI_HOST_CALLBACK);
|
API_vhci_host_register_callback(&VHCI_HOST_CALLBACK);
|
||||||
}
|
}
|
||||||
|
crate::flags::BLE.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ble_deinit() {
|
pub(crate) fn ble_deinit() {
|
||||||
@ -453,6 +454,7 @@ pub(crate) fn ble_deinit() {
|
|||||||
btdm_controller_deinit();
|
btdm_controller_deinit();
|
||||||
crate::common_adapter::chip_specific::phy_disable();
|
crate::common_adapter::chip_specific::phy_disable();
|
||||||
}
|
}
|
||||||
|
crate::flags::BLE.store(false, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_hci(data: &[u8]) {
|
pub fn send_hci(data: &[u8]) {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use embedded_io::{Error, ErrorType, Read, Write};
|
|||||||
use super::{read_hci, read_next, send_hci};
|
use super::{read_hci, read_next, send_hci};
|
||||||
use crate::{
|
use crate::{
|
||||||
hal::peripheral::{Peripheral, PeripheralRef},
|
hal::peripheral::{Peripheral, PeripheralRef},
|
||||||
EspWifiInitialization,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A blocking HCI connector
|
/// A blocking HCI connector
|
||||||
@ -11,14 +11,18 @@ pub struct BleConnector<'d> {
|
|||||||
_device: PeripheralRef<'d, crate::hal::peripherals::BT>,
|
_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> {
|
impl<'d> BleConnector<'d> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
init: &EspWifiInitialization,
|
_init: &'d EspWifiController<'d>,
|
||||||
device: impl Peripheral<P = crate::hal::peripherals::BT> + 'd,
|
device: impl Peripheral<P = crate::hal::peripherals::BT> + 'd,
|
||||||
) -> BleConnector<'d> {
|
) -> BleConnector<'d> {
|
||||||
if !init.is_ble() {
|
crate::ble::ble_init();
|
||||||
panic!("Not initialized for BLE use");
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
_device: device.into_ref(),
|
_device: device.into_ref(),
|
||||||
@ -80,7 +84,7 @@ impl Write for BleConnector<'_> {
|
|||||||
|
|
||||||
/// Async Interface
|
/// Async Interface
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
pub mod asynch {
|
pub(crate) mod asynch {
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use bt_hci::{
|
use bt_hci::{
|
||||||
@ -91,14 +95,9 @@ pub mod asynch {
|
|||||||
WriteHci,
|
WriteHci,
|
||||||
};
|
};
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
use embedded_io::ErrorType;
|
|
||||||
|
|
||||||
use super::{read_hci, send_hci, BleConnectorError};
|
use super::*;
|
||||||
use crate::{
|
use crate::ble::have_hci_read_data;
|
||||||
ble::have_hci_read_data,
|
|
||||||
hal::peripheral::{Peripheral, PeripheralRef},
|
|
||||||
EspWifiInitialization,
|
|
||||||
};
|
|
||||||
|
|
||||||
static HCI_WAKER: AtomicWaker = AtomicWaker::new();
|
static HCI_WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
|
|
||||||
@ -106,30 +105,6 @@ pub mod asynch {
|
|||||||
HCI_WAKER.wake();
|
HCI_WAKER.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Async HCI connector
|
|
||||||
pub struct BleConnector<'d> {
|
|
||||||
_device: PeripheralRef<'d, crate::hal::peripherals::BT>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d> BleConnector<'d> {
|
|
||||||
pub fn new(
|
|
||||||
init: &EspWifiInitialization,
|
|
||||||
device: impl Peripheral<P = crate::hal::peripherals::BT> + 'd,
|
|
||||||
) -> BleConnector<'d> {
|
|
||||||
if !init.is_ble() {
|
|
||||||
panic!("Not initialized for BLE use");
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
_device: device.into_ref(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ErrorType for BleConnector<'_> {
|
|
||||||
type Error = BleConnectorError;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl embedded_io_async::Read for BleConnector<'_> {
|
impl embedded_io_async::Read for BleConnector<'_> {
|
||||||
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
|
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
|
||||||
if !have_hci_read_data() {
|
if !have_hci_read_data() {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ pub(crate) mod npl;
|
|||||||
use alloc::{boxed::Box, collections::vec_deque::VecDeque, vec::Vec};
|
use alloc::{boxed::Box, collections::vec_deque::VecDeque, vec::Vec};
|
||||||
use core::{cell::RefCell, mem::MaybeUninit};
|
use core::{cell::RefCell, mem::MaybeUninit};
|
||||||
|
|
||||||
pub(crate) use ble::{ble_init, send_hci};
|
pub(crate) use ble::{ble_deinit, ble_init, send_hci};
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
|
|
||||||
#[cfg(any(esp32, esp32c3, esp32s3))]
|
#[cfg(any(esp32, esp32c3, esp32s3))]
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use alloc::boxed::Box;
|
|||||||
use core::{
|
use core::{
|
||||||
mem::size_of_val,
|
mem::size_of_val,
|
||||||
ptr::{addr_of, addr_of_mut},
|
ptr::{addr_of, addr_of_mut},
|
||||||
|
sync::atomic::Ordering,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -1179,6 +1180,7 @@ pub(crate) fn ble_init() {
|
|||||||
|
|
||||||
debug!("The ble_controller_init was initialized");
|
debug!("The ble_controller_init was initialized");
|
||||||
}
|
}
|
||||||
|
crate::flags::BLE.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ble_deinit() {
|
pub(crate) fn ble_deinit() {
|
||||||
@ -1205,6 +1207,7 @@ pub(crate) fn ble_deinit() {
|
|||||||
|
|
||||||
crate::common_adapter::chip_specific::phy_disable();
|
crate::common_adapter::chip_specific::phy_disable();
|
||||||
}
|
}
|
||||||
|
crate::flags::BLE.store(false, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(esp32c2)]
|
#[cfg(esp32c2)]
|
||||||
|
|||||||
@ -34,6 +34,7 @@ unsafe extern "C" fn strcat(destination: *mut u8, source: *const u8) -> *const u
|
|||||||
unsafe extern "C" fn strcmp(str1: *const i8, str2: *const i8) -> i32 {
|
unsafe extern "C" fn strcmp(str1: *const i8, str2: *const i8) -> i32 {
|
||||||
trace!("strcmp {:?} {:?}", str1, str2);
|
trace!("strcmp {:?} {:?}", str1, str2);
|
||||||
|
|
||||||
|
// TODO: unwrap!() when defmt supports it
|
||||||
let s1 = core::ffi::CStr::from_ptr(str1).to_str().unwrap();
|
let s1 = core::ffi::CStr::from_ptr(str1).to_str().unwrap();
|
||||||
let s2 = core::ffi::CStr::from_ptr(str2).to_str().unwrap();
|
let s2 = core::ffi::CStr::from_ptr(str2).to_str().unwrap();
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ unsafe extern "C" fn strdup(str: *const i8) -> *const u8 {
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let s = core::ffi::CStr::from_ptr(str);
|
let s = core::ffi::CStr::from_ptr(str);
|
||||||
let s = s.to_str().unwrap();
|
let s = s.to_str().unwrap(); // TODO when defmt supports it
|
||||||
|
|
||||||
let p = malloc(s.len() + 1);
|
let p = malloc(s.len() + 1);
|
||||||
core::ptr::copy_nonoverlapping(str, p as *mut i8, s.len() + 1);
|
core::ptr::copy_nonoverlapping(str, p as *mut i8, s.len() + 1);
|
||||||
|
|||||||
@ -19,8 +19,8 @@ use portable_atomic::{AtomicBool, AtomicU8, Ordering};
|
|||||||
use crate::{
|
use crate::{
|
||||||
binary::include::*,
|
binary::include::*,
|
||||||
hal::peripheral::{Peripheral, PeripheralRef},
|
hal::peripheral::{Peripheral, PeripheralRef},
|
||||||
wifi::{Protocol, RxControlInfo},
|
wifi::{Protocol, RxControlInfo, WifiError},
|
||||||
EspWifiInitialization,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
const RECEIVE_QUEUE_SIZE: usize = 10;
|
const RECEIVE_QUEUE_SIZE: usize = 10;
|
||||||
@ -113,6 +113,14 @@ pub enum EspNowError {
|
|||||||
SendFailed,
|
SendFailed,
|
||||||
/// Attempt to create `EspNow` instance twice.
|
/// Attempt to create `EspNow` instance twice.
|
||||||
DuplicateInstance,
|
DuplicateInstance,
|
||||||
|
/// Initialization error
|
||||||
|
Initialization(WifiError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WifiError> for EspNowError {
|
||||||
|
fn from(f: WifiError) -> Self {
|
||||||
|
Self::Initialization(f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Holds the count of peers in an ESP-NOW communication context.
|
/// Holds the count of peers in an ESP-NOW communication context.
|
||||||
@ -469,6 +477,21 @@ impl EspNowManager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for EspNowManager<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if unwrap!(
|
||||||
|
crate::flags::WIFI.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
|
||||||
|
Some(x.saturating_sub(1))
|
||||||
|
})
|
||||||
|
) == 0
|
||||||
|
{
|
||||||
|
if let Err(e) = crate::wifi::wifi_deinit() {
|
||||||
|
warn!("Failed to cleanly deinit wifi: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This is the sender part of ESP-NOW. You can get this sender by splitting
|
/// This is the sender part of ESP-NOW. You can get this sender by splitting
|
||||||
/// a `EspNow` instance.
|
/// a `EspNow` instance.
|
||||||
///
|
///
|
||||||
@ -607,16 +630,16 @@ impl Drop for EspNowRc<'_> {
|
|||||||
/// Currently this implementation (when used together with traditional Wi-Fi)
|
/// Currently this implementation (when used together with traditional Wi-Fi)
|
||||||
/// ONLY support STA mode.
|
/// ONLY support STA mode.
|
||||||
pub struct EspNow<'d> {
|
pub struct EspNow<'d> {
|
||||||
_device: Option<PeripheralRef<'d, crate::hal::peripherals::WIFI>>,
|
|
||||||
manager: EspNowManager<'d>,
|
manager: EspNowManager<'d>,
|
||||||
sender: EspNowSender<'d>,
|
sender: EspNowSender<'d>,
|
||||||
receiver: EspNowReceiver<'d>,
|
receiver: EspNowReceiver<'d>,
|
||||||
|
_phantom: PhantomData<&'d ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> EspNow<'d> {
|
impl<'d> EspNow<'d> {
|
||||||
/// Creates an `EspNow` instance.
|
/// Creates an `EspNow` instance.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
) -> Result<EspNow<'d>, EspNowError> {
|
) -> Result<EspNow<'d>, EspNowError> {
|
||||||
EspNow::new_internal(inited, Some(device.into_ref()))
|
EspNow::new_internal(inited, Some(device.into_ref()))
|
||||||
@ -624,7 +647,7 @@ impl<'d> EspNow<'d> {
|
|||||||
|
|
||||||
/// Creates an `EspNow` instance with support for Wi-Fi coexistence.
|
/// Creates an `EspNow` instance with support for Wi-Fi coexistence.
|
||||||
pub fn new_with_wifi(
|
pub fn new_with_wifi(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
_token: EspNowWithWifiCreateToken,
|
_token: EspNowWithWifiCreateToken,
|
||||||
) -> Result<EspNow<'d>, EspNowError> {
|
) -> Result<EspNow<'d>, EspNowError> {
|
||||||
EspNow::new_internal(
|
EspNow::new_internal(
|
||||||
@ -634,16 +657,17 @@ impl<'d> EspNow<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_internal(
|
fn new_internal(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: Option<PeripheralRef<'d, crate::hal::peripherals::WIFI>>,
|
device: Option<PeripheralRef<'d, crate::hal::peripherals::WIFI>>,
|
||||||
) -> Result<EspNow<'d>, EspNowError> {
|
) -> Result<EspNow<'d>, EspNowError> {
|
||||||
if !inited.is_wifi() {
|
if !inited.wifi() {
|
||||||
return Err(EspNowError::Error(Error::NotInitialized));
|
// if wifi isn't already enabled, and we try to coexist - panic
|
||||||
|
assert!(device.is_some());
|
||||||
|
crate::wifi::wifi_init()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let espnow_rc = EspNowRc::new()?;
|
let espnow_rc = EspNowRc::new()?;
|
||||||
let esp_now = EspNow {
|
let esp_now = EspNow {
|
||||||
_device: device,
|
|
||||||
manager: EspNowManager {
|
manager: EspNowManager {
|
||||||
_rc: espnow_rc.clone(),
|
_rc: espnow_rc.clone(),
|
||||||
},
|
},
|
||||||
@ -651,6 +675,7 @@ impl<'d> EspNow<'d> {
|
|||||||
_rc: espnow_rc.clone(),
|
_rc: espnow_rc.clone(),
|
||||||
},
|
},
|
||||||
receiver: EspNowReceiver { _rc: espnow_rc },
|
receiver: EspNowReceiver { _rc: espnow_rc },
|
||||||
|
_phantom: PhantomData,
|
||||||
};
|
};
|
||||||
check_error!({ esp_wifi_set_mode(wifi_mode_t_WIFI_MODE_STA) })?;
|
check_error!({ esp_wifi_set_mode(wifi_mode_t_WIFI_MODE_STA) })?;
|
||||||
check_error!({ esp_wifi_start() })?;
|
check_error!({ esp_wifi_start() })?;
|
||||||
|
|||||||
@ -93,25 +93,25 @@ extern crate alloc;
|
|||||||
// MUST be the first module
|
// MUST be the first module
|
||||||
mod fmt;
|
mod fmt;
|
||||||
|
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use common_adapter::chip_specific::phy_mem_init;
|
use common_adapter::chip_specific::phy_mem_init;
|
||||||
use esp_config::*;
|
use esp_config::*;
|
||||||
use esp_hal as hal;
|
use esp_hal as hal;
|
||||||
|
use esp_hal::peripheral::Peripheral;
|
||||||
#[cfg(not(feature = "esp32"))]
|
#[cfg(not(feature = "esp32"))]
|
||||||
use esp_hal::timer::systimer::Alarm;
|
use esp_hal::timer::systimer::Alarm;
|
||||||
use fugit::MegahertzU32;
|
use fugit::MegahertzU32;
|
||||||
use hal::{
|
use hal::{
|
||||||
clock::Clocks,
|
clock::Clocks,
|
||||||
|
rng::{Rng, Trng},
|
||||||
system::RadioClockController,
|
system::RadioClockController,
|
||||||
timer::{timg::Timer as TimgTimer, AnyTimer, PeriodicTimer},
|
timer::{timg::Timer as TimgTimer, AnyTimer, PeriodicTimer},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "wifi")]
|
use portable_atomic::Ordering;
|
||||||
use num_traits::FromPrimitive;
|
|
||||||
|
|
||||||
#[cfg(feature = "wifi")]
|
#[cfg(feature = "wifi")]
|
||||||
use crate::{
|
use crate::wifi::WifiError;
|
||||||
binary::include::{self, esp_supplicant_deinit, esp_wifi_deinit_internal, esp_wifi_stop},
|
|
||||||
wifi::WifiError,
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
tasks::init_tasks,
|
tasks::init_tasks,
|
||||||
timer::{setup_timer_isr, shutdown_timer_isr},
|
timer::{setup_timer_isr, shutdown_timer_isr},
|
||||||
@ -233,73 +233,53 @@ const _: () = {
|
|||||||
|
|
||||||
type TimeBase = PeriodicTimer<'static, AnyTimer>;
|
type TimeBase = PeriodicTimer<'static, AnyTimer>;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd)]
|
pub(crate) mod flags {
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
use portable_atomic::{AtomicBool, AtomicUsize};
|
||||||
#[non_exhaustive]
|
|
||||||
/// An internal struct designed to make [`EspWifiInitialization`] uncreatable
|
|
||||||
/// outside of this crate.
|
|
||||||
pub struct EspWifiInitializationInternal;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd)]
|
pub(crate) static ESP_WIFI_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
pub(crate) static WIFI: AtomicUsize = AtomicUsize::new(0);
|
||||||
/// Initialized the driver for WiFi, Bluetooth or both.
|
pub(crate) static BLE: AtomicBool = AtomicBool::new(false);
|
||||||
pub enum EspWifiInitialization {
|
|
||||||
#[cfg(feature = "wifi")]
|
|
||||||
Wifi(EspWifiInitializationInternal),
|
|
||||||
#[cfg(feature = "ble")]
|
|
||||||
Ble(EspWifiInitializationInternal),
|
|
||||||
#[cfg(coex)]
|
|
||||||
WifiBle(EspWifiInitializationInternal),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EspWifiInitialization {
|
|
||||||
#[allow(unused)]
|
|
||||||
fn is_wifi(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "ble")]
|
|
||||||
EspWifiInitialization::Ble(_) => false,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
fn is_ble(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "wifi")]
|
|
||||||
EspWifiInitialization::Wifi(_) => false,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd)]
|
#[derive(Debug, PartialEq, PartialOrd)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
/// Initialize the driver for WiFi, Bluetooth or both.
|
pub struct EspWifiController<'d> {
|
||||||
pub enum EspWifiInitFor {
|
_inner: PhantomData<&'d ()>,
|
||||||
#[cfg(feature = "wifi")]
|
|
||||||
Wifi,
|
|
||||||
#[cfg(feature = "ble")]
|
|
||||||
Ble,
|
|
||||||
#[cfg(coex)]
|
|
||||||
WifiBle,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EspWifiInitFor {
|
impl<'d> EspWifiController<'d> {
|
||||||
#[allow(unused)]
|
/// Is the WiFi part of the radio running
|
||||||
fn is_wifi(&self) -> bool {
|
pub fn wifi(&self) -> bool {
|
||||||
match self {
|
crate::flags::WIFI.load(Ordering::Acquire) > 0
|
||||||
#[cfg(feature = "ble")]
|
}
|
||||||
EspWifiInitFor::Ble => false,
|
|
||||||
_ => true,
|
/// Is the BLE part of the radio running
|
||||||
|
pub fn ble(&self) -> bool {
|
||||||
|
crate::flags::BLE.load(Ordering::Acquire)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// De-initialize the radio
|
||||||
|
pub fn deinit(self) -> Result<(), InitializationError> {
|
||||||
|
if crate::flags::ESP_WIFI_INITIALIZED.load(Ordering::Acquire) {
|
||||||
|
// safety: no other driver can be using this if this is callable
|
||||||
|
unsafe { deinit_unchecked() }
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
pub(crate) unsafe fn conjure() -> Self {
|
||||||
fn is_ble(&self) -> bool {
|
Self {
|
||||||
match self {
|
_inner: PhantomData,
|
||||||
#[cfg(feature = "wifi")]
|
}
|
||||||
EspWifiInitFor::Wifi => false,
|
}
|
||||||
_ => true,
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for EspWifiController<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if crate::flags::ESP_WIFI_INITIALIZED.load(Ordering::Acquire) {
|
||||||
|
// safety: no other driver can be using this if this is callable
|
||||||
|
unsafe { deinit_unchecked().ok() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +288,7 @@ impl EspWifiInitFor {
|
|||||||
///
|
///
|
||||||
/// This trait is meant to be used only for the `init` function.
|
/// This trait is meant to be used only for the `init` function.
|
||||||
/// Calling `timers()` multiple times may panic.
|
/// Calling `timers()` multiple times may panic.
|
||||||
pub trait EspWifiTimerSource {
|
pub trait EspWifiTimerSource: private::Sealed {
|
||||||
/// Returns the timer source.
|
/// Returns the timer source.
|
||||||
fn timer(self) -> TimeBase;
|
fn timer(self) -> TimeBase;
|
||||||
}
|
}
|
||||||
@ -338,7 +318,7 @@ impl IntoAnyTimer for AnyTimer {}
|
|||||||
|
|
||||||
impl<T> EspWifiTimerSource for T
|
impl<T> EspWifiTimerSource for T
|
||||||
where
|
where
|
||||||
T: IntoAnyTimer,
|
T: IntoAnyTimer + private::Sealed,
|
||||||
{
|
{
|
||||||
fn timer(self) -> TimeBase {
|
fn timer(self) -> TimeBase {
|
||||||
TimeBase::new(self.into()).timer()
|
TimeBase::new(self.into()).timer()
|
||||||
@ -351,6 +331,29 @@ impl EspWifiTimerSource for TimeBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl private::Sealed for TimeBase {}
|
||||||
|
impl<T, DM> private::Sealed for TimgTimer<T, DM>
|
||||||
|
where
|
||||||
|
DM: esp_hal::Mode,
|
||||||
|
Self: Into<AnyTimer>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "esp32"))]
|
||||||
|
impl<T, DM, COMP, UNIT> private::Sealed for Alarm<'_, T, DM, COMP, UNIT>
|
||||||
|
where
|
||||||
|
DM: esp_hal::Mode,
|
||||||
|
Self: Into<AnyTimer>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A marker trait for suitable Rng sources for esp-wifi
|
||||||
|
pub trait EspWifiRngSource: rand_core::RngCore + private::Sealed {}
|
||||||
|
|
||||||
|
impl EspWifiRngSource for Rng {}
|
||||||
|
impl private::Sealed for Rng {}
|
||||||
|
impl EspWifiRngSource for Trng<'_> {}
|
||||||
|
impl private::Sealed for Trng<'_> {}
|
||||||
|
|
||||||
/// Initialize for using WiFi and or BLE.
|
/// Initialize for using WiFi and or BLE.
|
||||||
///
|
///
|
||||||
/// # The `timer` argument
|
/// # The `timer` argument
|
||||||
@ -380,12 +383,11 @@ impl EspWifiTimerSource for TimeBase {
|
|||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn init(
|
pub fn init<'d, T: EspWifiTimerSource>(
|
||||||
init_for: EspWifiInitFor,
|
timer: impl Peripheral<P = T> + 'd,
|
||||||
timer: impl EspWifiTimerSource,
|
_rng: impl EspWifiRngSource,
|
||||||
_rng: hal::rng::Rng,
|
_radio_clocks: impl Peripheral<P = hal::peripherals::RADIO_CLK> + 'd,
|
||||||
_radio_clocks: hal::peripherals::RADIO_CLK,
|
) -> Result<EspWifiController<'d>, InitializationError> {
|
||||||
) -> Result<EspWifiInitialization, InitializationError> {
|
|
||||||
// A minimum clock of 80MHz is required to operate WiFi module.
|
// A minimum clock of 80MHz is required to operate WiFi module.
|
||||||
const MIN_CLOCK: u32 = 80;
|
const MIN_CLOCK: u32 = 80;
|
||||||
let clocks = Clocks::get();
|
let clocks = Clocks::get();
|
||||||
@ -397,7 +399,7 @@ pub fn init(
|
|||||||
crate::common_adapter::chip_specific::enable_wifi_power_domain();
|
crate::common_adapter::chip_specific::enable_wifi_power_domain();
|
||||||
phy_mem_init();
|
phy_mem_init();
|
||||||
init_tasks();
|
init_tasks();
|
||||||
setup_timer_isr(timer.timer())?;
|
setup_timer_isr(unsafe { timer.clone_unchecked() }.timer());
|
||||||
|
|
||||||
wifi_set_log_verbose();
|
wifi_set_log_verbose();
|
||||||
init_clocks();
|
init_clocks();
|
||||||
@ -408,60 +410,23 @@ pub fn init(
|
|||||||
error => return Err(InitializationError::General(error)),
|
error => return Err(InitializationError::General(error)),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wifi")]
|
crate::flags::ESP_WIFI_INITIALIZED.store(true, Ordering::Release);
|
||||||
if init_for.is_wifi() {
|
|
||||||
debug!("wifi init");
|
|
||||||
// wifi init
|
|
||||||
crate::wifi::wifi_init()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "ble")]
|
Ok(EspWifiController {
|
||||||
if init_for.is_ble() {
|
_inner: PhantomData,
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deinitializes WiFi and/or BLE
|
/// Deinitializes the entire radio stack
|
||||||
///
|
///
|
||||||
/// After user calls this function, WiFi and/or BLE (depending on what has been
|
/// This can be useful to shutdown the stack before going to sleep for example.
|
||||||
/// 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
|
/// # Safety
|
||||||
/// Actual implementation assumes that the user takes responsibility for how the
|
///
|
||||||
/// function is used. For example, after using this function, user should not
|
/// The user must ensure that any use of the radio via the WIFI/BLE/ESP-NOW
|
||||||
/// use BLE or WiFi stack or controller instances (it is possible to
|
/// drivers are complete, else undefined behavour may occur within those
|
||||||
/// reinitialize communication using the `init` function), not to call
|
/// drivers.
|
||||||
/// `deinit_unsafe` before the first initialization, and so on. Also, there is
|
pub unsafe fn deinit_unchecked() -> Result<(), InitializationError> {
|
||||||
/// 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
|
// Disable coexistence
|
||||||
#[cfg(coex)]
|
#[cfg(coex)]
|
||||||
{
|
{
|
||||||
@ -469,33 +434,35 @@ pub unsafe fn deinit_unchecked(
|
|||||||
unsafe { crate::wifi::os_adapter::coex_deinit() };
|
unsafe { crate::wifi::os_adapter::coex_deinit() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deinitialize WiFi
|
let controller = unsafe { EspWifiController::conjure() };
|
||||||
#[cfg(feature = "wifi")]
|
|
||||||
if init.is_wifi() {
|
// Peripheral drivers should already take care of shutting these down
|
||||||
esp_wifi_result!(unsafe { esp_wifi_stop() })?;
|
// we have to check this in the case where a user calls `deinit_unchecked`
|
||||||
esp_wifi_result!(unsafe { esp_wifi_deinit_internal() })?;
|
// directly.
|
||||||
esp_wifi_result!(esp_supplicant_deinit())?;
|
if controller.wifi() {
|
||||||
|
#[cfg(feature = "wifi")]
|
||||||
|
crate::wifi::wifi_deinit()?;
|
||||||
|
crate::flags::WIFI.store(0, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deinitialize BLE
|
if controller.ble() {
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
if init.is_ble() {
|
crate::ble::ble_deinit();
|
||||||
#[cfg(any(esp32, esp32c3, esp32s3))]
|
crate::flags::BLE.store(false, Ordering::Release);
|
||||||
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();
|
crate::preempt::delete_all_tasks();
|
||||||
|
|
||||||
let timer = critical_section::with(|cs| crate::timer::TIMER.borrow_ref_mut(cs).take())
|
critical_section::with(|cs| crate::timer::TIMER.borrow_ref_mut(cs).take());
|
||||||
.ok_or(InitializationError::TimerUnavailable)?;
|
|
||||||
|
|
||||||
let radio_clocks = unsafe { esp_hal::peripherals::RADIO_CLK::steal() };
|
crate::flags::ESP_WIFI_INITIALIZED.store(false, Ordering::Release);
|
||||||
|
|
||||||
Ok((timer, radio_clocks))
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) mod private {
|
||||||
|
pub trait Sealed {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@ -506,15 +473,6 @@ pub enum InitializationError {
|
|||||||
#[cfg(feature = "wifi")]
|
#[cfg(feature = "wifi")]
|
||||||
WifiError(WifiError),
|
WifiError(WifiError),
|
||||||
WrongClockConfig,
|
WrongClockConfig,
|
||||||
Timer(hal::timer::Error),
|
|
||||||
TimerUnavailable,
|
|
||||||
RadioClockUnavailable,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<hal::timer::Error> for InitializationError {
|
|
||||||
fn from(value: hal::timer::Error) -> Self {
|
|
||||||
InitializationError::Timer(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wifi")]
|
#[cfg(feature = "wifi")]
|
||||||
|
|||||||
@ -22,24 +22,22 @@ use crate::TimeBase;
|
|||||||
|
|
||||||
pub(crate) static TIMER: Mutex<RefCell<Option<TimeBase>>> = Mutex::new(RefCell::new(None));
|
pub(crate) static TIMER: Mutex<RefCell<Option<TimeBase>>> = 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_radio_isr();
|
||||||
|
|
||||||
setup_timer(timebase)?;
|
setup_timer(timebase);
|
||||||
|
|
||||||
setup_multitasking();
|
setup_multitasking();
|
||||||
|
|
||||||
yield_task();
|
yield_task();
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn shutdown_timer_isr() -> Result<(), esp_hal::timer::Error> {
|
pub(crate) fn shutdown_timer_isr() {
|
||||||
shutdown_radio_isr();
|
shutdown_radio_isr();
|
||||||
|
|
||||||
disable_timer()?;
|
disable_timer();
|
||||||
|
|
||||||
disable_multitasking();
|
disable_multitasking();
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|||||||
@ -23,28 +23,24 @@ pub const TICKS_PER_SECOND: u64 = 1_000_000;
|
|||||||
|
|
||||||
use super::TIMER;
|
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
|
// make sure the scheduling won't start before everything is setup
|
||||||
riscv::interrupt::disable();
|
riscv::interrupt::disable();
|
||||||
|
|
||||||
let cb: extern "C" fn() = unsafe { core::mem::transmute(handler as *const ()) };
|
let cb: extern "C" fn() = unsafe { core::mem::transmute(handler as *const ()) };
|
||||||
alarm0.set_interrupt_handler(InterruptHandler::new(cb, interrupt::Priority::Priority1));
|
alarm0.set_interrupt_handler(InterruptHandler::new(cb, interrupt::Priority::Priority1));
|
||||||
alarm0.start(TIMESLICE_FREQUENCY.into_duration())?;
|
unwrap!(alarm0.start(TIMESLICE_FREQUENCY.into_duration()));
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
alarm0.enable_interrupt(true);
|
alarm0.enable_interrupt(true);
|
||||||
TIMER.borrow_ref_mut(cs).replace(alarm0);
|
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| {
|
critical_section::with(|cs| {
|
||||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
|
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
|
||||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel().unwrap();
|
unwrap!(unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel());
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn setup_multitasking() {
|
pub(crate) fn setup_multitasking() {
|
||||||
|
|||||||
@ -21,26 +21,23 @@ pub(crate) fn get_systimer_count() -> u64 {
|
|||||||
esp_hal::time::now().ticks()
|
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(
|
timer1.set_interrupt_handler(InterruptHandler::new(
|
||||||
unsafe { core::mem::transmute::<*const (), extern "C" fn()>(handler as *const ()) },
|
unsafe { core::mem::transmute::<*const (), extern "C" fn()>(handler as *const ()) },
|
||||||
interrupt::Priority::Priority2,
|
interrupt::Priority::Priority2,
|
||||||
));
|
));
|
||||||
timer1.start(TIMESLICE_FREQUENCY.into_duration())?;
|
unwrap!(timer1.start(TIMESLICE_FREQUENCY.into_duration()));
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
timer1.enable_interrupt(true);
|
timer1.enable_interrupt(true);
|
||||||
TIMER.borrow_ref_mut(cs).replace(timer1);
|
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| {
|
critical_section::with(|cs| {
|
||||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
|
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
|
||||||
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel().unwrap();
|
unwrap!(unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel());
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn setup_multitasking() {
|
pub(crate) fn setup_multitasking() {
|
||||||
|
|||||||
@ -69,7 +69,7 @@ use crate::{
|
|||||||
macros::ram,
|
macros::ram,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
},
|
},
|
||||||
EspWifiInitialization,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ETHERNET_FRAME_HEADER_SIZE: usize = 18;
|
const ETHERNET_FRAME_HEADER_SIZE: usize = 18;
|
||||||
@ -90,8 +90,10 @@ use crate::binary::{
|
|||||||
esp_err_t,
|
esp_err_t,
|
||||||
esp_interface_t_ESP_IF_WIFI_AP,
|
esp_interface_t_ESP_IF_WIFI_AP,
|
||||||
esp_interface_t_ESP_IF_WIFI_STA,
|
esp_interface_t_ESP_IF_WIFI_STA,
|
||||||
|
esp_supplicant_deinit,
|
||||||
esp_supplicant_init,
|
esp_supplicant_init,
|
||||||
esp_wifi_connect,
|
esp_wifi_connect,
|
||||||
|
esp_wifi_deinit_internal,
|
||||||
esp_wifi_disconnect,
|
esp_wifi_disconnect,
|
||||||
esp_wifi_get_mode,
|
esp_wifi_get_mode,
|
||||||
esp_wifi_init_internal,
|
esp_wifi_init_internal,
|
||||||
@ -281,7 +283,7 @@ pub struct AccessPointConfiguration {
|
|||||||
impl Default for AccessPointConfiguration {
|
impl Default for AccessPointConfiguration {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ssid: "iot-device".try_into().unwrap(),
|
ssid: unwrap!("iot-device".try_into()),
|
||||||
ssid_hidden: false,
|
ssid_hidden: false,
|
||||||
channel: 1,
|
channel: 1,
|
||||||
secondary_channel: None,
|
secondary_channel: None,
|
||||||
@ -1587,10 +1589,19 @@ pub(crate) fn wifi_init() -> Result<(), WifiError> {
|
|||||||
chip_specific::g_misc_nvs = addr_of!(NVS_STRUCT) as u32;
|
chip_specific::g_misc_nvs = addr_of!(NVS_STRUCT) as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate::flags::WIFI.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() })?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn recv_cb_sta(
|
unsafe extern "C" fn recv_cb_sta(
|
||||||
buffer: *mut c_types::c_void,
|
buffer: *mut c_types::c_void,
|
||||||
len: u16,
|
len: u16,
|
||||||
@ -1654,11 +1665,11 @@ unsafe extern "C" fn recv_cb_ap(
|
|||||||
pub(crate) static WIFI_TX_INFLIGHT: AtomicUsize = AtomicUsize::new(0);
|
pub(crate) static WIFI_TX_INFLIGHT: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
fn decrement_inflight_counter() {
|
fn decrement_inflight_counter() {
|
||||||
WIFI_TX_INFLIGHT
|
unwrap!(
|
||||||
.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
|
WIFI_TX_INFLIGHT.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
|
||||||
Some(x.saturating_sub(1))
|
Some(x.saturating_sub(1))
|
||||||
})
|
})
|
||||||
.unwrap();
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ram]
|
#[ram]
|
||||||
@ -1878,7 +1889,7 @@ pub(crate) fn wifi_start_scan(
|
|||||||
///
|
///
|
||||||
/// If you want to use AP-STA mode, use `[new_ap_sta]`.
|
/// If you want to use AP-STA mode, use `[new_ap_sta]`.
|
||||||
pub fn new_with_config<'d, MODE: WifiDeviceMode>(
|
pub fn new_with_config<'d, MODE: WifiDeviceMode>(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
config: MODE::Config,
|
config: MODE::Config,
|
||||||
) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> {
|
) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> {
|
||||||
@ -1896,8 +1907,8 @@ pub fn new_with_config<'d, MODE: WifiDeviceMode>(
|
|||||||
/// This function will panic if the mode is [`WifiMode::ApSta`].
|
/// This function will panic if the mode is [`WifiMode::ApSta`].
|
||||||
/// If you want to use AP-STA mode, use `[new_ap_sta]`.
|
/// If you want to use AP-STA mode, use `[new_ap_sta]`.
|
||||||
pub fn new_with_mode<'d, MODE: WifiDeviceMode>(
|
pub fn new_with_mode<'d, MODE: WifiDeviceMode>(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
_mode: MODE,
|
_mode: MODE,
|
||||||
) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> {
|
) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> {
|
||||||
new_with_config(inited, device, <MODE as Sealed>::Config::default())
|
new_with_config(inited, device, <MODE as Sealed>::Config::default())
|
||||||
@ -1908,7 +1919,7 @@ pub fn new_with_mode<'d, MODE: WifiDeviceMode>(
|
|||||||
///
|
///
|
||||||
/// Returns a tuple of `(AP device, STA device, controller)`.
|
/// Returns a tuple of `(AP device, STA device, controller)`.
|
||||||
pub fn new_ap_sta<'d>(
|
pub fn new_ap_sta<'d>(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
@ -1925,7 +1936,7 @@ pub fn new_ap_sta<'d>(
|
|||||||
///
|
///
|
||||||
/// Returns a tuple of `(AP device, STA device, controller)`.
|
/// Returns a tuple of `(AP device, STA device, controller)`.
|
||||||
pub fn new_ap_sta_with_config<'d>(
|
pub fn new_ap_sta_with_config<'d>(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
sta_config: crate::wifi::ClientConfiguration,
|
sta_config: crate::wifi::ClientConfiguration,
|
||||||
ap_config: crate::wifi::AccessPointConfiguration,
|
ap_config: crate::wifi::AccessPointConfiguration,
|
||||||
@ -2448,8 +2459,9 @@ impl Sniffer {
|
|||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
// This shouldn't fail, since the way this is created, means that wifi will
|
// This shouldn't fail, since the way this is created, means that wifi will
|
||||||
// always be initialized.
|
// always be initialized.
|
||||||
esp_wifi_result!(unsafe { esp_wifi_set_promiscuous_rx_cb(Some(promiscuous_rx_cb)) })
|
unwrap!(esp_wifi_result!(unsafe {
|
||||||
.unwrap();
|
esp_wifi_set_promiscuous_rx_cb(Some(promiscuous_rx_cb))
|
||||||
|
}));
|
||||||
Self {
|
Self {
|
||||||
promiscuous_mode_enabled: AtomicBool::new(false),
|
promiscuous_mode_enabled: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
@ -2493,14 +2505,29 @@ pub struct WifiController<'d> {
|
|||||||
sniffer_taken: AtomicBool,
|
sniffer_taken: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> Drop for WifiController<'d> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if unwrap!(
|
||||||
|
crate::flags::WIFI.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
|
||||||
|
Some(x.saturating_sub(1))
|
||||||
|
})
|
||||||
|
) == 0
|
||||||
|
{
|
||||||
|
if let Err(e) = crate::wifi::wifi_deinit() {
|
||||||
|
warn!("Failed to cleanly deinit wifi: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d> WifiController<'d> {
|
impl<'d> WifiController<'d> {
|
||||||
pub(crate) fn new_with_config(
|
pub(crate) fn new_with_config(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
_device: PeripheralRef<'d, crate::hal::peripherals::WIFI>,
|
_device: PeripheralRef<'d, crate::hal::peripherals::WIFI>,
|
||||||
config: Configuration,
|
config: Configuration,
|
||||||
) -> Result<Self, WifiError> {
|
) -> Result<Self, WifiError> {
|
||||||
if !inited.is_wifi() {
|
if !inited.wifi() {
|
||||||
return Err(WifiError::NotInitialized);
|
crate::wifi::wifi_init()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We set up the controller with the default config because we need to call
|
// We set up the controller with the default config because we need to call
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use smoltcp::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{WifiApDevice, WifiController, WifiDevice, WifiDeviceMode, WifiError, WifiStaDevice};
|
use super::{WifiApDevice, WifiController, WifiDevice, WifiDeviceMode, WifiError, WifiStaDevice};
|
||||||
use crate::{timestamp, EspWifiInitialization};
|
use crate::{timestamp, EspWifiController};
|
||||||
|
|
||||||
fn setup_iface<'a, MODE: WifiDeviceMode>(
|
fn setup_iface<'a, MODE: WifiDeviceMode>(
|
||||||
device: &mut WifiDevice<'_, MODE>,
|
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
|
/// You can use the provided macros to create and pass a suitable backing
|
||||||
/// storage.
|
/// storage.
|
||||||
pub fn create_network_interface<'a, 'd, MODE: WifiDeviceMode>(
|
pub fn create_network_interface<'a, 'd, MODE: WifiDeviceMode>(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
mode: MODE,
|
mode: MODE,
|
||||||
storage: &'a mut [SocketStorage<'a>],
|
storage: &'a mut [SocketStorage<'a>],
|
||||||
@ -69,7 +69,7 @@ pub struct ApStaInterface<'a, 'd> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_ap_sta_network_interface<'a, 'd>(
|
pub fn create_ap_sta_network_interface<'a, 'd>(
|
||||||
inited: &EspWifiInitialization,
|
inited: &'d EspWifiController<'d>,
|
||||||
device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
|
||||||
ap_storage: &'a mut [SocketStorage<'a>],
|
ap_storage: &'a mut [SocketStorage<'a>],
|
||||||
sta_storage: &'a mut [SocketStorage<'a>],
|
sta_storage: &'a mut [SocketStorage<'a>],
|
||||||
|
|||||||
@ -30,7 +30,7 @@ esp-hal-embassy = { path = "../esp-hal-embassy", optional = true }
|
|||||||
esp-ieee802154 = { path = "../esp-ieee802154", optional = true }
|
esp-ieee802154 = { path = "../esp-ieee802154", optional = true }
|
||||||
esp-println = { path = "../esp-println", features = ["log"] }
|
esp-println = { path = "../esp-println", features = ["log"] }
|
||||||
esp-storage = { path = "../esp-storage", optional = true }
|
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"
|
fugit = "0.3.7"
|
||||||
heapless = "0.8.0"
|
heapless = "0.8.0"
|
||||||
hmac = { version = "0.12.1", default-features = false }
|
hmac = { version = "0.12.1", default-features = false }
|
||||||
|
|||||||
@ -13,13 +13,8 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use esp_alloc as _;
|
use esp_alloc as _;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{delay::Delay, prelude::*, rng::Rng, timer::timg::TimerGroup};
|
||||||
delay::Delay,
|
use esp_wifi::{init, wifi};
|
||||||
prelude::*,
|
|
||||||
rng::Rng,
|
|
||||||
timer::{timg::TimerGroup, AnyTimer, PeriodicTimer},
|
|
||||||
};
|
|
||||||
use esp_wifi::{init, wifi, EspWifiInitFor};
|
|
||||||
use ieee80211::{
|
use ieee80211::{
|
||||||
common::{CapabilitiesInformation, FCFFlags},
|
common::{CapabilitiesInformation, FCFFlags},
|
||||||
element_chain,
|
element_chain,
|
||||||
@ -47,12 +42,9 @@ fn main() -> ! {
|
|||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
let timer0: AnyTimer = timg0.timer0.into();
|
|
||||||
let timer = PeriodicTimer::new(timer0);
|
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
timg0.timer0,
|
||||||
timer,
|
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -33,7 +33,6 @@ use esp_wifi::{
|
|||||||
WifiApDevice,
|
WifiApDevice,
|
||||||
},
|
},
|
||||||
wifi_interface::WifiStack,
|
wifi_interface::WifiStack,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
use smoltcp::iface::SocketStorage;
|
use smoltcp::iface::SocketStorage;
|
||||||
|
|
||||||
@ -51,7 +50,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -34,7 +34,6 @@ use esp_wifi::{
|
|||||||
Configuration,
|
Configuration,
|
||||||
},
|
},
|
||||||
wifi_interface::WifiStack,
|
wifi_interface::WifiStack,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::SocketStorage,
|
iface::SocketStorage,
|
||||||
@ -58,7 +57,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -36,7 +36,6 @@ use esp_wifi::{
|
|||||||
WifiStaDevice,
|
WifiStaDevice,
|
||||||
},
|
},
|
||||||
wifi_interface::WifiStack,
|
wifi_interface::WifiStack,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::SocketStorage,
|
iface::SocketStorage,
|
||||||
@ -71,7 +70,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -32,7 +32,7 @@ use esp_hal::{
|
|||||||
timer::timg::TimerGroup,
|
timer::timg::TimerGroup,
|
||||||
};
|
};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
use esp_wifi::{ble::controller::BleConnector, init, EspWifiInitFor};
|
use esp_wifi::{ble::controller::BleConnector, init};
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
@ -48,7 +48,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Ble,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -41,7 +41,6 @@ use esp_wifi::{
|
|||||||
init,
|
init,
|
||||||
wifi::{utils::create_network_interface, ClientConfiguration, Configuration, WifiStaDevice},
|
wifi::{utils::create_network_interface, ClientConfiguration, Configuration, WifiStaDevice},
|
||||||
wifi_interface::WifiStack,
|
wifi_interface::WifiStack,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::SocketStorage,
|
iface::SocketStorage,
|
||||||
@ -83,7 +82,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::WifiBle,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -35,7 +35,6 @@ use esp_wifi::{
|
|||||||
WifiStaDevice,
|
WifiStaDevice,
|
||||||
},
|
},
|
||||||
wifi_interface::WifiStack,
|
wifi_interface::WifiStack,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::SocketStorage,
|
iface::SocketStorage,
|
||||||
@ -59,7 +58,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -41,7 +41,7 @@ use esp_wifi::{
|
|||||||
WifiEvent,
|
WifiEvent,
|
||||||
WifiState,
|
WifiState,
|
||||||
},
|
},
|
||||||
EspWifiInitFor,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
@ -67,13 +67,15 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Wifi,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let wifi = peripherals.WIFI;
|
let wifi = peripherals.WIFI;
|
||||||
let (wifi_interface, controller) =
|
let (wifi_interface, controller) =
|
||||||
|
|||||||
@ -46,7 +46,7 @@ use esp_wifi::{
|
|||||||
WifiStaDevice,
|
WifiStaDevice,
|
||||||
WifiState,
|
WifiState,
|
||||||
},
|
},
|
||||||
EspWifiInitFor,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SSID: &str = env!("SSID");
|
const SSID: &str = env!("SSID");
|
||||||
@ -75,13 +75,15 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Wifi,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let wifi = peripherals.WIFI;
|
let wifi = peripherals.WIFI;
|
||||||
let (wifi_ap_interface, wifi_sta_interface, mut controller) =
|
let (wifi_ap_interface, wifi_sta_interface, mut controller) =
|
||||||
|
|||||||
@ -36,7 +36,7 @@ use esp_wifi::{
|
|||||||
WifiStaDevice,
|
WifiStaDevice,
|
||||||
WifiState,
|
WifiState,
|
||||||
},
|
},
|
||||||
EspWifiInitFor,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
@ -98,13 +98,15 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Wifi,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let wifi = peripherals.WIFI;
|
let wifi = peripherals.WIFI;
|
||||||
let (wifi_interface, controller) =
|
let (wifi_interface, controller) =
|
||||||
|
|||||||
@ -35,7 +35,17 @@ use esp_hal::{
|
|||||||
timer::timg::TimerGroup,
|
timer::timg::TimerGroup,
|
||||||
};
|
};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
use esp_wifi::{ble::controller::asynch::BleConnector, init, EspWifiInitFor};
|
use esp_wifi::{ble::controller::BleConnector, init, EspWifiController};
|
||||||
|
|
||||||
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
|
macro_rules! mk_static {
|
||||||
|
($t:ty,$val:expr) => {{
|
||||||
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||||
|
#[deny(unused_attributes)]
|
||||||
|
let x = STATIC_CELL.uninit().write(($val));
|
||||||
|
x
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[esp_hal_embassy::main]
|
#[esp_hal_embassy::main]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
@ -50,13 +60,15 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Ble,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ use esp_wifi::{
|
|||||||
WifiStaDevice,
|
WifiStaDevice,
|
||||||
WifiState,
|
WifiState,
|
||||||
},
|
},
|
||||||
EspWifiInitFor,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
@ -61,13 +61,15 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Wifi,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let wifi = peripherals.WIFI;
|
let wifi = peripherals.WIFI;
|
||||||
let (wifi_interface, controller) =
|
let (wifi_interface, controller) =
|
||||||
|
|||||||
@ -20,9 +20,19 @@ use esp_println::println;
|
|||||||
use esp_wifi::{
|
use esp_wifi::{
|
||||||
esp_now::{PeerInfo, BROADCAST_ADDRESS},
|
esp_now::{PeerInfo, BROADCAST_ADDRESS},
|
||||||
init,
|
init,
|
||||||
EspWifiInitFor,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
|
macro_rules! mk_static {
|
||||||
|
($t:ty,$val:expr) => {{
|
||||||
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||||
|
#[deny(unused_attributes)]
|
||||||
|
let x = STATIC_CELL.uninit().write(($val));
|
||||||
|
x
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[esp_hal_embassy::main]
|
#[esp_hal_embassy::main]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
esp_println::logger::init_logger_from_env();
|
esp_println::logger::init_logger_from_env();
|
||||||
@ -36,13 +46,15 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Wifi,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let wifi = peripherals.WIFI;
|
let wifi = peripherals.WIFI;
|
||||||
let mut esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap();
|
let mut esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap();
|
||||||
|
|||||||
@ -20,7 +20,7 @@ use esp_println::println;
|
|||||||
use esp_wifi::{
|
use esp_wifi::{
|
||||||
esp_now::{EspNowManager, EspNowReceiver, EspNowSender, PeerInfo, BROADCAST_ADDRESS},
|
esp_now::{EspNowManager, EspNowReceiver, EspNowSender, PeerInfo, BROADCAST_ADDRESS},
|
||||||
init,
|
init,
|
||||||
EspWifiInitFor,
|
EspWifiController,
|
||||||
};
|
};
|
||||||
|
|
||||||
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
@ -46,13 +46,15 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = &*mk_static!(
|
||||||
EspWifiInitFor::Wifi,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let wifi = peripherals.WIFI;
|
let wifi = peripherals.WIFI;
|
||||||
let esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap();
|
let esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap();
|
||||||
|
|||||||
@ -18,8 +18,8 @@ use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
|||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_alloc as _;
|
use esp_alloc as _;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{prelude::*, timer::timg::TimerGroup};
|
use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup};
|
||||||
use esp_wifi::ble::controller::asynch::BleConnector;
|
use esp_wifi::{ble::controller::BleConnector, init, EspWifiController};
|
||||||
use log::*;
|
use log::*;
|
||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
use trouble_host::{
|
use trouble_host::{
|
||||||
@ -31,6 +31,16 @@ use trouble_host::{
|
|||||||
PacketQos,
|
PacketQos,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||||
|
macro_rules! mk_static {
|
||||||
|
($t:ty,$val:expr) => {{
|
||||||
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||||
|
#[deny(unused_attributes)]
|
||||||
|
let x = STATIC_CELL.uninit().write(($val));
|
||||||
|
x
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[esp_hal_embassy::main]
|
#[esp_hal_embassy::main]
|
||||||
async fn main(_s: Spawner) {
|
async fn main(_s: Spawner) {
|
||||||
esp_println::logger::init_logger_from_env();
|
esp_println::logger::init_logger_from_env();
|
||||||
@ -44,13 +54,15 @@ async fn main(_s: Spawner) {
|
|||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = esp_wifi::init(
|
let init = &*mk_static!(
|
||||||
esp_wifi::EspWifiInitFor::Ble,
|
EspWifiController<'static>,
|
||||||
timg0.timer0,
|
init(
|
||||||
esp_hal::rng::Rng::new(peripherals.RNG),
|
timg0.timer0,
|
||||||
peripherals.RADIO_CLK,
|
Rng::new(peripherals.RNG),
|
||||||
)
|
peripherals.RADIO_CLK,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "esp32")]
|
#[cfg(feature = "esp32")]
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,7 +20,6 @@ use esp_println::println;
|
|||||||
use esp_wifi::{
|
use esp_wifi::{
|
||||||
esp_now::{PeerInfo, BROADCAST_ADDRESS},
|
esp_now::{PeerInfo, BROADCAST_ADDRESS},
|
||||||
init,
|
init,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
@ -37,7 +36,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -19,13 +19,9 @@ use core::cell::RefCell;
|
|||||||
|
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup};
|
||||||
prelude::*,
|
|
||||||
rng::Rng,
|
|
||||||
timer::{timg::TimerGroup, AnyTimer, PeriodicTimer},
|
|
||||||
};
|
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
use esp_wifi::{init, wifi, EspWifiInitFor};
|
use esp_wifi::{init, wifi};
|
||||||
use ieee80211::{match_frames, mgmt_frame::BeaconFrame};
|
use ieee80211::{match_frames, mgmt_frame::BeaconFrame};
|
||||||
|
|
||||||
static KNOWN_SSIDS: Mutex<RefCell<BTreeSet<String>>> = Mutex::new(RefCell::new(BTreeSet::new()));
|
static KNOWN_SSIDS: Mutex<RefCell<BTreeSet<String>>> = Mutex::new(RefCell::new(BTreeSet::new()));
|
||||||
@ -42,12 +38,8 @@ fn main() -> ! {
|
|||||||
esp_alloc::heap_allocator!(72 * 1024);
|
esp_alloc::heap_allocator!(72 * 1024);
|
||||||
|
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
let timer0: AnyTimer = timg0.timer0.into();
|
|
||||||
let timer = PeriodicTimer::new(timer0);
|
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
timg0.timer0,
|
||||||
timer,
|
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -34,7 +34,6 @@ use esp_wifi::{
|
|||||||
WifiStaDevice,
|
WifiStaDevice,
|
||||||
},
|
},
|
||||||
wifi_interface::WifiStack,
|
wifi_interface::WifiStack,
|
||||||
EspWifiInitFor,
|
|
||||||
};
|
};
|
||||||
use smoltcp::iface::SocketStorage;
|
use smoltcp::iface::SocketStorage;
|
||||||
|
|
||||||
@ -57,7 +56,6 @@ fn main() -> ! {
|
|||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
|
|
||||||
let init = init(
|
let init = init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
@ -17,7 +17,6 @@ use esp_hal::{
|
|||||||
rng::Rng,
|
rng::Rng,
|
||||||
timer::timg::TimerGroup,
|
timer::timg::TimerGroup,
|
||||||
};
|
};
|
||||||
use esp_wifi::{init, EspWifiInitFor};
|
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
@ -101,8 +100,7 @@ mod tests {
|
|||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
fn fpu_stays_enabled_with_wifi(peripherals: Peripherals) {
|
fn fpu_stays_enabled_with_wifi(peripherals: Peripherals) {
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
let _init = init(
|
let _init = esp_wifi::init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer1,
|
timg0.timer1,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
@ -138,8 +136,7 @@ mod tests {
|
|||||||
unsafe { &mut *core::ptr::addr_of_mut!(APP_CORE_STACK) },
|
unsafe { &mut *core::ptr::addr_of_mut!(APP_CORE_STACK) },
|
||||||
move || {
|
move || {
|
||||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
let _init = init(
|
let _init = esp_wifi::init(
|
||||||
EspWifiInitFor::Wifi,
|
|
||||||
timg0.timer1,
|
timg0.timer1,
|
||||||
Rng::new(peripherals.RNG),
|
Rng::new(peripherals.RNG),
|
||||||
peripherals.RADIO_CLK,
|
peripherals.RADIO_CLK,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user