Tweak features and dependencies (#3425)

* Group optional dependencies

* Separate version from crate name

* Restore defmt-log mutual exclusivity

* Gate ufmt

* Remove usb-device

* Feature-gate unsable dependencies behind unstable

* S2: assume single core for portable-atomic

* Clean up feature flag docs

* Sack debug

* Fix clippy

* Update examples

* Fix usb-otg feature

* Fix fmt

* Add version to log dep

* Also mark bluetooth private

* Correct changelog/MG

* Clean up esp-hal-embassy

* Clean up ieee802154

* Clean up esp-println

* Move the timestamp function up

* Move info from readme to feature docs

* Clean up esp-storage

* Clean up esp-wifi

* Fix examples

* Add a note for the private features
This commit is contained in:
Dániel Buga 2025-05-05 13:33:55 +02:00 committed by GitHub
parent c255604d4b
commit 16897bb68d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 816 additions and 570 deletions

View File

@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The `IntoAnyTimer` trait has been removed (#3444) - The `IntoAnyTimer` trait has been removed (#3444)
- The `TimerCollection` trait has been sealed and renamed to `TimeBase`. Former `IntoAnyTimer` functionality has been merged into `TimeBase`. (#3444) - The `TimerCollection` trait has been sealed and renamed to `TimeBase`. Former `IntoAnyTimer` functionality has been merged into `TimeBase`. (#3444)
- `esp_hal_embassy::init` will panic if called multiple times (#3444) - `esp_hal_embassy::init` will panic if called multiple times (#3444)
- The `log` feature has been replaced by `log-04`. (#3425)
### Fixed ### Fixed

View File

@ -19,20 +19,27 @@ bench = false
test = false test = false
[dependencies] [dependencies]
cfg-if = "1.0.0"
critical-section = "1.2.0" critical-section = "1.2.0"
defmt = { version = "1.0.1", optional = true } esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" }
portable-atomic = "1.11.0"
static_cell = "2.1.0"
# Unstable dependencies that are not (strictly) part of the public API
document-features = "0.2.11" document-features = "0.2.11"
embassy-executor = { version = "0.7.0", features = ["timer-item-payload-size-4"], optional = true }
embassy-sync = { version = "0.6.2" } embassy-sync = { version = "0.6.2" }
embassy-time = { version = "0.4.0" } embassy-time = { version = "0.4.0" }
embassy-time-driver = { version = "0.2.0", features = [ "tick-hz-1_000_000" ] } embassy-time-driver = { version = "0.2.0", features = [ "tick-hz-1_000_000" ] }
embassy-time-queue-utils = { version = "0.1.0", features = ["_generic-queue"] } embassy-time-queue-utils = { version = "0.1.0", features = ["_generic-queue"] }
esp-config = { version = "0.3.0", path = "../esp-config" } esp-config = { version = "0.3.0", path = "../esp-config" }
esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" }
log = { version = "0.4.27", optional = true }
macros = { version = "0.17.0", features = ["embassy"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" } macros = { version = "0.17.0", features = ["embassy"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
portable-atomic = "1.11.0"
static_cell = "2.1.0" # Optional dependencies that enable ecosystem support.
embassy-executor = { version = "0.7.0", features = ["timer-item-payload-size-4"], optional = true }
# Logging interfaces, they are mutually exclusive so they need to be behind separate features.
defmt = { version = "1.0.1", optional = true }
log-04 = { package = "log", version = "0.4.27", optional = true }
[build-dependencies] [build-dependencies]
esp-build = { version = "0.2.0", path = "../esp-build" } esp-build = { version = "0.2.0", path = "../esp-build" }
@ -50,12 +57,14 @@ esp32h2 = ["esp-hal/esp32h2"]
esp32s2 = ["esp-hal/esp32s2"] esp32s2 = ["esp-hal/esp32s2"]
esp32s3 = ["esp-hal/esp32s3"] esp32s3 = ["esp-hal/esp32s3"]
## Implement `defmt::Format` on certain types. ## Enable the `Executor` and `InterruptExecutor` embassy executor implementations.
defmt = ["dep:defmt", "embassy-executor?/defmt", "esp-hal/defmt"]
## Enable logging via the log crate
log = ["dep:log"]
## Provide `Executor` and `InterruptExecutor`
executors = ["dep:embassy-executor", "esp-hal/__esp_hal_embassy"] executors = ["dep:embassy-executor", "esp-hal/__esp_hal_embassy"]
#! ### Logging Feature Flags
## Enable logging output using version 0.4 of the `log` crate.
log-04 = ["dep:log-04"]
## Enable logging output using `defmt` and implement `defmt::Format` on certain types.
defmt = ["dep:defmt", "embassy-executor?/defmt", "esp-hal/defmt"]
[lints.rust] [lints.rust]
unexpected_cfgs = "allow" unexpected_cfgs = "allow"

View File

@ -5,10 +5,13 @@
macro_rules! assert { macro_rules! assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert!($($x)*);
::defmt::assert!($($x)*); } else {
::core::assert!($($x)*);
}
}
} }
}; };
} }
@ -17,10 +20,13 @@ macro_rules! assert {
macro_rules! assert_eq { macro_rules! assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_eq!($($x)*);
::defmt::assert_eq!($($x)*); } else {
::core::assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -29,10 +35,13 @@ macro_rules! assert_eq {
macro_rules! assert_ne { macro_rules! assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_ne!($($x)*);
::defmt::assert_ne!($($x)*); } else {
::core::assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -41,10 +50,13 @@ macro_rules! assert_ne {
macro_rules! debug_assert { macro_rules! debug_assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert!($($x)*);
::defmt::debug_assert!($($x)*); } else {
::core::debug_assert!($($x)*);
}
}
} }
}; };
} }
@ -53,10 +65,13 @@ macro_rules! debug_assert {
macro_rules! debug_assert_eq { macro_rules! debug_assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_eq!($($x)*);
::defmt::debug_assert_eq!($($x)*); } else {
::core::debug_assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -65,10 +80,13 @@ macro_rules! debug_assert_eq {
macro_rules! debug_assert_ne { macro_rules! debug_assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_ne!($($x)*);
::defmt::debug_assert_ne!($($x)*); } else {
::core::debug_assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -77,10 +95,13 @@ macro_rules! debug_assert_ne {
macro_rules! todo { macro_rules! todo {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::todo!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::todo!($($x)*);
::defmt::todo!($($x)*); } else {
::core::todo!($($x)*);
}
}
} }
}; };
} }
@ -89,10 +110,13 @@ macro_rules! todo {
macro_rules! unreachable { macro_rules! unreachable {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::unreachable!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::unreachable!($($x)*);
::defmt::unreachable!($($x)*); } else {
::core::unreachable!($($x)*);
}
}
} }
}; };
} }
@ -101,10 +125,13 @@ macro_rules! unreachable {
macro_rules! panic { macro_rules! panic {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::panic!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::panic!($($x)*);
::defmt::panic!($($x)*); } else {
::core::panic!($($x)*);
}
}
} }
}; };
} }
@ -113,12 +140,15 @@ macro_rules! panic {
macro_rules! trace { macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::trace!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::trace!($s $(, $x)*);
::defmt::trace!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::trace!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -127,12 +157,15 @@ macro_rules! trace {
macro_rules! debug { macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::debug!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug!($s $(, $x)*);
::defmt::debug!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::debug!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -141,12 +174,15 @@ macro_rules! debug {
macro_rules! info { macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::info!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::info!($s $(, $x)*);
::defmt::info!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::info!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -155,12 +191,15 @@ macro_rules! info {
macro_rules! warn { macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::warn!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::warn!($s $(, $x)*);
::defmt::warn!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::warn!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -169,12 +208,15 @@ macro_rules! warn {
macro_rules! error { macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::error!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::error!($s $(, $x)*);
::defmt::error!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::error!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }

View File

@ -56,6 +56,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update `defmt` to 1.0 (#3416) - Update `defmt` to 1.0 (#3416)
- `spi::master::Spi::transfer` no longer returns the received data as a slice (#?) - `spi::master::Spi::transfer` no longer returns the received data as a slice (#?)
- esp-hal no longer clears the GPIO interrupt status bits by default. (#3408) - esp-hal no longer clears the GPIO interrupt status bits by default. (#3408)
- `spi::master::Spi::transfer` no longer returns the received data as a slice (#3417)
- The `log` feature has been replaced by `log-04`. (#3425)
- Multiple feature flags have been replaced by `unstable`. (#3425)
- The `debug` feature has been removed. (#3425)
- The `usb_otg` and `bluetooth` features are now considered private and have been renamed accordingly. (#3425)
### Fixed ### Fixed

View File

@ -23,40 +23,51 @@ test = false
[dependencies] [dependencies]
bitflags = "2.9.0" bitflags = "2.9.0"
bytemuck = "1.22.0" bytemuck = "1.22.0"
bitfield = "0.19.0"
cfg-if = "1.0.0" cfg-if = "1.0.0"
critical-section = { version = "1.2.0", features = ["restore-state-u32"] } critical-section = { version = "1.2.0", features = ["restore-state-u32"] }
defmt = { version = "1.0.1", optional = true }
delegate = "0.13.3"
digest = { version = "0.10.7", default-features = false, optional = true }
document-features = "0.2.11"
embassy-embedded-hal = { version = "0.3.0", optional = true }
embassy-futures = "0.1.1"
embassy-sync = "0.6.2"
embassy-usb-driver = { version = "0.1.0", optional = true }
embassy-usb-synopsys-otg = { version = "0.2.0", optional = true }
embedded-can = { version = "0.4.1", optional = true }
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
embedded-hal-async = "1.0.0" embedded-hal-async = "1.0.0"
embedded-io = { version = "0.6.1", optional = true }
embedded-io-async = { version = "0.6.1", optional = true }
enumset = "1.1.5" enumset = "1.1.5"
paste = "1.0.15"
portable-atomic = { version = "1.11.0", default-features = false }
# Unstable dependencies that are not (strictly) part of the public API
bitfield = "0.19.0"
delegate = "0.13.3"
document-features = "0.2.11"
embassy-futures = "0.1.1"
embassy-sync = "0.6.2"
fugit = "0.3.7"
instability = "0.3.7"
strum = { version = "0.27.1", default-features = false, features = ["derive"] }
esp-build = { version = "0.2.0", path = "../esp-build" } esp-build = { version = "0.2.0", path = "../esp-build" }
esp-config = { version = "0.3.0", path = "../esp-config" } esp-config = { version = "0.3.0", path = "../esp-config" }
esp-metadata = { version = "0.6.0", path = "../esp-metadata", default-features = false } esp-metadata = { version = "0.6.0", path = "../esp-metadata", default-features = false }
esp-synopsys-usb-otg = { version = "0.4.2", optional = true, features = ["fs", "esp32sx"] }
fugit = "0.3.7"
instability = "0.3.7"
log = { version = "0.4.27", optional = true }
nb = { version = "1.1.0", optional = true }
paste = "1.0.15"
portable-atomic = { version = "1.11.0", default-features = false }
procmacros = { version = "0.17.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" } procmacros = { version = "0.17.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
strum = { version = "0.27.1", default-features = false, features = ["derive"] }
usb-device = { version = "0.3.2", optional = true } # Dependencies that are optional because they are used by unstable drivers.
rand_core06 = { package = "rand_core", version = "0.6.4", optional = true } # They are needed when using the `unstable` feature.
rand_core09 = { package = "rand_core", version = "0.9.0", optional = true } digest = { version = "0.10.7", default-features = false, optional = true }
ufmt-write = "0.1.0" embassy-usb-driver = { version = "0.1.0", optional = true }
embassy-usb-synopsys-otg = { version = "0.2.0", optional = true }
embedded-can = { version = "0.4.1", optional = true }
esp-synopsys-usb-otg = { version = "0.4.2", optional = true }
nb = { version = "1.1.0", optional = true }
# Logging interfaces, they are mutually exclusive so they need to be behind separate features.
defmt = { version = "1.0.1", optional = true }
log-04 = { package = "log", version = "0.4.27", optional = true }
# Optional dependencies that enable ecosystem support.
# We could support individually enabling them, but there is no big downside to just
# enabling them all via the `unstable` feature.
embassy-embedded-hal = { version = "0.3.0", optional = true }
embedded-io = { version = "0.6.1", optional = true }
embedded-io-async = { version = "0.6.1", optional = true }
rand_core-06 = { package = "rand_core", version = "0.6.4", optional = true }
rand_core-09 = { package = "rand_core", version = "0.9.0", optional = true }
ufmt-write = { version = "0.1.0", optional = true }
# IMPORTANT: # IMPORTANT:
# Each supported device MUST have its PAC included below along with a # Each supported device MUST have its PAC included below along with a
@ -91,50 +102,78 @@ jiff = { version = "0.2.10", default-features = false, features = ["static"] }
[features] [features]
default = [] default = []
bluetooth = [] # These features are considered private and unstable. They are not covered by
# semver guarantees and may change or be removed without notice.
usb-otg = ["dep:embassy-usb-driver", "dep:embassy-usb-synopsys-otg", "dep:esp-synopsys-usb-otg", "dep:usb-device"] __bluetooth = []
__esp_hal_embassy = [] __esp_hal_embassy = []
__usb_otg = [
## Enable debug features in the HAL (used for development). "dep:embassy-usb-driver",
debug = [ "dep:embassy-usb-synopsys-otg",
"esp32?/impl-register-debug", "dep:esp-synopsys-usb-otg",
"esp32c2?/impl-register-debug", "esp-synopsys-usb-otg/esp32sx",
"esp32c3?/impl-register-debug", "esp-synopsys-usb-otg/fs",
"esp32c6?/impl-register-debug",
"esp32h2?/impl-register-debug",
"esp32s2?/impl-register-debug",
"esp32s3?/impl-register-debug",
] ]
## Enable logging output using the `log` crate.
log = ["dep:log"]
# Chip Support Feature Flags # Chip Support Feature Flags
# Target the ESP32. # Target the ESP32.
esp32 = ["dep:esp32", "procmacros/rtc-slow", "xtensa-lx-rt/esp32"] esp32 = [
"dep:esp32",
"procmacros/rtc-slow",
"xtensa-lx-rt/esp32",
]
# Target the ESP32-C2. # Target the ESP32-C2.
esp32c2 = ["dep:esp32c2", "portable-atomic/unsafe-assume-single-core"] esp32c2 = [
"dep:esp32c2",
"portable-atomic/unsafe-assume-single-core",
]
# Target the ESP32-C3. # Target the ESP32-C3.
esp32c3 = ["dep:esp32c3", "esp-riscv-rt/rtc-ram", "portable-atomic/unsafe-assume-single-core"] esp32c3 = [
"dep:esp32c3",
"esp-riscv-rt/rtc-ram",
"portable-atomic/unsafe-assume-single-core",
]
# Target the ESP32-C6. # Target the ESP32-C6.
esp32c6 = ["dep:esp32c6", "esp-riscv-rt/rtc-ram", "procmacros/has-lp-core"] esp32c6 = [
"dep:esp32c6",
"esp-riscv-rt/rtc-ram",
"procmacros/has-lp-core",
]
# Target the ESP32-H2. # Target the ESP32-H2.
esp32h2 = ["dep:esp32h2", "esp-riscv-rt/rtc-ram"] esp32h2 = [
"dep:esp32h2",
"esp-riscv-rt/rtc-ram",
]
# Target the ESP32-S2. # Target the ESP32-S2.
esp32s2 = ["dep:esp32s2", "portable-atomic/critical-section", "procmacros/has-ulp-core", "procmacros/rtc-slow", "usb-otg", "xtensa-lx-rt/esp32s2"] esp32s2 = [
"dep:esp32s2",
"portable-atomic/unsafe-assume-single-core",
"procmacros/has-ulp-core",
"procmacros/rtc-slow",
"xtensa-lx-rt/esp32s2",
"__usb_otg",
]
# Target the ESP32-S3. # Target the ESP32-S3.
esp32s3 = ["dep:esp32s3", "procmacros/has-ulp-core", "procmacros/rtc-slow", "usb-otg", "xtensa-lx-rt/esp32s3"] esp32s3 = [
"dep:esp32s3",
"procmacros/has-ulp-core",
"procmacros/rtc-slow",
"xtensa-lx-rt/esp32s3",
"__usb_otg",
]
#! ### Trait Implementation Feature Flags
## Implement `defmt::Format` on certain types. #! ### Logging Feature Flags
## Enable logging output using version 0.4 of the `log` crate.
log-04 = ["dep:log-04"]
## Enable logging output using `defmt` and implement `defmt::Format` on certain types.
defmt = [ defmt = [
"dep:defmt", "dep:defmt",
"embassy-futures/defmt", "embassy-futures/defmt",
"embassy-sync/defmt", "embassy-sync/defmt",
"embedded-hal/defmt-03", "embedded-hal/defmt-03",
"embedded-io/defmt-03", "embedded-io?/defmt-03",
"embedded-io-async/defmt-03", "embedded-io-async?/defmt-03",
"esp32?/defmt", "esp32?/defmt",
"esp32c2?/defmt", "esp32c2?/defmt",
"esp32c3?/defmt", "esp32c3?/defmt",
@ -146,6 +185,7 @@ defmt = [
] ]
#! ### PSRAM Feature Flags #! ### PSRAM Feature Flags
## Use externally connected PSRAM (`quad` by default, can be configured to `octal` via ESP_HAL_CONFIG_PSRAM_MODE) ## Use externally connected PSRAM (`quad` by default, can be configured to `octal` via ESP_HAL_CONFIG_PSRAM_MODE)
psram = [] psram = []
@ -156,13 +196,15 @@ psram = []
## Enables APIs that are not stable and thus come with no stability guarantees. ## Enables APIs that are not stable and thus come with no stability guarantees.
unstable = [ unstable = [
"dep:digest",
"dep:embassy-embedded-hal", "dep:embassy-embedded-hal",
"dep:embedded-can", "dep:embedded-can",
"dep:embedded-io", "dep:embedded-io",
"dep:embedded-io-async", "dep:embedded-io-async",
"dep:rand_core06", "dep:rand_core-06",
"dep:rand_core09", "dep:rand_core-09",
"dep:nb", "dep:nb",
"dep:ufmt-write",
] ]
[lints.clippy] [lints.clippy]

View File

@ -352,3 +352,15 @@ Some configuration options are now unstable and they require the `unstable` feat
enabled. You can learn about a particular option in the [esp-hal documentation](https://docs.espressif.com/projects/rust/esp-hal/latest/). enabled. You can learn about a particular option in the [esp-hal documentation](https://docs.espressif.com/projects/rust/esp-hal/latest/).
The `ESP_HAL_CONFIG_PLACE_SPI_DRIVER_IN_RAM` configuration option has been renamed to `ESP_HAL_CONFIG_PLACE_SPI_MASTER_DRIVER_IN_RAM`. The `ESP_HAL_CONFIG_PLACE_SPI_DRIVER_IN_RAM` configuration option has been renamed to `ESP_HAL_CONFIG_PLACE_SPI_MASTER_DRIVER_IN_RAM`.
## Changes related to cargo features
The `log` feature has been replaced by `log-04`.
The following dependencies are now gated behind the `unstable` feature and their
invididual features are no longer available:
- `digest`
- `ufmt-write`
The `usb_otg` and `bluetooth` features are now considered private and have been renamed accordingly.
The `debug` feature has been removed. If you used it, enable `impl-register-debug` on the PAC of your device.

View File

@ -8,7 +8,7 @@ use std::{
str::FromStr, str::FromStr,
}; };
use esp_build::assert_unique_used_features; use esp_build::{assert_unique_features, assert_unique_used_features};
use esp_config::{ConfigOption, Stability, Validator, Value, generate_config}; use esp_config::{ConfigOption, Stability, Validator, Value, generate_config};
use esp_metadata::{Chip, Config}; use esp_metadata::{Chip, Config};
@ -26,6 +26,11 @@ fn main() -> Result<(), Box<dyn Error>> {
"esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3" "esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3"
); );
// Log and defmt are mutually exclusive features. The main technical reason is
// that allowing both would make the exact panicking behaviour a fragile
// implementation detail.
assert_unique_features!("log-04", "defmt");
// NOTE: update when adding new device support! // NOTE: update when adding new device support!
// Determine the name of the configured device: // Determine the name of the configured device:
let device_name = if cfg!(feature = "esp32") { let device_name = if cfg!(feature = "esp32") {
@ -383,7 +388,7 @@ fn substitute_config(cfg: &HashMap<String, Value>, line: &str) -> String {
#[cfg(feature = "esp32")] #[cfg(feature = "esp32")]
fn generate_memory_extras() -> Vec<u8> { fn generate_memory_extras() -> Vec<u8> {
let reserve_dram = if cfg!(feature = "bluetooth") { let reserve_dram = if cfg!(feature = "__bluetooth") {
"0x10000" "0x10000"
} else { } else {
"0x0" "0x0"

View File

@ -5,10 +5,13 @@
macro_rules! assert { macro_rules! assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert!($($x)*);
::defmt::assert!($($x)*); } else {
::core::assert!($($x)*);
}
}
} }
}; };
} }
@ -17,10 +20,13 @@ macro_rules! assert {
macro_rules! assert_eq { macro_rules! assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_eq!($($x)*);
::defmt::assert_eq!($($x)*); } else {
::core::assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -29,10 +35,13 @@ macro_rules! assert_eq {
macro_rules! assert_ne { macro_rules! assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_ne!($($x)*);
::defmt::assert_ne!($($x)*); } else {
::core::assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -41,10 +50,13 @@ macro_rules! assert_ne {
macro_rules! debug_assert { macro_rules! debug_assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert!($($x)*);
::defmt::debug_assert!($($x)*); } else {
::core::debug_assert!($($x)*);
}
}
} }
}; };
} }
@ -53,10 +65,13 @@ macro_rules! debug_assert {
macro_rules! debug_assert_eq { macro_rules! debug_assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_eq!($($x)*);
::defmt::debug_assert_eq!($($x)*); } else {
::core::debug_assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -65,10 +80,13 @@ macro_rules! debug_assert_eq {
macro_rules! debug_assert_ne { macro_rules! debug_assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_ne!($($x)*);
::defmt::debug_assert_ne!($($x)*); } else {
::core::debug_assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -77,10 +95,13 @@ macro_rules! debug_assert_ne {
macro_rules! todo { macro_rules! todo {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::todo!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::todo!($($x)*);
::defmt::todo!($($x)*); } else {
::core::todo!($($x)*);
}
}
} }
}; };
} }
@ -89,10 +110,13 @@ macro_rules! todo {
macro_rules! unreachable { macro_rules! unreachable {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::unreachable!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::unreachable!($($x)*);
::defmt::unreachable!($($x)*); } else {
::core::unreachable!($($x)*);
}
}
} }
}; };
} }
@ -101,10 +125,13 @@ macro_rules! unreachable {
macro_rules! panic { macro_rules! panic {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::panic!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::panic!($($x)*);
::defmt::panic!($($x)*); } else {
::core::panic!($($x)*);
}
}
} }
}; };
} }
@ -113,12 +140,15 @@ macro_rules! panic {
macro_rules! trace { macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::trace!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::trace!($s $(, $x)*);
::defmt::trace!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::trace!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -127,12 +157,15 @@ macro_rules! trace {
macro_rules! debug { macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::debug!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug!($s $(, $x)*);
::defmt::debug!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::debug!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -141,12 +174,15 @@ macro_rules! debug {
macro_rules! info { macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::info!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::info!($s $(, $x)*);
::defmt::info!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::info!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -155,12 +191,15 @@ macro_rules! info {
macro_rules! warn { macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::warn!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::warn!($s $(, $x)*);
::defmt::warn!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::warn!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -169,12 +208,15 @@ macro_rules! warn {
macro_rules! error { macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::error!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::error!($s $(, $x)*);
::defmt::error!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::error!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }

View File

@ -134,7 +134,7 @@ impl Rng {
impl Sealed for Rng {} impl Sealed for Rng {}
#[instability::unstable] #[instability::unstable]
impl rand_core06::RngCore for Rng { impl rand_core_06::RngCore for Rng {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
self.random() self.random()
} }
@ -150,14 +150,14 @@ impl rand_core06::RngCore for Rng {
self.read(dest); self.read(dest);
} }
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core06::Error> { fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
self.read(dest); self.read(dest);
Ok(()) Ok(())
} }
} }
#[instability::unstable] #[instability::unstable]
impl rand_core09::RngCore for Rng { impl rand_core_09::RngCore for Rng {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
self.random() self.random()
} }
@ -231,7 +231,7 @@ impl Drop for Trng<'_> {
/// Implementing RngCore trait from rand_core for `Trng` structure /// Implementing RngCore trait from rand_core for `Trng` structure
#[instability::unstable] #[instability::unstable]
impl rand_core06::RngCore for Trng<'_> { impl rand_core_06::RngCore for Trng<'_> {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
self.rng.next_u32() self.rng.next_u32()
} }
@ -244,13 +244,13 @@ impl rand_core06::RngCore for Trng<'_> {
self.rng.fill_bytes(dest) self.rng.fill_bytes(dest)
} }
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core06::Error> { fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
self.rng.try_fill_bytes(dest) self.rng.try_fill_bytes(dest)
} }
} }
#[instability::unstable] #[instability::unstable]
impl rand_core09::RngCore for Trng<'_> { impl rand_core_09::RngCore for Trng<'_> {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
self.rng.next_u32() self.rng.next_u32()
} }
@ -265,8 +265,8 @@ impl rand_core09::RngCore for Trng<'_> {
/// Implementing a CryptoRng marker trait that indicates that the generator is /// Implementing a CryptoRng marker trait that indicates that the generator is
/// cryptographically secure. /// cryptographically secure.
#[instability::unstable] #[instability::unstable]
impl rand_core06::CryptoRng for Trng<'_> {} impl rand_core_06::CryptoRng for Trng<'_> {}
#[instability::unstable] #[instability::unstable]
impl rand_core09::CryptoRng for Trng<'_> {} impl rand_core_09::CryptoRng for Trng<'_> {}
impl Sealed for Trng<'_> {} impl Sealed for Trng<'_> {}

View File

@ -60,7 +60,6 @@
use core::{borrow::Borrow, convert::Infallible, marker::PhantomData, mem::size_of}; use core::{borrow::Borrow, convert::Infallible, marker::PhantomData, mem::size_of};
/// Re-export digest for convenience /// Re-export digest for convenience
#[cfg(feature = "digest")]
pub use digest::Digest; pub use digest::Digest;
#[cfg(not(esp32))] #[cfg(not(esp32))]
@ -490,7 +489,6 @@ pub trait ShaAlgorithm: crate::private::Sealed {
/// For example, in SHA-256, this would be 32 bytes. /// For example, in SHA-256, this would be 32 bytes.
const DIGEST_LENGTH: usize; const DIGEST_LENGTH: usize;
#[cfg(feature = "digest")]
#[doc(hidden)] #[doc(hidden)]
type DigestOutputSize: digest::generic_array::ArrayLength<u8> + 'static; type DigestOutputSize: digest::generic_array::ArrayLength<u8> + 'static;
@ -522,25 +520,20 @@ pub trait ShaAlgorithm: crate::private::Sealed {
/// implement digest traits if digest feature is present. /// implement digest traits if digest feature is present.
/// Note: digest has a blanket trait implementation for [digest::Digest] for any /// Note: digest has a blanket trait implementation for [digest::Digest] for any
/// element that implements FixedOutput + Default + Update + HashMarker /// element that implements FixedOutput + Default + Update + HashMarker
#[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::HashMarker for ShaDigest<'d, A, S> {} impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::HashMarker for ShaDigest<'d, A, S> {}
#[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::OutputSizeUser for ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::OutputSizeUser for ShaDigest<'d, A, S> {
type OutputSize = A::DigestOutputSize; type OutputSize = A::DigestOutputSize;
} }
#[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::Update for ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::Update for ShaDigest<'d, A, S> {
fn update(&mut self, data: &[u8]) { fn update(&mut self, mut remaining: &[u8]) {
let mut remaining = data.as_ref();
while !remaining.is_empty() { while !remaining.is_empty() {
remaining = nb::block!(Self::update(self, remaining)).unwrap(); remaining = nb::block!(Self::update(self, remaining)).unwrap();
} }
} }
} }
#[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> {
fn finalize_into(mut self, out: &mut digest::Output<Self>) { fn finalize_into(mut self, out: &mut digest::Output<Self>) {
nb::block!(self.finish(out)).unwrap(); nb::block!(self.finish(out)).unwrap();
@ -575,7 +568,6 @@ macro_rules! impl_sha {
#[cfg(not(esp32))] #[cfg(not(esp32))]
const MODE_AS_BITS: u8 = $mode_bits; const MODE_AS_BITS: u8 = $mode_bits;
#[cfg(feature = "digest")]
// We use paste to append `U` to the digest size to match a const defined in // We use paste to append `U` to the digest size to match a const defined in
// digest // digest
type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]); type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]);

View File

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
- Update `defmt` to 1.0 (#3416) - Update `defmt` to 1.0 (#3416)
- The `log` feature has been replaced by `log-04`. (#3425)
### Fixed ### Fixed

View File

@ -19,17 +19,23 @@ bench = false
test = false test = false
[dependencies] [dependencies]
byte = "0.2.7"
critical-section = "1.2.0"
document-features = "0.2.11"
esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" }
esp-wifi-sys = "0.7.1"
heapless = "0.8.0"
ieee802154 = "0.6.1"
cfg-if = "1.0.0" cfg-if = "1.0.0"
critical-section = "1.2.0"
esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal" }
# ⚠️ Unstable dependencies that are part of the public API
heapless = "0.8.0"
# Unstable dependencies that are not (strictly) part of the public API
byte = "0.2.7"
document-features = "0.2.11"
esp-config = { version = "0.3.0", path = "../esp-config" } esp-config = { version = "0.3.0", path = "../esp-config" }
defmt = { version = "1.0.1", optional = true } esp-wifi-sys = "0.7.1"
log = { version = "0.4.27", optional = true } ieee802154 = "0.6.1"
# Logging interfaces, they are mutually exclusive so they need to be behind separate features.
defmt = { version = "1.0.1", optional = true }
log-04 = { package = "log", version = "0.4.27", optional = true }
[build-dependencies] [build-dependencies]
esp-config = { version = "0.3.0", path = "../esp-config" } esp-config = { version = "0.3.0", path = "../esp-config" }
@ -38,6 +44,12 @@ esp-config = { version = "0.3.0", path = "../esp-config" }
[features] [features]
esp32c6 = ["esp-hal/esp32c6", "esp-wifi-sys/esp32c6"] esp32c6 = ["esp-hal/esp32c6", "esp-wifi-sys/esp32c6"]
esp32h2 = ["esp-hal/esp32h2", "esp-wifi-sys/esp32h2"] esp32h2 = ["esp-hal/esp32h2", "esp-wifi-sys/esp32h2"]
## Enables log messages from the esp-wifi blobs.
sys-logs = ["esp-wifi-sys/sys-logs"] sys-logs = ["esp-wifi-sys/sys-logs"]
log = ["dep:log", "esp-wifi-sys/log"]
#! ### Logging Feature Flags
## Enable logging output using version 0.4 of the `log` crate.
log-04 = ["dep:log-04", "esp-wifi-sys/log"]
## Enable logging output using `defmt` and implement `defmt::Format` on certain types.
defmt = ["dep:defmt", "esp-wifi-sys/defmt"] defmt = ["dep:defmt", "esp-wifi-sys/defmt"]

View File

@ -7,10 +7,13 @@ use core::fmt::{Debug, Display, LowerHex};
macro_rules! assert { macro_rules! assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert!($($x)*);
::defmt::assert!($($x)*); } else {
::core::assert!($($x)*);
}
}
} }
}; };
} }
@ -19,10 +22,13 @@ macro_rules! assert {
macro_rules! assert_eq { macro_rules! assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_eq!($($x)*);
::defmt::assert_eq!($($x)*); } else {
::core::assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -31,10 +37,13 @@ macro_rules! assert_eq {
macro_rules! assert_ne { macro_rules! assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_ne!($($x)*);
::defmt::assert_ne!($($x)*); } else {
::core::assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -43,10 +52,13 @@ macro_rules! assert_ne {
macro_rules! debug_assert { macro_rules! debug_assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert!($($x)*);
::defmt::debug_assert!($($x)*); } else {
::core::debug_assert!($($x)*);
}
}
} }
}; };
} }
@ -55,10 +67,13 @@ macro_rules! debug_assert {
macro_rules! debug_assert_eq { macro_rules! debug_assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_eq!($($x)*);
::defmt::debug_assert_eq!($($x)*); } else {
::core::debug_assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -67,10 +82,13 @@ macro_rules! debug_assert_eq {
macro_rules! debug_assert_ne { macro_rules! debug_assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_ne!($($x)*);
::defmt::debug_assert_ne!($($x)*); } else {
::core::debug_assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -79,10 +97,13 @@ macro_rules! debug_assert_ne {
macro_rules! todo { macro_rules! todo {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::todo!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::todo!($($x)*);
::defmt::todo!($($x)*); } else {
::core::todo!($($x)*);
}
}
} }
}; };
} }
@ -91,10 +112,13 @@ macro_rules! todo {
macro_rules! unreachable { macro_rules! unreachable {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::unreachable!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::unreachable!($($x)*);
::defmt::unreachable!($($x)*); } else {
::core::unreachable!($($x)*);
}
}
} }
}; };
} }
@ -103,10 +127,13 @@ macro_rules! unreachable {
macro_rules! panic { macro_rules! panic {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::panic!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::panic!($($x)*);
::defmt::panic!($($x)*); } else {
::core::panic!($($x)*);
}
}
} }
}; };
} }
@ -115,12 +142,15 @@ macro_rules! panic {
macro_rules! trace { macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::trace!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::trace!($s $(, $x)*);
::defmt::trace!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::trace!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -129,12 +159,15 @@ macro_rules! trace {
macro_rules! debug { macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::debug!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug!($s $(, $x)*);
::defmt::debug!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::debug!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -143,12 +176,15 @@ macro_rules! debug {
macro_rules! info { macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::info!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::info!($s $(, $x)*);
::defmt::info!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::info!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -157,12 +193,15 @@ macro_rules! info {
macro_rules! warn { macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::warn!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::warn!($s $(, $x)*);
::defmt::warn!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::warn!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -171,12 +210,15 @@ macro_rules! warn {
macro_rules! error { macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::error!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::error!($s $(, $x)*);
::defmt::error!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::error!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }

View File

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
- Update `defmt` to 1.0 (#3416) - Update `defmt` to 1.0 (#3416)
- The `log` feature has been replaced by `log-04`. (#3425)
### Fixed ### Fixed

View File

@ -21,21 +21,23 @@ bench = false
test = false test = false
[dependencies] [dependencies]
document-features = "0.2.11"
# Optional dependencies
critical-section = { version = "1.2.0", optional = true } critical-section = { version = "1.2.0", optional = true }
defmt = { version = "1.0.1", optional = true }
log = { version = "0.4.27", optional = true }
portable-atomic = { version = "1.11.0", optional = true, default-features = false } portable-atomic = { version = "1.11.0", optional = true, default-features = false }
# Logging interfaces, they are mutually exclusive so they need to be behind separate features.
defmt = { version = "1.0.1", optional = true }
log-04 = { package = "log", version = "0.4.27", optional = true }
[build-dependencies] [build-dependencies]
esp-build = { version = "0.2.0", path = "../esp-build" } esp-build = { version = "0.2.0", path = "../esp-build" }
log = "0.4.27" log-04 = { package = "log", version = "0.4.27" }
[features] [features]
default = ["auto", "colors", "critical-section"] default = ["auto", "colors", "critical-section"]
critical-section = ["dep:critical-section"]
log = ["dep:log"]
# You must enable exactly 1 of the below features to support the correct chip:
esp32 = [] esp32 = []
esp32c2 = [] esp32c2 = []
esp32c3 = [] esp32c3 = []
@ -45,20 +47,42 @@ esp32p4 = []
esp32s2 = [] esp32s2 = []
esp32s3 = [] esp32s3 = []
# You must enable exactly 1 of the below features to enable to intended ## Use a critical section around print calls. This ensures that the output is consistent.
# communication method (note that "auto" is enabled by default): critical-section = ["dep:critical-section"]
jtag-serial = ["dep:portable-atomic"] # C3, C6, H2, P4, and S3 only!
uart = []
auto = ["dep:portable-atomic"]
# Don't print anything #! ### Output interfaces
#! You must enable exactly 1 of the below features to enable to intended
#! communication method.
## Automatically select the best output interface for the target.
auto = ["dep:portable-atomic"]
## Use the `USB_SERIAL_JTAG` interface for printing. Available on ESP32-C3, ESP32-C6, ESP32-H2, ESP32-P4, and ESP32-S3.
jtag-serial = ["dep:portable-atomic"]
## Use the `UART0` peripehral for printing. Available on all devices.
uart = []
## Don't print anything
no-op = [] no-op = []
# Enables a `defmt` backend usable with espflash. We force rzcobs encoding to simplify implementation #! ### Logging framework features
## Enables using the `log` crate for logging.
log-04 = ["dep:log-04"]
## Enables printing using `defmt`.
##
## defmt-encoded output can only be read using espflash. With esp_hal, this works out of the box.
## Without esp_hal, you need to set the `--log-format defmt` argument for espflash.
defmt-espflash = ["dep:defmt", "defmt?/encoding-rzcobs"] defmt-espflash = ["dep:defmt", "defmt?/encoding-rzcobs"]
# logging sub-features #! ### `log`-specific features
## Colors the message severity in the terminal.
colors = [] colors = []
## Prints the timestamp in the log message.
##
## This option requires the following function to be implemented:
## ```rust
## extern "Rust" {
## fn _esp_println_timestamp() -> u64;
## }
## ```
timestamp = [] timestamp = []
[lints.rust] [lints.rust]

View File

@ -33,34 +33,10 @@ use esp_println::println;
You can now `println!("Hello world")` as usual. You can now `println!("Hello world")` as usual.
# Features
- There is one feature for each supported target: `esp32`, `esp32c2`,
`esp32c3`, `esp32c6`, `esp32h2`, `esp32s2`, and `esp32s3`.
- One of these features must be enabled.
- Only one of these features can be enabled at a time.
- There is one feature for each supported communication method: `uart`, `jtag-serial` and `auto`.
- Only one of these features can be enabled at a time.
- `no-op`: Don't print anything.
- `log`: Enables logging using [`log` crate].
- `colors`: Enable colored logging.
- Only effective when using the `log` feature.
- `critical-section`: Enables critical sections.
- `defmt-espflash`: This is intended to be used with [`espflash`], see `-L/--log-format` argument
of `flash` or `monitor` subcommands of `espflash` and `cargo-espflash`. Uses [rzCOBS] encoding
and adds framing.
## Default Features
By default, we use the `auto`, `critial-section` and `colors` features.
Which means that it will auto-detect if it needs to print to the UART or JTAG-Serial, use critical sections and output
messages will be colored.
If we want to use a communication method that is not `auto`, the default
one, we need to [disable the default features].
## Logging ## Logging
With the feature `log` activated you can initialize a simple logger like this With the feature `log-04` activated, and version 0.4 of the `log` crate added to your dependencies,
you can initialize a simple logger like this:
```rust ```rust
init_logger(log::LevelFilter::Info); init_logger(log::LevelFilter::Info);
@ -97,7 +73,6 @@ https://github.com/knurling-rs/defmt?tab=readme-ov-file#msrv
[`log` crate]: https://github.com/rust-lang/log [`log` crate]: https://github.com/rust-lang/log
[rzCOBS]: https://github.com/Dirbaio/rzcobs [rzCOBS]: https://github.com/Dirbaio/rzcobs
[`espflash`]: https://github.com/esp-rs/espflash [`espflash`]: https://github.com/esp-rs/espflash
[disable the default features]: https://doc.rust-lang.org/cargo/reference/features.html#the-default-feature
[Implementing a Logger section log documentaion]: https://docs.rs/log/0.4.17/log/#implementing-a-logger [Implementing a Logger section log documentaion]: https://docs.rs/log/0.4.17/log/#implementing-a-logger
[`defmt` book's setup instructions]: https://defmt.ferrous-systems.com/setup [`defmt` book's setup instructions]: https://defmt.ferrous-systems.com/setup

View File

@ -1,6 +1,7 @@
use std::{env, path::Path}; use std::{env, path::Path};
use esp_build::assert_unique_used_features; use esp_build::assert_unique_used_features;
use log_04::LevelFilter;
fn main() { fn main() {
// Ensure that only a single chip is specified // Ensure that only a single chip is specified
@ -25,10 +26,10 @@ fn main() {
); );
} }
// Ensure that, if the `colors` is used with `log`.` // Ensure that, if the `colors` is used with `log-04`.
if cfg!(feature = "colors") && !cfg!(feature = "log") { if cfg!(feature = "colors") && !cfg!(feature = "log-04") {
println!( println!(
"cargo:warning=The `colors` feature is only effective when using the `log` feature" "cargo:warning=The `colors` feature is only effective when using the `log-04` feature"
); );
} }
@ -63,40 +64,41 @@ fn generate_filter_snippet() {
.iter() .iter()
.map(|v| v.level) .map(|v| v.level)
.max() .max()
.unwrap_or(log::LevelFilter::Off); .unwrap_or(LevelFilter::Off);
let max = match max { let max = match max {
log::LevelFilter::Off => "Off", LevelFilter::Off => "Off",
log::LevelFilter::Error => "Error", LevelFilter::Error => "Error",
log::LevelFilter::Warn => "Warn", LevelFilter::Warn => "Warn",
log::LevelFilter::Info => "Info", LevelFilter::Info => "Info",
log::LevelFilter::Debug => "Debug", LevelFilter::Debug => "Debug",
log::LevelFilter::Trace => "Trace", LevelFilter::Trace => "Trace",
}; };
let mut snippet = String::new(); let mut snippet = String::new();
snippet.push_str(&format!( snippet.push_str(&format!(
"pub(crate) const FILTER_MAX: log::LevelFilter = log::LevelFilter::{max};" "pub(crate) const FILTER_MAX: log_04::LevelFilter = log_04::LevelFilter::{max};"
)); ));
snippet snippet.push_str(
.push_str("pub(crate) fn is_enabled(level: log::Level, _target: &str) -> bool {"); "pub(crate) fn is_enabled(level: log_04::Level, _target: &str) -> bool {",
);
let mut global_level = None; let mut global_level = None;
for directive in res.directives { for directive in res.directives {
let level = match directive.level { let level = match directive.level {
log::LevelFilter::Off => "Off", LevelFilter::Off => "Off",
log::LevelFilter::Error => "Error", LevelFilter::Error => "Error",
log::LevelFilter::Warn => "Warn", LevelFilter::Warn => "Warn",
log::LevelFilter::Info => "Info", LevelFilter::Info => "Info",
log::LevelFilter::Debug => "Debug", LevelFilter::Debug => "Debug",
log::LevelFilter::Trace => "Trace", LevelFilter::Trace => "Trace",
}; };
if let Some(name) = directive.name { if let Some(name) = directive.name {
// If a prefix matches, don't continue to the next directive // If a prefix matches, don't continue to the next directive
snippet.push_str(&format!( snippet.push_str(&format!(
"if _target.starts_with(\"{}\") {{ return level <= log::LevelFilter::{}; }}", "if _target.starts_with(\"{}\") {{ return level <= log_04::LevelFilter::{}; }}",
&name, level &name, level
)); ));
} else { } else {
@ -109,7 +111,7 @@ fn generate_filter_snippet() {
// Place the fallback rule at the end // Place the fallback rule at the end
if let Some(level) = global_level { if let Some(level) = global_level {
snippet.push_str(&format!("level <= log::LevelFilter::{level}")); snippet.push_str(&format!("level <= log_04::LevelFilter::{level}"));
} else { } else {
snippet.push_str(" false"); snippet.push_str(" false");
} }
@ -117,7 +119,7 @@ fn generate_filter_snippet() {
snippet snippet
} }
} else { } else {
"pub(crate) const FILTER_MAX: log::LevelFilter = log::LevelFilter::Off; pub(crate) fn is_enabled(_level: log::Level, _target: &str) -> bool { true }".to_string() "pub(crate) const FILTER_MAX: log_04::LevelFilter = log_04::LevelFilter::Off; pub(crate) fn is_enabled(_level: log_04::Level, _target: &str) -> bool { true }".to_string()
}; };
std::fs::write(&dest_path, &snippet).unwrap(); std::fs::write(&dest_path, &snippet).unwrap();
@ -142,7 +144,7 @@ impl ParseResult {
#[derive(Debug)] #[derive(Debug)]
struct Directive { struct Directive {
pub(crate) name: Option<String>, pub(crate) name: Option<String>,
pub(crate) level: log::LevelFilter, pub(crate) level: LevelFilter,
} }
/// Parse a logging specification string (e.g: /// Parse a logging specification string (e.g:
@ -167,10 +169,10 @@ fn parse_spec(spec: &str) -> ParseResult {
// treat that as a global fallback // treat that as a global fallback
match part0.parse() { match part0.parse() {
Ok(num) => (num, None), Ok(num) => (num, None),
Err(_) => (log::LevelFilter::max(), Some(part0)), Err(_) => (LevelFilter::max(), Some(part0)),
} }
} }
(Some(part0), Some(""), None) => (log::LevelFilter::max(), Some(part0)), (Some(part0), Some(""), None) => (LevelFilter::max(), Some(part0)),
(Some(part0), Some(part1), None) => { (Some(part0), Some(part1), None) => {
if let Ok(num) = part1.parse() { if let Ok(num) = part1.parse() {
(num, Some(part0)) (num, Some(part0))

View File

@ -1,11 +1,13 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
//! ## Feature Flags
#![doc = document_features::document_features!()]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
#![allow(rustdoc::bare_urls)] #![allow(rustdoc::bare_urls)]
#![no_std] #![no_std]
#[cfg(feature = "defmt-espflash")] #[cfg(feature = "defmt-espflash")]
pub mod defmt; pub mod defmt;
#[cfg(feature = "log")] #[cfg(feature = "log-04")]
pub mod logger; pub mod logger;
macro_rules! log_format { macro_rules! log_format {
@ -528,3 +530,31 @@ fn with<R>(f: impl FnOnce(LockToken) -> R) -> R {
#[cfg(not(feature = "critical-section"))] #[cfg(not(feature = "critical-section"))]
f(unsafe { LockToken::conjure() }) f(unsafe { LockToken::conjure() })
} }
/// A user-provided hook to supply a timestamp in milliseconds for logging.
///
/// When enabled via the `"timestamp"` feature, this function should be
/// implemented to return a timestamp in milliseconds since a reference point
/// (e.g., system boot or Unix epoch).
///
/// # Example
///
/// When using [`esp-hal`], you can define this function as follows:
///
/// ```rust
/// #[no_mangle]
/// pub extern "Rust" fn _esp_println_timestamp() -> u64 {
/// esp_hal::time::Instant::now()
/// .duration_since_epoch()
/// .as_millis()
/// }
/// ```
///
/// # Notes
///
/// - If no implementations is provided, attempting to use this function will
/// result in a linker error.
#[cfg(feature = "timestamp")]
extern "Rust" {
fn _esp_println_timestamp() -> u64;
}

View File

@ -1,3 +1,5 @@
use log_04 as log;
use super::println; use super::println;
#[cfg(not(host_is_windows))] #[cfg(not(host_is_windows))]
@ -94,32 +96,3 @@ fn print_log_record(record: &log::Record) {
#[cfg(not(feature = "timestamp"))] #[cfg(not(feature = "timestamp"))]
println!("{}{} - {}{}", color, record.level(), record.args(), reset); println!("{}{} - {}{}", color, record.level(), record.args(), reset);
} }
/// A user-provided hook to supply a timestamp in milliseconds for logging.
///
/// When enabled via the `"timestamp"` feature, this function should be
/// implemented to return a timestamp in milliseconds since a reference point
/// (e.g., system boot or Unix epoch).
///
/// # Example
///
/// When using [`esp-hal`], you can define this function as follows:
///
/// ```rust
/// #[no_mangle]
/// pub extern "Rust" fn _esp_println_timestamp() -> u64 {
/// esp_hal::time::Instant::now()
/// .duration_since_epoch()
/// .as_millis()
/// }
/// ```
///
/// # Notes
///
/// - If no implementations is provided, attempting to use this function will
/// result in a linker
/// error.
#[cfg(feature = "timestamp")]
extern "Rust" {
fn _esp_println_timestamp() -> u64;
}

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
- The `low-level` feature has been removed, the gated API is always available (#3425)
### Fixed ### Fixed

View File

@ -20,28 +20,43 @@ test = false
[dependencies] [dependencies]
embedded-storage = "0.3.1" embedded-storage = "0.3.1"
# Optional dependencies
critical-section = { version = "1.2.0", optional = true } critical-section = { version = "1.2.0", optional = true }
# Unstable dependencies that are not (strictly) part of the public API
document-features = "0.2.11"
[build-dependencies] [build-dependencies]
esp-build = { version = "0.2.0", path = "../esp-build" } esp-build = { version = "0.2.0", path = "../esp-build" }
[features] [features]
default = ["critical-section"] default = ["critical-section"]
## Place the flash operations in a critical section
critical-section = ["dep:critical-section"] critical-section = ["dep:critical-section"]
esp32c2 = [] ## Bytewise read emulation
esp32c3 = []
esp32c6 = []
esp32h2 = []
esp32 = []
esp32s2 = []
esp32s3 = []
# Bytewise read emulation
bytewise-read = [] bytewise-read = []
# Enable flash emulation to run tests #! ### Chip selection
emulation = [] #! One of the following features must be enabled to select the target chip:
# this feature is reserved for very specific use-cases - usually you don't want to use this! # The following trailing spaces ("## ") are important to display the feature names.
low-level = []
##
esp32c2 = []
##
esp32c3 = []
##
esp32c6 = []
##
esp32h2 = []
##
esp32 = []
##
esp32s2 = []
##
esp32s3 = []
## Used for testing on a host.
emulation = []

View File

@ -1,6 +1,7 @@
//! ## Feature Flags
#![doc = document_features::document_features!()]
#![cfg_attr(not(all(test, feature = "emulation")), no_std)] #![cfg_attr(not(all(test, feature = "emulation")), no_std)]
#[cfg(not(feature = "emulation"))]
#[cfg_attr(feature = "esp32c2", path = "esp32c2.rs")] #[cfg_attr(feature = "esp32c2", path = "esp32c2.rs")]
#[cfg_attr(feature = "esp32c3", path = "esp32c3.rs")] #[cfg_attr(feature = "esp32c3", path = "esp32c3.rs")]
#[cfg_attr(feature = "esp32c6", path = "esp32c6.rs")] #[cfg_attr(feature = "esp32c6", path = "esp32c6.rs")]
@ -8,22 +9,7 @@
#[cfg_attr(feature = "esp32", path = "esp32.rs")] #[cfg_attr(feature = "esp32", path = "esp32.rs")]
#[cfg_attr(feature = "esp32s2", path = "esp32s2.rs")] #[cfg_attr(feature = "esp32s2", path = "esp32s2.rs")]
#[cfg_attr(feature = "esp32s3", path = "esp32s3.rs")] #[cfg_attr(feature = "esp32s3", path = "esp32s3.rs")]
#[cfg_attr( #[cfg_attr(feature = "emulation", path = "stub.rs")]
not(any(
feature = "esp32c2",
feature = "esp32c3",
feature = "esp32c6",
feature = "esp32",
feature = "esp32s2",
feature = "esp32s3",
feature = "esp32h2"
)),
path = "stub.rs"
)]
mod chip_specific;
#[cfg(feature = "emulation")]
#[path = "stub.rs"]
mod chip_specific; mod chip_specific;
mod common; mod common;
@ -31,12 +17,10 @@ mod common;
use common::FlashSectorBuffer; use common::FlashSectorBuffer;
pub use common::{FlashStorage, FlashStorageError}; pub use common::{FlashStorage, FlashStorageError};
pub mod ll;
mod nor_flash; mod nor_flash;
mod storage; mod storage;
#[cfg(feature = "low-level")]
pub mod ll;
#[cfg(not(feature = "emulation"))] #[cfg(not(feature = "emulation"))]
#[inline(always)] #[inline(always)]
#[unsafe(link_section = ".rwtext")] #[unsafe(link_section = ".rwtext")]

View File

@ -1,8 +1,11 @@
/// Low-level API //! # Low-level API
/// //!
/// This gives you access to the underlying low level functionality. //! ⚠️ This is a low-level API and should be used with caution. ⚠️
/// These operate on raw pointers and all functions here are unsafe. //!
/// No pre-conditions are checked by any of these functions. //! This gives you access to the underlying low level functionality.
//! These operate on raw pointers and all functions here are unsafe.
//! No pre-conditions are checked by any of these functions.
use crate::chip_specific; use crate::chip_specific;
/// Low-level SPI NOR Flash read /// Low-level SPI NOR Flash read

View File

@ -14,20 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- The scheduler now runs at interrupt priority 1 on Xtensa chips, too. (#3164) - The scheduler now runs at interrupt priority 1 on Xtensa chips, too. (#3164)
- `esp-now` and `sniffer` are available via `Interfaces` (#3283) - `esp-now` and `sniffer` are available via `Interfaces` (#3283)
- Remove the `heapless` dependency (including from the public API) (#3317) - Remove the `heapless` dependency (including from the public API) (#3317)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
- Update `defmt` to 1.0 (#3416) - Update `defmt` to 1.0 (#3416)
- The `log` feature has been replaced by `log-04`. (#3425)
### Fixed ### Fixed
- Update bt-hci version to fix serialization/deserialization of byte slices (#3340) - Update bt-hci version to fix serialization/deserialization of byte slices (#3340)
- Allow `Configuration::None`, set country early, changed default power-save-mode to None (#3364) - Allow `Configuration::None`, set country early, changed default power-save-mode to None (#3364)
- Enterprise WPA fixed for ESP32-S2 (#3406) - Enterprise WPA fixed for ESP32-S2 (#3406)
- COEX on ESP32 is now working (#3403) - COEX on ESP32 is now working (#3403)

View File

@ -15,35 +15,40 @@ bench = false
test = false test = false
[dependencies] [dependencies]
esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal", default-features = false }
critical-section = "1.2.0"
cfg-if = "1.0.0"
portable-atomic = { version = "1.11.0", default-features = false }
enumset = { version = "1.1.5", default-features = false, optional = true }
# ⚠️ Unstable dependencies
embedded-io = { version = "0.6.1", default-features = false }
embedded-io-async = { version = "0.6.1" }
rand_core = "0.9.3"
# Unstable dependencies that are not (strictly) part of the public API
allocator-api2 = { version = "0.2.0", default-features = false, features = ["alloc"] } allocator-api2 = { version = "0.2.0", default-features = false, features = ["alloc"] }
defmt = { version = "1.0.1", optional = true }
log = { version = "0.4.27", optional = true }
document-features = "0.2.11" document-features = "0.2.11"
esp-alloc = { version = "0.7.0", path = "../esp-alloc", optional = true } esp-alloc = { version = "0.7.0", path = "../esp-alloc", optional = true }
esp-hal = { version = "1.0.0-beta.0", path = "../esp-hal", default-features = false } esp-config = { version = "0.3.0", path = "../esp-config" }
esp-wifi-sys = "0.7.1"
num-derive = { version = "0.4.2" }
num-traits = { version = "0.2.19", default-features = false }
portable_atomic_enum = { version = "0.3.1", features = ["portable-atomic"] }
xtensa-lx-rt = { version = "0.18.0", path = "../xtensa-lx-rt", optional = true }
# Optional dependencies enabling ecosystem features
serde = { version = "1.0.218", default-features = false, features = ["derive"], optional = true }
smoltcp = { version = "0.12.0", default-features = false, features = [ smoltcp = { version = "0.12.0", default-features = false, features = [
"medium-ethernet", "medium-ethernet",
"socket-raw", "socket-raw",
], optional = true } ], optional = true }
critical-section = "1.2.0"
enumset = { version = "1.1.5", default-features = false, optional = true }
embedded-io = { version = "0.6.1", default-features = false }
embedded-io-async = { version = "0.6.1" }
num-derive = { version = "0.4.2" }
num-traits = { version = "0.2.19", default-features = false }
esp-wifi-sys = "0.7.1"
embassy-sync = { version = "0.6.2", optional = true }
embassy-net-driver = { version = "0.2.0", optional = true } embassy-net-driver = { version = "0.2.0", optional = true }
cfg-if = "1.0.0"
portable-atomic = { version = "1.11.0", default-features = false }
portable_atomic_enum = { version = "0.3.1", features = ["portable-atomic"] }
rand_core = "0.9.3"
bt-hci = { version = "0.3.0", optional = true } bt-hci = { version = "0.3.0", optional = true }
esp-config = { version = "0.3.0", path = "../esp-config" }
xtensa-lx-rt = { version = "0.18.0", path = "../xtensa-lx-rt", optional = true } # Logging interfaces, they are mutually exclusive so they need to be behind separate features.
serde = { version = "1.0.218", default-features = false, features = ["derive"], optional = true } defmt = { version = "1.0.1", optional = true }
log-04 = { package = "log", version = "0.4.27", optional = true }
[build-dependencies] [build-dependencies]
esp-build = { version = "0.2.0", path = "../esp-build" } esp-build = { version = "0.2.0", path = "../esp-build" }
@ -53,14 +58,6 @@ esp-metadata = { version = "0.6.0", path = "../esp-metadata" }
[features] [features]
default = ["builtin-scheduler", "esp-alloc"] default = ["builtin-scheduler", "esp-alloc"]
## Use `esp-alloc` for dynamic allocations.
##
## If you opt-out you need to provide implementations for the following functions:
## - `pub extern "C" fn esp_wifi_free_internal_heap() -> usize`
## - `pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8`
## - `pub extern "C" fn esp_wifi_deallocate_internal_ram(ptr: *mut u8)`
esp-alloc = ["dep:esp-alloc"]
# Chip Support Feature Flags # Chip Support Feature Flags
# Target the ESP32-C2. # Target the ESP32-C2.
esp32c2 = [ esp32c2 = [
@ -101,20 +98,24 @@ esp32s3 = [
"xtensa-lx-rt/float-save-restore", "xtensa-lx-rt/float-save-restore",
] ]
## Enable WiFi-BLE coexistence support ## Use `esp-alloc` for dynamic allocations.
coex = [] ##
## If you opt-out you need to provide implementations for the following functions:
## - `pub extern "C" fn esp_wifi_free_internal_heap() -> usize`
## - `pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8`
## - `pub extern "C" fn esp_wifi_deallocate_internal_ram(ptr: *mut u8)`
esp-alloc = ["dep:esp-alloc"]
## Logs the WiFi logs from the driver at log level info (needs a nightly-compiler) ## Logs the WiFi logs from the driver at log level info (needs a nightly-compiler)
sys-logs = ["esp-wifi-sys/sys-logs"] sys-logs = ["esp-wifi-sys/sys-logs"]
## Enable support for `defmt` ## Use builtin scheduler
defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt", "bt-hci?/defmt", "esp-wifi-sys/defmt"] builtin-scheduler = []
## Enable support for the `log` crate #! ### Wireless Feature Flags
log = ["dep:log", "esp-hal/log", "esp-wifi-sys/log"]
## Enable WiFi support ## Enable WiFi support
wifi = ["dep:enumset", "dep:embassy-net-driver", "dep:embassy-sync"] wifi = ["dep:enumset", "dep:embassy-net-driver"]
## Enable esp-now support ## Enable esp-now support
esp-now = ["wifi"] esp-now = ["wifi"]
@ -123,20 +124,29 @@ esp-now = ["wifi"]
sniffer = ["wifi"] sniffer = ["wifi"]
## Enable BLE support ## Enable BLE support
ble = ["esp-hal/bluetooth", "dep:bt-hci", "dep:embassy-sync"] ble = ["esp-hal/__bluetooth", "dep:bt-hci"]
## Enable WiFi-BLE coexistence support
coex = []
## Enable WiFi channel state information. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv4N18wifi_init_config_t10csi_enableE)", ## Enable WiFi channel state information. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv4N18wifi_init_config_t10csi_enableE)",
csi = [] csi = []
#! ### Ecosystem Feature Flags
## Provide implementations of smoltcp traits ## Provide implementations of smoltcp traits
smoltcp = ["dep:smoltcp"] smoltcp = ["dep:smoltcp"]
## Use builtin scheduler ## Implement serde Serialize / Deserialize
builtin-scheduler = []
# Implement serde Serialize / Deserialize
serde = ["dep:serde", "enumset?/serde"] serde = ["dep:serde", "enumset?/serde"]
#! ### Logging Feature Flags
## Enable logging output using version 0.4 of the `log` crate.
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.
defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt", "bt-hci?/defmt", "esp-wifi-sys/defmt"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = [ features = [
"esp32c3", "esp32c3",

View File

@ -299,19 +299,6 @@ fn main() -> Result<(), Box<dyn Error>> {
Ok(()) Ok(())
} }
#[cfg(not(any(
feature = "esp32",
feature = "esp32c2",
feature = "esp32c3",
feature = "esp32c6",
feature = "esp32h2",
feature = "esp32s2",
feature = "esp32s3",
)))]
fn main() {
panic!("Select a chip via it's cargo feature");
}
fn print_warning(message: impl core::fmt::Display) { fn print_warning(message: impl core::fmt::Display) {
println!("cargo:warning={message}"); println!("cargo:warning={message}");
} }

View File

@ -5,10 +5,13 @@
macro_rules! assert { macro_rules! assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert!($($x)*);
::defmt::assert!($($x)*); } else {
::core::assert!($($x)*);
}
}
} }
}; };
} }
@ -17,10 +20,13 @@ macro_rules! assert {
macro_rules! assert_eq { macro_rules! assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_eq!($($x)*);
::defmt::assert_eq!($($x)*); } else {
::core::assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -29,10 +35,13 @@ macro_rules! assert_eq {
macro_rules! assert_ne { macro_rules! assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::assert_ne!($($x)*);
::defmt::assert_ne!($($x)*); } else {
::core::assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -41,10 +50,13 @@ macro_rules! assert_ne {
macro_rules! debug_assert { macro_rules! debug_assert {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert!($($x)*);
::defmt::debug_assert!($($x)*); } else {
::core::debug_assert!($($x)*);
}
}
} }
}; };
} }
@ -53,10 +65,13 @@ macro_rules! debug_assert {
macro_rules! debug_assert_eq { macro_rules! debug_assert_eq {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_eq!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_eq!($($x)*);
::defmt::debug_assert_eq!($($x)*); } else {
::core::debug_assert_eq!($($x)*);
}
}
} }
}; };
} }
@ -65,10 +80,13 @@ macro_rules! debug_assert_eq {
macro_rules! debug_assert_ne { macro_rules! debug_assert_ne {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::debug_assert_ne!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug_assert_ne!($($x)*);
::defmt::debug_assert_ne!($($x)*); } else {
::core::debug_assert_ne!($($x)*);
}
}
} }
}; };
} }
@ -77,10 +95,13 @@ macro_rules! debug_assert_ne {
macro_rules! todo { macro_rules! todo {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::todo!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::todo!($($x)*);
::defmt::todo!($($x)*); } else {
::core::todo!($($x)*);
}
}
} }
}; };
} }
@ -89,10 +110,13 @@ macro_rules! todo {
macro_rules! unreachable { macro_rules! unreachable {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::unreachable!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::unreachable!($($x)*);
::defmt::unreachable!($($x)*); } else {
::core::unreachable!($($x)*);
}
}
} }
}; };
} }
@ -101,10 +125,13 @@ macro_rules! unreachable {
macro_rules! panic { macro_rules! panic {
($($x:tt)*) => { ($($x:tt)*) => {
{ {
#[cfg(not(feature = "defmt"))] cfg_if::cfg_if! {
::core::panic!($($x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::panic!($($x)*);
::defmt::panic!($($x)*); } else {
::core::panic!($($x)*);
}
}
} }
}; };
} }
@ -113,12 +140,15 @@ macro_rules! panic {
macro_rules! trace { macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::trace!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::trace!($s $(, $x)*);
::defmt::trace!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::trace!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -127,12 +157,15 @@ macro_rules! trace {
macro_rules! debug { macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::debug!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::debug!($s $(, $x)*);
::defmt::debug!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::debug!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -141,12 +174,15 @@ macro_rules! debug {
macro_rules! info { macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::info!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::info!($s $(, $x)*);
::defmt::info!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::info!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -155,12 +191,15 @@ macro_rules! info {
macro_rules! warn { macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::warn!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::warn!($s $(, $x)*);
::defmt::warn!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::warn!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }
@ -169,12 +208,15 @@ macro_rules! warn {
macro_rules! error { macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => { ($s:literal $(, $x:expr)* $(,)?) => {
{ {
#[cfg(feature = "log")] cfg_if::cfg_if! {
::log::error!($s $(, $x)*); if #[cfg(feature = "defmt")] {
#[cfg(feature = "defmt")] ::defmt::error!($s $(, $x)*);
::defmt::error!($s $(, $x)*); } else if #[cfg(feature = "log-04")] {
#[cfg(not(any(feature = "log", feature="defmt")))] ::log_04::error!($s $(, $x)*);
let _ = ($( & $x ),*); } else {
let _ = ($( & $x ),*);
}
}
} }
}; };
} }

View File

@ -14,9 +14,9 @@ critical-section = "1.1.3"
embassy-executor = { version = "0.7.0", features = ["task-arena-size-20480"] } embassy-executor = { version = "0.7.0", features = ["task-arena-size-20480"] }
embassy-futures = "0.1.1" embassy-futures = "0.1.1"
embassy-net = { version = "0.6.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net = { version = "0.6.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] }
embassy-sync = "0.6.0" embassy-sync = "0.6.2"
embassy-time = "0.4.0" embassy-time = "0.4.0"
embassy-usb = { version = "0.2.0", default-features = false } embassy-usb = { version = "0.4.0", default-features = false }
embedded-hal-async = "1.0.0" embedded-hal-async = "1.0.0"
embedded-io = { version = "0.6.1", default-features = false } embedded-io = { version = "0.6.1", default-features = false }
embedded-io-async = "0.6.1" embedded-io-async = "0.6.1"
@ -24,17 +24,17 @@ embedded-storage = "0.3.1"
esp-alloc = { path = "../esp-alloc" } esp-alloc = { path = "../esp-alloc" }
esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] } esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] }
esp-bootloader-esp-idf = { path = "../esp-bootloader-esp-idf" } esp-bootloader-esp-idf = { path = "../esp-bootloader-esp-idf" }
esp-hal = { path = "../esp-hal", features = ["log"] } esp-hal = { path = "../esp-hal", features = ["log-04"] }
esp-hal-embassy = { path = "../esp-hal-embassy", optional = true } esp-hal-embassy = { path = "../esp-hal-embassy", optional = true }
esp-ieee802154 = { path = "../esp-ieee802154", optional = true } esp-ieee802154 = { path = "../esp-ieee802154", optional = true }
esp-println = { path = "../esp-println", features = ["log"] } esp-println = { path = "../esp-println", features = ["log-04"] }
esp-storage = { path = "../esp-storage", optional = true } esp-storage = { path = "../esp-storage", optional = true }
esp-wifi = { path = "../esp-wifi", features = ["log"], optional = true } esp-wifi = { path = "../esp-wifi", features = ["log-04"], optional = true }
heapless = "0.8.0" heapless = "0.8.0"
hmac = { version = "0.12.1", default-features = false } hmac = { version = "0.12.1", default-features = false }
ieee80211 = { version = "0.4.0", default-features = false } ieee80211 = { version = "0.4.0", default-features = false }
ieee802154 = "0.6.1" ieee802154 = "0.6.1"
log = "0.4.22" log = "0.4.27"
nb = "1.1.0" nb = "1.1.0"
sha2 = { version = "0.10.8", default-features = false } sha2 = { version = "0.10.8", default-features = false }
smoltcp = { version = "0.12.0", default-features = false, features = [ "medium-ethernet", "socket-raw"] } smoltcp = { version = "0.12.0", default-features = false, features = [ "medium-ethernet", "socket-raw"] }

