diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df98d99a25c..79f6b994eb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ on: env: CARGO_TERM_COLOR: always GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - MSRV: "1.77.0" + MSRV: "1.79.0" RUSTDOCFLAGS: -Dwarnings DEFMT_LOG: trace @@ -179,3 +179,19 @@ jobs: # Check the formatting of all packages: - run: cargo xtask fmt-packages --check + + # -------------------------------------------------------------------------- + # host tests + + host-tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@v1 + with: + toolchain: stable + - uses: Swatinem/rust-cache@v2 + + # Check the formatting of all packages: + - run: cd esp-config && cargo test --features build diff --git a/Cargo.toml b/Cargo.toml index 1a5ae61ce38..7186091d691 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ exclude = [ "esp-alloc", "esp-backtrace", "esp-build", + "esp-config", "esp-hal", "esp-hal-embassy", "esp-hal-procmacros", diff --git a/esp-config/Cargo.toml b/esp-config/Cargo.toml new file mode 100644 index 00000000000..43413ec6894 --- /dev/null +++ b/esp-config/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "esp-config" +version = "0.1.0" +edition = "2021" +rust-version = "1.79.0" + +[dependencies] +document-features = "0.2.10" + +[dev-dependencies] +temp-env = "0.3.6" + +[features] +## Enable the generation and parsing of a config +build = [] \ No newline at end of file diff --git a/esp-config/README.md b/esp-config/README.md new file mode 100644 index 00000000000..e5881392c2d --- /dev/null +++ b/esp-config/README.md @@ -0,0 +1,65 @@ +# esp-config + +[![Crates.io](https://img.shields.io/crates/v/esp-config?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp-config) +[![docs.rs](https://img.shields.io/docsrs/esp-config?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.rs/esp-config) +![MSRV](https://img.shields.io/badge/MSRV-1.79-blue?labelColor=1C2C2E&style=flat-square) +![Crates.io](https://img.shields.io/crates/l/esp-config?labelColor=1C2C2E&style=flat-square) +[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&labelColor=1C2C2E&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org) + +## [Documentation](https://docs.rs/crate/esp-config) + +## Usage + +`esp-config` takes a prefix (usually the crate name) and a set of configuration keys and default values to produce a configuration system that supports: + +- Emitting rustc cfg's for boolean keys +- Emitting environment variables for numbers + - Along with decimal parsing, it supports Hex, Octal and Binary with the respective `0x`, `0o` and `0b` prefixes. +- Emitting environment variables string values + +### Viewing the configuration + +The possible configuration values are output as a markdown table in the crates `OUT_DIR` with the format `{prefix}_config_table.md`, this can then be included into the crates top level documentation. Here is an example of the output: + + +| Name | Description | Default value | +|------|-------------|---------------| +|**ESP_HAL_PLACE_SPI_DRIVER_IN_RAM**|Places the SPI driver in RAM for better performance|false| + +### Setting configuration options + +For any available configuration option, the environment variable or cfg is _always_ set based on the default value specified in the table. Users can override this by setting environment variables locally in their shell _or_ the preferred option is to utilize cargo's [`env` section](https://doc.rust-lang.org/cargo/reference/config.html#env). + +It's important to note that due to a [bug in cargo](https://github.com/rust-lang/cargo/issues/10358), any modifications to the environment, local or otherwise will only get picked up on a full clean build of the project. + +To see the final selected configuration another table is output to the `OUT_DIR` with the format `{prefix}_selected_config.md`. + +### Capturing configuration values in the downstream crate + +For all supported data types, there are helper macros that emit `const` code for parsing the configuration values. + +- Numbers - `esp_config_int!(integer_type, "ENV")` +- Strings - `esp_config_str!("ENV")` +- Bool - `esp_config_bool!("ENV")` + +In addition to environment variables, for boolean types rust `cfg`'s are emitted in snake case _without_ the prefix. + +## Minimum Supported Rust Version (MSRV) + +This crate is guaranteed to compile on stable Rust 1.79 and up. It _might_ +compile with older versions but that may change in any new patch release. + +## License + +Licensed under either of: + +- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in +the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without +any additional terms or conditions. diff --git a/esp-config/src/generate.rs b/esp-config/src/generate.rs new file mode 100644 index 00000000000..a3257d4576a --- /dev/null +++ b/esp-config/src/generate.rs @@ -0,0 +1,365 @@ +use core::fmt::Write; +use std::{collections::HashMap, env, fs, path::PathBuf}; + +const DOC_TABLE_HEADER: &str = r#" +| Name | Description | Default value | +|------|-------------|---------------| +"#; +const CHOSEN_TABLE_HEADER: &str = r#" +| Name | Selected value | +|------|----------------| +"#; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ParseError(String); + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Value { + Number(usize), + Bool(bool), + String(String), +} + +impl Value { + fn parse_in_place(&mut self, s: &str) -> Result<(), ParseError> { + *self = match self { + Value::Bool(_) => match s { + "false" | "no" | "n" => Value::Bool(false), + "true" | "yes" | "y" => Value::Bool(true), + _ => return Err(ParseError(format!("Invalid boolean value: {}", s))), + }, + Value::Number(_) => Value::Number( + match s.as_bytes() { + [b'0', b'x', ..] => usize::from_str_radix(&s[2..], 16), + [b'0', b'o', ..] => usize::from_str_radix(&s[2..], 8), + [b'0', b'b', ..] => usize::from_str_radix(&s[2..], 2), + _ => usize::from_str_radix(&s, 10), + } + .map_err(|_| ParseError(format!("Invalid numerical value: {}", s)))?, + ), + Value::String(_) => Value::String(String::from(s)), + }; + Ok(()) + } + + fn as_string(&self) -> String { + match self { + Value::Bool(value) => String::from(if *value { "true" } else { "false" }), + Value::Number(value) => format!("{}", value), + Value::String(value) => value.clone(), + } + } +} + +/// Generate and parse config from a prefix, and array of key, default, +/// description tuples. +/// +/// This function will parse any `SCREAMING_SNAKE_CASE` environment variables +/// that match the given prefix. It will then attempt to parse the [`Value`]. +/// Once the config has been parsed, this function will emit `snake_case` cfg's +/// _without_ the prefix which can be used in the dependant crate. After that, +/// it will create a markdown table in the `OUT_DIR` under the name +/// `{prefix}_config_table.md` where prefix has also been converted +/// to `snake_case`. This can be included in crate documentation to outline the +/// available configuration options for the crate. +/// +/// Passing a value of true for the `emit_md_tables` argument will create and +/// write markdown files of the available configuration and selected +/// configuration which can be included in documentation. +/// +/// Unknown keys with the supplied prefix will cause this function to panic. +pub fn generate_config( + prefix: &str, + config: &[(&str, Value, &str)], + emit_md_tables: bool, +) -> HashMap { + // only rebuild if build.rs changed. Otherwise Cargo will rebuild if any + // other file changed. + println!("cargo:rerun-if-changed=build.rs"); + #[cfg(not(test))] + env_change_work_around(); + + // ensure that the prefix is `SCREAMING_SNAKE_CASE` + let prefix = format!("{}_", screaming_snake_case(prefix)); + let mut doc_table = String::from(DOC_TABLE_HEADER); + let mut selected_config = String::from(CHOSEN_TABLE_HEADER); + + let mut configs = create_config(&prefix, config, &mut doc_table); + capture_from_env(&prefix, &mut configs); + emit_configuration(&prefix, &configs, &mut selected_config); + + if emit_md_tables { + let file_name = snake_case(&prefix); + write_config_tables(&file_name, doc_table, selected_config); + } + + configs +} + +// A work-around for https://github.com/rust-lang/cargo/issues/10358 +// This can be removed when https://github.com/rust-lang/cargo/pull/14058 is merged. +// Unlikely to work on projects in workspaces +#[cfg(not(test))] +fn env_change_work_around() { + let mut out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + // We clean out_dir by removing all trailing directories, until it ends with + // target + while !out_dir.ends_with("target") { + if !out_dir.pop() { + // We ran out of directories... + return; + } + } + out_dir.pop(); + + let dotcargo = out_dir.join(".cargo/"); + if dotcargo.exists() { + println!( + "cargo:rerun-if-changed={}", + dotcargo.clone().join("config.toml").to_str().unwrap() + ); + println!( + "cargo:rerun-if-changed={}", + dotcargo.clone().join("config").to_str().unwrap() + ); + } +} + +fn emit_configuration( + prefix: &str, + configs: &HashMap, + selected_config: &mut String, +) { + // emit cfgs and set envs + for (name, value) in configs.into_iter() { + let cfg_name = snake_case(name.trim_start_matches(prefix)); + println!("cargo:rustc-check-cfg=cfg({cfg_name})"); + match value { + Value::Bool(true) => { + println!("cargo:rustc-cfg={cfg_name}") + } + _ => {} + } + + let value = value.as_string(); + // values that haven't been seen will be output here with the default value + println!("cargo:rustc-env={}={}", name, value); + + writeln!(selected_config, "|**{name}**|{value}|").unwrap(); + } +} + +fn capture_from_env(prefix: &str, configs: &mut HashMap) { + let mut unknown = Vec::new(); + let mut failed = Vec::new(); + + // Try and capture input from the environment + for (var, value) in env::vars() { + if let Some(_) = var.strip_prefix(prefix) { + let Some(cfg) = configs.get_mut(&var) else { + unknown.push(var); + continue; + }; + + if let Err(e) = cfg.parse_in_place(&value) { + failed.push(format!("{}: {e:?}", var)); + } + } + } + + if !failed.is_empty() { + panic!("Invalid configuration options detected: {:?}", failed); + } + + if !unknown.is_empty() { + panic!("Unknown configuration options detected: {:?}", unknown); + } +} + +fn create_config( + prefix: &str, + config: &[(&str, Value, &str)], + doc_table: &mut String, +) -> HashMap { + // Generate the template for the config + let mut configs = HashMap::new(); + for (name, default, desc) in config { + let name = format!("{prefix}{}", screaming_snake_case(&name)); + configs.insert(name.clone(), default.clone()); + + // write doc table line + let default = default.as_string(); + writeln!(doc_table, "|**{name}**|{desc}|{default}|").unwrap(); + + // Rebuild if config envvar changed. + println!("cargo:rerun-if-env-changed={name}"); + } + + configs +} + +fn write_config_tables(prefix: &str, doc_table: String, selected_config: String) { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let out_file = out_dir + .join(format!("{prefix}config_table.md")) + .to_string_lossy() + .to_string(); + fs::write(out_file, doc_table).unwrap(); + + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let out_file = out_dir + .join(format!("{prefix}selected_config.md")) + .to_string_lossy() + .to_string(); + fs::write(out_file, selected_config).unwrap(); +} + +// Converts a symbol name like +// "PLACE-spi_DRIVER-IN_ram" +// to +// "place_spi_driver_in_ram" +fn snake_case(name: &str) -> String { + let mut name = name.replace("-", "_"); + name.make_ascii_lowercase(); + name +} + +// Converts a symbol name like +// "PLACE-spi_DRIVER-IN_ram" +// to +// "PLACE_SPI_DRIVER_IN_RAM" +fn screaming_snake_case(name: &str) -> String { + let mut name = name.replace("-", "_"); + name.make_ascii_uppercase(); + name +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn value_number_formats() { + const INPUTS: &[&str] = &["0xAA", "0o252", "0b0000000010101010", "170"]; + let mut v = Value::Number(0); + + for input in INPUTS { + v.parse_in_place(input).unwrap(); + // no matter the input format, the output format should be decimal + assert_eq!(v.as_string(), "170"); + } + } + + #[test] + fn value_bool_inputs() { + const TRUE_INPUTS: &[&str] = &["true", "y", "yes"]; + const FALSE_INPUTS: &[&str] = &["false", "n", "no"]; + let mut v = Value::Bool(false); + + for input in TRUE_INPUTS { + v.parse_in_place(input).unwrap(); + // no matter the input variant, the output format should be "true" + assert_eq!(v.as_string(), "true"); + } + + for input in FALSE_INPUTS { + v.parse_in_place(input).unwrap(); + // no matter the input variant, the output format should be "false" + assert_eq!(v.as_string(), "false"); + } + } + + #[test] + fn env_override() { + temp_env::with_vars( + [ + ("ESP_TEST_NUMBER", Some("0xaa")), + ("ESP_TEST_STRING", Some("Hello world!")), + ("ESP_TEST_BOOL", Some("true")), + ], + || { + let configs = generate_config( + "esp-test", + &[ + ("number", Value::Number(999), "NA"), + ("string", Value::String("Demo".to_owned()), "NA"), + ("bool", Value::Bool(false), "NA"), + ("number_default", Value::Number(999), "NA"), + ("string_default", Value::String("Demo".to_owned()), "NA"), + ("bool_default", Value::Bool(false), "NA"), + ], + false, + ); + + // some values have changed + assert_eq!( + match configs.get("ESP_TEST_NUMBER").unwrap() { + Value::Number(num) => *num, + _ => unreachable!(), + }, + 0xaa + ); + assert_eq!( + match configs.get("ESP_TEST_STRING").unwrap() { + Value::String(val) => val, + _ => unreachable!(), + }, + "Hello world!" + ); + assert_eq!( + match configs.get("ESP_TEST_BOOL").unwrap() { + Value::Bool(val) => *val, + _ => unreachable!(), + }, + true + ); + + // the rest are the defaults + assert_eq!( + match configs.get("ESP_TEST_NUMBER_DEFAULT").unwrap() { + Value::Number(num) => *num, + _ => unreachable!(), + }, + 999 + ); + assert_eq!( + match configs.get("ESP_TEST_STRING_DEFAULT").unwrap() { + Value::String(val) => val, + _ => unreachable!(), + }, + "Demo" + ); + assert_eq!( + match configs.get("ESP_TEST_BOOL_DEFAULT").unwrap() { + Value::Bool(val) => *val, + _ => unreachable!(), + }, + false + ); + }, + ) + } + + #[test] + #[should_panic] + fn env_unknown_bails() { + temp_env::with_vars( + [ + ("ESP_TEST_NUMBER", Some("0xaa")), + ("ESP_TEST_RANDOM_VARIABLE", Some("")), + ], + || { + generate_config("esp-test", &[("number", Value::Number(999), "NA")], false); + }, + ); + } + + #[test] + #[should_panic] + fn env_invalid_values_bails() { + temp_env::with_vars([("ESP_TEST_NUMBER", Some("Hello world"))], || { + generate_config("esp-test", &[("number", Value::Number(999), "NA")], false); + }); + } +} diff --git a/esp-config/src/lib.rs b/esp-config/src/lib.rs new file mode 100644 index 00000000000..34ef2f3f3c5 --- /dev/null +++ b/esp-config/src/lib.rs @@ -0,0 +1,44 @@ +#![doc = include_str!("../README.md")] +//! ## Feature Flags +#![doc = document_features::document_features!(feature_label = r#"{feature}"#)] +#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] +#![cfg_attr(not(feature = "build"), no_std)] + +#[cfg(feature = "build")] +mod generate; +#[cfg(feature = "build")] +pub use generate::*; + +#[macro_export] +// TODO from 1.82 we can use <$ty>::from_str_radix(env!($var), 10) instead +macro_rules! esp_config_int { + ($ty:ty, $var:expr) => { + const { + let mut bytes = env!($var).as_bytes(); + let mut val: $ty = 0; + while let [byte, rest @ ..] = bytes { + ::core::assert!(b'0' <= *byte && *byte <= b'9', "invalid digit"); + val = val * 10 + (*byte - b'0') as $ty; + bytes = rest; + } + val + } + }; +} + +#[macro_export] +macro_rules! esp_config_str { + ($var:expr) => { + env!($var) + }; +} + +#[macro_export] +macro_rules! esp_config_bool { + ($var:expr) => { + match env!($var).as_bytes() { + b"false" => false, + _ => true, + } + }; +} diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 37c8bdbbfa6..7e9bd08a202 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Bump MSRV to 1.77.0 (#1971) +- Bump MSRV to 1.79.0 (#1971) ### Added @@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed the parameters of `Spi::with_pins` to no longer be optional (#2133) - Renamed `DummyPin` to `NoPin` and removed all internal logic from it. (#2133) - The `NO_PIN` constant has been removed. (#2133) +- MSRV bump to 1.79 (#2156) ### Fixed @@ -70,6 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed `_with_default_pins` UART constructors (#2132) - Removed `uart::{DefaultRxPin, DefaultTxPin}` (#2132) - Removed `PcntSource` and `PcntInputConfig`. (#2134) +- Removed the `place-spi-driver-in-ram` feature, this is now enabled via [esp-config](https://docs.rs/esp-config) (#2156) ## [0.20.1] - 2024-08-30 diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index 4f26cff6a53..cbde3477652 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -2,7 +2,7 @@ name = "esp-hal" version = "0.20.1" edition = "2021" -rust-version = "1.77.0" +rust-version = "1.79.0" description = "Bare-metal HAL for Espressif devices" documentation = "https://docs.esp-rs.org/esp-hal/" repository = "https://github.com/esp-rs/esp-hal" @@ -74,6 +74,7 @@ basic-toml = "0.1.9" cfg-if = "1.0.0" esp-build = { version = "0.1.0", path = "../esp-build" } esp-metadata = { version = "0.3.0", path = "../esp-metadata" } +esp-config = { version = "0.1.0", path = "../esp-config", features = ["build"] } serde = { version = "1.0.209", features = ["derive"] } [features] @@ -100,8 +101,6 @@ debug = [ ] ## Enable logging output using the `log` crate. log = ["dep:log"] -## Configuration for placing device drivers in the IRAM for faster access. -place-spi-driver-in-ram = [] # Chip Support Feature Flags # Target the ESP32. @@ -164,7 +163,7 @@ opsram-8m = [] opsram-16m = [] # This feature is intended for testing; you probably don't want to enable it: -ci = ["defmt", "bluetooth", "place-spi-driver-in-ram"] +ci = ["defmt", "bluetooth"] [lints.clippy] mixed_attributes_style = "allow" diff --git a/esp-hal/MIGRATING-0.20.md b/esp-hal/MIGRATING-0.20.md index 866a74c97ca..4f19c3f4815 100644 --- a/esp-hal/MIGRATING-0.20.md +++ b/esp-hal/MIGRATING-0.20.md @@ -198,3 +198,14 @@ let mut i8080 = I8080::new(....); - i8080.send(0x12, 0, &[0, 1, 2, 3, 4]); + i8080.send(0x12u8, 0, &[0, 1, 2, 3, 4]); ``` + +### Placing drivers in RAM is now done via esp-config + +We've replaced some usage of features with [esp-config](https://docs.rs/esp-config). Please remove any reference to `place-spi-driver-in-ram` in your `Cargo.toml` and migrate to the `[env]` section of `.cargo/config.toml`. + +```diff +# feature in Cargo.toml +- esp-hal = { version = "0.20", features = ["place-spi-driver-in-ram"] } +# key in .cargo/config.toml [env] section ++ ESP_HAL_PLACE_SPI_DRIVER_IN_RAM=true +``` diff --git a/esp-hal/README.md b/esp-hal/README.md index 0bac1874fdf..9b887d93261 100644 --- a/esp-hal/README.md +++ b/esp-hal/README.md @@ -48,7 +48,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.76 and up. It _might_ +This crate is guaranteed to compile on stable Rust 1.79 and up. It _might_ compile with older versions but that may change in any new patch release. ## License diff --git a/esp-hal/build.rs b/esp-hal/build.rs index d6c28894540..644b32c1f49 100644 --- a/esp-hal/build.rs +++ b/esp-hal/build.rs @@ -8,6 +8,7 @@ use std::{ }; use esp_build::assert_unique_used_features; +use esp_config::{generate_config, Value}; use esp_metadata::{Chip, Config}; #[cfg(debug_assertions)] @@ -122,6 +123,17 @@ fn main() -> Result<(), Box> { copy_dir_all(&config_symbols, "ld/sections", &out)?; copy_dir_all(&config_symbols, format!("ld/{device_name}"), &out)?; + // emit config + generate_config( + "esp_hal", + &[( + "place-spi-driver-in-ram", + Value::Bool(false), + "Places the SPI driver in RAM for better performance", + )], + true, + ); + Ok(()) } diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index fc4b294df0b..a413c56db37 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -88,31 +88,33 @@ //! } //! ``` //! -//! The steps here are: -//! - Call [`init`] with the desired [`CpuClock`] configuration -//! - Create [`gpio::Io`] which provides access to the GPIO pins -//! - Create an [`gpio::Output`] pin driver which lets us control the logical -//! level of an output pin -//! - Create a [`delay::Delay`] driver -//! - In a loop, toggle the output pin's logical level with a delay of 1000 ms +//! ## Additional configuration //! -//! ## `PeripheralRef` Pattern +//! 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_hal_config_table.md"))] +#![doc = ""] +//! It's important to note that due to a [bug in cargo](https://github.com/rust-lang/cargo/issues/10358), +//! any modifications to the environment, local or otherwise will only get +//! picked up on a full clean build of the project. //! -//! Generally drivers take pins and peripherals as [peripheral::PeripheralRef]. -//! This means you can pass the pin/peripheral or a mutable reference to the -//! pin/peripheral. +//! ## `Peripheral` Pattern +//! +//! Drivers take pins and peripherals as [peripheral::Peripheral] in most +//! circumstances. This means you can pass the pin/peripheral or a mutable +//! reference to the pin/peripheral. //! //! The latter can be used to regain access to the pin when the driver gets //! dropped. Then it's possible to reuse the pin/peripheral for a different //! purpose. //! -//! ## Don't use [core::mem::forget] -//! -//! In general drivers are _NOT_ safe to use with [core::mem::forget] -//! -//! You should never use [core::mem::forget] on any type defined in the HAL. +//! ## Don't use `core::mem::forget` //! -//! Some types heavily rely on their [Drop] implementation to not leave the +//! You should never use `core::mem::forget` on any type defined in the HAL. +//! Some types heavily rely on their `Drop` implementation to not leave the //! hardware in undefined state and causing UB. //! //! You might want to consider using [`#[deny(clippy::mem_forget)`](https://rust-lang.github.io/rust-clippy/v0.0.212/index.html#mem_forget) in your project. diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 5858c3fc6a1..f646d4101da 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -66,7 +66,7 @@ use enumset::EnumSet; #[cfg(gdma)] use enumset::EnumSetType; use fugit::HertzU32; -#[cfg(feature = "place-spi-driver-in-ram")] +#[cfg(place_spi_driver_in_ram)] use procmacros::ram; use super::{ @@ -1199,7 +1199,7 @@ mod dma { /// SPI instance. The maximum amount of data to be sent is 32736 /// bytes. #[allow(clippy::type_complexity)] - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] pub fn dma_write( mut self, mut buffer: TX, @@ -1226,7 +1226,7 @@ mod dma { /// the SPI instance. The maximum amount of data to be /// received is 32736 bytes. #[allow(clippy::type_complexity)] - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] pub fn dma_read( mut self, mut buffer: RX, @@ -1301,7 +1301,7 @@ mod dma { { /// Perform a half-duplex read operation using DMA. #[allow(clippy::type_complexity)] - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] pub fn read( mut self, data_mode: SpiDataMode, @@ -1378,7 +1378,7 @@ mod dma { /// Perform a half-duplex write operation using DMA. #[allow(clippy::type_complexity)] - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] pub fn write( mut self, data_mode: SpiDataMode, @@ -2247,7 +2247,7 @@ pub trait InstanceDma: Instance { Ok(()) } - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] unsafe fn start_write_bytes_dma( &mut self, buffer: &mut impl DmaTxBuffer, @@ -2295,7 +2295,7 @@ pub trait InstanceDma: Instance { Ok(()) } - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] unsafe fn start_read_bytes_dma( &mut self, buffer: &mut BUF, @@ -3050,7 +3050,7 @@ pub trait Instance: private::Sealed { /// all bytes of the last chunk to transmit have been sent to the wire. If /// you must ensure that the whole messages was written correctly, use /// [`Self::flush`]. - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] fn write_bytes(&mut self, words: &[u8]) -> Result<(), Error> { let num_chunks = words.len() / FIFO_SIZE; @@ -3107,7 +3107,7 @@ pub trait Instance: private::Sealed { /// Sends out a stuffing byte for every byte to read. This function doesn't /// perform flushing. If you want to read the response to something you /// have written before, consider using [`Self::transfer`] instead. - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] fn read_bytes(&mut self, words: &mut [u8]) -> Result<(), Error> { let empty_array = [EMPTY_WRITE_PAD; FIFO_SIZE]; @@ -3125,7 +3125,7 @@ pub trait Instance: private::Sealed { /// doesn't perform flushing. If you want to read the response to /// something you have written before, consider using [`Self::transfer`] /// instead. - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] fn read_bytes_from_fifo(&mut self, words: &mut [u8]) -> Result<(), Error> { let reg_block = self.register_block(); @@ -3157,7 +3157,7 @@ pub trait Instance: private::Sealed { Ok(()) } - #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] + #[cfg_attr(place_spi_driver_in_ram, ram)] fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Error> { for chunk in words.chunks_mut(FIFO_SIZE) { self.write_bytes(chunk)?; diff --git a/esp-wifi/CHANGELOG.md b/esp-wifi/CHANGELOG.md index 26d84fc3351..8c406f68f52 100644 --- a/esp-wifi/CHANGELOG.md +++ b/esp-wifi/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - Removed the `clocks` parameter from `esp_wifi::initialize` (#1999) +- `cfg_toml` configuration system has been removed in favour of [esp-config](https://docs.rs/esp-config) (#2156) ## 0.9.1 - 2024-09-03 diff --git a/esp-wifi/Cargo.toml b/esp-wifi/Cargo.toml index ca531fb3b06..402e7cbe323 100644 --- a/esp-wifi/Cargo.toml +++ b/esp-wifi/Cargo.toml @@ -2,7 +2,7 @@ name = "esp-wifi" version = "0.9.1" edition = "2021" -rust-version = "1.77.0" +rust-version = "1.79.0" authors = ["The ESP-RS team"] description = "A WiFi, Bluetooth and ESP-NOW driver for use with Espressif chips and bare-metal Rust" repository = "https://github.com/esp-rs/esp-hal" @@ -52,10 +52,12 @@ atomic-waker = { version = "1.1.2", default-features = false, features = [ "portable-atomic", ] } bt-hci = { version = "0.1.0", optional = true } +esp-config = { version = "0.1.0", path = "../esp-config" } [build-dependencies] toml-cfg = "0.2.0" esp-build = { version = "0.1.0", path = "../esp-build" } +esp-config = { version = "0.1.0", path = "../esp-config", features = ["build"] } esp-metadata = { version = "0.3.0", path = "../esp-metadata" } [features] diff --git a/esp-wifi/MIGRATING-0.9.md b/esp-wifi/MIGRATING-0.9.md index 520ed67219f..d88da420af8 100644 --- a/esp-wifi/MIGRATING-0.9.md +++ b/esp-wifi/MIGRATING-0.9.md @@ -91,3 +91,14 @@ pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8 { ``` It's important to allocate from internal memory (i.e. not PSRAM) + +### Tunable parameters are now set via esp-config + +We've replaced usage of `cfg_toml` with [esp-config](https://docs.rs/esp-config). Please remove any esp-wifi entries from `cfg.toml` and migrate the key value pairs to the `[env]` section of `.cargo/config.toml`. + +```diff +# key in cfg.toml +- rx_queue_size = 40 +# key in .cargo/config.toml [env] section ++ ESP_WIFI_RX_QUEUE_SIZE=40 +``` \ No newline at end of file diff --git a/esp-wifi/README.md b/esp-wifi/README.md index 3b19baa4877..3b14850b6f9 100644 --- a/esp-wifi/README.md +++ b/esp-wifi/README.md @@ -22,60 +22,7 @@ If a cell contains an em dash (—) this means that the particular feature i | ESP32-S2 | ✓ | — | — | ✓ | | ESP32-S3 | ✓ | ✓ | ✓ | ✓ | -Minimum supported Rust compiler version: 1.72.0.0 - -## Usage - -### Importing - -Ensure that the right features are enabled for your chip. See [Examples](https://github.com/esp-rs/esp-hal/tree/main/examples#examples) for more examples. - -```toml -[dependencies.esp-wifi] -# A supported chip needs to be specified, as well as specific use-case features -features = ["esp32s3", "wifi", "esp-now"] -``` - -### Link configuration - -Make sure to include the rom functions for your target: - -```toml -# .cargo/config.toml -rustflags = [ - "-C", "link-arg=-Tlinkall.x", - "-C", "link-arg=-Trom_functions.x", -] -``` - -At the time of writing, you will already have the `linkall` flag if you used `cargo generate`. Generating from a template does not include the `rom_functions` flag. - -### Optimization Level - -It is necessary to build with optimization level 2 or 3 since otherwise, it might not even be able to connect or advertise. - -To make it work also for your debug builds add this to your `Cargo.toml` - -```toml -[profile.dev.package.esp-wifi] -opt-level = 3 -``` - -### Xtensa considerations - -Within this crate, `CCOMPARE0` CPU timer is used for timing, ensure that in your application you are not using this CPU timer. - -## USB-SERIAL-JTAG - -When using USB-SERIAL-JTAG (for example by selecting `jtag-serial` in [`esp-println`](https://crates.io/crates/esp-println)) you have to activate the feature `phy-enable-usb`. - -Don't use this feature if you are _not_ using USB-SERIAL-JTAG as it might reduce WiFi performance. - -## Tuning - -The defaults used by `esp-wifi` and the examples are rather conservative. It is possible to change a few of the important settings. - -See [Tuning](./tuning.md) for details +Minimum supported Rust compiler version: 1.79.0 ## Missing / To be done diff --git a/esp-wifi/build.rs b/esp-wifi/build.rs index 14f089947e2..cf0c723b74e 100644 --- a/esp-wifi/build.rs +++ b/esp-wifi/build.rs @@ -1,6 +1,7 @@ use std::{error::Error, str::FromStr}; use esp_build::assert_unique_used_features; +use esp_config::{generate_config, Value}; use esp_metadata::{Chip, Config}; fn main() -> Result<(), Box> { @@ -130,6 +131,42 @@ fn main() -> Result<(), Box> { } } + // emit config + generate_config( + "esp_wifi", + &[ + ("rx_queue_size", Value::Number(5), "Size of the RX queue in frames"), + ("tx_queue_size", Value::Number(3), "Size of the TX queue in frames"), + ("static_rx_buf_num", Value::Number(10), "WiFi static RX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("dynamic_rx_buf_num", Value::Number(32), "WiFi dynamic RX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("static_tx_buf_num", Value::Number(0), "WiFi static TX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("dynamic_tx_buf_num", Value::Number(32), "WiFi dynamic TX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("ampdu_rx_enable", Value::Bool(false), "WiFi AMPDU RX feature enable flag. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("ampdu_tx_enable", Value::Bool(false), "WiFi AMPDU TX feature enable flag. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("amsdu_tx_enable", Value::Bool(false), "WiFi AMSDU TX feature enable flag. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("rx_ba_win", Value::Number(6), "WiFi Block Ack RX window size. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)"), + ("max_burst_size", Value::Number(1), "See [smoltcp's documentation](https://docs.rs/smoltcp/0.10.0/smoltcp/phy/struct.DeviceCapabilities.html#structfield.max_burst_size)"), + ( + "country_code", + Value::String("CN".to_owned()), + "Country code. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-country-code)", + ), + ( + "country_code_operating_class", + Value::Number(0), + "If not 0: Operating Class table number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-country-code)", + ), + ("mtu", Value::Number(1492), "MTU, see [smoltcp's documentation](https://docs.rs/smoltcp/0.10.0/smoltcp/phy/struct.DeviceCapabilities.html#structfield.max_transmission_unit)"), + ("tick_rate_hz", Value::Number(100), "Tick rate of the internal task scheduler in hertz"), + ("listen_interval", Value::Number(3), "Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval. For example, if beacon interval is 100 ms and listen interval is 3, the interval for station to listen to beacon is 300 ms"), + ("beacon_timeout", Value::Number(6), "For Station, If the station does not receive a beacon frame from the connected SoftAP during the inactive time, disconnect from SoftAP. Default 6s. Range 6-30"), + ("ap_beacon_timeout", Value::Number(300), "For SoftAP, If the SoftAP doesn’t receive any data from the connected STA during inactive time, the SoftAP will force deauth the STA. Default is 300s"), + ("failure_retry_cnt", Value::Number(1), "Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. Defaults to 1"), + ("scan_method", Value::Number(0), "0 = WIFI_FAST_SCAN, 1 = WIFI_ALL_CHANNEL_SCAN, defaults to 0"), + ], + true + ); + Ok(()) } diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index 896dd2392ff..08e21c6a572 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -1,3 +1,72 @@ +//! This documentation is built for the +#![cfg_attr(esp32, doc = "**ESP32**")] +#![cfg_attr(esp32s2, doc = "**ESP32-S2**")] +#![cfg_attr(esp32s3, doc = "**ESP32-S3**")] +#![cfg_attr(esp32c2, doc = "**ESP32-C2**")] +#![cfg_attr(esp32c3, doc = "**ESP32-C3**")] +#![cfg_attr(esp32c6, doc = "**ESP32-C6**")] +#![cfg_attr(esp32h2, doc = "**ESP32-H2**")] +//! . Please ensure you are reading the correct documentation for your target +//! device. +//! +//! ## Usage +//! +//! ### Importing +//! +//! Ensure that the right features are enabled for your chip. See [Examples](https://github.com/esp-rs/esp-hal/tree/main/examples#examples) for more examples. +//! +//! ```toml +//! [dependencies.esp-wifi] +//! # A supported chip needs to be specified, as well as specific use-case features +//! features = ["esp32s3", "wifi", "esp-now"] +//! ``` +//! +//! ### Link configuration +//! +//! Make sure to include the rom functions for your target: +//! +//! ```toml +//! # .cargo/config.toml +//! rustflags = [ +//! "-C", "link-arg=-Tlinkall.x", +//! "-C", "link-arg=-Trom_functions.x", +//! ] +//! ``` +//! +//! At the time of writing, you will already have the `linkall` flag if you used +//! `cargo generate`. Generating from a template does not include the +//! `rom_functions` flag. +//! +//! ### Optimization Level +//! +//! It is necessary to build with optimization level 2 or 3 since otherwise, it +//! might not even be able to connect or advertise. +//! +//! To make it work also for your debug builds add this to your `Cargo.toml` +//! +//! ```toml +//! [profile.dev.package.esp-wifi] +//! opt-level = 3 +//! ``` +//! ## Globally disable logging +//! +//! `esp-wifi` contains a lot of trace-level logging statements. +//! For maximum performance you might want to disable logging via +//! a feature flag of the `log` crate. See [documentation](https://docs.rs/log/0.4.19/log/#compile-time-filters). +//! You should set it to `release_max_level_off`. +//! +//! ### Xtensa considerations +//! +//! Within this crate, `CCOMPARE0` CPU timer is used for timing, ensure that in +//! your application you are not using this CPU timer. +//! +//! ## USB-SERIAL-JTAG +//! +//! When using USB-SERIAL-JTAG (for example by selecting `jtag-serial` in [`esp-println`](https://crates.io/crates/esp-println)) you have to activate the feature `phy-enable-usb`. +//! +//! Don't use this feature if you are _not_ using USB-SERIAL-JTAG as it might +//! reduce WiFi performance. +//! //! # Features flags //! //! Note that not all features are available on every MCU. For example, `ble` @@ -8,7 +77,19 @@ //! For more information see //! [extras/esp-wifishark/README.md](../extras/esp-wifishark/README.md) #![doc = document_features::document_features!(feature_label = r#"{feature}"#)] -#![doc = include_str!("../README.md")] +//! ## 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_wifi_config_table.md"))] +#![doc = ""] +//! It's important to note that due to a [bug in cargo](https://github.com/rust-lang/cargo/issues/10358), +//! any modifications to the environment, local or otherwise will only get +//! picked up on a full clean build of the project. + #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![no_std] #![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))] @@ -25,6 +106,7 @@ extern crate alloc; mod fmt; use common_adapter::{chip_specific::phy_mem_init, init_radio_clock_control, RADIO_CLOCKS}; +use esp_config::*; use esp_hal as hal; #[cfg(not(feature = "esp32"))] use esp_hal::timer::systimer::Alarm; @@ -73,61 +155,56 @@ pub fn current_millis() -> u64 { ticks_to_millis(get_systimer_count()) } -#[allow(unused)] -#[cfg(debug_assertions)] -const DEFAULT_TICK_RATE_HZ: u32 = 50; - -#[allow(unused)] -#[cfg(not(debug_assertions))] -const DEFAULT_TICK_RATE_HZ: u32 = 100; - #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[toml_cfg::toml_config] /// Tunable parameters for the WiFi driver +#[allow(unused)] // currently there are no ble tunables struct Config { - #[default(5)] rx_queue_size: usize, - #[default(3)] tx_queue_size: usize, - #[default(10)] static_rx_buf_num: usize, - #[default(32)] dynamic_rx_buf_num: usize, - #[default(0)] static_tx_buf_num: usize, - #[default(32)] dynamic_tx_buf_num: usize, - #[default(0)] - ampdu_rx_enable: usize, - #[default(0)] - ampdu_tx_enable: usize, - #[default(0)] - amsdu_tx_enable: usize, - #[default(6)] + ampdu_rx_enable: bool, + ampdu_tx_enable: bool, + amsdu_tx_enable: bool, rx_ba_win: usize, - #[default(1)] max_burst_size: usize, - #[default("CN")] country_code: &'static str, - #[default(0)] country_code_operating_class: u8, - #[default(1492)] mtu: usize, - #[default(DEFAULT_TICK_RATE_HZ)] tick_rate_hz: u32, - #[default(3)] listen_interval: u16, - #[default(6)] beacon_timeout: u16, - #[default(300)] ap_beacon_timeout: u16, - #[default(1)] failure_retry_cnt: u8, - #[default(0)] scan_method: u32, } +pub(crate) const CONFIG: Config = Config { + rx_queue_size: esp_config_int!(usize, "ESP_WIFI_RX_QUEUE_SIZE"), + tx_queue_size: esp_config_int!(usize, "ESP_WIFI_TX_QUEUE_SIZE"), + static_rx_buf_num: esp_config_int!(usize, "ESP_WIFI_STATIC_RX_BUF_NUM"), + dynamic_rx_buf_num: esp_config_int!(usize, "ESP_WIFI_DYNAMIC_RX_BUF_NUM"), + static_tx_buf_num: esp_config_int!(usize, "ESP_WIFI_STATIC_TX_BUF_NUM"), + dynamic_tx_buf_num: esp_config_int!(usize, "ESP_WIFI_DYNAMIC_TX_BUF_NUM"), + ampdu_rx_enable: esp_config_bool!("ESP_WIFI_AMPDU_RX_ENABLE"), + ampdu_tx_enable: esp_config_bool!("ESP_WIFI_AMPDU_TX_ENABLE"), + amsdu_tx_enable: esp_config_bool!("ESP_WIFI_AMSDU_TX_ENABLE"), + rx_ba_win: esp_config_int!(usize, "ESP_WIFI_RX_BA_WIN"), + max_burst_size: esp_config_int!(usize, "ESP_WIFI_MAX_BURST_SIZE"), + country_code: esp_config_str!("ESP_WIFI_COUNTRY_CODE"), + country_code_operating_class: esp_config_int!(u8, "ESP_WIFI_COUNTRY_CODE_OPERATING_CLASS"), + mtu: esp_config_int!(usize, "ESP_WIFI_MTU"), + tick_rate_hz: esp_config_int!(u32, "ESP_WIFI_TICK_RATE_HZ"), + listen_interval: esp_config_int!(u16, "ESP_WIFI_LISTEN_INTERVAL"), + beacon_timeout: esp_config_int!(u16, "ESP_WIFI_BEACON_TIMEOUT"), + ap_beacon_timeout: esp_config_int!(u16, "ESP_WIFI_AP_BEACON_TIMEOUT"), + failure_retry_cnt: esp_config_int!(u8, "ESP_WIFI_FAILURE_RETRY_CNT"), + scan_method: esp_config_int!(u32, "ESP_WIFI_SCAN_METHOD"), +}; + // Validate the configuration at compile time #[allow(clippy::assertions_on_constants)] const _: () = { diff --git a/esp-wifi/tuning.md b/esp-wifi/tuning.md deleted file mode 100644 index ec80d27e408..00000000000 --- a/esp-wifi/tuning.md +++ /dev/null @@ -1,56 +0,0 @@ -# Tuning the configuration - -You can change a few of the default settings used. Please keep in mind that it's almost always a tradeoff between memory usage and performance. -It's easy to decrease performance by using unfortunate settings or even break the application or making it less stable. - -So you should test every change very carefully. - -Be aware that settings which work fine on one ESP32 model might not work at all on other. Also, settings should be adjusted according to your application's needs. - -## Create a configuration - -We use [toml-cfg](https://crates.io/crates/toml-cfg) for the build time configuration - -You need to add a `cfg.toml` file in the root of your binary crate. When using a _Cargo Workspace_ you should put the file in the root of the workspace directory. - -A configuration file can look like this: -```toml -[esp-wifi] -rx_queue_size = 15 -tx_queue_size = 3 -static_rx_buf_num = 10 -dynamic_rx_buf_num = 16 -ampdu_rx_enable = 0 -ampdu_tx_enable = 0 -rx_ba_win = 32 -max_burst_size = 6 -``` - -You can set the following settings -|Key|Description| -|-|-| -|rx_queue_size|Size of the RX queue in frames| -|tx_queue_size|Size of the TX queue in frames| -|max_burst_size|See [documentation](https://docs.rs/smoltcp/0.10.0/smoltcp/phy/struct.DeviceCapabilities.html#structfield.max_burst_size)| -|static_rx_buf_num|WiFi static RX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|dynamic_rx_buf_num|WiFi dynamic RX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|static_tx_buf_num|WiFi static TX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|dynamic_tx_buf_num|WiFi dynamic TX buffer number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|ampdu_rx_enable|WiFi AMPDU RX feature enable flag. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|ampdu_rx_enable|WiFi AMPDU RX feature enable flag. (0 or 1) See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|ampdu_tx_enable|WiFi AMPDU TX feature enable flag. (0 or 1) See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|amsdu_tx_enable|WiFi AMSDU TX feature enable flag. (0 or 1) See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|rx_ba_win|WiFi Block Ack RX window size. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv418wifi_init_config_t)| -|country_code|Country code. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-country-code)| -|country_code_operating_class|If not 0: Operating Class table number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-country-code)| -|mtu|MTU, see [documentation](https://docs.rs/smoltcp/0.10.0/smoltcp/phy/struct.DeviceCapabilities.html#structfield.max_transmission_unit)| -|tick_rate_hz|Tick rate of the internal task scheduler in hertz.| -|listen_interval|Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval. For example, if beacon interval is 100 ms and listen interval is 3, the interval for station to listen to beacon is 300 ms| -|beacon_timeout|For Station, If the station does not receive a beacon frame from the connected SoftAP during the inactive time, disconnect from SoftAP. Default 6s. Range 6-30| -|ap_beacon_timeout|For SoftAP, If the SoftAP doesn’t receive any data from the connected STA during inactive time, the SoftAP will force deauth the STA. Default is 300s.| -|failure_retry_cnt|Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. Defaults to 1| -|scan_method|0 = WIFI_FAST_SCAN, 1 = WIFI_ALL_CHANNEL_SCAN, defaults to 0| - -## Globally disable logging - -`esp-wifi` contains a lot of trace-level logging statements. For maximum performance you might want to disable logging via a feature flag of the `log` crate. See [documentation](https://docs.rs/log/0.4.19/log/#compile-time-filters). You should set it to `release_max_level_off` diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index ae8a397bac8..1378b70c684 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -36,6 +36,7 @@ pub enum Package { EspAlloc, EspBacktrace, EspBuild, + EspConfig, EspHal, EspHalEmbassy, EspHalProcmacros,