#![cfg_attr( all(docsrs, not(not_really_docsrs)), doc = "
You might want to browse the esp-radio
documentation on the esp-rs website instead.
The documentation here on docs.rs is built for a single chip only (ESP32-C3, in particular), while on the esp-rs website you can select your exact chip from the list of supported devices. Available peripherals and their APIs might change depending on the chip.
{feature}
"#)]
//! ## Additional configuration
//!
//! We've exposed some configuration options that don't fit into cargo
//! features. These can be set via environment variables, or via cargo's `[env]`
//! section inside `.cargo/config.toml`. Below is a table of tunable parameters
//! for this crate:
#![doc = ""]
#![doc = include_str!(concat!(env!("OUT_DIR"), "/esp_radio_config_table.md"))]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
#![no_std]
#![cfg_attr(xtensa, feature(asm_experimental_arch))]
#![cfg_attr(feature = "sys-logs", feature(c_variadic))]
#![deny(rust_2018_idioms, rustdoc::all)]
#![allow(rustdoc::bare_urls)]
// allow until num-derive doesn't generate this warning anymore (unknown_lints because Xtensa
// toolchain doesn't know about that lint, yet)
#![allow(unknown_lints)]
#![allow(non_local_definitions)]
#![cfg_attr(
not(any(feature = "wifi", feature = "ble")),
allow(
unused,
reason = "There are a number of places where code is needed for either wifi or ble,
and cfg-ing them out would make the code less readable just to avoid warnings in the
less common case. Truly unused code will be flagged by the check that enables either
ble or wifi."
)
)]
#[macro_use]
extern crate esp_metadata_generated;
extern crate alloc;
// MUST be the first module
mod fmt;
use core::marker::PhantomData;
use common_adapter::chip_specific::phy_mem_init;
use esp_config::*;
use esp_hal::{self as hal};
use esp_radio_preempt_driver as preempt;
use hal::{
clock::{Clocks, init_radio_clocks},
time::Rate,
};
#[cfg(feature = "wifi")]
use crate::wifi::WifiError;
use crate::{
preempt::yield_task,
radio::{setup_radio_isr, shutdown_radio_isr},
tasks::init_tasks,
};
mod binary {
pub use esp_wifi_sys::*;
}
mod compat;
mod radio;
mod time;
#[cfg(feature = "wifi")]
pub mod wifi;
#[cfg(feature = "ble")]
pub mod ble;
#[cfg(feature = "esp-now")]
pub mod esp_now;
pub mod config;
pub(crate) mod common_adapter;
#[doc(hidden)]
pub mod tasks;
pub(crate) mod memory_fence;
// this is just to verify that we use the correct defaults in `build.rs`
#[allow(clippy::assertions_on_constants)] // TODO: try assert_eq once it's usable in const context
const _: () = {
cfg_if::cfg_if! {
if #[cfg(not(esp32h2))] {
core::assert!(binary::include::CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM == 10);
core::assert!(binary::include::CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM == 32);
core::assert!(binary::include::WIFI_STATIC_TX_BUFFER_NUM == 0);
core::assert!(binary::include::CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM == 32);
core::assert!(binary::include::CONFIG_ESP_WIFI_AMPDU_RX_ENABLED == 1);
core::assert!(binary::include::CONFIG_ESP_WIFI_AMPDU_TX_ENABLED == 1);
core::assert!(binary::include::WIFI_AMSDU_TX_ENABLED == 0);
core::assert!(binary::include::CONFIG_ESP32_WIFI_RX_BA_WIN == 6);
}
};
};
pub(crate) const CONFIG: config::EspRadioConfig = config::EspRadioConfig {
rx_queue_size: esp_config_int!(usize, "ESP_RADIO_CONFIG_RX_QUEUE_SIZE"),
tx_queue_size: esp_config_int!(usize, "ESP_RADIO_CONFIG_TX_QUEUE_SIZE"),
static_rx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_STATIC_RX_BUF_NUM"),
dynamic_rx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_DYNAMIC_RX_BUF_NUM"),
static_tx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_STATIC_TX_BUF_NUM"),
dynamic_tx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_DYNAMIC_TX_BUF_NUM"),
ampdu_rx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMPDU_RX_ENABLE"),
ampdu_tx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMPDU_TX_ENABLE"),
amsdu_tx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMSDU_TX_ENABLE"),
rx_ba_win: esp_config_int!(usize, "ESP_RADIO_CONFIG_RX_BA_WIN"),
max_burst_size: esp_config_int!(usize, "ESP_RADIO_CONFIG_MAX_BURST_SIZE"),
country_code: esp_config_str!("ESP_RADIO_CONFIG_COUNTRY_CODE"),
country_code_operating_class: esp_config_int!(
u8,
"ESP_RADIO_CONFIG_COUNTRY_CODE_OPERATING_CLASS"
),
mtu: esp_config_int!(usize, "ESP_RADIO_CONFIG_MTU"),
listen_interval: esp_config_int!(u16, "ESP_RADIO_CONFIG_LISTEN_INTERVAL"),
beacon_timeout: esp_config_int!(u16, "ESP_RADIO_CONFIG_BEACON_TIMEOUT"),
ap_beacon_timeout: esp_config_int!(u16, "ESP_RADIO_CONFIG_AP_BEACON_TIMEOUT"),
failure_retry_cnt: esp_config_int!(u8, "ESP_RADIO_CONFIG_FAILURE_RETRY_CNT"),
scan_method: esp_config_int!(u32, "ESP_RADIO_CONFIG_SCAN_METHOD"),
};
#[derive(Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct EspRadioController<'d> {
_inner: PhantomData<&'d ()>,
}
impl Drop for EspRadioController<'_> {
fn drop(&mut self) {
// Disable coexistence
#[cfg(coex)]
{
unsafe { crate::wifi::os_adapter::coex_disable() };
unsafe { crate::wifi::os_adapter::coex_deinit() };
}
shutdown_radio_isr();
// This shuts down the task switcher and timer tick interrupt.
preempt::disable();
}
}
/// Initialize for using WiFi and or BLE.
///
/// Make sure to **not** call this function while interrupts are disabled.
pub fn init<'d>() -> Result