View File

@ -2,7 +2,7 @@
//! //!
//! If your module is octal PSRAM then you need to set `ESP_HAL_CONFIG_PSRAM_MODE` to `octal`. //! If your module is octal PSRAM then you need to set `ESP_HAL_CONFIG_PSRAM_MODE` to `octal`.
//% FEATURES: esp-hal/log esp-hal/psram aligned esp-hal/unstable //% FEATURES: esp-hal/psram aligned esp-hal/unstable
//% CHIPS: esp32s3 //% CHIPS: esp32s3
#![no_std] #![no_std]

View File

@ -1,6 +1,6 @@
//! Uses DMA to copy memory to memory. //! Uses DMA to copy memory to memory.
//% FEATURES: esp-hal/log esp-hal/unstable //% FEATURES: esp-hal/unstable
//% CHIPS: esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2 //% CHIPS: esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
#![no_std] #![no_std]

View File

@ -15,7 +15,7 @@
// The interrupt-executor is created in `main` and is used to spawn `high_prio`. // The interrupt-executor is created in `main` and is used to spawn `high_prio`.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embassy esp-hal-embassy/log esp-hal/unstable //% FEATURES: embassy esp-hal-embassy/log-04 esp-hal/unstable
#![no_std] #![no_std]
#![no_main] #![no_main]

