mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 04:10:28 +00:00
esp-wifi: Add unstable feature, mark ble
, esp-now
, csi
, sniffer
, and smoltcp
features and APIs as unstable (#3865)
* esp-wifi: Add unstable feature, mark ble, esp-now and csi features and APIs as unstable * changelog * fix hils * rebase and reviews * rebase * Make at least wifi_embassy_dhcp work without unstable feature * remove rand_core * rebase * Check if a feature is selected which needs unstable * reviews and fix ci * reviews
This commit is contained in:
parent
dfd66be8ab
commit
0fbbe2d22c
@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `AccessPointInfo::country` to access the Country Code from the Wi-Fi scan results (#3837)
|
- `AccessPointInfo::country` to access the Country Code from the Wi-Fi scan results (#3837)
|
||||||
|
- `unstable` feature to opt into `ble`, `esp-now`, `csi`, `sniffer`, `esp-ieee802154` and `smoltcp` APIs (#3865)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Removed `EspWifi` prefix from structs in the package codebase. (#3869)
|
- Removed `EspWifi` prefix from structs in the package codebase. (#3869)
|
||||||
- Rename `esp-wifi` to `esp-radio`. (#3858)
|
- Rename `esp-wifi` to `esp-radio`. (#3858)
|
||||||
- `esp-ieee802154` package has been folded into `esp-radio`. (#3861)
|
- `esp-ieee802154` package has been folded into `esp-radio`. (#3861)
|
||||||
|
- `ble`, `esp-now`, `csi`, `sniffer`, `esp-ieee802154` and `smoltcp` features and APIs marked as unstable (#3865)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ enumset = { version = "1.1.6", default-features = false, optional = true }
|
|||||||
embedded-io = { version = "0.6.1", default-features = false }
|
embedded-io = { version = "0.6.1", default-features = false }
|
||||||
embedded-io-async = { version = "0.6.1" }
|
embedded-io-async = { version = "0.6.1" }
|
||||||
esp-radio-preempt-driver = { version = "0.0.1", path = "../esp-radio-preempt-driver" }
|
esp-radio-preempt-driver = { version = "0.0.1", path = "../esp-radio-preempt-driver" }
|
||||||
rand_core = "0.9.3"
|
|
||||||
heapless = "0.8.0"
|
heapless = "0.8.0"
|
||||||
|
instability = "0.3.9"
|
||||||
|
|
||||||
# Unstable dependencies that are not (strictly) part of the public API
|
# Unstable dependencies that are not (strictly) part of the public API
|
||||||
allocator-api2 = { version = "0.3.0", default-features = false, features = ["alloc"] }
|
allocator-api2 = { version = "0.3.0", default-features = false, features = ["alloc"] }
|
||||||
@ -158,6 +158,17 @@ log-04 = ["dep:log-04", "esp-hal/log-04", "esp-wifi-sys/log"]
|
|||||||
## Enable logging output using `defmt` and implement `defmt::Format` on certain types.
|
## Enable logging output using `defmt` and implement `defmt::Format` on certain types.
|
||||||
defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt", "bt-hci?/defmt", "esp-wifi-sys/defmt", "enumset/defmt"]
|
defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt", "bt-hci?/defmt", "esp-wifi-sys/defmt", "enumset/defmt"]
|
||||||
|
|
||||||
|
#! ### Unstable APIs
|
||||||
|
#! Unstable APIs are drivers and features that are not yet ready for general use.
|
||||||
|
#! They may be incomplete, have bugs, or be subject to change without notice.
|
||||||
|
unstable = []
|
||||||
|
|
||||||
|
## Libraries that depend on `esp-radio` should enable this feature to indicate their use of unstable APIs.
|
||||||
|
## However, they must **not** enable the `unstable` feature themselves.
|
||||||
|
##
|
||||||
|
## For development you can enable the `unstable` and the chip feature by adding esp-radio as a dev-dependency.
|
||||||
|
requires-unstable = []
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = [
|
features = [
|
||||||
"esp32c3",
|
"esp32c3",
|
||||||
|
@ -21,6 +21,27 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
// Define all necessary configuration symbols for the configured device:
|
// Define all necessary configuration symbols for the configured device:
|
||||||
chip.define_cfgs();
|
chip.define_cfgs();
|
||||||
|
|
||||||
|
// If some library required unstable make sure unstable is actually enabled.
|
||||||
|
if cfg!(feature = "requires-unstable") && !cfg!(feature = "unstable") {
|
||||||
|
panic!(
|
||||||
|
"\n\nThe `unstable` feature is required by a dependent crate but is not enabled.\n\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg!(feature = "ble")
|
||||||
|
|| cfg!(feature = "coex")
|
||||||
|
|| cfg!(feature = "csi")
|
||||||
|
|| cfg!(feature = "esp-now")
|
||||||
|
|| cfg!(feature = "ieee802154")
|
||||||
|
|| cfg!(feature = "smoltcp")
|
||||||
|
|| cfg!(feature = "sniffer"))
|
||||||
|
&& !cfg!(feature = "unstable")
|
||||||
|
{
|
||||||
|
panic!(
|
||||||
|
"\n\nThe `unstable` feature was not provided, but is required for the following features: `ble`, `coex`, `csi`, `esp-now`, `ieee802154`, `smoltcp`, `sniffer`.\n\n"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Log and defmt are mutually exclusive features. The main technical reason is
|
// Log and defmt are mutually exclusive features. The main technical reason is
|
||||||
// that allowing both would make the exact panicking behaviour a fragile
|
// that allowing both would make the exact panicking behaviour a fragile
|
||||||
// implementation detail.
|
// implementation detail.
|
||||||
|
@ -468,7 +468,8 @@ pub(crate) fn ble_deinit() {
|
|||||||
crate::common_adapter::chip_specific::phy_disable();
|
crate::common_adapter::chip_specific::phy_disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Sends HCI data to the BLE controller.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn send_hci(data: &[u8]) {
|
pub fn send_hci(data: &[u8]) {
|
||||||
let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
|
let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
|
||||||
hci_out.push(data);
|
hci_out.push(data);
|
||||||
|
@ -4,6 +4,7 @@ use super::{read_hci, read_next, send_hci};
|
|||||||
use crate::Controller;
|
use crate::Controller;
|
||||||
|
|
||||||
/// A blocking HCI connector
|
/// A blocking HCI connector
|
||||||
|
#[instability::unstable]
|
||||||
pub struct BleConnector<'d> {
|
pub struct BleConnector<'d> {
|
||||||
_device: crate::hal::peripherals::BT<'d>,
|
_device: crate::hal::peripherals::BT<'d>,
|
||||||
}
|
}
|
||||||
@ -15,6 +16,8 @@ impl Drop for BleConnector<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> BleConnector<'d> {
|
impl<'d> BleConnector<'d> {
|
||||||
|
/// Create and init a new BLE connector.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_init: &'d Controller<'d>,
|
_init: &'d Controller<'d>,
|
||||||
device: crate::hal::peripherals::BT<'d>,
|
device: crate::hal::peripherals::BT<'d>,
|
||||||
@ -24,12 +27,16 @@ impl<'d> BleConnector<'d> {
|
|||||||
Self { _device: device }
|
Self { _device: device }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the next HCI packet from the BLE controller.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn next(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
|
pub fn next(&mut self, buf: &mut [u8]) -> Result<usize, BleConnectorError> {
|
||||||
Ok(read_next(buf))
|
Ok(read_next(buf))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
/// Error type for the BLE connector.
|
||||||
|
#[instability::unstable]
|
||||||
pub enum BleConnectorError {
|
pub enum BleConnectorError {
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ use self::btdm as ble;
|
|||||||
#[cfg(any(esp32c2, esp32c6, esp32h2))]
|
#[cfg(any(esp32c2, esp32c6, esp32h2))]
|
||||||
use self::npl as ble;
|
use self::npl as ble;
|
||||||
|
|
||||||
pub mod controller;
|
unstable_module! {
|
||||||
|
pub mod controller;
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) unsafe extern "C" fn malloc(size: u32) -> *mut crate::binary::c_types::c_void {
|
pub(crate) unsafe extern "C" fn malloc(size: u32) -> *mut crate::binary::c_types::c_void {
|
||||||
unsafe { crate::compat::malloc::malloc(size as usize).cast() }
|
unsafe { crate::compat::malloc::malloc(size as usize).cast() }
|
||||||
@ -108,7 +110,10 @@ impl HciOutCollector {
|
|||||||
static BLE_HCI_READ_DATA: Mutex<RefCell<Vec<u8>>> = Mutex::new(RefCell::new(Vec::new()));
|
static BLE_HCI_READ_DATA: Mutex<RefCell<Vec<u8>>> = Mutex::new(RefCell::new(Vec::new()));
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
/// Represents a received BLE packet.
|
||||||
|
#[instability::unstable]
|
||||||
pub struct ReceivedPacket {
|
pub struct ReceivedPacket {
|
||||||
|
/// The data of the received packet.
|
||||||
pub data: Box<[u8]>,
|
pub data: Box<[u8]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +124,8 @@ impl defmt::Format for ReceivedPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if there is any HCI data available to read.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn have_hci_read_data() -> bool {
|
pub fn have_hci_read_data() -> bool {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
|
let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
|
||||||
@ -141,6 +148,8 @@ pub(crate) fn read_next(data: &mut [u8]) -> usize {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reads the next HCI packet from the BLE controller.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn read_hci(data: &mut [u8]) -> usize {
|
pub fn read_hci(data: &mut [u8]) -> usize {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let mut hci_read_data = BLE_HCI_READ_DATA.borrow_ref_mut(cs);
|
let mut hci_read_data = BLE_HCI_READ_DATA.borrow_ref_mut(cs);
|
||||||
|
@ -138,7 +138,7 @@ impl OsMbufPool {
|
|||||||
|
|
||||||
/// Chained memory buffer.
|
/// Chained memory buffer.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct OsMbuf {
|
pub(crate) struct OsMbuf {
|
||||||
/// Current pointer to data in the structure
|
/// Current pointer to data in the structure
|
||||||
om_data: *const u8,
|
om_data: *const u8,
|
||||||
/// Flags associated with this buffer, see OS_MBUF_F_* defintions
|
/// Flags associated with this buffer, see OS_MBUF_F_* defintions
|
||||||
@ -279,7 +279,8 @@ unsafe extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ExtFuncsT {
|
/// Contains pointers to external functions used by the BLE stack.
|
||||||
|
pub(crate) struct ExtFuncsT {
|
||||||
ext_version: u32,
|
ext_version: u32,
|
||||||
esp_intr_alloc: Option<
|
esp_intr_alloc: Option<
|
||||||
unsafe extern "C" fn(
|
unsafe extern "C" fn(
|
||||||
@ -428,7 +429,8 @@ unsafe extern "C" fn esp_intr_free(_ret_handle: *mut *mut c_void) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct npl_funcs_t {
|
/// Contains pointers to functions used by the BLE NPL (Non-Preemptive Layer).
|
||||||
|
pub(crate) struct npl_funcs_t {
|
||||||
p_ble_npl_os_started: Option<unsafe extern "C" fn() -> bool>,
|
p_ble_npl_os_started: Option<unsafe extern "C" fn() -> bool>,
|
||||||
p_ble_npl_get_current_task_id: Option<unsafe extern "C" fn() -> *const c_void>,
|
p_ble_npl_get_current_task_id: Option<unsafe extern "C" fn() -> *const c_void>,
|
||||||
p_ble_npl_eventq_init: Option<unsafe extern "C" fn(queue: *const ble_npl_eventq)>,
|
p_ble_npl_eventq_init: Option<unsafe extern "C" fn(queue: *const ble_npl_eventq)>,
|
||||||
@ -564,7 +566,8 @@ static mut G_NPL_FUNCS: npl_funcs_t = npl_funcs_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct OsiCoexFuncsT {
|
/// Contains pointers to functions used for BLE coexistence with Wi-Fi.
|
||||||
|
pub(crate) struct OsiCoexFuncsT {
|
||||||
magic: u32,
|
magic: u32,
|
||||||
version: u32,
|
version: u32,
|
||||||
coex_wifi_sleep_set: Option<unsafe extern "C" fn(sleep: bool)>,
|
coex_wifi_sleep_set: Option<unsafe extern "C" fn(sleep: bool)>,
|
||||||
@ -1053,7 +1056,8 @@ unsafe extern "C" fn ble_npl_os_started() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct BleNplCountInfoT {
|
/// Contains information about the BLE NPL (Non-Preemptive Layer) elements.
|
||||||
|
pub(crate) struct BleNplCountInfoT {
|
||||||
evt_count: u16,
|
evt_count: u16,
|
||||||
evtq_count: u16,
|
evtq_count: u16,
|
||||||
co_count: u16,
|
co_count: u16,
|
||||||
@ -1400,6 +1404,8 @@ unsafe extern "C" fn ble_hs_rx_data(om: *const OsMbuf, arg: *const c_void) -> i3
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sends HCI data to the Bluetooth controller.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn send_hci(data: &[u8]) {
|
pub fn send_hci(data: &[u8]) {
|
||||||
let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
|
let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
|
||||||
hci_out.push(data);
|
hci_out.push(data);
|
||||||
|
@ -16,17 +16,17 @@ use crate::{
|
|||||||
hal::{interrupt, peripherals::Interrupt},
|
hal::{interrupt, peripherals::Interrupt},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static mut ISR_INTERRUPT_5: (
|
pub(crate) static mut ISR_INTERRUPT_5: (
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
||||||
|
|
||||||
pub static mut ISR_INTERRUPT_8: (
|
pub(crate) static mut ISR_INTERRUPT_8: (
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
||||||
|
|
||||||
pub static mut ISR_INTERRUPT_7: (
|
pub(crate) static mut ISR_INTERRUPT_7: (
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
||||||
|
@ -4,12 +4,12 @@ use crate::{
|
|||||||
hal::{interrupt, peripherals::Interrupt},
|
hal::{interrupt, peripherals::Interrupt},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static mut ISR_INTERRUPT_5: (
|
pub(crate) static mut ISR_INTERRUPT_5: (
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
||||||
|
|
||||||
pub static mut ISR_INTERRUPT_8: (
|
pub(crate) static mut ISR_INTERRUPT_8: (
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
*mut crate::binary::c_types::c_void,
|
*mut crate::binary::c_types::c_void,
|
||||||
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
) = (core::ptr::null_mut(), core::ptr::null_mut());
|
||||||
|
@ -10,11 +10,18 @@
|
|||||||
//! For more information see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html
|
//! For more information see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html
|
||||||
|
|
||||||
use alloc::{boxed::Box, collections::vec_deque::VecDeque};
|
use alloc::{boxed::Box, collections::vec_deque::VecDeque};
|
||||||
use core::{cell::RefCell, fmt::Debug, marker::PhantomData};
|
use core::{
|
||||||
|
cell::RefCell,
|
||||||
|
fmt::Debug,
|
||||||
|
marker::PhantomData,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
|
use esp_hal::asynch::AtomicWaker;
|
||||||
use portable_atomic::{AtomicBool, AtomicU8, Ordering};
|
use portable_atomic::{AtomicBool, AtomicU8, Ordering};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
#[cfg(feature = "csi")]
|
#[cfg(feature = "csi")]
|
||||||
use crate::wifi::CsiConfig;
|
use crate::wifi::CsiConfig;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -69,6 +76,7 @@ macro_rules! check_error_expect {
|
|||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// ESP-NOW is not initialized.
|
/// ESP-NOW is not initialized.
|
||||||
NotInitialized = 12389,
|
NotInitialized = 12389,
|
||||||
@ -100,6 +108,7 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
#[instability::unstable]
|
||||||
pub fn from_code(code: u32) -> Error {
|
pub fn from_code(code: u32) -> Error {
|
||||||
match code {
|
match code {
|
||||||
12389 => Error::NotInitialized,
|
12389 => Error::NotInitialized,
|
||||||
@ -118,6 +127,7 @@ impl Error {
|
|||||||
/// Common errors that can occur while using ESP-NOW driver.
|
/// Common errors that can occur while using ESP-NOW driver.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub enum EspNowError {
|
pub enum EspNowError {
|
||||||
/// Internal Error.
|
/// Internal Error.
|
||||||
Error(Error),
|
Error(Error),
|
||||||
@ -138,6 +148,7 @@ impl From<WifiError> for EspNowError {
|
|||||||
/// Holds the count of peers in an ESP-NOW communication context.
|
/// Holds the count of peers in an ESP-NOW communication context.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub struct PeerCount {
|
pub struct PeerCount {
|
||||||
/// The total number of peers.
|
/// The total number of peers.
|
||||||
pub total_count: i32,
|
pub total_count: i32,
|
||||||
@ -149,6 +160,7 @@ pub struct PeerCount {
|
|||||||
/// ESP-NOW rate of specified interface.
|
/// ESP-NOW rate of specified interface.
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub enum WifiPhyRate {
|
pub enum WifiPhyRate {
|
||||||
/// < 1 Mbps with long preamble
|
/// < 1 Mbps with long preamble
|
||||||
Rate1mL = 0,
|
Rate1mL = 0,
|
||||||
@ -223,6 +235,7 @@ pub enum WifiPhyRate {
|
|||||||
/// ESP-NOW peer information parameters.
|
/// ESP-NOW peer information parameters.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub struct PeerInfo {
|
pub struct PeerInfo {
|
||||||
/// Interface to use
|
/// Interface to use
|
||||||
pub interface: EspNowWifiInterface,
|
pub interface: EspNowWifiInterface,
|
||||||
@ -245,6 +258,7 @@ pub struct PeerInfo {
|
|||||||
/// Information about a received packet.
|
/// Information about a received packet.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub struct ReceiveInfo {
|
pub struct ReceiveInfo {
|
||||||
/// The source address of the received packet.
|
/// The source address of the received packet.
|
||||||
pub src_address: [u8; 6],
|
pub src_address: [u8; 6],
|
||||||
@ -259,6 +273,7 @@ pub struct ReceiveInfo {
|
|||||||
/// Stores information about the received data, including the packet content and
|
/// Stores information about the received data, including the packet content and
|
||||||
/// associated information.
|
/// associated information.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[instability::unstable]
|
||||||
pub struct ReceivedData {
|
pub struct ReceivedData {
|
||||||
data: Box<[u8]>,
|
data: Box<[u8]>,
|
||||||
pub info: ReceiveInfo,
|
pub info: ReceiveInfo,
|
||||||
@ -266,6 +281,7 @@ pub struct ReceivedData {
|
|||||||
|
|
||||||
impl ReceivedData {
|
impl ReceivedData {
|
||||||
/// Returns the received payload.
|
/// Returns the received payload.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn data(&self) -> &[u8] {
|
pub fn data(&self) -> &[u8] {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
@ -290,6 +306,7 @@ impl Debug for ReceivedData {
|
|||||||
/// The interface to use for this peer
|
/// The interface to use for this peer
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[instability::unstable]
|
||||||
pub enum EspNowWifiInterface {
|
pub enum EspNowWifiInterface {
|
||||||
/// Use the AP interface
|
/// Use the AP interface
|
||||||
Ap,
|
Ap,
|
||||||
@ -317,6 +334,7 @@ impl EspNowWifiInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Manages the `EspNow` instance lifecycle while ensuring it remains active.
|
/// Manages the `EspNow` instance lifecycle while ensuring it remains active.
|
||||||
|
#[instability::unstable]
|
||||||
pub struct EspNowManager<'d> {
|
pub struct EspNowManager<'d> {
|
||||||
_rc: EspNowRc<'d>,
|
_rc: EspNowRc<'d>,
|
||||||
}
|
}
|
||||||
@ -324,11 +342,13 @@ pub struct EspNowManager<'d> {
|
|||||||
impl EspNowManager<'_> {
|
impl EspNowManager<'_> {
|
||||||
/// Set primary WiFi channel.
|
/// Set primary WiFi channel.
|
||||||
/// Should only be used when using ESP-NOW without AP or STA.
|
/// Should only be used when using ESP-NOW without AP or STA.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> {
|
pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> {
|
||||||
check_error!({ esp_wifi_set_channel(channel, 0) })
|
check_error!({ esp_wifi_set_channel(channel, 0) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the version of ESP-NOW.
|
/// Get the version of ESP-NOW.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn version(&self) -> Result<u32, EspNowError> {
|
pub fn version(&self) -> Result<u32, EspNowError> {
|
||||||
let mut version = 0u32;
|
let mut version = 0u32;
|
||||||
check_error!({ esp_now_get_version(&mut version as *mut u32) })?;
|
check_error!({ esp_now_get_version(&mut version as *mut u32) })?;
|
||||||
@ -336,6 +356,7 @@ impl EspNowManager<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add a peer to the list of known peers.
|
/// Add a peer to the list of known peers.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
||||||
let raw_peer = esp_now_peer_info_t {
|
let raw_peer = esp_now_peer_info_t {
|
||||||
peer_addr: peer.peer_address,
|
peer_addr: peer.peer_address,
|
||||||
@ -350,6 +371,7 @@ impl EspNowManager<'_> {
|
|||||||
|
|
||||||
/// Set CSI configuration and register the receiving callback.
|
/// Set CSI configuration and register the receiving callback.
|
||||||
#[cfg(feature = "csi")]
|
#[cfg(feature = "csi")]
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_csi(
|
pub fn set_csi(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut csi: CsiConfig,
|
mut csi: CsiConfig,
|
||||||
@ -363,11 +385,13 @@ impl EspNowManager<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the given peer.
|
/// Remove the given peer.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> {
|
pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> {
|
||||||
check_error!({ esp_now_del_peer(peer_address.as_ptr()) })
|
check_error!({ esp_now_del_peer(peer_address.as_ptr()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modify a peer information.
|
/// Modify a peer information.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
||||||
let raw_peer = esp_now_peer_info_t {
|
let raw_peer = esp_now_peer_info_t {
|
||||||
peer_addr: peer.peer_address,
|
peer_addr: peer.peer_address,
|
||||||
@ -381,6 +405,7 @@ impl EspNowManager<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get peer by MAC address.
|
/// Get peer by MAC address.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn peer(&self, peer_address: &[u8; 6]) -> Result<PeerInfo, EspNowError> {
|
pub fn peer(&self, peer_address: &[u8; 6]) -> Result<PeerInfo, EspNowError> {
|
||||||
let mut raw_peer = esp_now_peer_info_t {
|
let mut raw_peer = esp_now_peer_info_t {
|
||||||
peer_addr: [0u8; 6],
|
peer_addr: [0u8; 6],
|
||||||
@ -414,6 +439,7 @@ impl EspNowManager<'_> {
|
|||||||
/// Only returns peers which address is unicast, for multicast/broadcast
|
/// Only returns peers which address is unicast, for multicast/broadcast
|
||||||
/// addresses, the function will skip the entry and find the next in the
|
/// addresses, the function will skip the entry and find the next in the
|
||||||
/// peer list.
|
/// peer list.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn fetch_peer(&self, from_head: bool) -> Result<PeerInfo, EspNowError> {
|
pub fn fetch_peer(&self, from_head: bool) -> Result<PeerInfo, EspNowError> {
|
||||||
let mut raw_peer = esp_now_peer_info_t {
|
let mut raw_peer = esp_now_peer_info_t {
|
||||||
peer_addr: [0u8; 6],
|
peer_addr: [0u8; 6],
|
||||||
@ -443,11 +469,13 @@ impl EspNowManager<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check is peer is known.
|
/// Check is peer is known.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool {
|
pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool {
|
||||||
unsafe { esp_now_is_peer_exist(peer_address.as_ptr()) }
|
unsafe { esp_now_is_peer_exist(peer_address.as_ptr()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of peers.
|
/// Get the number of peers.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn peer_count(&self) -> Result<PeerCount, EspNowError> {
|
pub fn peer_count(&self) -> Result<PeerCount, EspNowError> {
|
||||||
let mut peer_num = esp_now_peer_num_t {
|
let mut peer_num = esp_now_peer_num_t {
|
||||||
total_num: 0,
|
total_num: 0,
|
||||||
@ -462,6 +490,7 @@ impl EspNowManager<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the primary master key.
|
/// Set the primary master key.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> {
|
pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> {
|
||||||
check_error!({ esp_now_set_pmk(pmk.as_ptr()) })
|
check_error!({ esp_now_set_pmk(pmk.as_ptr()) })
|
||||||
}
|
}
|
||||||
@ -470,11 +499,13 @@ impl EspNowManager<'_> {
|
|||||||
///
|
///
|
||||||
/// Window is milliseconds the chip keep waked each interval, from 0 to
|
/// Window is milliseconds the chip keep waked each interval, from 0 to
|
||||||
/// 65535.
|
/// 65535.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> {
|
pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> {
|
||||||
check_error!({ esp_now_set_wake_window(wake_window) })
|
check_error!({ esp_now_set_wake_window(wake_window) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure ESP-NOW rate.
|
/// Configure ESP-NOW rate.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> {
|
pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> {
|
||||||
check_error!({ esp_wifi_config_espnow_rate(wifi_interface_t_WIFI_IF_STA, rate as u32,) })
|
check_error!({ esp_wifi_config_espnow_rate(wifi_interface_t_WIFI_IF_STA, rate as u32,) })
|
||||||
}
|
}
|
||||||
@ -487,6 +518,7 @@ impl EspNowManager<'_> {
|
|||||||
/// **DO NOT USE** a lock implementation that disables interrupts since the
|
/// **DO NOT USE** a lock implementation that disables interrupts since the
|
||||||
/// completion of a sending requires waiting for a callback invoked in an
|
/// completion of a sending requires waiting for a callback invoked in an
|
||||||
/// interrupt.
|
/// interrupt.
|
||||||
|
#[instability::unstable]
|
||||||
pub struct EspNowSender<'d> {
|
pub struct EspNowSender<'d> {
|
||||||
_rc: EspNowRc<'d>,
|
_rc: EspNowRc<'d>,
|
||||||
}
|
}
|
||||||
@ -495,6 +527,7 @@ impl EspNowSender<'_> {
|
|||||||
/// Send data to peer
|
/// Send data to peer
|
||||||
///
|
///
|
||||||
/// The peer needs to be added to the peer list first.
|
/// The peer needs to be added to the peer list first.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn send<'s>(
|
pub fn send<'s>(
|
||||||
&'s mut self,
|
&'s mut self,
|
||||||
dst_addr: &[u8; 6],
|
dst_addr: &[u8; 6],
|
||||||
@ -519,11 +552,13 @@ impl EspNowSender<'_> {
|
|||||||
/// since the callback which signals the completion of sending will never be
|
/// since the callback which signals the completion of sending will never be
|
||||||
/// invoked.
|
/// invoked.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
#[instability::unstable]
|
||||||
pub struct SendWaiter<'s>(PhantomData<&'s mut EspNowSender<'s>>);
|
pub struct SendWaiter<'s>(PhantomData<&'s mut EspNowSender<'s>>);
|
||||||
|
|
||||||
impl SendWaiter<'_> {
|
impl SendWaiter<'_> {
|
||||||
/// Wait for the previous sending to complete, i.e. the send callback is
|
/// Wait for the previous sending to complete, i.e. the send callback is
|
||||||
/// invoked with status of the sending.
|
/// invoked with status of the sending.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn wait(self) -> Result<(), EspNowError> {
|
pub fn wait(self) -> Result<(), EspNowError> {
|
||||||
// prevent redundant waiting since we waits for the callback in the Drop
|
// prevent redundant waiting since we waits for the callback in the Drop
|
||||||
// implementation
|
// implementation
|
||||||
@ -548,12 +583,14 @@ impl Drop for SendWaiter<'_> {
|
|||||||
|
|
||||||
/// This is the receiver part of ESP-NOW. You can get this receiver by splitting
|
/// This is the receiver part of ESP-NOW. You can get this receiver by splitting
|
||||||
/// an `EspNow` instance.
|
/// an `EspNow` instance.
|
||||||
|
#[instability::unstable]
|
||||||
pub struct EspNowReceiver<'d> {
|
pub struct EspNowReceiver<'d> {
|
||||||
_rc: EspNowRc<'d>,
|
_rc: EspNowRc<'d>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EspNowReceiver<'_> {
|
impl EspNowReceiver<'_> {
|
||||||
/// Receives data from the ESP-NOW queue.
|
/// Receives data from the ESP-NOW queue.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn receive(&self) -> Option<ReceivedData> {
|
pub fn receive(&self) -> Option<ReceivedData> {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
|
let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
|
||||||
@ -613,6 +650,7 @@ impl Drop for EspNowRc<'_> {
|
|||||||
///
|
///
|
||||||
/// For convenience, by default there will be a broadcast peer added on the STA
|
/// For convenience, by default there will be a broadcast peer added on the STA
|
||||||
/// interface.
|
/// interface.
|
||||||
|
#[instability::unstable]
|
||||||
pub struct EspNow<'d> {
|
pub struct EspNow<'d> {
|
||||||
manager: EspNowManager<'d>,
|
manager: EspNowManager<'d>,
|
||||||
sender: EspNowSender<'d>,
|
sender: EspNowSender<'d>,
|
||||||
@ -659,37 +697,44 @@ impl<'d> EspNow<'d> {
|
|||||||
|
|
||||||
/// Splits the `EspNow` instance into its manager, sender, and receiver
|
/// Splits the `EspNow` instance into its manager, sender, and receiver
|
||||||
/// components.
|
/// components.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn split(self) -> (EspNowManager<'d>, EspNowSender<'d>, EspNowReceiver<'d>) {
|
pub fn split(self) -> (EspNowManager<'d>, EspNowSender<'d>, EspNowReceiver<'d>) {
|
||||||
(self.manager, self.sender, self.receiver)
|
(self.manager, self.sender, self.receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set primary WiFi channel.
|
/// Set primary WiFi channel.
|
||||||
/// Should only be used when using ESP-NOW without AP or STA.
|
/// Should only be used when using ESP-NOW without AP or STA.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> {
|
pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> {
|
||||||
self.manager.set_channel(channel)
|
self.manager.set_channel(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the version of ESP-NOW.
|
/// Get the version of ESP-NOW.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn version(&self) -> Result<u32, EspNowError> {
|
pub fn version(&self) -> Result<u32, EspNowError> {
|
||||||
self.manager.version()
|
self.manager.version()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a peer to the list of known peers.
|
/// Add a peer to the list of known peers.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
||||||
self.manager.add_peer(peer)
|
self.manager.add_peer(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the given peer.
|
/// Remove the given peer.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> {
|
pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> {
|
||||||
self.manager.remove_peer(peer_address)
|
self.manager.remove_peer(peer_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modify a peer information.
|
/// Modify a peer information.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
|
||||||
self.manager.modify_peer(peer)
|
self.manager.modify_peer(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get peer by MAC address.
|
/// Get peer by MAC address.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn peer(&self, peer_address: &[u8; 6]) -> Result<PeerInfo, EspNowError> {
|
pub fn peer(&self, peer_address: &[u8; 6]) -> Result<PeerInfo, EspNowError> {
|
||||||
self.manager.peer(peer_address)
|
self.manager.peer(peer_address)
|
||||||
}
|
}
|
||||||
@ -699,21 +744,25 @@ impl<'d> EspNow<'d> {
|
|||||||
/// Only returns peers which address is unicast, for multicast/broadcast
|
/// Only returns peers which address is unicast, for multicast/broadcast
|
||||||
/// addresses, the function will skip the entry and find the next in the
|
/// addresses, the function will skip the entry and find the next in the
|
||||||
/// peer list.
|
/// peer list.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn fetch_peer(&self, from_head: bool) -> Result<PeerInfo, EspNowError> {
|
pub fn fetch_peer(&self, from_head: bool) -> Result<PeerInfo, EspNowError> {
|
||||||
self.manager.fetch_peer(from_head)
|
self.manager.fetch_peer(from_head)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check is peer is known.
|
/// Check is peer is known.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool {
|
pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool {
|
||||||
self.manager.peer_exists(peer_address)
|
self.manager.peer_exists(peer_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of peers.
|
/// Get the number of peers.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn peer_count(&self) -> Result<PeerCount, EspNowError> {
|
pub fn peer_count(&self) -> Result<PeerCount, EspNowError> {
|
||||||
self.manager.peer_count()
|
self.manager.peer_count()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the primary master key.
|
/// Set the primary master key.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> {
|
pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> {
|
||||||
self.manager.set_pmk(pmk)
|
self.manager.set_pmk(pmk)
|
||||||
}
|
}
|
||||||
@ -722,11 +771,13 @@ impl<'d> EspNow<'d> {
|
|||||||
///
|
///
|
||||||
/// Window is milliseconds the chip keep waked each interval, from 0 to
|
/// Window is milliseconds the chip keep waked each interval, from 0 to
|
||||||
/// 65535.
|
/// 65535.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> {
|
pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> {
|
||||||
self.manager.set_wake_window(wake_window)
|
self.manager.set_wake_window(wake_window)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure ESP-NOW rate.
|
/// Configure ESP-NOW rate.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> {
|
pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> {
|
||||||
self.manager.set_rate(rate)
|
self.manager.set_rate(rate)
|
||||||
}
|
}
|
||||||
@ -734,6 +785,7 @@ impl<'d> EspNow<'d> {
|
|||||||
/// Send data to peer.
|
/// Send data to peer.
|
||||||
///
|
///
|
||||||
/// The peer needs to be added to the peer list first.
|
/// The peer needs to be added to the peer list first.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn send<'s>(
|
pub fn send<'s>(
|
||||||
&'s mut self,
|
&'s mut self,
|
||||||
dst_addr: &[u8; 6],
|
dst_addr: &[u8; 6],
|
||||||
@ -743,6 +795,7 @@ impl<'d> EspNow<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Receive data.
|
/// Receive data.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn receive(&self) -> Option<ReceivedData> {
|
pub fn receive(&self) -> Option<ReceivedData> {
|
||||||
self.receiver.receive()
|
self.receiver.receive()
|
||||||
}
|
}
|
||||||
@ -755,7 +808,7 @@ unsafe extern "C" fn send_cb(_mac_addr: *const u8, status: esp_now_send_status_t
|
|||||||
|
|
||||||
ESP_NOW_SEND_CB_INVOKED.store(true, Ordering::Release);
|
ESP_NOW_SEND_CB_INVOKED.store(true, Ordering::Release);
|
||||||
|
|
||||||
asynch::ESP_NOW_TX_WAKER.wake();
|
ESP_NOW_TX_WAKER.wake();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,123 +858,119 @@ unsafe extern "C" fn rcv_cb(
|
|||||||
|
|
||||||
queue.push_back(ReceivedData { data, info });
|
queue.push_back(ReceivedData { data, info });
|
||||||
|
|
||||||
asynch::ESP_NOW_RX_WAKER.wake();
|
ESP_NOW_RX_WAKER.wake();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use asynch::SendFuture;
|
pub(super) static ESP_NOW_TX_WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
|
pub(super) static ESP_NOW_RX_WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
|
|
||||||
mod asynch {
|
impl EspNowReceiver<'_> {
|
||||||
use core::task::{Context, Poll};
|
/// This function takes mutable reference to self because the
|
||||||
|
/// implementation of `ReceiveFuture` is not logically thread
|
||||||
use esp_hal::asynch::AtomicWaker;
|
/// safe.
|
||||||
|
#[instability::unstable]
|
||||||
use super::*;
|
pub fn receive_async(&mut self) -> ReceiveFuture<'_> {
|
||||||
|
ReceiveFuture(PhantomData)
|
||||||
pub(super) static ESP_NOW_TX_WAKER: AtomicWaker = AtomicWaker::new();
|
|
||||||
pub(super) static ESP_NOW_RX_WAKER: AtomicWaker = AtomicWaker::new();
|
|
||||||
|
|
||||||
impl EspNowReceiver<'_> {
|
|
||||||
/// This function takes mutable reference to self because the
|
|
||||||
/// implementation of `ReceiveFuture` is not logically thread
|
|
||||||
/// safe.
|
|
||||||
pub fn receive_async(&mut self) -> ReceiveFuture<'_> {
|
|
||||||
ReceiveFuture(PhantomData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EspNowSender<'_> {
|
impl EspNowSender<'_> {
|
||||||
/// Sends data asynchronously to a peer (using its MAC) using ESP-NOW.
|
/// Sends data asynchronously to a peer (using its MAC) using ESP-NOW.
|
||||||
pub fn send_async<'s, 'r>(
|
#[instability::unstable]
|
||||||
&'s mut self,
|
pub fn send_async<'s, 'r>(
|
||||||
addr: &'r [u8; 6],
|
&'s mut self,
|
||||||
data: &'r [u8],
|
|
||||||
) -> SendFuture<'s, 'r> {
|
|
||||||
SendFuture {
|
|
||||||
_sender: PhantomData,
|
|
||||||
addr,
|
|
||||||
data,
|
|
||||||
sent: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EspNow<'_> {
|
|
||||||
/// This function takes mutable reference to self because the
|
|
||||||
/// implementation of `ReceiveFuture` is not logically thread
|
|
||||||
/// safe.
|
|
||||||
pub fn receive_async(&mut self) -> ReceiveFuture<'_> {
|
|
||||||
self.receiver.receive_async()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The returned future must not be dropped before it's ready to avoid
|
|
||||||
/// getting wrong status for sendings.
|
|
||||||
pub fn send_async<'s, 'r>(
|
|
||||||
&'s mut self,
|
|
||||||
dst_addr: &'r [u8; 6],
|
|
||||||
data: &'r [u8],
|
|
||||||
) -> SendFuture<'s, 'r> {
|
|
||||||
self.sender.send_async(dst_addr, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `future` representing the result of an asynchronous ESP-NOW send
|
|
||||||
/// operation.
|
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
|
||||||
pub struct SendFuture<'s, 'r> {
|
|
||||||
_sender: PhantomData<&'s mut EspNowSender<'s>>,
|
|
||||||
addr: &'r [u8; 6],
|
addr: &'r [u8; 6],
|
||||||
data: &'r [u8],
|
data: &'r [u8],
|
||||||
sent: bool,
|
) -> SendFuture<'s, 'r> {
|
||||||
}
|
SendFuture {
|
||||||
|
_sender: PhantomData,
|
||||||
impl core::future::Future for SendFuture<'_, '_> {
|
addr,
|
||||||
type Output = Result<(), EspNowError>;
|
data,
|
||||||
|
sent: false,
|
||||||
fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
}
|
||||||
if !self.sent {
|
}
|
||||||
ESP_NOW_TX_WAKER.register(cx.waker());
|
}
|
||||||
ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release);
|
|
||||||
if let Err(e) = check_error!({
|
impl EspNow<'_> {
|
||||||
esp_now_send(self.addr.as_ptr(), self.data.as_ptr(), self.data.len())
|
/// This function takes mutable reference to self because the
|
||||||
}) {
|
/// implementation of `ReceiveFuture` is not logically thread
|
||||||
return Poll::Ready(Err(e));
|
/// safe.
|
||||||
}
|
#[instability::unstable]
|
||||||
self.sent = true;
|
pub fn receive_async(&mut self) -> ReceiveFuture<'_> {
|
||||||
}
|
self.receiver.receive_async()
|
||||||
|
}
|
||||||
if !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {
|
|
||||||
Poll::Pending
|
/// The returned future must not be dropped before it's ready to avoid
|
||||||
} else {
|
/// getting wrong status for sendings.
|
||||||
Poll::Ready(if ESP_NOW_SEND_STATUS.load(Ordering::Relaxed) {
|
#[instability::unstable]
|
||||||
Ok(())
|
pub fn send_async<'s, 'r>(
|
||||||
} else {
|
&'s mut self,
|
||||||
Err(EspNowError::SendFailed)
|
dst_addr: &'r [u8; 6],
|
||||||
})
|
data: &'r [u8],
|
||||||
}
|
) -> SendFuture<'s, 'r> {
|
||||||
}
|
self.sender.send_async(dst_addr, data)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// It's not logically safe to poll multiple instances of `ReceiveFuture`
|
|
||||||
/// simultaneously since the callback can only wake one future, leaving
|
/// A `future` representing the result of an asynchronous ESP-NOW send
|
||||||
/// the rest of them unwakable.
|
/// operation.
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct ReceiveFuture<'r>(PhantomData<&'r mut EspNowReceiver<'r>>);
|
#[instability::unstable]
|
||||||
|
pub struct SendFuture<'s, 'r> {
|
||||||
impl core::future::Future for ReceiveFuture<'_> {
|
_sender: PhantomData<&'s mut EspNowSender<'s>>,
|
||||||
type Output = ReceivedData;
|
addr: &'r [u8; 6],
|
||||||
|
data: &'r [u8],
|
||||||
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
sent: bool,
|
||||||
ESP_NOW_RX_WAKER.register(cx.waker());
|
}
|
||||||
|
|
||||||
if let Some(data) = critical_section::with(|cs| {
|
impl core::future::Future for SendFuture<'_, '_> {
|
||||||
let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
|
type Output = Result<(), EspNowError>;
|
||||||
queue.pop_front()
|
|
||||||
}) {
|
fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
Poll::Ready(data)
|
if !self.sent {
|
||||||
} else {
|
ESP_NOW_TX_WAKER.register(cx.waker());
|
||||||
Poll::Pending
|
ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release);
|
||||||
}
|
if let Err(e) = check_error!({
|
||||||
|
esp_now_send(self.addr.as_ptr(), self.data.as_ptr(), self.data.len())
|
||||||
|
}) {
|
||||||
|
return Poll::Ready(Err(e));
|
||||||
|
}
|
||||||
|
self.sent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {
|
||||||
|
Poll::Pending
|
||||||
|
} else {
|
||||||
|
Poll::Ready(if ESP_NOW_SEND_STATUS.load(Ordering::Relaxed) {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(EspNowError::SendFailed)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// It's not logically safe to poll multiple instances of `ReceiveFuture`
|
||||||
|
/// simultaneously since the callback can only wake one future, leaving
|
||||||
|
/// the rest of them unwakable.
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
|
#[instability::unstable]
|
||||||
|
pub struct ReceiveFuture<'r>(PhantomData<&'r mut EspNowReceiver<'r>>);
|
||||||
|
|
||||||
|
impl core::future::Future for ReceiveFuture<'_> {
|
||||||
|
type Output = ReceivedData;
|
||||||
|
|
||||||
|
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
ESP_NOW_RX_WAKER.register(cx.waker());
|
||||||
|
|
||||||
|
if let Some(data) = critical_section::with(|cs| {
|
||||||
|
let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
|
||||||
|
queue.pop_front()
|
||||||
|
}) {
|
||||||
|
Poll::Ready(data)
|
||||||
|
} else {
|
||||||
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
ble or wifi."
|
ble or wifi."
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
|
#![cfg_attr(docsrs, feature(doc_cfg, custom_inner_attributes, proc_macro_hygiene))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate esp_metadata_generated;
|
extern crate esp_metadata_generated;
|
||||||
@ -129,6 +130,28 @@ use crate::{
|
|||||||
tasks::init_tasks,
|
tasks::init_tasks,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// can't use instability on inline module definitions, see https://github.com/rust-lang/rust/issues/54727
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! unstable_module {
|
||||||
|
($(
|
||||||
|
$(#[$meta:meta])*
|
||||||
|
pub mod $module:ident;
|
||||||
|
)*) => {
|
||||||
|
$(
|
||||||
|
$(#[$meta])*
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
|
pub mod $module;
|
||||||
|
|
||||||
|
$(#[$meta])*
|
||||||
|
#[cfg(not(feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) mod $module;
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
mod binary {
|
mod binary {
|
||||||
pub use esp_wifi_sys::*;
|
pub use esp_wifi_sys::*;
|
||||||
}
|
}
|
||||||
@ -137,18 +160,19 @@ mod compat;
|
|||||||
mod radio;
|
mod radio;
|
||||||
mod time;
|
mod time;
|
||||||
|
|
||||||
|
pub(crate) use unstable_module;
|
||||||
|
|
||||||
#[cfg(feature = "wifi")]
|
#[cfg(feature = "wifi")]
|
||||||
pub mod wifi;
|
pub mod wifi;
|
||||||
|
|
||||||
#[cfg(feature = "ble")]
|
unstable_module! {
|
||||||
pub mod ble;
|
#[cfg(feature = "esp-now")]
|
||||||
|
pub mod esp_now;
|
||||||
#[cfg(feature = "esp-now")]
|
#[cfg(feature = "ble")]
|
||||||
pub mod esp_now;
|
pub mod ble;
|
||||||
|
#[cfg(feature = "ieee802154")]
|
||||||
#[cfg(feature = "ieee802154")]
|
pub mod ieee802154;
|
||||||
pub mod ieee802154;
|
}
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
||||||
pub(crate) mod common_adapter;
|
pub(crate) mod common_adapter;
|
||||||
@ -202,6 +226,7 @@ pub(crate) const CONFIG: config::Config = config::Config {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd)]
|
#[derive(Debug, PartialEq, PartialOrd)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
/// Controller for the ESP Radio driver.
|
||||||
pub struct Controller<'d> {
|
pub struct Controller<'d> {
|
||||||
_inner: PhantomData<&'d ()>,
|
_inner: PhantomData<&'d ()>,
|
||||||
}
|
}
|
||||||
@ -319,6 +344,7 @@ impl From<WifiError> for InitializationError {
|
|||||||
|
|
||||||
/// Enable verbose logging within the WiFi driver
|
/// Enable verbose logging within the WiFi driver
|
||||||
/// Does nothing unless the `sys-logs` feature is enabled.
|
/// Does nothing unless the `sys-logs` feature is enabled.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn wifi_set_log_verbose() {
|
pub fn wifi_set_log_verbose() {
|
||||||
#[cfg(all(feature = "sys-logs", not(esp32h2)))]
|
#[cfg(all(feature = "sys-logs", not(esp32h2)))]
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -16,6 +16,7 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// The type of handlers of events.
|
/// The type of handlers of events.
|
||||||
|
#[instability::unstable]
|
||||||
pub type Handler<T> = dyn FnMut(&T) + Sync + Send;
|
pub type Handler<T> = dyn FnMut(&T) + Sync + Send;
|
||||||
|
|
||||||
fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
|
fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
|
||||||
@ -40,6 +41,7 @@ fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
|
|||||||
// ```
|
// ```
|
||||||
// event::update_handler::<event::ApStaconnected, _>(...)
|
// event::update_handler::<event::ApStaconnected, _>(...)
|
||||||
// ```
|
// ```
|
||||||
|
#[instability::unstable]
|
||||||
pub trait EventExt: sealed::Event + Sized + 'static {
|
pub trait EventExt: sealed::Event + Sized + 'static {
|
||||||
/// Get the handler for this event, replacing it with the default handler.
|
/// Get the handler for this event, replacing it with the default handler.
|
||||||
fn take_handler() -> Box<Handler<Self>> {
|
fn take_handler() -> Box<Handler<Self>> {
|
||||||
@ -162,6 +164,7 @@ impl_wifi_event!(HomeChannelChange, wifi_event_home_channel_change_t);
|
|||||||
impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t);
|
impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t);
|
||||||
|
|
||||||
/// Handle the given event using the registered event handlers.
|
/// Handle the given event using the registered event handlers.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn handle<Event: EventExt>(event_data: &Event) -> bool {
|
pub fn handle<Event: EventExt>(event_data: &Event) -> bool {
|
||||||
Event::handler().with(|handler| {
|
Event::handler().with(|handler| {
|
||||||
if let Some(handler) = handler {
|
if let Some(handler) = handler {
|
||||||
|
@ -43,7 +43,8 @@ use esp_wifi_sys::include::{
|
|||||||
wifi_pkt_rx_ctrl_t,
|
wifi_pkt_rx_ctrl_t,
|
||||||
wifi_scan_channel_bitmap_t,
|
wifi_scan_channel_bitmap_t,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
use esp_wifi_sys::include::{
|
use esp_wifi_sys::include::{
|
||||||
esp_wifi_80211_tx,
|
esp_wifi_80211_tx,
|
||||||
esp_wifi_set_promiscuous,
|
esp_wifi_set_promiscuous,
|
||||||
@ -57,7 +58,8 @@ pub(crate) use os_adapter::*;
|
|||||||
use portable_atomic::{AtomicUsize, Ordering};
|
use portable_atomic::{AtomicUsize, Ordering};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "smoltcp")]
|
#[cfg(all(feature = "smoltcp", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
use smoltcp::phy::{Device, DeviceCapabilities, RxToken, TxToken};
|
use smoltcp::phy::{Device, DeviceCapabilities, RxToken, TxToken};
|
||||||
pub use state::*;
|
pub use state::*;
|
||||||
|
|
||||||
@ -75,8 +77,10 @@ const MTU: usize = crate::CONFIG.mtu;
|
|||||||
#[cfg(all(feature = "csi", esp32c6))]
|
#[cfg(all(feature = "csi", esp32c6))]
|
||||||
use crate::binary::include::wifi_csi_acquire_config_t;
|
use crate::binary::include::wifi_csi_acquire_config_t;
|
||||||
#[cfg(feature = "csi")]
|
#[cfg(feature = "csi")]
|
||||||
|
#[instability::unstable]
|
||||||
pub use crate::binary::include::wifi_csi_info_t;
|
pub use crate::binary::include::wifi_csi_info_t;
|
||||||
#[cfg(feature = "csi")]
|
#[cfg(feature = "csi")]
|
||||||
|
#[instability::unstable]
|
||||||
use crate::binary::include::{
|
use crate::binary::include::{
|
||||||
esp_wifi_set_csi,
|
esp_wifi_set_csi,
|
||||||
esp_wifi_set_csi_config,
|
esp_wifi_set_csi_config,
|
||||||
@ -2060,7 +2064,8 @@ impl RxControlInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Represents a Wi-Fi packet in promiscuous mode.
|
/// Represents a Wi-Fi packet in promiscuous mode.
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
|
#[instability::unstable]
|
||||||
pub struct PromiscuousPkt<'a> {
|
pub struct PromiscuousPkt<'a> {
|
||||||
/// Control information related to packet reception.
|
/// Control information related to packet reception.
|
||||||
pub rx_cntl: RxControlInfo,
|
pub rx_cntl: RxControlInfo,
|
||||||
@ -2071,7 +2076,8 @@ pub struct PromiscuousPkt<'a> {
|
|||||||
/// Data contained in the received packet.
|
/// Data contained in the received packet.
|
||||||
pub data: &'a [u8],
|
pub data: &'a [u8],
|
||||||
}
|
}
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
impl PromiscuousPkt<'_> {
|
impl PromiscuousPkt<'_> {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// When calling this, you have to ensure, that `buf` points to a valid
|
/// When calling this, you have to ensure, that `buf` points to a valid
|
||||||
@ -2096,10 +2102,10 @@ impl PromiscuousPkt<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
static SNIFFER_CB: Locked<Option<fn(PromiscuousPkt<'_>)>> = Locked::new(None);
|
static SNIFFER_CB: Locked<Option<fn(PromiscuousPkt<'_>)>> = Locked::new(None);
|
||||||
|
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
unsafe extern "C" fn promiscuous_rx_cb(buf: *mut core::ffi::c_void, frame_type: u32) {
|
unsafe extern "C" fn promiscuous_rx_cb(buf: *mut core::ffi::c_void, frame_type: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(sniffer_callback) = SNIFFER_CB.with(|callback| *callback) {
|
if let Some(sniffer_callback) = SNIFFER_CB.with(|callback| *callback) {
|
||||||
@ -2109,12 +2115,13 @@ unsafe extern "C" fn promiscuous_rx_cb(buf: *mut core::ffi::c_void, frame_type:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
|
#[instability::unstable]
|
||||||
/// A wifi sniffer.
|
/// A wifi sniffer.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct Sniffer {}
|
pub struct Sniffer {}
|
||||||
|
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
impl Sniffer {
|
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
|
||||||
@ -2125,11 +2132,13 @@ impl Sniffer {
|
|||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
/// Set promiscuous mode enabled or disabled.
|
/// Set promiscuous mode enabled or disabled.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_promiscuous_mode(&self, enabled: bool) -> Result<(), WifiError> {
|
pub fn set_promiscuous_mode(&self, enabled: bool) -> Result<(), WifiError> {
|
||||||
esp_wifi_result!(unsafe { esp_wifi_set_promiscuous(enabled) })?;
|
esp_wifi_result!(unsafe { esp_wifi_set_promiscuous(enabled) })?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
/// Transmit a raw frame.
|
/// Transmit a raw frame.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn send_raw_frame(
|
pub fn send_raw_frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
use_sta_interface: bool,
|
use_sta_interface: bool,
|
||||||
@ -2150,13 +2159,15 @@ impl Sniffer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/// Set the callback for receiving a packet.
|
/// Set the callback for receiving a packet.
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_receive_cb(&mut self, cb: fn(PromiscuousPkt<'_>)) {
|
pub fn set_receive_cb(&mut self, cb: fn(PromiscuousPkt<'_>)) {
|
||||||
SNIFFER_CB.with(|callback| *callback = Some(cb));
|
SNIFFER_CB.with(|callback| *callback = Some(cb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://docs.rs/smoltcp/0.7.1/smoltcp/phy/index.html
|
// see https://docs.rs/smoltcp/0.7.1/smoltcp/phy/index.html
|
||||||
#[cfg(feature = "smoltcp")]
|
#[cfg(all(feature = "smoltcp", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
impl Device for WifiDevice<'_> {
|
impl Device for WifiDevice<'_> {
|
||||||
type RxToken<'a>
|
type RxToken<'a>
|
||||||
= WifiRxToken
|
= WifiRxToken
|
||||||
@ -2223,7 +2234,8 @@ impl WifiRxToken {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "smoltcp")]
|
#[cfg(all(feature = "smoltcp", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
impl RxToken for WifiRxToken {
|
impl RxToken for WifiRxToken {
|
||||||
fn consume<R, F>(self, f: F) -> R
|
fn consume<R, F>(self, f: F) -> R
|
||||||
where
|
where
|
||||||
@ -2263,7 +2275,8 @@ impl WifiTxToken {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "smoltcp")]
|
#[cfg(all(feature = "smoltcp", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
impl TxToken for WifiTxToken {
|
impl TxToken for WifiTxToken {
|
||||||
fn consume<R, F>(self, len: usize, f: F) -> R
|
fn consume<R, F>(self, len: usize, f: F) -> R
|
||||||
where
|
where
|
||||||
@ -2633,13 +2646,16 @@ impl Drop for FreeApListOnDrop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the Wi-Fi controller and its associated interfaces.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct Interfaces<'d> {
|
pub struct Interfaces<'d> {
|
||||||
pub sta: WifiDevice<'d>,
|
pub sta: WifiDevice<'d>,
|
||||||
pub ap: WifiDevice<'d>,
|
pub ap: WifiDevice<'d>,
|
||||||
#[cfg(feature = "esp-now")]
|
#[cfg(all(feature = "esp-now", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
pub esp_now: crate::esp_now::EspNow<'d>,
|
pub esp_now: crate::esp_now::EspNow<'d>,
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
pub sniffer: Sniffer,
|
pub sniffer: Sniffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2695,9 +2711,9 @@ pub fn new<'d>(
|
|||||||
_phantom: Default::default(),
|
_phantom: Default::default(),
|
||||||
mode: WifiDeviceMode::Ap,
|
mode: WifiDeviceMode::Ap,
|
||||||
},
|
},
|
||||||
#[cfg(feature = "esp-now")]
|
#[cfg(all(feature = "esp-now", feature = "unstable"))]
|
||||||
esp_now: crate::esp_now::EspNow::new_internal(),
|
esp_now: crate::esp_now::EspNow::new_internal(),
|
||||||
#[cfg(feature = "sniffer")]
|
#[cfg(all(feature = "sniffer", feature = "unstable"))]
|
||||||
sniffer: Sniffer::new(),
|
sniffer: Sniffer::new(),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
@ -2723,6 +2739,7 @@ impl Drop for WifiController<'_> {
|
|||||||
impl WifiController<'_> {
|
impl WifiController<'_> {
|
||||||
/// Set CSI configuration and register the receiving callback.
|
/// Set CSI configuration and register the receiving callback.
|
||||||
#[cfg(feature = "csi")]
|
#[cfg(feature = "csi")]
|
||||||
|
#[instability::unstable]
|
||||||
pub fn set_csi(
|
pub fn set_csi(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut csi: CsiConfig,
|
mut csi: CsiConfig,
|
||||||
|
@ -38,11 +38,13 @@ pub(crate) static STA_STATE: AtomicWifiState = AtomicWifiState::new(WifiState::I
|
|||||||
pub(crate) static AP_STATE: AtomicWifiState = AtomicWifiState::new(WifiState::Invalid);
|
pub(crate) static AP_STATE: AtomicWifiState = AtomicWifiState::new(WifiState::Invalid);
|
||||||
|
|
||||||
/// Get the current state of the AP
|
/// Get the current state of the AP
|
||||||
|
#[instability::unstable]
|
||||||
pub fn ap_state() -> WifiState {
|
pub fn ap_state() -> WifiState {
|
||||||
AP_STATE.load(Ordering::Relaxed)
|
AP_STATE.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current state of the STA
|
/// Get the current state of the STA
|
||||||
|
#[instability::unstable]
|
||||||
pub fn sta_state() -> WifiState {
|
pub fn sta_state() -> WifiState {
|
||||||
STA_STATE.load(Ordering::Relaxed)
|
STA_STATE.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//% CHIPS: esp32c6 esp32h2
|
//% CHIPS: esp32c6 esp32h2
|
||||||
//% FEATURES: esp-hal/unstable esp-radio/ieee802154
|
//% FEATURES: esp-hal/unstable esp-radio/ieee802154 esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//% CHIPS: esp32c6 esp32h2
|
//% CHIPS: esp32c6 esp32h2
|
||||||
//% FEATURES: esp-hal/unstable esp-radio/ieee802154
|
//% FEATURES: esp-hal/unstable esp-radio/ieee802154 esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//% CHIPS: esp32c6 esp32h2
|
//% CHIPS: esp32c6 esp32h2
|
||||||
//% FEATURES: esp-hal/unstable esp-radio/ieee802154
|
//% FEATURES: esp-hal/unstable esp-radio/ieee802154 esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//% CHIPS: esp32c6 esp32h2
|
//% CHIPS: esp32c6 esp32h2
|
||||||
//% FEATURES: esp-hal/unstable esp-radio/ieee802154
|
//% FEATURES: esp-hal/unstable esp-radio/ieee802154 esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//! identical to ieee802154_receive_all_frames
|
//! identical to ieee802154_receive_all_frames
|
||||||
|
|
||||||
//% CHIPS: esp32c6 esp32h2
|
//% CHIPS: esp32c6 esp32h2
|
||||||
//% FEATURES: esp-hal/unstable esp-radio/ieee802154
|
//% FEATURES: esp-hal/unstable esp-radio/ieee802154 esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Periodically transmits a beacon frame.
|
//! Periodically transmits a beacon frame.
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/sniffer esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/sniffer esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
||||||
//! can use a shell and try `curl` and `ping`
|
//! can use a shell and try `curl` and `ping`
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
||||||
//! can use a shell and try `curl` and `ping`
|
//! can use a shell and try `curl` and `ping`
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
//! variable. E.g `HOST_IP="192.168.0.24"` and also set SSID and PASSWORD env
|
//! variable. E.g `HOST_IP="192.168.0.24"` and also set SSID and PASSWORD env
|
||||||
//! variable before running this example.
|
//! variable before running this example.
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//! read/write/notify)
|
//! read/write/notify)
|
||||||
//! - pressing the boot-button on a dev-board will send a notification if it is subscribed
|
//! - pressing the boot-button on a dev-board will send a notification if it is subscribed
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/ble esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/ble esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
|
//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/ble esp-radio/coex
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/ble esp-radio/coex
|
||||||
//% FEATURES: esp-hal/unstable
|
//% FEATURES: esp-radio/unstable esp-hal/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/log-04 esp-radio/csi
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/log-04 esp-radio/csi
|
||||||
//% FEATURES: esp-hal/unstable
|
//% FEATURES: esp-radio/unstable esp-hal/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
//! This gets an ip address via DHCP then performs an HTTP get request to some
|
//! This gets an ip address via DHCP then performs an HTTP get request to some
|
||||||
//! "random" server
|
//! "random" server
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-hal/unstable esp-radio/smoltcp
|
//% FEATURES: esp-radio esp-radio/wifi esp-hal/unstable esp-radio/smoltcp esp-radio/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
// esp-radio/utils
|
// esp-radio/utils
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
||||||
//! can use a shell and try `curl` and `ping`
|
//! can use a shell and try `curl` and `ping`
|
||||||
|
|
||||||
//% FEATURES: embassy esp-radio esp-radio/wifi esp-hal/unstable
|
//% FEATURES: embassy esp-radio esp-radio/wifi esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
//! WiFi has no internet connection, Chrome might not want to load the URL - you
|
||||||
//! can use a shell and try `curl` and `ping`
|
//! can use a shell and try `curl` and `ping`
|
||||||
|
|
||||||
//% FEATURES: embassy esp-radio esp-radio/wifi esp-hal/unstable
|
//% FEATURES: embassy esp-radio esp-radio/wifi esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
||||||
//! and ESP32-C2
|
//! and ESP32-C2
|
||||||
|
|
||||||
//% FEATURES: embassy esp-radio esp-radio/wifi esp-hal/unstable
|
//% FEATURES: embassy esp-radio esp-radio/wifi esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c3 esp32c6
|
||||||
|
|
||||||
#![allow(static_mut_refs)]
|
#![allow(static_mut_refs)]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//! read/write/notify)
|
//! read/write/notify)
|
||||||
//! - pressing the boot-button on a dev-board will send a notification if it is subscribed
|
//! - pressing the boot-button on a dev-board will send a notification if it is subscribed
|
||||||
|
|
||||||
//% FEATURES: embassy esp-radio esp-radio/ble esp-hal/unstable
|
//% FEATURES: embassy esp-radio esp-radio/ble esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
|
//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
|
||||||
|
|
||||||
// Embassy offers another compatible BLE crate [trouble](https://github.com/embassy-rs/trouble/tree/main/examples/esp32) with esp32 examples.
|
// Embassy offers another compatible BLE crate [trouble](https://github.com/embassy-rs/trouble/tree/main/examples/esp32) with esp32 examples.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
||||||
|
|
||||||
//% FEATURES: embassy esp-radio esp-radio/esp-now esp-hal/unstable
|
//% FEATURES: embassy esp-radio esp-radio/esp-now esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
||||||
|
|
||||||
//% FEATURES: embassy esp-radio esp-radio/esp-now esp-hal/unstable
|
//% FEATURES: embassy esp-radio esp-radio/esp-now esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Broadcasts, receives and sends messages via esp-now
|
//! Broadcasts, receives and sends messages via esp-now
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/esp-now esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/esp-now esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Sniffs for beacon frames.
|
//! Sniffs for beacon frames.
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/sniffer esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/sniffer esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
//! - uses the given static IP
|
//! - uses the given static IP
|
||||||
//! - responds with some HTML content when connecting to port 8080
|
//! - responds with some HTML content when connecting to port 8080
|
||||||
|
|
||||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-hal/unstable
|
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/unstable esp-hal/unstable
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//! THIS DOESN'T ACTUALLY TEST THE RADIO HOWEVER.
|
//! THIS DOESN'T ACTUALLY TEST THE RADIO HOWEVER.
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s3
|
||||||
//% FEATURES: unstable esp-radio esp-alloc esp-radio/ble
|
//% FEATURES: unstable esp-radio esp-alloc esp-radio/ble esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Cp0Disable exception regression test
|
//! Cp0Disable exception regression test
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32s2 esp32s3
|
||||||
//% FEATURES: unstable esp-radio esp-alloc esp-radio/wifi
|
//% FEATURES: unstable esp-radio esp-alloc esp-radio/wifi esp-radio/unstable
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! disabled in common ways
|
//! disabled in common ways
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32s2 esp32c2 esp32c3 esp32c6 esp32s3
|
//% CHIPS: esp32 esp32s2 esp32c2 esp32c3 esp32c6 esp32s3
|
||||||
//% FEATURES: unstable esp-radio esp-alloc esp-radio/wifi embassy
|
//% FEATURES: unstable esp-radio esp-alloc esp-radio/wifi esp-radio/unstable embassy
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
@ -211,6 +211,11 @@ impl Package {
|
|||||||
if config.contains("wifi") && config.contains("bt") {
|
if config.contains("wifi") && config.contains("bt") {
|
||||||
features.push("coex".to_owned());
|
features.push("coex".to_owned());
|
||||||
}
|
}
|
||||||
|
if features.iter().any(|f| {
|
||||||
|
f == "csi" || f == "ble" || f == "esp-now" || f == "sniffer" || f == "coex"
|
||||||
|
}) {
|
||||||
|
features.push("unstable".to_owned());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Package::EspHalProcmacros => {
|
Package::EspHalProcmacros => {
|
||||||
features.push("embassy".to_owned());
|
features.push("embassy".to_owned());
|
||||||
@ -248,7 +253,7 @@ impl Package {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Additional feature rules to test subsets of features for a package.
|
/// Additional feature rules to test subsets of features for a package.
|
||||||
pub fn lint_feature_rules(&self, _config: &Config) -> Vec<Vec<String>> {
|
pub fn lint_feature_rules(&self, config: &Config) -> Vec<Vec<String>> {
|
||||||
let mut cases = Vec::new();
|
let mut cases = Vec::new();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
@ -265,6 +270,14 @@ impl Package {
|
|||||||
Package::EspRadio => {
|
Package::EspRadio => {
|
||||||
// Minimal set of features that when enabled _should_ still compile:
|
// Minimal set of features that when enabled _should_ still compile:
|
||||||
cases.push(vec!["esp-hal/rt".to_owned(), "esp-hal/unstable".to_owned()]);
|
cases.push(vec!["esp-hal/rt".to_owned(), "esp-hal/unstable".to_owned()]);
|
||||||
|
// This tests if `wifi` feature works without `unstable`
|
||||||
|
if config.contains("wifi") {
|
||||||
|
cases.push(vec![
|
||||||
|
"esp-hal/rt".to_owned(),
|
||||||
|
"esp-hal/unstable".to_owned(),
|
||||||
|
"wifi".to_owned(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Package::EspMetadataGenerated => {
|
Package::EspMetadataGenerated => {
|
||||||
cases.push(vec!["build-script".to_owned()]);
|
cases.push(vec!["build-script".to_owned()]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user