View File

@ -15,7 +15,7 @@
//! //!
//! If your module is octal PSRAM then you need to set `ESP_HAL_CONFIG_PSRAM_MODE` to `octal`. //! If your module is octal PSRAM then you need to set `ESP_HAL_CONFIG_PSRAM_MODE` to `octal`.
//% FEATURES: esp-hal/log esp-hal/psram esp-hal/unstable //% FEATURES: esp-hal/psram esp-hal/unstable
//% CHIPS: esp32s3 //% CHIPS: esp32s3
#![no_std] #![no_std]

View File

@ -4,7 +4,7 @@
//! Set SSID and PASSWORD env variable before running this example. //! Set SSID and PASSWORD env variable before running this example.
//! //!
//% FEATURES: esp-wifi esp-wifi/wifi esp-wifi/smoltcp esp-wifi/log esp-wifi/csi esp-hal/unstable //% FEATURES: esp-wifi esp-wifi/wifi esp-wifi/smoltcp esp-wifi/log-04 esp-wifi/csi esp-hal/unstable
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 //% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
#![no_std] #![no_std]

View File

@ -238,7 +238,7 @@ embedded-hal-async = "1.0.0"
embedded-hal-nb = "1.0.0" embedded-hal-nb = "1.0.0"
esp-alloc = { path = "../esp-alloc", optional = true } esp-alloc = { path = "../esp-alloc", optional = true }
esp-backtrace = { path = "../esp-backtrace", default-features = false, features = ["exception-handler", "defmt", "semihosting"] } esp-backtrace = { path = "../esp-backtrace", default-features = false, features = ["exception-handler", "defmt", "semihosting"] }
esp-hal = { path = "../esp-hal", features = ["digest"], optional = true } esp-hal = { path = "../esp-hal", optional = true }
esp-hal-embassy = { path = "../esp-hal-embassy", optional = true } esp-hal-embassy = { path = "../esp-hal-embassy", optional = true }
esp-storage = { path = "../esp-storage", optional = true } esp-storage = { path = "../esp-storage", optional = true }
esp-wifi = { path = "../esp-wifi", optional = true } esp-wifi = { path = "../esp-wifi", optional = true }

View File

@ -15,9 +15,9 @@ embedded-graphics = "0.8.1"
embedded-hal-async = "1.0.0" embedded-hal-async = "1.0.0"
esp-alloc = { path = "../esp-alloc" } esp-alloc = { path = "../esp-alloc" }
esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] } esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] }
esp-hal = { path = "../esp-hal", features = ["unstable", "log"] } esp-hal = { path = "../esp-hal", features = ["unstable", "log-04"] }
esp-hal-embassy = { path = "../esp-hal-embassy" } esp-hal-embassy = { path = "../esp-hal-embassy" }
esp-println = { path = "../esp-println", features = ["log"] } esp-println = { path = "../esp-println", features = ["log-04"] }
lis3dh-async = "0.9.3" lis3dh-async = "0.9.3"
ssd1306 = "0.10.0" ssd1306 = "0.10.0"

View File

@ -6,7 +6,7 @@
//! the device comes with octal-SPIRAM //! the device comes with octal-SPIRAM
//% CHIPS: esp32 esp32s2 esp32s3 //% CHIPS: esp32 esp32s2 esp32s3
//% FEATURES: esp-hal/psram esp-alloc/internal-heap-stats esp-hal/log //% FEATURES: esp-hal/psram esp-alloc/internal-heap-stats
#![no_std] #![no_std]
#![no_main] #![no_main]

View File

@ -112,10 +112,10 @@ impl Package {
features.push("psram".to_owned()) features.push("psram".to_owned())
} }
if config.contains("usb0") { if config.contains("usb0") {
features.push("usb-otg".to_owned()); features.push("__usb_otg".to_owned());
} }
if config.contains("bt") { if config.contains("bt") {
features.push("bluetooth".to_owned()); features.push("__bluetooth".to_owned());
} }
} }
Package::EspWifi => { Package::EspWifi => {
@ -157,9 +157,7 @@ impl Package {
features.push("auto".to_owned()); features.push("auto".to_owned());
features.push("defmt-espflash".to_owned()); features.push("defmt-espflash".to_owned());
} }
Package::EspStorage => { Package::EspStorage => {}
features.push("low-level".to_owned());
}
Package::EspBootloaderEspIdf => { Package::EspBootloaderEspIdf => {
features.push("defmt".to_owned()); features.push("defmt".to_owned());
features.push("validation".to_owned()); features.push("validation".to_owned());