From f7f790ae47a0854423ae748f3dd44cf95efe17e8 Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Mon, 27 May 2024 08:34:39 +0200 Subject: [PATCH 1/2] Remove everything but esp-wifi-sys/xtask --- CHANGELOG.md | 71 - Cargo.toml | 62 +- README.md | 4 +- esp-wifi/.cargo/config.toml | 62 - esp-wifi/Cargo.toml | 150 - esp-wifi/README.md | 146 - .../automated-tests/esp_now_broadcaster.rs | 57 - esp-wifi/automated-tests/open_access_point.rs | 119 - esp-wifi/automated-tests/test_ble.rs | 109 - esp-wifi/automated-tests/test_connect.rs | 191 - esp-wifi/automated-tests/test_esp_now.rs | 69 - esp-wifi/build.rs | 172 - esp-wifi/docs/examples.md | 145 - esp-wifi/docs/tuning.md | 57 - esp-wifi/examples/access_point.rs | 162 - esp-wifi/examples/access_point_with_sta.rs | 225 -- esp-wifi/examples/bench.rs | 245 -- esp-wifi/examples/ble.rs | 163 - esp-wifi/examples/coex.rs | 172 - esp-wifi/examples/dhcp.rs | 150 - esp-wifi/examples/embassy_access_point.rs | 189 - .../examples/embassy_access_point_with_sta.rs | 302 -- esp-wifi/examples/embassy_bench.rs | 297 -- esp-wifi/examples/embassy_ble.rs | 168 - esp-wifi/examples/embassy_dhcp.rs | 171 - esp-wifi/examples/embassy_esp_now.rs | 81 - esp-wifi/examples/embassy_esp_now_duplex.rs | 113 - esp-wifi/examples/esp_now.rs | 78 - esp-wifi/examples/static_ip.rs | 198 -- esp-wifi/src/ble/btdm.rs | 614 ---- esp-wifi/src/ble/controller/mod.rs | 177 - esp-wifi/src/ble/mod.rs | 101 - esp-wifi/src/ble/npl.rs | 1416 -------- esp-wifi/src/ble/os_adapter_esp32.rs | 625 ---- esp-wifi/src/ble/os_adapter_esp32c2.rs | 123 - esp-wifi/src/ble/os_adapter_esp32c3.rs | 318 -- esp-wifi/src/ble/os_adapter_esp32c6.rs | 129 - esp-wifi/src/ble/os_adapter_esp32h2.rs | 129 - esp-wifi/src/ble/os_adapter_esp32s3.rs | 313 -- .../common_adapter/common_adapter_esp32.rs | 235 -- .../common_adapter/common_adapter_esp32c2.rs | 144 - .../common_adapter/common_adapter_esp32c3.rs | 172 - .../common_adapter/common_adapter_esp32c6.rs | 136 - .../common_adapter/common_adapter_esp32h2.rs | 139 - .../common_adapter/common_adapter_esp32s2.rs | 228 -- .../common_adapter/common_adapter_esp32s3.rs | 194 -- esp-wifi/src/common_adapter/mod.rs | 390 --- .../src/common_adapter/phy_init_data_esp32.rs | 146 - .../common_adapter/phy_init_data_esp32c2.rs | 146 - .../common_adapter/phy_init_data_esp32c3.rs | 146 - .../common_adapter/phy_init_data_esp32c6.rs | 146 - .../common_adapter/phy_init_data_esp32h2.rs | 146 - .../common_adapter/phy_init_data_esp32s2.rs | 146 - .../common_adapter/phy_init_data_esp32s3.rs | 146 - esp-wifi/src/compat/common.rs | 343 -- esp-wifi/src/compat/malloc.rs | 58 - esp-wifi/src/compat/mod.rs | 9 - esp-wifi/src/compat/syslog.rs | 194 -- esp-wifi/src/compat/task_runner.rs | 52 - esp-wifi/src/compat/timer_compat.rs | 170 - esp-wifi/src/esp_now/mod.rs | 928 ----- esp-wifi/src/fmt.rs | 225 -- esp-wifi/src/lib.rs | 352 -- esp-wifi/src/memory_fence.rs | 11 - esp-wifi/src/preempt/mod.rs | 48 - esp-wifi/src/preempt/preempt_riscv.rs | 167 - esp-wifi/src/preempt/preempt_xtensa.rs | 125 - esp-wifi/src/tasks.rs | 49 - esp-wifi/src/timer/mod.rs | 51 - esp-wifi/src/timer/riscv.rs | 112 - esp-wifi/src/timer/timer_esp32.rs | 94 - esp-wifi/src/timer/timer_esp32c2.rs | 99 - esp-wifi/src/timer/timer_esp32c3.rs | 110 - esp-wifi/src/timer/timer_esp32c6.rs | 112 - esp-wifi/src/timer/timer_esp32h2.rs | 63 - esp-wifi/src/timer/timer_esp32s2.rs | 39 - esp-wifi/src/timer/timer_esp32s3.rs | 75 - esp-wifi/src/timer/xtensa.rs | 129 - esp-wifi/src/wifi/mod.rs | 3086 ----------------- esp-wifi/src/wifi/os_adapter.rs | 2005 ----------- esp-wifi/src/wifi/os_adapter_esp32.rs | 106 - esp-wifi/src/wifi/os_adapter_esp32c2.rs | 114 - esp-wifi/src/wifi/os_adapter_esp32c3.rs | 115 - esp-wifi/src/wifi/os_adapter_esp32c6.rs | 143 - esp-wifi/src/wifi/os_adapter_esp32h2.rs | 132 - esp-wifi/src/wifi/os_adapter_esp32s2.rs | 92 - esp-wifi/src/wifi/os_adapter_esp32s3.rs | 83 - esp-wifi/src/wifi/state.rs | 84 - esp-wifi/src/wifi/utils.rs | 97 - esp-wifi/src/wifi_interface.rs | 951 ----- examples-util/util.rs | 26 - extras/bench-server/.gitignore | 1 - extras/bench-server/Cargo.toml | 8 - extras/bench-server/src/main.rs | 87 - extras/esp-wifishark/.gitignore | 1 - extras/esp-wifishark/Cargo.toml | 11 - extras/esp-wifishark/README.md | 13 - extras/esp-wifishark/src/main.rs | 175 - run_tests.bat | 92 - smoketest.bat | 177 - 100 files changed, 3 insertions(+), 21944 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 esp-wifi/.cargo/config.toml delete mode 100644 esp-wifi/Cargo.toml delete mode 100644 esp-wifi/README.md delete mode 100644 esp-wifi/automated-tests/esp_now_broadcaster.rs delete mode 100644 esp-wifi/automated-tests/open_access_point.rs delete mode 100644 esp-wifi/automated-tests/test_ble.rs delete mode 100644 esp-wifi/automated-tests/test_connect.rs delete mode 100644 esp-wifi/automated-tests/test_esp_now.rs delete mode 100644 esp-wifi/build.rs delete mode 100644 esp-wifi/docs/examples.md delete mode 100644 esp-wifi/docs/tuning.md delete mode 100644 esp-wifi/examples/access_point.rs delete mode 100644 esp-wifi/examples/access_point_with_sta.rs delete mode 100644 esp-wifi/examples/bench.rs delete mode 100644 esp-wifi/examples/ble.rs delete mode 100644 esp-wifi/examples/coex.rs delete mode 100644 esp-wifi/examples/dhcp.rs delete mode 100644 esp-wifi/examples/embassy_access_point.rs delete mode 100644 esp-wifi/examples/embassy_access_point_with_sta.rs delete mode 100644 esp-wifi/examples/embassy_bench.rs delete mode 100644 esp-wifi/examples/embassy_ble.rs delete mode 100644 esp-wifi/examples/embassy_dhcp.rs delete mode 100644 esp-wifi/examples/embassy_esp_now.rs delete mode 100644 esp-wifi/examples/embassy_esp_now_duplex.rs delete mode 100644 esp-wifi/examples/esp_now.rs delete mode 100644 esp-wifi/examples/static_ip.rs delete mode 100644 esp-wifi/src/ble/btdm.rs delete mode 100644 esp-wifi/src/ble/controller/mod.rs delete mode 100644 esp-wifi/src/ble/mod.rs delete mode 100644 esp-wifi/src/ble/npl.rs delete mode 100644 esp-wifi/src/ble/os_adapter_esp32.rs delete mode 100644 esp-wifi/src/ble/os_adapter_esp32c2.rs delete mode 100644 esp-wifi/src/ble/os_adapter_esp32c3.rs delete mode 100644 esp-wifi/src/ble/os_adapter_esp32c6.rs delete mode 100644 esp-wifi/src/ble/os_adapter_esp32h2.rs delete mode 100644 esp-wifi/src/ble/os_adapter_esp32s3.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32c2.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32c3.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32c6.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32h2.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32s2.rs delete mode 100644 esp-wifi/src/common_adapter/common_adapter_esp32s3.rs delete mode 100644 esp-wifi/src/common_adapter/mod.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32c2.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32c3.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32c6.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32s2.rs delete mode 100644 esp-wifi/src/common_adapter/phy_init_data_esp32s3.rs delete mode 100644 esp-wifi/src/compat/common.rs delete mode 100644 esp-wifi/src/compat/malloc.rs delete mode 100644 esp-wifi/src/compat/mod.rs delete mode 100644 esp-wifi/src/compat/syslog.rs delete mode 100644 esp-wifi/src/compat/task_runner.rs delete mode 100644 esp-wifi/src/compat/timer_compat.rs delete mode 100644 esp-wifi/src/esp_now/mod.rs delete mode 100644 esp-wifi/src/fmt.rs delete mode 100644 esp-wifi/src/lib.rs delete mode 100644 esp-wifi/src/memory_fence.rs delete mode 100644 esp-wifi/src/preempt/mod.rs delete mode 100644 esp-wifi/src/preempt/preempt_riscv.rs delete mode 100644 esp-wifi/src/preempt/preempt_xtensa.rs delete mode 100644 esp-wifi/src/tasks.rs delete mode 100644 esp-wifi/src/timer/mod.rs delete mode 100644 esp-wifi/src/timer/riscv.rs delete mode 100644 esp-wifi/src/timer/timer_esp32.rs delete mode 100644 esp-wifi/src/timer/timer_esp32c2.rs delete mode 100644 esp-wifi/src/timer/timer_esp32c3.rs delete mode 100644 esp-wifi/src/timer/timer_esp32c6.rs delete mode 100644 esp-wifi/src/timer/timer_esp32h2.rs delete mode 100644 esp-wifi/src/timer/timer_esp32s2.rs delete mode 100644 esp-wifi/src/timer/timer_esp32s3.rs delete mode 100644 esp-wifi/src/timer/xtensa.rs delete mode 100644 esp-wifi/src/wifi/mod.rs delete mode 100644 esp-wifi/src/wifi/os_adapter.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32c2.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32c3.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32c6.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32h2.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32s2.rs delete mode 100644 esp-wifi/src/wifi/os_adapter_esp32s3.rs delete mode 100644 esp-wifi/src/wifi/state.rs delete mode 100644 esp-wifi/src/wifi/utils.rs delete mode 100644 esp-wifi/src/wifi_interface.rs delete mode 100644 examples-util/util.rs delete mode 100644 extras/bench-server/.gitignore delete mode 100644 extras/bench-server/Cargo.toml delete mode 100644 extras/bench-server/src/main.rs delete mode 100644 extras/esp-wifishark/.gitignore delete mode 100644 extras/esp-wifishark/Cargo.toml delete mode 100644 extras/esp-wifishark/README.md delete mode 100644 extras/esp-wifishark/src/main.rs delete mode 100644 run_tests.bat delete mode 100644 smoketest.bat diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index e65a4ea1..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,71 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added - -### Fixed - -### Changed - -### Removed -- Removed embedded-hal v0.2 dependency - -## [0.5.1] - 2024-04-22 - -Patch release to fix docs.rs build - -## [0.5.0] - 2024-04-19 - -### Added - -### Fixed -- Fix compile error when using smoltcp `DNS_MAX_RESULT_COUNT` values other than 1 - -### Changed - -### Removed - -## [0.4.0] - 2024-03-12 - -### Added - -### Fixed - -### Changed -- Users don't need embedded-svc to control wifi anymore. The wifi trait is optionally implemented now. (#429) -- Better network performance by forced yielding of the task when buffers are full / empty. (#430) -- Depend on esp-hal 0.16.1, update other dependencies - -### Removed - -## [0.3.0] - 2024-01-29 - -### Added - -- Include coex in list of enabled features for docs.rs (#405) - -### Fixed - -- Small correction to coex warning message (#404) -- Use a random local port when initializing the wifi stack. (#414) - -### Changed - -- Update driver blobs (#410) -- Update dependencies to fit `embedded-hal` `1.0` - -### Removed - -## [0.2.0] - 2024-01-05 - -Initial release supporting WiFi on ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C2, ESP32-C6, supporting BLE on WiFi on ESP32, ESP32-S3, ESP32-C3, ESP32-C2, ESP32-C6, ESP32-H2 - -## [0.1.0] - 2023-11-27 - -Initial release supporting WiFi on ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C2, ESP32-C6, supporting BLE on WiFi on ESP32, ESP32-S3, ESP32-C3, ESP32-C2, ESP32-C6 diff --git a/Cargo.toml b/Cargo.toml index 1da2f8b2..6eba0912 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,67 +1,7 @@ [workspace] -members = ["esp-wifi", "esp-wifi-sys", "xtask"] -exclude = ["extras/bench-server", "extras/esp-wifishark"] +members = ["esp-wifi-sys", "xtask"] resolver = "2" [profile.release] opt-level = 3 debug = true - -[workspace.dependencies] -defmt = "0.3.6" -esp-hal = { version = "0.17.0", default-features = false } -smoltcp = { version = "0.11.0", default-features = false, features = [ - "medium-ethernet", - "socket-raw", -] } -critical-section = "1.1.1" -portable-atomic = { version = "1.5", default-features = false } -portable_atomic_enum = { version = "0.3.0", features = ["portable-atomic"] } -log = "0.4.20" -embedded-svc = { version = "0.27.0", default-features = false, features = [] } -no-std-net = "0.6.0" -enumset = { version = "1.1.3", default-features = false } -linked_list_allocator = { version = "0.10.5", default-features = false, features = [ - "const_mut_refs", -] } -embedded-io = { version = "0.6.1", default-features = false } -fugit = "0.3.7" -heapless = { version = "0.8", default-features = false, features = [ - "portable-atomic", -] } -num-derive = { version = "0.4" } -num-traits = { version = "0.2", default-features = false } -esp-wifi-sys = { version = "0.3.0", path = "../esp-wifi-sys" } -embassy-sync = { version = "0.5.0" } -embassy-futures = { version = "0.1.0" } -toml-cfg = "0.2.0" -libm = "0.2.7" -cfg-if = "1.0.0" -static_cell = { version = "2.0", features = ["nightly"] } - -embassy-net-driver = { version = "0.2" } -embassy-net = { version = "0.4.0", features = [ - "tcp", - "udp", - "dhcpv4", - "medium-ethernet", -] } -bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "9371d7d4d510ba5c936c1eef96674f8fd4f63e8a", features = [ - "macros", -] } -embassy-executor = { version = "0.5.0", package = "embassy-executor", features = [ - "task-arena-size-12288", - "integrated-timers", -] } -embassy-time = { version = "0.3.0" } -esp-println = { version = "0.9.0", default-features = false } -esp-backtrace = { version = "0.11.0" } -embedded-hal-async = { version = "1.0.0" } -embedded-io-async = { version = "0.6.0" } - -futures-util = { version = "0.3.28", default-features = false, features = [ - "portable-atomic", -] } # need this to activate portable-atomic on AtomicWaker even though we don't use it -atomic-waker = { version = "1.1.2", default-features = false, features = [ - "portable-atomic", -] } # need this to activate portable-atomic on AtomicWaker used by embedded-svc even though we don't use it diff --git a/README.md b/README.md index 4f696aec..278d7d04 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # esp-wifi -A WiFi, BLE and ESP-NOW driver for Espressif microcontrollers. +This repository hosts the wireless-driver's binaries. -See [esp-wifi's README.md](./esp-wifi/README.md) for more information. +If you are looking for `esp-wifi` see [esp-wifi in esp-hal](https://github.com/esp-rs/esp-hal/tree/main/esp-wifi) ## License diff --git a/esp-wifi/.cargo/config.toml b/esp-wifi/.cargo/config.toml deleted file mode 100644 index a52462b8..00000000 --- a/esp-wifi/.cargo/config.toml +++ /dev/null @@ -1,62 +0,0 @@ -# Alias' for quickly building for different chips or running examples -# By default we enable -# - `default` HAL features to set up basic chip specific settings -# - `embassy-time-timg0` as the examples assume we are using this time driver -# - `embassy-executor-thread` on Xtensa chips to take advantage of the Xtensa specific executor we have in esp-hal -[alias] -esp32 = "run --features esp32 --target xtensa-esp32-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -esp32s2 = "run --features esp32s2 --target xtensa-esp32s2-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -esp32s3 = "run --features esp32s3 --target xtensa-esp32s3-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -esp32c2 = "run --features esp32c2 --target riscv32imc-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -esp32c3 = "run --features esp32c3 --target riscv32imc-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -esp32c6 = "run --features esp32c6 --target riscv32imac-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -esp32h2 = "run --features esp32h2 --target riscv32imac-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread" - -besp32 = "build --features esp32 --target xtensa-esp32-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -besp32s2 = "build --features esp32s2 --target xtensa-esp32s2-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -besp32s3 = "build --features esp32s3 --target xtensa-esp32s3-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -besp32c2 = "build --features esp32c2 --target riscv32imc-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -besp32c3 = "build --features esp32c3 --target riscv32imc-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -besp32c6 = "build --features esp32c6 --target riscv32imac-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi-default" -besp32h2 = "build --features esp32h2 --target riscv32imac-unknown-none-elf --features esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread" - -[target.riscv32imc-unknown-none-elf] -runner = "espflash flash --monitor" -rustflags = [ - "-C", "link-arg=-Tlinkall.x", - "-C", "link-arg=-Trom_functions.x", - "-C", "force-frame-pointers", -] - -[target.riscv32imac-unknown-none-elf] -runner = "espflash flash --monitor" -rustflags = [ - "-C", "link-arg=-Tlinkall.x", - "-C", "link-arg=-Trom_functions.x", - "-C", "force-frame-pointers", -] - -[target.xtensa-esp32-none-elf] -runner = "espflash flash --monitor" -rustflags = [ - "-C", "link-arg=-Tlinkall.x", - "-C", "link-arg=-Trom_functions.x", -] - -[target.xtensa-esp32s3-none-elf] -runner = "espflash flash --monitor" -rustflags = [ - "-C", "link-arg=-Tlinkall.x", - "-C", "link-arg=-Trom_functions.x", -] - -[target.xtensa-esp32s2-none-elf] -runner = "espflash flash --monitor" -rustflags = [ - "-C", "link-arg=-Tlinkall.x", - "-C", "link-arg=-Trom_functions.x", - "-C", "force-frame-pointers", -] - -[unstable] -build-std = [ "core" ] \ No newline at end of file diff --git a/esp-wifi/Cargo.toml b/esp-wifi/Cargo.toml deleted file mode 100644 index f1c7211a..00000000 --- a/esp-wifi/Cargo.toml +++ /dev/null @@ -1,150 +0,0 @@ -[package] -name = "esp-wifi" -version = "0.5.1" -edition = "2021" -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-wifi" -license = "MIT OR Apache-2.0" - -keywords = [ - "wifi", - "bluetooth", - "esp", - "no-std", -] -categories = [ - "embedded", - "hardware-support", - "no-std", -] - -[dependencies] -defmt = { workspace = true, optional = true } -esp-hal = { workspace = true } -smoltcp = { workspace = true, optional = true } -critical-section.workspace = true -log = { workspace = true, optional = true } -embedded-svc = { workspace = true, optional = true } -enumset = { workspace = true, optional = true } -linked_list_allocator = { workspace = true } -embedded-io.workspace = true -embedded-io-async = { workspace = true, optional = true } -fugit.workspace = true -heapless = { workspace = true, default-features = false } -num-derive = { workspace = true } -num-traits = { workspace = true, default-features = false } -no-std-net = { workspace = true, optional = true } -esp-wifi-sys = { version = "0.3.0", path = "../esp-wifi-sys" } -embassy-sync = { workspace = true, optional = true } -embassy-futures = { workspace = true, optional = true } -embassy-net-driver = { workspace = true, optional = true } -toml-cfg.workspace = true -libm.workspace = true -cfg-if.workspace = true -portable-atomic.workspace = true -portable_atomic_enum.workspace = true - -futures-util.workspace = true -atomic-waker.workspace = true - -[build-dependencies] -toml-cfg.workspace = true - -[dev-dependencies] -esp-println = { workspace = true, features = ["log", "uart"] } -esp-backtrace = { workspace = true, features = [ - "panic-handler", - "exception-handler", - "println", -] } -embassy-executor.workspace = true -embassy-time.workspace = true -embassy-net.workspace = true -bleps = { workspace = true, features = ["async"] } -embedded-hal-async.workspace = true -log.workspace = true -static_cell.workspace = true - -[features] -default = [ "log" ] - -# chip features -esp32c2 = [ "esp-hal/esp32c2", "esp-wifi-sys/esp32c2", "esp-println/esp32c2", "esp-backtrace/esp32c2" ] -esp32c3 = [ "esp-hal/esp32c3", "esp-wifi-sys/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3" ] -esp32c6 = [ "esp-hal/esp32c6", "esp-wifi-sys/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6" ] -esp32h2 = [ "esp-hal/esp32h2", "esp-wifi-sys/esp32h2", "esp-println/esp32h2", "esp-backtrace/esp32h2" ] -esp32 = [ "esp-hal/esp32", "esp-wifi-sys/esp32", "esp-println/esp32", "esp-backtrace/esp32" ] -esp32s2 = [ "esp-hal/esp32s2", "esp-wifi-sys/esp32s2", "esp-println/esp32s2", "esp-backtrace/esp32s2" ] -esp32s3 = [ "esp-hal/esp32s3", "esp-wifi-sys/esp32s3", "esp-println/esp32s3", "esp-backtrace/esp32s3" ] - -# async features -async = [ - "dep:embassy-sync", - "dep:embassy-futures", - "dep:embedded-io-async", - "esp-hal/embassy", - "esp-hal/async", -] - -embassy-net = ["dep:embassy-net-driver", "async"] - -# misc features -coex = [] -wifi-logs = [] -dump-packets = [] -smoltcp = [ "dep:smoltcp" ] -utils = [ "smoltcp" ] -enumset = [] -wifi = [ "dep:enumset", "dep:no-std-net" ] -embedded-svc = [ "dep:embedded-svc" ] -ble = [ "esp-hal/bluetooth" ] -phy-enable-usb = [] -ps-min-modem = [] -ps-max-modem = [] -esp-now = [ "wifi" ] -ipv6 = ["wifi", "utils", "smoltcp?/proto-ipv6"] -ipv4 = ["wifi", "utils", "smoltcp?/proto-ipv4"] -tcp = ["ipv4", "smoltcp?/socket-tcp"] -udp = ["ipv4", "smoltcp?/socket-udp"] -icmp = ["ipv4", "smoltcp?/socket-icmp"] -igmp = ["ipv4", "smoltcp?/proto-igmp"] -dns = ["udp", "smoltcp?/proto-dns", "smoltcp?/socket-dns"] -dhcpv4 = ["wifi", "utils", "smoltcp?/proto-dhcpv4", "smoltcp?/socket-dhcpv4"] -wifi-default = ["ipv4", "tcp", "udp", "icmp", "igmp", "dns", "dhcpv4"] -defmt = [ - "dep:defmt", - "smoltcp?/defmt", - "esp-hal/defmt", -] -log = [ - "dep:log", - "esp-hal/log", -] - -[package.metadata.docs.rs] -features = ["esp32c3", "wifi", "ble", "coex", "async", "embassy-net", "esp-hal/embassy-time-timg0", "esp-hal/default"] -default-target = "riscv32imc-unknown-none-elf" - -# These examples are used in test automation -[[example]] -name = "test_esp_now" -path = "automated-tests/test_esp_now.rs" - -[[example]] -name = "esp_now_broadcaster" -path = "automated-tests/esp_now_broadcaster.rs" - -[[example]] -name = "open_access_point" -path = "automated-tests/open_access_point.rs" - -[[example]] -name = "test_connect" -path = "automated-tests/test_connect.rs" - -[[example]] -name = "test_ble" -path = "automated-tests/test_ble.rs" diff --git a/esp-wifi/README.md b/esp-wifi/README.md deleted file mode 100644 index d5d58f15..00000000 --- a/esp-wifi/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# esp-wifi - -A WiFi, BLE and ESP-NOW driver for Espressif microcontrollers. - -## Current support - -If a cell contains an em dash (—) this means that the particular feature is not present for a chip. A check mark (✓) means that some driver implementation exists. A Tilde (˜) means it is implemented but buggy. An empty cell means that the feature is present in the chip but not implemented yet. - -| | [Wifi](https://github.com/esp-rs/esp-wifi/issues/94) | [BLE](https://github.com/esp-rs/esp-wifi/issues/93) | [Coex](https://github.com/esp-rs/esp-wifi/issues/92) | ESP-NOW | -| :------: | :--------------------------------------------------: | :-------------------------------------------------: | :--------------------------------------------------: | :-----: | -| ESP32 | ✓ | ✓ | ✓ | ✓ | -| ESP32-C2 | ✓ | ✓ | ✓ | ✓ | -| ESP32-C3 | ✓ | ✓ | ✓ | ✓ | -| ESP32-C6 | ✓ | ✓ | ✓ | ✓ | -| ESP32-H2 | — | ✓ | — | — | -| 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] 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. - -## Features - -| Feature | Meaning | -| -------------- | ---------------------------------------------------------------------------------------------------- | -| wifi-logs | logs the WiFi logs from the driver at log level `info` | -| wifi-default | A convenience feature to enable some reasonable defaults for wifi use. | -| dump-packets | dumps packet info at log level `info` | -| smoltcp | Provide implementations of `smoltcp` traits | -| utils | Provide utilities for smoltcp initialization. Adds `smoltcp` dependency | -| ble | Enable BLE support | -| wifi | Enable WiFi support | -| esp-now | Enable [esp-now](https://www.espressif.com/en/solutions/low-power-solutions/esp-now) support | -| coex | Enable WiFi-BLE coexistence support | -| ipv4 | IPv4 support. Includes `utils` feature | -| ipv6 | IPv6 support. Includes `utils` feature | -| tcp | TCP socket support. Includes `ipv4` feature | -| udp | UDP socket support. Includes `ipv4` feature | -| igmp | IGMP (multicast) support. Includes `ipv4` feature | -| dns | DNS support. Includes `udp` feature | -| dhcpv4 | DHCPv4 support, both creating sockets and autoconfiguring network settings. Includes `utils` feature | -| phy-enable-usb | See [USB-SERIAL-JTAG](#usb-serial-jtag) above | -| ps-min-modem | Enable minimum modem sleep. Only affects STA mode | -| ps-max-modem | Enable maximum modem sleep. Only affects STA mode | -| log | Route log output to the `log` crate | -| defmt | Add `defmt::Format` implementation and output logs via `defmt` | -| embedded-svc | Implement the embedded-svc Wifi trait | - -Note that not all features are available on every MCU. For example, `ble` (and thus, `coex`) is not available on ESP32-S2. - -When using the `dump-packets` feature you can use the extcap in `extras/esp-wifishark` to analyze the frames in Wireshark. -For more information see [extras/esp-wifishark/README.md](../extras/esp-wifishark/README.md) - -## 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](https://github.com/esp-rs/esp-wifi/blob/main/esp-wifi/docs/tuning.md) for details - -## Examples - -See [Examples] for details. - -[Examples]: https://github.com/esp-rs/esp-wifi/blob/main/esp-wifi/docs/examples.md - -## Missing / To be done - -- Support for non-open SoftAP - -## Directory Structure - -- `src/timer/`: systimer code used for timing and task switching -- `src/preemt/`: a bare minimum RISCV and Xtensa round-robin task scheduler -- `src/compat/`: code needed to emulate enough of an (RT)OS to use the driver - - `common.rs`: basics like semaphores and recursive mutexes - - `timer_compat.rs`: code to emulate timer related functionality -- `examples/*.rs`: examples - -## Driver version - -This uses the WiFi drivers from https://github.com/esp-rs/esp-wireless-drivers-3rdparty - -v5.1.2-602-gdb1e54a0c5-dirty commit db1e54a0c537d8b2cc2bd109ee88b50e1ca0ea80 - -https://github.com/esp-rs/esp-wireless-drivers-3rdparty/ (commit ca2809144cf6d2f89d413f1d415f1c4454ee6249) - -## 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-wifi/automated-tests/esp_now_broadcaster.rs b/esp-wifi/automated-tests/esp_now_broadcaster.rs deleted file mode 100644 index f0a393e0..00000000 --- a/esp-wifi/automated-tests/esp_now_broadcaster.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![no_std] -#![no_main] - -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::esp_now::BROADCAST_ADDRESS; -use esp_wifi::{current_millis, initialize, EspWifiInitFor}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap(); - - println!("esp-now version {}", esp_now.get_version().unwrap()); - - let next_send_time = current_millis() + 1 * 1000; - loop { - if current_millis() >= next_send_time { - println!("Send"); - let status = esp_now - .send(&BROADCAST_ADDRESS, b"0123456789") - .unwrap() - .wait(); - println!("Send broadcast status: {:?}", status); - break; - } - } - - loop {} -} diff --git a/esp-wifi/automated-tests/open_access_point.rs b/esp-wifi/automated-tests/open_access_point.rs deleted file mode 100644 index 2502021e..00000000 --- a/esp-wifi/automated-tests/open_access_point.rs +++ /dev/null @@ -1,119 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::initialize; -use esp_wifi::wifi::utils::create_network_interface; -use esp_wifi::wifi::WifiApDevice; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -use smoltcp::iface::SocketStorage; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut socket_set_entries: [SocketStorage; 3] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiApDevice, &mut socket_set_entries).unwrap(); - let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::AccessPoint(AccessPointConfiguration { - ssid: "esp-wifi".try_into().unwrap(), - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("{:?}", controller.get_capabilities()); - - wifi_stack - .set_iface_configuration(&esp_wifi::wifi::ipv4::Configuration::Client( - esp_wifi::wifi::ipv4::ClientConfiguration::Fixed( - esp_wifi::wifi::ipv4::ClientSettings { - ip: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), - subnet: esp_wifi::wifi::ipv4::Subnet { - gateway: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), - mask: esp_wifi::wifi::ipv4::Mask(24), - }, - dns: None, - secondary_dns: None, - }, - ), - )) - .unwrap(); - - println!("Start busy loop on main. Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/"); - println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1"); - - let mut rx_buffer = [0u8; 1536]; - let mut tx_buffer = [0u8; 1536]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - socket.listen(8080).unwrap(); - - loop { - socket.work(); - - if !socket.is_open() { - socket.listen(8080).unwrap(); - } - - if socket.is_connected() { - println!("Connected"); - socket.write_all(b"DATA!").unwrap(); - socket.flush().unwrap(); - socket.close(); - println!("Done\n"); - println!(); - } - - let wait_end = current_millis() + 5 * 1000; - while current_millis() < wait_end { - socket.work(); - } - } -} - -fn parse_ip(ip: &str) -> [u8; 4] { - let mut result = [0u8; 4]; - for (idx, octet) in ip.split(".").into_iter().enumerate() { - result[idx] = u8::from_str_radix(octet, 10).unwrap(); - } - result -} diff --git a/esp-wifi/automated-tests/test_ble.rs b/esp-wifi/automated-tests/test_ble.rs deleted file mode 100644 index f2bf94e2..00000000 --- a/esp-wifi/automated-tests/test_ble.rs +++ /dev/null @@ -1,109 +0,0 @@ -#![no_std] -#![no_main] - -use core::cell::RefCell; - -use bleps::{ - ad_structure::{ - create_advertising_data, AdStructure, BR_EDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE, - }, - attribute_server::{AttributeServer, WorkResult}, - gatt, Ble, HciConnector, -}; -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::{ble::controller::BleConnector, initialize, EspWifiInitFor}; -use examples_util::hal; -use hal::{clock::ClockControl, peripherals::*, prelude::*, rng::Rng}; -#[path = "../../examples-util/util.rs"] -mod examples_util; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Ble, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let mut bluetooth = peripherals.BT; - - loop { - let connector = BleConnector::new(&init, &mut bluetooth); - let hci = HciConnector::new(connector, esp_wifi::current_millis); - let mut ble = Ble::new(&hci); - - println!("{:?}", ble.init()); - println!("{:?}", ble.cmd_set_le_advertising_parameters()); - println!( - "{:?}", - ble.cmd_set_le_advertising_data( - create_advertising_data(&[ - AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), - AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]), - AdStructure::CompleteLocalName("ESP-WIFI"), - ]) - .unwrap() - ) - ); - println!("{:?}", ble.cmd_set_le_advertise_enable(true)); - println!("started advertising"); - - println!("[HOST bletool write ESP-WIFI 937312E0-2354-11EB-9F10-FBC30A62CF38 937312E0-2354-11EB-9F10-FBC30A62CF38 Hello]"); - - let rcv_buffer = RefCell::new([0u8; 32]); - let mut rf = |_offset: usize, data: &mut [u8]| { - data[..20].copy_from_slice(&b"Hello Bare-Metal BLE"[..]); - 17 - }; - let mut wf = |offset: usize, data: &[u8]| { - println!("RECEIVED: {} {:?}", offset, data); - rcv_buffer.borrow_mut()[..data.len()].copy_from_slice(data); - }; - - gatt!([service { - uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", - characteristics: [characteristic { - uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", - read: rf, - write: wf, - },], - },]); - - let mut rng = bleps::no_rng::NoRng; - let mut srv = AttributeServer::new(&mut ble, &mut gatt_attributes, &mut rng); - - loop { - match srv.do_work_with_notification(None) { - Ok(res) => { - if let WorkResult::GotDisconnected = res { - break; - } - } - Err(err) => { - println!("{:?}", err); - } - } - - if &rcv_buffer.borrow()[..5] == b"Hello" { - println!("[PASSED]"); - loop {} - } - } - } -} diff --git a/esp-wifi/automated-tests/test_connect.rs b/esp-wifi/automated-tests/test_connect.rs deleted file mode 100644 index f795aa47..00000000 --- a/esp-wifi/automated-tests/test_connect.rs +++ /dev/null @@ -1,191 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointInfo, AuthMethod, ClientConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::initialize; -use esp_wifi::wifi::WifiStaDevice; -use esp_wifi::wifi::{utils::create_network_interface, WifiError}; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -use smoltcp::iface::SocketStorage; -use smoltcp::wire::{IpAddress, Ipv4Address}; - -const SSID: &str = "esp-wifi"; -const STATIC_IP: &str = "192.168.2.2"; -const GATEWAY_IP: &str = "192.168.2.1"; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - println!("Running test"); - - #[cfg(not(feature = "esp32"))] - println!("[RUN esp32 open_access_point]"); - - #[cfg(feature = "esp32")] - println!("[RUN esp32c3 open_access_point]"); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut socket_set_entries: [SocketStorage; 3] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap(); - let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - auth_method: AuthMethod::None, - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("{:?}", controller.get_capabilities()); - - let mut tries = 15; - - 'outer: loop { - println!("Start Wifi Scan"); - let res: Result<(heapless::Vec, usize), WifiError> = - controller.scan_n(); - if let Ok((res, _count)) = res { - for ap in res { - println!("{:?}", ap); - if ap.ssid == SSID { - break 'outer; - } - } - } - tries -= 1; - if tries == 0 { - break 'outer; - } - - let wait_end = current_millis() + 1 * 1000; - while current_millis() < wait_end { - // wait - } - } - - println!("wifi_connect {:?}", controller.connect()); - - // wait to get connected - println!("Wait to get connected"); - loop { - let res = controller.is_connected(); - match res { - Ok(connected) => { - if connected { - break; - } - } - Err(err) => { - println!("{:?}", err); - break; - } - } - } - println!("{:?}", controller.is_connected()); - - if let Ok(c) = controller.is_connected() { - if !c { - println!("[FAILED]"); - loop {} - } - } - if let Err(WifiError::Disconnected) = controller.is_connected() { - println!("[FAILED]"); - loop {} - } - - println!("Setting static IP {}", STATIC_IP); - - wifi_stack - .set_iface_configuration(&esp_wifi::wifi::ipv4::Configuration::Client( - esp_wifi::wifi::ipv4::ClientConfiguration::Fixed( - esp_wifi::wifi::ipv4::ClientSettings { - ip: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip(STATIC_IP)), - subnet: esp_wifi::wifi::ipv4::Subnet { - gateway: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip(GATEWAY_IP)), - mask: esp_wifi::wifi::ipv4::Mask(24), - }, - dns: None, - secondary_dns: None, - }, - ), - )) - .unwrap(); - - let mut rx_buffer = [0u8; 1536]; - let mut tx_buffer = [0u8; 1536]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - 'outer: loop { - socket.work(); - - socket - .open(IpAddress::Ipv4(Ipv4Address::new(192, 168, 2, 1)), 8080) - .unwrap(); - - loop { - let mut buffer = [0u8; 512]; - if let Ok(len) = socket.read(&mut buffer) { - let to_print = unsafe { core::str::from_utf8_unchecked(&buffer[..len]) }; - println!("{}", to_print); - if to_print.contains("DATA") { - println!("[PASSED]"); - break 'outer; - } - } else { - break; - } - } - println!(); - - socket.disconnect(); - } - - loop {} -} - -fn parse_ip(ip: &str) -> [u8; 4] { - let mut result = [0u8; 4]; - for (idx, octet) in ip.split(".").into_iter().enumerate() { - result[idx] = u8::from_str_radix(octet, 10).unwrap(); - } - result -} diff --git a/esp-wifi/automated-tests/test_esp_now.rs b/esp-wifi/automated-tests/test_esp_now.rs deleted file mode 100644 index 339f77fc..00000000 --- a/esp-wifi/automated-tests/test_esp_now.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![no_std] -#![no_main] - -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::esp_now::{PeerInfo, BROADCAST_ADDRESS}; -use esp_wifi::{initialize, EspWifiInitFor}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap(); - - println!("esp-now version {}", esp_now.get_version().unwrap()); - - #[cfg(not(feature = "esp32"))] - println!("[RUN esp32 esp_now_broadcaster]"); - - #[cfg(feature = "esp32")] - println!("[RUN esp32c3 esp_now_broadcaster]"); - - loop { - let r = esp_now.receive(); - if let Some(r) = r { - println!("Received {:?}", r); - - if r.info.dst_address == BROADCAST_ADDRESS { - if !esp_now.peer_exists(&r.info.src_address) { - esp_now - .add_peer(PeerInfo { - peer_address: r.info.src_address, - lmk: None, - channel: None, - encrypt: false, - }) - .unwrap(); - } - println!("[PASSED]"); - } - } - } -} diff --git a/esp-wifi/build.rs b/esp-wifi/build.rs deleted file mode 100644 index 666163b7..00000000 --- a/esp-wifi/build.rs +++ /dev/null @@ -1,172 +0,0 @@ -#[cfg(any( - feature = "esp32", - feature = "esp32c2", - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32h2", - feature = "esp32s2", - feature = "esp32s3", -))] -fn main() -> Result<(), String> { - #[cfg(all(feature = "ble", feature = "esp32s2"))] - { - panic!( - r#" - - BLE is not supported on this target. - - "# - ); - } - #[cfg(all(feature = "wifi", feature = "esp32h2"))] - { - panic!( - r#" - - WiFi is not supported on this target. - - "# - ); - } - #[cfg(all(feature = "coex", any(feature = "esp32s2")))] - { - panic!( - r#" - - COEX is not yet supported on this target. - - See https://github.com/esp-rs/esp-wifi/issues/92. - - "# - ); - } - match std::env::var("OPT_LEVEL") { - Ok(level) => { - if level != "2" && level != "3" { - let message = format!( - "esp-wifi should be built with optimization level 2 or 3 - yours is {level}. - See https://github.com/esp-rs/esp-wifi", - ); - print_warning(message); - } - } - Err(_err) => (), - } - - #[cfg(feature = "esp32")] - println!("cargo:rustc-cfg=esp32"); - - #[cfg(feature = "esp32c2")] - println!("cargo:rustc-cfg=esp32c2"); - - #[cfg(feature = "esp32c3")] - println!("cargo:rustc-cfg=esp32c3"); - - #[cfg(feature = "esp32c6")] - println!("cargo:rustc-cfg=esp32c6"); - - #[cfg(feature = "esp32h2")] - println!("cargo:rustc-cfg=esp32h2"); - - #[cfg(feature = "esp32s2")] - println!("cargo:rustc-cfg=esp32s2"); - - #[cfg(feature = "esp32s3")] - println!("cargo:rustc-cfg=esp32s3"); - - #[cfg(feature = "coex")] - { - #[cfg(all(feature = "wifi", feature = "ble"))] - println!("cargo:rustc-cfg=coex"); - - #[cfg(not(feature = "wifi"))] - println!("cargo:warning=coex is enabled but wifi is not"); - - #[cfg(not(feature = "ble"))] - println!("cargo:warning=coex is enabled but ble is not"); - } - - let version_output = std::process::Command::new( - std::env::var_os("RUSTC").unwrap_or_else(|| std::ffi::OsString::from("rustc")), - ) - .arg("-V") - .output() - .unwrap() - .stdout; - let version_string = String::from_utf8_lossy(&version_output); - - // HACK: we detect the xtensa-enabled compiler by existence of the second version string in parens - // - upstream output format: rustc 1.75.0-nightly (cae0791da 2023-10-05) - // - xtensa output format: rustc 1.73.0-nightly (9163a2087 2023-10-03) (1.73.0.0) - // - gentoo format (non-xtensa): rustc 1.73.0-nightly (cc66ad468 2023-10-03) (gentoo) - if version_string.chars().filter(|&c| c == '(').count() == 2 { - let version = version_string - .split('(') - .last() - .unwrap() - .split(')') - .next() - .unwrap(); - if let Some(version) = try_read_xtensa_rustc_version(version) { - if version >= Version4(1, 73, 0, 1) - // Patch accidentally missing from 1.74.0.0 - && version != Version4(1, 74, 0, 0) - { - println!("cargo:rustc-cfg=xtensa_has_vaarg"); - } - } - } - - Ok(()) -} - -fn try_read_xtensa_rustc_version(version: &str) -> Option { - let mut version = version.trim_start_matches('v').split('.'); - - let major = version.next()?.parse::().ok()?; - let minor = version.next()?.parse::().ok()?; - let patch = version.next()?.parse::().ok()?; - let release = version.next()?.parse::().ok()?; - - Some(Version4(major, minor, patch, release)) -} - -#[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"); -} - -use std::cmp::Ordering; - -#[derive(Debug, Clone, Copy, PartialEq)] -struct Version4(u32, u32, u32, u32); - -impl PartialOrd for Version4 { - fn partial_cmp(&self, other: &Self) -> Option { - match self.0.partial_cmp(&other.0) { - Some(Ordering::Equal) => {} - ord => return ord, - } - match self.1.partial_cmp(&other.1) { - Some(Ordering::Equal) => {} - ord => return ord, - } - match self.2.partial_cmp(&other.2) { - Some(Ordering::Equal) => {} - ord => return ord, - } - self.3.partial_cmp(&other.3) - } -} - -fn print_warning(message: impl core::fmt::Display) { - println!("cargo:warning={}", message); -} diff --git a/esp-wifi/docs/examples.md b/esp-wifi/docs/examples.md deleted file mode 100644 index b8bd5c58..00000000 --- a/esp-wifi/docs/examples.md +++ /dev/null @@ -1,145 +0,0 @@ -## Examples - - > The following instructions assume you have the [Xtensa toolchain](https://esp-rs.github.io/book/installation/riscv-and-xtensa.html) set up. In case you are building for a RISC-V target and would use -the mainline Rust compiler, you'll need to edit or remove the `rust-toolchain.toml` file. - -To build these ensure you are in the `esp-wifi` directory (the inner one, which has `examples` inside) and you are using the right chip name invocation. For example, to build for the `esp32c3`, please run - -``` -cargo esp32c3 --release ... -``` - -### dhcp - -- set SSID and PASSWORD env variable -- gets an ip address via DHCP -- performs an HTTP get request to some "random" server - -`cargo $CHIP --example dhcp --release --features "wifi"` - -### static_ip - -- set SSID and PASSWORD env variable -- set STATIC_IP and GATEWAY_IP env variable (e.g. "192.168.2.191" / "192.168.2.1") -- might be necessary to configure your WiFi access point accordingly -- uses the given static IP -- responds with some HTML content when connecting to port 8080 - -`cargo $CHIP --example static_ip --release --features "wifi"` - -### ble - -- starts Bluetooth advertising -- offers one service with three characteristics (one is read/write, one is write only, one is read/write/notify) -- pressing the boot-button on a dev-board will send a notification if it is subscribed -- this uses a toy level BLE stack - might not work with every BLE central device (tested with Android and Windows Bluetooth LE Explorer) - -`cargo $CHIP --example ble --release --features "ble"` - -**NOTE:** ESP32-S2 doesn't support bluetooth - -### embassy_ble - -- same as `ble` but async - -`cargo $CHIP --example embassy_ble --release --features "async,ble"` - -**NOTE:** ESP32-S2 doesn't support bluetooth - -### coex - -- set SSID and PASSWORD env variable -- gets an ip address via DHCP -- performs an HTTP get request to some "random" server -- does BLE advertising -- coex support is still somewhat flaky - -`cargo $CHIP --example coex --release --features "wifi,ble"` - -**NOTE:** Not currently available for the ESP32, ESP32-C2, ESP32-C6 or ESP32-S2 - -### esp_now - -- broadcasts, receives and sends messages via esp-now - -`cargo $CHIP --example esp_now --release --features "esp-now"` - -### embassy_esp_now - -- broadcasts, receives and sends messages via esp-now in an async way - -`cargo $CHIP --example embassy_esp_now --release --features "async,esp-now"` - -### embassy_esp_now_duplex - -- asynchronously broadcasts, receives and sends messages via esp-now in multiple embassy tasks - -`cargo $CHIP --example embassy_esp_now_duplex --release --features "async,esp-now"` - -### embassy_dhcp - -- Read and Write to sockets over WiFi asyncronously using embassy-executor. - -`cargo $CHIP --example embassy_dhcp --release --features "async,wifi,embassy-net"` - -### access_point - -- creates an open access-point with SSID `esp-wifi` -- you can connect to it using a static IP in range 192.168.2.2 .. 192.168.2.255, gateway 192.168.2.1 -- open http://192.168.2.1:8080/ in your browser -- on Android you might need to choose _Keep Accesspoint_ when it tells you the WiFi has no internet connection, Chrome might not want to load the URL - you can use a shell and try `curl` and `ping` - -`cargo $CHIP --example access_point --release --features "wifi"` - -### access_point_with_sta - -- set SSID and PASSWORD env variable -- gets an ip address via DHCP -- creates an open access-point with SSID `esp-wifi` -- you can connect to it using a static IP in range 192.168.2.2 .. 192.168.2.255, gateway 192.168.2.1 -- open http://192.168.2.1:8080/ in your browser - the example will perform an HTTP get request to some "random" server -- on Android you might need to choose _Keep Accesspoint_ when it tells you the WiFi has no internet connection, Chrome might not want to load the URL - you can use a shell and try `curl` and `ping` - -`cargo $CHIP --example access_point_with_sta --release --features "wifi"` - -### embassy_access_point - -- creates an open access-point with SSID `esp-wifi` -- you can connect to it using a static IP in range 192.168.2.2 .. 192.168.2.255, gateway 192.168.2.1 -- open http://192.168.2.1:8080/ in your browser -- on Android you might need to choose _Keep Accesspoint_ when it tells you the WiFi has no internet connection, Chrome might not want to load the URL - you can use a shell and try `curl` and `ping` - -`cargo $CHIP --example embassy_access_point --release --features "async,wifi,embassy-net"` - -### embassy_access_point_with_sta - -- set SSID and PASSWORD env variable -- gets an ip address via DHCP -- creates an open access-point with SSID `esp-wifi` -- you can connect to it using a static IP in range 192.168.2.2 .. 192.168.2.255, gateway 192.168.2.1 -- open http://192.168.2.1:8080/ in your browser - the example will perform an HTTP get request to some "random" server -- on Android you might need to choose _Keep Accesspoint_ when it tells you the WiFi has no internet connection, Chrome might not want to load the URL - you can use a shell and try `curl` and `ping` - -`cargo $CHIP --example embassy_access_point_with_sta --release --features "async,wifi,embassy-net"` - -## Benchmarking - -A prerequisite to running the benchmark examples is to run the benchmark server on your local machine. Simply run the following commands to do so. - -``` -cd extras/bench-server -cargo run --release -``` - -### bench - -- Run a test of download, upload and download+upload in a blocking fashion. -- Ensure you have set the IP of your local machine in the `HOST_IP` env variable. E.g `HOST_IP="192.168.0.24"` - -`cargo $CHIP --example bench --release --features "wifi"` - -### embassy_bench - -- Run a test of download, upload and download+upload in a async fashion. - -`cargo $CHIP --example embassy_bench --release --features "wifi,embassy-net"` \ No newline at end of file diff --git a/esp-wifi/docs/tuning.md b/esp-wifi/docs/tuning.md deleted file mode 100644 index c73625e1..00000000 --- a/esp-wifi/docs/tuning.md +++ /dev/null @@ -1,57 +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)| -|heap_size|Size of the WiFi/BLE heap in bytes| -|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/esp-wifi/examples/access_point.rs b/esp-wifi/examples/access_point.rs deleted file mode 100644 index ada530af..00000000 --- a/esp-wifi/examples/access_point.rs +++ /dev/null @@ -1,162 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::initialize; -use esp_wifi::wifi::utils::create_network_interface; -use esp_wifi::wifi::WifiApDevice; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -use smoltcp::iface::SocketStorage; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut socket_set_entries: [SocketStorage; 3] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiApDevice, &mut socket_set_entries).unwrap(); - let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::AccessPoint(AccessPointConfiguration { - ssid: "esp-wifi".try_into().unwrap(), - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("{:?}", controller.get_capabilities()); - - wifi_stack - .set_iface_configuration(&esp_wifi::wifi::ipv4::Configuration::Client( - esp_wifi::wifi::ipv4::ClientConfiguration::Fixed( - esp_wifi::wifi::ipv4::ClientSettings { - ip: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), - subnet: esp_wifi::wifi::ipv4::Subnet { - gateway: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), - mask: esp_wifi::wifi::ipv4::Mask(24), - }, - dns: None, - secondary_dns: None, - }, - ), - )) - .unwrap(); - - println!("Start busy loop on main. Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/"); - println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1"); - - let mut rx_buffer = [0u8; 1536]; - let mut tx_buffer = [0u8; 1536]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - socket.listen(8080).unwrap(); - - loop { - socket.work(); - - if !socket.is_open() { - socket.listen(8080).unwrap(); - } - - if socket.is_connected() { - println!("Connected"); - - let mut time_out = false; - let wait_end = current_millis() + 20 * 1000; - let mut buffer = [0u8; 1024]; - let mut pos = 0; - loop { - if let Ok(len) = socket.read(&mut buffer[pos..]) { - let to_print = - unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; - - if to_print.contains("\r\n\r\n") { - print!("{}", to_print); - println!(); - break; - } - - pos += len; - } else { - break; - } - - if current_millis() > wait_end { - println!("Timeout"); - time_out = true; - break; - } - } - - if !time_out { - socket - .write_all( - b"HTTP/1.0 200 OK\r\n\r\n\ - \ - \ -

Hello Rust! Hello esp-wifi!

\ - \ - \r\n\ - ", - ) - .unwrap(); - - socket.flush().unwrap(); - } - - socket.close(); - - println!("Done\n"); - println!(); - } - - let wait_end = current_millis() + 5 * 1000; - while current_millis() < wait_end { - socket.work(); - } - } -} - -fn parse_ip(ip: &str) -> [u8; 4] { - let mut result = [0u8; 4]; - for (idx, octet) in ip.split(".").into_iter().enumerate() { - result[idx] = u8::from_str_radix(octet, 10).unwrap(); - } - result -} diff --git a/esp-wifi/examples/access_point_with_sta.rs b/esp-wifi/examples/access_point_with_sta.rs deleted file mode 100644 index f1b40d51..00000000 --- a/esp-wifi/examples/access_point_with_sta.rs +++ /dev/null @@ -1,225 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointConfiguration, ClientConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::initialize; -use esp_wifi::wifi::utils::{create_ap_sta_network_interface, ApStaInterface}; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -use smoltcp::iface::SocketStorage; -use smoltcp::wire::IpAddress; -use smoltcp::wire::Ipv4Address; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - - let mut ap_socket_set_entries: [SocketStorage; 3] = Default::default(); - let mut sta_socket_set_entries: [SocketStorage; 3] = Default::default(); - - let ApStaInterface { - ap_interface, - sta_interface, - ap_device, - sta_device, - mut controller, - ap_socket_set, - sta_socket_set, - } = create_ap_sta_network_interface( - &init, - wifi, - &mut ap_socket_set_entries, - &mut sta_socket_set_entries, - ) - .unwrap(); - - let mut wifi_ap_stack = WifiStack::new(ap_interface, ap_device, ap_socket_set, current_millis); - let wifi_sta_stack = WifiStack::new(sta_interface, sta_device, sta_socket_set, current_millis); - - let client_config = Configuration::Mixed( - ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }, - AccessPointConfiguration { - ssid: "esp-wifi".try_into().unwrap(), - ..Default::default() - }, - ); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("{:?}", controller.get_capabilities()); - - wifi_ap_stack - .set_iface_configuration(&esp_wifi::wifi::ipv4::Configuration::Client( - esp_wifi::wifi::ipv4::ClientConfiguration::Fixed( - esp_wifi::wifi::ipv4::ClientSettings { - ip: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), - subnet: esp_wifi::wifi::ipv4::Subnet { - gateway: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), - mask: esp_wifi::wifi::ipv4::Mask(24), - }, - dns: None, - secondary_dns: None, - }, - ), - )) - .unwrap(); - - println!("wifi_connect {:?}", controller.connect()); - - // wait for STA getting an ip address - println!("Wait to get an ip address"); - loop { - wifi_sta_stack.work(); - - if wifi_sta_stack.is_iface_up() { - println!("got ip {:?}", wifi_sta_stack.get_ip_info()); - break; - } - } - - println!("Start busy loop on main. Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/"); - println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1"); - - let mut rx_buffer = [0u8; 1536]; - let mut tx_buffer = [0u8; 1536]; - let mut ap_socket = wifi_ap_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - let mut sta_rx_buffer = [0u8; 1536]; - let mut sta_tx_buffer = [0u8; 1536]; - let mut sta_socket = wifi_sta_stack.get_socket(&mut sta_rx_buffer, &mut sta_tx_buffer); - - ap_socket.listen(8080).unwrap(); - - loop { - ap_socket.work(); - - if !ap_socket.is_open() { - ap_socket.listen(8080).unwrap(); - } - - if ap_socket.is_connected() { - println!("Connected"); - - let mut time_out = false; - let wait_end = current_millis() + 20 * 1000; - let mut buffer = [0u8; 1024]; - let mut pos = 0; - loop { - if let Ok(len) = ap_socket.read(&mut buffer[pos..]) { - let to_print = - unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; - - if to_print.contains("\r\n\r\n") { - print!("{}", to_print); - println!(); - break; - } - - pos += len; - } else { - break; - } - - if current_millis() > wait_end { - println!("Timeout"); - time_out = true; - break; - } - } - - if !time_out { - println!("Making HTTP request"); - sta_socket.work(); - - sta_socket - .open(IpAddress::Ipv4(Ipv4Address::new(142, 250, 185, 115)), 80) - .unwrap(); - - sta_socket - .write(b"GET / HTTP/1.0\r\nHost: www.mobile-j.de\r\n\r\n") - .unwrap(); - sta_socket.flush().unwrap(); - - let wait_end = current_millis() + 20 * 1000; - loop { - let mut buffer = [0u8; 512]; - if let Ok(len) = sta_socket.read(&mut buffer) { - ap_socket.write_all(&buffer[..len]).unwrap(); - ap_socket.flush().unwrap(); - } else { - break; - } - - if current_millis() > wait_end { - println!("Timeout"); - break; - } - } - println!(); - - sta_socket.disconnect(); - } - - ap_socket.close(); - - println!("Done\n"); - println!(); - } - - let wait_end = current_millis() + 5 * 1000; - while current_millis() < wait_end { - ap_socket.work(); - } - } -} - -fn parse_ip(ip: &str) -> [u8; 4] { - let mut result = [0u8; 4]; - for (idx, octet) in ip.split(".").into_iter().enumerate() { - result[idx] = u8::from_str_radix(octet, 10).unwrap(); - } - result -} diff --git a/esp-wifi/examples/bench.rs b/esp-wifi/examples/bench.rs deleted file mode 100644 index 1f86ef8f..00000000 --- a/esp-wifi/examples/bench.rs +++ /dev/null @@ -1,245 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointInfo, ClientConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::wifi::utils::create_network_interface; -use esp_wifi::wifi::{WifiError, WifiStaDevice}; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::delay::Delay; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; -use smoltcp::iface::SocketStorage; -use smoltcp::wire::IpAddress; -use smoltcp::wire::Ipv4Address; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); -const HOST_IP: &str = env!("HOST_IP"); - -const TEST_DURATION: usize = 15; -const RX_BUFFER_SIZE: usize = 16384; -const TX_BUFFER_SIZE: usize = 16384; -const IO_BUFFER_SIZE: usize = 1024; -const DOWNLOAD_PORT: u16 = 4321; -const UPLOAD_PORT: u16 = 4322; -const UPLOAD_DOWNLOAD_PORT: u16 = 4323; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - let server_address: Ipv4Address = HOST_IP.parse().expect("Invalid HOST_IP address"); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut socket_set_entries: [SocketStorage; 3] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap(); - let wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("Start Wifi Scan"); - let res: Result<(heapless::Vec, usize), WifiError> = controller.scan_n(); - if let Ok((res, _count)) = res { - for ap in res { - println!("{:?}", ap); - } - } - - println!("{:?}", controller.get_capabilities()); - println!("wifi_connect {:?}", controller.connect()); - - // wait to get connected - println!("Wait to get connected"); - loop { - let res = controller.is_connected(); - match res { - Ok(connected) => { - if connected { - break; - } - } - Err(err) => { - println!("{:?}", err); - loop {} - } - } - } - println!("{:?}", controller.is_connected()); - - // wait for getting an ip address - println!("Wait to get an ip address"); - loop { - wifi_stack.work(); - - if wifi_stack.is_iface_up() { - println!("got ip {:?}", wifi_stack.get_ip_info()); - break; - } - } - - let mut rx_buffer = [0u8; RX_BUFFER_SIZE]; - let mut tx_buffer = [0u8; TX_BUFFER_SIZE]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - let delay = Delay::new(&clocks); - - loop { - test_download(server_address, &mut socket); - delay.delay_millis(3_000u32); - socket.work(); - test_upload(server_address, &mut socket); - socket.work(); - delay.delay_millis(3_000u32); - test_upload_download(server_address, &mut socket); - socket.work(); - delay.delay_millis(3_000u32); - } -} - -fn test_download<'a>( - server_address: Ipv4Address, - socket: &mut esp_wifi::wifi_interface::Socket<'a, 'a, WifiStaDevice>, -) { - println!("Testing download..."); - socket.work(); - - socket - .open(IpAddress::Ipv4(server_address), DOWNLOAD_PORT) - .unwrap(); - - let mut buf = [0; IO_BUFFER_SIZE]; - - let mut total = 0; - let wait_end = current_millis() + (TEST_DURATION as u64 * 1000); - loop { - socket.work(); - if let Ok(len) = socket.read(&mut buf) { - total += len; - } else { - break; - } - - if current_millis() > wait_end { - break; - } - } - - let kbps = (total + 512) / 1024 / TEST_DURATION; - println!("download: {} kB/s", kbps); - - socket.disconnect(); -} - -fn test_upload<'a>( - server_address: Ipv4Address, - socket: &mut esp_wifi::wifi_interface::Socket<'a, 'a, WifiStaDevice>, -) { - println!("Testing upload..."); - socket.work(); - - socket - .open(IpAddress::Ipv4(server_address), UPLOAD_PORT) - .unwrap(); - - let buf = [0; IO_BUFFER_SIZE]; - - let mut total = 0; - let wait_end = current_millis() + (TEST_DURATION as u64 * 1000); - loop { - socket.work(); - if let Ok(len) = socket.write(&buf) { - total += len; - } else { - break; - } - - if current_millis() > wait_end { - break; - } - } - - let kbps = (total + 512) / 1024 / TEST_DURATION; - println!("upload: {} kB/s", kbps); - - socket.disconnect(); -} - -fn test_upload_download<'a>( - server_address: Ipv4Address, - socket: &mut esp_wifi::wifi_interface::Socket<'a, 'a, WifiStaDevice>, -) { - println!("Testing upload+download..."); - socket.work(); - - socket - .open(IpAddress::Ipv4(server_address), UPLOAD_DOWNLOAD_PORT) - .unwrap(); - - let tx_buf = [0; IO_BUFFER_SIZE]; - let mut rx_buf = [0; IO_BUFFER_SIZE]; - - let mut total = 0; - let wait_end = current_millis() + (TEST_DURATION as u64 * 1000); - loop { - socket.work(); - if let Err(_) = socket.write(&tx_buf) { - break; - } - - socket.work(); - - if let Ok(len) = socket.read(&mut rx_buf) { - total += len; - } else { - break; - } - - if current_millis() > wait_end { - break; - } - } - - let kbps = (total + 512) / 1024 / TEST_DURATION; - println!("upload+download: {} kB/s", kbps); - - socket.disconnect(); -} diff --git a/esp-wifi/examples/ble.rs b/esp-wifi/examples/ble.rs deleted file mode 100644 index 422976f2..00000000 --- a/esp-wifi/examples/ble.rs +++ /dev/null @@ -1,163 +0,0 @@ -#![no_std] -#![no_main] - -use bleps::{ - ad_structure::{ - create_advertising_data, AdStructure, BR_EDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE, - }, - attribute_server::{AttributeServer, NotificationData, WorkResult}, - gatt, Ble, HciConnector, -}; -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::{ble::controller::BleConnector, initialize, EspWifiInitFor}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; -use hal::{clock::ClockControl, gpio::IO, peripherals::*, prelude::*, rng::Rng}; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Ble, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); - #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] - let button = io.pins.gpio0.into_pull_down_input(); - #[cfg(any( - feature = "esp32c2", - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32h2" - ))] - let button = io.pins.gpio9.into_pull_down_input(); - - let mut debounce_cnt = 500; - - let mut bluetooth = peripherals.BT; - - loop { - let connector = BleConnector::new(&init, &mut bluetooth); - let hci = HciConnector::new(connector, esp_wifi::current_millis); - let mut ble = Ble::new(&hci); - - println!("{:?}", ble.init()); - println!("{:?}", ble.cmd_set_le_advertising_parameters()); - println!( - "{:?}", - ble.cmd_set_le_advertising_data( - create_advertising_data(&[ - AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), - AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]), - AdStructure::CompleteLocalName(examples_util::SOC_NAME), - ]) - .unwrap() - ) - ); - println!("{:?}", ble.cmd_set_le_advertise_enable(true)); - - println!("started advertising"); - - let mut rf = |_offset: usize, data: &mut [u8]| { - data[..20].copy_from_slice(&b"Hello Bare-Metal BLE"[..]); - 17 - }; - let mut wf = |offset: usize, data: &[u8]| { - println!("RECEIVED: {} {:?}", offset, data); - }; - - let mut wf2 = |offset: usize, data: &[u8]| { - println!("RECEIVED: {} {:?}", offset, data); - }; - - let mut rf3 = |_offset: usize, data: &mut [u8]| { - data[..5].copy_from_slice(&b"Hola!"[..]); - 5 - }; - let mut wf3 = |offset: usize, data: &[u8]| { - println!("RECEIVED: Offset {}, data {:?}", offset, data); - }; - - gatt!([service { - uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", - characteristics: [ - characteristic { - uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", - read: rf, - write: wf, - }, - characteristic { - uuid: "957312e0-2354-11eb-9f10-fbc30a62cf38", - write: wf2, - }, - characteristic { - name: "my_characteristic", - uuid: "987312e0-2354-11eb-9f10-fbc30a62cf38", - notify: true, - read: rf3, - write: wf3, - }, - ], - },]); - - let mut rng = bleps::no_rng::NoRng; - let mut srv = AttributeServer::new(&mut ble, &mut gatt_attributes, &mut rng); - - loop { - let mut notification = None; - - if button.is_low() && debounce_cnt > 0 { - debounce_cnt -= 1; - if debounce_cnt == 0 { - let mut cccd = [0u8; 1]; - if let Some(1) = srv.get_characteristic_value( - my_characteristic_notify_enable_handle, - 0, - &mut cccd, - ) { - // if notifications enabled - if cccd[0] == 1 { - notification = Some(NotificationData::new( - my_characteristic_handle, - &b"Notification"[..], - )); - } - } - } - }; - - if button.is_high() { - debounce_cnt = 500; - } - - match srv.do_work_with_notification(notification) { - Ok(res) => { - if let WorkResult::GotDisconnected = res { - break; - } - } - Err(err) => { - println!("{:?}", err); - } - } - } - } -} diff --git a/esp-wifi/examples/coex.rs b/esp-wifi/examples/coex.rs deleted file mode 100644 index 73edcdfc..00000000 --- a/esp-wifi/examples/coex.rs +++ /dev/null @@ -1,172 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use bleps::{ - ad_structure::{ - create_advertising_data, AdStructure, BR_EDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE, - }, - att::Uuid, - Ble, HciConnector, -}; - -use esp_wifi::{ - ble::controller::BleConnector, current_millis, wifi::WifiStaDevice, wifi_interface::WifiStack, - EspWifiInitFor, -}; - -use embedded_io::*; -use esp_wifi::wifi::{ClientConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::initialize; -use esp_wifi::wifi::utils::create_network_interface; -use hal::{clock::ClockControl, rng::Rng}; -use hal::{peripherals::Peripherals, prelude::*}; -use smoltcp::{iface::SocketStorage, wire::IpAddress, wire::Ipv4Address}; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::WifiBle, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let bluetooth = peripherals.BT; - - let mut socket_set_entries: [SocketStorage; 2] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap(); - let wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - println!("{:?}", controller.get_capabilities()); - println!("wifi_connect {:?}", controller.connect()); - - // wait to get connected - println!("Wait to get connected"); - loop { - let res = controller.is_connected(); - match res { - Ok(connected) => { - if connected { - break; - } - } - Err(err) => { - println!("{:?}", err); - loop {} - } - } - } - println!("{:?}", controller.is_connected()); - - // wait for getting an ip address - println!("Wait to get an ip address"); - loop { - wifi_stack.work(); - - if wifi_stack.is_iface_up() { - println!("got ip {:?}", wifi_stack.get_ip_info()); - break; - } - } - - let connector = BleConnector::new(&init, bluetooth); - let hci = HciConnector::new(connector, esp_wifi::current_millis); - let mut ble = Ble::new(&hci); - - println!("{:?}", ble.init()); - println!("{:?}", ble.cmd_set_le_advertising_parameters()); - println!( - "{:?}", - ble.cmd_set_le_advertising_data( - create_advertising_data(&[ - AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), - AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]), - AdStructure::CompleteLocalName(examples_util::SOC_NAME), - ]) - .unwrap() - ) - ); - println!("{:?}", ble.cmd_set_le_advertise_enable(true)); - - println!("started advertising"); - - println!("Start busy loop on main"); - - let mut rx_buffer = [0u8; 128]; - let mut tx_buffer = [0u8; 128]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - loop { - println!("Making HTTP request"); - socket.work(); - - socket - .open(IpAddress::Ipv4(Ipv4Address::new(142, 250, 185, 115)), 80) - .unwrap(); - - socket - .write(b"GET / HTTP/1.0\r\nHost: www.mobile-j.de\r\n\r\n") - .unwrap(); - socket.flush().unwrap(); - - let wait_end = current_millis() + 20 * 1000; - loop { - let mut buffer = [0u8; 128]; - if let Ok(len) = socket.read(&mut buffer) { - let to_print = unsafe { core::str::from_utf8_unchecked(&buffer[..len]) }; - print!("{}", to_print); - } else { - break; - } - - if current_millis() > wait_end { - println!("Timeout"); - break; - } - } - println!(); - - socket.disconnect(); - - let wait_end = current_millis() + 5 * 1000; - while current_millis() < wait_end { - socket.work(); - } - } -} diff --git a/esp-wifi/examples/dhcp.rs b/esp-wifi/examples/dhcp.rs deleted file mode 100644 index 0b964357..00000000 --- a/esp-wifi/examples/dhcp.rs +++ /dev/null @@ -1,150 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointInfo, ClientConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::wifi::utils::create_network_interface; -use esp_wifi::wifi::{WifiError, WifiStaDevice}; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; -use smoltcp::iface::SocketStorage; -use smoltcp::wire::IpAddress; -use smoltcp::wire::Ipv4Address; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut socket_set_entries: [SocketStorage; 3] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap(); - let wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("Start Wifi Scan"); - let res: Result<(heapless::Vec, usize), WifiError> = controller.scan_n(); - if let Ok((res, _count)) = res { - for ap in res { - println!("{:?}", ap); - } - } - - println!("{:?}", controller.get_capabilities()); - println!("wifi_connect {:?}", controller.connect()); - - // wait to get connected - println!("Wait to get connected"); - loop { - let res = controller.is_connected(); - match res { - Ok(connected) => { - if connected { - break; - } - } - Err(err) => { - println!("{:?}", err); - loop {} - } - } - } - println!("{:?}", controller.is_connected()); - - // wait for getting an ip address - println!("Wait to get an ip address"); - loop { - wifi_stack.work(); - - if wifi_stack.is_iface_up() { - println!("got ip {:?}", wifi_stack.get_ip_info()); - break; - } - } - - println!("Start busy loop on main"); - - let mut rx_buffer = [0u8; 1536]; - let mut tx_buffer = [0u8; 1536]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - loop { - println!("Making HTTP request"); - socket.work(); - - socket - .open(IpAddress::Ipv4(Ipv4Address::new(142, 250, 185, 115)), 80) - .unwrap(); - - socket - .write(b"GET / HTTP/1.0\r\nHost: www.mobile-j.de\r\n\r\n") - .unwrap(); - socket.flush().unwrap(); - - let wait_end = current_millis() + 20 * 1000; - loop { - let mut buffer = [0u8; 512]; - if let Ok(len) = socket.read(&mut buffer) { - let to_print = unsafe { core::str::from_utf8_unchecked(&buffer[..len]) }; - print!("{}", to_print); - } else { - break; - } - - if current_millis() > wait_end { - println!("Timeout"); - break; - } - } - println!(); - - socket.disconnect(); - - let wait_end = current_millis() + 5 * 1000; - while current_millis() < wait_end { - socket.work(); - } - } -} diff --git a/esp-wifi/examples/embassy_access_point.rs b/esp-wifi/examples/embassy_access_point.rs deleted file mode 100644 index 29d32a75..00000000 --- a/esp-wifi/examples/embassy_access_point.rs +++ /dev/null @@ -1,189 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy_net::tcp::TcpSocket; -use embassy_net::{ - Config, IpListenEndpoint, Ipv4Address, Ipv4Cidr, Stack, StackResources, StaticConfigV4, -}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::wifi::{AccessPointConfiguration, Configuration}; -use esp_wifi::wifi::{WifiApDevice, WifiController, WifiDevice, WifiEvent, WifiState}; -use esp_wifi::{initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup}; -use static_cell::make_static; - -#[main] -async fn main(spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let (wifi_interface, controller) = - esp_wifi::wifi::new_with_mode(&init, wifi, WifiApDevice).unwrap(); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let config = Config::ipv4_static(StaticConfigV4 { - address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 2, 1), 24), - gateway: Some(Ipv4Address::from_bytes(&[192, 168, 2, 1])), - dns_servers: Default::default(), - }); - - let seed = 1234; // very random, very secure seed - - // Init network stack - let stack = &*make_static!(Stack::new( - wifi_interface, - config, - make_static!(StackResources::<3>::new()), - seed - )); - - spawner.spawn(connection(controller)).ok(); - spawner.spawn(net_task(&stack)).ok(); - - let mut rx_buffer = [0; 1536]; - let mut tx_buffer = [0; 1536]; - - loop { - if stack.is_link_up() { - break; - } - Timer::after(Duration::from_millis(500)).await; - } - println!("Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/"); - println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1"); - - let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer); - socket.set_timeout(Some(embassy_time::Duration::from_secs(10))); - loop { - println!("Wait for connection..."); - let r = socket - .accept(IpListenEndpoint { - addr: None, - port: 8080, - }) - .await; - println!("Connected..."); - - if let Err(e) = r { - println!("connect error: {:?}", e); - continue; - } - - use embedded_io_async::Write; - - let mut buffer = [0u8; 1024]; - let mut pos = 0; - loop { - match socket.read(&mut buffer).await { - Ok(0) => { - println!("read EOF"); - break; - } - Ok(len) => { - let to_print = - unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; - - if to_print.contains("\r\n\r\n") { - print!("{}", to_print); - println!(); - break; - } - - pos += len; - } - Err(e) => { - println!("read error: {:?}", e); - break; - } - }; - } - - let r = socket - .write_all( - b"HTTP/1.0 200 OK\r\n\r\n\ - \ - \ -

Hello Rust! Hello esp-wifi!

\ - \ - \r\n\ - ", - ) - .await; - if let Err(e) = r { - println!("write error: {:?}", e); - } - - let r = socket.flush().await; - if let Err(e) = r { - println!("flush error: {:?}", e); - } - Timer::after(Duration::from_millis(1000)).await; - - socket.close(); - Timer::after(Duration::from_millis(1000)).await; - - socket.abort(); - } -} - -#[embassy_executor::task] -async fn connection(mut controller: WifiController<'static>) { - println!("start connection task"); - println!("Device capabilities: {:?}", controller.get_capabilities()); - loop { - match esp_wifi::wifi::get_wifi_state() { - WifiState::ApStarted => { - // wait until we're no longer connected - controller.wait_for_event(WifiEvent::ApStop).await; - Timer::after(Duration::from_millis(5000)).await - } - _ => {} - } - if !matches!(controller.is_started(), Ok(true)) { - let client_config = Configuration::AccessPoint(AccessPointConfiguration { - ssid: "esp-wifi".try_into().unwrap(), - ..Default::default() - }); - controller.set_configuration(&client_config).unwrap(); - println!("Starting wifi"); - controller.start().await.unwrap(); - println!("Wifi started!"); - } - } -} - -#[embassy_executor::task] -async fn net_task(stack: &'static Stack>) { - stack.run().await -} diff --git a/esp-wifi/examples/embassy_access_point_with_sta.rs b/esp-wifi/examples/embassy_access_point_with_sta.rs deleted file mode 100644 index 922f2c04..00000000 --- a/esp-wifi/examples/embassy_access_point_with_sta.rs +++ /dev/null @@ -1,302 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy_net::tcp::TcpSocket; -use embassy_net::{ - Config, IpListenEndpoint, Ipv4Address, Ipv4Cidr, Stack, StackResources, StaticConfigV4, -}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::wifi::{AccessPointConfiguration, ClientConfiguration, Configuration}; -use esp_wifi::wifi::{ - WifiApDevice, WifiController, WifiDevice, WifiEvent, WifiStaDevice, WifiState, -}; -use esp_wifi::{initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup}; -use static_cell::make_static; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); - -#[main] -async fn main(spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let (wifi_ap_interface, wifi_sta_interface, mut controller) = - esp_wifi::wifi::new_ap_sta(&init, wifi).unwrap(); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let ap_config = Config::ipv4_static(StaticConfigV4 { - address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 2, 1), 24), - gateway: Some(Ipv4Address::from_bytes(&[192, 168, 2, 1])), - dns_servers: Default::default(), - }); - let sta_config = Config::dhcpv4(Default::default()); - - let seed = 1234; // very random, very secure seed - - // Init network stacks - let ap_stack = &*make_static!(Stack::new( - wifi_ap_interface, - ap_config, - make_static!(StackResources::<3>::new()), - seed - )); - let sta_stack = &*make_static!(Stack::new( - wifi_sta_interface, - sta_config, - make_static!(StackResources::<3>::new()), - seed - )); - - let client_config = Configuration::Mixed( - ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }, - AccessPointConfiguration { - ssid: "esp-wifi".try_into().unwrap(), - ..Default::default() - }, - ); - controller.set_configuration(&client_config).unwrap(); - - spawner.spawn(connection(controller)).ok(); - spawner.spawn(ap_task(&ap_stack)).ok(); - spawner.spawn(sta_task(&sta_stack)).ok(); - - loop { - if sta_stack.is_link_up() { - break; - } - println!("Waiting for IP..."); - Timer::after(Duration::from_millis(500)).await; - } - loop { - if ap_stack.is_link_up() { - break; - } - Timer::after(Duration::from_millis(500)).await; - } - println!("Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/"); - println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1"); - - let mut ap_rx_buffer = [0; 1536]; - let mut ap_tx_buffer = [0; 1536]; - - let mut ap_socket = TcpSocket::new(&ap_stack, &mut ap_rx_buffer, &mut ap_tx_buffer); - ap_socket.set_timeout(Some(embassy_time::Duration::from_secs(10))); - - let mut sta_rx_buffer = [0; 1536]; - let mut sta_tx_buffer = [0; 1536]; - - let mut sta_socket = TcpSocket::new(&sta_stack, &mut sta_rx_buffer, &mut sta_tx_buffer); - sta_socket.set_timeout(Some(embassy_time::Duration::from_secs(10))); - - loop { - println!("Wait for connection..."); - let r = ap_socket - .accept(IpListenEndpoint { - addr: None, - port: 8080, - }) - .await; - println!("Connected..."); - - if let Err(e) = r { - println!("connect error: {:?}", e); - continue; - } - - use embedded_io_async::Write; - - let mut buffer = [0u8; 1024]; - let mut pos = 0; - loop { - match ap_socket.read(&mut buffer).await { - Ok(0) => { - println!("AP read EOF"); - break; - } - Ok(len) => { - let to_print = - unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; - - if to_print.contains("\r\n\r\n") { - print!("{}", to_print); - println!(); - break; - } - - pos += len; - } - Err(e) => { - println!("AP read error: {:?}", e); - break; - } - }; - } - - if sta_stack.is_link_up() { - let remote_endpoint = (Ipv4Address::new(142, 250, 185, 115), 80); - println!("connecting..."); - let r = sta_socket.connect(remote_endpoint).await; - if let Err(e) = r { - println!("STA connect error: {:?}", e); - continue; - } - - use embedded_io_async::Write; - let r = sta_socket - .write_all(b"GET / HTTP/1.0\r\nHost: www.mobile-j.de\r\n\r\n") - .await; - - if let Err(e) = r { - println!("STA write error: {:?}", e); - - let r = ap_socket - .write_all( - b"HTTP/1.0 500 Internal Server Error\r\n\r\n\ - \ - \ -

Hello Rust! Hello esp-wifi! STA failed to send request.

\ - \ - \r\n\ - ", - ) - .await; - if let Err(e) = r { - println!("AP write error: {:?}", e); - } - } else { - let r = sta_socket.flush().await; - if let Err(e) = r { - println!("STA flush error: {:?}", e); - } else { - println!("connected!"); - let mut buf = [0; 1024]; - loop { - match sta_socket.read(&mut buf).await { - Ok(0) => { - println!("STA read EOF"); - break; - } - Ok(n) => { - let r = ap_socket.write_all(&buf[..n]).await; - if let Err(e) = r { - println!("AP write error: {:?}", e); - break; - } - } - Err(e) => { - println!("STA read error: {:?}", e); - break; - } - } - } - } - } - - sta_socket.close(); - } else { - let r = ap_socket - .write_all( - b"HTTP/1.0 200 OK\r\n\r\n\ - \ - \ -

Hello Rust! Hello esp-wifi! STA is not connected.

\ - \ - \r\n\ - ", - ) - .await; - if let Err(e) = r { - println!("AP write error: {:?}", e); - } - } - - let r = ap_socket.flush().await; - if let Err(e) = r { - println!("AP flush error: {:?}", e); - } - Timer::after(Duration::from_millis(1000)).await; - - ap_socket.close(); - Timer::after(Duration::from_millis(1000)).await; - - ap_socket.abort(); - } -} - -#[embassy_executor::task] -async fn connection(mut controller: WifiController<'static>) { - println!("start connection task"); - println!("Device capabilities: {:?}", controller.get_capabilities()); - - println!("Starting wifi"); - controller.start().await.unwrap(); - println!("Wifi started!"); - - loop { - match esp_wifi::wifi::get_ap_state() { - WifiState::ApStarted => { - println!("About to connect..."); - - match controller.connect().await { - Ok(_) => { - // wait until we're no longer connected - controller.wait_for_event(WifiEvent::StaDisconnected).await; - println!("STA disconnected"); - } - Err(e) => { - println!("Failed to connect to wifi: {e:?}"); - Timer::after(Duration::from_millis(5000)).await - } - } - } - _ => return, - } - } -} - -#[embassy_executor::task] -async fn ap_task(stack: &'static Stack>) { - stack.run().await -} - -#[embassy_executor::task] -async fn sta_task(stack: &'static Stack>) { - stack.run().await -} diff --git a/esp-wifi/examples/embassy_bench.rs b/esp-wifi/examples/embassy_bench.rs deleted file mode 100644 index a817ee79..00000000 --- a/esp-wifi/examples/embassy_bench.rs +++ /dev/null @@ -1,297 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy_executor::Spawner; -use embassy_futures::join::join; -use embassy_net::tcp::TcpSocket; -use embassy_net::{Config, Ipv4Address, Stack, StackResources}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embassy_time::{with_timeout, Duration, Timer}; -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::wifi::{ClientConfiguration, Configuration, WifiStaDevice}; -use esp_wifi::wifi::{WifiController, WifiDevice, WifiEvent, WifiState}; -use esp_wifi::{initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup}; -use static_cell::make_static; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); -const HOST_IP: &str = env!("HOST_IP"); - -const TEST_DURATION: usize = 15; -const RX_BUFFER_SIZE: usize = 16384; -const TX_BUFFER_SIZE: usize = 16384; -const IO_BUFFER_SIZE: usize = 1024; -const DOWNLOAD_PORT: u16 = 4321; -const UPLOAD_PORT: u16 = 4322; -const UPLOAD_DOWNLOAD_PORT: u16 = 4323; - -// static buffers to not need a huge task-arena -static mut RX_BUFFER: [u8; RX_BUFFER_SIZE] = [0; RX_BUFFER_SIZE]; -static mut TX_BUFFER: [u8; TX_BUFFER_SIZE] = [0; TX_BUFFER_SIZE]; - -#[main] -async fn main(spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - let server_address: Ipv4Address = HOST_IP.parse().expect("Invalid HOST_IP address"); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let (wifi_interface, controller) = - esp_wifi::wifi::new_with_mode(&init, wifi, WifiStaDevice).unwrap(); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let config = Config::dhcpv4(Default::default()); - - let seed = 1234; // very random, very secure seed - - // Init network stack - let stack = &*make_static!(Stack::new( - wifi_interface, - config, - make_static!(StackResources::<3>::new()), - seed - )); - - spawner.spawn(connection(controller)).ok(); - spawner.spawn(net_task(&stack)).ok(); - - loop { - if stack.is_link_up() { - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - println!("Waiting to get IP address..."); - loop { - if let Some(config) = stack.config_v4() { - println!("Got IP: {}", config.address); - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - let mut socket = TcpSocket::new( - stack, - unsafe { &mut *core::ptr::addr_of_mut!(RX_BUFFER) }, - unsafe { &mut *core::ptr::addr_of_mut!(TX_BUFFER) }, - ); - - loop { - let _down = test_download(server_address, &mut socket).await; - let _up = test_upload(server_address, &mut socket).await; - let _updown = test_upload_download(server_address, &mut socket).await; - - Timer::after(Duration::from_millis(10000)).await; - } -} - -#[embassy_executor::task] -async fn connection(mut controller: WifiController<'static>) { - println!("start connection task"); - println!("Device capabilities: {:?}", controller.get_capabilities()); - loop { - match esp_wifi::wifi::get_wifi_state() { - WifiState::StaConnected => { - // wait until we're no longer connected - controller.wait_for_event(WifiEvent::StaDisconnected).await; - Timer::after(Duration::from_millis(5000)).await - } - _ => {} - } - if !matches!(controller.is_started(), Ok(true)) { - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }); - controller.set_configuration(&client_config).unwrap(); - println!("Starting wifi"); - controller.start().await.unwrap(); - println!("Wifi started!"); - } - println!("About to connect..."); - - match controller.connect().await { - Ok(_) => println!("Wifi connected!"), - Err(e) => { - println!("Failed to connect to wifi: {e:?}"); - Timer::after(Duration::from_millis(5000)).await - } - } - } -} - -#[embassy_executor::task] -async fn net_task(stack: &'static Stack>) { - stack.run().await -} - -async fn test_download(server_address: Ipv4Address, socket: &mut TcpSocket<'_>) -> usize { - println!("Testing download..."); - - socket.abort(); - socket.set_timeout(Some(Duration::from_secs(10))); - - println!("connecting to {:?}:{}...", server_address, DOWNLOAD_PORT); - if let Err(e) = socket.connect((server_address, DOWNLOAD_PORT)).await { - println!("connect error: {:?}", e); - return 0; - } - println!("connected, testing..."); - - let mut buf = [0; IO_BUFFER_SIZE]; - let mut total: usize = 0; - with_timeout(Duration::from_secs(TEST_DURATION as _), async { - loop { - match socket.read(&mut buf).await { - Ok(0) => { - println!("read EOF"); - return 0; - } - Ok(n) => total += n, - Err(e) => { - println!("read error: {:?}", e); - return 0; - } - } - } - }) - .await - .ok(); - - let kbps = (total + 512) / 1024 / TEST_DURATION; - println!("download: {} kB/s", kbps); - kbps -} - -async fn test_upload(server_address: Ipv4Address, socket: &mut TcpSocket<'_>) -> usize { - println!("Testing upload..."); - socket.abort(); - socket.set_timeout(Some(Duration::from_secs(10))); - - println!("connecting to {:?}:{}...", server_address, UPLOAD_PORT); - if let Err(e) = socket.connect((server_address, UPLOAD_PORT)).await { - println!("connect error: {:?}", e); - return 0; - } - println!("connected, testing..."); - - let buf = [0; IO_BUFFER_SIZE]; - let mut total: usize = 0; - with_timeout(Duration::from_secs(TEST_DURATION as _), async { - loop { - match socket.write(&buf).await { - Ok(0) => { - println!("write zero?!??!?!"); - return 0; - } - Ok(n) => total += n, - Err(e) => { - println!("write error: {:?}", e); - return 0; - } - } - } - }) - .await - .ok(); - - let kbps = (total + 512) / 1024 / TEST_DURATION; - println!("upload: {} kB/s", kbps); - kbps -} - -async fn test_upload_download(server_address: Ipv4Address, socket: &mut TcpSocket<'_>) -> usize { - println!("Testing upload+download..."); - - socket.abort(); - socket.set_timeout(Some(Duration::from_secs(10))); - - println!( - "connecting to {:?}:{}...", - server_address, UPLOAD_DOWNLOAD_PORT - ); - if let Err(e) = socket.connect((server_address, UPLOAD_DOWNLOAD_PORT)).await { - println!("connect error: {:?}", e); - return 0; - } - println!("connected, testing..."); - - let (mut reader, mut writer) = socket.split(); - - let tx_buf = [0; IO_BUFFER_SIZE]; - let mut rx_buf = [0; IO_BUFFER_SIZE]; - let mut total: usize = 0; - let tx_fut = async { - loop { - match writer.write(&tx_buf).await { - Ok(0) => { - println!("write zero?!??!?!"); - return 0; - } - Ok(_) => {} - Err(e) => { - println!("write error: {:?}", e); - return 0; - } - } - } - }; - - let rx_fut = async { - loop { - match reader.read(&mut rx_buf).await { - Ok(0) => { - println!("read EOF"); - return 0; - } - Ok(n) => total += n, - Err(e) => { - println!("read error: {:?}", e); - return 0; - } - } - } - }; - - with_timeout( - Duration::from_secs(TEST_DURATION as _), - join(tx_fut, rx_fut), - ) - .await - .ok(); - - let kbps = (total + 512) / 1024 / TEST_DURATION; - println!("upload+download: {} kB/s", kbps); - kbps -} diff --git a/esp-wifi/examples/embassy_ble.rs b/esp-wifi/examples/embassy_ble.rs deleted file mode 100644 index b1298616..00000000 --- a/esp-wifi/examples/embassy_ble.rs +++ /dev/null @@ -1,168 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] -#![feature(async_closure)] - -use core::cell::RefCell; - -use bleps::{ - ad_structure::{ - create_advertising_data, AdStructure, BR_EDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE, - }, - async_attribute_server::AttributeServer, - asynch::Ble, - attribute_server::NotificationData, - gatt, -}; -use embassy_executor::Spawner; -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::{ble::controller::asynch::BleConnector, initialize, EspWifiInitFor}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; -use hal::{ - clock::ClockControl, embassy, gpio::IO, peripherals::*, prelude::*, rng::Rng, timer::TimerGroup, -}; - -#[main] -async fn main(_spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Ble, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); - #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] - let button = io.pins.gpio0.into_pull_down_input(); - #[cfg(any( - feature = "esp32c2", - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32h2" - ))] - let button = io.pins.gpio9.into_pull_down_input(); - - // Async requires the GPIO interrupt to wake futures - hal::interrupt::enable( - hal::peripherals::Interrupt::GPIO, - hal::interrupt::Priority::Priority1, - ) - .unwrap(); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let mut bluetooth = peripherals.BT; - - let connector = BleConnector::new(&init, &mut bluetooth); - let mut ble = Ble::new(connector, esp_wifi::current_millis); - println!("Connector created"); - - let pin_ref = RefCell::new(button); - let pin_ref = &pin_ref; - - loop { - println!("{:?}", ble.init().await); - println!("{:?}", ble.cmd_set_le_advertising_parameters().await); - println!( - "{:?}", - ble.cmd_set_le_advertising_data( - create_advertising_data(&[ - AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), - AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]), - AdStructure::CompleteLocalName(examples_util::SOC_NAME), - ]) - .unwrap() - ) - .await - ); - println!("{:?}", ble.cmd_set_le_advertise_enable(true).await); - - println!("started advertising"); - - let mut rf = |_offset: usize, data: &mut [u8]| { - data[..20].copy_from_slice(&b"Hello Bare-Metal BLE"[..]); - 17 - }; - let mut wf = |offset: usize, data: &[u8]| { - println!("RECEIVED: {} {:?}", offset, data); - }; - - let mut wf2 = |offset: usize, data: &[u8]| { - println!("RECEIVED: {} {:?}", offset, data); - }; - - let mut rf3 = |_offset: usize, data: &mut [u8]| { - data[..5].copy_from_slice(&b"Hola!"[..]); - 5 - }; - let mut wf3 = |offset: usize, data: &[u8]| { - println!("RECEIVED: Offset {}, data {:?}", offset, data); - }; - - gatt!([service { - uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", - characteristics: [ - characteristic { - uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", - read: rf, - write: wf, - }, - characteristic { - uuid: "957312e0-2354-11eb-9f10-fbc30a62cf38", - write: wf2, - }, - characteristic { - name: "my_characteristic", - uuid: "987312e0-2354-11eb-9f10-fbc30a62cf38", - notify: true, - read: rf3, - write: wf3, - }, - ], - },]); - - let mut rng = bleps::no_rng::NoRng; - let mut srv = AttributeServer::new(&mut ble, &mut gatt_attributes, &mut rng); - - let counter = RefCell::new(0u8); - let counter = &counter; - - let mut notifier = || { - // TODO how to check if notifications are enabled for the characteristic? - // maybe pass something into the closure which just can query the characteristic value - // probably passing in the attribute server won't work? - - async { - pin_ref.borrow_mut().wait_for_rising_edge().await; - let mut data = [0u8; 13]; - data.copy_from_slice(b"Notification0"); - { - let mut counter = counter.borrow_mut(); - data[data.len() - 1] += *counter; - *counter = (*counter + 1) % 10; - } - NotificationData::new(my_characteristic_handle, &data) - } - }; - - srv.run(&mut notifier).await.unwrap(); - } -} diff --git a/esp-wifi/examples/embassy_dhcp.rs b/esp-wifi/examples/embassy_dhcp.rs deleted file mode 100644 index 8973b401..00000000 --- a/esp-wifi/examples/embassy_dhcp.rs +++ /dev/null @@ -1,171 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy_executor::Spawner; -use embassy_net::tcp::TcpSocket; -use embassy_net::{Config, Ipv4Address, Stack, StackResources}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embassy_time::{Duration, Timer}; -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::wifi::{ClientConfiguration, Configuration}; -use esp_wifi::wifi::{WifiController, WifiDevice, WifiEvent, WifiStaDevice, WifiState}; -use esp_wifi::{initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup}; -use static_cell::make_static; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); - -#[main] -async fn main(spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let (wifi_interface, controller) = - esp_wifi::wifi::new_with_mode(&init, wifi, WifiStaDevice).unwrap(); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let config = Config::dhcpv4(Default::default()); - - let seed = 1234; // very random, very secure seed - - // Init network stack - let stack = &*make_static!(Stack::new( - wifi_interface, - config, - make_static!(StackResources::<3>::new()), - seed - )); - - spawner.spawn(connection(controller)).ok(); - spawner.spawn(net_task(&stack)).ok(); - - let mut rx_buffer = [0; 4096]; - let mut tx_buffer = [0; 4096]; - - loop { - if stack.is_link_up() { - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - println!("Waiting to get IP address..."); - loop { - if let Some(config) = stack.config_v4() { - println!("Got IP: {}", config.address); - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - loop { - Timer::after(Duration::from_millis(1_000)).await; - - let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer); - - socket.set_timeout(Some(embassy_time::Duration::from_secs(10))); - - let remote_endpoint = (Ipv4Address::new(142, 250, 185, 115), 80); - println!("connecting..."); - let r = socket.connect(remote_endpoint).await; - if let Err(e) = r { - println!("connect error: {:?}", e); - continue; - } - println!("connected!"); - let mut buf = [0; 1024]; - loop { - use embedded_io_async::Write; - let r = socket - .write_all(b"GET / HTTP/1.0\r\nHost: www.mobile-j.de\r\n\r\n") - .await; - if let Err(e) = r { - println!("write error: {:?}", e); - break; - } - let n = match socket.read(&mut buf).await { - Ok(0) => { - println!("read EOF"); - break; - } - Ok(n) => n, - Err(e) => { - println!("read error: {:?}", e); - break; - } - }; - println!("{}", core::str::from_utf8(&buf[..n]).unwrap()); - } - Timer::after(Duration::from_millis(3000)).await; - } -} - -#[embassy_executor::task] -async fn connection(mut controller: WifiController<'static>) { - println!("start connection task"); - println!("Device capabilities: {:?}", controller.get_capabilities()); - loop { - match esp_wifi::wifi::get_wifi_state() { - WifiState::StaConnected => { - // wait until we're no longer connected - controller.wait_for_event(WifiEvent::StaDisconnected).await; - Timer::after(Duration::from_millis(5000)).await - } - _ => {} - } - if !matches!(controller.is_started(), Ok(true)) { - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }); - controller.set_configuration(&client_config).unwrap(); - println!("Starting wifi"); - controller.start().await.unwrap(); - println!("Wifi started!"); - } - println!("About to connect..."); - - match controller.connect().await { - Ok(_) => println!("Wifi connected!"), - Err(e) => { - println!("Failed to connect to wifi: {e:?}"); - Timer::after(Duration::from_millis(5000)).await - } - } - } -} - -#[embassy_executor::task] -async fn net_task(stack: &'static Stack>) { - stack.run().await -} diff --git a/esp-wifi/examples/embassy_esp_now.rs b/esp-wifi/examples/embassy_esp_now.rs deleted file mode 100644 index 4c5e76ff..00000000 --- a/esp-wifi/examples/embassy_esp_now.rs +++ /dev/null @@ -1,81 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy_futures::select::{select, Either}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embassy_executor::Spawner; -use embassy_time::{Duration, Ticker}; -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::esp_now::{PeerInfo, BROADCAST_ADDRESS}; -use esp_wifi::{initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup}; - -#[main] -async fn main(_spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap(); - println!("esp-now version {}", esp_now.get_version().unwrap()); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let mut ticker = Ticker::every(Duration::from_secs(5)); - loop { - let res = select(ticker.next(), async { - let r = esp_now.receive_async().await; - println!("Received {:?}", r); - if r.info.dst_address == BROADCAST_ADDRESS { - if !esp_now.peer_exists(&r.info.src_address) { - esp_now - .add_peer(PeerInfo { - peer_address: r.info.src_address, - lmk: None, - channel: None, - encrypt: false, - }) - .unwrap(); - } - let status = esp_now.send_async(&r.info.src_address, b"Hello Peer").await; - println!("Send hello to peer status: {:?}", status); - } - }) - .await; - - match res { - Either::First(_) => { - println!("Send"); - let status = esp_now.send_async(&BROADCAST_ADDRESS, b"0123456789").await; - println!("Send broadcast status: {:?}", status) - } - Either::Second(_) => (), - } - } -} diff --git a/esp-wifi/examples/embassy_esp_now_duplex.rs b/esp-wifi/examples/embassy_esp_now_duplex.rs deleted file mode 100644 index ae7961d7..00000000 --- a/esp-wifi/examples/embassy_esp_now_duplex.rs +++ /dev/null @@ -1,113 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy_sync::blocking_mutex::raw::NoopRawMutex; -use embassy_sync::mutex::Mutex; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embassy_executor::Spawner; -use embassy_time::{Duration, Ticker}; -use esp_backtrace as _; - -use esp_println::println; -use esp_wifi::esp_now::{EspNowManager, EspNowReceiver, EspNowSender, PeerInfo, BROADCAST_ADDRESS}; -use esp_wifi::{initialize, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup}; -use static_cell::make_static; - -#[main] -async fn main(spawner: Spawner) -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap(); - println!("esp-now version {}", esp_now.get_version().unwrap()); - - let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks); - embassy::init(&clocks, timer_group0); - - let (manager, sender, receiver) = esp_now.split(); - let manager = make_static!(manager); - let sender = make_static!(Mutex::::new(sender)); - - spawner.spawn(listener(manager, receiver)).ok(); - spawner.spawn(broadcaster(sender)).ok(); - - let mut ticker = Ticker::every(Duration::from_millis(500)); - loop { - ticker.next().await; - let peer = match manager.fetch_peer(false) { - Ok(peer) => peer, - Err(_) => { - if let Ok(peer) = manager.fetch_peer(true) { - peer - } else { - continue; - } - } - }; - - println!("Send hello to peer {:?}", peer.peer_address); - let mut sender = sender.lock().await; - let status = sender.send_async(&peer.peer_address, b"Hello Peer.").await; - println!("Send hello status: {:?}", status); - } -} - -#[embassy_executor::task] -async fn broadcaster(sender: &'static Mutex>) { - let mut ticker = Ticker::every(Duration::from_secs(1)); - loop { - ticker.next().await; - - println!("Send Broadcast..."); - let mut sender = sender.lock().await; - let status = sender.send_async(&BROADCAST_ADDRESS, b"Hello.").await; - println!("Send broadcast status: {:?}", status); - } -} - -#[embassy_executor::task] -async fn listener(manager: &'static EspNowManager<'static>, mut receiver: EspNowReceiver<'static>) { - loop { - let r = receiver.receive_async().await; - println!("Received {:?}", r.get_data()); - if r.info.dst_address == BROADCAST_ADDRESS { - if !manager.peer_exists(&r.info.src_address) { - manager - .add_peer(PeerInfo { - peer_address: r.info.src_address, - lmk: None, - channel: None, - encrypt: false, - }) - .unwrap(); - println!("Added peer {:?}", r.info.src_address); - } - } - } -} diff --git a/esp-wifi/examples/esp_now.rs b/esp-wifi/examples/esp_now.rs deleted file mode 100644 index 8bd58068..00000000 --- a/esp-wifi/examples/esp_now.rs +++ /dev/null @@ -1,78 +0,0 @@ -#![no_std] -#![no_main] - -use esp_backtrace as _; -use esp_println::println; -use esp_wifi::esp_now::{PeerInfo, BROADCAST_ADDRESS}; -use esp_wifi::{current_millis, initialize, EspWifiInitFor}; -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut esp_now = esp_wifi::esp_now::EspNow::new(&init, wifi).unwrap(); - - println!("esp-now version {}", esp_now.get_version().unwrap()); - - let mut next_send_time = current_millis() + 5 * 1000; - loop { - let r = esp_now.receive(); - if let Some(r) = r { - println!("Received {:?}", r); - - if r.info.dst_address == BROADCAST_ADDRESS { - if !esp_now.peer_exists(&r.info.src_address) { - esp_now - .add_peer(PeerInfo { - peer_address: r.info.src_address, - lmk: None, - channel: None, - encrypt: false, - }) - .unwrap(); - } - let status = esp_now - .send(&r.info.src_address, b"Hello Peer") - .unwrap() - .wait(); - println!("Send hello to peer status: {:?}", status); - } - } - - if current_millis() >= next_send_time { - next_send_time = current_millis() + 5 * 1000; - println!("Send"); - let status = esp_now - .send(&BROADCAST_ADDRESS, b"0123456789") - .unwrap() - .wait(); - println!("Send broadcast status: {:?}", status) - } - } -} diff --git a/esp-wifi/examples/static_ip.rs b/esp-wifi/examples/static_ip.rs deleted file mode 100644 index eeb7df0f..00000000 --- a/esp-wifi/examples/static_ip.rs +++ /dev/null @@ -1,198 +0,0 @@ -#![no_std] -#![no_main] - -#[path = "../../examples-util/util.rs"] -mod examples_util; -use examples_util::hal; - -use embedded_io::*; -use esp_wifi::wifi::{AccessPointInfo, ClientConfiguration, Configuration}; - -use esp_backtrace as _; -use esp_println::{print, println}; -use esp_wifi::initialize; -use esp_wifi::wifi::WifiStaDevice; -use esp_wifi::wifi::{utils::create_network_interface, WifiError}; -use esp_wifi::wifi_interface::WifiStack; -use esp_wifi::{current_millis, EspWifiInitFor}; -use hal::clock::ClockControl; -use hal::rng::Rng; -use hal::{peripherals::Peripherals, prelude::*}; - -use smoltcp::iface::SocketStorage; - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); -const STATIC_IP: &str = env!("STATIC_IP"); -const GATEWAY_IP: &str = env!("GATEWAY_IP"); - -#[entry] -fn main() -> ! { - #[cfg(feature = "log")] - esp_println::logger::init_logger(log::LevelFilter::Info); - - let peripherals = Peripherals::take(); - - let system = peripherals.SYSTEM.split(); - let clocks = ClockControl::max(system.clock_control).freeze(); - - #[cfg(target_arch = "xtensa")] - let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks, None).timer0; - #[cfg(target_arch = "riscv32")] - let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0; - let init = initialize( - EspWifiInitFor::Wifi, - timer, - Rng::new(peripherals.RNG), - system.radio_clock_control, - &clocks, - ) - .unwrap(); - - let wifi = peripherals.WIFI; - let mut socket_set_entries: [SocketStorage; 3] = Default::default(); - let (iface, device, mut controller, sockets) = - create_network_interface(&init, wifi, WifiStaDevice, &mut socket_set_entries).unwrap(); - let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis); - - let client_config = Configuration::Client(ClientConfiguration { - ssid: SSID.try_into().unwrap(), - password: PASSWORD.try_into().unwrap(), - ..Default::default() - }); - let res = controller.set_configuration(&client_config); - println!("wifi_set_configuration returned {:?}", res); - - controller.start().unwrap(); - println!("is wifi started: {:?}", controller.is_started()); - - println!("Start Wifi Scan"); - let res: Result<(heapless::Vec, usize), WifiError> = controller.scan_n(); - if let Ok((res, _count)) = res { - for ap in res { - println!("{:?}", ap); - } - } - - println!("{:?}", controller.get_capabilities()); - println!("wifi_connect {:?}", controller.connect()); - - // wait to get connected - println!("Wait to get connected"); - loop { - let res = controller.is_connected(); - match res { - Ok(connected) => { - if connected { - break; - } - } - Err(err) => { - println!("{:?}", err); - loop {} - } - } - } - println!("{:?}", controller.is_connected()); - - println!("Setting static IP {}", STATIC_IP); - - wifi_stack - .set_iface_configuration(&esp_wifi::wifi::ipv4::Configuration::Client( - esp_wifi::wifi::ipv4::ClientConfiguration::Fixed( - esp_wifi::wifi::ipv4::ClientSettings { - ip: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip(STATIC_IP)), - subnet: esp_wifi::wifi::ipv4::Subnet { - gateway: esp_wifi::wifi::ipv4::Ipv4Addr::from(parse_ip(GATEWAY_IP)), - mask: esp_wifi::wifi::ipv4::Mask(24), - }, - dns: None, - secondary_dns: None, - }, - ), - )) - .unwrap(); - - println!( - "Start busy loop on main. Point your browser to http://{}:8080/", - STATIC_IP - ); - - let mut rx_buffer = [0u8; 1536]; - let mut tx_buffer = [0u8; 1536]; - let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); - - socket.listen(8080).unwrap(); - - loop { - socket.work(); - - if !socket.is_open() { - socket.listen(8080).unwrap(); - } - - if socket.is_connected() { - println!("Connected"); - - let mut time_out = false; - let wait_end = current_millis() + 20 * 1000; - let mut buffer = [0u8; 1024]; - let mut pos = 0; - loop { - if let Ok(len) = socket.read(&mut buffer[pos..]) { - let to_print = - unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; - - if to_print.contains("\r\n\r\n") { - print!("{}", to_print); - println!(); - break; - } - - pos += len; - } else { - break; - } - - if current_millis() > wait_end { - println!("Timeout"); - time_out = true; - break; - } - } - - if !time_out { - socket.write_all( - b"HTTP/1.0 200 OK\r\n\r\n\ - \ - \ -

Hello Rust! Hello esp-wifi!

\ - - \ - \r\n\ - " - ).unwrap(); - - socket.flush().unwrap(); - } - - socket.close(); - - println!("Done\n"); - println!(); - } - - let wait_end = current_millis() + 5 * 1000; - while current_millis() < wait_end { - socket.work(); - } - } -} - -fn parse_ip(ip: &str) -> [u8; 4] { - let mut result = [0u8; 4]; - for (idx, octet) in ip.split(".").into_iter().enumerate() { - result[idx] = u8::from_str_radix(octet, 10).unwrap(); - } - result -} diff --git a/esp-wifi/src/ble/btdm.rs b/esp-wifi/src/ble/btdm.rs deleted file mode 100644 index 02d933d7..00000000 --- a/esp-wifi/src/ble/btdm.rs +++ /dev/null @@ -1,614 +0,0 @@ -use core::{cell::RefCell, ptr::addr_of}; - -use critical_section::Mutex; -use portable_atomic::{AtomicBool, Ordering}; - -use crate::ble::btdm::ble_os_adapter_chip_specific::{osi_funcs_s, G_OSI_FUNCS}; -use crate::ble::HciOutCollector; -use crate::ble::HCI_OUT_COLLECTOR; -use crate::hal::macros::ram; -use crate::{ - binary::include::*, - compat::{common::str_from_c, queue::SimpleQueue, task_runner::spawn_task}, - memory_fence::memory_fence, - timer::yield_task, -}; - -#[cfg_attr(esp32c3, path = "os_adapter_esp32c3.rs")] -#[cfg_attr(esp32s3, path = "os_adapter_esp32s3.rs")] -#[cfg_attr(esp32, path = "os_adapter_esp32.rs")] -pub(crate) mod ble_os_adapter_chip_specific; - -static BT_RECEIVE_QUEUE: Mutex>> = - Mutex::new(RefCell::new(SimpleQueue::new())); - -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct ReceivedPacket { - pub len: u8, - pub data: [u8; 256], -} - -static BT_INTERNAL_QUEUE: Mutex>> = - Mutex::new(RefCell::new(SimpleQueue::new())); - -static PACKET_SENT: AtomicBool = AtomicBool::new(true); - -#[repr(C)] -struct vhci_host_callback_s { - notify_host_send_available: extern "C" fn(), /* callback used to notify that the host can send packet to controller */ - notify_host_recv: extern "C" fn(*mut u8, u16) -> i32, /* callback used to notify that the controller has a packet to send to the host */ -} - -extern "C" { - fn btdm_osi_funcs_register(osi_funcs: *const osi_funcs_s) -> i32; - fn btdm_controller_get_compile_version() -> *const u8; - - #[cfg(any(esp32c3, esp32s3))] - fn btdm_controller_init(config_opts: *const esp_bt_controller_config_t) -> i32; - - #[cfg(esp32)] - fn btdm_controller_init( - config_mask: u32, - config_opts: *const esp_bt_controller_config_t, - ) -> i32; - - fn btdm_controller_enable(mode: esp_bt_mode_t); - - fn API_vhci_host_check_send_available() -> bool; - fn API_vhci_host_send_packet(data: *const u8, len: u16); - fn API_vhci_host_register_callback(vhci_host_callbac: *const vhci_host_callback_s) -> i32; -} - -static VHCI_HOST_CALLBACK: vhci_host_callback_s = vhci_host_callback_s { - notify_host_send_available: notify_host_send_available, - notify_host_recv: notify_host_recv, -}; - -extern "C" fn notify_host_send_available() { - trace!("notify_host_send_available"); - - PACKET_SENT.store(true, Ordering::Relaxed); -} - -extern "C" fn notify_host_recv(data: *mut u8, len: u16) -> i32 { - trace!("notify_host_recv {:?} {}", data, len); - - unsafe { - let mut buf = [0u8; 256]; - buf[..len as usize].copy_from_slice(&core::slice::from_raw_parts(data, len as usize)); - - let packet = ReceivedPacket { - len: len as u8, - data: buf, - }; - - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - if queue.enqueue(packet).is_err() { - warn!("Dropping BLE packet"); - } - }); - - dump_packet_info(&core::slice::from_raw_parts( - data as *const u8, - len as usize, - )); - - #[cfg(feature = "async")] - crate::ble::controller::asynch::hci_read_data_available(); - } - - 0 -} - -#[cfg(target_arch = "riscv32")] -static mut G_INTER_FLAGS: [u8; 10] = [0; 10]; - -#[cfg(target_arch = "xtensa")] -static mut G_INTER_FLAGS: [u32; 10] = [0; 10]; - -static mut INTERRUPT_DISABLE_CNT: usize = 0; - -#[ram] -unsafe extern "C" fn interrupt_enable() { - INTERRUPT_DISABLE_CNT -= 1; - let flags = G_INTER_FLAGS[INTERRUPT_DISABLE_CNT]; - trace!("interrupt_enable {}", flags); - critical_section::release(core::mem::transmute(flags)); -} - -#[ram] -unsafe extern "C" fn interrupt_disable() { - trace!("interrupt_disable"); - let flags = core::mem::transmute(critical_section::acquire()); - G_INTER_FLAGS[INTERRUPT_DISABLE_CNT] = flags; - INTERRUPT_DISABLE_CNT += 1; - trace!("interrupt_disable {}", flags); -} - -#[ram] -unsafe extern "C" fn task_yield() { - todo!(); -} - -unsafe extern "C" fn task_yield_from_isr() { - todo!(); -} - -unsafe extern "C" fn semphr_create(max: u32, init: u32) -> *const () { - crate::common_adapter::semphr_create(max, init) as *const () -} - -unsafe extern "C" fn semphr_delete(sem: *const ()) { - crate::common_adapter::semphr_delete(sem as *mut crate::binary::c_types::c_void); -} - -unsafe extern "C" fn semphr_take(sem: *const (), block_time_ms: u32) -> i32 { - crate::common_adapter::semphr_take(sem as *mut crate::binary::c_types::c_void, block_time_ms) -} - -unsafe extern "C" fn semphr_give(sem: *const ()) -> i32 { - crate::common_adapter::semphr_give(sem as *mut crate::binary::c_types::c_void) -} - -unsafe extern "C" fn mutex_create() -> *const () { - todo!(); -} - -unsafe extern "C" fn mutex_delete(_mutex: *const ()) { - todo!(); -} - -unsafe extern "C" fn mutex_lock(_mutex: *const ()) -> i32 { - todo!(); -} - -unsafe extern "C" fn mutex_unlock(_mutex: *const ()) -> i32 { - todo!(); -} - -unsafe extern "C" fn queue_create(len: u32, item_size: u32) -> *const () { - if len != 5 && item_size != 8 { - panic!("Unexpected queue spec {} {}", len, item_size); - } - &BT_INTERNAL_QUEUE as *const _ as *const () -} - -unsafe extern "C" fn queue_delete(queue: *const ()) { - trace!("Unimplemented queue_delete {:?}", queue); -} - -#[ram] -unsafe extern "C" fn queue_send(queue: *const (), item: *const (), _block_time_ms: u32) -> i32 { - if queue == &BT_INTERNAL_QUEUE as *const _ as *const () { - critical_section::with(|_| { - // assume the size is 8 - shouldn't rely on that - let message = item as *const u8; - let mut data = [0u8; 8]; - for i in 0..8 as usize { - data[i] = *(message.offset(i as isize)); - } - trace!("queue posting {:?}", data); - - critical_section::with(|cs| { - let mut queue = BT_INTERNAL_QUEUE.borrow_ref_mut(cs); - unwrap!(queue.enqueue(data)); - }); - memory_fence(); - }); - } else { - panic!("Unknown queue"); - } - 1 -} - -#[ram] -unsafe extern "C" fn queue_send_from_isr( - _queue: *const (), - _item: *const (), - _hptw: *const (), -) -> i32 { - trace!("queue_send_from_isr {:?} {:?} {:?}", _queue, _item, _hptw); - // Force to set the value to be false - *(_hptw as *mut bool) = false; - queue_send(_queue, _item, 0) -} - -unsafe extern "C" fn queue_recv(queue: *const (), item: *const (), block_time_ms: u32) -> i32 { - trace!( - "queue_recv {:?} item {:?} block_time_tick {}", - queue, - item, - block_time_ms - ); - - let forever = block_time_ms == OSI_FUNCS_TIME_BLOCKING; - let start = crate::timer::get_systimer_count(); - let block_ticks = crate::timer::millis_to_ticks(block_time_ms as u64); - - // handle the BT_QUEUE - if queue == &BT_INTERNAL_QUEUE as *const _ as *const () { - loop { - let res = critical_section::with(|_| { - memory_fence(); - - critical_section::with(|cs| { - let mut queue = BT_INTERNAL_QUEUE.borrow_ref_mut(cs); - if let Some(message) = queue.dequeue() { - let item = item as *mut u8; - for i in 0..8 { - item.offset(i).write_volatile(message[i as usize]); - } - trace!("received {:?}", message); - 1 - } else { - 0 - } - }) - }); - - if res == 1 { - trace!("queue_recv returns"); - return res; - } - - if !forever && crate::timer::elapsed_time_since(start) > block_ticks { - trace!("queue_recv returns with timeout"); - return -1; - } - - yield_task(); - } - } else { - panic!("Unknown queue to handle in queue_recv"); - } -} - -#[ram] -unsafe extern "C" fn queue_recv_from_isr( - _queue: *const (), - _item: *const (), - _hptw: *const (), -) -> i32 { - todo!(); -} - -unsafe extern "C" fn task_create( - func: *mut crate::binary::c_types::c_void, - name: *const u8, - stack_depth: u32, - param: *mut crate::binary::c_types::c_void, - prio: u32, - handle: *mut crate::binary::c_types::c_void, - core_id: u32, -) -> i32 { - let n = str_from_c(name); - trace!( - "task_create {:?} {:?} {} {} {:?} {} {:?} {}", - func, - name, - n, - stack_depth, - param, - prio, - handle, - core_id - ); - - *(handle as *mut usize) = 0; // we will run it in task 0 - - if spawn_task( - func, - name as *const i8, - stack_depth, - param, - prio, - handle, - core_id, - ) { - 1 - } else { - 0 - } -} - -unsafe extern "C" fn task_delete(_task: *const ()) { - todo!(); -} - -#[ram] -unsafe extern "C" fn is_in_isr() -> i32 { - 0 -} - -#[ram] -unsafe extern "C" fn cause_sw_intr_to_core(_core: i32, _intr_no: i32) -> i32 { - #[cfg(any(esp32c3, esp32s3))] - todo!("cause_sw_intr_to_core is not implemented for this target"); - - #[cfg(esp32)] - { - trace!("cause_sw_intr_to_core {} {}", _core, _intr_no); - let intr = 1 << _intr_no; - core::arch::asm!("wsr.intset {0}", in(reg) intr, options(nostack)); - 0 - } -} - -#[allow(unused)] -#[ram] -unsafe extern "C" fn srand(seed: u32) { - debug!("!!!! unimplemented srand {}", seed); -} - -#[allow(unused)] -#[ram] -unsafe extern "C" fn rand() -> i32 { - trace!("rand"); - crate::common_adapter::random() as i32 -} - -#[ram] -unsafe extern "C" fn btdm_lpcycles_2_hus(_cycles: u32, _error_corr: u32) -> u32 { - todo!(); -} - -#[ram] -unsafe extern "C" fn btdm_hus_2_lpcycles(us: u32) -> u32 { - const RTC_CLK_CAL_FRACT: u32 = 19; - let g_btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; - let g_btdm_lpcycle_us = 2 << (g_btdm_lpcycle_us_frac); - - // Converts a duration in half us into a number of low power clock cycles. - let cycles: u64 = (us as u64) << (g_btdm_lpcycle_us_frac as u64 / g_btdm_lpcycle_us as u64); - debug!("*** NOT implemented btdm_hus_2_lpcycles {} {}", us, cycles); - // probably not right ... NX returns half of the values we calculate here - - cycles as u32 -} - -unsafe extern "C" fn btdm_sleep_check_duration(_slot_cnt: i32) -> i32 { - todo!(); -} - -unsafe extern "C" fn btdm_sleep_enter_phase1(_lpcycles: i32) { - todo!(); -} - -unsafe extern "C" fn btdm_sleep_enter_phase2() { - todo!(); -} - -unsafe extern "C" fn btdm_sleep_exit_phase1() { - todo!(); -} - -unsafe extern "C" fn btdm_sleep_exit_phase2() { - todo!(); -} - -unsafe extern "C" fn btdm_sleep_exit_phase3() { - todo!(); -} - -unsafe extern "C" fn coex_schm_status_bit_set(_typ: i32, status: i32) { - debug!("coex_schm_status_bit_set {} {}", _typ, status); - #[cfg(coex)] - crate::binary::include::coex_schm_status_bit_set(_typ as u32, status as u32); -} - -unsafe extern "C" fn coex_schm_status_bit_clear(_typ: i32, status: i32) { - debug!("coex_schm_status_bit_clear {} {}", _typ, status); - #[cfg(coex)] - crate::binary::include::coex_schm_status_bit_clear(_typ as u32, status as u32); -} - -#[ram] -unsafe extern "C" fn read_efuse_mac(mac: *const ()) -> i32 { - crate::common_adapter::read_mac(mac as *mut _, 2) -} - -#[cfg(esp32)] -unsafe extern "C" fn set_isr13(n: i32, handler: unsafe extern "C" fn(), arg: *const ()) -> i32 { - ble_os_adapter_chip_specific::set_isr(n, handler, arg) -} - -#[cfg(esp32)] -unsafe extern "C" fn interrupt_l3_disable() { - // info!("unimplemented interrupt_l3_disable"); -} - -#[cfg(esp32)] -unsafe extern "C" fn interrupt_l3_restore() { - // info!("unimplemented interrupt_l3_restore"); -} - -#[cfg(esp32)] -unsafe extern "C" fn custom_queue_create( - _len: u32, - _item_size: u32, -) -> *mut crate::binary::c_types::c_void { - todo!(); -} - -pub(crate) fn ble_init() { - unsafe { - *(HCI_OUT_COLLECTOR.as_mut_ptr()) = HciOutCollector::new(); - // turn on logging - #[cfg(feature = "wifi-logs")] - { - extern "C" { - static mut g_bt_plf_log_level: u32; - } - - debug!("g_bt_plf_log_level = {}", g_bt_plf_log_level); - g_bt_plf_log_level = 10; - } - - // esp32_bt_controller_init - ble_os_adapter_chip_specific::btdm_controller_mem_init(); - - let mut cfg = ble_os_adapter_chip_specific::create_ble_config(); - - let res = btdm_osi_funcs_register(addr_of!(G_OSI_FUNCS)); - if res != 0 { - panic!("btdm_osi_funcs_register returned {}", res); - } - - #[cfg(coex)] - { - let res = crate::wifi::coex_init(); - if res != 0 { - panic!("got error"); - } - } - - let version = btdm_controller_get_compile_version(); - let version_str = str_from_c(version); - debug!("BT controller compile version {}", version_str); - - ble_os_adapter_chip_specific::bt_periph_module_enable(); - - ble_os_adapter_chip_specific::disable_sleep_mode(); - - #[cfg(any(esp32c3, esp32s3))] - let res = btdm_controller_init(&mut cfg as *mut esp_bt_controller_config_t); - - #[cfg(esp32)] - let res = btdm_controller_init( - (1 << 3) | (1 << 4), - &mut cfg as *mut esp_bt_controller_config_t, - ); // see btdm_config_mask_load for mask - - if res != 0 { - panic!("btdm_controller_init returned {}", res); - } - - debug!("The btdm_controller_init was initialized"); - - #[cfg(coex)] - crate::binary::include::coex_enable(); - - crate::common_adapter::chip_specific::phy_enable(); - - #[cfg(esp32)] - { - extern "C" { - fn btdm_rf_bb_init_phase2(); - } - - btdm_rf_bb_init_phase2(); - coex_bt_high_prio(); - } - - #[cfg(coex)] - coex_enable(); - - btdm_controller_enable(esp_bt_mode_t_ESP_BT_MODE_BLE); - - API_vhci_host_register_callback(&VHCI_HOST_CALLBACK); - } -} - -static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256]; -static mut BLE_HCI_READ_DATA_INDEX: usize = 0; -static mut BLE_HCI_READ_DATA_LEN: usize = 0; - -#[cfg(feature = "async")] -pub fn have_hci_read_data() -> bool { - critical_section::with(|cs| { - let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - !queue.is_empty() - || unsafe { - BLE_HCI_READ_DATA_LEN > 0 && (BLE_HCI_READ_DATA_LEN >= BLE_HCI_READ_DATA_INDEX) - } - }) -} - -pub(crate) fn read_next(data: &mut [u8]) -> usize { - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - - match queue.dequeue() { - Some(packet) => { - data[..packet.len as usize].copy_from_slice(&packet.data[..packet.len as usize]); - packet.len as usize - } - None => 0, - } - }) -} - -pub fn read_hci(data: &mut [u8]) -> usize { - unsafe { - if BLE_HCI_READ_DATA_LEN == 0 { - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - - if let Some(packet) = queue.dequeue() { - BLE_HCI_READ_DATA[..packet.len as usize] - .copy_from_slice(&packet.data[..packet.len as usize]); - BLE_HCI_READ_DATA_LEN = packet.len as usize; - BLE_HCI_READ_DATA_INDEX = 0; - } - }); - } - - if BLE_HCI_READ_DATA_LEN > 0 { - data[0] = BLE_HCI_READ_DATA[BLE_HCI_READ_DATA_INDEX]; - BLE_HCI_READ_DATA_INDEX += 1; - - if BLE_HCI_READ_DATA_INDEX >= BLE_HCI_READ_DATA_LEN { - BLE_HCI_READ_DATA_LEN = 0; - BLE_HCI_READ_DATA_INDEX = 0; - } - return 1; - } - } - - 0 -} - -pub fn send_hci(data: &[u8]) { - let hci_out = unsafe { &mut *HCI_OUT_COLLECTOR.as_mut_ptr() }; - hci_out.push(data); - - if hci_out.is_ready() { - let packet = hci_out.packet(); - - unsafe { - loop { - let can_send = API_vhci_host_check_send_available(); - - if !can_send { - trace!("can_send is false"); - continue; - } - - PACKET_SENT.store(false, Ordering::Relaxed); - API_vhci_host_send_packet(packet.as_ptr() as *const u8, packet.len() as u16); - trace!("sent vhci host packet"); - - dump_packet_info(packet); - - break; - } - - // make sure the packet buffer doesn't get touched until sent - while !PACKET_SENT.load(Ordering::Relaxed) {} - } - - hci_out.reset(); - } -} - -#[allow(unreachable_code, unused_variables)] -fn dump_packet_info(buffer: &[u8]) { - #[cfg(not(feature = "dump-packets"))] - return; - - critical_section::with(|cs| { - info!("@HCIFRAME {:?}", buffer); - }); -} diff --git a/esp-wifi/src/ble/controller/mod.rs b/esp-wifi/src/ble/controller/mod.rs deleted file mode 100644 index 9d2f0c86..00000000 --- a/esp-wifi/src/ble/controller/mod.rs +++ /dev/null @@ -1,177 +0,0 @@ -use embedded_io::{Error, ErrorType, Read, Write}; - -use crate::hal::peripheral::{Peripheral, PeripheralRef}; -use crate::EspWifiInitialization; - -use super::{read_hci, read_next, send_hci}; - -/// A blocking HCI connector -pub struct BleConnector<'d> { - _device: PeripheralRef<'d, crate::hal::peripherals::BT>, -} - -impl<'d> BleConnector<'d> { - pub fn new( - init: &EspWifiInitialization, - device: impl Peripheral

+ 'd, - ) -> BleConnector<'d> { - if !init.is_ble() { - panic!("Not initialized for BLE use"); - } - - Self { - _device: device.into_ref(), - } - } - - pub fn get_next(&mut self, buf: &mut [u8]) -> Result { - Ok(read_next(buf)) - } -} - -#[derive(Debug)] -pub enum BleConnectorError { - Unknown, -} - -impl Error for BleConnectorError { - fn kind(&self) -> embedded_io::ErrorKind { - embedded_io::ErrorKind::Other - } -} - -impl ErrorType for BleConnector<'_> { - type Error = BleConnectorError; -} - -impl Read for BleConnector<'_> { - fn read(&mut self, buf: &mut [u8]) -> Result { - let mut total = 0; - for b in buf { - let mut buffer = [0u8]; - let len = read_hci(&mut buffer); - - if len == 1 { - *b = buffer[0]; - total += 1; - } else { - return Ok(total); - } - } - - Ok(total) - } -} - -impl Write for BleConnector<'_> { - fn write(&mut self, buf: &[u8]) -> Result { - for b in buf { - send_hci(&[*b]); - } - Ok(buf.len()) - } - - fn flush(&mut self) -> Result<(), Self::Error> { - // nothing to do - Ok(()) - } -} - -/// Async Interface -#[cfg(feature = "async")] -pub mod asynch { - use core::task::Poll; - - use crate::ble::ble::have_hci_read_data; - use crate::EspWifiInitialization; - - use super::BleConnectorError; - use super::{read_hci, send_hci}; - use crate::hal::peripheral::{Peripheral, PeripheralRef}; - use embassy_sync::waitqueue::AtomicWaker; - use embedded_io::ErrorType; - - static HCI_WAKER: AtomicWaker = AtomicWaker::new(); - - pub(crate) fn hci_read_data_available() { - HCI_WAKER.wake(); - } - - /// Async HCI connector - pub struct BleConnector<'d> { - _device: PeripheralRef<'d, crate::hal::peripherals::BT>, - } - - impl<'d> BleConnector<'d> { - pub fn new( - init: &EspWifiInitialization, - device: impl Peripheral

+ 'd, - ) -> BleConnector<'d> { - if !init.is_ble() { - panic!("Not initialized for BLE use"); - } - - Self { - _device: device.into_ref(), - } - } - } - - impl ErrorType for BleConnector<'_> { - type Error = BleConnectorError; - } - - impl embedded_io_async::Read for BleConnector<'_> { - async fn read(&mut self, buf: &mut [u8]) -> Result { - if !have_hci_read_data() { - HciReadyEventFuture.await; - } - - let mut total = 0; - for b in buf { - let mut buffer = [0u8]; - let len = read_hci(&mut buffer); - - if len == 1 { - *b = buffer[0]; - total += 1; - } else { - return Ok(total); - } - } - - Ok(total) - } - } - - impl embedded_io_async::Write for BleConnector<'_> { - async fn write(&mut self, buf: &[u8]) -> Result { - send_hci(buf); - Ok(buf.len()) - } - - async fn flush(&mut self) -> Result<(), BleConnectorError> { - // nothing to do - Ok(()) - } - } - - pub(crate) struct HciReadyEventFuture; - - impl core::future::Future for HciReadyEventFuture { - type Output = (); - - fn poll( - self: core::pin::Pin<&mut Self>, - cx: &mut core::task::Context<'_>, - ) -> Poll { - HCI_WAKER.register(cx.waker()); - - if have_hci_read_data() { - Poll::Ready(()) - } else { - Poll::Pending - } - } - } -} diff --git a/esp-wifi/src/ble/mod.rs b/esp-wifi/src/ble/mod.rs deleted file mode 100644 index c676064a..00000000 --- a/esp-wifi/src/ble/mod.rs +++ /dev/null @@ -1,101 +0,0 @@ -//! Bluetooth Low Energy HCI interface - -#[cfg(any(esp32, esp32c3, esp32s3))] -pub(crate) mod btdm; - -#[cfg(any(esp32c2, esp32c6, esp32h2))] -pub(crate) mod npl; - -use core::mem::MaybeUninit; - -#[cfg(any(esp32, esp32c3, esp32s3))] -use self::btdm as ble; - -#[cfg(any(esp32c2, esp32c6, esp32h2))] -use self::npl as ble; - -pub(crate) use ble::ble_init; -pub(crate) use ble::read_hci; -pub(crate) use ble::read_next; -pub(crate) use ble::send_hci; - -pub mod controller; - -pub(crate) unsafe extern "C" fn malloc(size: u32) -> *mut crate::binary::c_types::c_void { - crate::compat::malloc::malloc(size as usize).cast() -} - -#[cfg(any(esp32, esp32c3, esp32s3))] -pub(crate) unsafe extern "C" fn malloc_internal(size: u32) -> *mut crate::binary::c_types::c_void { - crate::compat::malloc::malloc(size as usize).cast() -} - -pub(crate) unsafe extern "C" fn free(ptr: *mut crate::binary::c_types::c_void) { - crate::compat::malloc::free(ptr.cast()) -} - -static mut HCI_OUT_COLLECTOR: MaybeUninit = MaybeUninit::uninit(); - -#[derive(PartialEq, Debug)] -enum HciOutType { - Unknown, - Acl, - Command, -} - -struct HciOutCollector { - data: [u8; 256], - index: usize, - ready: bool, - kind: HciOutType, -} - -impl HciOutCollector { - fn new() -> HciOutCollector { - HciOutCollector { - data: [0u8; 256], - index: 0, - ready: false, - kind: HciOutType::Unknown, - } - } - - fn is_ready(&self) -> bool { - self.ready - } - - fn push(&mut self, data: &[u8]) { - self.data[self.index..(self.index + data.len())].copy_from_slice(data); - self.index += data.len(); - - if self.kind == HciOutType::Unknown { - self.kind = match self.data[0] { - 1 => HciOutType::Command, - 2 => HciOutType::Acl, - _ => HciOutType::Unknown, - }; - } - - if !self.ready { - if self.kind == HciOutType::Command && self.index >= 4 { - if self.index == self.data[3] as usize + 4 { - self.ready = true; - } - } else if self.kind == HciOutType::Acl && self.index >= 5 { - if self.index == (self.data[3] as usize) + ((self.data[4] as usize) << 8) + 5 { - self.ready = true; - } - } - } - } - - fn reset(&mut self) { - self.index = 0; - self.ready = false; - self.kind = HciOutType::Unknown; - } - - fn packet(&self) -> &[u8] { - &self.data[0..(self.index as usize)] - } -} diff --git a/esp-wifi/src/ble/npl.rs b/esp-wifi/src/ble/npl.rs deleted file mode 100644 index bc05d396..00000000 --- a/esp-wifi/src/ble/npl.rs +++ /dev/null @@ -1,1416 +0,0 @@ -use core::{ - cell::RefCell, - ptr::{addr_of, addr_of_mut}, -}; - -use critical_section::Mutex; - -use super::*; -use crate::binary::c_types::{c_char, c_void}; -use crate::binary::include::*; -use crate::compat; -use crate::compat::common::str_from_c; -use crate::compat::queue::SimpleQueue; -use crate::compat::task_runner::spawn_task; -use crate::timer::yield_task; - -#[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")] -#[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")] -#[cfg_attr(esp32h2, path = "os_adapter_esp32h2.rs")] -pub(crate) mod ble_os_adapter_chip_specific; - -const TIME_FOREVER: u32 = u32::MAX; - -#[cfg(esp32c2)] -const OS_MSYS_1_BLOCK_COUNT: i32 = 24; -#[cfg(esp32c2)] -const SYSINIT_MSYS_1_MEMPOOL_SIZE: usize = 768; -#[cfg(esp32c2)] -const SYSINIT_MSYS_1_MEMBLOCK_SIZE: i32 = 128; -#[cfg(esp32c2)] -const OS_MSYS_2_BLOCK_COUNT: i32 = 24; -#[cfg(esp32c2)] -const SYSINIT_MSYS_2_MEMPOOL_SIZE: usize = 1920; -#[cfg(esp32c2)] -const SYSINIT_MSYS_2_MEMBLOCK_SIZE: i32 = 320; - -const BLE_HCI_TRANS_BUF_CMD: i32 = 3; - -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -const ACL_DATA_MBUF_LEADINGSPACE: usize = 4; - -#[derive(Copy, Clone)] -struct Callout { - _callout: *const ble_npl_callout, - eventq: *const ble_npl_eventq, - timer_handle: ets_timer, - events: ble_npl_event, -} - -static mut CALLOUTS: [Option; 18] = [None; 18]; - -#[derive(Copy, Clone)] -struct Event { - event: *const ble_npl_event, - event_fn_ptr: *const ble_npl_event_fn, - ev_arg_ptr: *const c_void, - queued: bool, -} - -static mut EVENTS: [Option; 95] = [None; 95]; - -static mut EVENT_QUEUE: SimpleQueue = SimpleQueue::new(); - -static BT_RECEIVE_QUEUE: Mutex>> = - Mutex::new(RefCell::new(SimpleQueue::new())); - -#[cfg(esp32c2)] -type OsMembufT = u32; - -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct ReceivedPacket { - pub len: u8, - pub data: [u8; 256], -} - -/** - * Memory pool - */ -#[repr(C)] -pub(crate) struct OsMempool { - /** Size of the memory blocks, in bytes. */ - mp_block_size: u32, - /** The number of memory blocks. */ - mp_num_blocks: u16, - /** The number of free blocks left */ - mp_num_free: u16, - /** The lowest number of free blocks seen */ - mp_min_free: u16, - /** Bitmap of OS_MEMPOOL_F_[...] values. */ - mp_flags: u8, - /** Address of memory buffer used by pool */ - mp_membuf_addr: u32, - - //STAILQ_ENTRY(os_mempool) mp_list; - next: *const OsMempool, - - //SLIST_HEAD(,os_memblock); - first: *const c_void, - - /** Name for memory block */ - name: *const u8, -} - -#[cfg(esp32c2)] -impl OsMempool { - const fn zeroed() -> Self { - Self { - mp_block_size: 0, - mp_num_blocks: 0, - mp_num_free: 0, - mp_min_free: 0, - mp_flags: 0, - mp_membuf_addr: 0, - next: core::ptr::null(), - first: core::ptr::null(), - name: core::ptr::null(), - } - } -} - -/** - * A mbuf pool from which to allocate mbufs. This contains a pointer to the os - * mempool to allocate mbufs out of, the total number of elements in the pool, - * and the amount of "user" data in a non-packet header mbuf. The total pool - * size, in bytes, should be: - * os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf)) - */ -#[repr(C)] -pub(crate) struct OsMbufPool { - /** - * Total length of the databuf in each mbuf. This is the size of the - * mempool block, minus the mbuf header - */ - omp_databuf_len: u16, - /** - * The memory pool which to allocate mbufs out of - */ - omp_pool: *const OsMempool, - - //STAILQ_ENTRY(os_mbuf_pool) omp_next; - next: *const OsMbufPool, -} - -#[cfg(esp32c2)] -impl OsMbufPool { - const fn zeroed() -> Self { - Self { - omp_databuf_len: 0, - omp_pool: core::ptr::null(), - next: core::ptr::null(), - } - } -} - -/** - * Chained memory buffer. - */ -#[repr(C)] -pub struct OsMbuf { - /** - * Current pointer to data in the structure - */ - om_data: *const u8, - /** - * Flags associated with this buffer, see OS_MBUF_F_* defintions - */ - om_flags: u8, - /** - * Length of packet header - */ - om_pkthdr_len: u8, - /** - * Length of data in this buffer - */ - om_len: u16, - - /** - * The mbuf pool this mbuf was allocated out of - */ - om_omp: *const OsMbufPool, - - //SLIST_ENTRY(os_mbuf) om_next; - next: *const OsMbuf, - - /** - * Pointer to the beginning of the data, after this buffer - */ - om_databuf: u32, -} - -#[repr(C)] -pub struct OsMempoolExt { - mpe_mp: OsMempool, - - /* Callback that is executed immediately when a block is freed. */ - mpe_put_cb: OsMempoolPutFn, - mpe_put_arg: *const c_void, -} - -type OsMempoolPutFn = Option< - unsafe extern "C" fn(ome: *const OsMempoolExt, data: *const c_void, arg: *const c_void) -> i32, ->; - -#[repr(C)] -pub struct BleHciTransFuncsT { - ble_hci_trans_hs_acl_tx: Option i32>, - ble_hci_trans_hs_cmd_tx: Option i32>, - ble_hci_trans_ll_acl_tx: Option i32>, - ble_hci_trans_ll_evt_tx: Option i32>, - ble_hci_trans_reset: Option i32>, - ble_hci_trans_set_acl_free_cb: - Option i32>, -} - -#[cfg(esp32c2)] -pub(crate) static mut OS_MSYS_INIT_1_DATA: *mut OsMembufT = core::ptr::null_mut(); -#[cfg(esp32c2)] -pub(crate) static mut OS_MSYS_INIT_1_MBUF_POOL: OsMbufPool = OsMbufPool::zeroed(); -#[cfg(esp32c2)] -pub(crate) static mut OS_MSYS_INIT_1_MEMPOOL: OsMempool = OsMempool::zeroed(); - -#[cfg(esp32c2)] -pub(crate) static mut OS_MSYS_INIT_2_DATA: *mut OsMembufT = core::ptr::null_mut(); -#[cfg(esp32c2)] -pub(crate) static mut OS_MSYS_INIT_2_MBUF_POOL: OsMbufPool = OsMbufPool::zeroed(); -#[cfg(esp32c2)] -pub(crate) static mut OS_MSYS_INIT_2_MEMPOOL: OsMempool = OsMempool::zeroed(); - -extern "C" { - static ble_hci_trans_funcs_ptr: &'static BleHciTransFuncsT; - - #[cfg(esp32c2)] - static mut r_ble_stub_funcs_ptr: *mut u32; - - pub(crate) fn ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32; - - pub(crate) fn ble_controller_enable(mode: u8) -> i32; - - pub(crate) fn esp_register_ext_funcs(funcs: *const ext_funcs_t) -> i32; - - pub(crate) fn esp_register_npl_funcs(funcs: *const npl_funcs_t) -> i32; - - pub(crate) fn ble_get_npl_element_info( - cfg: *const esp_bt_controller_config_t, - npl_info: *const ble_npl_count_info_t, - ) -> i32; - - pub(crate) fn bt_bb_v2_init_cmplx(value: u8); - - pub(crate) fn r_ble_hci_trans_cfg_hs( - evt: Option, // ble_hci_trans_rx_cmd_fn - evt_arg: *const c_void, - acl_cb: Option, // ble_hci_trans_rx_acl_fn - acl_arg: *const c_void, - ); - - pub(crate) fn esp_ble_ll_set_public_addr(addr: *const u8); - - #[cfg(esp32c2)] - pub(crate) fn r_mem_init_mbuf_pool( - mem: *const c_void, - mempool: *const OsMempool, - mbuf_pool: *const OsMbufPool, - num_blocks: i32, - block_size: i32, - name: *const u8, - ) -> i32; - - #[cfg(esp32c2)] - pub(crate) fn r_os_msys_reset(); - - #[cfg(esp32c2)] - pub(crate) fn r_os_msys_register(mbuf_pool: *const OsMbufPool) -> i32; - - #[allow(unused)] - pub(crate) fn ble_osi_coex_funcs_register(coex_funcs: *const osi_coex_funcs_t) -> i32; - - pub(crate) fn r_os_msys_get_pkthdr(dsize: u16, user_hdr_len: u16) -> *mut OsMbuf; - - pub(crate) fn r_os_mbuf_append(om: *mut OsMbuf, src: *const u8, len: u16) -> i32; - - pub(crate) fn r_os_mbuf_free_chain(om: *mut OsMbuf) -> i32; - - pub(crate) fn r_ble_hci_trans_buf_alloc(typ: i32) -> *const u8; - - pub(crate) fn r_ble_hci_trans_buf_free(buf: *const u8); - - static mut ble_hci_trans_env_p: u32; -} - -#[repr(C)] -pub struct ext_funcs_t { - ext_version: u32, - esp_intr_alloc: Option< - unsafe extern "C" fn( - source: u32, - flags: u32, - handler: *mut c_void, - arg: *mut c_void, - ret_handle: *mut *mut c_void, - ) -> i32, - >, - esp_intr_free: Option i32>, - malloc: Option *mut c_void>, - free: Option, - hal_uart_start_tx: Option, - hal_uart_init_cbs: Option< - unsafe extern "C" fn(i32, *const c_void, *const c_void, *const c_void, c_void) -> i32, - >, - hal_uart_config: Option i32>, - hal_uart_close: Option i32>, - hal_uart_blocking_tx: Option, - hal_uart_init: Option i32>, - task_create: Option< - unsafe extern "C" fn( - *const c_void, - *const c_char, - u32, - *const c_void, - u32, - *const c_void, - u32, - ) -> i32, - >, - task_delete: Option, - osi_assert: Option, - os_random: Option u32>, - ecc_gen_key_pair: Option i32>, - ecc_gen_dh_key: Option i32>, - esp_reset_rpa_moudle: Option, - #[cfg(esp32c2)] - esp_bt_track_pll_cap: Option, - magic: u32, -} - -static G_OSI_FUNCS: ext_funcs_t = ext_funcs_t { - ext_version: 0x20221122, - esp_intr_alloc: Some(self::ble_os_adapter_chip_specific::esp_intr_alloc), - esp_intr_free: Some(esp_intr_free), - malloc: Some(crate::ble::malloc), - free: Some(crate::ble::free), - hal_uart_start_tx: None, - hal_uart_init_cbs: None, - hal_uart_config: None, - hal_uart_close: None, - hal_uart_blocking_tx: None, - hal_uart_init: None, - task_create: Some(task_create), - task_delete: Some(task_delete), - osi_assert: Some(osi_assert), - os_random: Some(os_random), - ecc_gen_key_pair: Some(ecc_gen_key_pair), - ecc_gen_dh_key: Some(ecc_gen_dh_key), - esp_reset_rpa_moudle: Some(self::ble_os_adapter_chip_specific::esp_reset_rpa_moudle), - #[cfg(esp32c2)] - esp_bt_track_pll_cap: None, - magic: 0xA5A5A5A5, -}; - -unsafe extern "C" fn ecc_gen_dh_key(_: *const u8, _: *const u8, _: *const u8, _: *const u8) -> i32 { - todo!() -} - -unsafe extern "C" fn ecc_gen_key_pair(_: *const u8, _: *const u8) -> i32 { - todo!() -} - -unsafe extern "C" fn os_random() -> u32 { - trace!("os_random"); - (crate::common_adapter::random() & u32::MAX) as u32 -} - -unsafe extern "C" fn task_create( - task_func: *const c_void, - name: *const c_char, - stack_depth: u32, - param: *const c_void, - prio: u32, - task_handle: *const c_void, - core_id: u32, -) -> i32 { - let name_str = str_from_c(name as *const u8); - trace!( - "task_create {:?} {} {} {:?} {} {:?} {}", - task_func, - name_str, - stack_depth, - param, - prio, - task_handle, - core_id, - ); - - *(task_handle as *mut usize) = 0; // we will run it in task 0 - - if spawn_task( - task_func as *mut c_void, - name as *const c_char, - stack_depth, - param as *mut c_void, - prio, - task_handle as *mut c_void, - core_id, - ) { - 1 - } else { - 0 - } -} - -unsafe extern "C" fn task_delete(_: *const c_void) { - todo!(); -} - -unsafe extern "C" fn osi_assert(ln: u32, fn_name: *const c_void, param1: u32, param2: u32) { - let name_str = str_from_c(fn_name as *const u8); - panic!("ASSERT {}:{} {} {}", name_str, ln, param1, param2); -} - -unsafe extern "C" fn esp_intr_free(_ret_handle: *mut *mut c_void) -> i32 { - todo!(); -} - -#[repr(C)] -pub struct npl_funcs_t { - p_ble_npl_os_started: Option bool>, - p_ble_npl_get_current_task_id: Option *const c_void>, - p_ble_npl_eventq_init: Option, - p_ble_npl_eventq_deinit: Option, - p_ble_npl_eventq_get: Option< - unsafe extern "C" fn( - queue: *const ble_npl_eventq, - time: ble_npl_time_t, - ) -> *const ble_npl_event, - >, - p_ble_npl_eventq_put: - Option, - p_ble_npl_eventq_remove: - Option, - p_ble_npl_event_run: Option, - p_ble_npl_eventq_is_empty: Option bool>, - p_ble_npl_event_init: Option< - unsafe extern "C" fn( - event: *const ble_npl_event, - func: *const ble_npl_event_fn, - *const c_void, - ), - >, - p_ble_npl_event_deinit: Option, - p_ble_npl_event_reset: Option, - p_ble_npl_event_is_queued: Option bool>, - p_ble_npl_event_get_arg: - Option *const c_void>, - p_ble_npl_event_set_arg: - Option, - p_ble_npl_mutex_init: - Option ble_npl_error_t>, - p_ble_npl_mutex_deinit: - Option ble_npl_error_t>, - p_ble_npl_mutex_pend: Option< - unsafe extern "C" fn(mutex: *const ble_npl_mutex, time: ble_npl_time_t) -> ble_npl_error_t, - >, - p_ble_npl_mutex_release: - Option ble_npl_error_t>, - p_ble_npl_sem_init: - Option ble_npl_error_t>, - p_ble_npl_sem_deinit: Option ble_npl_error_t>, - p_ble_npl_sem_pend: Option< - unsafe extern "C" fn(sem: *const ble_npl_sem, time: ble_npl_time_t) -> ble_npl_error_t, - >, - p_ble_npl_sem_release: Option ble_npl_error_t>, - p_ble_npl_sem_get_count: Option u16>, - p_ble_npl_callout_init: Option< - unsafe extern "C" fn( - callout: *const ble_npl_callout, - eventq: *const ble_npl_eventq, - func: *const ble_npl_event_fn, - args: *const c_void, - ) -> i32, - >, - p_ble_npl_callout_reset: Option< - unsafe extern "C" fn( - callout: *const ble_npl_callout, - time: ble_npl_time_t, - ) -> ble_npl_error_t, - >, - p_ble_npl_callout_stop: Option, - p_ble_npl_callout_deinit: Option, - p_ble_npl_callout_mem_reset: Option, - p_ble_npl_callout_is_active: - Option bool>, - p_ble_npl_callout_get_ticks: - Option ble_npl_time_t>, - p_ble_npl_callout_remaining_ticks: - Option u32>, - p_ble_npl_callout_set_arg: - Option, - p_ble_npl_time_get: Option u32>, - p_ble_npl_time_ms_to_ticks: - Option ble_npl_error_t>, - p_ble_npl_time_ticks_to_ms: - Option ble_npl_error_t>, - p_ble_npl_time_ms_to_ticks32: Option ble_npl_time_t>, - p_ble_npl_time_ticks_to_ms32: Option u32>, - p_ble_npl_time_delay: Option, - p_ble_npl_hw_set_isr: Option, - p_ble_npl_hw_enter_critical: Option u32>, - p_ble_npl_hw_exit_critical: Option, - p_ble_npl_get_time_forever: Option u32>, - p_ble_npl_hw_is_in_critical: Option u8>, -} - -static mut G_NPL_FUNCS: npl_funcs_t = npl_funcs_t { - p_ble_npl_os_started: Some(ble_npl_os_started), - p_ble_npl_get_current_task_id: Some(ble_npl_get_current_task_id), - p_ble_npl_eventq_init: Some(ble_npl_eventq_init), - p_ble_npl_eventq_deinit: Some(ble_npl_eventq_deinit), - p_ble_npl_eventq_get: Some(ble_npl_eventq_get), - p_ble_npl_eventq_put: Some(ble_npl_eventq_put), - p_ble_npl_eventq_remove: Some(ble_npl_eventq_remove), - p_ble_npl_event_run: Some(ble_npl_event_run), - p_ble_npl_eventq_is_empty: Some(ble_npl_eventq_is_empty), - p_ble_npl_event_init: Some(ble_npl_event_init), - p_ble_npl_event_deinit: Some(ble_npl_event_deinit), - p_ble_npl_event_reset: Some(ble_npl_event_reset), - p_ble_npl_event_is_queued: Some(ble_npl_event_is_queued), - p_ble_npl_event_get_arg: Some(ble_npl_event_get_arg), - p_ble_npl_event_set_arg: Some(ble_npl_event_set_arg), - p_ble_npl_mutex_init: Some(ble_npl_mutex_init), - p_ble_npl_mutex_deinit: Some(ble_npl_mutex_deinit), - p_ble_npl_mutex_pend: Some(ble_npl_mutex_pend), - p_ble_npl_mutex_release: Some(ble_npl_mutex_release), - p_ble_npl_sem_init: Some(ble_npl_sem_init), - p_ble_npl_sem_deinit: Some(ble_npl_sem_deinit), - p_ble_npl_sem_pend: Some(ble_npl_sem_pend), - p_ble_npl_sem_release: Some(ble_npl_sem_release), - p_ble_npl_sem_get_count: Some(ble_npl_sem_get_count), - p_ble_npl_callout_init: Some(ble_npl_callout_init), - p_ble_npl_callout_reset: Some(ble_npl_callout_reset), - p_ble_npl_callout_stop: Some(ble_npl_callout_stop), - p_ble_npl_callout_deinit: Some(ble_npl_callout_deinit), - p_ble_npl_callout_mem_reset: Some(ble_npl_callout_mem_reset), - p_ble_npl_callout_is_active: Some(ble_npl_callout_is_active), - p_ble_npl_callout_get_ticks: Some(ble_npl_callout_get_ticks), - p_ble_npl_callout_remaining_ticks: Some(ble_npl_callout_remaining_ticks), - p_ble_npl_callout_set_arg: Some(ble_npl_callout_set_arg), - p_ble_npl_time_get: Some(ble_npl_time_get), - p_ble_npl_time_ms_to_ticks: Some(ble_npl_time_ms_to_ticks), - p_ble_npl_time_ticks_to_ms: Some(ble_npl_time_ticks_to_ms), - p_ble_npl_time_ms_to_ticks32: Some(ble_npl_time_ms_to_ticks32), - p_ble_npl_time_ticks_to_ms32: Some(ble_npl_time_ticks_to_ms32), - p_ble_npl_time_delay: Some(ble_npl_time_delay), - p_ble_npl_hw_set_isr: Some(ble_npl_hw_set_isr), - p_ble_npl_hw_enter_critical: Some(ble_npl_hw_enter_critical), - p_ble_npl_hw_exit_critical: Some(ble_npl_hw_exit_critical), - p_ble_npl_get_time_forever: Some(ble_npl_get_time_forever), - p_ble_npl_hw_is_in_critical: Some(ble_npl_hw_is_in_critical), -}; - -#[repr(C)] -pub struct osi_coex_funcs_t { - magic: u32, - version: u32, - coex_wifi_sleep_set: Option, - coex_core_ble_conn_dyn_prio_get: - Option i32>, - coex_schm_status_bit_set: Option, - coex_schm_status_bit_clear: Option, -} - -#[allow(unused)] -static G_COEX_FUNCS: osi_coex_funcs_t = osi_coex_funcs_t { - magic: 0xFADEBEAD, - version: 0x00010006, - coex_wifi_sleep_set: Some(coex_wifi_sleep_set), - coex_core_ble_conn_dyn_prio_get: Some(coex_core_ble_conn_dyn_prio_get), - coex_schm_status_bit_set: Some(coex_schm_status_bit_set), - coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear), -}; - -#[allow(unused)] -unsafe extern "C" fn coex_wifi_sleep_set(_sleep: bool) { - todo!() -} - -#[allow(unused)] -unsafe extern "C" fn coex_core_ble_conn_dyn_prio_get(_low: *mut bool, _high: *mut bool) -> i32 { - todo!() -} - -#[allow(unused)] -unsafe extern "C" fn coex_schm_status_bit_set(_type: u32, _status: u32) { - trace!("coex_schm_status_bit_set is an empty stub"); -} - -#[allow(unused)] -unsafe extern "C" fn coex_schm_status_bit_clear(_type: u32, _status: u32) { - trace!("coex_schm_status_bit_clear is an empty stub"); -} - -unsafe extern "C" fn ble_npl_hw_is_in_critical() -> u8 { - todo!() -} - -unsafe extern "C" fn ble_npl_get_time_forever() -> u32 { - trace!("ble_npl_get_time_forever"); - TIME_FOREVER -} - -unsafe extern "C" fn ble_npl_hw_exit_critical(mask: u32) { - trace!("ble_npl_hw_exit_critical {}", mask); - critical_section::release(core::mem::transmute(mask as u8)); -} - -unsafe extern "C" fn ble_npl_hw_enter_critical() -> u32 { - trace!("ble_npl_hw_enter_critical"); - let as_u8: u8 = core::mem::transmute(critical_section::acquire()); - as_u8 as u32 -} - -unsafe extern "C" fn ble_npl_hw_set_isr(_no: i32, _mask: u32) { - todo!() -} - -unsafe extern "C" fn ble_npl_time_delay(_time: ble_npl_time_t) { - todo!() -} - -unsafe extern "C" fn ble_npl_time_ticks_to_ms32(_time: ble_npl_time_t) -> u32 { - todo!() -} - -unsafe extern "C" fn ble_npl_time_ms_to_ticks32(ms: u32) -> ble_npl_time_t { - trace!("ble_npl_time_ms_to_ticks32 {}", ms); - ms -} - -unsafe extern "C" fn ble_npl_time_ticks_to_ms( - _time: ble_npl_time_t, - _p_ms: *const u32, -) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_time_ms_to_ticks( - _ms: u32, - _p_time: *const ble_npl_time_t, -) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_time_get() -> u32 { - trace!("ble_npl_time_get"); - crate::current_millis() as u32 -} - -unsafe extern "C" fn ble_npl_callout_set_arg( - _callout: *const ble_npl_callout, - _arg: *const c_void, -) { - todo!() -} - -unsafe extern "C" fn ble_npl_callout_remaining_ticks( - _callout: *const ble_npl_callout, - _time: ble_npl_time_t, -) -> u32 { - todo!() -} - -unsafe extern "C" fn ble_npl_callout_get_ticks(_callout: *const ble_npl_callout) -> ble_npl_time_t { - todo!() -} - -unsafe extern "C" fn ble_npl_callout_is_active(_callout: *const ble_npl_callout) -> bool { - todo!() -} - -unsafe extern "C" fn ble_npl_callout_mem_reset(callout: *const ble_npl_callout) { - trace!("ble_npl_callout_mem_reset"); - - ble_npl_callout_stop(callout); -} - -unsafe extern "C" fn ble_npl_callout_deinit(callout: *const ble_npl_callout) { - trace!("ble_npl_callout_deinit"); - - ble_npl_callout_stop(callout); -} - -unsafe extern "C" fn ble_npl_callout_stop(callout: *const ble_npl_callout) { - trace!("ble_npl_callout_stop {:?}", callout); - - if (*callout).dummy == 0 { - panic!("Trying to stop an uninitialzed callout"); - } - - let co = unwrap!(CALLOUTS[((*callout).dummy - 1) as usize].as_mut()); - - // stop timer - compat::timer_compat::compat_timer_disarm(addr_of_mut!(co.timer_handle)); -} - -unsafe extern "C" fn ble_npl_callout_reset( - callout: *const ble_npl_callout, - time: ble_npl_time_t, -) -> ble_npl_error_t { - trace!("ble_npl_callout_reset {:?} {}", callout, time); - - let co = unwrap!(CALLOUTS[((*callout).dummy - 1) as usize].as_mut()); - - // start timer - compat::timer_compat::compat_timer_arm(addr_of_mut!(co.timer_handle), time, false); - - 0 -} - -unsafe extern "C" fn ble_npl_sem_get_count(_sem: *const ble_npl_sem) -> u16 { - todo!() -} - -unsafe extern "C" fn ble_npl_sem_release(_sem: *const ble_npl_sem) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_sem_pend( - _sem: *const ble_npl_sem, - _time: ble_npl_time_t, -) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_sem_deinit(_sem: *const ble_npl_sem) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_sem_init(_sem: *const ble_npl_sem, _val: u16) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_mutex_release(_mutex: *const ble_npl_mutex) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_mutex_pend( - _mutex: *const ble_npl_mutex, - _time: ble_npl_time_t, -) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_mutex_deinit(_mutex: *const ble_npl_mutex) -> ble_npl_error_t { - todo!() -} - -unsafe extern "C" fn ble_npl_event_set_arg(event: *const ble_npl_event, arg: *const c_void) { - trace!("ble_npl_event_set_arg {:?} {:?}", event, arg); - if (*event).dummy == 0 { - panic!("Call set_arg on uninitialized event"); - } - - unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()).ev_arg_ptr = arg; -} - -unsafe extern "C" fn ble_npl_event_get_arg(event: *const ble_npl_event) -> *const c_void { - trace!("ble_npl_event_get_arg {:?}", event); - if (*event).dummy == 0 { - panic!("Call get_arg on uninitialized event"); - } - - let arg_ptr = unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()).ev_arg_ptr; - - trace!("returning arg {:x}", arg_ptr as usize); - - arg_ptr -} - -unsafe extern "C" fn ble_npl_event_is_queued(event: *const ble_npl_event) -> bool { - trace!("ble_npl_event_is_queued {:?}", event); - if (*event).dummy == 0 { - panic!("Call is_queued on uninitialized event"); - } - - unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()).queued -} - -unsafe extern "C" fn ble_npl_event_reset(event: *const ble_npl_event) { - trace!("ble_npl_event_reset {:?}", event); - - let event = event as *mut ble_npl_event; - if (*event).dummy == 0 { - panic!("Trying to reset an uninitialized event"); - } else { - unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()).queued = false; - } -} - -unsafe extern "C" fn ble_npl_event_deinit(_event: *const ble_npl_event) { - todo!() -} - -unsafe extern "C" fn ble_npl_event_init( - event: *const ble_npl_event, - func: *const ble_npl_event_fn, - arg: *const c_void, -) { - trace!("ble_npl_event_init {:?} {:?} {:?}", event, func, arg); - - if (*event).dummy == 0 { - let idx = unwrap!(EVENTS.iter().position(|item| item.is_none())); - EVENTS[idx] = Some(Event { - event, - event_fn_ptr: func, - ev_arg_ptr: arg, - queued: false, - }); - - let event = event.cast_mut(); - (*event).dummy = (idx + 1) as i32; - } -} - -unsafe extern "C" fn ble_npl_eventq_is_empty(queue: *const ble_npl_eventq) -> bool { - trace!("ble_npl_eventq_is_empty {:?}", queue); - - if (*queue).dummy == 0 { - panic!("Try to use uninitialized queue"); - } - - critical_section::with(|_| EVENT_QUEUE.is_empty()) -} - -unsafe extern "C" fn ble_npl_event_run(event: *const ble_npl_event) { - trace!("ble_npl_event_run {:?}", event); - - let event = event as *mut ble_npl_event; - if (*event).dummy == 0 { - panic!("Trying to run an uninitialized event"); - } else { - let ev = unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()); - trace!("info {:?} with arg {:x}", ev.event_fn_ptr, event as u32); - let func: unsafe extern "C" fn(u32) = core::mem::transmute(ev.event_fn_ptr); - func(event as u32); - } - - trace!("ble_npl_event_run done"); -} - -unsafe extern "C" fn ble_npl_eventq_remove( - queue: *const ble_npl_eventq, - event: *const ble_npl_event, -) { - trace!("ble_npl_eventq_remove {:?} {:?}", queue, event); - - if (*queue).dummy == 0 { - panic!("Try to use uninitialized queue"); - } - - if (*event).dummy == 0 { - panic!("Try to use uninitialized event"); - } - - critical_section::with(|_| { - unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()).queued = false; - }); -} - -unsafe extern "C" fn ble_npl_eventq_put(queue: *const ble_npl_eventq, event: *const ble_npl_event) { - trace!("ble_npl_eventq_put {:?} {:?}", queue, event); - - if (*queue).dummy == 0 { - panic!("Try to use uninitialized queue"); - } - - if (*event).dummy == 0 { - panic!("Try to use uninitialized event"); - } - - critical_section::with(|_| { - unwrap!(EVENTS[((*event).dummy - 1) as usize].as_mut()).queued = true; - unwrap!(EVENT_QUEUE.enqueue((*event).dummy as usize)); - }); -} - -unsafe extern "C" fn ble_npl_eventq_get( - queue: *const ble_npl_eventq, - time: ble_npl_time_t, -) -> *const ble_npl_event { - trace!("ble_npl_eventq_get {:?} {}", queue, time); - - if time == TIME_FOREVER { - loop { - let dequeued = critical_section::with(|_| EVENT_QUEUE.dequeue()); - - if let Some(event_idx) = dequeued { - let evt = unwrap!(EVENTS[event_idx - 1].as_mut()); - if evt.queued { - trace!("got {:x}", evt.event as usize); - evt.queued = false; - return evt.event; - } - } - - yield_task(); - } - } else { - panic!("timed eventq_get not yet supported - go implement it!"); - } -} - -unsafe extern "C" fn ble_npl_eventq_deinit(_queue: *const ble_npl_eventq) { - todo!() -} - -unsafe extern "C" fn ble_npl_callout_init( - callout: *const ble_npl_callout, - eventq: *const ble_npl_eventq, - func: *const ble_npl_event_fn, - args: *const c_void, -) -> i32 { - trace!( - "ble_npl_callout_init {:?} {:?} {:?} {:?}", - callout, - eventq, - func, - args - ); - - if (*callout).dummy == 0 { - let callout = callout.cast_mut(); - let idx = unwrap!(CALLOUTS.iter().position(|item| item.is_none())); - - let new_callout = CALLOUTS[idx].insert(Callout { - _callout: callout, - eventq, - timer_handle: ets_timer { - next: core::ptr::null_mut(), - expire: 0, - period: 0, - func: None, - priv_: core::ptr::null_mut(), - }, - events: ble_npl_event { dummy: 0 }, - }); - - ble_npl_event_init(addr_of_mut!(new_callout.events), func, args); - - crate::compat::timer_compat::compat_timer_setfn( - addr_of_mut!(new_callout.timer_handle), - callout_timer_callback_wrapper, - idx as *mut c_void, - ); - - (*callout).dummy = (idx + 1) as i32; - } - - 0 -} - -unsafe extern "C" fn callout_timer_callback_wrapper(arg: *mut c_void) { - info!("callout_timer_callback_wrapper {:?}", arg); - let co = unwrap!(CALLOUTS[arg as usize].as_mut()); - - if co.eventq.is_null() { - ble_npl_eventq_put(addr_of!(co.events).cast(), addr_of!(co.events)); - } else { - ble_npl_event_run(addr_of!(co.events)); - } -} - -unsafe extern "C" fn ble_npl_eventq_init(queue: *const ble_npl_eventq) { - trace!("ble_npl_eventq_init {:?}", queue); - - critical_section::with(|_cs| { - let queue = queue as *mut ble_npl_eventq; - - if (*queue).dummy == 0 { - (*queue).dummy = 1; - } else { - panic!("Only one emulated queue supported"); - } - }); -} - -unsafe extern "C" fn ble_npl_mutex_init(_mutex: *const ble_npl_mutex) -> u32 { - todo!() -} - -unsafe extern "C" fn ble_npl_get_current_task_id() -> *const c_void { - todo!() -} - -unsafe extern "C" fn ble_npl_os_started() -> bool { - todo!(); -} - -#[repr(C)] -pub struct ble_npl_count_info_t { - evt_count: u16, - evtq_count: u16, - co_count: u16, - sem_count: u16, - mutex_count: u16, -} - -pub(crate) fn ble_init() { - unsafe { - *(HCI_OUT_COLLECTOR.as_mut_ptr()) = HciOutCollector::new(); - - // turn on logging - #[cfg(feature = "wifi-logs")] - { - extern "C" { - static mut g_ble_plf_log_level: u32; - } - - debug!("g_ble_plf_log_level = {}", g_ble_plf_log_level); - g_ble_plf_log_level = 10; - } - - self::ble_os_adapter_chip_specific::ble_rtc_clk_init(); - - let cfg = ble_os_adapter_chip_specific::BLE_CONFIG; - - let res = esp_register_ext_funcs(&G_OSI_FUNCS as *const ext_funcs_t); - if res != 0 { - panic!("esp_register_ext_funcs returned {}", res); - } - - #[cfg(coex)] - { - let res = crate::wifi::coex_init(); - if res != 0 { - panic!("got error"); - } - } - - ble_os_adapter_chip_specific::bt_periph_module_enable(); - - ble_os_adapter_chip_specific::disable_sleep_mode(); - - let res = esp_register_npl_funcs(core::ptr::addr_of!(G_NPL_FUNCS)); - if res != 0 { - panic!("esp_register_npl_funcs returned {}", res); - } - - let npl_info = ble_npl_count_info_t { - evt_count: 0, - evtq_count: 0, - co_count: 0, - sem_count: 0, - mutex_count: 0, - }; - let res = ble_get_npl_element_info( - &cfg as *const esp_bt_controller_config_t, - &npl_info as *const ble_npl_count_info_t, - ); - if res != 0 { - panic!("ble_get_npl_element_info returned {}", res); - } - // not really using npl_info here ... remove it? - - #[cfg(esp32c2)] - { - // Initialize the global memory pool - let ret = os_msys_buf_alloc(); - if !ret { - panic!("os_msys_buf_alloc failed"); - } - - os_msys_init(); - } - - crate::common_adapter::chip_specific::phy_enable(); - - // init bb - bt_bb_v2_init_cmplx(1); - - #[cfg(coex)] - { - let rc = ble_osi_coex_funcs_register(&G_COEX_FUNCS as *const osi_coex_funcs_t); - if rc != 0 { - panic!("ble_osi_coex_funcs_register returned {}", rc); - } - } - - let res = ble_controller_init(&cfg as *const esp_bt_controller_config_t); - - if res != 0 { - panic!("ble_controller_init returned {}", res); - } - - #[cfg(not(esp32c2))] - { - extern "C" { - fn esp_ble_msys_init( - msys_size1: u16, - msys_size2: u16, - msys_cnt1: u16, - msys_cnt2: u16, - from_heap: u8, - ) -> i32; - } - - let res = esp_ble_msys_init(256, 320, 12, 24, 1); - if res != 0 { - panic!("esp_ble_msys_init returned {}", res); - } - } - - #[cfg(coex)] - crate::binary::include::coex_enable(); - - let mut mac = [0u8; 6]; - crate::common_adapter::read_mac(mac.as_mut_ptr(), 2); - mac.reverse(); - - esp_ble_ll_set_public_addr(&mac as *const u8); - - r_ble_hci_trans_cfg_hs( - Some(ble_hs_hci_rx_evt), - core::ptr::null(), - Some(ble_hs_rx_data), - core::ptr::null(), - ); - - let res = ble_controller_enable(1); // 1 = BLE - if res != 0 { - panic!("ble_controller_enable returned {}", res); - } - - // "patch" r_ble_ll_random - it needs syscall_table_ptr - // probably long term we should rather initialize syscall_table_ptr - #[cfg(esp32c2)] - { - *(r_ble_stub_funcs_ptr.offset(0x7dc / 4)) = - self::ble_os_adapter_chip_specific::ble_ll_random_override as *const u32 as u32; - } - - // this is to avoid (ASSERT r_ble_hci_ram_hs_cmd_tx:34 0 0) - // r_ble_hci_trans_cfg_ll initializes ble_hci_trans_env_p + 0x34 - // it's called by r_ble_ll_task which is run in another task - // in r_ble_hci_ram_hs_cmd_tx this is checked for non-null - while (ble_hci_trans_env_p as *const u32) - .add(0x34 / 4) - .read_volatile() - == 0 - { - // wait - } - - debug!("The ble_controller_init was initialized"); - } -} - -#[cfg(esp32c2)] -fn os_msys_buf_alloc() -> bool { - unsafe { - OS_MSYS_INIT_1_DATA = crate::compat::malloc::calloc( - 1, - core::mem::size_of::() * SYSINIT_MSYS_1_MEMPOOL_SIZE as usize, - ) as *mut u32; - OS_MSYS_INIT_2_DATA = crate::compat::malloc::calloc( - 1, - core::mem::size_of::() * SYSINIT_MSYS_2_MEMPOOL_SIZE, - ) as *mut u32; - - !(OS_MSYS_INIT_1_DATA.is_null() || OS_MSYS_INIT_2_DATA.is_null()) - } -} - -#[cfg(esp32c2)] -fn os_msys_init() { - static MSYS1: &[u8] = b"msys_1\0"; - static MSYS2: &[u8] = b"msys_2\0"; - - unsafe { - r_os_msys_reset(); - - let rc = r_mem_init_mbuf_pool( - OS_MSYS_INIT_1_DATA as *const c_void, - addr_of!(OS_MSYS_INIT_1_MEMPOOL), - addr_of!(OS_MSYS_INIT_1_MBUF_POOL), - OS_MSYS_1_BLOCK_COUNT, - SYSINIT_MSYS_1_MEMBLOCK_SIZE, - MSYS1 as *const _ as *const u8, - ); - if rc != 0 { - panic!("r_mem_init_mbuf_pool failed"); - } - - let rc = r_os_msys_register(addr_of!(OS_MSYS_INIT_1_MBUF_POOL)); - if rc != 0 { - panic!("r_os_msys_register failed"); - } - - let rc = r_mem_init_mbuf_pool( - OS_MSYS_INIT_2_DATA as *const c_void, - addr_of!(OS_MSYS_INIT_2_MEMPOOL), - addr_of!(OS_MSYS_INIT_2_MBUF_POOL), - OS_MSYS_2_BLOCK_COUNT, - SYSINIT_MSYS_2_MEMBLOCK_SIZE, - MSYS2 as *const _ as *const u8, - ); - if rc != 0 { - panic!("r_mem_init_mbuf_pool failed"); - } - - let rc = r_os_msys_register(addr_of!(OS_MSYS_INIT_2_MBUF_POOL)); - if rc != 0 { - panic!("r_os_msys_register failed"); - } - } -} - -unsafe extern "C" fn ble_hs_hci_rx_evt(cmd: *const u8, arg: *const c_void) { - trace!("ble_hs_hci_rx_evt {:?} {:?}", cmd, arg); - debug!("$ cmd = {:x}", *cmd); - debug!("$ len = {:x}", *(cmd.offset(1))); - - let event = *cmd; - let len = *(cmd.offset(1)) as usize; - let payload = core::slice::from_raw_parts(cmd.offset(2), len); - debug!("$ pld = {:?}", payload); - - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - let mut data = [0u8; 256]; - - data[0] = 0x04; // this is an event - data[1] = event; - data[2] = len as u8; - data[3..][..len].copy_from_slice(payload); - - if queue - .enqueue(ReceivedPacket { - len: (len + 3) as u8, - data, - }) - .is_err() - { - warn!("Dropping BLE packet"); - } - - dump_packet_info(&data[..(len + 3) as usize]); - }); - - r_ble_hci_trans_buf_free(cmd); - - #[cfg(feature = "async")] - crate::ble::controller::asynch::hci_read_data_available(); -} - -unsafe extern "C" fn ble_hs_rx_data(om: *const OsMbuf, arg: *const c_void) { - trace!("ble_hs_rx_data {:?} {:?}", om, arg); - - let data_ptr = (*om).om_data; - let len = (*om).om_len; - let data_slice = core::slice::from_raw_parts(data_ptr, len as usize); - - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - let mut data = [0u8; 256]; - - data[0] = 0x02; // ACL - data[1..][..data_slice.len()].copy_from_slice(data_slice); - - if queue - .enqueue(ReceivedPacket { - len: (len + 1) as u8, - data, - }) - .is_err() - { - warn!("Dropping BLE packet"); - } - - dump_packet_info(&data[..(len + 1) as usize]); - }); - - r_os_mbuf_free_chain(om as *mut _); - - #[cfg(feature = "async")] - crate::ble::controller::asynch::hci_read_data_available(); -} - -static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256]; -static mut BLE_HCI_READ_DATA_INDEX: usize = 0; -static mut BLE_HCI_READ_DATA_LEN: usize = 0; - -#[cfg(feature = "async")] -pub fn have_hci_read_data() -> bool { - critical_section::with(|cs| { - let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - !queue.is_empty() - || unsafe { - BLE_HCI_READ_DATA_LEN > 0 && (BLE_HCI_READ_DATA_LEN >= BLE_HCI_READ_DATA_INDEX) - } - }) -} - -pub(crate) fn read_next(data: &mut [u8]) -> usize { - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - - match queue.dequeue() { - Some(packet) => { - data[..packet.len as usize].copy_from_slice(&packet.data[..packet.len as usize]); - packet.len as usize - } - None => 0, - } - }) -} - -pub fn read_hci(data: &mut [u8]) -> usize { - unsafe { - if BLE_HCI_READ_DATA_LEN == 0 { - critical_section::with(|cs| { - let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs); - - if let Some(packet) = queue.dequeue() { - BLE_HCI_READ_DATA[..packet.len as usize] - .copy_from_slice(&packet.data[..packet.len as usize]); - BLE_HCI_READ_DATA_LEN = packet.len as usize; - BLE_HCI_READ_DATA_INDEX = 0; - } - }); - } - - if BLE_HCI_READ_DATA_LEN > 0 { - data[0] = BLE_HCI_READ_DATA[BLE_HCI_READ_DATA_INDEX]; - BLE_HCI_READ_DATA_INDEX += 1; - - if BLE_HCI_READ_DATA_INDEX >= BLE_HCI_READ_DATA_LEN { - BLE_HCI_READ_DATA_LEN = 0; - BLE_HCI_READ_DATA_INDEX = 0; - } - return 1; - } - } - - 0 -} - -pub fn send_hci(data: &[u8]) { - let hci_out = unsafe { &mut *HCI_OUT_COLLECTOR.as_mut_ptr() }; - hci_out.push(data); - - if hci_out.is_ready() { - let packet = hci_out.packet(); - - unsafe { - loop { - const DATA_TYPE_COMMAND: u8 = 1; - const DATA_TYPE_ACL: u8 = 2; - - dump_packet_info(&packet); - - critical_section::with(|_cs| { - if packet[0] == DATA_TYPE_COMMAND { - let cmd = r_ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - core::ptr::copy_nonoverlapping( - &packet[1] as *const _ as *mut u8, // don't send the TYPE - cmd as *mut u8, - packet.len() - 1, - ); - - let res = unwrap!(ble_hci_trans_funcs_ptr.ble_hci_trans_hs_cmd_tx)(cmd); - - if res != 0 { - warn!("ble_hci_trans_hs_cmd_tx res == {}", res); - } - } else if packet[0] == DATA_TYPE_ACL { - let om = r_os_msys_get_pkthdr( - packet.len() as u16, - ACL_DATA_MBUF_LEADINGSPACE as u16, - ); - - let res = r_os_mbuf_append( - om, - packet.as_ptr().offset(1), - (packet.len() - 1) as u16, - ); - if res != 0 { - panic!("r_os_mbuf_append returned {}", res); - } - - // this modification of the ACL data packet makes it getting sent and received by the other side - *((*om).om_data as *mut u8).offset(1) = 0; - - let res = unwrap!(ble_hci_trans_funcs_ptr.ble_hci_trans_hs_acl_tx)(om); - if res != 0 { - panic!("ble_hci_trans_hs_acl_tx returned {}", res); - } - trace!("ACL tx done"); - } - }); - break; - } - } - - hci_out.reset(); - } -} - -#[allow(unreachable_code, unused_variables)] -fn dump_packet_info(buffer: &[u8]) { - #[cfg(not(feature = "dump-packets"))] - return; - - critical_section::with(|cs| { - info!("@HCIFRAME {:?}", buffer); - }); -} diff --git a/esp-wifi/src/ble/os_adapter_esp32.rs b/esp-wifi/src/ble/os_adapter_esp32.rs deleted file mode 100644 index 05272a9c..00000000 --- a/esp-wifi/src/ble/os_adapter_esp32.rs +++ /dev/null @@ -1,625 +0,0 @@ -use super::*; -use crate::binary::{ - c_types, - include::{ - esp_bt_controller_config_t, esp_bt_mode_t, esp_bt_mode_t_ESP_BT_MODE_BLE, - esp_bt_mode_t_ESP_BT_MODE_BTDM, esp_bt_mode_t_ESP_BT_MODE_CLASSIC_BT, - esp_bt_mode_t_ESP_BT_MODE_IDLE, - }, -}; - -use core::ptr::addr_of_mut; - -pub static mut ISR_INTERRUPT_5: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub static mut ISR_INTERRUPT_8: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub static mut ISR_INTERRUPT_7: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -#[repr(C)] -pub(super) struct osi_funcs_s { - version: u32, - set_isr: Option i32>, - ints_on: Option, - interrupt_disable: Option, - interrupt_restore: Option, - task_yield: Option, - task_yield_from_isr: Option, - semphr_create: Option *const ()>, - semphr_delete: Option, - semphr_take_from_isr: Option i32>, - semphr_give_from_isr: Option i32>, - semphr_take: Option i32>, - semphr_give: Option i32>, - mutex_create: Option *const ()>, - mutex_delete: Option, - mutex_lock: Option i32>, - mutex_unlock: Option i32>, - queue_create: Option *const ()>, - queue_delete: Option, - queue_send: Option i32>, - queue_send_from_isr: Option i32>, - queue_recv: Option i32>, - queue_recv_from_isr: Option i32>, - task_create: Option< - unsafe extern "C" fn( - *mut crate::binary::c_types::c_void, - *const u8, - u32, - *mut crate::binary::c_types::c_void, - u32, - *mut crate::binary::c_types::c_void, - u32, - ) -> i32, - >, - task_delete: Option, - is_in_isr: Option i32>, - cause_sw_intr_to_core: Option i32>, - malloc: Option *mut crate::binary::c_types::c_void>, - malloc_internal: Option *mut crate::binary::c_types::c_void>, - free: Option, - read_efuse_mac: Option i32>, - srand: Option, - rand: Option i32>, - btdm_lpcycles_2_hus: Option u32>, - btdm_hus_2_lpcycles: Option u32>, - btdm_sleep_check_duration: Option i32>, - btdm_sleep_enter_phase1: Option, - btdm_sleep_enter_phase2: Option, - btdm_sleep_exit_phase1: Option, - btdm_sleep_exit_phase2: Option, - btdm_sleep_exit_phase3: Option, - coex_bt_wakeup_request: Option bool>, - coex_bt_wakeup_request_end: Option, - coex_bt_request: Option i32>, - coex_bt_release: Option i32>, - coex_register_bt_cb: Option i32>, - coex_bb_reset_lock: Option u32>, - coex_bb_reset_unlock: Option, - coex_schm_register_btdm_callback: Option i32>, - coex_schm_status_bit_clear: Option, - coex_schm_status_bit_set: Option, - coex_schm_interval_get: Option u32>, - coex_schm_curr_period_get: Option u8>, - coex_schm_curr_phase_get: Option *const ()>, - coex_wifi_channel_get: Option i32>, - coex_register_wifi_channel_change_callback: - Option i32>, - set_isr13: Option i32>, - interrupt_l3_disable: Option, - interrupt_l3_restore: Option, - custom_queue_create: - Option *mut crate::binary::c_types::c_void>, - coex_version_get: Option< - unsafe extern "C" fn( - *mut crate::binary::c_types::c_uint, - *mut crate::binary::c_types::c_uint, - *mut crate::binary::c_types::c_uint, - ) -> crate::binary::c_types::c_int, - >, - magic: u32, -} - -pub(super) static G_OSI_FUNCS: osi_funcs_s = osi_funcs_s { - version: 0x00010004, - set_isr: Some(ble_os_adapter_chip_specific::set_isr), - ints_on: Some(ble_os_adapter_chip_specific::ints_on), - interrupt_disable: Some(interrupt_disable), - interrupt_restore: Some(interrupt_enable), - task_yield: Some(task_yield), - task_yield_from_isr: Some(task_yield_from_isr), - semphr_create: Some(semphr_create), - semphr_delete: Some(semphr_delete), - semphr_take_from_isr: Some(crate::common_adapter::semphr_take_from_isr), - semphr_give_from_isr: Some(crate::common_adapter::semphr_give_from_isr), - semphr_take: Some(semphr_take), - semphr_give: Some(semphr_give), - mutex_create: Some(mutex_create), - mutex_delete: Some(mutex_delete), - mutex_lock: Some(mutex_lock), - mutex_unlock: Some(mutex_unlock), - queue_create: Some(queue_create), - queue_delete: Some(queue_delete), - queue_send: Some(queue_send), - queue_send_from_isr: Some(queue_send_from_isr), - queue_recv: Some(queue_recv), - queue_recv_from_isr: Some(queue_recv_from_isr), - task_create: Some(task_create), - task_delete: Some(task_delete), - is_in_isr: Some(is_in_isr), - cause_sw_intr_to_core: Some(cause_sw_intr_to_core), - malloc: Some(crate::ble::malloc), - malloc_internal: Some(crate::ble::malloc_internal), - free: Some(crate::ble::free), - read_efuse_mac: Some(read_efuse_mac), - srand: Some(crate::ble::btdm::srand), - rand: Some(crate::ble::btdm::rand), - btdm_lpcycles_2_hus: Some(btdm_lpcycles_2_hus), - btdm_hus_2_lpcycles: Some(btdm_hus_2_lpcycles), - btdm_sleep_check_duration: Some(btdm_sleep_check_duration), - btdm_sleep_enter_phase1: Some(btdm_sleep_enter_phase1), - btdm_sleep_enter_phase2: Some(btdm_sleep_enter_phase2), - btdm_sleep_exit_phase1: Some(btdm_sleep_exit_phase1), - btdm_sleep_exit_phase2: Some(btdm_sleep_exit_phase2), - btdm_sleep_exit_phase3: Some(btdm_sleep_exit_phase3), - coex_bt_wakeup_request: Some(ble_os_adapter_chip_specific::coex_bt_wakeup_request), - coex_bt_wakeup_request_end: Some(ble_os_adapter_chip_specific::coex_bt_wakeup_request_end), - coex_bt_request: Some(ble_os_adapter_chip_specific::coex_bt_request), - coex_bt_release: Some(ble_os_adapter_chip_specific::coex_bt_release), - coex_register_bt_cb: Some(ble_os_adapter_chip_specific::coex_register_bt_cb_wrapper), - coex_bb_reset_lock: Some(ble_os_adapter_chip_specific::coex_bb_reset_lock), - coex_bb_reset_unlock: Some(ble_os_adapter_chip_specific::coex_bb_reset_unlock), - coex_schm_register_btdm_callback: Some( - ble_os_adapter_chip_specific::coex_schm_register_btdm_callback_wrapper, - ), - coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear), - coex_schm_status_bit_set: Some(coex_schm_status_bit_set), - coex_schm_interval_get: Some(ble_os_adapter_chip_specific::coex_schm_interval_get), - coex_schm_curr_period_get: Some(ble_os_adapter_chip_specific::coex_schm_curr_period_get), - coex_schm_curr_phase_get: Some(ble_os_adapter_chip_specific::coex_schm_curr_phase_get), - coex_wifi_channel_get: Some(ble_os_adapter_chip_specific::coex_wifi_channel_get), - coex_register_wifi_channel_change_callback: Some( - ble_os_adapter_chip_specific::coex_register_wifi_channel_change_callback, - ), - set_isr13: Some(set_isr13), - interrupt_l3_disable: Some(interrupt_l3_disable), - interrupt_l3_restore: Some(interrupt_l3_restore), - custom_queue_create: Some(custom_queue_create), - coex_version_get: Some(coex_version_get_wrapper), - magic: 0xfadebead, -}; - -extern "C" fn coex_version_get_wrapper(major: *mut u32, minor: *mut u32, patch: *mut u32) -> i32 { - unsafe { - let coex_version = unwrap!(core::ffi::CStr::from_ptr( - crate::binary::include::coex_version_get() - ) - .to_str() - .ok()); - info!("COEX Version {}", coex_version); - // we should parse it ... for now just hardcoded - major.write_volatile(1); - minor.write_volatile(2); - patch.write_volatile(0); - } - - 0 -} - -#[repr(C)] -struct btdm_dram_available_region_t { - mode: esp_bt_mode_t, - start: u32, // ptr - end: u32, // ptr -} - -const SOC_MEM_BT_DATA_START: u32 = 0x3ffae6e0; -const SOC_MEM_BT_DATA_END: u32 = 0x3ffaff10; -const SOC_MEM_BT_EM_BTDM0_START: u32 = 0x3ffb0000; -const SOC_MEM_BT_EM_BTDM0_END: u32 = 0x3ffb09a8; -const SOC_MEM_BT_EM_BLE_START: u32 = 0x3ffb09a8; -const SOC_MEM_BT_EM_BLE_END: u32 = 0x3ffb1ddc; -const SOC_MEM_BT_EM_BTDM1_START: u32 = 0x3ffb1ddc; -const SOC_MEM_BT_EM_BTDM1_END: u32 = 0x3ffb2730; -const SOC_MEM_BT_EM_BREDR_START: u32 = 0x3ffb2730; -const SOC_MEM_BT_BSS_START: u32 = 0x3ffb8000; -const SOC_MEM_BT_BSS_END: u32 = 0x3ffb9a20; -const SOC_MEM_BT_MISC_START: u32 = 0x3ffbdb28; -const SOC_MEM_BT_MISC_END: u32 = 0x3ffbdb5c; - -const SOC_MEM_BT_EM_BREDR_REAL_END: u32 = 0x3ffb6388; // (SOC_MEM_BT_EM_BREDR_NO_SYNC_END + CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF * SOC_MEM_BT_EM_PER_SYNC_SIZE); - -static BTDM_DRAM_AVAILABLE_REGION: [btdm_dram_available_region_t; 7] = [ - /* following is .data */ - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_BTDM, - start: SOC_MEM_BT_DATA_START, - end: SOC_MEM_BT_DATA_END, - }, - /* following is memory which HW will use */ - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_BTDM, - start: SOC_MEM_BT_EM_BTDM0_START, - end: SOC_MEM_BT_EM_BTDM0_END, - }, - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_BLE, - start: SOC_MEM_BT_EM_BLE_START, - end: SOC_MEM_BT_EM_BLE_END, - }, - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_BTDM, - start: SOC_MEM_BT_EM_BTDM1_START, - end: SOC_MEM_BT_EM_BTDM1_END, - }, - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_CLASSIC_BT, - start: SOC_MEM_BT_EM_BREDR_START, - end: SOC_MEM_BT_EM_BREDR_REAL_END, - }, - /* following is .bss */ - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_BTDM, - start: SOC_MEM_BT_BSS_START, - end: SOC_MEM_BT_BSS_END, - }, - btdm_dram_available_region_t { - mode: esp_bt_mode_t_ESP_BT_MODE_BTDM, - start: SOC_MEM_BT_MISC_START, - end: SOC_MEM_BT_MISC_END, - }, -]; - -pub(crate) fn create_ble_config() -> esp_bt_controller_config_t { - esp_bt_controller_config_t { - controller_task_stack_size: 4096, - controller_task_prio: 110, - hci_uart_no: 1, - hci_uart_baudrate: 921600, - scan_duplicate_mode: 0, - scan_duplicate_type: 0, - normal_adv_size: 200, - mesh_adv_size: 0, - send_adv_reserved_size: 1000, - controller_debug_flag: 0 << 0, - mode: 0x01, // BLE - ble_max_conn: 3, - bt_max_acl_conn: 0, - bt_sco_datapath: 0, - auto_latency: false, - bt_legacy_auth_vs_evt: false, - bt_max_sync_conn: 1, - ble_sca: 1, - pcm_role: 0, - pcm_polar: 0, - hli: false, - dup_list_refresh_period: 0, - magic: 0x20221207, - } -} - -pub(crate) fn btdm_controller_mem_init() { - extern "C" { - static mut _data_start_btdm: u32; - static mut _data_end_btdm: u32; - static _data_start_btdm_rom: u32; - } - - // initialise .data section - unsafe { - let data_start = addr_of_mut!(_data_start_btdm).cast::(); - let data_end = addr_of_mut!(_data_end_btdm).cast::(); - - // `_data_start_btdm_rom` is a pointer to the actual initialization data in the ROM. - let data_start_rom = _data_start_btdm_rom as *const u8; - - let len = data_end as usize - data_start as usize; - - core::ptr::copy_nonoverlapping(data_start_rom, data_start, len); - - debug!( - "btdm_controller_mem_init {:?} {:?} {}", - data_start_rom, data_start, len, - ); - } - - // initialize em, .bss section - let btdm_dram_regions = BTDM_DRAM_AVAILABLE_REGION.len(); - - for i in 1..btdm_dram_regions { - if BTDM_DRAM_AVAILABLE_REGION[i].mode != esp_bt_mode_t_ESP_BT_MODE_IDLE { - unsafe { - core::ptr::write_bytes( - BTDM_DRAM_AVAILABLE_REGION[i].start as *mut u8, - 0x0, - (BTDM_DRAM_AVAILABLE_REGION[i].end - BTDM_DRAM_AVAILABLE_REGION[i].start) - as usize, - ); - } - debug!( - ".bss initialise {:x} - {:x}\n", - BTDM_DRAM_AVAILABLE_REGION[i].start, BTDM_DRAM_AVAILABLE_REGION[i].end - ); - } - } - - debug!("btdm_controller_mem_init done"); -} - -pub(crate) fn bt_periph_module_enable() { - // nothing -} - -pub(crate) fn disable_sleep_mode() { - extern "C" { - fn btdm_controller_set_sleep_mode(mode: u8); - } - - const BTDM_MODEM_SLEEP_MODE_NONE: u8 = 0; - - unsafe { - btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE); - } -} - -pub(crate) unsafe extern "C" fn coex_bt_wakeup_request() -> bool { - debug!("coex_bt_wakeup_request"); - #[cfg(coex)] - return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX); - - #[cfg(not(coex))] - true -} - -pub(crate) unsafe extern "C" fn coex_bt_wakeup_request_end() { - warn!("coex_bt_wakeup_request_end"); - - #[cfg(coex)] - async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_COEX); -} - -#[allow(unused_variables)] -pub(crate) unsafe extern "C" fn coex_bt_request(event: u32, latency: u32, duration: u32) -> i32 { - debug!("coex_bt_request"); - extern "C" { - #[cfg(coex)] - fn coex_bt_request(event: u32, latency: u32, duration: u32) -> i32; - } - - #[cfg(coex)] - return coex_bt_request(event, latency, duration); - - #[cfg(not(coex))] - 0 -} - -#[allow(unused_variables)] -pub(crate) unsafe extern "C" fn coex_bt_release(event: u32) -> i32 { - debug!("coex_bt_release"); - extern "C" { - #[cfg(coex)] - fn coex_bt_release(event: u32) -> i32; - } - - #[cfg(coex)] - return coex_bt_release(event); - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn coex_register_bt_cb_wrapper( - callback: unsafe extern "C" fn(), -) -> i32 { - warn!("coex_register_bt_cb {:?}", callback); - extern "C" { - #[cfg(coex)] - fn coex_register_bt_cb(callback: unsafe extern "C" fn()) -> i32; - } - - #[cfg(coex)] - return coex_register_bt_cb(callback); - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn coex_bb_reset_lock() -> u32 { - debug!("coex_bb_reset_lock"); - extern "C" { - #[cfg(coex)] - fn coex_bb_reset_lock() -> u32; - } - - #[cfg(coex)] - return coex_bb_reset_lock(); - - #[cfg(not(coex))] - 0 -} - -#[allow(unused_variables)] -pub(crate) unsafe extern "C" fn coex_bb_reset_unlock(event: u32) { - debug!("coex_bb_reset_unlock"); - extern "C" { - #[cfg(coex)] - fn coex_bb_reset_unlock(event: u32); - } - - #[cfg(coex)] - coex_bb_reset_unlock(event); -} - -pub(crate) unsafe extern "C" fn coex_schm_register_btdm_callback_wrapper( - callback: unsafe extern "C" fn(), -) -> i32 { - warn!("coex_schm_register_btdm_callback {:?}", callback); - extern "C" { - #[cfg(coex)] - fn coex_schm_register_callback(kind: u32, callback: unsafe extern "C" fn()) -> i32; - } - - #[cfg(coex)] - return coex_schm_register_callback(1, callback); // COEX_SCHM_CALLBACK_TYPE_BT = 1 - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn coex_schm_interval_get() -> u32 { - debug!("coex_schm_interval_get"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_interval_get(); - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn coex_schm_curr_period_get() -> u8 { - debug!("coex_schm_curr_period_get"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_curr_period_get() as u8; - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn coex_schm_curr_phase_get() -> *const () { - debug!("coex_schm_curr_phase_get"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_curr_phase_get() as *const (); - - #[cfg(not(coex))] - return 0 as *const (); -} - -#[allow(unused_variables)] -pub(crate) unsafe extern "C" fn coex_wifi_channel_get(primary: *mut u8, secondary: *mut u8) -> i32 { - warn!("coex_wifi_channel_get"); - extern "C" { - #[cfg(coex)] - fn coex_wifi_channel_get(primary: *mut u8, secondary: *mut u8) -> i32; - } - - #[cfg(coex)] - return coex_wifi_channel_get(primary, secondary); - - #[cfg(not(coex))] - -1 -} - -#[allow(unused_variables)] -pub(crate) unsafe extern "C" fn coex_register_wifi_channel_change_callback( - callback: unsafe extern "C" fn(), -) -> i32 { - warn!("coex_register_wifi_channel_change_callback"); - extern "C" { - #[cfg(coex)] - fn coex_register_wifi_channel_change_callback(callback: unsafe extern "C" fn()) -> i32; - } - - #[cfg(coex)] - return coex_register_wifi_channel_change_callback(callback); - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn set_isr(n: i32, f: unsafe extern "C" fn(), arg: *const ()) -> i32 { - trace!("set_isr called {} {:?} {:?}", n, f, arg); - - match n { - 5 => { - ISR_INTERRUPT_5 = (f as *mut c_types::c_void, arg as *mut c_types::c_void); - } - 7 => { - ISR_INTERRUPT_7 = (f as *mut c_types::c_void, arg as *mut c_types::c_void); - } - 8 => { - ISR_INTERRUPT_8 = (f as *mut c_types::c_void, arg as *mut c_types::c_void); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - - 0 -} - -pub(crate) unsafe extern "C" fn ints_on(mask: u32) { - trace!("chip_ints_on esp32 {:b}", mask); - crate::hal::xtensa_lx::interrupt::enable_mask(mask); -} - -#[cfg(coex)] -const BTDM_ASYNC_WAKEUP_REQ_HCI: i32 = 0; - -#[cfg(coex)] -const BTDM_ASYNC_WAKEUP_REQ_COEX: i32 = 1; - -//const BTDM_ASYNC_WAKEUP_REQMAX: i32 = 2; - -/**************************************************************************** - * Name: async_wakeup_request - * - * Description: - * Request the BLE Controller to wakeup - * - * Input Parameters: - * event - the event that triggered the wakeup - * - * Returned Value: - * true if request lock is needed, false otherwise - * - ****************************************************************************/ - -#[cfg(coex)] -fn async_wakeup_request(event: i32) -> bool { - let request_lock: bool; - let mut do_wakeup_request = false; - - match event { - e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => request_lock = true, - e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => request_lock = false, - _ => return false, - } - - extern "C" { - fn btdm_power_state_active() -> bool; - fn btdm_wakeup_request(request_lock: bool); - } - - if !unsafe { btdm_power_state_active() } { - do_wakeup_request = true; - unsafe { btdm_wakeup_request(request_lock) }; - } - - return do_wakeup_request; -} - -/**************************************************************************** - * Name: async_wakeup_request_end - * - * Description: - * Finish a wakeup request - * - * Input Parameters: - * event - the event that triggered the wakeup - * - * Returned Value: - * true if request lock is needed, false otherwise - * - ****************************************************************************/ - -#[cfg(coex)] -fn async_wakeup_request_end(event: i32) { - let request_lock: bool; - - match event { - e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => request_lock = true, - e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => request_lock = false, - _ => return, - } - - extern "C" { - // this isn't found anywhere ... not a ROM function - // not in any of the libs - but the code will never call this anyway - - // fn btdm_wakeup_request_end(); - } - if request_lock { - // unsafe { btdm_wakeup_request_end() }; - } - - return; -} diff --git a/esp-wifi/src/ble/os_adapter_esp32c2.rs b/esp-wifi/src/ble/os_adapter_esp32c2.rs deleted file mode 100644 index 58bb7606..00000000 --- a/esp-wifi/src/ble/os_adapter_esp32c2.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::binary::include::esp_bt_controller_config_t; -use crate::common_adapter::RADIO_CLOCKS; -use crate::hal::system::RadioClockController; - -pub(crate) static mut ISR_INTERRUPT_4: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static mut ISR_INTERRUPT_7: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static BLE_CONFIG: esp_bt_controller_config_t = esp_bt_controller_config_t { - config_version: 0x20231124, - ble_ll_resolv_list_size: 4, - ble_hci_evt_hi_buf_count: 30, - ble_hci_evt_lo_buf_count: 8, - ble_ll_sync_list_cnt: 5, - ble_ll_sync_cnt: 20, - ble_ll_rsp_dup_list_count: 20, - ble_ll_adv_dup_list_count: 20, - ble_ll_tx_pwr_dbm: 9, - rtc_freq: 32000, - ble_ll_sca: 60, - ble_ll_scan_phy_number: 1, - ble_ll_conn_def_auth_pyld_tmo: 3000, - ble_ll_jitter_usecs: 16, - ble_ll_sched_max_adv_pdu_usecs: 376, - ble_ll_sched_direct_adv_max_usecs: 502, - ble_ll_sched_adv_max_usecs: 852, - ble_scan_rsp_data_max_len: 31, - ble_ll_cfg_num_hci_cmd_pkts: 1, - ble_ll_ctrl_proc_timeout_ms: 40000, - nimble_max_connections: 2, - ble_whitelist_size: 12, - ble_acl_buf_size: 255, - ble_acl_buf_count: 24, - ble_hci_evt_buf_size: 70, - ble_multi_adv_instances: 1, - ble_ext_adv_max_size: 31, - controller_task_stack_size: 4096, - controller_task_prio: 253, - controller_run_cpu: 0, - enable_qa_test: 0, - enable_bqb_test: 0, - enable_uart_hci: 0, - ble_hci_uart_port: 0, - ble_hci_uart_baud: 0, - ble_hci_uart_data_bits: 0, - ble_hci_uart_stop_bits: 0, - ble_hci_uart_flow_ctrl: 0, - ble_hci_uart_uart_parity: 0, - enable_tx_cca: 0, - cca_rssi_thresh: (256 - 50) as u8, - sleep_en: 0, - coex_phy_coded_tx_rx_time_limit: 0, - dis_scan_backoff: 0, - ble_scan_classify_filter_enable: 0, - cca_drop_mode: 0, //??? - cca_low_tx_pwr: 0, //??? - main_xtal_freq: 40, - version_num: 0, // chips revision: EFUSE.blk0_rdata5.rd_wafer_version_minor - ignore_wl_for_direct_adv: 0, - csa2_select: 0, - config_magic: 0x5A5AA5A5, -}; - -pub(crate) fn bt_periph_module_enable() { - // nothing -} - -pub(crate) fn disable_sleep_mode() { - // nothing -} - -pub(super) unsafe extern "C" fn esp_intr_alloc( - source: u32, - flags: u32, - handler: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, - ret_handle: *mut *mut crate::binary::c_types::c_void, -) -> i32 { - trace!( - "esp_intr_alloc {} {} {:?} {:?} {:?}", - source, - flags, - handler, - arg, - ret_handle - ); - - match source { - 4 => ISR_INTERRUPT_4 = (handler, arg), - 7 => ISR_INTERRUPT_7 = (handler, arg), - _ => panic!("Unexpected interrupt source {}", source), - } - - 0 -} - -pub(super) fn ble_rtc_clk_init() { - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).ble_rtc_clk_init(); - } -} - -pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() { - trace!("esp_reset_rpa_moudle"); - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).reset_rpa(); - } -} - -pub(super) unsafe extern "C" fn ble_ll_random_override() -> u32 { - // this is not very random but good enough for now - it's not used for crypto - unsafe { - static mut VALUE: u32 = 0; - VALUE = VALUE.wrapping_add(3); - VALUE - } -} diff --git a/esp-wifi/src/ble/os_adapter_esp32c3.rs b/esp-wifi/src/ble/os_adapter_esp32c3.rs deleted file mode 100644 index ea590463..00000000 --- a/esp-wifi/src/ble/os_adapter_esp32c3.rs +++ /dev/null @@ -1,318 +0,0 @@ -use super::*; - -pub(crate) static mut BT_INTERRUPT_FUNCTION5: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static mut BT_INTERRUPT_FUNCTION8: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -#[repr(C)] -pub(super) struct osi_funcs_s { - magic: u32, - version: u32, - interrupt_set: Option, - interrupt_clear: Option, - interrupt_handler_set: Option, - interrupt_disable: Option, - interrupt_enable: Option, - task_yield: Option, - task_yield_from_isr: Option, - semphr_create: Option *const ()>, - semphr_delete: Option, - semphr_take_from_isr: Option i32>, - semphr_give_from_isr: Option i32>, - semphr_take: Option i32>, - semphr_give: Option i32>, - mutex_create: Option *const ()>, - mutex_delete: Option, - mutex_lock: Option i32>, - mutex_unlock: Option i32>, - queue_create: Option *const ()>, - queue_delete: Option, - queue_send: Option i32>, - queue_send_from_isr: Option i32>, - queue_recv: Option i32>, - queue_recv_from_isr: Option i32>, - task_create: Option< - unsafe extern "C" fn( - *mut crate::binary::c_types::c_void, - *const u8, - u32, - *mut crate::binary::c_types::c_void, - u32, - *mut crate::binary::c_types::c_void, - u32, - ) -> i32, - >, - task_delete: Option, - is_in_isr: Option i32>, - cause_sw_intr_to_core: Option i32>, - malloc: Option *mut crate::binary::c_types::c_void>, - malloc_internal: Option *mut crate::binary::c_types::c_void>, - free: Option, - read_efuse_mac: Option i32>, - srand: Option, - rand: Option i32>, - btdm_lpcycles_2_hus: Option u32>, - btdm_hus_2_lpcycles: Option u32>, - btdm_sleep_check_duration: Option i32>, - btdm_sleep_enter_phase1: Option, - btdm_sleep_enter_phase2: Option, - btdm_sleep_exit_phase1: Option, - btdm_sleep_exit_phase2: Option, - btdm_sleep_exit_phase3: Option, - coex_wifi_sleep_set: Option, - coex_core_ble_conn_dyn_prio_get: Option i32>, - coex_schm_status_bit_set: Option, - coex_schm_status_bit_clear: Option, - interrupt_on: Option, - interrupt_off: Option, - esp_hw_power_down: Option, - esp_hw_power_up: Option, - ets_backup_dma_copy: Option, - ets_delay_us: Option, - btdm_rom_table_ready: Option, -} - -pub(super) static G_OSI_FUNCS: osi_funcs_s = osi_funcs_s { - magic: 0xfadebead, - version: 0x00010007, - interrupt_set: Some(ble_os_adapter_chip_specific::interrupt_set), - interrupt_clear: Some(ble_os_adapter_chip_specific::interrupt_clear), - interrupt_handler_set: Some(ble_os_adapter_chip_specific::interrupt_handler_set), - interrupt_disable: Some(interrupt_disable), - interrupt_enable: Some(interrupt_enable), - task_yield: Some(task_yield), - task_yield_from_isr: Some(task_yield_from_isr), - semphr_create: Some(semphr_create), - semphr_delete: Some(semphr_delete), - semphr_take_from_isr: Some(crate::common_adapter::semphr_take_from_isr), - semphr_give_from_isr: Some(crate::common_adapter::semphr_give_from_isr), - semphr_take: Some(semphr_take), - semphr_give: Some(semphr_give), - mutex_create: Some(mutex_create), - mutex_delete: Some(mutex_delete), - mutex_lock: Some(mutex_lock), - mutex_unlock: Some(mutex_unlock), - queue_create: Some(queue_create), - queue_delete: Some(queue_delete), - queue_send: Some(queue_send), - queue_send_from_isr: Some(queue_send_from_isr), - queue_recv: Some(queue_recv), - queue_recv_from_isr: Some(queue_recv_from_isr), - task_create: Some(task_create), - task_delete: Some(task_delete), - is_in_isr: Some(is_in_isr), - cause_sw_intr_to_core: Some(cause_sw_intr_to_core), - malloc: Some(crate::ble::malloc), - malloc_internal: Some(crate::ble::malloc_internal), - free: Some(crate::ble::free), - read_efuse_mac: Some(read_efuse_mac), - srand: Some(crate::ble::btdm::srand), - rand: Some(crate::ble::btdm::rand), - btdm_lpcycles_2_hus: Some(btdm_lpcycles_2_hus), - btdm_hus_2_lpcycles: Some(btdm_hus_2_lpcycles), - btdm_sleep_check_duration: Some(btdm_sleep_check_duration), - btdm_sleep_enter_phase1: Some(btdm_sleep_enter_phase1), - btdm_sleep_enter_phase2: Some(btdm_sleep_enter_phase2), - btdm_sleep_exit_phase1: Some(btdm_sleep_exit_phase1), - btdm_sleep_exit_phase2: Some(btdm_sleep_exit_phase2), - btdm_sleep_exit_phase3: Some(btdm_sleep_exit_phase3), - coex_wifi_sleep_set: Some(ble_os_adapter_chip_specific::coex_wifi_sleep_set), - coex_core_ble_conn_dyn_prio_get: Some( - ble_os_adapter_chip_specific::coex_core_ble_conn_dyn_prio_get, - ), - coex_schm_status_bit_set: Some(coex_schm_status_bit_set), - coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear), - interrupt_on: Some(ble_os_adapter_chip_specific::interrupt_on), - interrupt_off: Some(ble_os_adapter_chip_specific::interrupt_off), - esp_hw_power_down: Some(ble_os_adapter_chip_specific::esp_hw_power_down), - esp_hw_power_up: Some(ble_os_adapter_chip_specific::esp_hw_power_up), - ets_backup_dma_copy: Some(ble_os_adapter_chip_specific::ets_backup_dma_copy), - ets_delay_us: Some(ets_delay_us_wrapper), - btdm_rom_table_ready: Some(btdm_rom_table_ready_wrapper), -}; - -extern "C" fn ets_delay_us_wrapper(us: u32) { - extern "C" { - fn ets_delay_us(us: u32); - } - - unsafe { - ets_delay_us(us); - } -} - -extern "C" fn btdm_rom_table_ready_wrapper() { - debug!("btdm_rom_table_ready_wrapper not implemented"); - - // #if BT_BLE_CCA_MODE == 2 - // btdm_cca_feature_enable(); - // #endif -} - -extern "C" { - fn btdm_controller_rom_data_init() -> i32; -} - -pub(crate) fn create_ble_config() -> esp_bt_controller_config_t { - esp_bt_controller_config_t { - magic: 0x5a5aa5a5, - version: 0x02307120, - controller_task_stack_size: 8192, - controller_task_prio: 200, - controller_task_run_cpu: 0, - bluetooth_mode: 1, - ble_max_act: 10, - sleep_mode: 0, - sleep_clock: 0, - ble_st_acl_tx_buf_nb: 0, - ble_hw_cca_check: 0, - ble_adv_dup_filt_max: 30, - coex_param_en: false, - ce_len_type: 0, - coex_use_hooks: false, - hci_tl_type: 1, - hci_tl_funcs: core::ptr::null_mut(), - txant_dft: 0, - rxant_dft: 0, - txpwr_dft: 9, - cfg_mask: 1, - scan_duplicate_mode: 0, - scan_duplicate_type: 0, - normal_adv_size: 20, - mesh_adv_size: 0, - coex_phy_coded_tx_rx_time_limit: 0, - hw_target_code: 0x01010000, - slave_ce_len_min: 5, - hw_recorrect_en: 1 << 0, - cca_thresh: 20, - dup_list_refresh_period: 0, - scan_backoff_upperlimitmax: 0, - ble_50_feat_supp: true, // BT_CTRL_50_FEATURE_SUPPORT - ble_cca_mode: 0, - } -} - -pub(crate) unsafe extern "C" fn interrupt_on(intr_num: i32) { - trace!("interrupt_on {}", intr_num); - - // NO-OP -} - -pub(crate) unsafe extern "C" fn interrupt_off(_intr_num: i32) { - todo!(); -} - -pub(crate) fn btdm_controller_mem_init() { - unsafe { - btdm_controller_rom_data_init(); - } -} - -pub(crate) fn bt_periph_module_enable() { - // nothing -} - -pub(crate) fn disable_sleep_mode() { - // nothing -} - -// OSI functions - -pub(crate) unsafe extern "C" fn interrupt_set( - cpu_no: i32, - intr_source: i32, - interrupt_no: i32, - interrupt_prio: i32, -) { - trace!( - "interrupt_set {} {} {} {}", - cpu_no, - intr_source, - interrupt_no, - interrupt_prio - ); - - /* Set the interrupt type (Edge or Level). */ - /* Map the CPU interrupt ID to the peripheral. */ - - // NO-OP -} - -pub(crate) unsafe extern "C" fn interrupt_clear(_interrupt_source: i32, _interrupt_no: i32) { - todo!(); -} - -pub(crate) unsafe extern "C" fn interrupt_handler_set( - interrupt_no: i32, - func: extern "C" fn(*const ()), - arg: *const (), -) { - trace!( - "interrupt_handler_set {} {:?} {:?}", - interrupt_no, - func, - arg - ); - match interrupt_no { - 5 => { - BT_INTERRUPT_FUNCTION5 = ( - func as *mut crate::binary::c_types::c_void, - arg as *mut crate::binary::c_types::c_void, - ) - } - 8 => { - BT_INTERRUPT_FUNCTION8 = ( - func as *mut crate::binary::c_types::c_void, - arg as *mut crate::binary::c_types::c_void, - ) - } - _ => panic!("Unsupported interrupt number {}", interrupt_no), - } -} - -pub(crate) unsafe extern "C" fn coex_wifi_sleep_set(sleep: i32) { - debug!( - "ignored coex_wifi_sleep_set {} - because original implementation does the same", - sleep - ); -} - -#[allow(unused_variables, dead_code)] -pub(crate) unsafe extern "C" fn coex_core_ble_conn_dyn_prio_get( - low: *mut i32, - high: *mut i32, -) -> i32 { - extern "C" { - fn coex_core_ble_conn_dyn_prio_get(low: *mut i32, high: *mut i32) -> i32; - } - debug!("coex_core_ble_conn_dyn_prio_get"); - - #[cfg(coex)] - return coex_core_ble_conn_dyn_prio_get(low, high); - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn esp_hw_power_down() { - todo!(); -} - -pub(crate) unsafe extern "C" fn esp_hw_power_up() { - todo!(); -} - -pub(crate) unsafe extern "C" fn ets_backup_dma_copy( - _reg: u32, - _mem_addr: u32, - _num: u32, - _to_rem: i32, -) { - todo!(); -} diff --git a/esp-wifi/src/ble/os_adapter_esp32c6.rs b/esp-wifi/src/ble/os_adapter_esp32c6.rs deleted file mode 100644 index 79209d66..00000000 --- a/esp-wifi/src/ble/os_adapter_esp32c6.rs +++ /dev/null @@ -1,129 +0,0 @@ -use crate::binary::include::esp_bt_controller_config_t; -use crate::common_adapter::RADIO_CLOCKS; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -pub(crate) static mut ISR_INTERRUPT_4: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static mut ISR_INTERRUPT_7: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static BLE_CONFIG: esp_bt_controller_config_t = esp_bt_controller_config_t { - config_version: 0x20231124, - ble_ll_resolv_list_size: 4, - ble_hci_evt_hi_buf_count: 30, - ble_hci_evt_lo_buf_count: 8, - ble_ll_sync_list_cnt: 5, - ble_ll_sync_cnt: 20, - ble_ll_rsp_dup_list_count: 20, - ble_ll_adv_dup_list_count: 20, - ble_ll_tx_pwr_dbm: 9, - rtc_freq: 32000, - ble_ll_sca: 60, - ble_ll_scan_phy_number: 1, - ble_ll_conn_def_auth_pyld_tmo: 3000, - ble_ll_jitter_usecs: 16, - ble_ll_sched_max_adv_pdu_usecs: 376, - ble_ll_sched_direct_adv_max_usecs: 502, - ble_ll_sched_adv_max_usecs: 852, - ble_scan_rsp_data_max_len: 31, - ble_ll_cfg_num_hci_cmd_pkts: 1, - ble_ll_ctrl_proc_timeout_ms: 40000, - nimble_max_connections: 2, - ble_whitelist_size: 12, - ble_acl_buf_size: 255, - ble_acl_buf_count: 24, - ble_hci_evt_buf_size: 70, - ble_multi_adv_instances: 1, - ble_ext_adv_max_size: 31, - controller_task_stack_size: 4096, - controller_task_prio: 253, - controller_run_cpu: 0, - enable_qa_test: 0, - enable_bqb_test: 0, - enable_uart_hci: 0, - ble_hci_uart_port: 0, - ble_hci_uart_baud: 0, - ble_hci_uart_data_bits: 0, - ble_hci_uart_stop_bits: 0, - ble_hci_uart_flow_ctrl: 0, - ble_hci_uart_uart_parity: 0, - enable_tx_cca: 0, - cca_rssi_thresh: (256 - 50) as u8, - sleep_en: 0, - coex_phy_coded_tx_rx_time_limit: 0, - dis_scan_backoff: 0, - ble_scan_classify_filter_enable: 1, - cca_drop_mode: 0, //??? - cca_low_tx_pwr: 0, //??? - main_xtal_freq: 40, - ignore_wl_for_direct_adv: 0, - config_magic: 0x5A5AA5A5, - - cpu_freq_mhz: 160, - enable_pcl: 0, // CONFIG_BT_LE_POWER_CONTROL_ENABLED - version_num: 0, - csa2_select: 1, -}; - -pub(crate) fn bt_periph_module_enable() { - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Bt); - } -} - -pub(crate) fn disable_sleep_mode() { - // nothing -} - -pub(super) unsafe extern "C" fn esp_intr_alloc( - source: u32, - flags: u32, - handler: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, - ret_handle: *mut *mut crate::binary::c_types::c_void, -) -> i32 { - debug!( - "esp_intr_alloc {} {} {:?} {:?} {:?}", - source, flags, handler, arg, ret_handle - ); - - match source { - 4 => ISR_INTERRUPT_4 = (handler, arg), - 7 => ISR_INTERRUPT_7 = (handler, arg), - _ => panic!("Unexpected interrupt source {}", source), - } - - 0 -} - -pub(super) fn ble_rtc_clk_init() { - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).ble_rtc_clk_init(); - } -} - -pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() { - trace!("esp_reset_rpa_moudle"); - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).reset_rpa(); - } -} - -#[allow(improper_ctypes_definitions)] -#[no_mangle] -unsafe extern "C" fn jrand48( - _xsubi: [crate::binary::c_types::c_ushort; 3], -) -> crate::binary::c_types::c_long { - // this is not very random but good enough for now - it's apparently not used for crypto - unsafe { - static mut VALUE: u32 = 0; - VALUE = VALUE.wrapping_add(3); - VALUE as i32 - } -} diff --git a/esp-wifi/src/ble/os_adapter_esp32h2.rs b/esp-wifi/src/ble/os_adapter_esp32h2.rs deleted file mode 100644 index 60fe2462..00000000 --- a/esp-wifi/src/ble/os_adapter_esp32h2.rs +++ /dev/null @@ -1,129 +0,0 @@ -use crate::binary::include::esp_bt_controller_config_t; -use crate::common_adapter::RADIO_CLOCKS; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -pub(crate) static mut ISR_INTERRUPT_15: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static mut ISR_INTERRUPT_3: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub(crate) static BLE_CONFIG: esp_bt_controller_config_t = esp_bt_controller_config_t { - config_version: 0x20231124, - ble_ll_resolv_list_size: 4, - ble_hci_evt_hi_buf_count: 30, - ble_hci_evt_lo_buf_count: 8, - ble_ll_sync_list_cnt: 5, - ble_ll_sync_cnt: 20, - ble_ll_rsp_dup_list_count: 20, - ble_ll_adv_dup_list_count: 20, - ble_ll_tx_pwr_dbm: 9, - rtc_freq: 32000, - ble_ll_sca: 60, - ble_ll_scan_phy_number: 1, - ble_ll_conn_def_auth_pyld_tmo: 3000, - ble_ll_jitter_usecs: 16, - ble_ll_sched_max_adv_pdu_usecs: 376, - ble_ll_sched_direct_adv_max_usecs: 502, - ble_ll_sched_adv_max_usecs: 852, - ble_scan_rsp_data_max_len: 31, - ble_ll_cfg_num_hci_cmd_pkts: 1, - ble_ll_ctrl_proc_timeout_ms: 40000, - nimble_max_connections: 2, - ble_whitelist_size: 12, - ble_acl_buf_size: 255, - ble_acl_buf_count: 24, - ble_hci_evt_buf_size: 70, - ble_multi_adv_instances: 1, - ble_ext_adv_max_size: 31, - controller_task_stack_size: 4096, - controller_task_prio: 253, // ??? - controller_run_cpu: 0, - enable_qa_test: 0, - enable_bqb_test: 0, - enable_uart_hci: 0, - ble_hci_uart_port: 0, - ble_hci_uart_baud: 0, - ble_hci_uart_data_bits: 0, - ble_hci_uart_stop_bits: 0, - ble_hci_uart_flow_ctrl: 0, - ble_hci_uart_uart_parity: 0, - enable_tx_cca: 0, - cca_rssi_thresh: (256 - 50) as u8, - sleep_en: 0, - coex_phy_coded_tx_rx_time_limit: 0, - dis_scan_backoff: 0, - ble_scan_classify_filter_enable: 1, - cca_drop_mode: 0, //??? - cca_low_tx_pwr: 0, //??? - main_xtal_freq: 32, - ignore_wl_for_direct_adv: 0, - config_magic: 0x5A5AA5A5, - - cpu_freq_mhz: 96, - enable_pcl: 0, - // version_num: 0, - csa2_select: 1, -}; - -pub(crate) fn bt_periph_module_enable() { - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Bt); - } -} - -pub(crate) fn disable_sleep_mode() { - // nothing -} - -pub(super) unsafe extern "C" fn esp_intr_alloc( - source: u32, - flags: u32, - handler: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, - ret_handle: *mut *mut crate::binary::c_types::c_void, -) -> i32 { - debug!( - "esp_intr_alloc {} {} {:?} {:?} {:?}", - source, flags, handler, arg, ret_handle - ); - - match source { - 3 => ISR_INTERRUPT_3 = (handler, arg), - 15 => ISR_INTERRUPT_15 = (handler, arg), - _ => panic!("Unexpected interrupt source {}", source), - } - - 0 -} - -pub(super) fn ble_rtc_clk_init() { - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).ble_rtc_clk_init(); - } -} - -pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() { - trace!("esp_reset_rpa_moudle"); - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).reset_rpa(); - } -} - -#[allow(improper_ctypes_definitions)] -#[no_mangle] -unsafe extern "C" fn jrand48( - _xsubi: [crate::binary::c_types::c_ushort; 3], -) -> crate::binary::c_types::c_long { - // this is not very random but good enough for now - it's apparently not used for crypto - unsafe { - static mut VALUE: u32 = 0; - VALUE = VALUE.wrapping_add(3); - VALUE as i32 - } -} diff --git a/esp-wifi/src/ble/os_adapter_esp32s3.rs b/esp-wifi/src/ble/os_adapter_esp32s3.rs deleted file mode 100644 index fd0da61f..00000000 --- a/esp-wifi/src/ble/os_adapter_esp32s3.rs +++ /dev/null @@ -1,313 +0,0 @@ -use super::*; -use crate::binary::include::esp_bt_controller_config_t; - -pub static mut ISR_INTERRUPT_5: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -pub static mut ISR_INTERRUPT_8: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -#[repr(C)] -pub(super) struct osi_funcs_s { - magic: u32, - version: u32, - interrupt_set: Option, - interrupt_clear: Option, - interrupt_handler_set: Option, - interrupt_disable: Option, - interrupt_enable: Option, - task_yield: Option, - task_yield_from_isr: Option, - semphr_create: Option *const ()>, - semphr_delete: Option, - semphr_take_from_isr: Option i32>, - semphr_give_from_isr: Option i32>, - semphr_take: Option i32>, - semphr_give: Option i32>, - mutex_create: Option *const ()>, - mutex_delete: Option, - mutex_lock: Option i32>, - mutex_unlock: Option i32>, - queue_create: Option *const ()>, - queue_delete: Option, - queue_send: Option i32>, - queue_send_from_isr: Option i32>, - queue_recv: Option i32>, - queue_recv_from_isr: Option i32>, - task_create: Option< - unsafe extern "C" fn( - *mut crate::binary::c_types::c_void, - *const u8, - u32, - *mut crate::binary::c_types::c_void, - u32, - *mut crate::binary::c_types::c_void, - u32, - ) -> i32, - >, - task_delete: Option, - is_in_isr: Option i32>, - cause_sw_intr_to_core: Option i32>, - malloc: Option *mut crate::binary::c_types::c_void>, - malloc_internal: Option *mut crate::binary::c_types::c_void>, - free: Option, - read_efuse_mac: Option i32>, - srand: Option, - rand: Option i32>, - btdm_lpcycles_2_hus: Option u32>, - btdm_hus_2_lpcycles: Option u32>, - btdm_sleep_check_duration: Option i32>, - btdm_sleep_enter_phase1: Option, - btdm_sleep_enter_phase2: Option, - btdm_sleep_exit_phase1: Option, - btdm_sleep_exit_phase2: Option, - btdm_sleep_exit_phase3: Option, - coex_wifi_sleep_set: Option, - coex_core_ble_conn_dyn_prio_get: Option i32>, - coex_schm_status_bit_set: Option, - coex_schm_status_bit_clear: Option, - interrupt_on: Option, - interrupt_off: Option, - esp_hw_power_down: Option, - esp_hw_power_up: Option, - ets_backup_dma_copy: Option, - ets_delay_us: Option, - btdm_rom_table_ready: Option, -} - -pub(super) static G_OSI_FUNCS: osi_funcs_s = osi_funcs_s { - magic: 0xfadebead, - version: 0x00010007, - interrupt_set: Some(ble_os_adapter_chip_specific::interrupt_set), - interrupt_clear: Some(ble_os_adapter_chip_specific::interrupt_clear), - interrupt_handler_set: Some(ble_os_adapter_chip_specific::interrupt_handler_set), - interrupt_disable: Some(interrupt_disable), - interrupt_enable: Some(interrupt_enable), - task_yield: Some(task_yield), - task_yield_from_isr: Some(task_yield_from_isr), - semphr_create: Some(semphr_create), - semphr_delete: Some(semphr_delete), - semphr_take_from_isr: Some(crate::common_adapter::semphr_take_from_isr), - semphr_give_from_isr: Some(crate::common_adapter::semphr_give_from_isr), - semphr_take: Some(semphr_take), - semphr_give: Some(semphr_give), - mutex_create: Some(mutex_create), - mutex_delete: Some(mutex_delete), - mutex_lock: Some(mutex_lock), - mutex_unlock: Some(mutex_unlock), - queue_create: Some(queue_create), - queue_delete: Some(queue_delete), - queue_send: Some(queue_send), - queue_send_from_isr: Some(queue_send_from_isr), - queue_recv: Some(queue_recv), - queue_recv_from_isr: Some(queue_recv_from_isr), - task_create: Some(task_create), - task_delete: Some(task_delete), - is_in_isr: Some(is_in_isr), - cause_sw_intr_to_core: Some(cause_sw_intr_to_core), - malloc: Some(crate::ble::malloc), - malloc_internal: Some(crate::ble::malloc_internal), - free: Some(crate::ble::free), - read_efuse_mac: Some(read_efuse_mac), - srand: Some(crate::ble::btdm::srand), - rand: Some(crate::ble::btdm::rand), - btdm_lpcycles_2_hus: Some(btdm_lpcycles_2_hus), - btdm_hus_2_lpcycles: Some(btdm_hus_2_lpcycles), - btdm_sleep_check_duration: Some(btdm_sleep_check_duration), - btdm_sleep_enter_phase1: Some(btdm_sleep_enter_phase1), - btdm_sleep_enter_phase2: Some(btdm_sleep_enter_phase2), - btdm_sleep_exit_phase1: Some(btdm_sleep_exit_phase1), - btdm_sleep_exit_phase2: Some(btdm_sleep_exit_phase2), - btdm_sleep_exit_phase3: Some(btdm_sleep_exit_phase3), - coex_wifi_sleep_set: Some(ble_os_adapter_chip_specific::coex_wifi_sleep_set), - coex_core_ble_conn_dyn_prio_get: Some( - ble_os_adapter_chip_specific::coex_core_ble_conn_dyn_prio_get, - ), - coex_schm_status_bit_set: Some(coex_schm_status_bit_set), - coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear), - interrupt_on: Some(ble_os_adapter_chip_specific::interrupt_on), - interrupt_off: Some(ble_os_adapter_chip_specific::interrupt_off), - esp_hw_power_down: Some(ble_os_adapter_chip_specific::esp_hw_power_down), - esp_hw_power_up: Some(ble_os_adapter_chip_specific::esp_hw_power_up), - ets_backup_dma_copy: Some(ble_os_adapter_chip_specific::ets_backup_dma_copy), - ets_delay_us: Some(ets_delay_us_wrapper), - btdm_rom_table_ready: Some(btdm_rom_table_ready_wrapper), -}; - -extern "C" fn ets_delay_us_wrapper(us: u32) { - extern "C" { - fn ets_delay_us(us: u32); - } - - unsafe { - ets_delay_us(us); - } -} - -extern "C" fn btdm_rom_table_ready_wrapper() { - debug!("btdm_rom_table_ready_wrapper is NOT implemented"); - - // #if BT_BLE_CCA_MODE == 2 - // btdm_cca_feature_enable(); - // #endif -} - -extern "C" { - fn btdm_controller_rom_data_init() -> i32; -} - -pub(crate) fn create_ble_config() -> esp_bt_controller_config_t { - esp_bt_controller_config_t { - magic: 0x5a5aa5a5, - version: 0x02307120, - controller_task_stack_size: 8192, - controller_task_prio: 200, - controller_task_run_cpu: 0, - bluetooth_mode: 1, - ble_max_act: 10, - sleep_mode: 0, - sleep_clock: 0, - ble_st_acl_tx_buf_nb: 0, - ble_hw_cca_check: 0, - ble_adv_dup_filt_max: 30, - coex_param_en: false, - ce_len_type: 0, - coex_use_hooks: false, - hci_tl_type: 1, - hci_tl_funcs: core::ptr::null_mut(), - txant_dft: 0, - rxant_dft: 0, - txpwr_dft: 9, - cfg_mask: 1, - scan_duplicate_mode: 0, - scan_duplicate_type: 0, - normal_adv_size: 20, - mesh_adv_size: 0, - coex_phy_coded_tx_rx_time_limit: 0, - hw_target_code: 0x02010000, // BLE_HW_TARGET_CODE_ESP32S3_CHIP_ECO0 - slave_ce_len_min: 5, - hw_recorrect_en: 1 << 0, - cca_thresh: 20, - dup_list_refresh_period: 0, - scan_backoff_upperlimitmax: 0, - ble_50_feat_supp: true, // BT_CTRL_50_FEATURE_SUPPORT - ble_cca_mode: 0, - } -} - -pub(crate) unsafe extern "C" fn interrupt_on(intr_num: i32) { - trace!("interrupt_on {}", intr_num); - unsafe { crate::hal::xtensa_lx::interrupt::enable_mask(1 << 1) }; -} - -pub(crate) unsafe extern "C" fn interrupt_off(_intr_num: i32) { - todo!(); -} - -pub(crate) fn btdm_controller_mem_init() { - unsafe { - btdm_controller_rom_data_init(); - } -} - -pub(crate) fn bt_periph_module_enable() { - // nothing -} - -pub(crate) fn disable_sleep_mode() { - // nothing -} - -// OSI functions - -pub(crate) unsafe extern "C" fn interrupt_set( - cpu_no: i32, - intr_source: i32, - interrupt_no: i32, - interrupt_prio: i32, -) { - trace!( - "interrupt_set {} {} {} {}", - cpu_no, - intr_source, - interrupt_no, - interrupt_prio - ); -} - -pub(crate) unsafe extern "C" fn interrupt_clear(_interrupt_source: i32, _interrupt_no: i32) { - todo!(); -} - -pub(crate) unsafe extern "C" fn interrupt_handler_set( - interrupt_no: i32, - func: extern "C" fn(*const ()), - arg: *const (), -) { - trace!( - "interrupt_handler_set {} {:?} {:?}", - interrupt_no, - func, - arg - ); - match interrupt_no { - 5 => { - ISR_INTERRUPT_5 = ( - func as *mut crate::binary::c_types::c_void, - arg as *mut crate::binary::c_types::c_void, - ) - } - 8 => { - ISR_INTERRUPT_8 = ( - func as *mut crate::binary::c_types::c_void, - arg as *mut crate::binary::c_types::c_void, - ) - } - _ => panic!("Unsupported interrupt number {}", interrupt_no), - } -} - -pub(crate) unsafe extern "C" fn coex_wifi_sleep_set(sleep: i32) { - debug!( - "ignored coex_wifi_sleep_set {} - because original implementation does the same", - sleep - ); -} - -#[allow(unused_variables, dead_code)] -pub(crate) unsafe extern "C" fn coex_core_ble_conn_dyn_prio_get( - low: *mut i32, - high: *mut i32, -) -> i32 { - extern "C" { - fn coex_core_ble_conn_dyn_prio_get(low: *mut i32, high: *mut i32) -> i32; - } - debug!("coex_core_ble_conn_dyn_prio_get"); - - #[cfg(coex)] - return coex_core_ble_conn_dyn_prio_get(low, high); - - #[cfg(not(coex))] - 0 -} - -pub(crate) unsafe extern "C" fn esp_hw_power_down() { - todo!(); -} - -pub(crate) unsafe extern "C" fn esp_hw_power_up() { - todo!(); -} - -pub(crate) unsafe extern "C" fn ets_backup_dma_copy( - _reg: u32, - _mem_addr: u32, - _num: u32, - _to_rem: i32, -) { - todo!(); -} diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32.rs b/esp-wifi/src/common_adapter/common_adapter_esp32.rs deleted file mode 100644 index e9e62275..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32.rs +++ /dev/null @@ -1,235 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::hal::prelude::ram; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); -static mut PHY_CLOCK_ENABLE_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn enable_wifi_power_domain() { - unsafe { - let rtc_cntl = &*crate::hal::peripherals::LPWR::ptr(); - - rtc_cntl - .dig_pwc() - .modify(|_, w| w.wifi_force_pd().clear_bit()); - - rtc_cntl - .dig_iso() - .modify(|_, w| w.wifi_force_iso().clear_bit()); - } -} - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - // #if CONFIG_IDF_TARGET_ESP32 - // // Update time stamp - // s_phy_rf_en_ts = esp_timer_get_time(); - // // Update WiFi MAC time before WiFi/BT common clock is enabled - // phy_update_wifi_mac_time(false, s_phy_rf_en_ts); - // #endif - - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let init_data = &PHY_INIT_DATA_DEFAULT; - - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(coex)] - coex_bt_high_prio(); - - trace!("PHY ENABLE"); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // #if CONFIG_IDF_TARGET_ESP32 - // // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock - // phy_update_wifi_mac_time(true, esp_timer_get_time()); - // #endif - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - trace!("PHY DISABLE"); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - trace!("phy_enable_clock"); - - let count = PHY_CLOCK_ENABLE_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - trace!("phy_disable_clock"); - - let count = PHY_CLOCK_ENABLE_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - }); - } -} - -/**************************************************************************** - * Name: esp_dport_access_reg_read - * - * Description: - * Read regitser value safely in SMP - * - * Input Parameters: - * reg - Register address - * - * Returned Value: - * Register value - * - ****************************************************************************/ - -#[ram] -#[no_mangle] -unsafe extern "C" fn esp_dport_access_reg_read(reg: u32) -> u32 { - let res = (reg as *mut u32).read_volatile(); - //trace!("esp_dport_access_reg_read {:x} => {:x}", reg, res); - res -} - -/**************************************************************************** - * Name: phy_enter_critical - * - * Description: - * Enter critical state - * - * Input Parameters: - * None - * - * Returned Value: - * CPU PS value - * - ****************************************************************************/ -#[ram] -#[no_mangle] -unsafe extern "C" fn phy_enter_critical() -> u32 { - trace!("phy_enter_critical"); - - core::mem::transmute(critical_section::acquire()) -} - -/**************************************************************************** - * Name: phy_exit_critical - * - * Description: - * Exit from critical state - * - * Input Parameters: - * level - CPU PS value - * - * Returned Value: - * None - * - ****************************************************************************/ -#[ram] -#[no_mangle] -unsafe extern "C" fn phy_exit_critical(level: u32) { - trace!("phy_exit_critical {}", level); - - critical_section::release(core::mem::transmute(level)); -} - -#[ram] -#[no_mangle] -unsafe extern "C" fn rtc_get_xtal() -> u32 { - use crate::hal::clock::Clock; - let xtal = crate::hal::rtc_cntl::RtcClock::get_xtal_freq(); - xtal.mhz() -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_deinit() { - trace!("misc_nvs_deinit") -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_init() -> i32 { - trace!("misc_nvs_init"); - 0 -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_restore() -> i32 { - todo!("misc_nvs_restore") -} - -#[no_mangle] -static mut g_log_mod: i32 = 0; - -#[no_mangle] -static mut g_log_level: i32 = 0; - -#[no_mangle] -pub static mut g_misc_nvs: u32 = 0; diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32c2.rs b/esp-wifi/src/common_adapter/common_adapter_esp32c2.rs deleted file mode 100644 index e714fc51..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32c2.rs +++ /dev/null @@ -1,144 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::compat::common::str_from_c; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn enable_wifi_power_domain() { - // In esp-idf, neither SOC_PM_SUPPORT_MODEM_PD or SOC_PM_SUPPORT_WIFI_PD are defined, - // which makes `esp_wifi_bt_power_domain_on` a no-op. -} - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let phy_version = get_phy_version_str(); - trace!("phy_version {}", str_from_c(phy_version as *const u8)); - - let init_data = &PHY_INIT_DATA_DEFAULT; - - #[cfg(feature = "phy-enable-usb")] - { - extern "C" { - pub fn phy_bbpll_en_usb(param: bool); - } - - phy_bbpll_en_usb(true); - } - - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(feature = "ble")] - { - extern "C" { - fn coex_pti_v2(); - } - coex_pti_v2(); - } - - trace!("PHY ENABLE"); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // Disable PHY temperature sensor - phy_xpd_tsens(); - - // #if CONFIG_IDF_TARGET_ESP32 - // // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock - // phy_update_wifi_mac_time(true, esp_timer_get_time()); - // #endif - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - trace!("PHY DISABLE"); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - trace!("phy_enable_clock"); - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - }); - - trace!("phy_enable_clock done!"); -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - trace!("phy_disable_clock"); - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - }); - - trace!("phy_disable_clock done!"); -} - -#[no_mangle] -pub extern "C" fn rtc_clk_xtal_freq_get() -> i32 { - use crate::hal::clock::Clock; - let xtal = crate::hal::rtc_cntl::RtcClock::get_xtal_freq(); - xtal.mhz() as i32 -} diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32c3.rs b/esp-wifi/src/common_adapter/common_adapter_esp32c3.rs deleted file mode 100644 index b025ff55..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32c3.rs +++ /dev/null @@ -1,172 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::compat::common::str_from_c; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn enable_wifi_power_domain() { - const SYSTEM_WIFIBB_RST: u32 = 1 << 0; - const SYSTEM_FE_RST: u32 = 1 << 1; - const SYSTEM_WIFIMAC_RST: u32 = 1 << 2; - const SYSTEM_BTBB_RST: u32 = 1 << 3; /* Bluetooth Baseband */ - const SYSTEM_BTMAC_RST: u32 = 1 << 4; /* deprecated */ - const SYSTEM_RW_BTMAC_RST: u32 = 1 << 9; /* Bluetooth MAC */ - const SYSTEM_RW_BTMAC_REG_RST: u32 = 1 << 11; /* Bluetooth MAC Regsiters */ - const SYSTEM_BTBB_REG_RST: u32 = 1 << 13; /* Bluetooth Baseband Registers */ - - const MODEM_RESET_FIELD_WHEN_PU: u32 = SYSTEM_WIFIBB_RST - | SYSTEM_FE_RST - | SYSTEM_WIFIMAC_RST - | SYSTEM_BTBB_RST - | SYSTEM_BTMAC_RST - | SYSTEM_RW_BTMAC_RST - | SYSTEM_RW_BTMAC_REG_RST - | SYSTEM_BTBB_REG_RST; - - unsafe { - let rtc_cntl = &*crate::hal::peripherals::LPWR::ptr(); - let syscon = &*crate::hal::peripherals::APB_CTRL::ptr(); - - rtc_cntl - .dig_pwc() - .modify(|_, w| w.wifi_force_pd().clear_bit()); - - syscon - .wifi_rst_en() - .modify(|r, w| w.bits(r.bits() | MODEM_RESET_FIELD_WHEN_PU)); - syscon - .wifi_rst_en() - .modify(|r, w| w.bits(r.bits() & !MODEM_RESET_FIELD_WHEN_PU)); - - rtc_cntl - .dig_iso() - .modify(|_, w| w.wifi_force_iso().clear_bit()); - } -} - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let phy_version = get_phy_version_str(); - trace!("phy_version {}", str_from_c(phy_version as *const u8)); - - let init_data = &PHY_INIT_DATA_DEFAULT; - - #[cfg(feature = "phy-enable-usb")] - { - extern "C" { - pub fn phy_bbpll_en_usb(param: bool); - } - - phy_bbpll_en_usb(true); - } - - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(feature = "ble")] - { - extern "C" { - fn coex_pti_v2(); - } - coex_pti_v2(); - } - - trace!("PHY ENABLE"); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // Disable PHY temperature sensor - phy_xpd_tsens(); - - // #if CONFIG_IDF_TARGET_ESP32 - // // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock - // phy_update_wifi_mac_time(true, esp_timer_get_time()); - // #endif - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - trace!("PHY DISABLE"); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - trace!("phy_enable_clock"); - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - }); - trace!("phy_enable_clock done!"); -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - trace!("phy_disable_clock"); - const SYSTEM_WIFI_CLK_EN_REG: u32 = 0x60026000 + 0x014; - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - }); - - trace!("phy_disable_clock done!"); -} diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32c6.rs b/esp-wifi/src/common_adapter/common_adapter_esp32c6.rs deleted file mode 100644 index 984b0b32..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32c6.rs +++ /dev/null @@ -1,136 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::compat::common::str_from_c; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn enable_wifi_power_domain() { - // In esp-idf, SOC_PMU_SUPPORTED is set which makes `esp_wifi_bt_power_domain_on` - // a no-op. -} - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let phy_version = get_phy_version_str(); - trace!("phy_version {}", str_from_c(phy_version as *const u8)); - - let init_data = &PHY_INIT_DATA_DEFAULT; - - #[cfg(feature = "phy-enable-usb")] - { - extern "C" { - pub fn phy_bbpll_en_usb(param: bool); - } - - phy_bbpll_en_usb(true); - } - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(feature = "ble")] - { - extern "C" { - fn coex_pti_v2(); - } - coex_pti_v2(); - } - - trace!("PHY ENABLE"); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // Disable PHY temperature sensor - phy_xpd_tsens(); - - // #if CONFIG_IDF_TARGET_ESP32 - // // Update WiFi MAC time before disable WiFi/BT common peripheral clock - // phy_update_wifi_mac_time(true, esp_timer_get_time()); - // #endif - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - trace!("PHY DISABLE"); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - trace!("phy_enable_clock"); - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - trace!("phy_enable_clock done!"); -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - trace!("phy_disable_clock"); - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - trace!("phy_disable_clock done!"); -} - -#[no_mangle] -pub extern "C" fn rtc_clk_xtal_freq_get() -> i32 { - // JUST SUPPORT 40MHz XTAL for now - 40 -} diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32h2.rs b/esp-wifi/src/common_adapter/common_adapter_esp32h2.rs deleted file mode 100644 index e64be726..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32h2.rs +++ /dev/null @@ -1,139 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::compat::common::str_from_c; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -// use atomic_polyfill::AtomicU32; -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn enable_wifi_power_domain() { - // In esp-idf, SOC_PMU_SUPPORTED is set which makes `esp_wifi_bt_power_domain_on` - // a no-op. -} - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let phy_version = get_phy_version_str(); - trace!("phy_version {}", str_from_c(phy_version as *const u8)); - - let init_data = &PHY_INIT_DATA_DEFAULT; - - // this would cause linker errors when the feature is activated - see https://github.com/esp-rs/esp-wifi/issues/457 - - // #[cfg(feature = "phy-enable-usb")] - // { - // extern "C" { - // pub fn phy_bbpll_en_usb(param: bool); - // } - - // phy_bbpll_en_usb(true); - // } - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(feature = "ble")] - { - extern "C" { - fn coex_pti_v2(); - } - coex_pti_v2(); - } - - trace!("PHY ENABLE"); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // Disable PHY temperature sensor - phy_xpd_tsens(); - - // #if CONFIG_IDF_TARGET_ESP32 - // // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock - // phy_update_wifi_mac_time(true, esp_timer_get_time()); - // #endif - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - trace!("PHY DISABLE"); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - trace!("phy_enable_clock"); - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - trace!("phy_enable_clock done!"); -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - trace!("phy_disable_clock"); - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - trace!("phy_disable_clock done!"); -} - -#[no_mangle] -pub extern "C" fn rtc_clk_xtal_freq_get() -> i32 { - // JUST SUPPORT 32MHz XTAL for now - 32 -} diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs b/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs deleted file mode 100644 index 01e3fb2d..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs +++ /dev/null @@ -1,228 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::hal::prelude::ram; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); -static mut PHY_CLOCK_ENABLE_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn enable_wifi_power_domain() { - const DPORT_WIFIBB_RST: u32 = 1 << 0; - const DPORT_FE_RST: u32 = 1 << 1; - const DPORT_WIFIMAC_RST: u32 = 1 << 2; - const DPORT_BTBB_RST: u32 = 1 << 3; - const DPORT_BTMAC_RST: u32 = 1 << 4; - const DPORT_RW_BTMAC_RST: u32 = 1 << 9; - - const MODEM_RESET_FIELD_WHEN_PU: u32 = DPORT_WIFIBB_RST - | DPORT_FE_RST - | DPORT_WIFIMAC_RST - | DPORT_BTBB_RST - | DPORT_BTMAC_RST - | DPORT_RW_BTMAC_RST; - - unsafe { - let rtc_cntl = &*crate::hal::peripherals::LPWR::ptr(); - - let syscon = &*crate::hal::peripherals::SYSCON::ptr(); - - rtc_cntl - .dig_pwc() - .modify(|_, w| w.wifi_force_pd().clear_bit()); - - syscon - .wifi_rst_en() - .modify(|r, w| w.bits(r.bits() | MODEM_RESET_FIELD_WHEN_PU)); - syscon - .wifi_rst_en() - .modify(|r, w| w.bits(r.bits() & !MODEM_RESET_FIELD_WHEN_PU)); - - rtc_cntl - .dig_iso() - .modify(|_, w| w.wifi_force_iso().clear_bit()); - } -} - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let init_data = &PHY_INIT_DATA_DEFAULT; - - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(feature = "ble")] - { - extern "C" { - fn coex_pti_v2(); - } - coex_pti_v2(); - } - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // Disable PHY temperature sensor - phy_xpd_tsens(); - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - let count = PHY_CLOCK_ENABLE_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - }); - - trace!("phy_enable_clock done!"); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - let count = PHY_CLOCK_ENABLE_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - }); - - trace!("phy_disable_clock done!"); - } -} - -/**************************************************************************** - * Name: phy_enter_critical - * - * Description: - * Enter critical state - * - * Input Parameters: - * None - * - * Returned Value: - * CPU PS value - * - ****************************************************************************/ -#[ram] -#[no_mangle] -unsafe extern "C" fn phy_enter_critical() -> u32 { - trace!("phy_enter_critical"); - - core::mem::transmute(critical_section::acquire()) -} - -/**************************************************************************** - * Name: phy_exit_critical - * - * Description: - * Exit from critical state - * - * Input Parameters: - * level - CPU PS value - * - * Returned Value: - * None - * - ****************************************************************************/ -#[ram] -#[no_mangle] -unsafe extern "C" fn phy_exit_critical(level: u32) { - trace!("phy_exit_critical {}", level); - - critical_section::release(core::mem::transmute(level)); -} - -#[no_mangle] -unsafe extern "C" fn abort() { - trace!("misc_nvs_deinit") -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_deinit() { - trace!("misc_nvs_deinit") -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_init() -> i32 { - trace!("misc_nvs_init"); - 0 -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_restore() -> i32 { - todo!("misc_nvs_restore") -} - -#[no_mangle] -static mut g_log_mod: i32 = 0; - -#[no_mangle] -static mut g_log_level: i32 = 0; - -#[no_mangle] -pub static mut g_misc_nvs: &u32 = unsafe { &*core::ptr::addr_of!(NVS) }; - -pub static mut NVS: u32 = 0; diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32s3.rs b/esp-wifi/src/common_adapter/common_adapter_esp32s3.rs deleted file mode 100644 index 7ca2055c..00000000 --- a/esp-wifi/src/common_adapter/common_adapter_esp32s3.rs +++ /dev/null @@ -1,194 +0,0 @@ -use super::phy_init_data::PHY_INIT_DATA_DEFAULT; -use crate::binary::include::*; -use crate::common_adapter::RADIO_CLOCKS; -use crate::hal::system::RadioClockController; -use crate::hal::system::RadioPeripherals; - -use portable_atomic::{AtomicU32, Ordering}; - -const SOC_PHY_DIG_REGS_MEM_SIZE: usize = 21 * 4; - -static mut SOC_PHY_DIG_REGS_MEM: [u8; SOC_PHY_DIG_REGS_MEM_SIZE] = [0u8; SOC_PHY_DIG_REGS_MEM_SIZE]; -static mut G_IS_PHY_CALIBRATED: bool = false; -static mut G_PHY_DIGITAL_REGS_MEM: *mut u32 = core::ptr::null_mut(); -static mut S_IS_PHY_REG_STORED: bool = false; -static mut PHY_ACCESS_REF: AtomicU32 = AtomicU32::new(0); - -pub(crate) fn phy_mem_init() { - unsafe { - G_PHY_DIGITAL_REGS_MEM = SOC_PHY_DIG_REGS_MEM.as_ptr() as *mut u32; - } -} - -pub(crate) fn enable_wifi_power_domain() { - const SYSTEM_WIFIBB_RST: u32 = 1 << 0; - const SYSTEM_FE_RST: u32 = 1 << 1; - const SYSTEM_WIFIMAC_RST: u32 = 1 << 2; - const SYSTEM_BTBB_RST: u32 = 1 << 3; /* Bluetooth Baseband */ - const SYSTEM_BTMAC_RST: u32 = 1 << 4; /* deprecated */ - const SYSTEM_RW_BTMAC_RST: u32 = 1 << 9; /* Bluetooth MAC */ - const SYSTEM_RW_BTMAC_REG_RST: u32 = 1 << 11; /* Bluetooth MAC Regsiters */ - const SYSTEM_BTBB_REG_RST: u32 = 1 << 13; /* Bluetooth Baseband Registers */ - - const MODEM_RESET_FIELD_WHEN_PU: u32 = SYSTEM_WIFIBB_RST - | SYSTEM_FE_RST - | SYSTEM_WIFIMAC_RST - | SYSTEM_BTBB_RST - | SYSTEM_BTMAC_RST - | SYSTEM_RW_BTMAC_RST - | SYSTEM_RW_BTMAC_REG_RST - | SYSTEM_BTBB_REG_RST; - - unsafe { - let rtc_cntl = &*crate::hal::peripherals::LPWR::ptr(); - let syscon = &*crate::hal::peripherals::APB_CTRL::ptr(); - - rtc_cntl - .dig_pwc() - .modify(|_, w| w.wifi_force_pd().clear_bit()); - - syscon - .wifi_rst_en() - .modify(|r, w| w.bits(r.bits() | MODEM_RESET_FIELD_WHEN_PU)); - syscon - .wifi_rst_en() - .modify(|r, w| w.bits(r.bits() & !MODEM_RESET_FIELD_WHEN_PU)); - - rtc_cntl - .dig_iso() - .modify(|_, w| w.wifi_force_iso().clear_bit()); - } -} - -pub(crate) unsafe fn phy_enable() { - let count = PHY_ACCESS_REF.fetch_add(1, Ordering::SeqCst); - if count == 0 { - critical_section::with(|_| { - phy_enable_clock(); - - if G_IS_PHY_CALIBRATED == false { - let mut cal_data: [u8; core::mem::size_of::()] = - [0u8; core::mem::size_of::()]; - - let init_data = &PHY_INIT_DATA_DEFAULT; - - #[cfg(feature = "phy-enable-usb")] - { - extern "C" { - pub fn phy_bbpll_en_usb(param: bool); - } - - phy_bbpll_en_usb(true); - } - - register_chipv7_phy( - init_data, - &mut cal_data as *mut _ - as *mut crate::binary::include::esp_phy_calibration_data_t, - esp_phy_calibration_mode_t_PHY_RF_CAL_FULL, - ); - - G_IS_PHY_CALIBRATED = true; - } else { - phy_wakeup_init(); - phy_digital_regs_load(); - } - - #[cfg(feature = "ble")] - { - extern "C" { - fn coex_pti_v2(); - } - coex_pti_v2(); - } - - trace!("PHY ENABLE"); - }); - } -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable() { - let count = PHY_ACCESS_REF.fetch_sub(1, Ordering::SeqCst); - if count == 1 { - critical_section::with(|_| { - phy_digital_regs_store(); - // Disable PHY and RF. - phy_close_rf(); - - // Disable PHY temperature sensor - phy_xpd_tsens(); - - // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - phy_disable_clock(); - - trace!("PHY DISABLE"); - }); - } -} - -fn phy_digital_regs_load() { - unsafe { - if S_IS_PHY_REG_STORED && !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(false, G_PHY_DIGITAL_REGS_MEM); - } - } -} - -fn phy_digital_regs_store() { - unsafe { - if !G_PHY_DIGITAL_REGS_MEM.is_null() { - phy_dig_reg_backup(true, G_PHY_DIGITAL_REGS_MEM); - S_IS_PHY_REG_STORED = true; - } - } -} - -pub(crate) unsafe fn phy_enable_clock() { - trace!("phy_enable_clock"); - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Phy); - }); - - trace!("phy_enable_clock done!"); -} - -#[allow(unused)] -pub(crate) unsafe fn phy_disable_clock() { - trace!("phy_disable_clock"); - critical_section::with(|_| { - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Phy); - }); - - trace!("phy_disable_clock done!"); -} - -#[no_mangle] -unsafe extern "C" fn abort() { - trace!("misc_nvs_deinit") -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_deinit() { - trace!("misc_nvs_deinit") -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_init() -> i32 { - trace!("misc_nvs_init"); - 0 -} - -#[no_mangle] -unsafe extern "C" fn misc_nvs_restore() -> i32 { - todo!("misc_nvs_restore") -} - -#[no_mangle] -static mut g_log_mod: i32 = 0; - -#[no_mangle] -static mut g_log_level: i32 = 0; - -#[no_mangle] -pub static mut g_misc_nvs: u32 = 0; diff --git a/esp-wifi/src/common_adapter/mod.rs b/esp-wifi/src/common_adapter/mod.rs deleted file mode 100644 index 63bb3747..00000000 --- a/esp-wifi/src/common_adapter/mod.rs +++ /dev/null @@ -1,390 +0,0 @@ -use core::ptr::addr_of; - -use crate::binary::include::esp_event_base_t; -use crate::binary::include::esp_timer_create_args_t; -use crate::binary::include::esp_timer_get_time; -use crate::binary::include::esp_timer_handle_t; - -use crate::compat::common::*; -use crate::compat::syslog::syslog; -use crate::compat::timer_compat::*; - -use crate::hal; - -use esp_wifi_sys::include::timespec; -use hal::rng::Rng; -use hal::system::RadioClockControl; - -use hal::macros::ram; - -#[cfg_attr(esp32c3, path = "common_adapter_esp32c3.rs")] -#[cfg_attr(esp32c2, path = "common_adapter_esp32c2.rs")] -#[cfg_attr(esp32c6, path = "common_adapter_esp32c6.rs")] -#[cfg_attr(esp32h2, path = "common_adapter_esp32h2.rs")] -#[cfg_attr(esp32, path = "common_adapter_esp32.rs")] -#[cfg_attr(esp32s3, path = "common_adapter_esp32s3.rs")] -#[cfg_attr(esp32s2, path = "common_adapter_esp32s2.rs")] -pub(crate) mod chip_specific; - -#[cfg_attr(esp32c3, path = "phy_init_data_esp32c3.rs")] -#[cfg_attr(esp32c2, path = "phy_init_data_esp32c2.rs")] -#[cfg_attr(esp32c6, path = "phy_init_data_esp32c6.rs")] -#[cfg_attr(esp32h2, path = "phy_init_data_esp32h2.rs")] -#[cfg_attr(esp32, path = "phy_init_data_esp32.rs")] -#[cfg_attr(esp32s3, path = "phy_init_data_esp32s3.rs")] -#[cfg_attr(esp32s2, path = "phy_init_data_esp32s2.rs")] -pub(crate) mod phy_init_data; - -pub(crate) static mut RANDOM_GENERATOR: Option = None; - -pub(crate) static mut RADIO_CLOCKS: Option = None; - -pub(crate) fn init_rng(rng: Rng) { - unsafe { RANDOM_GENERATOR = Some(core::mem::transmute(rng)) }; -} - -pub(crate) fn init_radio_clock_control(rcc: RadioClockControl) { - unsafe { RADIO_CLOCKS = Some(core::mem::transmute(rcc)) }; -} - -/**************************************************************************** - * Name: esp_semphr_create - * - * Description: - * Create and initialize semaphore - * - * Input Parameters: - * max - No mean - * init - semaphore initialization value - * - * Returned Value: - * Semaphore data pointer - * - ****************************************************************************/ -#[allow(unused)] -pub unsafe extern "C" fn semphr_create(max: u32, init: u32) -> *mut crate::binary::c_types::c_void { - trace!("semphr_create - max {} init {}", max, init); - sem_create(max, init) -} - -/**************************************************************************** - * Name: esp_semphr_delete - * - * Description: - * Delete semaphore - * - * Input Parameters: - * semphr - Semaphore data pointer - * - * Returned Value: - * None - * - ****************************************************************************/ -#[allow(unused)] -pub unsafe extern "C" fn semphr_delete(semphr: *mut crate::binary::c_types::c_void) { - trace!("semphr_delete {:?}", semphr); - sem_delete(semphr); -} - -/**************************************************************************** - * Name: esp_semphr_take - * - * Description: - * Wait semaphore within a certain period of time - * - * Input Parameters: - * semphr - Semaphore data pointer - * ticks - Wait system ticks - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -#[ram] -pub unsafe extern "C" fn semphr_take( - semphr: *mut crate::binary::c_types::c_void, - tick: u32, -) -> i32 { - sem_take(semphr, tick) -} - -/**************************************************************************** - * Name: esp_semphr_give - * - * Description: - * Post semaphore - * - * Input Parameters: - * semphr - Semaphore data pointer - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -#[ram] -pub unsafe extern "C" fn semphr_give(semphr: *mut crate::binary::c_types::c_void) -> i32 { - sem_give(semphr) -} - -/**************************************************************************** - * Name: esp_random_ulong - ****************************************************************************/ -#[allow(unused)] -#[ram] -#[no_mangle] -pub unsafe extern "C" fn random() -> crate::binary::c_types::c_ulong { - trace!("random"); - - if let Some(ref mut rng) = RANDOM_GENERATOR { - rng.random() - } else { - 0 - } -} - -/**************************************************************************** - * Name: esp_wifi_read_mac - * - * Description: - * Read MAC address from efuse - * - * Input Parameters: - * mac - MAC address buffer pointer - * type - MAC address type - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn read_mac(mac: *mut u8, type_: u32) -> crate::binary::c_types::c_int { - trace!("read_mac {:?} {}", mac, type_); - - let base_mac = crate::hal::efuse::Efuse::get_mac_address(); - - for i in 0..6 { - mac.offset(i as isize).write_volatile(base_mac[i]); - } - - /* ESP_MAC_WIFI_SOFTAP */ - if type_ == 1 { - let tmp = mac.offset(0).read_volatile(); - for i in 0..64 { - mac.offset(0).write_volatile(tmp | 0x02); - mac.offset(0) - .write_volatile(mac.offset(0).read_volatile() ^ (i << 2)); - - if mac.offset(0).read_volatile() != tmp { - break; - } - } - } - - // ESP_MAC_BT - if type_ == 2 { - let tmp = mac.offset(0).read_volatile(); - for i in 0..64 { - mac.offset(0).write_volatile(tmp | 0x02); - mac.offset(0) - .write_volatile(mac.offset(0).read_volatile() ^ (i << 2)); - - if mac.offset(0).read_volatile() != tmp { - break; - } - } - - mac.offset(5) - .write_volatile(mac.offset(5).read_volatile() + 1); - } - - 0 -} - -#[allow(unused)] -#[ram] -pub(crate) unsafe extern "C" fn semphr_take_from_isr(sem: *const (), hptw: *const ()) -> i32 { - trace!("sem take from isr"); - (hptw as *mut u32).write_volatile(0); - crate::common_adapter::semphr_take(sem as *mut crate::binary::c_types::c_void, 0) -} - -#[allow(unused)] -#[ram] -pub(crate) unsafe extern "C" fn semphr_give_from_isr(sem: *const (), hptw: *const ()) -> i32 { - trace!("sem give from isr"); - (hptw as *mut u32).write_volatile(0); - crate::common_adapter::semphr_give(sem as *mut crate::binary::c_types::c_void) -} - -// other functions -#[no_mangle] -pub unsafe extern "C" fn puts(s: *const u8) { - let cstr = str_from_c(s); - info!("{}", cstr); -} - -#[no_mangle] -pub unsafe extern "C" fn sprintf(dst: *mut u8, format: *const u8, args: ...) -> i32 { - let str = str_from_c(format); - trace!("sprintf format: {}", str); - - let len = crate::compat::syslog::vsnprintf(dst, 512, format, args); - - let s = str_from_c(dst); - trace!("sprintf result: {}", s); - - len -} - -#[no_mangle] -pub unsafe extern "C" fn printf(s: *const u8, args: ...) { - syslog(0, s, args); -} - -#[no_mangle] -pub unsafe extern "C" fn rtc_printf(s: *const u8, args: ...) { - syslog(0, s, args); -} - -#[no_mangle] -pub unsafe extern "C" fn phy_printf(s: *const u8, args: ...) { - syslog(0, s, args); -} - -#[no_mangle] -pub unsafe extern "C" fn coexist_printf(s: *const u8, args: ...) { - syslog(0, s, args); -} - -#[no_mangle] -pub unsafe extern "C" fn net80211_printf(s: *const u8, args: ...) { - syslog(0, s, args); -} - -#[no_mangle] -pub unsafe extern "C" fn pp_printf(s: *const u8, args: ...) { - syslog(0, s, args); -} - -// #define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id -static mut EVT: i8 = 0; -#[no_mangle] -static mut WIFI_EVENT: esp_event_base_t = unsafe { addr_of!(EVT) }; - -// stuff needed by wpa-supplicant -#[no_mangle] -pub unsafe extern "C" fn __assert_func( - file: *const u8, - line: u32, - func: *const u8, - failed_expr: *const u8, -) { - let file = str_from_c(file); - let (func_pre, func) = if func.is_null() { - ("", "") - } else { - (", function: ", str_from_c(func)) - }; - let expr = str_from_c(failed_expr); - - panic!( - "assertion \"{}\" failed: file \"{}\", line {}{}{}", - expr, file, line, func_pre, func - ); -} - -#[no_mangle] -pub unsafe extern "C" fn ets_timer_disarm(timer: *mut crate::binary::c_types::c_void) { - compat_timer_disarm(timer.cast()); -} - -#[no_mangle] -pub unsafe extern "C" fn ets_timer_done(timer: *mut crate::binary::c_types::c_void) { - compat_timer_done(timer.cast()); -} - -#[no_mangle] -pub unsafe extern "C" fn ets_timer_setfn( - ptimer: *mut crate::binary::c_types::c_void, - pfunction: *mut crate::binary::c_types::c_void, - parg: *mut crate::binary::c_types::c_void, -) { - compat_timer_setfn(ptimer.cast(), core::mem::transmute(pfunction), parg); -} - -#[no_mangle] -pub unsafe extern "C" fn ets_timer_arm( - timer: *mut crate::binary::c_types::c_void, - tmout: u32, - repeat: bool, -) { - compat_timer_arm(timer.cast(), tmout, repeat); -} - -#[no_mangle] -pub unsafe extern "C" fn ets_timer_arm_us( - timer: *mut crate::binary::c_types::c_void, - tmout: u32, - repeat: bool, -) { - compat_timer_arm_us(timer.cast(), tmout, repeat); -} - -#[no_mangle] -pub unsafe extern "C" fn gettimeofday(tv: *mut timespec, _tz: *mut ()) -> i32 { - if !tv.is_null() { - unsafe { - let microseconds = esp_timer_get_time(); - (*tv).tv_sec = (microseconds / 1_000_000) as i32; - (*tv).tv_nsec = (microseconds % 1_000_000) as i32 * 1000; - } - } - - 0 -} - -#[no_mangle] -pub unsafe extern "C" fn esp_fill_random(dst: *mut u8, len: u32) { - trace!("esp_fill_random"); - let dst = core::slice::from_raw_parts_mut(dst, len as usize); - - if let Some(ref mut rng) = RANDOM_GENERATOR { - for chunk in dst.chunks_mut(4) { - let bytes = rng.random().to_le_bytes(); - chunk.copy_from_slice(&bytes[..chunk.len()]); - } - } -} - -#[no_mangle] -pub unsafe extern "C" fn esp_timer_stop(_handle: *mut ()) { - todo!("esp_timer_stop"); -} - -#[no_mangle] -pub unsafe extern "C" fn esp_timer_delete(_handle: *mut ()) { - todo!("esp_timer_delete"); -} - -#[no_mangle] -pub unsafe extern "C" fn esp_timer_start_once(_handle: *mut (), _timeout_us: u64) -> i32 { - todo!("esp_timer_start_once"); -} - -#[no_mangle] -pub unsafe extern "C" fn esp_timer_create( - args: *const esp_timer_create_args_t, - out_handle: *mut esp_timer_handle_t, -) -> i32 { - compat_esp_timer_create(args, out_handle) -} - -#[no_mangle] -pub unsafe extern "C" fn strrchr(_s: *const (), _c: u32) -> *const u8 { - todo!("strrchr"); -} - -#[no_mangle] -#[linkage = "weak"] -pub unsafe extern "C" fn floor(v: f64) -> f64 { - libm::floor(v) -} diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32.rs deleted file mode 100644 index f051bbaa..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP32_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 3, - 3, - 0x05, - 0x09, - 0x06, - 0x05, - 0x03, - 0x06, - 0x05, - 0x04, - 0x06, - 0x04, - 0x05, - 0x00, - 0x00, - 0x00, - 0x00, - 0x05, - 0x09, - 0x06, - 0x05, - 0x03, - 0x06, - 0x05, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xfc, - 0xfc, - 0xfe, - 0xf0, - 0xf0, - 0xf0, - 0xe0, - 0xe0, - 0xe0, - 0x18, - 0x18, - 0x18, - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 84), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 72), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 66), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 60), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 56), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 52), - 0, - 1, - 1, - 2, - 2, - 3, - 4, - 5, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], -}; diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32c2.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32c2.rs deleted file mode 100644 index b761fc02..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32c2.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP32_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 0x00, - 0x00, - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x44), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4a), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x46), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x46), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x42), - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x74, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], -}; diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32c3.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32c3.rs deleted file mode 100644 index b761fc02..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32c3.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP32_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 0x00, - 0x00, - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x44), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x4a), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x46), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x46), - limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 0x42), - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x74, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], -}; diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32c6.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32c6.rs deleted file mode 100644 index d379b0be..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32c6.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 0x01, - 0x00, - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x9B, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], -}; diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs deleted file mode 100644 index d379b0be..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32h2.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 0x01, - 0x00, - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x28), - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x9B, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], -}; diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32s2.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32s2.rs deleted file mode 100644 index 055929a5..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32s2.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 0x80, - 0x00, - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4E), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4E), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x44), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x44), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x44), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x42), - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0xf1, - ], -}; diff --git a/esp-wifi/src/common_adapter/phy_init_data_esp32s3.rs b/esp-wifi/src/common_adapter/phy_init_data_esp32s3.rs deleted file mode 100644 index 71186f37..00000000 --- a/esp-wifi/src/common_adapter/phy_init_data_esp32s3.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::binary::include::esp_phy_init_data_t; - -const CONFIG_ESP_PHY_MAX_TX_POWER: u8 = 20; - -const fn limit(val: u8, low: u8, high: u8) -> u8 { - if val < low { - low - } else if val > high { - high - } else { - val - } -} - -pub(crate) static PHY_INIT_DATA_DEFAULT: esp_phy_init_data_t = esp_phy_init_data_t { - params: [ - 0x00, - 0x00, - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x44), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4a), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x46), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x46), - limit(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x42), - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x74, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], -}; diff --git a/esp-wifi/src/compat/common.rs b/esp-wifi/src/compat/common.rs deleted file mode 100644 index 9e2ab879..00000000 --- a/esp-wifi/src/compat/common.rs +++ /dev/null @@ -1,343 +0,0 @@ -#![allow(unused)] - -use core::{ - ffi::VaListImpl, - fmt::Write, - ptr::{addr_of, addr_of_mut}, -}; - -use super::queue::SimpleQueue; -use crate::{ - binary::{ - c_types::{c_int, c_void}, - include::OSI_FUNCS_TIME_BLOCKING, - }, - memory_fence::memory_fence, - preempt::current_task, - timer::yield_task, -}; - -static mut CURR_SEM: [Option; 20] = [ - None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, - None, None, None, None, -]; - -static mut PER_THREAD_SEM: [Option<*mut c_void>; 4] = [None; 4]; - -#[derive(Clone, Copy, Debug)] -struct Mutex { - locking_pid: usize, - count: u32, - recursive: bool, -} - -static mut MUTEXES: [Mutex; 10] = [Mutex { - locking_pid: 0xffff_ffff, - count: 0, - recursive: false, -}; 10]; -static mut MUTEX_IDX_CURRENT: usize = 0; - -static mut FAKE_WIFI_QUEUE: *const SimpleQueue<[u8; 8], 200> = unsafe { addr_of!(REAL_WIFI_QUEUE) }; -static mut REAL_WIFI_QUEUE: SimpleQueue<[u8; 8], 200> = SimpleQueue::new(); // first there is a ptr to the real queue - driver checks it's not null - -pub unsafe fn str_from_c<'a>(s: *const u8) -> &'a str { - let c_str = core::ffi::CStr::from_ptr(s.cast()); - core::str::from_utf8_unchecked(c_str.to_bytes()) -} - -#[no_mangle] -unsafe extern "C" fn strnlen(chars: *const u8, maxlen: usize) -> usize { - let mut len = 0; - loop { - if chars.offset(len).read_volatile() == 0 { - break; - } - len += 1; - } - - len as usize -} - -pub fn sem_create(max: u32, init: u32) -> *mut c_void { - critical_section::with(|_| unsafe { - let mut res = 0xffff; - memory_fence(); - for (i, sem) in CURR_SEM.iter().enumerate() { - memory_fence(); - if let None = *sem { - res = i; - break; - } - } - - trace!("sem created res = {} (+1)", res); - - if res != 0xffff { - memory_fence(); - CURR_SEM[res] = Some(init); - (res + 1) as *mut c_void - } else { - core::ptr::null_mut() - } - }) -} - -pub fn sem_delete(semphr: *mut c_void) { - trace!(">>> sem delete"); - critical_section::with(|_| unsafe { - CURR_SEM[semphr as usize - 1] = None; - memory_fence(); - }) -} - -pub fn sem_take(semphr: *mut c_void, tick: u32) -> i32 { - trace!(">>>> semphr_take {:?} block_time_tick {}", semphr, tick); - - let forever = tick == OSI_FUNCS_TIME_BLOCKING; - let timeout = tick as u64; - let start = crate::timer::get_systimer_count(); - - let sem_idx = semphr as usize - 1; - - 'outer: loop { - let res = critical_section::with(|_| unsafe { - memory_fence(); - if let Some(cnt) = CURR_SEM[sem_idx] { - if cnt > 0 { - CURR_SEM[sem_idx] = Some(cnt - 1); - 1 - } else { - 0 - } - } else { - 0 - } - }); - - if res == 1 { - trace!(">>>> return from semphr_take"); - return 1; - } - - if !forever && crate::timer::elapsed_time_since(start) > timeout { - break 'outer; - } - - yield_task(); - } - - trace!(">>>> return from semphr_take with timeout"); - 0 -} - -pub fn sem_give(semphr: *mut c_void) -> i32 { - trace!("semphr_give {:?}", semphr); - let sem_idx = semphr as usize - 1; - - let res = critical_section::with(|_| unsafe { - if let Some(cnt) = CURR_SEM[sem_idx] { - CURR_SEM[sem_idx] = Some(cnt + 1); - memory_fence(); - 1 - } else { - 0 - } - }); - - res -} - -pub fn thread_sem_get() -> *mut c_void { - trace!("wifi_thread_semphr_get"); - critical_section::with(|_| unsafe { - let tid = current_task(); - if let Some(sem) = PER_THREAD_SEM[tid] { - trace!("wifi_thread_semphr_get - return for {} {:?}", tid, sem); - sem - } else { - let sem = sem_create(1, 0); - trace!("wifi_thread_semphr_get - create for {} {:?}", tid, sem); - PER_THREAD_SEM[tid] = Some(sem); - sem - } - }) -} - -pub fn create_recursive_mutex() -> *mut c_void { - critical_section::with(|_| unsafe { - let ptr = &mut MUTEXES[MUTEX_IDX_CURRENT] as *mut _ as *mut Mutex; - (*ptr).recursive = true; - MUTEX_IDX_CURRENT += 1; - memory_fence(); - trace!("recursive_mutex_create called {:?}", ptr); - ptr as *mut c_void - }) -} - -/// Lock a mutex. Block until successful. -pub fn lock_mutex(mutex: *mut c_void) -> i32 { - trace!("mutex_lock ptr = {:?}", mutex); - - let ptr = mutex as *mut Mutex; - let current_task = current_task(); - - loop { - let mutex_locked = critical_section::with(|_| unsafe { - if (*ptr).count == 0 { - (*ptr).locking_pid = current_task; - (*ptr).count += 1; - true - } else if (*ptr).locking_pid == current_task { - (*ptr).count += 1; - true - } else { - false - } - }); - memory_fence(); - - if mutex_locked { - return 1; - } - - yield_task(); - } -} - -pub fn unlock_mutex(mutex: *mut c_void) -> i32 { - trace!("mutex_unlock {:?}", mutex); - - let ptr = mutex as *mut Mutex; - critical_section::with(|_| unsafe { - memory_fence(); - if (*ptr).count > 0 { - (*ptr).count -= 1; - 1 - } else { - 0 - } - }) -} - -pub fn create_wifi_queue(queue_len: c_int, item_size: c_int) -> *mut c_void { - trace!( - "wifi_create_queue len={} size={} ptr={:?} real-queue {:?} - not checked", - queue_len, - item_size, - unsafe { addr_of_mut!(FAKE_WIFI_QUEUE) }, - unsafe { addr_of_mut!(REAL_WIFI_QUEUE) }, - ); - - if item_size > 8 { - // TODO: don't assume - panic!("don't expecting the wifi queue to hold items larger than 8"); - } - - unsafe { addr_of_mut!(FAKE_WIFI_QUEUE).cast() } -} - -pub fn send_queued(queue: *mut c_void, item: *mut c_void, block_time_tick: u32) -> i32 { - trace!( - "queue_send queue {:?} item {:x} block_time_tick {}", - queue, - item as usize, - block_time_tick - ); - - // handle the WIFI_QUEUE - unsafe { - if queue != addr_of_mut!(REAL_WIFI_QUEUE).cast() { - warn!("Posting message to an unknown queue"); - return 0; - } - } - - let message = unsafe { - // SAFETY: we checked that our queue is used and it stores with 8 byte items - core::slice::from_raw_parts(item.cast::(), 8) - }; - let mut data: [u8; 8] = unwrap!(message.try_into()); - trace!("queue posting {:?}", data); - - critical_section::with(|_| { - if unsafe { REAL_WIFI_QUEUE.enqueue(data).is_ok() } { - memory_fence(); - 1 - } else { - warn!("queue_send failed"); - 0 - } - }) -} - -pub fn receive_queued(queue: *mut c_void, item: *mut c_void, block_time_tick: u32) -> i32 { - trace!( - "queue_recv {:?} item {:?} block_time_tick {}", - queue, - item, - block_time_tick - ); - - let forever = block_time_tick == OSI_FUNCS_TIME_BLOCKING; - let timeout = block_time_tick as u64; - let start = crate::timer::get_systimer_count(); - - // handle the WIFI_QUEUE - if queue != unsafe { addr_of_mut!(REAL_WIFI_QUEUE).cast() } { - warn!("Posting message to an unknown queue"); - return 0; - } - - loop { - let message = critical_section::with(|_| unsafe { REAL_WIFI_QUEUE.dequeue() }); - - if let Some(message) = message { - let out_message = unsafe { - // SAFETY: we checked that our queue is used and it stores with 8 byte items - core::slice::from_raw_parts_mut(item.cast::(), 8) - }; - out_message.copy_from_slice(&message); - trace!("received {:?}", message); - - return 1; - } - - if !forever && crate::timer::elapsed_time_since(start) > timeout { - trace!("queue_recv returns with timeout"); - return -1; - } - - yield_task(); - } -} - -/// Implementation of sleep() from newlib in esp-idf. -/// components/newlib/time.c -#[no_mangle] -unsafe extern "C" fn sleep( - seconds: crate::binary::c_types::c_uint, -) -> crate::binary::c_types::c_uint { - trace!("sleep"); - - usleep(seconds * 1_000); - 0 -} - -/// Implementation of usleep() from newlib in esp-idf. -/// components/newlib/time.c -#[no_mangle] -unsafe extern "C" fn usleep(us: u32) -> crate::binary::c_types::c_int { - trace!("usleep"); - extern "C" { - fn esp_rom_delay_us(us: u32); - } - esp_rom_delay_us(us); - 0 -} - -#[no_mangle] -unsafe extern "C" fn putchar(c: i32) -> crate::binary::c_types::c_int { - info!("putchar {}", c as u8 as char); - c -} diff --git a/esp-wifi/src/compat/malloc.rs b/esp-wifi/src/compat/malloc.rs deleted file mode 100644 index 19f9daa0..00000000 --- a/esp-wifi/src/compat/malloc.rs +++ /dev/null @@ -1,58 +0,0 @@ -use core::alloc::Layout; - -use crate::HEAP; - -pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 { - trace!("alloc {}", size); - - let total_size = size as usize + 4; - - let layout = Layout::from_size_align_unchecked(total_size, 4); - let ptr = critical_section::with(|cs| { - HEAP.borrow_ref_mut(cs) - .allocate_first_fit(layout) - .ok() - .map_or(core::ptr::null_mut(), |allocation| allocation.as_ptr()) - }); - - if ptr.is_null() { - warn!("Unable to allocate {} bytes", size); - return ptr; - } - - *(ptr as *mut usize) = total_size; - ptr.offset(4) -} - -pub unsafe extern "C" fn free(ptr: *mut u8) { - trace!("free {:?}", ptr); - - if ptr.is_null() { - return; - } - - let ptr = ptr.offset(-4); - let total_size = *(ptr as *const usize); - - let layout = Layout::from_size_align_unchecked(total_size, 4); - critical_section::with(|cs| { - HEAP.borrow_ref_mut(cs) - .deallocate(core::ptr::NonNull::new_unchecked(ptr as *mut u8), layout) - }); -} - -#[no_mangle] -pub unsafe extern "C" fn calloc(number: u32, size: usize) -> *mut u8 { - trace!("calloc {} {}", number, size); - - let total_size = number as usize * size; - let ptr = malloc(total_size) as *mut u8; - - if !ptr.is_null() { - for i in 0..total_size as isize { - ptr.offset(i).write_volatile(0); - } - } - - ptr -} diff --git a/esp-wifi/src/compat/mod.rs b/esp-wifi/src/compat/mod.rs deleted file mode 100644 index 443525f5..00000000 --- a/esp-wifi/src/compat/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod common; -pub mod malloc; -pub mod syslog; -pub mod task_runner; -pub mod timer_compat; - -pub mod queue { - pub use heapless::spsc::Queue as SimpleQueue; -} diff --git a/esp-wifi/src/compat/syslog.rs b/esp-wifi/src/compat/syslog.rs deleted file mode 100644 index 0849152b..00000000 --- a/esp-wifi/src/compat/syslog.rs +++ /dev/null @@ -1,194 +0,0 @@ -use core::{ffi::VaListImpl, fmt::Write}; - -use super::common::str_from_c; - -pub struct StrWriter { - dst: *mut u8, - capacity: usize, - len: usize, -} - -impl StrWriter { - pub fn new(dst: *mut u8, capacity: usize) -> Self { - Self { - dst, - capacity, - len: 0, - } - } - - pub fn len(&self) -> usize { - self.len - } - - fn space(&self) -> usize { - self.capacity - self.len - } - - fn write(&mut self, byte: u8) { - unsafe { - self.dst.write(byte); - self.dst = self.dst.add(1); - } - } - - pub fn append_char(&mut self, c: char) { - let mut buf = [0u8; 4]; - let char = c.encode_utf8(&mut buf); - self.append(char); - } - - pub fn append(&mut self, s: &str) { - // Write as many bytes as possible. We're writing a c string which means we don't have - // to deal with utf8 character boundaries, so this should be fine. - let len = s.len().min(self.space()); - for byte in &s.as_bytes()[..len] { - self.write(*byte); - } - - // vsnprintf's semantics: it counts unwritten bytes, too - self.len += s.len(); - } - - pub fn append_byte(&mut self, b: u8) { - if self.space() >= 1 { - self.write(b); - } - - // vsnprintf's semantics: it counts unwritten bytes, too - self.len += 1; - } -} - -impl Write for StrWriter { - fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { - self.append(s); - Ok(()) - } -} - -pub unsafe extern "C" fn syslog(_priority: u32, _format: *const u8, _args: VaListImpl) { - #[cfg(feature = "wifi-logs")] - cfg_if::cfg_if! { - if #[cfg(any(target_arch = "riscv32", all(target_arch = "xtensa", xtensa_has_vaarg)))] - { - let mut buf = [0u8; 512]; - vsnprintf(&mut buf as *mut u8, 512, _format, _args); - let res_str = str_from_c(&buf as *const u8); - info!("{}", res_str); - } - else - { - let res_str = str_from_c(_format); - info!("{}", res_str); - } - } -} - -/// Returns the number of character that would have been written if the buffer was big enough. -pub(crate) unsafe fn vsnprintf( - dst: *mut u8, - capacity: u32, - format: *const u8, - mut args: VaListImpl, -) -> i32 { - let mut res_str = StrWriter::new(dst, capacity as usize - 1); - - let s = str_from_c(format); - - let mut format_char = ' '; - let mut is_long = 0; - let mut found = false; - for c in s.chars().into_iter() { - if !found { - if c == '%' { - found = true; - } - - if !found { - res_str.append_char(c); - } - } else { - if c.is_numeric() || c == '-' || c == 'l' { - if c == 'l' { - is_long = is_long + 1; - } - // ignore - } else { - // a format char - format_char = c; - } - } - - if found && format_char != ' ' { - // have to format an arg - match format_char { - 'd' => { - if is_long < 2 { - let v = args.arg::(); - write!(res_str, "{}", v).ok(); - } else { - let v = args.arg::(); - write!(res_str, "{}", v).ok(); - } - } - - 'u' => { - if is_long < 2 { - let v = args.arg::(); - write!(res_str, "{}", v).ok(); - } else { - let v = args.arg::(); - write!(res_str, "{}", v).ok(); - } - } - - 'p' => { - let v = args.arg::(); - write!(res_str, "0x{:x}", v).ok(); - } - - 'X' => { - let v = args.arg::(); - write!(res_str, "{:02X}", v).ok(); - } - - 'x' => { - let v = args.arg::(); - write!(res_str, "{:02x}", v).ok(); - } - - 's' => { - let v = args.arg::<*const u8>(); - let vbuf = str_from_c(v); - res_str.append(vbuf); - } - - 'c' => { - let v = args.arg::(); - if v != 0 { - res_str.append_byte(v); - } - } - - '%' => { - res_str.append_char('%'); - } - - _ => { - write!(res_str, "", format_char).ok(); - } - } - - format_char = ' '; - found = false; - is_long = 0; - } - } - - let chars_written = res_str.len(); - let terminating_at = chars_written.min(capacity as usize - 1); - dst.add(terminating_at).write(0); - - chars_written as i32 -} diff --git a/esp-wifi/src/compat/task_runner.rs b/esp-wifi/src/compat/task_runner.rs deleted file mode 100644 index 2be36579..00000000 --- a/esp-wifi/src/compat/task_runner.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::{binary::c_types, compat::common::str_from_c, timer::yield_task}; - -use super::queue::SimpleQueue; - -type TaskFunc = (extern "C" fn(*mut c_types::c_void), *mut c_types::c_void); - -static mut TASK_SPAWN_QUEUE: SimpleQueue = SimpleQueue::new(); - -pub fn spawn_task( - task_func: *mut c_types::c_void, - name: *const c_types::c_char, - _stack_depth: u32, - param: *mut c_types::c_void, - prio: u32, - _task_handle: *mut c_types::c_void, - _core_id: u32, -) -> bool { - debug!( - "spawning task {}: {:?} param {:?} prio {}", - unsafe { str_from_c(name.cast()) }, - task_func, - param, - prio - ); - - // TODO: allocate a stack and insert into the task queue - - critical_section::with(|_| unsafe { - if TASK_SPAWN_QUEUE - .enqueue((core::mem::transmute(task_func), param)) - .is_ok() - { - true - } else { - warn!("task spawn queue full"); - false - } - }) -} - -/// This function runs a single C task started by the wifi stack. -pub(crate) extern "C" fn run_c_task() { - loop { - // Take a task and run it. - if let Some((f, p)) = critical_section::with(|_| unsafe { TASK_SPAWN_QUEUE.dequeue() }) { - debug!("task started: {:?} {:?}", f, p); - f(p); - debug!("task finished: {:?} {:?}", f, p); - } - yield_task(); - } -} diff --git a/esp-wifi/src/compat/timer_compat.rs b/esp-wifi/src/compat/timer_compat.rs deleted file mode 100644 index d3497f0c..00000000 --- a/esp-wifi/src/compat/timer_compat.rs +++ /dev/null @@ -1,170 +0,0 @@ -use crate::binary::{ - c_types, - include::{esp_timer_create_args_t, esp_timer_handle_t, ets_timer}, -}; - -#[derive(Clone, Copy, Debug)] -pub(crate) struct TimerCallback { - f: unsafe extern "C" fn(*mut c_types::c_void), - args: *mut c_types::c_void, -} - -impl TimerCallback { - fn new(f: unsafe extern "C" fn(*mut c_types::c_void), args: *mut c_types::c_void) -> Self { - Self { f, args } - } - - pub fn call(self) { - unsafe { (self.f)(self.args) }; - } -} - -impl From<&esp_timer_create_args_t> for TimerCallback { - fn from(args: &esp_timer_create_args_t) -> Self { - Self::new(unwrap!(args.callback), args.arg) - } -} - -#[derive(Debug, Clone, Copy)] -pub(crate) struct Timer { - pub ets_timer: *mut ets_timer, - pub started: u64, - pub timeout: u64, - pub active: bool, - pub periodic: bool, - pub callback: TimerCallback, -} - -impl Timer { - pub fn id(&self) -> usize { - self.ets_timer as usize - } -} -#[cfg(coex)] -pub(crate) static mut TIMERS: heapless::Vec = heapless::Vec::new(); -#[cfg(not(coex))] -pub(crate) static mut TIMERS: heapless::Vec = heapless::Vec::new(); - -pub fn compat_timer_arm(ets_timer: *mut ets_timer, tmout: u32, repeat: bool) { - compat_timer_arm_us(ets_timer, tmout * 1000, repeat); -} - -pub fn compat_timer_arm_us(ets_timer: *mut ets_timer, us: u32, repeat: bool) { - let systick = crate::timer::get_systimer_count(); - let ticks = crate::timer::micros_to_ticks(us as u64); - - debug!( - "timer_arm_us {:x} current: {} ticks: {} repeat: {}", - ets_timer as usize, systick, ticks, repeat - ); - - critical_section::with(|_| unsafe { - if let Some(timer) = TIMERS.iter_mut().find(|t| t.ets_timer == ets_timer) { - timer.started = systick; - timer.timeout = ticks; - timer.active = true; - timer.periodic = repeat; - } else { - debug!("timer_arm_us {:x} not found", ets_timer as usize); - } - }) -} - -pub fn compat_timer_disarm(ets_timer: *mut ets_timer) { - critical_section::with(|_| unsafe { - if let Some(timer) = TIMERS.iter_mut().find(|t| t.ets_timer == ets_timer) { - debug!("timer_disarm {:x}", timer.id()); - timer.active = false; - } else { - debug!("timer_disarm {:x} not found", ets_timer as usize); - } - }) -} - -pub fn compat_timer_done(ets_timer: *mut ets_timer) { - critical_section::with(|_| unsafe { - if let Some(timer) = TIMERS.iter_mut().find(|t| t.ets_timer == ets_timer) { - debug!("timer_done {:x}", timer.id()); - timer.active = false; - - (*ets_timer).priv_ = core::ptr::null_mut(); - (*ets_timer).expire = 0; - } else { - debug!("timer_done {:x} not found", ets_timer as usize); - } - }) -} - -pub fn compat_timer_setfn( - ets_timer: *mut ets_timer, - pfunction: unsafe extern "C" fn(*mut c_types::c_void), - parg: *mut c_types::c_void, -) { - debug!( - "timer_setfn {:x} {:?} {:?}", - ets_timer as usize, pfunction, parg - ); - - let set = critical_section::with(|_| unsafe { - if let Some(timer) = TIMERS.iter_mut().find(|t| t.ets_timer == ets_timer) { - timer.callback = TimerCallback::new(pfunction, parg); - timer.active = false; - - (*ets_timer).expire = 0; - - true - } else { - (*ets_timer).next = core::ptr::null_mut(); - (*ets_timer).period = 0; - (*ets_timer).func = None; - (*ets_timer).priv_ = core::ptr::null_mut(); - TIMERS - .push(Timer { - ets_timer, - started: 0, - timeout: 0, - active: false, - periodic: false, - callback: TimerCallback::new(pfunction, parg), - }) - .is_ok() - } - }); - - if !set { - warn!("Failed to set timer function {:x}", ets_timer as usize); - } -} - -pub fn compat_esp_timer_create( - args: *const esp_timer_create_args_t, - out_handle: *mut esp_timer_handle_t, -) -> i32 { - unsafe { - debug!("esp_timer_create {:?} {:?}", (*args).callback, (*args).arg); - } - - critical_section::with(|_| unsafe { - if TIMERS.is_full() { - // TODO: should we return -1 instead? - panic!("ran out of timers"); - } - - let ets_timer = - crate::compat::malloc::calloc(1, core::mem::size_of::()).cast::(); - - _ = TIMERS.push(Timer { - ets_timer, - started: 0, - timeout: 0, - active: false, - periodic: false, - callback: TimerCallback::from(unwrap!(args.as_ref())), - }); - - debug!("esp_timer_create {:x}", ets_timer as usize); - *out_handle = ets_timer as _; - - return 0; - }) -} diff --git a/esp-wifi/src/esp_now/mod.rs b/esp-wifi/src/esp_now/mod.rs deleted file mode 100644 index fbee9f0b..00000000 --- a/esp-wifi/src/esp_now/mod.rs +++ /dev/null @@ -1,928 +0,0 @@ -//! ESP-NOW is a kind of connectionless Wi-Fi communication protocol that is defined by Espressif. -//! -//! In ESP-NOW, application data is encapsulated in a vendor-specific action frame and then transmitted from -//! one Wi-Fi device to another without connection. CTR with CBC-MAC Protocol(CCMP) is used to protect the action -//! frame for security. ESP-NOW is widely used in smart light, remote controlling, sensor, etc. -//! -//! For more information see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html - -use core::marker::PhantomData; -use core::{cell::RefCell, fmt::Debug}; - -use portable_atomic::{AtomicBool, AtomicU8, Ordering}; - -use critical_section::Mutex; - -use crate::compat::queue::SimpleQueue; -use crate::hal::peripheral::{Peripheral, PeripheralRef}; -use crate::EspWifiInitialization; - -use crate::binary::include::*; - -/// Maximum payload length -pub const ESP_NOW_MAX_DATA_LEN: usize = 250; - -/// Broadcast address -pub const BROADCAST_ADDRESS: [u8; 6] = [0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8]; - -static RECEIVE_QUEUE: Mutex>> = - Mutex::new(RefCell::new(SimpleQueue::new())); -/// This atomic behaves like a guard, so we need strict memory ordering when -/// operating it. -/// -/// This flag indicates whether the send callback has been called after a sending. -static ESP_NOW_SEND_CB_INVOKED: AtomicBool = AtomicBool::new(false); -/// Status of esp now send, true for success, false for failure -static ESP_NOW_SEND_STATUS: AtomicBool = AtomicBool::new(true); - -macro_rules! check_error { - ($block:block) => { - match unsafe { $block } { - 0 => Ok(()), - res => Err(EspNowError::Error(Error::from_code(res as u32))), - } - }; -} - -#[repr(u32)] -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Error { - NotInitialized = 12389, - InvalidArgument = 12390, - OutOfMemory = 12391, - PeerListFull = 12392, - UnknownPeer = 12393, - NotFound = 12394, - PeerExists = 12395, - InterfaceError = 12396, - Other(u32), -} - -impl Error { - pub fn from_code(code: u32) -> Error { - match code { - 12389 => Error::NotInitialized, - 12390 => Error::InvalidArgument, - 12391 => Error::OutOfMemory, - 12392 => Error::PeerListFull, - 12393 => Error::UnknownPeer, - 12394 => Error::NotFound, - 12395 => Error::PeerExists, - 12396 => Error::InterfaceError, - _ => Error::Other(code), - } - } -} - -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum EspNowError { - Error(Error), - SendFailed, - /// Attempt to create EspNow instance twice - DuplicateInstance, -} - -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct PeerCount { - pub total_count: i32, - pub encrypted_count: i32, -} - -#[repr(u32)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum WifiPhyRate { - /// < 1 Mbps with long preamble - Rate1mL = 0, - /// < 2 Mbps with long preamble - Rate2m, - /// < 5.5 Mbps with long preamble - Rate5mL, - /// < 11 Mbps with long preamble - Rate11mL, - /// < 2 Mbps with short preamble - Rate2mS, - /// < 5.5 Mbps with short preamble - Rate5mS, - /// < 11 Mbps with short preamble - Rate11mS, - /// < 48 Mbps - Rate48m, - /// < 24 Mbps - Rate24m, - /// < 12 Mbps - Rate12m, - /// < 6 Mbps - Rate6m, - /// < 54 Mbps - Rate54m, - /// < 36 Mbps - Rate36m, - /// < 18 Mbps - Rate18m, - /// < 9 Mbps - Rate9m, - /// < MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz - RateMcs0Lgi, - /// < MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz - RateMcs1Lgi, - /// < MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz - RateMcs2Lgi, - /// < MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz - RateMcs3Lgi, - /// < MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz - RateMcs4Lgi, - /// < MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz - RateMcs5Lgi, - /// < MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz - RateMcs6Lgi, - /// < MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz - RateMcs7Lgi, - /// < MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz - RateMcs0Sgi, - /// < MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz - RateMcs1Sgi, - /// < MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz - RateMcs2Sgi, - /// < MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz - RateMcs3Sgi, - /// < MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz - RateMcs4Sgi, - /// < MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz - RateMcs5Sgi, - /// < MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz - RateMcs6Sgi, - /// < MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz - RateMcs7Sgi, - /// < 250 Kbps - RateLora250k, - /// < 500 Kbps - RateLora500k, - /// Max - RateMax, -} - -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct PeerInfo { - pub peer_address: [u8; 6], - pub lmk: Option<[u8; 16]>, - pub channel: Option, - pub encrypt: bool, - // we always use STA for now -} - -#[cfg(not(any(esp32c6)))] -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct RxControlInfo { - pub rssi: i32, - pub rate: u32, - pub sig_mode: u32, - pub mcs: u32, - pub cwb: u32, - pub smoothing: u32, - pub not_sounding: u32, - pub aggregation: u32, - pub stbc: u32, - pub fec_coding: u32, - pub sgi: u32, - pub ampdu_cnt: u32, - pub channel: u32, - pub secondary_channel: u32, - pub timestamp: u32, - pub noise_floor: i32, - pub ant: u32, - pub sig_len: u32, - pub rx_state: u32, -} - -#[cfg(any(esp32c6))] -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct RxControlInfo { - pub rssi: i32, - pub rate: u32, - pub sig_len: u32, - pub rx_state: u32, - pub dump_len: u32, - pub he_sigb_len: u32, - pub cur_single_mpdu: u32, - pub cur_bb_format: u32, - pub rx_channel_estimate_info_vld: u32, - pub rx_channel_estimate_len: u32, - pub second: u32, - pub channel: u32, - pub data_rssi: i32, - pub noise_floor: u32, - pub is_group: u32, - pub rxend_state: u32, - pub rxmatch3: u32, - pub rxmatch2: u32, - pub rxmatch1: u32, - pub rxmatch0: u32, -} - -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct ReceiveInfo { - pub src_address: [u8; 6], - pub dst_address: [u8; 6], - pub rx_control: RxControlInfo, -} - -#[derive(Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct ReceivedData { - pub len: u8, - pub data: [u8; 256], - pub info: ReceiveInfo, -} - -impl ReceivedData { - pub fn get_data(&self) -> &[u8] { - &self.data[..self.len as usize] - } -} - -impl Debug for ReceivedData { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("ReceivedData") - .field("data", &self.get_data()) - .field("info", &self.info) - .finish() - } -} - -pub struct EspNowWithWifiCreateToken { - _private: (), -} - -pub fn enable_esp_now_with_wifi( - device: crate::hal::peripherals::WIFI, -) -> (crate::hal::peripherals::WIFI, EspNowWithWifiCreateToken) { - (device, EspNowWithWifiCreateToken { _private: () }) -} - -pub struct EspNowManager<'d> { - _rc: EspNowRc<'d>, -} - -impl<'d> EspNowManager<'d> { - /// Set primary WiFi channel - /// Should only be used when using ESP-NOW without AP or STA - pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> { - check_error!({ esp_wifi_set_channel(channel, 0) }) - } - - /// Get the version of ESPNOW - pub fn get_version(&self) -> Result { - let mut version = 0u32; - check_error!({ esp_now_get_version(&mut version as *mut u32) })?; - Ok(version) - } - - /// Add a peer to the list of known peers - pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> { - let raw_peer = esp_now_peer_info_t { - peer_addr: peer.peer_address, - lmk: peer.lmk.unwrap_or_else(|| [0u8; 16]), - channel: peer.channel.unwrap_or_else(|| 0), - ifidx: wifi_interface_t_WIFI_IF_STA, - encrypt: peer.encrypt, - priv_: core::ptr::null_mut(), - }; - check_error!({ esp_now_add_peer(&raw_peer as *const _) }) - } - - /// Remove the given peer - pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> { - check_error!({ esp_now_del_peer(peer_address.as_ptr()) }) - } - - /// Modify a peer information - pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> { - let raw_peer = esp_now_peer_info_t { - peer_addr: peer.peer_address, - lmk: peer.lmk.unwrap_or_else(|| [0u8; 16]), - channel: peer.channel.unwrap_or_else(|| 0), - ifidx: wifi_interface_t_WIFI_IF_STA, - encrypt: peer.encrypt, - priv_: core::ptr::null_mut(), - }; - check_error!({ esp_now_mod_peer(&raw_peer as *const _) }) - } - - /// Get peer by MAC address - pub fn get_peer(&self, peer_address: &[u8; 6]) -> Result { - let mut raw_peer = esp_now_peer_info_t { - peer_addr: [0u8; 6], - lmk: [0u8; 16], - channel: 0, - ifidx: 0, - encrypt: false, - priv_: core::ptr::null_mut(), - }; - check_error!({ esp_now_get_peer(peer_address.as_ptr(), &mut raw_peer as *mut _) })?; - - Ok(PeerInfo { - peer_address: raw_peer.peer_addr, - lmk: if raw_peer.lmk.is_empty() { - None - } else { - Some(raw_peer.lmk) - }, - channel: if raw_peer.channel != 0 { - Some(raw_peer.channel) - } else { - None - }, - encrypt: raw_peer.encrypt, - }) - } - - /// Fetch a peer from peer list - /// - /// Only returns peers which address is unicast, for multicast/broadcast addresses, the function will - /// skip the entry and find the next in the peer list. - pub fn fetch_peer(&self, from_head: bool) -> Result { - let mut raw_peer = esp_now_peer_info_t { - peer_addr: [0u8; 6], - lmk: [0u8; 16], - channel: 0, - ifidx: 0, - encrypt: false, - priv_: core::ptr::null_mut(), - }; - check_error!({ esp_now_fetch_peer(from_head, &mut raw_peer as *mut _) })?; - - Ok(PeerInfo { - peer_address: raw_peer.peer_addr, - lmk: if raw_peer.lmk.is_empty() { - None - } else { - Some(raw_peer.lmk) - }, - channel: if raw_peer.channel != 0 { - Some(raw_peer.channel) - } else { - None - }, - encrypt: raw_peer.encrypt, - }) - } - - /// Check is peer is known - pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool { - unsafe { esp_now_is_peer_exist(peer_address.as_ptr()) } - } - - /// Get the number of peers - pub fn peer_count(&self) -> Result { - let mut peer_num = esp_now_peer_num_t { - total_num: 0, - encrypt_num: 0, - }; - check_error!({ esp_now_get_peer_num(&mut peer_num as *mut _) })?; - - Ok(PeerCount { - total_count: peer_num.total_num, - encrypted_count: peer_num.encrypt_num, - }) - } - - /// Set the primary master key - pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> { - check_error!({ esp_now_set_pmk(pmk.as_ptr()) }) - } - - /// Set wake window for esp_now to wake up in interval unit - /// - /// Window is milliseconds the chip keep waked each interval, from 0 to 65535. - pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> { - check_error!({ esp_now_set_wake_window(wake_window) }) - } - - /// Config ESPNOW rate - pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> { - check_error!({ esp_wifi_config_espnow_rate(wifi_interface_t_WIFI_IF_STA, rate as u32,) }) - } -} - -/// This is the sender part of ESP-NOW. You can get this sender by splitting -/// a `EspNow` instance. -/// -/// You need a lock when using this sender in multiple tasks. -/// **DO NOT USE** a lock implementation that disables interrupts since the -/// completion of a sending requires waiting for a callback invoked in an -/// interrupt. -pub struct EspNowSender<'d> { - _rc: EspNowRc<'d>, -} - -impl<'d> EspNowSender<'d> { - /// Send data to peer - /// - /// The peer needs to be added to the peer list first. - pub fn send<'s>( - &'s mut self, - dst_addr: &[u8; 6], - data: &[u8], - ) -> Result, EspNowError> { - ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release); - check_error!({ esp_now_send(dst_addr.as_ptr(), data.as_ptr(), data.len()) })?; - Ok(SendWaiter(PhantomData)) - } -} - -/// This struct is returned by a sync esp now send. Invoking `wait` method of this -/// struct will block current task until the callback function of esp now send is called -/// and return the status of previous sending. -/// -/// This waiter borrows the sender, so when used in multiple tasks, the lock will only be -/// released when the waiter is dropped or consumed via `wait`. -/// -/// When using a lock that disables interrupts, the waiter will block forever since -/// the callback which signals the completion of sending will never be invoked. -#[must_use] -pub struct SendWaiter<'s>(PhantomData<&'s mut EspNowSender<'s>>); - -impl<'s> SendWaiter<'s> { - /// Wait for the previous sending to complete, i.e. the send callback is invoked with - /// status of the sending. - pub fn wait(self) -> Result<(), EspNowError> { - // prevent redundant waiting since we waits for the callback in the Drop implementation - core::mem::forget(self); - while !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {} - - if ESP_NOW_SEND_STATUS.load(Ordering::Relaxed) { - Ok(()) - } else { - Err(EspNowError::SendFailed) - } - } -} - -impl<'s> Drop for SendWaiter<'s> { - /// wait for the send to complete to prevent the lock on `EspNowSender` get unlocked - /// before a callback is invoked. - fn drop(&mut self) { - while !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {} - } -} - -/// This is the sender part of ESP-NOW. You can get this sender by splitting -/// a `EspNow` instance. -pub struct EspNowReceiver<'d> { - _rc: EspNowRc<'d>, -} - -impl<'d> EspNowReceiver<'d> { - pub fn receive(&self) -> Option { - critical_section::with(|cs| { - let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs); - queue.dequeue() - }) - } -} - -/// The reference counter for properly deinit espnow after all parts are dropped. -struct EspNowRc<'d> { - rc: &'static AtomicU8, - inner: PhantomData>, -} - -impl<'d> EspNowRc<'d> { - fn new() -> Result { - static ESP_NOW_RC: AtomicU8 = AtomicU8::new(0); - // The reference counter is not 0, which means there is another instance of - // EspNow, which is not allowed - if ESP_NOW_RC.fetch_add(1, Ordering::AcqRel) != 0 { - return Err(EspNowError::DuplicateInstance); - } - - Ok(Self { - rc: &ESP_NOW_RC, - inner: PhantomData, - }) - } -} - -impl<'d> Clone for EspNowRc<'d> { - fn clone(&self) -> Self { - self.rc.fetch_add(1, Ordering::Release); - Self { - rc: self.rc, - inner: PhantomData, - } - } -} - -impl<'d> Drop for EspNowRc<'d> { - fn drop(&mut self) { - if self.rc.fetch_sub(1, Ordering::AcqRel) == 1 { - unsafe { - esp_now_unregister_recv_cb(); - esp_now_deinit(); - } - } - } -} - -/// ESP-NOW is a kind of connectionless Wi-Fi communication protocol that is defined by Espressif. -/// In ESP-NOW, application data is encapsulated in a vendor-specific action frame and then transmitted from -/// one Wi-Fi device to another without connection. CTR with CBC-MAC Protocol(CCMP) is used to protect the -/// action frame for security. ESP-NOW is widely used in smart light, remote controlling, sensor, etc. -/// -/// Currently this implementation (when used together with traditional Wi-Fi) ONLY support STA mode. -/// -pub struct EspNow<'d> { - _device: Option>, - manager: EspNowManager<'d>, - sender: EspNowSender<'d>, - receiver: EspNowReceiver<'d>, -} - -impl<'d> EspNow<'d> { - pub fn new( - inited: &EspWifiInitialization, - device: impl Peripheral

+ 'd, - ) -> Result, EspNowError> { - EspNow::new_internal(inited, Some(device.into_ref())) - } - - pub fn new_with_wifi( - inited: &EspWifiInitialization, - _token: EspNowWithWifiCreateToken, - ) -> Result, EspNowError> { - EspNow::new_internal( - inited, - None::>, - ) - } - - fn new_internal( - inited: &EspWifiInitialization, - device: Option>, - ) -> Result, EspNowError> { - if !inited.is_wifi() { - return Err(EspNowError::Error(Error::NotInitialized)); - } - - let espnow_rc = EspNowRc::new()?; - let esp_now = EspNow { - _device: device, - manager: EspNowManager { - _rc: espnow_rc.clone(), - }, - sender: EspNowSender { - _rc: espnow_rc.clone(), - }, - receiver: EspNowReceiver { _rc: espnow_rc }, - }; - check_error!({ esp_wifi_set_mode(wifi_mode_t_WIFI_MODE_STA) })?; - check_error!({ esp_wifi_start() })?; - check_error!({ - esp_wifi_set_inactive_time(wifi_interface_t_WIFI_IF_STA, crate::CONFIG.beacon_timeout) - })?; - cfg_if::cfg_if! { - if #[cfg(feature = "ps-min-modem")] { - check_error!({esp_wifi_set_ps( - crate::binary::include::wifi_ps_type_t_WIFI_PS_MIN_MODEM - )})?; - } else if #[cfg(feature = "ps-max-modem")] { - check_error!({esp_wifi_set_ps( - crate::binary::include::wifi_ps_type_t_WIFI_PS_MAX_MODEM - )})?; - } else if #[cfg(coex)] { - check_error!({esp_wifi_set_ps( - crate::binary::include::wifi_ps_type_t_WIFI_PS_MIN_MODEM - )})?; - } else { - check_error!({esp_wifi_set_ps( - crate::binary::include::wifi_ps_type_t_WIFI_PS_NONE - )})?; - } - }; - check_error!({ esp_now_init() })?; - check_error!({ esp_now_register_recv_cb(Some(rcv_cb)) })?; - check_error!({ esp_now_register_send_cb(Some(send_cb)) })?; - - esp_now.add_peer(PeerInfo { - peer_address: BROADCAST_ADDRESS, - lmk: None, - channel: None, - encrypt: false, - })?; - - Ok(esp_now) - } - - pub fn split(self) -> (EspNowManager<'d>, EspNowSender<'d>, EspNowReceiver<'d>) { - (self.manager, self.sender, self.receiver) - } - - /// Set primary WiFi channel - /// Should only be used when using ESP-NOW without AP or STA - pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> { - self.manager.set_channel(channel) - } - - /// Get the version of ESPNOW - pub fn get_version(&self) -> Result { - self.manager.get_version() - } - - /// Add a peer to the list of known peers - pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> { - self.manager.add_peer(peer) - } - - /// Remove the given peer - pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> { - self.manager.remove_peer(peer_address) - } - - /// Modify a peer information - pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> { - self.manager.modify_peer(peer) - } - - /// Get peer by MAC address - pub fn get_peer(&self, peer_address: &[u8; 6]) -> Result { - self.manager.get_peer(peer_address) - } - - /// Fetch a peer from peer list - /// - /// Only returns peers which address is unicast, for multicast/broadcast addresses, the function will - /// skip the entry and find the next in the peer list. - pub fn fetch_peer(&self, from_head: bool) -> Result { - self.manager.fetch_peer(from_head) - } - - /// Check is peer is known - pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool { - self.manager.peer_exists(peer_address) - } - - /// Get the number of peers - pub fn peer_count(&self) -> Result { - self.manager.peer_count() - } - - /// Set the primary master key - pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> { - self.manager.set_pmk(pmk) - } - - /// Set wake window for esp_now to wake up in interval unit - /// - /// Window is milliseconds the chip keep waked each interval, from 0 to 65535. - pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> { - self.manager.set_wake_window(wake_window) - } - - /// Config ESPNOW rate - pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> { - self.manager.set_rate(rate) - } - - /// Send data to peer - /// - /// The peer needs to be added to the peer list first. - pub fn send<'s>( - &'s mut self, - dst_addr: &[u8; 6], - data: &[u8], - ) -> Result, EspNowError> { - self.sender.send(dst_addr, data) - } - - /// Receive data - pub fn receive(&self) -> Option { - self.receiver.receive() - } -} - -unsafe extern "C" fn send_cb(_mac_addr: *const u8, status: esp_now_send_status_t) { - critical_section::with(|_| { - let is_success = status == esp_now_send_status_t_ESP_NOW_SEND_SUCCESS; - ESP_NOW_SEND_STATUS.store(is_success, Ordering::Relaxed); - - ESP_NOW_SEND_CB_INVOKED.store(true, Ordering::Release); - - #[cfg(feature = "async")] - asynch::ESP_NOW_TX_WAKER.wake(); - }) -} - -unsafe extern "C" fn rcv_cb( - esp_now_info: *const esp_now_recv_info_t, - data: *const u8, - data_len: i32, -) { - let src = [ - (*esp_now_info).src_addr.offset(0).read(), - (*esp_now_info).src_addr.offset(1).read(), - (*esp_now_info).src_addr.offset(2).read(), - (*esp_now_info).src_addr.offset(3).read(), - (*esp_now_info).src_addr.offset(4).read(), - (*esp_now_info).src_addr.offset(5).read(), - ]; - - let dst = [ - (*esp_now_info).des_addr.offset(0).read(), - (*esp_now_info).des_addr.offset(1).read(), - (*esp_now_info).des_addr.offset(2).read(), - (*esp_now_info).des_addr.offset(3).read(), - (*esp_now_info).des_addr.offset(4).read(), - (*esp_now_info).des_addr.offset(5).read(), - ]; - - let rx_cntl = (*esp_now_info).rx_ctrl; - #[cfg(not(any(esp32c6)))] - let rx_control = RxControlInfo { - rssi: (*rx_cntl).rssi(), - rate: (*rx_cntl).rate(), - sig_mode: (*rx_cntl).sig_mode(), - mcs: (*rx_cntl).mcs(), - cwb: (*rx_cntl).cwb(), - smoothing: (*rx_cntl).smoothing(), - not_sounding: (*rx_cntl).not_sounding(), - aggregation: (*rx_cntl).aggregation(), - stbc: (*rx_cntl).stbc(), - fec_coding: (*rx_cntl).fec_coding(), - sgi: (*rx_cntl).sgi(), - ampdu_cnt: (*rx_cntl).ampdu_cnt(), - channel: (*rx_cntl).channel(), - secondary_channel: (*rx_cntl).secondary_channel(), - timestamp: (*rx_cntl).timestamp(), - noise_floor: (*rx_cntl).noise_floor(), - ant: (*rx_cntl).ant(), - sig_len: (*rx_cntl).sig_len(), - rx_state: (*rx_cntl).rx_state(), - }; - - #[cfg(any(esp32c6))] - let rx_control = RxControlInfo { - rssi: (*rx_cntl).rssi(), - rate: (*rx_cntl).rate(), - sig_len: (*rx_cntl).sig_len(), - rx_state: (*rx_cntl).rx_state(), - dump_len: (*rx_cntl).dump_len(), - he_sigb_len: (*rx_cntl).he_sigb_len(), - cur_single_mpdu: (*rx_cntl).cur_single_mpdu(), - cur_bb_format: (*rx_cntl).cur_bb_format(), - rx_channel_estimate_info_vld: (*rx_cntl).rx_channel_estimate_info_vld(), - rx_channel_estimate_len: (*rx_cntl).rx_channel_estimate_len(), - second: (*rx_cntl).second(), - channel: (*rx_cntl).channel(), - data_rssi: (*rx_cntl).data_rssi(), - noise_floor: (*rx_cntl).noise_floor(), - is_group: (*rx_cntl).is_group(), - rxend_state: (*rx_cntl).rxend_state(), - rxmatch3: (*rx_cntl).rxmatch3(), - rxmatch2: (*rx_cntl).rxmatch2(), - rxmatch1: (*rx_cntl).rxmatch1(), - rxmatch0: (*rx_cntl).rxmatch0(), - }; - - let info = ReceiveInfo { - src_address: src, - dst_address: dst, - rx_control, - }; - let slice = core::slice::from_raw_parts(data, data_len as usize); - critical_section::with(|cs| { - let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs); - let mut data = [0u8; 256]; - data[..slice.len()].copy_from_slice(slice); - - if queue.is_full() { - queue.dequeue(); - } - - unwrap!(queue.enqueue(ReceivedData { - len: slice.len() as u8, - data: data, - info, - })); - - #[cfg(feature = "async")] - asynch::ESP_NOW_RX_WAKER.wake(); - }); -} - -#[cfg(feature = "async")] -pub use asynch::SendFuture; - -#[cfg(feature = "async")] -mod asynch { - use super::*; - use core::task::{Context, Poll}; - use embassy_sync::waitqueue::AtomicWaker; - - pub(super) static ESP_NOW_TX_WAKER: AtomicWaker = AtomicWaker::new(); - pub(super) static ESP_NOW_RX_WAKER: AtomicWaker = AtomicWaker::new(); - - impl<'d> EspNowReceiver<'d> { - /// This function takes mutable reference to self because the implementation of - /// `ReceiveFuture` is not logically thread safe. - pub fn receive_async<'r>(&'r mut self) -> ReceiveFuture<'r> { - ReceiveFuture(PhantomData) - } - } - - impl<'d> EspNowSender<'d> { - pub fn send_async<'s, 'r>( - &'s mut self, - addr: &'r [u8; 6], - data: &'r [u8], - ) -> SendFuture<'s, 'r> { - SendFuture { - _sender: PhantomData, - addr, - data, - sent: false, - } - } - } - - impl<'d> EspNow<'d> { - /// This function takes mutable reference to self because the implementation of - /// `ReceiveFuture` is not logically thread safe. - #[must_use] - pub fn receive_async<'r>(&'r mut self) -> ReceiveFuture<'r> { - self.receiver.receive_async() - } - - /// The returned future must not be dropped before it's ready to avoid getting wrong status - /// for sendings. - #[must_use] - pub fn send_async<'s, 'r>( - &'s mut self, - dst_addr: &'r [u8; 6], - data: &'r [u8], - ) -> SendFuture<'s, 'r> { - self.sender.send_async(dst_addr, data) - } - } - - pub struct SendFuture<'s, 'r> { - _sender: PhantomData<&'s mut EspNowSender<'s>>, - addr: &'r [u8; 6], - data: &'r [u8], - sent: bool, - } - - impl<'s, 'r> core::future::Future for SendFuture<'s, 'r> { - type Output = Result<(), EspNowError>; - - fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - if !self.sent { - ESP_NOW_TX_WAKER.register(cx.waker()); - ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release); - if let Err(e) = check_error!({ - esp_now_send(self.addr.as_ptr(), self.data.as_ptr(), self.data.len()) - }) { - return Poll::Ready(Err(e)); - } - self.sent = true; - } - - if !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) { - Poll::Pending - } else { - Poll::Ready(if ESP_NOW_SEND_STATUS.load(Ordering::Relaxed) { - Ok(()) - } else { - Err(EspNowError::SendFailed) - }) - } - } - } - - /// It's not logically safe to poll multiple instances of `ReceiveFuture` simultaneously - /// since the callback can only wake one future, leaving the rest of them unwakable. - pub struct ReceiveFuture<'r>(PhantomData<&'r mut EspNowReceiver<'r>>); - - impl<'r> core::future::Future for ReceiveFuture<'r> { - type Output = ReceivedData; - - fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - ESP_NOW_RX_WAKER.register(cx.waker()); - - if let Some(data) = critical_section::with(|cs| { - let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs); - queue.dequeue() - }) { - Poll::Ready(data) - } else { - Poll::Pending - } - } - } -} diff --git a/esp-wifi/src/fmt.rs b/esp-wifi/src/fmt.rs deleted file mode 100644 index 06697081..00000000 --- a/esp-wifi/src/fmt.rs +++ /dev/null @@ -1,225 +0,0 @@ -#![macro_use] -#![allow(unused_macros)] - -#[cfg(all(feature = "defmt", feature = "log"))] -compile_error!("You may not enable both `defmt` and `log` features."); - -macro_rules! assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert!($($x)*); - } - }; -} - -macro_rules! assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_eq!($($x)*); - } - }; -} - -macro_rules! assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::assert_ne!($($x)*); - } - }; -} - -macro_rules! debug_assert { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert!($($x)*); - } - }; -} - -macro_rules! debug_assert_eq { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_eq!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_eq!($($x)*); - } - }; -} - -macro_rules! debug_assert_ne { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::debug_assert_ne!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::debug_assert_ne!($($x)*); - } - }; -} - -macro_rules! todo { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::todo!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::todo!($($x)*); - } - }; -} - -macro_rules! unreachable { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::unreachable!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::unreachable!($($x)*); - } - }; -} - -macro_rules! panic { - ($($x:tt)*) => { - { - #[cfg(not(feature = "defmt"))] - ::core::panic!($($x)*); - #[cfg(feature = "defmt")] - ::defmt::panic!($($x)*); - } - }; -} - -macro_rules! trace { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::trace!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::trace!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! debug { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::debug!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::debug!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! info { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::info!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::info!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! warn { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::warn!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::warn!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -macro_rules! error { - ($s:literal $(, $x:expr)* $(,)?) => { - { - #[cfg(feature = "log")] - ::log::error!($s $(, $x)*); - #[cfg(feature = "defmt")] - ::defmt::error!($s $(, $x)*); - #[cfg(not(any(feature = "log", feature="defmt")))] - let _ = ($( & $x ),*); - } - }; -} - -#[cfg(feature = "defmt")] -macro_rules! unwrap { - ($($x:tt)*) => { - ::defmt::unwrap!($($x)*) - }; -} - -#[cfg(not(feature = "defmt"))] -macro_rules! unwrap { - ($arg:expr) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); - } - } - }; - ($arg:expr, $($msg:expr),+ $(,)? ) => { - match $crate::fmt::Try::into_result($arg) { - ::core::result::Result::Ok(t) => t, - ::core::result::Result::Err(e) => { - ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); - } - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct NoneError; - -pub trait Try { - type Ok; - type Error; - fn into_result(self) -> Result; -} - -impl Try for Option { - type Ok = T; - type Error = NoneError; - - #[inline] - fn into_result(self) -> Result { - self.ok_or(NoneError) - } -} - -impl Try for Result { - type Ok = T; - type Error = E; - - #[inline] - fn into_result(self) -> Self { - self - } -} diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs deleted file mode 100644 index e09a91aa..00000000 --- a/esp-wifi/src/lib.rs +++ /dev/null @@ -1,352 +0,0 @@ -#![no_std] -#![allow(async_fn_in_trait)] -#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))] -#![feature(c_variadic)] -#![feature(linkage)] -#![cfg_attr(feature = "async", allow(incomplete_features))] -#![doc = include_str!("../README.md")] -#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] -#![allow(rustdoc::bare_urls)] -// allow until num-derive doesn't generate this warning anymore (unknown_lints because Xtensa toolchain doesn't know about that lint, yet) -#![allow(unknown_lints)] -#![allow(non_local_definitions)] - -// MUST be the first module -mod fmt; - -use core::cell::RefCell; -use core::mem::MaybeUninit; -use core::ptr::addr_of_mut; - -use common_adapter::RADIO_CLOCKS; -use critical_section::Mutex; - -use esp_hal as hal; - -#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))] -use hal::systimer::{Alarm, Target}; - -use common_adapter::init_radio_clock_control; -use hal::system::RadioClockController; - -use fugit::MegahertzU32; -use hal::clock::Clocks; -use linked_list_allocator::Heap; -#[cfg(feature = "wifi")] -use wifi::WifiError; - -use crate::common_adapter::init_rng; -use crate::tasks::init_tasks; -use crate::timer::setup_timer_isr; -use common_adapter::chip_specific::phy_mem_init; - -mod binary { - pub use esp_wifi_sys::*; -} -mod compat; -mod preempt; - -mod timer; - -#[cfg(feature = "wifi")] -pub mod wifi; - -#[cfg(feature = "ble")] -pub mod ble; - -#[cfg(feature = "esp-now")] -pub mod esp_now; - -pub(crate) mod common_adapter; - -#[doc(hidden)] -pub mod tasks; - -pub(crate) mod memory_fence; - -use timer::{get_systimer_count, ticks_to_millis}; - -#[cfg(all(feature = "wifi", any(feature = "tcp", feature = "udp")))] -pub mod wifi_interface; - -/// Return the current systimer time in milliseconds -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 -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)] - 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(65536)] - heap_size: 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, -} - -// Validate the configuration at compile time -const _: () = { - // We explicitely use `core` assert here because this evaluation happens at compile time and won't bloat the binary - core::assert!( - CONFIG.rx_ba_win < CONFIG.dynamic_rx_buf_num, - "WiFi configuration check: rx_ba_win should not be larger than dynamic_rx_buf_num!" - ); - core::assert!(CONFIG.rx_ba_win < (CONFIG.static_rx_buf_num * 2), "WiFi configuration check: rx_ba_win should not be larger than double of the static_rx_buf_num!"); -}; - -const HEAP_SIZE: usize = crate::CONFIG.heap_size; - -#[cfg_attr(esp32, link_section = ".dram2_uninit")] -static mut HEAP_DATA: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; - -pub(crate) static HEAP: Mutex> = Mutex::new(RefCell::new(Heap::empty())); - -fn init_heap() { - critical_section::with(|cs| { - HEAP.borrow_ref_mut(cs) - .init_from_slice(unsafe { &mut *addr_of_mut!(HEAP_DATA) as &mut [MaybeUninit] }) - }); -} - -#[cfg(any(esp32c3, esp32c2, esp32c6, esp32h2))] -pub(crate) type EspWifiTimer = Alarm; - -#[cfg(any(esp32, esp32s3, esp32s2))] -pub(crate) type EspWifiTimer = - hal::timer::Timer, esp_hal::Blocking>; - -#[derive(Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[non_exhaustive] -/// An internal struct designed to make [`EspWifiInitialization`] uncreatable outside of this crate. -pub struct EspWifiInitializationInternal; - -#[derive(Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Initialized the driver for WiFi, Bluetooth or both. -pub enum EspWifiInitialization { - #[cfg(feature = "wifi")] - Wifi(EspWifiInitializationInternal), - #[cfg(feature = "ble")] - Ble(EspWifiInitializationInternal), - #[cfg(coex)] - WifiBle(EspWifiInitializationInternal), -} - -impl EspWifiInitialization { - #[allow(unused)] - fn is_wifi(&self) -> bool { - match self { - #[cfg(feature = "ble")] - EspWifiInitialization::Ble(_) => false, - _ => true, - } - } - - #[allow(unused)] - fn is_ble(&self) -> bool { - match self { - #[cfg(feature = "wifi")] - EspWifiInitialization::Wifi(_) => false, - _ => true, - } - } -} - -#[derive(Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Initialize the driver for WiFi, Bluetooth or both. -pub enum EspWifiInitFor { - #[cfg(feature = "wifi")] - Wifi, - #[cfg(feature = "ble")] - Ble, - #[cfg(coex)] - WifiBle, -} - -impl EspWifiInitFor { - #[allow(unused)] - fn is_wifi(&self) -> bool { - match self { - #[cfg(feature = "ble")] - EspWifiInitFor::Ble => false, - _ => true, - } - } - - #[allow(unused)] - fn is_ble(&self) -> bool { - match self { - #[cfg(feature = "wifi")] - EspWifiInitFor::Wifi => false, - _ => true, - } - } -} - -/// Initialize for using WiFi and or BLE -pub fn initialize( - init_for: EspWifiInitFor, - timer: EspWifiTimer, - rng: hal::rng::Rng, - radio_clocks: hal::system::RadioClockControl, - clocks: &Clocks, -) -> Result { - #[cfg(any(esp32, esp32s3, esp32s2))] - const MAX_CLOCK: u32 = 240; - - #[cfg(any(esp32c3, esp32c6))] - const MAX_CLOCK: u32 = 160; - - #[cfg(esp32c2)] - const MAX_CLOCK: u32 = 120; - - #[cfg(esp32h2)] - const MAX_CLOCK: u32 = 96; - - if clocks.cpu_clock != MegahertzU32::MHz(MAX_CLOCK) { - return Err(InitializationError::WrongClockConfig); - } - - #[cfg(esp32s3)] - unsafe { - // should be done by the HAL in `ClockControl::configure` - const ETS_UPDATE_CPU_FREQUENCY: u32 = 0x40001a4c; - - // cast to usize is just needed because of the way we run clippy in CI - let rom_ets_update_cpu_frequency: fn(ticks_per_us: u32) = - core::mem::transmute(ETS_UPDATE_CPU_FREQUENCY as usize); - - rom_ets_update_cpu_frequency(240); // we know it's 240MHz because of the check above - } - - info!("esp-wifi configuration {:?}", crate::CONFIG); - - crate::common_adapter::chip_specific::enable_wifi_power_domain(); - - init_heap(); - phy_mem_init(); - init_radio_clock_control(radio_clocks); - init_rng(rng); - init_tasks(); - setup_timer_isr(timer); - wifi_set_log_verbose(); - init_clocks(); - - #[cfg(coex)] - match crate::wifi::coex_initialize() { - 0 => {} - error => return Err(InitializationError::General(error)), - } - - #[cfg(feature = "wifi")] - if init_for.is_wifi() { - debug!("wifi init"); - // wifi init - crate::wifi::wifi_init()?; - } - - #[cfg(feature = "ble")] - if init_for.is_ble() { - // ble init - // for some reason things don't work when initializing things the other way around - // while the original implementation in NuttX does it like that - debug!("ble init"); - crate::ble::ble_init(); - } - - match init_for { - #[cfg(feature = "wifi")] - EspWifiInitFor::Wifi => Ok(EspWifiInitialization::Wifi(EspWifiInitializationInternal)), - #[cfg(feature = "ble")] - EspWifiInitFor::Ble => Ok(EspWifiInitialization::Ble(EspWifiInitializationInternal)), - #[cfg(coex)] - EspWifiInitFor::WifiBle => Ok(EspWifiInitialization::WifiBle( - EspWifiInitializationInternal, - )), - } -} - -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Error which can be returned during [`initialize`]. -pub enum InitializationError { - General(i32), - #[cfg(feature = "wifi")] - WifiError(WifiError), - WrongClockConfig, -} - -#[cfg(feature = "wifi")] -impl From for InitializationError { - fn from(value: WifiError) -> Self { - InitializationError::WifiError(value) - } -} - -/// Enable verbose logging within the WiFi driver -/// Does nothing unless the `wifi-logs` feature is enabled. -pub fn wifi_set_log_verbose() { - #[cfg(feature = "wifi-logs")] - unsafe { - use crate::binary::include::{ - esp_wifi_internal_set_log_level, wifi_log_level_t_WIFI_LOG_VERBOSE, - }; - - esp_wifi_internal_set_log_level(wifi_log_level_t_WIFI_LOG_VERBOSE); - } -} - -fn init_clocks() { - unsafe { - unwrap!(RADIO_CLOCKS.as_mut()).init_clocks(); - } -} diff --git a/esp-wifi/src/memory_fence.rs b/esp-wifi/src/memory_fence.rs deleted file mode 100644 index c4e00f6c..00000000 --- a/esp-wifi/src/memory_fence.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub(crate) fn memory_fence() { - #[cfg(target_arch = "xtensa")] - unsafe { - core::arch::asm!("memw"); - } - - #[cfg(target_arch = "riscv")] - unsafe { - core::arch::asm!("fence"); - } -} diff --git a/esp-wifi/src/preempt/mod.rs b/esp-wifi/src/preempt/mod.rs deleted file mode 100644 index ebd7b601..00000000 --- a/esp-wifi/src/preempt/mod.rs +++ /dev/null @@ -1,48 +0,0 @@ -macro_rules! sum { - ($h:expr) => ($h); - ($h:expr, $($t:expr),*) => - ($h + sum!($($t),*)); -} - -macro_rules! task_stack { - ($($task_stack_size:literal),+) => { - const TASK_COUNT: usize = [$($task_stack_size),+].len(); - const TASK_STACK_SIZE: [usize; TASK_COUNT] = [$($task_stack_size),+]; - const TOTAL_STACK_SIZE: usize = sum!($($task_stack_size),+); - const MAX_TASK: usize = TASK_COUNT + 1; // +1 for the user program - - static mut TASK_STACK: [u8; TOTAL_STACK_SIZE] = [0u8; TOTAL_STACK_SIZE]; - }; -} - -static mut TASK_TOP: usize = 1; -static mut CTX_NOW: usize = 0; - -fn allocate_task() -> usize { - unsafe { - let i = TASK_TOP - 1; - CTX_NOW = TASK_TOP; - TASK_TOP += 1; - i - } -} - -fn next_task() { - unsafe { - CTX_NOW = (CTX_NOW + 1) % TASK_TOP; - } -} - -pub fn current_task() -> usize { - unsafe { CTX_NOW } -} - -#[cfg(coex)] -task_stack!(8192, 8192, 8192); - -#[cfg(not(coex))] -task_stack!(8192, 8192); - -#[cfg_attr(target_arch = "riscv32", path = "preempt_riscv.rs")] -#[cfg_attr(target_arch = "xtensa", path = "preempt_xtensa.rs")] -pub mod preempt; diff --git a/esp-wifi/src/preempt/preempt_riscv.rs b/esp-wifi/src/preempt/preempt_riscv.rs deleted file mode 100644 index 872aeb33..00000000 --- a/esp-wifi/src/preempt/preempt_riscv.rs +++ /dev/null @@ -1,167 +0,0 @@ -use super::*; - -use crate::hal::interrupt::TrapFrame; -use core::ptr::addr_of; - -#[derive(Debug, Default, Clone, Copy)] -pub struct Context { - trap_frame: TrapFrame, - _running: bool, -} - -static mut CTX_TASKS: [Context; MAX_TASK] = [Context { - trap_frame: TrapFrame { - ra: 0, - t0: 0, - t1: 0, - t2: 0, - t3: 0, - t4: 0, - t5: 0, - t6: 0, - a0: 0, - a1: 0, - a2: 0, - a3: 0, - a4: 0, - a5: 0, - a6: 0, - a7: 0, - s0: 0, - s1: 0, - s2: 0, - s3: 0, - s4: 0, - s5: 0, - s6: 0, - s7: 0, - s8: 0, - s9: 0, - s10: 0, - s11: 0, - gp: 0, - tp: 0, - sp: 0, - pc: 0, - mstatus: 0, - mcause: 0, - mtval: 0, - }, - _running: false, -}; MAX_TASK]; - -pub fn task_create(task: extern "C" fn()) { - unsafe { - let i = allocate_task(); - - CTX_TASKS[i].trap_frame.pc = task as usize; - - let task_stack_size = TASK_STACK_SIZE[i]; - - // stack must be aligned by 16 - let task_stack_ptr = addr_of!(TASK_STACK) as usize - + (task_stack_size as usize * i as usize) - + task_stack_size as usize - - 4; - let stack_ptr = task_stack_ptr - (task_stack_ptr % 0x10); - CTX_TASKS[i].trap_frame.sp = stack_ptr; - } -} - -pub fn restore_task_context(id: usize, trap_frame: &mut TrapFrame) -> usize { - unsafe { - trap_frame.ra = CTX_TASKS[id].trap_frame.ra; - trap_frame.sp = CTX_TASKS[id].trap_frame.sp; - trap_frame.a0 = CTX_TASKS[id].trap_frame.a0; - trap_frame.a1 = CTX_TASKS[id].trap_frame.a1; - trap_frame.a2 = CTX_TASKS[id].trap_frame.a2; - trap_frame.a3 = CTX_TASKS[id].trap_frame.a3; - trap_frame.a4 = CTX_TASKS[id].trap_frame.a4; - trap_frame.a5 = CTX_TASKS[id].trap_frame.a5; - trap_frame.a6 = CTX_TASKS[id].trap_frame.a6; - trap_frame.a7 = CTX_TASKS[id].trap_frame.a7; - trap_frame.t0 = CTX_TASKS[id].trap_frame.t0; - trap_frame.t1 = CTX_TASKS[id].trap_frame.t1; - trap_frame.t2 = CTX_TASKS[id].trap_frame.t2; - trap_frame.t3 = CTX_TASKS[id].trap_frame.t3; - trap_frame.t4 = CTX_TASKS[id].trap_frame.t4; - trap_frame.t5 = CTX_TASKS[id].trap_frame.t5; - trap_frame.t6 = CTX_TASKS[id].trap_frame.t6; - trap_frame.s0 = CTX_TASKS[id].trap_frame.s0; - trap_frame.s1 = CTX_TASKS[id].trap_frame.s1; - trap_frame.s2 = CTX_TASKS[id].trap_frame.s2; - trap_frame.s3 = CTX_TASKS[id].trap_frame.s3; - trap_frame.s4 = CTX_TASKS[id].trap_frame.s4; - trap_frame.s5 = CTX_TASKS[id].trap_frame.s5; - trap_frame.s6 = CTX_TASKS[id].trap_frame.s6; - trap_frame.s7 = CTX_TASKS[id].trap_frame.s7; - trap_frame.s8 = CTX_TASKS[id].trap_frame.s8; - trap_frame.s9 = CTX_TASKS[id].trap_frame.s9; - trap_frame.s10 = CTX_TASKS[id].trap_frame.s10; - trap_frame.s11 = CTX_TASKS[id].trap_frame.s11; - trap_frame.gp = CTX_TASKS[id].trap_frame.gp; - trap_frame.tp = CTX_TASKS[id].trap_frame.tp; - - CTX_TASKS[id].trap_frame.pc - } -} - -pub fn save_task_context(id: usize, pc: usize, trap_frame: &TrapFrame) { - unsafe { - CTX_TASKS[id].trap_frame.ra = trap_frame.ra; - CTX_TASKS[id].trap_frame.sp = trap_frame.sp; - CTX_TASKS[id].trap_frame.a0 = trap_frame.a0; - CTX_TASKS[id].trap_frame.a1 = trap_frame.a1; - CTX_TASKS[id].trap_frame.a2 = trap_frame.a2; - CTX_TASKS[id].trap_frame.a3 = trap_frame.a3; - CTX_TASKS[id].trap_frame.a4 = trap_frame.a4; - CTX_TASKS[id].trap_frame.a5 = trap_frame.a5; - CTX_TASKS[id].trap_frame.a6 = trap_frame.a6; - CTX_TASKS[id].trap_frame.a7 = trap_frame.a7; - CTX_TASKS[id].trap_frame.t0 = trap_frame.t0; - CTX_TASKS[id].trap_frame.t1 = trap_frame.t1; - CTX_TASKS[id].trap_frame.t2 = trap_frame.t2; - CTX_TASKS[id].trap_frame.t3 = trap_frame.t3; - CTX_TASKS[id].trap_frame.t4 = trap_frame.t4; - CTX_TASKS[id].trap_frame.t5 = trap_frame.t5; - CTX_TASKS[id].trap_frame.t6 = trap_frame.t6; - CTX_TASKS[id].trap_frame.s0 = trap_frame.s0; - CTX_TASKS[id].trap_frame.s1 = trap_frame.s1; - CTX_TASKS[id].trap_frame.s2 = trap_frame.s2; - CTX_TASKS[id].trap_frame.s3 = trap_frame.s3; - CTX_TASKS[id].trap_frame.s4 = trap_frame.s4; - CTX_TASKS[id].trap_frame.s5 = trap_frame.s5; - CTX_TASKS[id].trap_frame.s6 = trap_frame.s6; - CTX_TASKS[id].trap_frame.s7 = trap_frame.s7; - CTX_TASKS[id].trap_frame.s8 = trap_frame.s8; - CTX_TASKS[id].trap_frame.s9 = trap_frame.s9; - CTX_TASKS[id].trap_frame.s10 = trap_frame.s10; - CTX_TASKS[id].trap_frame.s11 = trap_frame.s11; - CTX_TASKS[id].trap_frame.gp = trap_frame.gp; - CTX_TASKS[id].trap_frame.tp = trap_frame.tp; - - CTX_TASKS[id].trap_frame.pc = pc; - } -} - -pub fn task_switch(trap_frame: &mut TrapFrame) { - let old_mepc = trap_frame.pc; - - save_task_context(current_task(), old_mepc, trap_frame); - - next_task(); - - let new_pc = restore_task_context(current_task(), trap_frame); - trap_frame.pc = new_pc; - - // debug aid! remove when not needed anymore!!!!! - // static mut CNT: u32 = 0; - // if CTX_NOW == 0 { - // if CNT < 5_000 { - // CNT += 1; - // } else { - // CNT = 0; - // info!("@@@ Task {} PC = {:x} {:?}", CTX_NOW, new_pc, trap_frame); - // } - // } -} diff --git a/esp-wifi/src/preempt/preempt_xtensa.rs b/esp-wifi/src/preempt/preempt_xtensa.rs deleted file mode 100644 index d67dd7e6..00000000 --- a/esp-wifi/src/preempt/preempt_xtensa.rs +++ /dev/null @@ -1,125 +0,0 @@ -use core::ptr::addr_of; - -use super::*; - -use crate::hal::trapframe::TrapFrame; - -#[derive(Debug, Clone, Copy)] -pub struct TaskContext { - trap_frame: TrapFrame, -} - -static mut CTX_TASKS: [TaskContext; MAX_TASK] = [TaskContext { - trap_frame: TrapFrame { - PC: 0, - PS: 0, - A0: 0, - A1: 0, - A2: 0, - A3: 0, - A4: 0, - A5: 0, - A6: 0, - A7: 0, - A8: 0, - A9: 0, - A10: 0, - A11: 0, - A12: 0, - A13: 0, - A14: 0, - A15: 0, - SAR: 0, - EXCCAUSE: 0, - EXCVADDR: 0, - LBEG: 0, - LEND: 0, - LCOUNT: 0, - THREADPTR: 0, - SCOMPARE1: 0, - BR: 0, - ACCLO: 0, - ACCHI: 0, - M0: 0, - M1: 0, - M2: 0, - M3: 0, - F64R_LO: 0, - F64R_HI: 0, - F64S: 0, - FCR: 0, - FSR: 0, - F0: 0, - F1: 0, - F2: 0, - F3: 0, - F4: 0, - F5: 0, - F6: 0, - F7: 0, - F8: 0, - F9: 0, - F10: 0, - F11: 0, - F12: 0, - F13: 0, - F14: 0, - F15: 0, - }, -}; MAX_TASK]; - -pub fn task_create(task: extern "C" fn()) { - unsafe { - let i = allocate_task(); - - CTX_TASKS[i].trap_frame.PC = task as u32; - - let task_stack_size = TASK_STACK_SIZE[i]; - - // stack must be aligned by 16 - let task_stack_ptr = (addr_of!(TASK_STACK) as *const _ as usize - + (task_stack_size as usize * i as usize) - + task_stack_size as usize - - 4) as u32; - let stack_ptr = task_stack_ptr - (task_stack_ptr % 0x10); - CTX_TASKS[i].trap_frame.A1 = stack_ptr; - - CTX_TASKS[i].trap_frame.PS = 0x00040000 | (1 & 3) << 16; // For windowed ABI set WOE and CALLINC (pretend task was 'call4'd). - - CTX_TASKS[i].trap_frame.A0 = 0; - - *((task_stack_ptr - 4) as *mut u32) = 0; - *((task_stack_ptr - 8) as *mut u32) = 0; - *((task_stack_ptr - 12) as *mut u32) = stack_ptr; - *((task_stack_ptr - 16) as *mut u32) = 0; - } -} - -fn restore_task_context(id: usize, trap_frame: &mut TrapFrame) { - unsafe { - *trap_frame = CTX_TASKS[id].trap_frame; - } -} - -fn save_task_context(id: usize, trap_frame: &TrapFrame) { - unsafe { - CTX_TASKS[id].trap_frame = *trap_frame; - } -} - -pub fn task_switch(trap_frame: &mut TrapFrame) { - save_task_context(current_task(), trap_frame); - next_task(); - restore_task_context(current_task(), trap_frame); - - // debug aid! remove when not needed anymore!!!!! - // static mut CNT: u32 = 0; - // if CTX_NOW == 0 { - // if CNT < 2_000 { - // CNT += 1; - // } else { - // CNT = 0; - // info!("@@@ Task {} {:?} ", 1, CTX_TASKS[1].trap_frame.PC); - // } - // } -} diff --git a/esp-wifi/src/tasks.rs b/esp-wifi/src/tasks.rs deleted file mode 100644 index 73fc31d4..00000000 --- a/esp-wifi/src/tasks.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::{ - compat::{self, queue::SimpleQueue, timer_compat::TIMERS}, - memory_fence::memory_fence, - preempt::preempt::task_create, - timer::{get_systimer_count, yield_task}, -}; - -pub fn init_tasks() { - task_create(compat::task_runner::run_c_task); - task_create(timer_task); - - // if coex then we know we have ble + wifi - #[cfg(coex)] - task_create(compat::task_runner::run_c_task); -} - -pub extern "C" fn timer_task() { - loop { - let mut to_run = SimpleQueue::<_, 20>::new(); - - let current_timestamp = get_systimer_count(); - critical_section::with(|_| unsafe { - memory_fence(); - for timer in TIMERS.iter_mut() { - if timer.active - && crate::timer::time_diff(timer.started, current_timestamp) >= timer.timeout - { - debug!("timer is due.... {:x}", timer.id()); - - if to_run.enqueue(timer.callback).is_err() { - break; - } - - timer.active = timer.periodic; - }; - } - memory_fence(); - }); - - // run the due timer callbacks NOT in an interrupt free context - while let Some(callback) = to_run.dequeue() { - trace!("trigger timer...."); - callback.call(); - trace!("timer callback called"); - } - - yield_task(); - } -} diff --git a/esp-wifi/src/timer/mod.rs b/esp-wifi/src/timer/mod.rs deleted file mode 100644 index a0697ffe..00000000 --- a/esp-wifi/src/timer/mod.rs +++ /dev/null @@ -1,51 +0,0 @@ -#[cfg_attr(esp32, path = "timer_esp32.rs")] -#[cfg_attr(esp32c2, path = "timer_esp32c2.rs")] -#[cfg_attr(esp32c3, path = "timer_esp32c3.rs")] -#[cfg_attr(esp32c6, path = "timer_esp32c6.rs")] -#[cfg_attr(esp32h2, path = "timer_esp32h2.rs")] -#[cfg_attr(esp32s3, path = "timer_esp32s3.rs")] -#[cfg_attr(esp32s2, path = "timer_esp32s2.rs")] -mod chip_specific; - -#[cfg_attr(any(esp32, esp32s2, esp32s3), path = "xtensa.rs")] -#[cfg_attr(any(esp32c2, esp32c3, esp32c6, esp32h2), path = "riscv.rs")] -mod arch_specific; - -pub use arch_specific::*; -pub use chip_specific::*; - -pub fn setup_timer_isr(timebase: TimeBase) { - setup_radio_isr(); - - setup_timer(timebase); - - setup_multitasking(); - - yield_task(); -} - -#[allow(unused)] -pub fn micros_to_ticks(us: u64) -> u64 { - us * (TICKS_PER_SECOND / 1_000_000) -} - -#[allow(unused)] -pub fn millis_to_ticks(ms: u64) -> u64 { - ms * (TICKS_PER_SECOND / 1_000) -} - -#[allow(unused)] -pub fn ticks_to_micros(ticks: u64) -> u64 { - ticks / (TICKS_PER_SECOND / 1_000_000) -} - -#[allow(unused)] -pub fn ticks_to_millis(ticks: u64) -> u64 { - ticks / (TICKS_PER_SECOND / 1_000) -} - -/// Do not call this in a critical section! -pub fn elapsed_time_since(start: u64) -> u64 { - let now = get_systimer_count(); - time_diff(start, now) -} diff --git a/esp-wifi/src/timer/riscv.rs b/esp-wifi/src/timer/riscv.rs deleted file mode 100644 index 510d1797..00000000 --- a/esp-wifi/src/timer/riscv.rs +++ /dev/null @@ -1,112 +0,0 @@ -use core::cell::RefCell; - -use critical_section::Mutex; - -use crate::{ - hal::{ - interrupt::{self, TrapFrame}, - peripherals::{self, Interrupt}, - riscv, - systimer::{Alarm, Periodic, SystemTimer, Target}, - }, - preempt::preempt::task_switch, -}; - -#[cfg(any(feature = "esp32c6", feature = "esp32h2"))] -use peripherals::INTPRI as SystemPeripheral; -#[cfg(not(any(feature = "esp32c6", feature = "esp32h2")))] -use peripherals::SYSTEM as SystemPeripheral; - -/// The timer responsible for time slicing. -pub type TimeBase = Alarm; -static ALARM0: Mutex>>> = - Mutex::new(RefCell::new(None)); -const TIMESLICE_FREQUENCY: fugit::HertzU32 = fugit::HertzU32::from_raw(crate::CONFIG.tick_rate_hz); - -// Time keeping - -pub const TICKS_PER_SECOND: u64 = 16_000_000; - -pub fn setup_timer(systimer: TimeBase) { - // make sure the scheduling won't start before everything is setup - riscv::interrupt::disable(); - - let mut alarm0 = systimer.into_periodic(); - alarm0.set_period(TIMESLICE_FREQUENCY.into_duration()); - alarm0.clear_interrupt(); - alarm0.enable_interrupt(true); - - critical_section::with(|cs| ALARM0.borrow_ref_mut(cs).replace(alarm0)); - - unsafe { - interrupt::bind_interrupt( - Interrupt::SYSTIMER_TARGET0, - core::mem::transmute(systimer_target0 as *const ()), - ); - } - - unwrap!(interrupt::enable( - Interrupt::SYSTIMER_TARGET0, - interrupt::Priority::Priority1, - )); -} - -pub fn setup_multitasking() { - unwrap!(interrupt::enable( - Interrupt::FROM_CPU_INTR3, - interrupt::Priority::Priority1, - )); - - unsafe { - riscv::interrupt::enable(); - } -} - -extern "C" fn systimer_target0(trap_frame: &mut TrapFrame) { - // clear the systimer intr - critical_section::with(|cs| { - unwrap!(ALARM0.borrow_ref_mut(cs).as_mut()).clear_interrupt(); - }); - - task_switch(trap_frame); -} - -#[no_mangle] -extern "C" fn FROM_CPU_INTR3(trap_frame: &mut TrapFrame) { - unsafe { - // clear FROM_CPU_INTR3 - (&*SystemPeripheral::PTR) - .cpu_intr_from_cpu_3() - .modify(|_, w| w.cpu_intr_from_cpu_3().clear_bit()); - } - - critical_section::with(|cs| { - let mut alarm0 = ALARM0.borrow_ref_mut(cs); - let alarm0 = unwrap!(alarm0.as_mut()); - - alarm0.set_period(TIMESLICE_FREQUENCY.into_duration()); - alarm0.clear_interrupt(); - }); - - task_switch(trap_frame); -} - -pub fn yield_task() { - unsafe { - (&*SystemPeripheral::PTR) - .cpu_intr_from_cpu_3() - .modify(|_, w| w.cpu_intr_from_cpu_3().set_bit()); - } -} - -/// Current systimer count value -/// A tick is 1 / 16_000_000 seconds -pub fn get_systimer_count() -> u64 { - SystemTimer::now() -} - -// TODO: use an Instance type instead... -pub fn time_diff(start: u64, end: u64) -> u64 { - // 52-bit wrapping sub - end.wrapping_sub(start) & 0x000f_ffff_ffff_ffff -} diff --git a/esp-wifi/src/timer/timer_esp32.rs b/esp-wifi/src/timer/timer_esp32.rs deleted file mode 100644 index 3a59a985..00000000 --- a/esp-wifi/src/timer/timer_esp32.rs +++ /dev/null @@ -1,94 +0,0 @@ -#[cfg(any(feature = "wifi", feature = "ble"))] -#[allow(unused_imports)] -use crate::hal::{interrupt, peripherals}; - -pub fn setup_radio_isr() { - // wifi enabled in set_isr - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::RWBT, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::BT_BB, - interrupt::Priority::Priority1, - )); - - // It's a mystery why these interrupts are enabled now since it worked without this before - // Now at least without disabling these nothing will work - interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::ETH_MAC); - interrupt::disable(crate::hal::Cpu::ProCpu, peripherals::Interrupt::UART0); - } -} - -#[cfg(feature = "ble")] -#[allow(non_snake_case)] -#[no_mangle] -fn Software0(_level: u32) { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_7; - trace!("interrupt Software0 {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_MAC() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn RWBT() { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_5; - trace!("interrupt RWBT {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn RWBLE() { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_5; - trace!("interrupt RWBLE {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn BT_BB() { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_8; - trace!("interrupt BT_BB {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} diff --git a/esp-wifi/src/timer/timer_esp32c2.rs b/esp-wifi/src/timer/timer_esp32c2.rs deleted file mode 100644 index 452790dc..00000000 --- a/esp-wifi/src/timer/timer_esp32c2.rs +++ /dev/null @@ -1,99 +0,0 @@ -#[cfg(any(feature = "wifi", feature = "ble"))] -#[allow(unused_imports)] -use crate::{ - binary, - hal::{interrupt, peripherals::Interrupt}, -}; - -pub fn setup_radio_isr() { - // wifi enabled in set_isr - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - Interrupt::LP_TIMER, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::BT_MAC, - interrupt::Priority::Priority1 - )); - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_MAC() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_PWR() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_PWR {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn LP_TIMER() { - unsafe { - trace!("LP_TIMER interrupt"); - - let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_7; - - trace!("interrupt LP_TIMER {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - trace!("interrupt LP_TIMER call"); - - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - trace!("LP_TIMER done"); - } - - trace!("interrupt LP_TIMER done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn BT_MAC() { - unsafe { - trace!("BT_MAC interrupt"); - - let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_4; - - trace!("interrupt BT_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - trace!("interrupt BT_MAC call"); - - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - trace!("BT_MAC done"); - } - - trace!("interrupt BT_MAC done"); - }; -} diff --git a/esp-wifi/src/timer/timer_esp32c3.rs b/esp-wifi/src/timer/timer_esp32c3.rs deleted file mode 100644 index d71682d3..00000000 --- a/esp-wifi/src/timer/timer_esp32c3.rs +++ /dev/null @@ -1,110 +0,0 @@ -#[cfg(any(feature = "wifi", feature = "ble"))] -#[allow(unused_imports)] -use crate::{ - binary, - hal::{interrupt, peripherals::Interrupt}, -}; - -pub fn setup_radio_isr() { - // wifi enabled in set_isr - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - Interrupt::RWBT, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::RWBLE, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::BT_BB, - interrupt::Priority::Priority1 - )); - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_MAC() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_PWR() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_PWR {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn RWBT() { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::BT_INTERRUPT_FUNCTION5; - - trace!("interrupt RWBT {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 5 done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn RWBLE() { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::BT_INTERRUPT_FUNCTION5; - - trace!("interrupt RWBLE {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 5 done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn BT_BB(_trap_frame: &mut crate::hal::interrupt::TrapFrame) { - unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::BT_INTERRUPT_FUNCTION8; - - trace!("interrupt BT_BB {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 8 done"); - }; -} diff --git a/esp-wifi/src/timer/timer_esp32c6.rs b/esp-wifi/src/timer/timer_esp32c6.rs deleted file mode 100644 index 992c0b5a..00000000 --- a/esp-wifi/src/timer/timer_esp32c6.rs +++ /dev/null @@ -1,112 +0,0 @@ -#[cfg(any(feature = "wifi", feature = "ble"))] -#[allow(unused_imports)] -use crate::{ - binary, - hal::{interrupt, peripherals::Interrupt}, -}; - -use crate::hal::peripherals; - -pub fn setup_radio_isr() { - // wifi enabled in set_isr - - // make sure to disable WIFI_BB/MODEM_PERI_TIMEOUT by mapping it to CPU interrupt 31 which is masked by default - // for some reason for this interrupt, mapping it to 0 doesn't deactivate it - let interrupt_core0 = unsafe { &*peripherals::INTERRUPT_CORE0::PTR }; - interrupt_core0 - .wifi_bb_intr_map() - .write(|w| unsafe { w.wifi_bb_intr_map().bits(31) }); - interrupt_core0 - .modem_peri_timeout_intr_map() - .write(|w| unsafe { w.modem_peri_timeout_intr_map().bits(31) }); - - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - Interrupt::LP_TIMER, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::BT_MAC, - interrupt::Priority::Priority1 - )); - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_MAC() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_PWR() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_PWR {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn LP_TIMER() { - unsafe { - trace!("LP_TIMER interrupt"); - - let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_7; - - trace!("interrupt LP_TIMER {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - trace!("interrupt LP_TIMER call"); - - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - trace!("LP_TIMER done"); - } - - trace!("interrupt LP_TIMER done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn BT_MAC() { - unsafe { - trace!("BT_MAC interrupt"); - - let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_4; - - trace!("interrupt BT_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - trace!("interrupt BT_MAC call"); - - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - trace!("BT_MAC done"); - } - - trace!("interrupt BT_MAC done"); - }; -} diff --git a/esp-wifi/src/timer/timer_esp32h2.rs b/esp-wifi/src/timer/timer_esp32h2.rs deleted file mode 100644 index efcdbd84..00000000 --- a/esp-wifi/src/timer/timer_esp32h2.rs +++ /dev/null @@ -1,63 +0,0 @@ -#[cfg(any(feature = "ble"))] -use crate::{ - binary, - hal::{interrupt, peripherals::Interrupt}, -}; - -pub fn setup_radio_isr() { - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - Interrupt::LP_BLE_TIMER, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::BT_MAC, - interrupt::Priority::Priority1 - )); - } -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn LP_BLE_TIMER() { - unsafe { - trace!("LP_TIMER interrupt"); - - let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_3; - - trace!("interrupt LP_TIMER {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - trace!("interrupt LP_TIMER call"); - - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - trace!("LP_TIMER done"); - } - - trace!("interrupt LP_TIMER done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn BT_MAC() { - unsafe { - trace!("BT_MAC interrupt"); - - let (fnc, arg) = crate::ble::npl::ble_os_adapter_chip_specific::ISR_INTERRUPT_15; - - trace!("interrupt BT_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - trace!("interrupt BT_MAC call"); - - let fnc: fn(*mut binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - trace!("BT_MAC done"); - } - - trace!("interrupt BT_MAC done"); - }; -} diff --git a/esp-wifi/src/timer/timer_esp32s2.rs b/esp-wifi/src/timer/timer_esp32s2.rs deleted file mode 100644 index c5023d23..00000000 --- a/esp-wifi/src/timer/timer_esp32s2.rs +++ /dev/null @@ -1,39 +0,0 @@ -#[cfg(feature = "wifi")] -#[allow(unused_imports)] -use crate::hal::{interrupt, peripherals}; - -pub fn setup_radio_isr() { - // wifi enabled in set_isr - // ble not supported -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_MAC() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_PWR() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - - trace!("interrupt WIFI_PWR {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} diff --git a/esp-wifi/src/timer/timer_esp32s3.rs b/esp-wifi/src/timer/timer_esp32s3.rs deleted file mode 100644 index 1d7c33df..00000000 --- a/esp-wifi/src/timer/timer_esp32s3.rs +++ /dev/null @@ -1,75 +0,0 @@ -#[cfg(any(feature = "wifi", feature = "ble"))] -#[allow(unused_imports)] -use crate::hal::{interrupt, peripherals}; - -pub fn setup_radio_isr() { - // wifi enabled in set_isr - #[cfg(feature = "ble")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::BT_BB, - interrupt::Priority::Priority1, - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::RWBLE, - interrupt::Priority::Priority1, - )); - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_MAC() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - trace!("interrupt WIFI_MAC {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - } -} - -#[cfg(feature = "wifi")] -#[no_mangle] -extern "C" fn WIFI_PWR() { - unsafe { - let (fnc, arg) = crate::wifi::os_adapter::ISR_INTERRUPT_1; - trace!("interrupt WIFI_PWR {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - - trace!("interrupt 1 done"); - }; -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn RWBLE() { - critical_section::with(|_| unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_5; - trace!("interrupt RWBLE {:?} {:?}", fnc, arg); - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - }); -} - -#[cfg(feature = "ble")] -#[no_mangle] -extern "C" fn BT_BB() { - critical_section::with(|_| unsafe { - let (fnc, arg) = crate::ble::btdm::ble_os_adapter_chip_specific::ISR_INTERRUPT_8; - trace!("interrupt RWBT {:?} {:?}", fnc, arg); - - if !fnc.is_null() { - let fnc: fn(*mut crate::binary::c_types::c_void) = core::mem::transmute(fnc); - fnc(arg); - } - }); -} diff --git a/esp-wifi/src/timer/xtensa.rs b/esp-wifi/src/timer/xtensa.rs deleted file mode 100644 index 7588cd0e..00000000 --- a/esp-wifi/src/timer/xtensa.rs +++ /dev/null @@ -1,129 +0,0 @@ -use core::cell::RefCell; - -use portable_atomic::{AtomicU32, Ordering}; - -use critical_section::Mutex; - -use crate::{ - hal::{ - interrupt, - peripherals::{self, TIMG1}, - prelude::*, - timer::{Timer, Timer0}, - trapframe::TrapFrame, - xtensa_lx, xtensa_lx_rt, - }, - preempt::preempt::task_switch, -}; - -/// The timer responsible for time slicing. -pub type TimeBase = Timer, esp_hal::Blocking>; -static TIMER1: Mutex>> = Mutex::new(RefCell::new(None)); -const TIMESLICE_FREQUENCY: fugit::HertzU64 = - fugit::HertzU64::from_raw(crate::CONFIG.tick_rate_hz as u64); - -// Time keeping - -static TIMER_OVERFLOWS: AtomicU32 = AtomicU32::new(0); -pub const CPU_CLOCK: u64 = 240_000_000; // ESP32, ESP32-S2 and ESP32-S3 all have 240MHz CPU clocks. -pub const CLOCK_CYCLES_PER_TICK: u64 = 8; -pub const TICKS_PER_SECOND: u64 = CPU_CLOCK / CLOCK_CYCLES_PER_TICK; - -/// This function must not be called in a critical section. Doing so may return an incorrect value. -pub fn get_systimer_count() -> u64 { - // We read the cycle counter twice to detect overflows. - // If we don't detect an overflow, we use the TIMER_OVERFLOWS count we read between. - // If we detect an overflow, we read the TIMER_OVERFLOWS count again to make sure we use the - // value after the overflow has been handled. - - let counter_before = xtensa_lx::timer::get_cycle_count(); - let mut overflow = TIMER_OVERFLOWS.load(Ordering::Relaxed); - let counter_after = xtensa_lx::timer::get_cycle_count(); - - if counter_after < counter_before { - overflow = TIMER_OVERFLOWS.load(Ordering::Relaxed); - } - - (((overflow as u64) << 32) + counter_after as u64) / CLOCK_CYCLES_PER_TICK -} - -pub fn setup_timer(mut timer1: TimeBase) { - unsafe { - interrupt::bind_interrupt( - peripherals::Interrupt::TG1_T0_LEVEL, - core::mem::transmute(tg1_t0_level as *const ()), - ); - } - - unwrap!(interrupt::enable( - peripherals::Interrupt::TG1_T0_LEVEL, - interrupt::Priority::Priority2, - )); - - timer1.listen(); - timer1.start(TIMESLICE_FREQUENCY.into_duration()); - critical_section::with(|cs| { - TIMER1.borrow_ref_mut(cs).replace(timer1); - }); - - // Set up the time keeping timer. - xtensa_lx::timer::set_ccompare0(0xffffffff); -} - -pub fn setup_multitasking() { - unsafe { - let enabled = xtensa_lx::interrupt::disable(); - xtensa_lx::interrupt::enable_mask( - 1 << 6 // Timer0 - | 1 << 29 // Software1 - | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level2.mask() - | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level6.mask() | enabled, - ); - } -} - -#[allow(non_snake_case)] -#[no_mangle] -fn Timer0(_level: u32) { - TIMER_OVERFLOWS.fetch_add(1, Ordering::Relaxed); - - xtensa_lx::timer::set_ccompare0(0xffffffff); -} - -fn do_task_switch(context: &mut TrapFrame) { - critical_section::with(|cs| { - let mut timer = TIMER1.borrow_ref_mut(cs); - let timer = unwrap!(timer.as_mut()); - timer.clear_interrupt(); - timer.start(TIMESLICE_FREQUENCY.into_duration()); - }); - - task_switch(context); -} - -extern "C" fn tg1_t0_level(context: &mut TrapFrame) { - do_task_switch(context); -} - -#[allow(non_snake_case)] -#[no_mangle] -fn Software1(_level: u32, context: &mut TrapFrame) { - let intr = 1 << 29; - unsafe { - core::arch::asm!("wsr.intclear {0}", in(reg) intr, options(nostack)); - } - - do_task_switch(context); -} - -pub fn yield_task() { - let intr = 1 << 29; - unsafe { - core::arch::asm!("wsr.intset {0}", in(reg) intr, options(nostack)); - } -} - -// TODO: use an Instance type instead... -pub fn time_diff(start: u64, end: u64) -> u64 { - end.wrapping_sub(start) -} diff --git a/esp-wifi/src/wifi/mod.rs b/esp-wifi/src/wifi/mod.rs deleted file mode 100644 index ccd89ddc..00000000 --- a/esp-wifi/src/wifi/mod.rs +++ /dev/null @@ -1,3086 +0,0 @@ -//! WiFi - -pub(crate) mod os_adapter; -pub(crate) mod state; - -use core::ptr::addr_of; -use core::time::Duration; -use core::{ - cell::{RefCell, RefMut}, - mem::MaybeUninit, -}; - -use portable_atomic::{AtomicUsize, Ordering}; - -use crate::common_adapter::*; -use crate::esp_wifi_result; -use crate::hal::macros::ram; -use crate::hal::peripheral::Peripheral; -use crate::hal::peripheral::PeripheralRef; -use crate::EspWifiInitialization; - -use critical_section::{CriticalSection, Mutex}; - -use enumset::EnumSet; -use enumset::EnumSetType; -use num_derive::FromPrimitive; -use num_traits::FromPrimitive; - -use core::fmt::Debug; -use core::mem; - -#[doc(hidden)] -pub use os_adapter::*; -pub use state::*; - -#[cfg(feature = "smoltcp")] -use smoltcp::phy::{Device, DeviceCapabilities, RxToken, TxToken}; - -const ETHERNET_FRAME_HEADER_SIZE: usize = 18; - -const MTU: usize = crate::CONFIG.mtu; - -#[cfg(feature = "utils")] -pub mod utils; - -#[cfg(coex)] -use include::{coex_adapter_funcs_t, coex_pre_init, esp_coex_adapter_register}; - -use crate::{ - binary::{ - c_types, - include::{ - self, __BindgenBitfieldUnit, esp_err_t, esp_interface_t_ESP_IF_WIFI_AP, - esp_interface_t_ESP_IF_WIFI_STA, esp_supplicant_init, esp_wifi_connect, - esp_wifi_disconnect, esp_wifi_get_mode, esp_wifi_init_internal, - esp_wifi_internal_free_rx_buffer, esp_wifi_internal_reg_rxcb, esp_wifi_internal_tx, - esp_wifi_scan_start, esp_wifi_set_config, esp_wifi_set_country, esp_wifi_set_mode, - esp_wifi_set_protocol, esp_wifi_set_ps, esp_wifi_set_tx_done_cb, esp_wifi_start, - esp_wifi_stop, g_wifi_default_wpa_crypto_funcs, wifi_active_scan_time_t, - wifi_ap_config_t, wifi_auth_mode_t, wifi_cipher_type_t_WIFI_CIPHER_TYPE_CCMP, - wifi_config_t, wifi_country_policy_t_WIFI_COUNTRY_POLICY_MANUAL, wifi_country_t, - wifi_init_config_t, wifi_interface_t, wifi_interface_t_WIFI_IF_AP, - wifi_interface_t_WIFI_IF_STA, wifi_mode_t, wifi_mode_t_WIFI_MODE_AP, - wifi_mode_t_WIFI_MODE_APSTA, wifi_mode_t_WIFI_MODE_NULL, wifi_mode_t_WIFI_MODE_STA, - wifi_osi_funcs_t, wifi_pmf_config_t, wifi_scan_config_t, wifi_scan_threshold_t, - wifi_scan_time_t, wifi_scan_type_t_WIFI_SCAN_TYPE_ACTIVE, - wifi_scan_type_t_WIFI_SCAN_TYPE_PASSIVE, wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL, - wifi_sta_config_t, wpa_crypto_funcs_t, ESP_WIFI_OS_ADAPTER_MAGIC, - ESP_WIFI_OS_ADAPTER_VERSION, WIFI_INIT_CONFIG_MAGIC, - }, - }, - compat::queue::SimpleQueue, -}; - -#[derive(EnumSetType, Debug, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Default)] -pub enum AuthMethod { - None, - WEP, - WPA, - #[default] - WPA2Personal, - WPAWPA2Personal, - WPA2Enterprise, - WPA3Personal, - WPA2WPA3Personal, - WAPIPersonal, -} - -#[derive(EnumSetType, Debug, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Default)] -pub enum Protocol { - P802D11B, - P802D11BG, - #[default] - P802D11BGN, - P802D11BGNLR, - P802D11LR, -} - -#[derive(EnumSetType, Debug, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Default)] -pub enum SecondaryChannel { - // TODO: Need to extend that for 5GHz - #[default] - None, - Above, - Below, -} - -#[derive(Clone, Debug, Default, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct AccessPointInfo { - pub ssid: heapless::String<32>, - pub bssid: [u8; 6], - pub channel: u8, - pub secondary_channel: SecondaryChannel, - pub signal_strength: i8, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub protocols: EnumSet, - pub auth_method: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct AccessPointConfiguration { - pub ssid: heapless::String<32>, - pub ssid_hidden: bool, - pub channel: u8, - pub secondary_channel: Option, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub protocols: EnumSet, - pub auth_method: AuthMethod, - pub password: heapless::String<64>, - pub max_connections: u16, -} - -impl Default for AccessPointConfiguration { - fn default() -> Self { - Self { - ssid: "iot-device".try_into().unwrap(), - ssid_hidden: false, - channel: 1, - secondary_channel: None, - protocols: Protocol::P802D11B | Protocol::P802D11BG | Protocol::P802D11BGN, - auth_method: AuthMethod::None, - password: heapless::String::new(), - max_connections: 255, - } - } -} - -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))] -pub struct ClientConfiguration { - pub ssid: heapless::String<32>, - pub bssid: Option<[u8; 6]>, - //pub protocol: Protocol, - pub auth_method: AuthMethod, - pub password: heapless::String<64>, - pub channel: Option, -} - -impl Debug for ClientConfiguration { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("ClientConfiguration") - .field("ssid", &self.ssid) - .field("bssid", &self.bssid) - .field("auth_method", &self.auth_method) - .field("channel", &self.channel) - .finish() - } -} - -impl Default for ClientConfiguration { - fn default() -> Self { - ClientConfiguration { - ssid: heapless::String::new(), - bssid: None, - auth_method: Default::default(), - password: heapless::String::new(), - channel: None, - } - } -} - -#[derive(EnumSetType, Debug, PartialOrd)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Capability { - Client, - AccessPoint, - Mixed, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Default)] -pub enum Configuration { - #[default] - None, - Client(ClientConfiguration), - AccessPoint(AccessPointConfiguration), - Mixed(ClientConfiguration, AccessPointConfiguration), -} - -impl Configuration { - pub fn as_client_conf_ref(&self) -> Option<&ClientConfiguration> { - match self { - Self::Client(client_conf) | Self::Mixed(client_conf, _) => Some(client_conf), - _ => None, - } - } - - pub fn as_ap_conf_ref(&self) -> Option<&AccessPointConfiguration> { - match self { - Self::AccessPoint(ap_conf) | Self::Mixed(_, ap_conf) => Some(ap_conf), - _ => None, - } - } - - pub fn as_client_conf_mut(&mut self) -> &mut ClientConfiguration { - match self { - Self::Client(client_conf) => client_conf, - Self::Mixed(_, _) => { - let prev = mem::replace(self, Self::None); - match prev { - Self::Mixed(client_conf, _) => { - *self = Self::Client(client_conf); - self.as_client_conf_mut() - } - _ => unreachable!(), - } - } - _ => { - *self = Self::Client(Default::default()); - self.as_client_conf_mut() - } - } - } - - pub fn as_ap_conf_mut(&mut self) -> &mut AccessPointConfiguration { - match self { - Self::AccessPoint(ap_conf) => ap_conf, - Self::Mixed(_, _) => { - let prev = mem::replace(self, Self::None); - match prev { - Self::Mixed(_, ap_conf) => { - *self = Self::AccessPoint(ap_conf); - self.as_ap_conf_mut() - } - _ => unreachable!(), - } - } - _ => { - *self = Self::AccessPoint(Default::default()); - self.as_ap_conf_mut() - } - } - } - - pub fn as_mixed_conf_mut( - &mut self, - ) -> (&mut ClientConfiguration, &mut AccessPointConfiguration) { - match self { - Self::Mixed(client_conf, ref mut ap_conf) => (client_conf, ap_conf), - Self::AccessPoint(_) => { - let prev = mem::replace(self, Self::None); - match prev { - Self::AccessPoint(ap_conf) => { - *self = Self::Mixed(Default::default(), ap_conf); - self.as_mixed_conf_mut() - } - _ => unreachable!(), - } - } - Self::Client(_) => { - let prev = mem::replace(self, Self::None); - match prev { - Self::Client(client_conf) => { - *self = Self::Mixed(client_conf, Default::default()); - self.as_mixed_conf_mut() - } - _ => unreachable!(), - } - } - _ => { - *self = Self::Mixed(Default::default(), Default::default()); - self.as_mixed_conf_mut() - } - } - } -} - -pub mod ipv4 { - use core::fmt::Display; - use core::str::FromStr; - - pub use no_std_net::*; - - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct Mask(pub u8); - - impl FromStr for Mask { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - s.parse::() - .map_err(|_| "Invalid subnet mask") - .map_or_else(Err, |mask| { - if (1..=32).contains(&mask) { - Ok(Mask(mask)) - } else { - Err("Mask should be a number between 1 and 32") - } - }) - } - } - - impl Display for Mask { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{}", self.0) - } - } - - impl TryFrom for Mask { - type Error = (); - - fn try_from(ip: Ipv4Addr) -> Result { - let octets = ip.octets(); - let addr: u32 = ((octets[0] as u32 & 0xff) << 24) - | ((octets[1] as u32 & 0xff) << 16) - | ((octets[2] as u32 & 0xff) << 8) - | (octets[3] as u32 & 0xff); - - if addr.leading_ones() + addr.trailing_zeros() == 32 { - Ok(Mask(addr.leading_ones() as u8)) - } else { - Err(()) - } - } - } - - impl From for Ipv4Addr { - fn from(mask: Mask) -> Self { - let addr: u32 = ((1 << (32 - mask.0)) - 1) ^ 0xffffffffu32; - - let (a, b, c, d) = ( - ((addr >> 24) & 0xff) as u8, - ((addr >> 16) & 0xff) as u8, - ((addr >> 8) & 0xff) as u8, - (addr & 0xff) as u8, - ); - - Ipv4Addr::new(a, b, c, d) - } - } - - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct Subnet { - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub gateway: Ipv4Addr, - pub mask: Mask, - } - - impl Display for Subnet { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{}/{}", self.gateway, self.mask) - } - } - - impl FromStr for Subnet { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - let mut split = s.split('/'); - if let Some(gateway_str) = split.next() { - if let Some(mask_str) = split.next() { - if split.next().is_none() { - if let Ok(gateway) = gateway_str.parse::() { - return mask_str.parse::().map(|mask| Self { gateway, mask }); - } else { - return Err("Invalid IP address format, expected XXX.XXX.XXX.XXX"); - } - } - } - } - - Err("Expected /") - } - } - - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct ClientSettings { - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub ip: Ipv4Addr, - pub subnet: Subnet, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub dns: Option, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub secondary_dns: Option, - } - - impl Default for ClientSettings { - fn default() -> ClientSettings { - ClientSettings { - ip: Ipv4Addr::new(192, 168, 71, 200), - subnet: Subnet { - gateway: Ipv4Addr::new(192, 168, 71, 1), - mask: Mask(24), - }, - dns: Some(Ipv4Addr::new(8, 8, 8, 8)), - secondary_dns: Some(Ipv4Addr::new(8, 8, 4, 4)), - } - } - } - - #[derive(Default, Clone, Debug, PartialEq, Eq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct DHCPClientSettings { - pub hostname: Option>, - } - - #[derive(Clone, Debug, PartialEq, Eq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum ClientConfiguration { - DHCP(DHCPClientSettings), - Fixed(ClientSettings), - } - - impl ClientConfiguration { - pub fn as_fixed_settings_ref(&self) -> Option<&ClientSettings> { - match self { - Self::Fixed(client_settings) => Some(client_settings), - _ => None, - } - } - - pub fn as_fixed_settings_mut(&mut self) -> &mut ClientSettings { - match self { - Self::Fixed(client_settings) => client_settings, - _ => { - *self = ClientConfiguration::Fixed(Default::default()); - self.as_fixed_settings_mut() - } - } - } - } - - impl Default for ClientConfiguration { - fn default() -> ClientConfiguration { - ClientConfiguration::DHCP(Default::default()) - } - } - - #[derive(Clone, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct RouterConfiguration { - pub subnet: Subnet, - pub dhcp_enabled: bool, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub dns: Option, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub secondary_dns: Option, - } - - impl Default for RouterConfiguration { - fn default() -> RouterConfiguration { - RouterConfiguration { - subnet: Subnet { - gateway: Ipv4Addr::new(192, 168, 71, 1), - mask: Mask(24), - }, - dhcp_enabled: true, - dns: Some(Ipv4Addr::new(8, 8, 8, 8)), - secondary_dns: Some(Ipv4Addr::new(8, 8, 4, 4)), - } - } - } - - #[derive(Clone, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum Configuration { - Client(ClientConfiguration), - Router(RouterConfiguration), - } - - impl Default for Configuration { - fn default() -> Self { - Self::Client(Default::default()) - } - } - - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct IpInfo { - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub ip: Ipv4Addr, - pub subnet: Subnet, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub dns: Option, - #[cfg_attr(feature = "defmt", defmt(Debug2Format))] - pub secondary_dns: Option, - } -} - -trait AuthMethodExt { - fn to_raw(&self) -> wifi_auth_mode_t; - fn from_raw(raw: wifi_auth_mode_t) -> Self; -} - -impl AuthMethodExt for AuthMethod { - fn to_raw(&self) -> wifi_auth_mode_t { - match self { - AuthMethod::None => include::wifi_auth_mode_t_WIFI_AUTH_OPEN, - AuthMethod::WEP => include::wifi_auth_mode_t_WIFI_AUTH_WEP, - AuthMethod::WPA => include::wifi_auth_mode_t_WIFI_AUTH_WPA_PSK, - AuthMethod::WPA2Personal => include::wifi_auth_mode_t_WIFI_AUTH_WPA2_PSK, - AuthMethod::WPAWPA2Personal => include::wifi_auth_mode_t_WIFI_AUTH_WPA_WPA2_PSK, - AuthMethod::WPA2Enterprise => include::wifi_auth_mode_t_WIFI_AUTH_WPA2_ENTERPRISE, - AuthMethod::WPA3Personal => include::wifi_auth_mode_t_WIFI_AUTH_WPA3_PSK, - AuthMethod::WPA2WPA3Personal => include::wifi_auth_mode_t_WIFI_AUTH_WPA2_WPA3_PSK, - AuthMethod::WAPIPersonal => include::wifi_auth_mode_t_WIFI_AUTH_WAPI_PSK, - } - } - - fn from_raw(raw: wifi_auth_mode_t) -> Self { - match raw { - include::wifi_auth_mode_t_WIFI_AUTH_OPEN => AuthMethod::None, - include::wifi_auth_mode_t_WIFI_AUTH_WEP => AuthMethod::WEP, - include::wifi_auth_mode_t_WIFI_AUTH_WPA_PSK => AuthMethod::WPA, - include::wifi_auth_mode_t_WIFI_AUTH_WPA2_PSK => AuthMethod::WPA2Personal, - include::wifi_auth_mode_t_WIFI_AUTH_WPA_WPA2_PSK => AuthMethod::WPAWPA2Personal, - include::wifi_auth_mode_t_WIFI_AUTH_WPA2_ENTERPRISE => AuthMethod::WPA2Enterprise, - include::wifi_auth_mode_t_WIFI_AUTH_WPA3_PSK => AuthMethod::WPA3Personal, - include::wifi_auth_mode_t_WIFI_AUTH_WPA2_WPA3_PSK => AuthMethod::WPA2WPA3Personal, - include::wifi_auth_mode_t_WIFI_AUTH_WAPI_PSK => AuthMethod::WAPIPersonal, - _ => unreachable!(), - } - } -} - -/// Wifi Mode (Sta and/or Ap) -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum WifiMode { - Sta, - Ap, - ApSta, -} - -impl WifiMode { - pub(crate) fn current() -> Result { - let mut mode = wifi_mode_t_WIFI_MODE_NULL; - esp_wifi_result!(unsafe { esp_wifi_get_mode(&mut mode) })?; - - Self::try_from(mode) - } - - /// Returns true if this mode works as a client - pub fn is_sta(&self) -> bool { - match self { - Self::Sta | Self::ApSta => true, - Self::Ap => false, - } - } - - /// Returns true if this mode works as an access point - pub fn is_ap(&self) -> bool { - match self { - Self::Sta => false, - Self::Ap | Self::ApSta => true, - } - } -} - -impl TryFrom<&Configuration> for WifiMode { - type Error = WifiError; - - fn try_from(config: &Configuration) -> Result { - let mode = match config { - Configuration::None => return Err(WifiError::UnknownWifiMode), - Configuration::AccessPoint(_) => Self::Ap, - Configuration::Client(_) => Self::Sta, - Configuration::Mixed(_, _) => Self::ApSta, - }; - - Ok(mode) - } -} - -impl TryFrom for WifiMode { - type Error = WifiError; - - fn try_from(value: wifi_mode_t) -> Result { - #[allow(non_upper_case_globals)] - match value { - include::wifi_mode_t_WIFI_MODE_STA => Ok(Self::Sta), - include::wifi_mode_t_WIFI_MODE_AP => Ok(Self::Ap), - include::wifi_mode_t_WIFI_MODE_APSTA => Ok(Self::ApSta), - _ => Err(WifiError::UnknownWifiMode), - } - } -} - -impl Into for WifiMode { - fn into(self) -> wifi_mode_t { - #[allow(non_upper_case_globals)] - match self { - Self::Sta => wifi_mode_t_WIFI_MODE_STA, - Self::Ap => wifi_mode_t_WIFI_MODE_AP, - Self::ApSta => wifi_mode_t_WIFI_MODE_APSTA, - } - } -} - -const DATA_FRAME_SIZE: usize = MTU + ETHERNET_FRAME_HEADER_SIZE; - -const RX_QUEUE_SIZE: usize = crate::CONFIG.rx_queue_size; -const TX_QUEUE_SIZE: usize = crate::CONFIG.tx_queue_size; - -pub(crate) static DATA_QUEUE_RX_AP: Mutex< - RefCell>, -> = Mutex::new(RefCell::new(SimpleQueue::new())); - -pub(crate) static DATA_QUEUE_RX_STA: Mutex< - RefCell>, -> = Mutex::new(RefCell::new(SimpleQueue::new())); - -/// Common errors -#[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum WifiError { - NotInitialized, - InternalError(InternalWifiError), - WrongClockConfig, - Disconnected, - UnknownWifiMode, -} - -/// Events generated by the WiFi driver -#[repr(i32)] -#[derive(Debug, FromPrimitive, EnumSetType)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum WifiEvent { - WifiReady = 0, - ScanDone, - StaStart, - StaStop, - StaConnected, - StaDisconnected, - StaAuthmodeChange, - StaWpsErSuccess, - StaWpsErFailed, - StaWpsErTimeout, - StaWpsErPin, - StaWpsErPbcOverlap, - ApStart, - ApStop, - ApStaconnected, - ApStadisconnected, - ApProbereqrecved, - FtmReport, - StaBssRssiLow, - ActionTxStatus, - RocDone, - StaBeaconTimeout, -} - -/// Error originating from the underlying drivers -#[repr(i32)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum InternalWifiError { - /// Out of memory - EspErrNoMem = 0x101, - - /// Invalid argument - EspErrInvalidArg = 0x102, - - /// WiFi driver was not installed by esp_wifi_init - EspErrWifiNotInit = 0x3001, - - /// WiFi driver was not started by esp_wifi_start - EspErrWifiNotStarted = 0x3002, - - /// WiFi driver was not stopped by esp_wifi_stop - EspErrWifiNotStopped = 0x3003, - - /// WiFi interface error - EspErrWifiIf = 0x3004, - - /// WiFi mode error - EspErrWifiMode = 0x3005, - - /// WiFi internal state error - EspErrWifiState = 0x3006, - - /// WiFi internal control block of station or soft-AP error - EspErrWifiConn = 0x3007, - - /// WiFi internal NVS module error - EspErrWifiNvs = 0x3008, - - /// MAC address is invalid - EspErrWifiMac = 0x3009, - - /// SSID is invalid - EspErrWifiSsid = 0x300A, - - /// Password is invalid - EspErrWifiPassword = 0x300B, - - /// Timeout error - EspErrWifiTimeout = 0x300C, - - /// WiFi is in sleep state(RF closed) and wakeup fail - EspErrWifiWakeFail = 0x300D, - - /// The caller would block - EspErrWifiWouldBlock = 0x300E, - - /// Station still in disconnect status - EspErrWifiNotConnect = 0x300F, - - /// Failed to post the event to WiFi task - EspErrWifiPost = 0x3012, - - /// Invalid WiFi state when init/deinit is called - EspErrWifiInitState = 0x3013, - - /// Returned when WiFi is stopping - EspErrWifiStopState = 0x3014, - - /// The WiFi connection is not associated - EspErrWifiNotAssoc = 0x3015, - - /// The WiFi TX is disallowed - EspErrWifiTxDisallow = 0x3016, -} - -#[cfg(all(coex, any(esp32, esp32c2, esp32c3, esp32c6, esp32s3)))] -static mut G_COEX_ADAPTER_FUNCS: coex_adapter_funcs_t = coex_adapter_funcs_t { - _version: include::COEX_ADAPTER_VERSION as i32, - _task_yield_from_isr: Some(task_yield_from_isr), - _semphr_create: Some(semphr_create), - _semphr_delete: Some(semphr_delete), - _semphr_take_from_isr: Some(semphr_take_from_isr_wrapper), - _semphr_give_from_isr: Some(semphr_give_from_isr_wrapper), - _semphr_take: Some(semphr_take), - _semphr_give: Some(semphr_give), - _is_in_isr: Some(is_in_isr_wrapper), - _malloc_internal: Some(malloc), - _free: Some(free), - _esp_timer_get_time: Some(esp_timer_get_time), - _env_is_chip: Some(env_is_chip), - _magic: include::COEX_ADAPTER_MAGIC as i32, - _timer_disarm: Some(ets_timer_disarm), - _timer_done: Some(ets_timer_done), - _timer_setfn: Some(ets_timer_setfn), - _timer_arm_us: Some(ets_timer_arm_us), - - #[cfg(esp32)] - _spin_lock_create: Some(spin_lock_create), - #[cfg(esp32)] - _spin_lock_delete: Some(spin_lock_delete), - #[cfg(esp32)] - _int_disable: Some(wifi_int_disable), - #[cfg(esp32)] - _int_enable: Some(wifi_int_restore), - - #[cfg(esp32c2)] - _slowclk_cal_get: Some(slowclk_cal_get), -}; - -#[cfg(coex)] -unsafe extern "C" fn semphr_take_from_isr_wrapper( - semphr: *mut c_types::c_void, - hptw: *mut c_types::c_void, -) -> i32 { - crate::common_adapter::semphr_take_from_isr(semphr as *const (), hptw as *const ()) -} - -#[cfg(coex)] -unsafe extern "C" fn semphr_give_from_isr_wrapper( - semphr: *mut c_types::c_void, - hptw: *mut c_types::c_void, -) -> i32 { - crate::common_adapter::semphr_give_from_isr(semphr as *const (), hptw as *const ()) -} - -#[cfg(coex)] -unsafe extern "C" fn is_in_isr_wrapper() -> i32 { - // like original implementation - 0 -} - -#[cfg(coex)] -pub(crate) fn coex_initialize() -> i32 { - debug!("call coex-initialize"); - unsafe { - let res = esp_coex_adapter_register(core::ptr::addr_of_mut!(G_COEX_ADAPTER_FUNCS).cast()); - if res != 0 { - error!("Error: esp_coex_adapter_register {}", res); - return res; - } - let res = coex_pre_init(); - if res != 0 { - error!("Error: coex_pre_init {}", res); - return res; - } - 0 - } -} - -pub(crate) unsafe extern "C" fn coex_init() -> i32 { - #[cfg(coex)] - { - debug!("coex-init"); - return include::coex_init(); - } - - #[cfg(not(coex))] - 0 -} - -#[no_mangle] -static g_wifi_osi_funcs: wifi_osi_funcs_t = wifi_osi_funcs_t { - _version: ESP_WIFI_OS_ADAPTER_VERSION as i32, - _env_is_chip: Some(env_is_chip), - _set_intr: Some(set_intr), - _clear_intr: Some(clear_intr), - _set_isr: Some(os_adapter_chip_specific::set_isr), - _ints_on: Some(ints_on), - _ints_off: Some(ints_off), - _is_from_isr: Some(is_from_isr), - _spin_lock_create: Some(spin_lock_create), - _spin_lock_delete: Some(spin_lock_delete), - _wifi_int_disable: Some(wifi_int_disable), - _wifi_int_restore: Some(wifi_int_restore), - _task_yield_from_isr: Some(task_yield_from_isr), - _semphr_create: Some(semphr_create), - _semphr_delete: Some(semphr_delete), - _semphr_take: Some(semphr_take), - _semphr_give: Some(semphr_give), - _wifi_thread_semphr_get: Some(wifi_thread_semphr_get), - _mutex_create: Some(mutex_create), - _recursive_mutex_create: Some(recursive_mutex_create), - _mutex_delete: Some(mutex_delete), - _mutex_lock: Some(mutex_lock), - _mutex_unlock: Some(mutex_unlock), - _queue_create: Some(queue_create), - _queue_delete: Some(queue_delete), - _queue_send: Some(queue_send), - _queue_send_from_isr: Some(queue_send_from_isr), - _queue_send_to_back: Some(queue_send_to_back), - _queue_send_to_front: Some(queue_send_to_front), - _queue_recv: Some(queue_recv), - _queue_msg_waiting: Some(queue_msg_waiting), - _event_group_create: Some(event_group_create), - _event_group_delete: Some(event_group_delete), - _event_group_set_bits: Some(event_group_set_bits), - _event_group_clear_bits: Some(event_group_clear_bits), - _event_group_wait_bits: Some(event_group_wait_bits), - _task_create_pinned_to_core: Some(task_create_pinned_to_core), - _task_create: Some(task_create), - _task_delete: Some(task_delete), - _task_delay: Some(task_delay), - _task_ms_to_tick: Some(task_ms_to_tick), - _task_get_current_task: Some(task_get_current_task), - _task_get_max_priority: Some(task_get_max_priority), - _malloc: Some(malloc), - _free: Some(free), - _event_post: Some(event_post), - _get_free_heap_size: Some(get_free_heap_size), - _rand: Some(rand), - _dport_access_stall_other_cpu_start_wrap: Some(dport_access_stall_other_cpu_start_wrap), - _dport_access_stall_other_cpu_end_wrap: Some(dport_access_stall_other_cpu_end_wrap), - _wifi_apb80m_request: Some(wifi_apb80m_request), - _wifi_apb80m_release: Some(wifi_apb80m_release), - _phy_disable: Some(phy_disable), - _phy_enable: Some(phy_enable), - _phy_update_country_info: Some(phy_update_country_info), - _read_mac: Some(read_mac), - _timer_arm: Some(ets_timer_arm), - _timer_disarm: Some(ets_timer_disarm), - _timer_done: Some(ets_timer_done), - _timer_setfn: Some(ets_timer_setfn), - _timer_arm_us: Some(ets_timer_arm_us), - _wifi_reset_mac: Some(wifi_reset_mac), - _wifi_clock_enable: Some(wifi_clock_enable), - _wifi_clock_disable: Some(wifi_clock_disable), - _wifi_rtc_enable_iso: Some(wifi_rtc_enable_iso), - _wifi_rtc_disable_iso: Some(wifi_rtc_disable_iso), - _esp_timer_get_time: Some(esp_timer_get_time), - _nvs_set_i8: Some(nvs_set_i8), - _nvs_get_i8: Some(nvs_get_i8), - _nvs_set_u8: Some(nvs_set_u8), - _nvs_get_u8: Some(nvs_get_u8), - _nvs_set_u16: Some(nvs_set_u16), - _nvs_get_u16: Some(nvs_get_u16), - _nvs_open: Some(nvs_open), - _nvs_close: Some(nvs_close), - _nvs_commit: Some(nvs_commit), - _nvs_set_blob: Some(nvs_set_blob), - _nvs_get_blob: Some(nvs_get_blob), - _nvs_erase_key: Some(nvs_erase_key), - _get_random: Some(get_random), - _get_time: Some(get_time), - _random: Some(random), - _log_write: Some(log_write), - _log_writev: Some(log_writev), - _log_timestamp: Some(log_timestamp), - _malloc_internal: Some(malloc_internal), - _realloc_internal: Some(realloc_internal), - _calloc_internal: Some(calloc_internal), - _zalloc_internal: Some(zalloc_internal), - _wifi_malloc: Some(wifi_malloc), - _wifi_realloc: Some(wifi_realloc), - _wifi_calloc: Some(wifi_calloc), - _wifi_zalloc: Some(wifi_zalloc), - _wifi_create_queue: Some(wifi_create_queue), - _wifi_delete_queue: Some(wifi_delete_queue), - _coex_init: Some(coex_init), - _coex_deinit: Some(coex_deinit), - _coex_enable: Some(coex_enable), - _coex_disable: Some(coex_disable), - _coex_status_get: Some(coex_status_get), - _coex_condition_set: None, - _coex_wifi_request: Some(coex_wifi_request), - _coex_wifi_release: Some(coex_wifi_release), - _coex_wifi_channel_set: Some(coex_wifi_channel_set), - _coex_event_duration_get: Some(coex_event_duration_get), - _coex_pti_get: Some(coex_pti_get), - _coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear), - _coex_schm_status_bit_set: Some(coex_schm_status_bit_set), - _coex_schm_interval_set: Some(coex_schm_interval_set), - _coex_schm_interval_get: Some(coex_schm_interval_get), - _coex_schm_curr_period_get: Some(coex_schm_curr_period_get), - _coex_schm_curr_phase_get: Some(coex_schm_curr_phase_get), - #[cfg(any(esp32c3, esp32c2, esp32c6, esp32h2, esp32s3, esp32s2))] - _slowclk_cal_get: Some(slowclk_cal_get), - #[cfg(any(esp32, esp32s2))] - _phy_common_clock_disable: Some(os_adapter_chip_specific::phy_common_clock_disable), - #[cfg(any(esp32, esp32s2))] - _phy_common_clock_enable: Some(os_adapter_chip_specific::phy_common_clock_enable), - _coex_register_start_cb: Some(coex_register_start_cb), - - #[cfg(any(esp32c6))] - _regdma_link_set_write_wait_content: Some( - os_adapter_chip_specific::regdma_link_set_write_wait_content_dummy, - ), - #[cfg(any(esp32c6))] - _sleep_retention_find_link_by_id: Some( - os_adapter_chip_specific::sleep_retention_find_link_by_id_dummy, - ), - #[cfg(any(esp32c6))] - _sleep_retention_entries_create: Some( - os_adapter_chip_specific::sleep_retention_entries_create_dummy, - ), - #[cfg(any(esp32c6))] - _sleep_retention_entries_destroy: Some( - os_adapter_chip_specific::sleep_retention_entries_destroy_dummy, - ), - - _coex_schm_process_restart: Some(coex_schm_process_restart_wrapper), - _coex_schm_register_cb: Some(coex_schm_register_cb_wrapper), - - _magic: ESP_WIFI_OS_ADAPTER_MAGIC as i32, -}; - -const CONFIG_FEATURE_WPA3_SAE_BIT: u64 = 1 << 0; - -const WIFI_FEATURE_CAPS: u64 = CONFIG_FEATURE_WPA3_SAE_BIT; - -#[no_mangle] -static mut g_wifi_feature_caps: u64 = WIFI_FEATURE_CAPS; - -static mut G_CONFIG: wifi_init_config_t = wifi_init_config_t { - osi_funcs: addr_of!(g_wifi_osi_funcs).cast_mut(), - - // dummy for now - populated in init - wpa_crypto_funcs: wpa_crypto_funcs_t { - size: 0, - version: 1, - aes_wrap: None, - aes_unwrap: None, - hmac_sha256_vector: None, - sha256_prf: None, - hmac_md5: None, - hamc_md5_vector: None, - hmac_sha1: None, - hmac_sha1_vector: None, - sha1_prf: None, - sha1_vector: None, - pbkdf2_sha1: None, - rc4_skip: None, - md5_vector: None, - aes_encrypt: None, - aes_encrypt_init: None, - aes_encrypt_deinit: None, - aes_decrypt: None, - aes_decrypt_init: None, - aes_decrypt_deinit: None, - aes_128_encrypt: None, - aes_128_decrypt: None, - omac1_aes_128: None, - ccmp_decrypt: None, - ccmp_encrypt: None, - aes_gmac: None, - sha256_vector: None, - crc32: None, - }, - static_rx_buf_num: crate::CONFIG.static_rx_buf_num as i32, - dynamic_rx_buf_num: crate::CONFIG.dynamic_rx_buf_num as i32, - tx_buf_type: 1, - static_tx_buf_num: crate::CONFIG.static_tx_buf_num as i32, - dynamic_tx_buf_num: crate::CONFIG.dynamic_tx_buf_num as i32, - rx_mgmt_buf_type: 0 as i32, - rx_mgmt_buf_num: 0 as i32, - cache_tx_buf_num: 0, - csi_enable: 1, - ampdu_rx_enable: crate::CONFIG.ampdu_rx_enable as i32, - ampdu_tx_enable: crate::CONFIG.ampdu_tx_enable as i32, - amsdu_tx_enable: crate::CONFIG.amsdu_tx_enable as i32, - nvs_enable: 0, - nano_enable: 0, - rx_ba_win: crate::CONFIG.rx_ba_win as i32, - wifi_task_core_id: 0, - beacon_max_len: 752, - mgmt_sbuf_num: 32, - feature_caps: WIFI_FEATURE_CAPS, - sta_disconnected_pm: false, - espnow_max_encrypt_num: 7, // 2 for ESP32-C2 - magic: WIFI_INIT_CONFIG_MAGIC as i32, -}; - -/// Get the STA MAC address -pub fn get_sta_mac(mac: &mut [u8; 6]) { - unsafe { - read_mac(mac as *mut u8, 0); - } -} - -/// Get the AP MAC address -pub fn get_ap_mac(mac: &mut [u8; 6]) { - unsafe { - read_mac(mac as *mut u8, 1); - } -} - -pub(crate) fn wifi_init() -> Result<(), WifiError> { - unsafe { - G_CONFIG.wpa_crypto_funcs = g_wifi_default_wpa_crypto_funcs; - G_CONFIG.feature_caps = g_wifi_feature_caps; - - #[cfg(coex)] - esp_wifi_result!(coex_init())?; - - esp_wifi_result!(esp_wifi_init_internal(addr_of!(G_CONFIG)))?; - esp_wifi_result!(esp_wifi_set_mode(wifi_mode_t_WIFI_MODE_NULL))?; - - esp_wifi_result!(esp_supplicant_init())?; - - esp_wifi_result!(esp_wifi_set_tx_done_cb(Some(esp_wifi_tx_done_cb)))?; - - esp_wifi_result!(esp_wifi_internal_reg_rxcb( - esp_interface_t_ESP_IF_WIFI_STA, - Some(recv_cb_sta) - ))?; - - // until we support APSTA we just register the same callback for AP and STA - esp_wifi_result!(esp_wifi_internal_reg_rxcb( - esp_interface_t_ESP_IF_WIFI_AP, - Some(recv_cb_ap) - ))?; - - #[cfg(any(esp32, esp32s3))] - { - static mut NVS_STRUCT: [u32; 12] = [0; 12]; - chip_specific::g_misc_nvs = addr_of!(NVS_STRUCT) as u32; - } - - Ok(()) - } -} - -unsafe extern "C" fn recv_cb_sta( - buffer: *mut c_types::c_void, - len: u16, - eb: *mut c_types::c_void, -) -> esp_err_t { - let packet = EspWifiPacketBuffer { buffer, len, eb }; - // We must handle the result outside of the critical section because - // EspWifiPacketBuffer::drop must not be called in a critical section. - // Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer` which - // will try to lock an internal mutex. If the mutex is already taken, the function will - // try to trigger a context switch, which will fail if we are in a critical section. - match critical_section::with(|cs| DATA_QUEUE_RX_STA.borrow_ref_mut(cs).enqueue(packet)) { - Ok(_) => { - #[cfg(feature = "embassy-net")] - embassy::STA_RECEIVE_WAKER.wake(); - include::ESP_OK as esp_err_t - } - Err(_) => { - debug!("RX QUEUE FULL"); - include::ESP_ERR_NO_MEM as esp_err_t - } - } -} - -unsafe extern "C" fn recv_cb_ap( - buffer: *mut c_types::c_void, - len: u16, - eb: *mut c_types::c_void, -) -> esp_err_t { - let packet = EspWifiPacketBuffer { buffer, len, eb }; - // We must handle the result outside of the critical section because - // EspWifiPacketBuffer::drop must not be called in a critical section. - // Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer` which - // will try to lock an internal mutex. If the mutex is already taken, the function will - // try to trigger a context switch, which will fail if we are in a critical section. - match critical_section::with(|cs| DATA_QUEUE_RX_AP.borrow_ref_mut(cs).enqueue(packet)) { - Ok(_) => { - #[cfg(feature = "embassy-net")] - embassy::AP_RECEIVE_WAKER.wake(); - include::ESP_OK as esp_err_t - } - Err(_) => { - debug!("RX QUEUE FULL"); - include::ESP_ERR_NO_MEM as esp_err_t - } - } -} - -pub(crate) static WIFI_TX_INFLIGHT: AtomicUsize = AtomicUsize::new(0); - -fn decrement_inflight_counter() { - WIFI_TX_INFLIGHT - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| { - Some(x.saturating_sub(1)) - }) - .unwrap(); -} - -#[ram] -unsafe extern "C" fn esp_wifi_tx_done_cb( - _ifidx: u8, - _data: *mut u8, - _data_len: *mut u16, - _tx_status: bool, -) { - trace!("esp_wifi_tx_done_cb"); - - decrement_inflight_counter(); - - #[cfg(feature = "embassy-net")] - embassy::TRANSMIT_WAKER.wake(); -} - -pub(crate) fn wifi_start() -> Result<(), WifiError> { - unsafe { - esp_wifi_result!(esp_wifi_start())?; - - let mode = WifiMode::current()?; - - // This is not an if-else because in AP-STA mode, both are true - if mode.is_ap() { - esp_wifi_result!(include::esp_wifi_set_inactive_time( - wifi_interface_t_WIFI_IF_AP, - crate::CONFIG.ap_beacon_timeout - ))?; - } - if mode.is_sta() { - esp_wifi_result!(include::esp_wifi_set_inactive_time( - wifi_interface_t_WIFI_IF_STA, - crate::CONFIG.beacon_timeout - ))?; - }; - - let ps_mode; - cfg_if::cfg_if! { - if #[cfg(feature = "ps-min-modem")] { - ps_mode = include::wifi_ps_type_t_WIFI_PS_MIN_MODEM; - } else if #[cfg(feature = "ps-max-modem")] { - ps_mode = include::wifi_ps_type_t_WIFI_PS_MAX_MODEM; - } else if #[cfg(coex)] { - ps_mode = include::wifi_ps_type_t_WIFI_PS_MIN_MODEM; - } else { - ps_mode = include::wifi_ps_type_t_WIFI_PS_NONE; - } - }; - - esp_wifi_result!(esp_wifi_set_ps(ps_mode))?; - - let mut cntry_code = [0u8; 3]; - cntry_code[..crate::CONFIG.country_code.len()] - .copy_from_slice(crate::CONFIG.country_code.as_bytes()); - cntry_code[2] = crate::CONFIG.country_code_operating_class; - - let country = wifi_country_t { - cc: core::mem::transmute(cntry_code), // [u8] -> [i8] conversion - schan: 1, - nchan: 13, - max_tx_power: 20, - policy: wifi_country_policy_t_WIFI_COUNTRY_POLICY_MANUAL, - }; - esp_wifi_result!(esp_wifi_set_country(&country))?; - } - - Ok(()) -} - -unsafe extern "C" fn coex_register_start_cb( - _cb: Option c_types::c_int>, -) -> c_types::c_int { - #[cfg(coex)] - return include::coex_register_start_cb(_cb); - - #[cfg(not(coex))] - 0 -} - -/// Configuration for active or passive scan. For details see the [WIFI Alliance FAQ](https://www.wi-fi.org/knowledge-center/faq/what-are-passive-and-active-scanning). -/// -/// # Comparison of active and passive scan -/// -///| | **Active** | **Passive** | -///|--------------------------------------|------------|-------------| -///| **Power consumption** | High | Low | -///| **Time required (typical behavior)** | Low | High | -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum ScanTypeConfig { - /// Active scan with min and max scan time per channel. This is the default and recommended if - /// you are unsure. - /// - /// # Procedure - /// 1. Send probe request on each channel. - /// 2. Wait for probe response. Wait at least `min` time, but if no response is received, wait up to `max` time. - /// 3. Switch channel. - /// 4. Repeat from 1. - Active { - /// Minimum scan time per channel. Defaults to 10ms. - min: Duration, - /// Maximum scan time per channel. Defaults to 20ms. - max: Duration, - }, - /// Passive scan - /// - /// # Procedure - /// 1. Wait for beacon for given duration. - /// 2. Switch channel. - /// 3. Repeat from 1. - /// - /// # Note - /// It is recommended to avoid duration longer thean 1500ms, as it may cause a station to - /// disconnect from the AP. - Passive(Duration), -} - -impl Default for ScanTypeConfig { - fn default() -> Self { - Self::Active { - min: Duration::from_millis(10), - max: Duration::from_millis(20), - } - } -} - -impl ScanTypeConfig { - fn validate(&self) { - if matches!(self, Self::Passive(dur) if *dur > Duration::from_millis(1500)) { - warn!("Passive scan duration longer than 1500ms may cause a station to disconnect from the AP"); - } - } -} - -/// Scan configuration -#[derive(Clone, Copy, Default, PartialEq, Eq)] -pub struct ScanConfig<'a> { - /// SSID to filter for. - /// If [`None`] is passed, all SSIDs will be returned. - /// If [`Some`] is passed, only the APs matching the given SSID will be returned. - pub ssid: Option<&'a str>, - /// BSSID to filter for. - /// If [`None`] is passed, all BSSIDs will be returned. - /// If [`Some`] is passed, only the APs matching the given BSSID will be returned. - pub bssid: Option<[u8; 6]>, - /// Channel to filter for. - /// If [`None`] is passed, all channels will be returned. - /// If [`Some`] is passed, only the APs on the given channel will be returned. - pub channel: Option, - /// Whether to show hidden networks. - pub show_hidden: bool, - /// Scan type, active or passive. - pub scan_type: ScanTypeConfig, -} - -pub(crate) fn wifi_start_scan( - block: bool, - ScanConfig { - ssid, - mut bssid, - channel, - show_hidden, - scan_type, - }: ScanConfig<'_>, -) -> i32 { - scan_type.validate(); - let (scan_time, scan_type) = match scan_type { - ScanTypeConfig::Active { min, max } => ( - wifi_scan_time_t { - active: wifi_active_scan_time_t { - min: min.as_millis() as u32, - max: max.as_millis() as u32, - }, - passive: 0, - }, - wifi_scan_type_t_WIFI_SCAN_TYPE_ACTIVE, - ), - ScanTypeConfig::Passive(dur) => ( - wifi_scan_time_t { - active: wifi_active_scan_time_t { min: 0, max: 0 }, - passive: dur.as_millis() as u32, - }, - wifi_scan_type_t_WIFI_SCAN_TYPE_PASSIVE, - ), - }; - - let mut ssid_buf = ssid.map(|m| { - let mut buf = heapless::Vec::::from_iter(m.bytes()); - unwrap!(buf.push(b'\0').ok()); - buf - }); - - let ssid = ssid_buf - .as_mut() - .map(|e| e.as_mut_ptr()) - .unwrap_or_else(core::ptr::null_mut); - let bssid = bssid - .as_mut() - .map(|e| e.as_mut_ptr()) - .unwrap_or_else(core::ptr::null_mut); - - let scan_config = wifi_scan_config_t { - ssid, - bssid, - channel: channel.unwrap_or(0), - show_hidden, - scan_type, - scan_time, - home_chan_dwell_time: 0, - }; - - unsafe { esp_wifi_scan_start(&scan_config, block) } -} - -/// Creates a new [WifiDevice] and [WifiController] in either AP or STA mode with the given -/// configuration. -/// -/// This function will panic if the configuration is not -/// [`Configuration::Client`] or [`Configuration::AccessPoint`]. -/// -/// If you want to use AP-STA mode, use `[new_ap_sta]`. -pub fn new_with_config<'d, MODE: WifiDeviceMode>( - inited: &EspWifiInitialization, - device: impl Peripheral

+ 'd, - config: MODE::Config, -) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> { - crate::hal::into_ref!(device); - - Ok(( - WifiDevice::new(unsafe { device.clone_unchecked() }, MODE::new()), - WifiController::new_with_config(inited, device, MODE::wrap_config(config))?, - )) -} - -/// Creates a new [WifiDevice] and [WifiController] in either AP or STA mode with a default -/// configuration. -/// -/// This function will panic if the mode is [`WifiMode::ApSta`]. -/// If you want to use AP-STA mode, use `[new_ap_sta]`. -pub fn new_with_mode<'d, MODE: WifiDeviceMode>( - inited: &EspWifiInitialization, - device: impl crate::hal::peripheral::Peripheral

+ 'd, - _mode: MODE, -) -> Result<(WifiDevice<'d, MODE>, WifiController<'d>), WifiError> { - new_with_config(inited, device, ::Config::default()) -} - -/// Creates a new [WifiDevice] and [WifiController] in AP-STA mode, with a default configuration. -/// -/// Returns a tuple of `(AP device, STA device, controller)`. -pub fn new_ap_sta<'d>( - inited: &EspWifiInitialization, - device: impl Peripheral

+ 'd, -) -> Result< - ( - WifiDevice<'d, WifiApDevice>, - WifiDevice<'d, WifiStaDevice>, - WifiController<'d>, - ), - WifiError, -> { - new_ap_sta_with_config(inited, device, Default::default(), Default::default()) -} - -/// Creates a new Wifi device and controller in AP-STA mode. -/// -/// Returns a tuple of `(AP device, STA device, controller)`. -pub fn new_ap_sta_with_config<'d>( - inited: &EspWifiInitialization, - device: impl Peripheral

+ 'd, - sta_config: crate::wifi::ClientConfiguration, - ap_config: crate::wifi::AccessPointConfiguration, -) -> Result< - ( - WifiDevice<'d, WifiApDevice>, - WifiDevice<'d, WifiStaDevice>, - WifiController<'d>, - ), - WifiError, -> { - crate::hal::into_ref!(device); - - Ok(( - WifiDevice::new(unsafe { device.clone_unchecked() }, WifiApDevice), - WifiDevice::new(unsafe { device.clone_unchecked() }, WifiStaDevice), - WifiController::new_with_config( - inited, - device, - Configuration::Mixed(sta_config, ap_config), - )?, - )) -} - -mod sealed { - use super::*; - - #[derive(Debug)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - /// Take care not to drop this while in a critical section. - /// - /// Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer` which - /// will try to lock an internal mutex. If the mutex is already taken, the function will - /// try to trigger a context switch, which will fail if we are in a critical section. - pub struct EspWifiPacketBuffer { - pub(crate) buffer: *mut c_types::c_void, - pub(crate) len: u16, - pub(crate) eb: *mut c_types::c_void, - } - - unsafe impl Send for EspWifiPacketBuffer {} - - impl Drop for EspWifiPacketBuffer { - fn drop(&mut self) { - trace!("Dropping EspWifiPacketBuffer, freeing memory"); - unsafe { esp_wifi_internal_free_rx_buffer(self.eb) }; - } - } - - impl EspWifiPacketBuffer { - pub fn as_slice_mut(&mut self) -> &mut [u8] { - unsafe { core::slice::from_raw_parts_mut(self.buffer as *mut u8, self.len as usize) } - } - } - - pub trait Sealed: Copy + Sized { - type Config: Default; - - fn new() -> Self; - - fn wrap_config(config: Self::Config) -> Configuration; - - fn data_queue_rx( - self, - cs: CriticalSection, - ) -> RefMut<'_, SimpleQueue>; - - fn can_send(self) -> bool { - WIFI_TX_INFLIGHT.load(Ordering::SeqCst) < TX_QUEUE_SIZE - } - - fn increase_in_flight_counter(self) { - WIFI_TX_INFLIGHT.fetch_add(1, Ordering::SeqCst); - } - - fn tx_token(self) -> Option> { - if !self.can_send() { - crate::timer::yield_task(); - } - - if self.can_send() { - Some(WifiTxToken { mode: self }) - } else { - None - } - } - - fn rx_token(self) -> Option<(WifiRxToken, WifiTxToken)> { - let is_empty = critical_section::with(|cs| self.data_queue_rx(cs).is_empty()); - if is_empty || !self.can_send() { - crate::timer::yield_task(); - } - - let is_empty = - is_empty && critical_section::with(|cs| self.data_queue_rx(cs).is_empty()); - - if !is_empty { - self.tx_token().map(|tx| (WifiRxToken { mode: self }, tx)) - } else { - None - } - } - - fn interface(self) -> wifi_interface_t; - - #[cfg(feature = "embassy-net")] - fn register_transmit_waker(self, cx: &mut core::task::Context) { - embassy::TRANSMIT_WAKER.register(cx.waker()) - } - - #[cfg(feature = "embassy-net")] - fn register_receive_waker(self, cx: &mut core::task::Context); - - #[cfg(feature = "embassy-net")] - fn register_link_state_waker(self, cx: &mut core::task::Context); - - #[cfg(feature = "embassy-net")] - fn link_state(self) -> embassy_net_driver::LinkState; - } - - impl Sealed for WifiStaDevice { - type Config = ClientConfiguration; - - fn new() -> Self { - Self - } - - fn wrap_config(config: ClientConfiguration) -> Configuration { - Configuration::Client(config) - } - - fn data_queue_rx( - self, - cs: CriticalSection, - ) -> RefMut<'_, SimpleQueue> { - DATA_QUEUE_RX_STA.borrow_ref_mut(cs) - } - - fn interface(self) -> wifi_interface_t { - wifi_interface_t_WIFI_IF_STA - } - - #[cfg(feature = "embassy-net")] - fn register_receive_waker(self, cx: &mut core::task::Context) { - embassy::STA_RECEIVE_WAKER.register(cx.waker()); - } - - #[cfg(feature = "embassy-net")] - fn register_link_state_waker(self, cx: &mut core::task::Context) { - embassy::STA_LINK_STATE_WAKER.register(cx.waker()); - } - - #[cfg(feature = "embassy-net")] - fn link_state(self) -> embassy_net_driver::LinkState { - if matches!(get_sta_state(), WifiState::StaConnected) { - embassy_net_driver::LinkState::Up - } else { - embassy_net_driver::LinkState::Down - } - } - } - - impl Sealed for WifiApDevice { - type Config = AccessPointConfiguration; - - fn new() -> Self { - Self - } - - fn wrap_config(config: AccessPointConfiguration) -> Configuration { - Configuration::AccessPoint(config) - } - - fn data_queue_rx( - self, - cs: CriticalSection, - ) -> RefMut<'_, SimpleQueue> { - DATA_QUEUE_RX_AP.borrow_ref_mut(cs) - } - - fn interface(self) -> wifi_interface_t { - wifi_interface_t_WIFI_IF_AP - } - - #[cfg(feature = "embassy-net")] - fn register_receive_waker(self, cx: &mut core::task::Context) { - embassy::AP_RECEIVE_WAKER.register(cx.waker()); - } - - #[cfg(feature = "embassy-net")] - fn register_link_state_waker(self, cx: &mut core::task::Context) { - embassy::AP_LINK_STATE_WAKER.register(cx.waker()); - } - - #[cfg(feature = "embassy-net")] - fn link_state(self) -> embassy_net_driver::LinkState { - if matches!(get_ap_state(), WifiState::ApStarted) { - embassy_net_driver::LinkState::Up - } else { - embassy_net_driver::LinkState::Down - } - } - } -} - -use sealed::*; - -pub trait WifiDeviceMode: Sealed { - fn mode(self) -> WifiMode; - - fn mac_address(self) -> [u8; 6]; -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct WifiStaDevice; - -impl WifiDeviceMode for WifiStaDevice { - fn mode(self) -> WifiMode { - WifiMode::Sta - } - - fn mac_address(self) -> [u8; 6] { - let mut mac = [0; 6]; - get_sta_mac(&mut mac); - mac - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct WifiApDevice; - -impl WifiDeviceMode for WifiApDevice { - fn mode(self) -> WifiMode { - WifiMode::Ap - } - - fn mac_address(self) -> [u8; 6] { - let mut mac = [0; 6]; - get_ap_mac(&mut mac); - mac - } -} - -/// A wifi device implementing smoltcp's Device trait. -pub struct WifiDevice<'d, MODE: WifiDeviceMode> { - _device: PeripheralRef<'d, crate::hal::peripherals::WIFI>, - mode: MODE, -} - -impl<'d, MODE: WifiDeviceMode> WifiDevice<'d, MODE> { - pub(crate) fn new( - _device: PeripheralRef<'d, crate::hal::peripherals::WIFI>, - mode: MODE, - ) -> Self { - Self { _device, mode } - } - - pub fn mac_address(&self) -> [u8; 6] { - self.mode.mac_address() - } - - #[cfg(not(feature = "smoltcp"))] - pub fn receive(&mut self) -> Option<(WifiRxToken, WifiTxToken)> { - self.mode.rx_token() - } - - #[cfg(not(feature = "smoltcp"))] - pub fn transmit(&mut self) -> Option> { - self.mode.tx_token() - } -} - -fn convert_ap_info(record: &include::wifi_ap_record_t) -> AccessPointInfo { - let str_len = record - .ssid - .iter() - .position(|&c| c == 0) - .unwrap_or(record.ssid.len()); - let ssid_ref = unsafe { core::str::from_utf8_unchecked(&record.ssid[..str_len]) }; - - let mut ssid = heapless::String::<32>::new(); - unwrap!(ssid.push_str(ssid_ref)); - - AccessPointInfo { - ssid, - bssid: record.bssid, - channel: record.primary, - secondary_channel: match record.second { - include::wifi_second_chan_t_WIFI_SECOND_CHAN_NONE => SecondaryChannel::None, - include::wifi_second_chan_t_WIFI_SECOND_CHAN_ABOVE => SecondaryChannel::Above, - include::wifi_second_chan_t_WIFI_SECOND_CHAN_BELOW => SecondaryChannel::Below, - _ => panic!(), - }, - signal_strength: record.rssi, - protocols: EnumSet::empty(), // TODO - auth_method: Some(AuthMethod::from_raw(record.authmode)), - } -} - -/// A wifi controller -pub struct WifiController<'d> { - _device: PeripheralRef<'d, crate::hal::peripherals::WIFI>, - config: Configuration, -} - -impl<'d> WifiController<'d> { - pub(crate) fn new_with_config( - inited: &EspWifiInitialization, - _device: PeripheralRef<'d, crate::hal::peripherals::WIFI>, - config: Configuration, - ) -> Result { - if !inited.is_wifi() { - return Err(WifiError::NotInitialized); - } - - // We set up the controller with the default config because we need to call - // `set_configuration` to apply the actual configuration, and it will update the stored - // configuration anyway. - let mut this = Self { - _device, - config: Default::default(), - }; - - let mode = WifiMode::try_from(&config)?; - esp_wifi_result!(unsafe { esp_wifi_set_mode(mode.into()) })?; - debug!("Wifi mode {:?} set", mode); - - this.set_configuration(&config)?; - Ok(this) - } - - /// Set the wifi mode. - /// - /// This will set the wifi protocol to the desired protocol, the default for this is: - /// `WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N` - /// - /// # Arguments: - /// - /// * `protocol` - The desired protocol - /// - /// # Example: - /// - /// ``` - /// use esp_wifi::wifi::Protocol; - /// use esp_wifi::wifi::WifiController; - /// let mut wifi = WifiController::new(); - /// wifi.set_mode(Protocol::P802D11BGNLR); - /// ``` - pub fn set_mode(&mut self, protocol: Protocol) -> Result<(), WifiError> { - let mut mode = wifi_mode_t_WIFI_MODE_NULL; - esp_wifi_result!(unsafe { esp_wifi_get_mode(&mut mode) })?; - esp_wifi_result!(unsafe { esp_wifi_set_protocol(mode, protocol as u8) })?; - Ok(()) - } - - pub fn is_sta_enabled(&self) -> Result { - WifiMode::try_from(&self.config).map(|m| m.is_sta()) - } - - pub fn is_ap_enabled(&self) -> Result { - WifiMode::try_from(&self.config).map(|m| m.is_ap()) - } - - /// A blocking wifi network scan with caller-provided scanning options. - pub fn scan_with_config_sync( - &mut self, - config: ScanConfig<'_>, - ) -> Result<(heapless::Vec, usize), WifiError> { - esp_wifi_result!(crate::wifi::wifi_start_scan(true, config))?; - - let count = self.scan_result_count()?; - let result = self.scan_results()?; - - Ok((result, count)) - } - - fn scan_result_count(&mut self) -> Result { - let mut bss_total: u16 = 0; - - // Prevents memory leak on error - let guard = FreeApListOnDrop; - - unsafe { esp_wifi_result!(include::esp_wifi_scan_get_ap_num(&mut bss_total))? }; - - guard.defuse(); - - Ok(bss_total as usize) - } - - fn scan_results( - &mut self, - ) -> Result, WifiError> { - let mut scanned = heapless::Vec::::new(); - let mut bss_total: u16 = N as u16; - - let mut records: [MaybeUninit; N] = [MaybeUninit::uninit(); N]; - - // Prevents memory leak on error - let guard = FreeApListOnDrop; - - unsafe { - esp_wifi_result!(include::esp_wifi_scan_get_ap_records( - &mut bss_total, - records[0].as_mut_ptr(), - ))? - }; - - guard.defuse(); - - for i in 0..bss_total { - let record = unsafe { MaybeUninit::assume_init_ref(&records[i as usize]) }; - let ap_info = convert_ap_info(record); - - scanned.push(ap_info).ok(); - } - - Ok(scanned) - } -} - -// see https://docs.rs/smoltcp/0.7.1/smoltcp/phy/index.html -#[cfg(feature = "smoltcp")] -impl Device for WifiDevice<'_, MODE> { - type RxToken<'a> = WifiRxToken where Self: 'a; - type TxToken<'a> = WifiTxToken where Self: 'a; - - fn receive( - &mut self, - _instant: smoltcp::time::Instant, - ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { - self.mode.rx_token() - } - - fn transmit(&mut self, _instant: smoltcp::time::Instant) -> Option> { - self.mode.tx_token() - } - - fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities { - let mut caps = DeviceCapabilities::default(); - caps.max_transmission_unit = MTU; - caps.max_burst_size = if crate::CONFIG.max_burst_size == 0 { - None - } else { - Some(crate::CONFIG.max_burst_size) - }; - caps - } -} - -#[doc(hidden)] -#[derive(Debug)] -pub struct WifiRxToken { - mode: MODE, -} - -impl WifiRxToken { - pub fn consume_token(self, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - let mut data = critical_section::with(|cs| { - let mut queue = self.mode.data_queue_rx(cs); - - unwrap!( - queue.dequeue(), - "unreachable: transmit()/receive() ensures there is a packet to process" - ) - }); - - // We handle the received data outside of the critical section because - // EspWifiPacketBuffer::drop must not be called in a critical section. - // Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer` which - // will try to lock an internal mutex. If the mutex is already taken, the function will - // try to trigger a context switch, which will fail if we are in a critical section. - let buffer = data.as_slice_mut(); - dump_packet_info(&buffer); - - f(buffer) - } -} - -#[cfg(feature = "smoltcp")] -impl RxToken for WifiRxToken { - fn consume(self, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - self.consume_token(f) - } -} - -#[doc(hidden)] -#[derive(Debug)] -pub struct WifiTxToken { - mode: MODE, -} - -impl WifiTxToken { - pub fn consume_token(self, len: usize, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - self.mode.increase_in_flight_counter(); - - // (safety): creation of multiple WiFi devices with the same mode is impossible in safe Rust, - // therefore only smoltcp _or_ embassy-net can be used at one time - static mut BUFFER: [u8; DATA_FRAME_SIZE] = [0u8; DATA_FRAME_SIZE]; - - let buffer = unsafe { &mut BUFFER[..len] }; - - let res = f(buffer); - - esp_wifi_send_data(self.mode.interface(), buffer); - - res - } -} - -#[cfg(feature = "smoltcp")] -impl TxToken for WifiTxToken { - fn consume(self, len: usize, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - self.consume_token(len, f) - } -} - -// FIXME data here has to be &mut because of `esp_wifi_internal_tx` signature, requiring a *mut ptr to the buffer -// Casting const to mut is instant UB, even though in reality `esp_wifi_internal_tx` copies the buffer into its own memory and -// does not modify -pub(crate) fn esp_wifi_send_data(interface: wifi_interface_t, data: &mut [u8]) { - trace!("sending... {} bytes", data.len()); - dump_packet_info(data); - - let len = data.len() as u16; - let ptr = data.as_mut_ptr().cast(); - - let res = unsafe { esp_wifi_internal_tx(interface, ptr, len) }; - - if res != 0 { - warn!("esp_wifi_internal_tx {}", res); - decrement_inflight_counter(); - } else { - trace!("esp_wifi_internal_tx ok"); - } -} - -fn apply_ap_config(config: &AccessPointConfiguration) -> Result<(), WifiError> { - let mut cfg = wifi_config_t { - ap: wifi_ap_config_t { - ssid: [0; 32], - password: [0; 64], - ssid_len: 0, - channel: config.channel, - authmode: config.auth_method.to_raw(), - ssid_hidden: if config.ssid_hidden { 1 } else { 0 }, - max_connection: config.max_connections as u8, - beacon_interval: 100, - pairwise_cipher: wifi_cipher_type_t_WIFI_CIPHER_TYPE_CCMP, - ftm_responder: false, - pmf_cfg: wifi_pmf_config_t { - capable: true, - required: false, - }, - sae_pwe_h2e: 0, - }, - }; - - unsafe { - cfg.ap.ssid[0..(config.ssid.len())].copy_from_slice(config.ssid.as_bytes()); - cfg.ap.ssid_len = config.ssid.len() as u8; - cfg.ap.password[0..(config.password.len())].copy_from_slice(config.password.as_bytes()); - - esp_wifi_result!(esp_wifi_set_config(wifi_interface_t_WIFI_IF_AP, &mut cfg)) - } -} - -fn apply_sta_config(config: &ClientConfiguration) -> Result<(), WifiError> { - let mut cfg = wifi_config_t { - sta: wifi_sta_config_t { - ssid: [0; 32], - password: [0; 64], - scan_method: crate::CONFIG.scan_method, - bssid_set: config.bssid.is_some(), - bssid: match config.bssid { - Some(bssid_ref) => bssid_ref, - None => [0; 6], - }, - channel: config.channel.unwrap_or(0), - listen_interval: crate::CONFIG.listen_interval, - sort_method: wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL, - threshold: wifi_scan_threshold_t { - rssi: -99, - authmode: config.auth_method.to_raw(), - }, - pmf_cfg: wifi_pmf_config_t { - capable: true, - required: false, - }, - sae_pwe_h2e: 3, - _bitfield_align_1: [0; 0], - _bitfield_1: __BindgenBitfieldUnit::new([0; 4]), - failure_retry_cnt: crate::CONFIG.failure_retry_cnt, - _bitfield_align_2: [0; 0], - _bitfield_2: __BindgenBitfieldUnit::new([0; 4]), - sae_pk_mode: 0, // ?? - sae_h2e_identifier: [0; 32], - }, - }; - - unsafe { - cfg.sta.ssid[0..(config.ssid.len())].copy_from_slice(config.ssid.as_bytes()); - cfg.sta.password[0..(config.password.len())].copy_from_slice(config.password.as_bytes()); - - esp_wifi_result!(esp_wifi_set_config(wifi_interface_t_WIFI_IF_STA, &mut cfg)) - } -} - -impl WifiController<'_> { - /// Get the supported capabilities of the controller. - pub fn get_capabilities(&self) -> Result, WifiError> { - let caps = match self.config { - Configuration::None => unreachable!(), - Configuration::Client(_) => enumset::enum_set! { Capability::Client }, - Configuration::AccessPoint(_) => enumset::enum_set! { Capability::AccessPoint }, - Configuration::Mixed(_, _) => { - Capability::Client | Capability::AccessPoint | Capability::Mixed - } - }; - - Ok(caps) - } - - /// Get the currently used configuration. - pub fn get_configuration(&self) -> Result { - Ok(self.config.clone()) - } - - /// Set the configuration, you need to use Wifi::connect() for connecting to an AP - pub fn set_configuration(&mut self, conf: &Configuration) -> Result<(), WifiError> { - match self.config { - Configuration::None => self.config = conf.clone(), // initial config - Configuration::Client(ref mut client) => { - if let Configuration::Client(conf) = conf { - *client = conf.clone(); - } else { - return Err(WifiError::InternalError( - InternalWifiError::EspErrInvalidArg, - )); - } - } - Configuration::AccessPoint(ref mut ap) => { - if let Configuration::AccessPoint(conf) = conf { - *ap = conf.clone(); - } else { - return Err(WifiError::InternalError( - InternalWifiError::EspErrInvalidArg, - )); - } - } - Configuration::Mixed(ref mut client, ref mut ap) => match conf { - Configuration::None => { - return Err(WifiError::InternalError( - InternalWifiError::EspErrInvalidArg, - )); - } - Configuration::Mixed(_, _) => self.config = conf.clone(), - Configuration::Client(conf) => *client = conf.clone(), - Configuration::AccessPoint(conf) => *ap = conf.clone(), - }, - } - - match conf { - Configuration::None => { - return Err(WifiError::InternalError( - InternalWifiError::EspErrInvalidArg, - )); - } - Configuration::Client(config) => apply_sta_config(config)?, - Configuration::AccessPoint(config) => apply_ap_config(config)?, - Configuration::Mixed(sta_config, ap_config) => { - apply_ap_config(ap_config)?; - apply_sta_config(sta_config)?; - } - }; - - Ok(()) - } - - pub(crate) fn stop_impl(&mut self) -> Result<(), WifiError> { - esp_wifi_result!(unsafe { esp_wifi_stop() }) - } - - pub(crate) fn connect_impl(&mut self) -> Result<(), WifiError> { - esp_wifi_result!(unsafe { esp_wifi_connect() }) - } - - pub(crate) fn disconnect_impl(&mut self) -> Result<(), WifiError> { - esp_wifi_result!(unsafe { esp_wifi_disconnect() }) - } - - pub fn is_started(&self) -> Result { - if matches!( - crate::wifi::get_sta_state(), - WifiState::StaStarted | WifiState::StaConnected | WifiState::StaDisconnected - ) { - return Ok(true); - } - if matches!(crate::wifi::get_ap_state(), WifiState::ApStarted) { - return Ok(true); - } - Ok(false) - } - - pub fn is_connected(&self) -> Result { - match crate::wifi::get_sta_state() { - crate::wifi::WifiState::StaConnected => Ok(true), - crate::wifi::WifiState::StaDisconnected => Err(WifiError::Disconnected), - //FIXME: Should any other enum value trigger an error instead of returning false? - _ => Ok(false), - } - } -} - -#[cfg(not(feature = "async"))] -impl WifiController<'_> { - /// A blocking wifi network scan with default scanning options. - pub fn scan_n( - &mut self, - ) -> Result<(heapless::Vec, usize), WifiError> { - self.scan_with_config_sync(Default::default()) - } - - pub fn start(&mut self) -> Result<(), WifiError> { - crate::wifi::wifi_start() - } - - pub fn stop(&mut self) -> Result<(), WifiError> { - self.stop_impl() - } - - pub fn connect(&mut self) -> Result<(), WifiError> { - self.connect_impl() - } - - pub fn disconnect(&mut self) -> Result<(), WifiError> { - self.disconnect_impl() - } -} - -fn dump_packet_info(_buffer: &[u8]) { - #[cfg(feature = "dump-packets")] - { - info!("@WIFIFRAME {:?}", _buffer); - } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! esp_wifi_result { - ($value:expr) => {{ - let result = $value; - if result != include::ESP_OK as i32 { - warn!("{} returned an error: {}", stringify!($value), result); - Err(WifiError::InternalError(unwrap!(FromPrimitive::from_i32( - result - )))) - } else { - Ok::<(), WifiError>(()) - } - }}; -} - -#[cfg(feature = "embassy-net")] -pub(crate) mod embassy { - use super::*; - use embassy_net_driver::{Capabilities, Driver, HardwareAddress, RxToken, TxToken}; - use embassy_sync::waitqueue::AtomicWaker; - - // We can get away with a single tx waker because the transmit queue is shared - // between interfaces. - pub(crate) static TRANSMIT_WAKER: AtomicWaker = AtomicWaker::new(); - - pub(crate) static AP_RECEIVE_WAKER: AtomicWaker = AtomicWaker::new(); - pub(crate) static AP_LINK_STATE_WAKER: AtomicWaker = AtomicWaker::new(); - - pub(crate) static STA_RECEIVE_WAKER: AtomicWaker = AtomicWaker::new(); - pub(crate) static STA_LINK_STATE_WAKER: AtomicWaker = AtomicWaker::new(); - - impl RxToken for WifiRxToken { - fn consume(self, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - self.consume_token(f) - } - } - - impl TxToken for WifiTxToken { - fn consume(self, len: usize, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - self.consume_token(len, f) - } - } - - impl Driver for WifiDevice<'_, MODE> { - type RxToken<'a> = WifiRxToken where Self: 'a; - type TxToken<'a> = WifiTxToken where Self: 'a; - - fn receive( - &mut self, - cx: &mut core::task::Context, - ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { - self.mode.register_receive_waker(cx); - self.mode.register_transmit_waker(cx); - self.mode.rx_token() - } - - fn transmit(&mut self, cx: &mut core::task::Context) -> Option> { - self.mode.register_transmit_waker(cx); - self.mode.tx_token() - } - - fn link_state(&mut self, cx: &mut core::task::Context) -> embassy_net_driver::LinkState { - self.mode.register_link_state_waker(cx); - self.mode.link_state() - } - - fn capabilities(&self) -> Capabilities { - let mut caps = Capabilities::default(); - caps.max_transmission_unit = MTU; - caps.max_burst_size = if crate::CONFIG.max_burst_size == 0 { - None - } else { - Some(crate::CONFIG.max_burst_size) - }; - caps - } - - fn hardware_address(&self) -> HardwareAddress { - HardwareAddress::Ethernet(self.mac_address()) - } - } -} - -#[cfg(feature = "async")] -mod asynch { - use core::task::Poll; - - use embassy_sync::waitqueue::AtomicWaker; - - use super::*; - - // TODO assumes STA mode only - impl<'d> WifiController<'d> { - /// Async version of [`crate::wifi::WifiController`]'s `scan_n` method - pub async fn scan_n( - &mut self, - ) -> Result<(heapless::Vec, usize), WifiError> { - self.scan_with_config(Default::default()).await - } - - pub async fn scan_with_config( - &mut self, - config: ScanConfig<'_>, - ) -> Result<(heapless::Vec, usize), WifiError> { - Self::clear_events(WifiEvent::ScanDone); - esp_wifi_result!(wifi_start_scan(false, config))?; - - // Prevents memory leak if `scan_n`'s future is dropped. - let guard = FreeApListOnDrop; - WifiEventFuture::new(WifiEvent::ScanDone).await; - - guard.defuse(); - - let count = self.scan_result_count()?; - let result = self.scan_results()?; - - Ok((result, count)) - } - - /// Async version of [`crate::wifi::WifiController`]'s `start` method - pub async fn start(&mut self) -> Result<(), WifiError> { - let mode = WifiMode::try_from(&self.config)?; - - let mut events = enumset::enum_set! {}; - if mode.is_ap() { - events |= WifiEvent::ApStart; - } - if mode.is_sta() { - events |= WifiEvent::StaStart; - } - - Self::clear_events(events); - - wifi_start()?; - - self.wait_for_all_events(events, false).await; - - Ok(()) - } - - /// Async version of [`crate::wifi::WifiController`]'s `stop` method - pub async fn stop(&mut self) -> Result<(), WifiError> { - let mode = WifiMode::try_from(&self.config)?; - - let mut events = enumset::enum_set! {}; - if mode.is_ap() { - events |= WifiEvent::ApStop; - } - if mode.is_sta() { - events |= WifiEvent::StaStop; - } - - Self::clear_events(events); - - crate::wifi::WifiController::stop_impl(self)?; - - self.wait_for_all_events(events, false).await; - - reset_ap_state(); - reset_sta_state(); - - Ok(()) - } - - /// Async version of [`crate::wifi::WifiController`]'s `connect` method - pub async fn connect(&mut self) -> Result<(), WifiError> { - Self::clear_events(WifiEvent::StaConnected | WifiEvent::StaDisconnected); - - let err = crate::wifi::WifiController::connect_impl(self).err(); - - if MultiWifiEventFuture::new(WifiEvent::StaConnected | WifiEvent::StaDisconnected) - .await - .contains(WifiEvent::StaDisconnected) - { - Err(err.unwrap_or(WifiError::Disconnected)) - } else { - Ok(()) - } - } - - /// Async version of [`crate::wifi::WifiController`]'s `Disconnect` method - pub async fn disconnect(&mut self) -> Result<(), WifiError> { - Self::clear_events(WifiEvent::StaDisconnected); - crate::wifi::WifiController::disconnect_impl(self)?; - WifiEventFuture::new(WifiEvent::StaDisconnected).await; - - Ok(()) - } - - fn clear_events(events: impl Into>) { - critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).remove_all(events.into())); - } - - /// Wait for one [`WifiEvent`]. - pub async fn wait_for_event(&mut self, event: WifiEvent) { - Self::clear_events(event); - WifiEventFuture::new(event).await - } - - /// Wait for one of multiple [`WifiEvent`]s. Returns the events that occurred while waiting. - pub async fn wait_for_events( - &mut self, - events: EnumSet, - clear_pending: bool, - ) -> EnumSet { - if clear_pending { - Self::clear_events(events); - } - MultiWifiEventFuture::new(events).await - } - - /// Wait for multiple [`WifiEvent`]s. - pub async fn wait_for_all_events( - &mut self, - mut events: EnumSet, - clear_pending: bool, - ) { - if clear_pending { - Self::clear_events(events); - } - - while !events.is_empty() { - let fired = MultiWifiEventFuture::new(events).await; - events -= fired; - } - } - } - - impl WifiEvent { - pub(crate) fn waker(&self) -> &'static AtomicWaker { - match self { - WifiEvent::ScanDone => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaStart => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaConnected => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaDisconnected => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaStop => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::WifiReady => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaAuthmodeChange => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaWpsErSuccess => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaWpsErFailed => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaWpsErTimeout => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaWpsErPin => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaWpsErPbcOverlap => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::ApStart => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::ApStop => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::ApStaconnected => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::ApStadisconnected => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::ApProbereqrecved => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::FtmReport => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaBssRssiLow => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::ActionTxStatus => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::RocDone => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - WifiEvent::StaBeaconTimeout => { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - } - } - } - - pub(crate) struct WifiEventFuture { - event: WifiEvent, - } - - impl WifiEventFuture { - pub fn new(event: WifiEvent) -> Self { - Self { event } - } - } - - impl core::future::Future for WifiEventFuture { - type Output = (); - - fn poll( - self: core::pin::Pin<&mut Self>, - cx: &mut core::task::Context<'_>, - ) -> Poll { - self.event.waker().register(cx.waker()); - if critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).remove(self.event)) { - Poll::Ready(()) - } else { - Poll::Pending - } - } - } - - pub(crate) struct MultiWifiEventFuture { - event: EnumSet, - } - - impl MultiWifiEventFuture { - pub fn new(event: EnumSet) -> Self { - Self { event } - } - } - - impl core::future::Future for MultiWifiEventFuture { - type Output = EnumSet; - - fn poll( - self: core::pin::Pin<&mut Self>, - cx: &mut core::task::Context<'_>, - ) -> Poll { - let output = critical_section::with(|cs| { - let mut events = WIFI_EVENTS.borrow_ref_mut(cs); - let active = events.intersection(self.event); - events.remove_all(active); - active - }); - if output.is_empty() { - for event in self.event.iter() { - event.waker().register(cx.waker()); - } - - Poll::Pending - } else { - Poll::Ready(output) - } - } - } -} - -struct FreeApListOnDrop; -impl FreeApListOnDrop { - pub fn defuse(self) { - core::mem::forget(self); - } -} - -impl Drop for FreeApListOnDrop { - fn drop(&mut self) { - unsafe { - include::esp_wifi_clear_ap_list(); - } - } -} - -#[cfg(feature = "embedded-svc")] -mod embedded_svc_compat { - use super::*; - - impl Into for Capability { - fn into(self) -> embedded_svc::wifi::Capability { - match self { - Capability::Client => embedded_svc::wifi::Capability::Client, - Capability::AccessPoint => embedded_svc::wifi::Capability::AccessPoint, - Capability::Mixed => embedded_svc::wifi::Capability::Mixed, - } - } - } - - impl Into for AuthMethod { - fn into(self) -> embedded_svc::wifi::AuthMethod { - match self { - AuthMethod::None => embedded_svc::wifi::AuthMethod::None, - AuthMethod::WEP => embedded_svc::wifi::AuthMethod::WEP, - AuthMethod::WPA => embedded_svc::wifi::AuthMethod::WPA, - AuthMethod::WPA2Personal => embedded_svc::wifi::AuthMethod::WPA2Personal, - AuthMethod::WPAWPA2Personal => embedded_svc::wifi::AuthMethod::WPAWPA2Personal, - AuthMethod::WPA2Enterprise => embedded_svc::wifi::AuthMethod::WPA2Enterprise, - AuthMethod::WPA3Personal => embedded_svc::wifi::AuthMethod::WPA3Personal, - AuthMethod::WPA2WPA3Personal => embedded_svc::wifi::AuthMethod::WPA2WPA3Personal, - AuthMethod::WAPIPersonal => embedded_svc::wifi::AuthMethod::WAPIPersonal, - } - } - } - - impl From for AuthMethod { - fn from(value: embedded_svc::wifi::AuthMethod) -> Self { - match value { - embedded_svc::wifi::AuthMethod::None => AuthMethod::None, - embedded_svc::wifi::AuthMethod::WEP => AuthMethod::WEP, - embedded_svc::wifi::AuthMethod::WPA => AuthMethod::WPA, - embedded_svc::wifi::AuthMethod::WPA2Personal => AuthMethod::WPA2Personal, - embedded_svc::wifi::AuthMethod::WPAWPA2Personal => AuthMethod::WPAWPA2Personal, - embedded_svc::wifi::AuthMethod::WPA2Enterprise => AuthMethod::WPA2Enterprise, - embedded_svc::wifi::AuthMethod::WPA3Personal => AuthMethod::WPA3Personal, - embedded_svc::wifi::AuthMethod::WPA2WPA3Personal => AuthMethod::WPA2WPA3Personal, - embedded_svc::wifi::AuthMethod::WAPIPersonal => AuthMethod::WAPIPersonal, - } - } - } - - impl Into for Protocol { - fn into(self) -> embedded_svc::wifi::Protocol { - match self { - Protocol::P802D11B => embedded_svc::wifi::Protocol::P802D11B, - Protocol::P802D11BG => embedded_svc::wifi::Protocol::P802D11BG, - Protocol::P802D11BGN => embedded_svc::wifi::Protocol::P802D11BGN, - Protocol::P802D11BGNLR => embedded_svc::wifi::Protocol::P802D11BGNLR, - Protocol::P802D11LR => embedded_svc::wifi::Protocol::P802D11LR, - } - } - } - - impl From for Protocol { - fn from(value: embedded_svc::wifi::Protocol) -> Self { - match value { - embedded_svc::wifi::Protocol::P802D11B => Protocol::P802D11B, - embedded_svc::wifi::Protocol::P802D11BG => Protocol::P802D11BG, - embedded_svc::wifi::Protocol::P802D11BGN => Protocol::P802D11BGN, - embedded_svc::wifi::Protocol::P802D11BGNLR => Protocol::P802D11BGNLR, - embedded_svc::wifi::Protocol::P802D11LR => Protocol::P802D11LR, - } - } - } - - impl Into for Configuration { - fn into(self) -> embedded_svc::wifi::Configuration { - match self { - Configuration::None => embedded_svc::wifi::Configuration::None, - Configuration::Client(conf) => embedded_svc::wifi::Configuration::Client( - embedded_svc::wifi::ClientConfiguration { - ssid: conf.ssid, - bssid: conf.bssid, - auth_method: conf.auth_method.into(), - password: conf.password, - channel: conf.channel, - }, - ), - Configuration::AccessPoint(conf) => embedded_svc::wifi::Configuration::AccessPoint( - embedded_svc::wifi::AccessPointConfiguration { - ssid: conf.ssid, - ssid_hidden: conf.ssid_hidden, - channel: conf.channel, - secondary_channel: conf.secondary_channel, - protocols: { - let mut res = EnumSet::::new(); - conf.protocols.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }, - auth_method: conf.auth_method.into(), - password: conf.password, - max_connections: conf.max_connections, - }, - ), - Configuration::Mixed(client, ap) => embedded_svc::wifi::Configuration::Mixed( - embedded_svc::wifi::ClientConfiguration { - ssid: client.ssid, - bssid: client.bssid, - auth_method: client.auth_method.into(), - password: client.password, - channel: client.channel, - }, - embedded_svc::wifi::AccessPointConfiguration { - ssid: ap.ssid, - ssid_hidden: ap.ssid_hidden, - channel: ap.channel, - secondary_channel: ap.secondary_channel, - protocols: { - let mut res = EnumSet::::new(); - ap.protocols.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }, - - auth_method: ap.auth_method.into(), - password: ap.password, - max_connections: ap.max_connections, - }, - ), - } - } - } - - impl From<&embedded_svc::wifi::Configuration> for Configuration { - fn from(value: &embedded_svc::wifi::Configuration) -> Self { - match value { - embedded_svc::wifi::Configuration::None => Configuration::None, - embedded_svc::wifi::Configuration::Client(conf) => { - Configuration::Client(ClientConfiguration { - ssid: conf.ssid.clone(), - bssid: conf.bssid.clone(), - auth_method: conf.auth_method.into(), - password: conf.password.clone(), - channel: conf.channel.clone(), - }) - } - embedded_svc::wifi::Configuration::AccessPoint(conf) => { - Configuration::AccessPoint(AccessPointConfiguration { - ssid: conf.ssid.clone(), - ssid_hidden: conf.ssid_hidden, - channel: conf.channel, - secondary_channel: conf.secondary_channel, - protocols: { - let mut res = EnumSet::::new(); - conf.protocols.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }, - auth_method: conf.auth_method.into(), - password: conf.password.clone(), - max_connections: conf.max_connections, - }) - } - embedded_svc::wifi::Configuration::Mixed(client, ap) => Configuration::Mixed( - ClientConfiguration { - ssid: client.ssid.clone(), - bssid: client.bssid.clone(), - auth_method: client.auth_method.into(), - password: client.password.clone(), - channel: client.channel, - }, - AccessPointConfiguration { - ssid: ap.ssid.clone(), - ssid_hidden: ap.ssid_hidden.clone(), - channel: ap.channel, - secondary_channel: ap.secondary_channel, - protocols: { - let mut res = EnumSet::::new(); - ap.protocols.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }, - auth_method: ap.auth_method.into(), - password: ap.password.clone(), - max_connections: ap.max_connections, - }, - ), - } - } - } - - impl Into for AccessPointInfo { - fn into(self) -> embedded_svc::wifi::AccessPointInfo { - embedded_svc::wifi::AccessPointInfo { - ssid: self.ssid.clone(), - bssid: self.bssid.clone(), - channel: self.channel, - secondary_channel: self.secondary_channel.into(), - signal_strength: self.signal_strength, - protocols: { - let mut res = EnumSet::::new(); - self.protocols.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }, - auth_method: self.auth_method.map(|v| v.into()), - } - } - } - - impl Into for SecondaryChannel { - fn into(self) -> embedded_svc::wifi::SecondaryChannel { - match self { - SecondaryChannel::None => embedded_svc::wifi::SecondaryChannel::None, - SecondaryChannel::Above => embedded_svc::wifi::SecondaryChannel::Above, - SecondaryChannel::Below => embedded_svc::wifi::SecondaryChannel::Below, - } - } - } - - impl Into for crate::wifi::ipv4::Subnet { - fn into(self) -> embedded_svc::ipv4::Subnet { - embedded_svc::ipv4::Subnet { - gateway: embedded_svc::ipv4::Ipv4Addr::from(self.gateway.octets()), - mask: embedded_svc::ipv4::Mask(self.mask.0), - } - } - } - - impl From for crate::wifi::ipv4::Subnet { - fn from(value: embedded_svc::ipv4::Subnet) -> Self { - Self { - gateway: super::ipv4::Ipv4Addr::from(value.gateway.octets()), - mask: super::ipv4::Mask(value.mask.0), - } - } - } - - impl Into for super::ipv4::IpInfo { - fn into(self) -> embedded_svc::ipv4::IpInfo { - embedded_svc::ipv4::IpInfo { - ip: embedded_svc::ipv4::Ipv4Addr::from(self.ip.octets()), - subnet: self.subnet.into(), - dns: self - .dns - .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - secondary_dns: self - .secondary_dns - .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - } - } - } - - impl From<&embedded_svc::ipv4::Configuration> for super::ipv4::Configuration { - fn from(value: &embedded_svc::ipv4::Configuration) -> Self { - match value { - embedded_svc::ipv4::Configuration::Client(client) => { - let config = match client { - embedded_svc::ipv4::ClientConfiguration::DHCP(dhcp) => { - super::ipv4::ClientConfiguration::DHCP( - super::ipv4::DHCPClientSettings { - hostname: dhcp.hostname.clone(), - }, - ) - } - embedded_svc::ipv4::ClientConfiguration::Fixed(fixed) => { - super::ipv4::ClientConfiguration::Fixed(super::ipv4::ClientSettings { - ip: super::ipv4::Ipv4Addr::from(fixed.ip.octets()), - subnet: fixed.subnet.into(), - dns: fixed.dns.map(|v| super::ipv4::Ipv4Addr::from(v.octets())), - secondary_dns: fixed - .secondary_dns - .map(|v| super::ipv4::Ipv4Addr::from(v.octets())), - }) - } - }; - super::ipv4::Configuration::Client(config) - } - embedded_svc::ipv4::Configuration::Router(router) => { - let config = super::ipv4::RouterConfiguration { - subnet: router.subnet.into(), - dhcp_enabled: router.dhcp_enabled, - dns: router.dns.map(|v| super::ipv4::Ipv4Addr::from(v.octets())), - secondary_dns: router - .secondary_dns - .map(|v| super::ipv4::Ipv4Addr::from(v.octets())), - }; - super::ipv4::Configuration::Router(config) - } - } - } - } - - impl Into for super::ipv4::Configuration { - fn into(self) -> embedded_svc::ipv4::Configuration { - match self { - super::ipv4::Configuration::Client(client) => { - let config = match client { - super::ipv4::ClientConfiguration::DHCP(dhcp) => { - embedded_svc::ipv4::ClientConfiguration::DHCP( - embedded_svc::ipv4::DHCPClientSettings { - hostname: dhcp.hostname.clone(), - }, - ) - } - super::ipv4::ClientConfiguration::Fixed(fixed) => { - embedded_svc::ipv4::ClientConfiguration::Fixed( - embedded_svc::ipv4::ClientSettings { - ip: embedded_svc::ipv4::Ipv4Addr::from(fixed.ip.octets()), - subnet: fixed.subnet.into(), - dns: fixed - .dns - .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - secondary_dns: fixed - .secondary_dns - .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - }, - ) - } - }; - embedded_svc::ipv4::Configuration::Client(config) - } - super::ipv4::Configuration::Router(router) => { - let config = embedded_svc::ipv4::RouterConfiguration { - subnet: router.subnet.into(), - dhcp_enabled: router.dhcp_enabled, - dns: router - .dns - .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - secondary_dns: router - .secondary_dns - .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - }; - embedded_svc::ipv4::Configuration::Router(config) - } - } - } - } - - #[cfg(not(feature = "async"))] - impl embedded_svc::wifi::Wifi for WifiController<'_> { - type Error = WifiError; - - fn get_capabilities(&self) -> Result, Self::Error> { - self.get_capabilities().map(|v| { - let mut res = EnumSet::::new(); - v.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }) - } - - fn get_configuration(&self) -> Result { - self.get_configuration().map(|v| v.into()) - } - - fn set_configuration( - &mut self, - conf: &embedded_svc::wifi::Configuration, - ) -> Result<(), Self::Error> { - let conf = conf.into(); - self.set_configuration(&conf) - } - - fn start(&mut self) -> Result<(), Self::Error> { - self.start() - } - - fn stop(&mut self) -> Result<(), Self::Error> { - self.stop() - } - - fn connect(&mut self) -> Result<(), Self::Error> { - self.connect() - } - - fn disconnect(&mut self) -> Result<(), Self::Error> { - self.disconnect() - } - - fn is_started(&self) -> Result { - self.is_started() - } - - fn is_connected(&self) -> Result { - self.is_connected() - } - - fn scan_n( - &mut self, - ) -> Result<(heapless::Vec, usize), Self::Error> - { - self.scan_n::().map(|(v, l)| { - let mut res: heapless::Vec = - heapless::Vec::new(); - for ap in v { - res.push(ap.into()).ok(); - } - (res, l) - }) - } - } - - #[cfg(feature = "async")] - impl embedded_svc::wifi::asynch::Wifi for WifiController<'_> { - type Error = WifiError; - - async fn get_capabilities( - &self, - ) -> Result, Self::Error> { - self.get_capabilities().map(|v| { - let mut res = EnumSet::::new(); - v.into_iter().for_each(|v| { - res.insert(v.into()); - }); - res - }) - } - - async fn get_configuration( - &self, - ) -> Result { - WifiController::get_configuration(self).map(|v| v.into()) - } - - async fn set_configuration( - &mut self, - conf: &embedded_svc::wifi::Configuration, - ) -> Result<(), Self::Error> { - let conf = conf.into(); - self.set_configuration(&conf) - } - - async fn start(&mut self) -> Result<(), Self::Error> { - self.start().await - } - - async fn stop(&mut self) -> Result<(), Self::Error> { - self.stop().await - } - - async fn connect(&mut self) -> Result<(), Self::Error> { - self.connect().await - } - - async fn disconnect(&mut self) -> Result<(), Self::Error> { - self.disconnect().await - } - - async fn is_started(&self) -> Result { - self.is_started() - } - - async fn is_connected(&self) -> Result { - self.is_connected() - } - - async fn scan_n( - &mut self, - ) -> Result<(heapless::Vec, usize), Self::Error> - { - self.scan_n::().await.map(|(v, l)| { - let mut res: heapless::Vec = - heapless::Vec::new(); - for ap in v { - res.push(ap.into()).ok(); - } - (res, l) - }) - } - } - - impl<'a, MODE: WifiDeviceMode> embedded_svc::ipv4::Interface - for crate::wifi_interface::WifiStack<'a, MODE> - { - type Error = crate::wifi_interface::WifiStackError; - - fn get_iface_configuration( - &self, - ) -> Result { - self.get_iface_configuration().map(|v| v.into()) - } - - fn set_iface_configuration( - &mut self, - conf: &embedded_svc::ipv4::Configuration, - ) -> Result<(), Self::Error> { - self.set_iface_configuration(&super::ipv4::Configuration::from(conf)) - } - - fn is_iface_up(&self) -> bool { - self.is_iface_up() - } - - fn get_ip_info(&self) -> Result { - self.get_ip_info().map(|v| v.into()) - } - } -} diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs deleted file mode 100644 index 29f9a938..00000000 --- a/esp-wifi/src/wifi/os_adapter.rs +++ /dev/null @@ -1,2005 +0,0 @@ -#[cfg_attr(esp32c3, path = "os_adapter_esp32c3.rs")] -#[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")] -#[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")] -#[cfg_attr(esp32h2, path = "os_adapter_esp32h2.rs")] -#[cfg_attr(esp32, path = "os_adapter_esp32.rs")] -#[cfg_attr(esp32s3, path = "os_adapter_esp32s3.rs")] -#[cfg_attr(esp32s2, path = "os_adapter_esp32s2.rs")] -pub(crate) mod os_adapter_chip_specific; - -use core::{cell::RefCell, ptr::addr_of_mut}; - -use critical_section::Mutex; -use enumset::EnumSet; - -use crate::{ - binary::include::*, - common_adapter::RADIO_CLOCKS, - compat::{ - common::{ - create_recursive_mutex, create_wifi_queue, lock_mutex, receive_queued, send_queued, - str_from_c, thread_sem_get, unlock_mutex, - }, - malloc::calloc, - task_runner::spawn_task, - }, - hal::system::RadioClockController, - hal::system::RadioPeripherals, - memory_fence::memory_fence, - timer::yield_task, -}; - -use crate::compat::syslog::syslog; - -use super::WifiEvent; - -// useful for waiting for events - clear and wait for the event bit to be set again -pub(crate) static WIFI_EVENTS: Mutex>> = - Mutex::new(RefCell::new(enumset::enum_set!())); - -/**************************************************************************** - * Name: wifi_env_is_chip - * - * Description: - * Config chip environment - * - * Returned Value: - * True if on chip or false if on FPGA. - * - ****************************************************************************/ -pub unsafe extern "C" fn env_is_chip() -> bool { - true -} - -/**************************************************************************** - * Name: wifi_set_intr - * - * Description: - * Do nothing - * - * Input Parameters: - * cpu_no - The CPU which the interrupt number belongs. - * intr_source - The interrupt hardware source number. - * intr_num - The interrupt number CPU. - * intr_prio - The interrupt priority. - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_intr(cpu_no: i32, intr_source: u32, intr_num: u32, intr_prio: i32) { - trace!( - "set_intr {} {} {} {}", - cpu_no, - intr_source, - intr_num, - intr_prio - ); - crate::wifi::os_adapter::os_adapter_chip_specific::set_intr( - cpu_no, - intr_source, - intr_num, - intr_prio, - ); -} - -/**************************************************************************** - * Name: wifi_clear_intr - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn clear_intr(intr_source: u32, intr_num: u32) { - // original code does nothing here - trace!("clear_intr called {} {}", intr_source, intr_num); -} - -pub static mut ISR_INTERRUPT_1: ( - *mut crate::binary::c_types::c_void, - *mut crate::binary::c_types::c_void, -) = (core::ptr::null_mut(), core::ptr::null_mut()); - -/**************************************************************************** - * Name: esp32c3_ints_on - * - * Description: - * Enable Wi-Fi interrupt - * - * Input Parameters: - * mask - No mean - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn ints_on(mask: u32) { - trace!("chip_ints_on {:x}", mask); - - crate::wifi::os_adapter::os_adapter_chip_specific::chip_ints_on(mask); -} - -/**************************************************************************** - * Name: esp32c3_ints_off - * - * Description: - * Disable Wi-Fi interrupt - * - * Input Parameters: - * mask - No mean - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn ints_off(mask: u32) { - trace!("chip_ints_off {:x}", mask); - - crate::wifi::os_adapter::os_adapter_chip_specific::chip_ints_off(mask); -} - -/**************************************************************************** - * Name: wifi_is_from_isr - * - * Description: - * Check current is in interrupt - * - * Input Parameters: - * None - * - * Returned Value: - * true if in interrupt or false if not - * - ****************************************************************************/ -pub unsafe extern "C" fn is_from_isr() -> bool { - true -} - -/**************************************************************************** - * Name: esp_spin_lock_create - * - * Description: - * Create spin lock in SMP mode - * - * Input Parameters: - * None - * - * Returned Value: - * Spin lock data pointer - * - ****************************************************************************/ -static mut FAKE_SPIN_LOCK: u8 = 1; -pub unsafe extern "C" fn spin_lock_create() -> *mut crate::binary::c_types::c_void { - // original: return (void *)1; - let ptr = addr_of_mut!(FAKE_SPIN_LOCK); - trace!("spin_lock_create {:?}", ptr); - ptr as *mut crate::binary::c_types::c_void -} - -/**************************************************************************** - * Name: esp_spin_lock_delete - * - * Description: - * Delete spin lock - * - * Input Parameters: - * lock - Spin lock data pointer - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn spin_lock_delete(lock: *mut crate::binary::c_types::c_void) { - // original: DEBUGASSERT((int)lock == 1); - trace!("spin_lock_delete {:?}", lock); -} - -/**************************************************************************** - * Name: esp_wifi_int_disable - * - * Description: - * Enter critical section by disabling interrupts and taking the spin lock - * if in SMP mode. - * - * Input Parameters: - * wifi_int_mux - Spin lock data pointer - * - * Returned Value: - * CPU PS value. - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - trace!("wifi_int_disable"); - crate::wifi::os_adapter::os_adapter_chip_specific::wifi_int_disable(wifi_int_mux) -} - -/**************************************************************************** - * Name: esp_wifi_int_restore - * - * Description: - * Exit from critical section by enabling interrupts and releasing the spin - * lock if in SMP mode. - * - * Input Parameters: - * wifi_int_mux - Spin lock data pointer - * tmp - CPU PS value. - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - trace!("wifi_int_restore"); - crate::wifi::os_adapter::os_adapter_chip_specific::wifi_int_restore(wifi_int_mux, tmp) -} - -/**************************************************************************** - * Name: esp_task_yield_from_isr - * - * Description: - * Do nothing in NuttX - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn task_yield_from_isr() { - // original: /* Do nothing */ - trace!("task_yield_from_isr"); - yield_task(); -} - -/**************************************************************************** - * Name: esp_thread_semphr_get - * - * Description: - * Get thread self's semaphore - * - * Input Parameters: - * None - * - * Returned Value: - * Semaphore data pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_thread_semphr_get() -> *mut crate::binary::c_types::c_void { - thread_sem_get() -} - -/**************************************************************************** - * Name: esp_mutex_create - * - * Description: - * Create mutex - * - * Input Parameters: - * None - * - * Returned Value: - * Mutex data pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn mutex_create() -> *mut crate::binary::c_types::c_void { - todo!("mutex_create") -} - -/**************************************************************************** - * Name: esp_recursive_mutex_create - * - * Description: - * Create recursive mutex - * - * Input Parameters: - * None - * - * Returned Value: - * Recursive mutex data pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn recursive_mutex_create() -> *mut crate::binary::c_types::c_void { - create_recursive_mutex() -} - -/**************************************************************************** - * Name: esp_mutex_delete - * - * Description: - * Delete mutex - * - * Input Parameters: - * mutex_data - mutex data pointer - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn mutex_delete(_mutex: *mut crate::binary::c_types::c_void) { - todo!("mutex_delete") -} - -/**************************************************************************** - * Name: esp_mutex_lock - * - * Description: - * Lock mutex - * - * Input Parameters: - * mutex_data - mutex data pointer - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn mutex_lock(mutex: *mut crate::binary::c_types::c_void) -> i32 { - lock_mutex(mutex) -} - -/**************************************************************************** - * Name: esp_mutex_unlock - * - * Description: - * Unlock mutex - * - * Input Parameters: - * mutex_data - mutex data pointer - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn mutex_unlock(mutex: *mut crate::binary::c_types::c_void) -> i32 { - unlock_mutex(mutex) -} - -/**************************************************************************** - * Name: esp_queue_create - * - * Description: - * Create message queue - * - * Input Parameters: - * queue_len - queue message number - * item_size - message size - * - * Returned Value: - * Message queue data pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_create( - _queue_len: u32, - _item_size: u32, -) -> *mut crate::binary::c_types::c_void { - todo!("queue_create") -} - -/**************************************************************************** - * Name: esp_queue_delete - * - * Description: - * Delete message queue - * - * Input Parameters: - * queue - Message queue data pointer - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_delete(_queue: *mut crate::binary::c_types::c_void) { - todo!("queue_delete") -} - -/**************************************************************************** - * Name: esp_queue_send - * - * Description: - * Send message of low priority to queue within a certain period of time - * - * Input Parameters: - * queue - Message queue data pointer - * item - Message data pointer - * ticks - Wait ticks - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_send( - queue: *mut crate::binary::c_types::c_void, - item: *mut crate::binary::c_types::c_void, - block_time_tick: u32, -) -> i32 { - send_queued(queue, item, block_time_tick) -} - -/**************************************************************************** - * Name: esp_queue_send_from_isr - * - * Description: - * Send message of low priority to queue in ISR within - * a certain period of time - * - * Input Parameters: - * queue - Message queue data pointer - * item - Message data pointer - * hptw - No mean - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_send_from_isr( - queue: *mut crate::binary::c_types::c_void, - item: *mut crate::binary::c_types::c_void, - _hptw: *mut crate::binary::c_types::c_void, -) -> i32 { - trace!("queue_send_from_isr"); - *(_hptw as *mut u32) = 1; - queue_send(queue, item, 1000) -} - -/**************************************************************************** - * Name: esp_queue_send_to_back - * - * Description: - * Send message of low priority to queue within a certain period of time - * - * Input Parameters: - * queue - Message queue data pointer - * item - Message data pointer - * ticks - Wait ticks - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_send_to_back( - _queue: *mut crate::binary::c_types::c_void, - _item: *mut crate::binary::c_types::c_void, - _block_time_tick: u32, -) -> i32 { - todo!("queue_send_to_back") -} - -/**************************************************************************** - * Name: esp_queue_send_from_to_front - * - * Description: - * Send message of high priority to queue within a certain period of time - * - * Input Parameters: - * queue - Message queue data pointer - * item - Message data pointer - * ticks - Wait ticks - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_send_to_front( - _queue: *mut crate::binary::c_types::c_void, - _item: *mut crate::binary::c_types::c_void, - _block_time_tick: u32, -) -> i32 { - todo!("queue_send_to_front") -} - -/**************************************************************************** - * Name: esp_queue_recv - * - * Description: - * Receive message from queue within a certain period of time - * - * Input Parameters: - * queue - Message queue data pointer - * item - Message data pointer - * ticks - Wait ticks - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_recv( - queue: *mut crate::binary::c_types::c_void, - item: *mut crate::binary::c_types::c_void, - block_time_tick: u32, -) -> i32 { - receive_queued(queue, item, block_time_tick) -} - -/**************************************************************************** - * Name: esp_queue_msg_waiting - * - * Description: - * Get message number in the message queue - * - * Input Parameters: - * queue - Message queue data pointer - * - * Returned Value: - * Message number - * - ****************************************************************************/ -pub unsafe extern "C" fn queue_msg_waiting(_queue: *mut crate::binary::c_types::c_void) -> u32 { - todo!("queue_msg_waiting") -} - -/**************************************************************************** - * Name: esp_event_group_create - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn event_group_create() -> *mut crate::binary::c_types::c_void { - todo!("event_group_create") -} - -/**************************************************************************** - * Name: esp_event_group_delete - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn event_group_delete(_event: *mut crate::binary::c_types::c_void) { - todo!("event_group_delete") -} - -/**************************************************************************** - * Name: esp_event_group_set_bits - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn event_group_set_bits( - _event: *mut crate::binary::c_types::c_void, - _bits: u32, -) -> u32 { - todo!("event_group_set_bits") -} - -/**************************************************************************** - * Name: esp_event_group_clear_bits - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn event_group_clear_bits( - _event: *mut crate::binary::c_types::c_void, - _bits: u32, -) -> u32 { - todo!("event_group_clear_bits") -} - -/**************************************************************************** - * Name: esp_event_group_wait_bits - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn event_group_wait_bits( - _event: *mut crate::binary::c_types::c_void, - _bits_to_wait_for: u32, - _clear_on_exit: crate::binary::c_types::c_int, - _wait_for_all_bits: crate::binary::c_types::c_int, - _block_time_tick: u32, -) -> u32 { - todo!("event_group_wait_bits") -} - -/**************************************************************************** - * Name: esp_task_create_pinned_to_core - * - * Description: - * Create task and bind it to target CPU, the task will run when it - * is created - * - * Input Parameters: - * entry - Task entry - * name - Task name - * stack_depth - Task stack size - * param - Task private data - * prio - Task priority - * task_handle - Task handle pointer which is used to pause, resume - * and delete the task - * core_id - CPU which the task runs in - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn task_create_pinned_to_core( - task_func: *mut crate::binary::c_types::c_void, - name: *const crate::binary::c_types::c_char, - stack_depth: u32, - param: *mut crate::binary::c_types::c_void, - prio: u32, - task_handle: *mut crate::binary::c_types::c_void, - core_id: u32, -) -> i32 { - trace!("task_create_pinned_to_core task_func {:?} name {} stack_depth {} param {:?} prio {}, task_handle {:?} core_id {}", - task_func, - str_from_c(name as *const u8), - stack_depth, - param, - prio, - task_handle, - core_id - ); - - *(task_handle as *mut usize) = 0; // we will run it in task 0 - - if spawn_task( - task_func, - name, - stack_depth, - param, - prio, - task_handle, - core_id, - ) { - 1 - } else { - 0 - } -} - -/**************************************************************************** - * Name: esp_task_create - * - * Description: - * Create task and the task will run when it is created - * - * Input Parameters: - * entry - Task entry - * name - Task name - * stack_depth - Task stack size - * param - Task private data - * prio - Task priority - * task_handle - Task handle pointer which is used to pause, resume - * and delete the task - * - * Returned Value: - * True if success or false if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn task_create( - _task_func: *mut crate::binary::c_types::c_void, - _name: *const crate::binary::c_types::c_char, - _stack_depth: u32, - _param: *mut crate::binary::c_types::c_void, - _prio: u32, - _task_handle: *mut crate::binary::c_types::c_void, -) -> i32 { - todo!("task_create"); -} - -/**************************************************************************** - * Name: esp_task_delete - * - * Description: - * Delete the target task - * - * Input Parameters: - * task_handle - Task handle pointer which is used to pause, resume - * and delete the task - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn task_delete(_task_handle: *mut crate::binary::c_types::c_void) { - todo!("task_delete") -} - -/**************************************************************************** - * Name: esp_task_delay - * - * Description: - * Current task wait for some ticks - * - * Input Parameters: - * tick - Waiting ticks - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn task_delay(tick: u32) { - trace!("task_delay tick {}", tick); - let start_time = crate::timer::get_systimer_count(); - while crate::timer::elapsed_time_since(start_time) < tick as u64 { - yield_task(); - } -} - -/**************************************************************************** - * Name: esp_task_ms_to_tick - * - * Description: - * Transform from millim seconds to system ticks - * - * Input Parameters: - * ms - Millim seconds - * - * Returned Value: - * System ticks - * - ****************************************************************************/ -pub unsafe extern "C" fn task_ms_to_tick(ms: u32) -> i32 { - trace!("task_ms_to_tick ms {}", ms); - crate::timer::millis_to_ticks(ms as u64) as i32 -} - -/**************************************************************************** - * Name: esp_task_get_current_task - * - * Description: - * Transform from millim seconds to system ticks - * - * Input Parameters: - * ms - Millim seconds - * - * Returned Value: - * System ticks - * - ****************************************************************************/ -pub unsafe extern "C" fn task_get_current_task() -> *mut crate::binary::c_types::c_void { - let res = crate::preempt::current_task() as *mut crate::binary::c_types::c_void; - trace!("task get current task - return {:?}", res); - - res -} - -/**************************************************************************** - * Name: esp_task_get_max_priority - * - * Description: - * Get OS task maximum priority - * - * Input Parameters: - * None - * - * Returned Value: - * Task maximum priority - * - ****************************************************************************/ -pub unsafe extern "C" fn task_get_max_priority() -> i32 { - trace!("task_get_max_priority"); - 255 -} - -/**************************************************************************** - * Name: esp_malloc - * - * Description: - * Allocate a block of memory - * - * Input Parameters: - * size - memory size - * - * Returned Value: - * Memory pointer - * - ****************************************************************************/ -#[no_mangle] -pub unsafe extern "C" fn malloc(size: usize) -> *mut crate::binary::c_types::c_void { - crate::compat::malloc::malloc(size).cast() -} - -/**************************************************************************** - * Name: esp_free - * - * Description: - * Free a block of memory - * - * Input Parameters: - * ptr - memory block - * - * Returned Value: - * No - * - ****************************************************************************/ -#[no_mangle] -pub unsafe extern "C" fn free(p: *mut crate::binary::c_types::c_void) { - crate::compat::malloc::free(p.cast()); -} - -/**************************************************************************** - * Name: esp_event_post - * - * Description: - * Active work queue and let the work to process the cached event - * - * Input Parameters: - * event_base - Event set name - * event_id - Event ID - * event_data - Event private data - * event_data_size - Event data size - * ticks - Waiting system ticks - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn event_post( - event_base: *const crate::binary::c_types::c_char, - event_id: i32, - event_data: *mut crate::binary::c_types::c_void, - event_data_size: usize, - ticks_to_wait: u32, -) -> i32 { - trace!( - "event_post {:?} {} {:?} {} {:?}", - event_base, - event_id, - event_data, - event_data_size, - ticks_to_wait - ); - use num_traits::FromPrimitive; - - let event = unwrap!(WifiEvent::from_i32(event_id)); - trace!("EVENT: {:?}", event); - critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).insert(event)); - - super::state::update_state(event); - - #[cfg(feature = "async")] - event.waker().wake(); - - #[cfg(feature = "embassy-net")] - match event { - WifiEvent::StaConnected | WifiEvent::StaDisconnected => { - crate::wifi::embassy::STA_LINK_STATE_WAKER.wake(); - } - - WifiEvent::ApStart | WifiEvent::ApStop => { - crate::wifi::embassy::AP_LINK_STATE_WAKER.wake(); - } - - _ => {} - } - - memory_fence(); - - 0 -} - -/**************************************************************************** - * Name: esp_get_free_heap_size - * - * Description: - * Get free heap size by byte - * - * Input Parameters: - * None - * - * Returned Value: - * Free heap size - * - ****************************************************************************/ -pub unsafe extern "C" fn get_free_heap_size() -> u32 { - critical_section::with(|cs| crate::HEAP.borrow_ref(cs).free() as u32) -} - -/**************************************************************************** - * Name: esp_rand - * - * Description: - * Get random data of type uint32_t - * - * Input Parameters: - * None - * - * Returned Value: - * Random data - * - ****************************************************************************/ -pub unsafe extern "C" fn rand() -> u32 { - crate::common_adapter::random() -} - -/**************************************************************************** - * Name: esp_dport_access_stall_other_cpu_start - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn dport_access_stall_other_cpu_start_wrap() { - trace!("dport_access_stall_other_cpu_start_wrap") -} - -/**************************************************************************** - * Name: esp_dport_access_stall_other_cpu_end - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn dport_access_stall_other_cpu_end_wrap() { - trace!("dport_access_stall_other_cpu_end_wrap") -} -/**************************************************************************** - * Name: wifi_apb80m_request - * - * Description: - * Take Wi-Fi lock in auto-sleep - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_apb80m_request() { - trace!("wifi_apb80m_request - no-op") -} -/**************************************************************************** - * Name: wifi_apb80m_release - * - * Description: - * Release Wi-Fi lock in auto-sleep - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_apb80m_release() { - trace!("wifi_apb80m_release - no-op") -} - -/**************************************************************************** - * Name: esp32c3_phy_disable - * - * Description: - * Deinitialize PHY hardware - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn phy_disable() { - trace!("phy_disable"); - - crate::common_adapter::chip_specific::phy_disable(); -} - -/**************************************************************************** - * Name: esp32c3_phy_enable - * - * Description: - * Initialize PHY hardware - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn phy_enable() { - // quite some code needed here - trace!("phy_enable"); - - crate::common_adapter::chip_specific::phy_enable(); -} - -/**************************************************************************** - * Name: wifi_phy_update_country_info - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn phy_update_country_info( - country: *const crate::binary::c_types::c_char, -) -> crate::binary::c_types::c_int { - // not implemented in original code - trace!("phy_update_country_info {}", *country as u8 as char); - -1 -} - -/**************************************************************************** - * Name: wifi_reset_mac - * - * Description: - * Reset Wi-Fi hardware MAC - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_reset_mac() { - trace!("wifi_reset_mac"); - unwrap!(RADIO_CLOCKS.as_mut()).reset_mac(); -} - -/**************************************************************************** - * Name: wifi_clock_enable - * - * Description: - * Enable Wi-Fi clock - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_clock_enable() { - trace!("wifi_clock_enable"); - unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Wifi); -} - -/**************************************************************************** - * Name: wifi_clock_disable - * - * Description: - * Disable Wi-Fi clock - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_clock_disable() { - trace!("wifi_clock_disable"); - unwrap!(RADIO_CLOCKS.as_mut()).disable(RadioPeripherals::Wifi); -} - -/**************************************************************************** - * Name: wifi_rtc_enable_iso - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_rtc_enable_iso() { - todo!("wifi_rtc_enable_iso") -} - -/**************************************************************************** - * Name: wifi_rtc_disable_iso - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_rtc_disable_iso() { - todo!("wifi_rtc_disable_iso") -} - -/**************************************************************************** - * Name: esp_timer_get_time - * - * Description: - * Get time in microseconds since boot. - * - * Returned Value: - * System time in micros - * - ****************************************************************************/ -#[no_mangle] -pub unsafe extern "C" fn esp_timer_get_time() -> i64 { - trace!("esp_timer_get_time"); - crate::timer::ticks_to_micros(crate::timer::get_systimer_count()) as i64 -} - -/**************************************************************************** - * Name: esp_nvs_set_i8 - * - * Description: - * Save data of type int8_t into file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * value - Stored data - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_set_i8( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _value: i8, -) -> crate::binary::c_types::c_int { - debug!("nvs_set_i8"); - -1 -} - -/**************************************************************************** - * Name: esp_nvs_get_i8 - * - * Description: - * Read data of type int8_t from file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * out_value - Read buffer pointer - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_get_i8( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _out_value: *mut i8, -) -> crate::binary::c_types::c_int { - todo!("nvs_get_i8") -} - -/**************************************************************************** - * Name: esp_nvs_set_u8 - * - * Description: - * Save data of type uint8_t into file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * value - Stored data - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_set_u8( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _value: u8, -) -> crate::binary::c_types::c_int { - todo!("nvs_set_u8") -} - -/**************************************************************************** - * Name: esp_nvs_get_u8 - * - * Description: - * Read data of type uint8_t from file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * out_value - Read buffer pointer - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_get_u8( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _out_value: *mut u8, -) -> crate::binary::c_types::c_int { - todo!("nvs_get_u8") -} - -/**************************************************************************** - * Name: esp_nvs_set_u16 - * - * Description: - * Save data of type uint16_t into file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * value - Stored data - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_set_u16( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _value: u16, -) -> crate::binary::c_types::c_int { - todo!("nvs_set_u16") -} - -/**************************************************************************** - * Name: esp_nvs_get_u16 - * - * Description: - * Read data of type uint16_t from file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * out_value - Read buffer pointer - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_get_u16( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _out_value: *mut u16, -) -> crate::binary::c_types::c_int { - todo!("nvs_get_u16") -} - -/**************************************************************************** - * Name: esp_nvs_open - * - * Description: - * Create a file system storage data object - * - * Input Parameters: - * name - Storage index - * open_mode - Storage mode - * out_handle - Storage handle - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_open( - _name: *const crate::binary::c_types::c_char, - _open_mode: u32, - _out_handle: *mut u32, -) -> crate::binary::c_types::c_int { - todo!("nvs_open") -} - -/**************************************************************************** - * Name: esp_nvs_close - * - * Description: - * Close storage data object and free resource - * - * Input Parameters: - * handle - NVS handle - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_close(_handle: u32) { - todo!("nvs_close") -} - -/**************************************************************************** - * Name: esp_nvs_commit - * - * Description: - * This function has no practical effect - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_commit(_handle: u32) -> crate::binary::c_types::c_int { - todo!("nvs_commit") -} - -/**************************************************************************** - * Name: esp_nvs_set_blob - * - * Description: - * Save a block of data into file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * value - Stored buffer pointer - * length - Buffer length - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_set_blob( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _value: *const crate::binary::c_types::c_void, - _length: usize, -) -> crate::binary::c_types::c_int { - todo!("nvs_set_blob") -} - -/**************************************************************************** - * Name: esp_nvs_get_blob - * - * Description: - * Read a block of data from file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * out_value - Read buffer pointer - * length - Buffer length - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_get_blob( - _handle: u32, - _key: *const crate::binary::c_types::c_char, - _out_value: *mut crate::binary::c_types::c_void, - _length: *mut usize, -) -> crate::binary::c_types::c_int { - todo!("nvs_get_blob") -} - -/**************************************************************************** - * Name: esp_nvs_erase_key - * - * Description: - * Read a block of data from file system - * - * Input Parameters: - * handle - NVS handle - * key - Data index - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn nvs_erase_key( - _handle: u32, - _key: *const crate::binary::c_types::c_char, -) -> crate::binary::c_types::c_int { - todo!("nvs_erase_key") -} - -/**************************************************************************** - * Name: esp_get_random - * - * Description: - * Fill random data int given buffer of given length - * - * Input Parameters: - * buf - buffer pointer - * len - buffer length - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn get_random(buf: *mut u8, len: usize) -> crate::binary::c_types::c_int { - trace!("get_random"); - if let Some(ref mut rng) = crate::common_adapter::RANDOM_GENERATOR { - let buffer = unsafe { core::slice::from_raw_parts_mut(buf, len) }; - - for chunk in buffer.chunks_mut(4) { - let bytes = rng.random().to_le_bytes(); - chunk.copy_from_slice(&bytes[..chunk.len()]); - } - - 0 - } else { - -1 - } -} - -/**************************************************************************** - * Name: esp_get_time - * - * Description: - * Get std C time - * - * Input Parameters: - * t - buffer to store time of type timeval - * - * Returned Value: - * 0 if success or -1 if fail - * - ****************************************************************************/ -pub unsafe extern "C" fn get_time( - _t: *mut crate::binary::c_types::c_void, -) -> crate::binary::c_types::c_int { - todo!("get_time") -} - -/**************************************************************************** - * Name: esp_log_write - * - * Description: - * Output log with by format string and its arguments - * - * Input Parameters: - * level - log level, no mean here - * tag - log TAG, no mean here - * format - format string - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn log_write( - level: u32, - _tag: *const crate::binary::c_types::c_char, - format: *const crate::binary::c_types::c_char, - args: ... -) { - let args = core::mem::transmute(args); - syslog(level, format as *const u8, args); -} - -/**************************************************************************** - * Name: esp_log_writev - * - * Description: - * Output log with by format string and its arguments - * - * Input Parameters: - * level - log level, no mean here - * tag - log TAG, no mean here - * format - format string - * args - arguments list - * - * Returned Value: - * None - * - ****************************************************************************/ -#[allow(improper_ctypes_definitions)] -pub unsafe extern "C" fn log_writev( - level: u32, - _tag: *const crate::binary::c_types::c_char, - format: *const crate::binary::c_types::c_char, - args: va_list, -) { - let args = core::mem::transmute(args); - syslog(level, format as *const u8, args); -} - -/**************************************************************************** - * Name: esp_log_timestamp - * - * Description: - * Get system time by millim second - * - * Input Parameters: - * None - * - * Returned Value: - * System time - * - ****************************************************************************/ -pub unsafe extern "C" fn log_timestamp() -> u32 { - crate::current_millis() as u32 -} - -/**************************************************************************** - * Name: esp_malloc_internal - * - * Description: - * Drivers allocate a block of memory - * - * Input Parameters: - * size - memory size - * - * Returned Value: - * Memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn malloc_internal(size: usize) -> *mut crate::binary::c_types::c_void { - crate::compat::malloc::malloc(size).cast() -} - -/**************************************************************************** - * Name: esp_realloc_internal - * - * Description: - * Drivers allocate a block of memory by old memory block - * - * Input Parameters: - * ptr - old memory pointer - * size - memory size - * - * Returned Value: - * New memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn realloc_internal( - _ptr: *mut crate::binary::c_types::c_void, - _size: usize, -) -> *mut crate::binary::c_types::c_void { - todo!("realloc_internal") -} - -/**************************************************************************** - * Name: esp_calloc_internal - * - * Description: - * Drivers allocate some continuous blocks of memory - * - * Input Parameters: - * n - memory block number - * size - memory block size - * - * Returned Value: - * New memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn calloc_internal( - n: usize, - size: usize, -) -> *mut crate::binary::c_types::c_void { - calloc(n as u32, size) as *mut crate::binary::c_types::c_void -} - -/**************************************************************************** - * Name: esp_zalloc_internal - * - * Description: - * Drivers allocate a block of memory and clear it with 0 - * - * Input Parameters: - * size - memory size - * - * Returned Value: - * New memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn zalloc_internal(size: usize) -> *mut crate::binary::c_types::c_void { - calloc(size as u32, 1usize) as *mut crate::binary::c_types::c_void -} - -/**************************************************************************** - * Name: esp_wifi_malloc - * - * Description: - * Applications allocate a block of memory - * - * Input Parameters: - * size - memory size - * - * Returned Value: - * Memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_malloc(size: usize) -> *mut crate::binary::c_types::c_void { - malloc(size) -} - -/**************************************************************************** - * Name: esp_wifi_realloc - * - * Description: - * Applications allocate a block of memory by old memory block - * - * Input Parameters: - * ptr - old memory pointer - * size - memory size - * - * Returned Value: - * New memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_realloc( - _ptr: *mut crate::binary::c_types::c_void, - _size: usize, -) -> *mut crate::binary::c_types::c_void { - todo!("wifi_realloc") -} - -/**************************************************************************** - * Name: esp_wifi_calloc - * - * Description: - * Applications allocate some continuous blocks of memory - * - * Input Parameters: - * n - memory block number - * size - memory block size - * - * Returned Value: - * New memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_calloc(n: usize, size: usize) -> *mut crate::binary::c_types::c_void { - trace!("wifi_calloc {} {}", n, size); - calloc(n as u32, size) as *mut crate::binary::c_types::c_void -} - -/**************************************************************************** - * Name: esp_wifi_zalloc - * - * Description: - * Applications allocate a block of memory and clear it with 0 - * - * Input Parameters: - * size - memory size - * - * Returned Value: - * New memory pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_zalloc(size: usize) -> *mut crate::binary::c_types::c_void { - wifi_calloc(size, 1) -} - -/**************************************************************************** - * Name: esp_wifi_create_queue - * - * Description: - * Create Wi-Fi static message queue - * - * Input Parameters: - * queue_len - queue message number - * item_size - message size - * - * Returned Value: - * Wi-Fi static message queue data pointer - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_create_queue( - queue_len: crate::binary::c_types::c_int, - item_size: crate::binary::c_types::c_int, -) -> *mut crate::binary::c_types::c_void { - create_wifi_queue(queue_len, item_size) -} - -/**************************************************************************** - * Name: esp_wifi_delete_queue - * - * Description: - * Delete Wi-Fi static message queue - * - * Input Parameters: - * queue - Wi-Fi static message queue data pointer - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn wifi_delete_queue(queue: *mut crate::binary::c_types::c_void) { - trace!( - "wifi_delete_queue {:?} - not implemented - doing nothing", - queue - ); -} - -/**************************************************************************** - * Name: wifi_coex_deinit - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn coex_deinit() { - warn!("coex_deinit - not implemented"); -} - -/**************************************************************************** - * Name: wifi_coex_enable - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn coex_enable() -> crate::binary::c_types::c_int { - trace!("coex_enable"); - - #[cfg(coex)] - return crate::binary::include::coex_enable(); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_disable - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn coex_disable() { - trace!("coex_disable"); - - #[cfg(coex)] - crate::binary::include::coex_disable(); -} - -/**************************************************************************** - * Name: esp_coex_status_get - * - * Description: - * Don't support - * - ****************************************************************************/ -pub unsafe extern "C" fn coex_status_get() -> u32 { - trace!("coex_status_get"); - - #[cfg(coex)] - return crate::binary::include::coex_status_get(); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: esp_coex_wifi_request - * - * Description: - * Don't support - * - ****************************************************************************/ -#[cfg_attr(not(coex), allow(unused_variables))] -pub unsafe extern "C" fn coex_wifi_request( - event: u32, - latency: u32, - duration: u32, -) -> crate::binary::c_types::c_int { - trace!("coex_wifi_request"); - - #[cfg(coex)] - return crate::binary::include::coex_wifi_request(event, latency, duration); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: esp_coex_wifi_release - * - * Description: - * Don't support - * - ****************************************************************************/ -#[cfg_attr(not(coex), allow(unused_variables))] -pub unsafe extern "C" fn coex_wifi_release(event: u32) -> crate::binary::c_types::c_int { - trace!("coex_wifi_release"); - - #[cfg(coex)] - return crate::binary::include::coex_wifi_release(event); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_wifi_set_channel - * - * Description: - * Don't support - * - ****************************************************************************/ -#[cfg_attr(not(coex), allow(unused_variables))] -pub unsafe extern "C" fn coex_wifi_channel_set( - primary: u8, - secondary: u8, -) -> crate::binary::c_types::c_int { - trace!("coex_wifi_channel_set"); - - #[cfg(coex)] - return crate::binary::include::coex_wifi_channel_set(primary, secondary); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_get_event_duration - * - * Description: - * Don't support - * - ****************************************************************************/ -#[cfg_attr(not(coex), allow(unused_variables))] -pub unsafe extern "C" fn coex_event_duration_get( - event: u32, - duration: *mut u32, -) -> crate::binary::c_types::c_int { - trace!("coex_event_duration_get"); - - #[cfg(coex)] - return crate::binary::include::coex_event_duration_get(event, duration); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_get_pti - * - * Description: - * Don't support - * - ****************************************************************************/ -#[cfg(any(esp32c3, esp32c2, esp32c6, esp32s3))] -#[cfg_attr(not(coex), allow(unused_variables))] -pub unsafe extern "C" fn coex_pti_get(event: u32, pti: *mut u8) -> crate::binary::c_types::c_int { - trace!("coex_pti_get"); - - #[cfg(coex)] - return crate::binary::include::coex_pti_get(event, pti); - - #[cfg(not(coex))] - 0 -} - -#[cfg(any(esp32, esp32s2))] -pub unsafe extern "C" fn coex_pti_get(event: u32, pti: *mut u8) -> crate::binary::c_types::c_int { - trace!("coex_pti_get {} {:?}", event, pti); - 0 -} - -/**************************************************************************** - * Name: wifi_coex_clear_schm_status_bit - * - * Description: - * Don't support - * - ****************************************************************************/ -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_status_bit_clear(type_: u32, status: u32) { - trace!("coex_schm_status_bit_clear"); - - #[cfg(coex)] - crate::binary::include::coex_schm_status_bit_clear(type_, status); -} - -/**************************************************************************** - * Name: wifi_coex_set_schm_status_bit - * - * Description: - * Don't support - * - ****************************************************************************/ -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_status_bit_set(type_: u32, status: u32) { - trace!("coex_schm_status_bit_set"); - - #[cfg(coex)] - crate::binary::include::coex_schm_status_bit_set(type_, status); -} - -/**************************************************************************** - * Name: wifi_coex_set_schm_interval - * - * Description: - * Don't support - * - ****************************************************************************/ -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_interval_set(interval: u32) -> crate::binary::c_types::c_int { - trace!("coex_schm_interval_set"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_interval_set(interval); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_get_schm_interval - * - * Description: - * Don't support - * - ****************************************************************************/ -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_interval_get() -> u32 { - trace!("coex_schm_interval_get"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_interval_get(); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_get_schm_curr_period - * - * Description: - * Don't support - * - ****************************************************************************/ -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_curr_period_get() -> u8 { - trace!("coex_schm_curr_period_get"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_curr_period_get(); - - #[cfg(not(coex))] - 0 -} - -/**************************************************************************** - * Name: wifi_coex_get_schm_curr_phase - * - * Description: - * Don't support - * - ****************************************************************************/ -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_curr_phase_get() -> *mut crate::binary::c_types::c_void { - trace!("coex_schm_curr_phase_get"); - - #[cfg(coex)] - return crate::binary::include::coex_schm_curr_phase_get(); - - #[cfg(not(coex))] - return core::ptr::null_mut(); -} - -pub unsafe extern "C" fn coex_schm_process_restart_wrapper() -> esp_wifi_sys::c_types::c_int { - trace!("coex_schm_process_restart_wrapper"); - - #[cfg(not(coex))] - return 0; - - #[cfg(coex)] - crate::binary::include::coex_schm_process_restart() -} - -#[allow(unused_variables)] -pub unsafe extern "C" fn coex_schm_register_cb_wrapper( - arg1: esp_wifi_sys::c_types::c_int, - cb: ::core::option::Option< - unsafe extern "C" fn(arg1: esp_wifi_sys::c_types::c_int) -> esp_wifi_sys::c_types::c_int, - >, -) -> esp_wifi_sys::c_types::c_int { - trace!("coex_schm_register_cb_wrapper {} {:?}", arg1, cb); - - #[cfg(not(coex))] - return 0; - - #[cfg(coex)] - crate::binary::include::coex_schm_register_callback( - arg1 as u32, - unwrap!(cb) as *const esp_wifi_sys::c_types::c_void as *mut esp_wifi_sys::c_types::c_void, - ) -} - -/**************************************************************************** - * Name: esp_clk_slowclk_cal_get_wrapper - * - * Description: - * Get the calibration value of RTC slow clock - * - * Input Parameters: - * None - * - * Returned Value: - * The calibration value obtained using rtc_clk_cal - * - ****************************************************************************/ -pub unsafe extern "C" fn slowclk_cal_get() -> u32 { - trace!("slowclk_cal_get"); - - // TODO not hardcode this - - #[cfg(esp32s2)] - return 44462; - - #[cfg(esp32s3)] - return 44462; - - #[cfg(esp32c3)] - return 28639; - - #[cfg(esp32c2)] - return 28639; - - #[cfg(any(esp32c6, esp32h2))] - return 0; - - #[cfg(esp32)] - return 28639; -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32.rs b/esp-wifi/src/wifi/os_adapter_esp32.rs deleted file mode 100644 index 28c8f501..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32.rs +++ /dev/null @@ -1,106 +0,0 @@ -#![allow(unused_variables)] -#![allow(dead_code)] -#![allow(non_snake_case)] - -use crate::hal::{interrupt, peripherals}; - -const DR_REG_DPORT_BASE: u32 = 0x3ff00000; -const DPORT_WIFI_CLK_EN_REG: u32 = DR_REG_DPORT_BASE + 0x0CC; -const DPORT_WIFI_CLK_WIFI_EN: u32 = 0x00000406; -const DPORT_WIFI_CLK_WIFI_EN_V: u32 = 0x406; -const DPORT_WIFI_CLK_WIFI_EN_S: u32 = 0; -const DPORT_WIFI_CLK_WIFI_EN_M: u32 = (DPORT_WIFI_CLK_WIFI_EN_V) << (DPORT_WIFI_CLK_WIFI_EN_S); - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { crate::hal::xtensa_lx::interrupt::enable_mask(mask) }; -} - -pub(crate) fn chip_ints_off(mask: u32) { - crate::hal::xtensa_lx::interrupt::disable_mask(mask); -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - core::mem::transmute(critical_section::acquire()) -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - critical_section::release(core::mem::transmute(tmp)) -} - -pub(crate) unsafe extern "C" fn phy_common_clock_disable() { - crate::common_adapter::chip_specific::phy_disable_clock(); -} - -pub(crate) unsafe extern "C" fn phy_common_clock_enable() { - crate::common_adapter::chip_specific::phy_enable_clock(); -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - intr_source: u32, - intr_num: u32, - _intr_prio: i32, -) { - extern "C" { - fn intr_matrix_set(cpu_no: u32, model_num: u32, intr_num: u32); - } - // Force to bind WiFi interrupt to CPU0 - intr_matrix_set(0, intr_source, intr_num); -} - -pub(crate) unsafe extern "C" fn wifi_clock_enable() { - let ptr = DPORT_WIFI_CLK_EN_REG as *mut u32; - let old = ptr.read_volatile(); - ptr.write_volatile(old | DPORT_WIFI_CLK_WIFI_EN_M); -} - -pub(crate) unsafe extern "C" fn wifi_clock_disable() { - let ptr = DPORT_WIFI_CLK_EN_REG as *mut u32; - let old = ptr.read_volatile(); - ptr.write_volatile(old & !DPORT_WIFI_CLK_WIFI_EN_M); -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - } -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32c2.rs b/esp-wifi/src/wifi/os_adapter_esp32c2.rs deleted file mode 100644 index 568d331d..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32c2.rs +++ /dev/null @@ -1,114 +0,0 @@ -use crate::hal::{ - interrupt, - peripherals::{self, Interrupt}, - riscv, -}; - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { - (*peripherals::INTERRUPT_CORE0::PTR) - .cpu_int_enable() - .modify(|r, w| w.bits(r.bits() | mask)); - } -} - -pub(crate) fn chip_ints_off(mask: u32) { - unsafe { - (*peripherals::INTERRUPT_CORE0::PTR) - .cpu_int_enable() - .modify(|r, w| w.bits(r.bits() & !mask)); - } -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - let res = if riscv::register::mstatus::read().mie() { - 1 - } else { - 0 - }; - riscv::interrupt::disable(); - - trace!( - "wifi_int_disable wifi_int_mux {:?} - return {}", - wifi_int_mux, - res, - ); - - res -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - trace!( - "wifi_int_restore wifi_int_mux {:?} tmp {}", - wifi_int_mux, - tmp - ); - - if tmp == 1 { - riscv::interrupt::enable(); - } -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - _intr_source: u32, - _intr_num: u32, - _intr_prio: i32, -) { - // this gets called with - // INFO - set_intr 0 2 1 1 (WIFI_PWR) - // INFO - set_intr 0 0 1 1 (WIFI_MAC) - - // we do nothing here since all the interrupts are already - // configured in `setup_timer_isr` and messing with the interrupts will - // get us into trouble -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - Interrupt::WIFI_MAC, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::WIFI_PWR, - interrupt::Priority::Priority1 - )); - } -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32c3.rs b/esp-wifi/src/wifi/os_adapter_esp32c3.rs deleted file mode 100644 index 48d97526..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32c3.rs +++ /dev/null @@ -1,115 +0,0 @@ -use crate::hal::{ - interrupt, - peripherals::{self, Interrupt}, - riscv, -}; - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { - (*peripherals::INTERRUPT_CORE0::PTR) - .cpu_int_enable() - .modify(|r, w| w.bits(r.bits() | mask)); - } -} - -pub(crate) fn chip_ints_off(mask: u32) { - unsafe { - (*peripherals::INTERRUPT_CORE0::PTR) - .cpu_int_enable() - .modify(|r, w| w.bits(r.bits() & !mask)); - } -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - let res = if riscv::register::mstatus::read().mie() { - 1 - } else { - 0 - }; - riscv::interrupt::disable(); - - trace!( - "wifi_int_disable wifi_int_mux {:?} - return {}", - wifi_int_mux, - res, - ); - - res -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - trace!( - "wifi_int_restore wifi_int_mux {:?} tmp {}", - wifi_int_mux, - tmp - ); - - if tmp == 1 { - riscv::interrupt::enable(); - } -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - _intr_source: u32, - _intr_num: u32, - _intr_prio: i32, -) { - // this gets called with - // INFO - set_intr 0 2 1 1 (WIFI_PWR) - // INFO - set_intr 0 0 1 1 (WIFI_MAC) - - // we do nothing here since all the interrupts are already - // configured in `setup_timer_isr` and messing with the interrupts will - // get us into trouble -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - Interrupt::WIFI_MAC, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::WIFI_PWR, - interrupt::Priority::Priority1 - )); - } -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32c6.rs b/esp-wifi/src/wifi/os_adapter_esp32c6.rs deleted file mode 100644 index d0cda88e..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32c6.rs +++ /dev/null @@ -1,143 +0,0 @@ -use crate::hal::{ - interrupt, - peripherals::{self, Interrupt}, - riscv, -}; - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { - (*peripherals::INTPRI::PTR) - .cpu_int_enable() - .modify(|r, w| w.bits(r.bits() | mask)); - } -} - -pub(crate) fn chip_ints_off(mask: u32) { - unsafe { - (*peripherals::INTPRI::PTR) - .cpu_int_enable() - .modify(|r, w| w.bits(r.bits() & !mask)); - } -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - let res = if riscv::register::mstatus::read().mie() { - 1 - } else { - 0 - }; - riscv::interrupt::disable(); - - trace!( - "wifi_int_disable wifi_int_mux {:?} - return {}", - wifi_int_mux, - res, - ); - - res -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - trace!( - "wifi_int_restore wifi_int_mux {:?} tmp {}", - wifi_int_mux, - tmp - ); - - if tmp == 1 { - riscv::interrupt::enable(); - } -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - _intr_source: u32, - _intr_num: u32, - _intr_prio: i32, -) { - // this gets called with - // INFO - set_intr 0 2 1 1 (WIFI_PWR) - // INFO - set_intr 0 0 1 1 (WIFI_MAC) - - // we do nothing here since all the interrupts are already - // configured in `setup_timer_isr` and messing with the interrupts will - // get us into trouble -} - -pub(crate) unsafe extern "C" fn regdma_link_set_write_wait_content_dummy( - _arg1: *mut esp_wifi_sys::c_types::c_void, - _arg2: u32, - _arg3: u32, -) { - todo!() -} - -pub(crate) unsafe extern "C" fn sleep_retention_find_link_by_id_dummy( - _arg1: esp_wifi_sys::c_types::c_int, -) -> *mut esp_wifi_sys::c_types::c_void { - todo!() -} - -pub(crate) unsafe extern "C" fn sleep_retention_entries_create_dummy( - _arg1: *const esp_wifi_sys::c_types::c_void, - _arg2: esp_wifi_sys::c_types::c_int, - _arg3: esp_wifi_sys::c_types::c_int, - _arg4: esp_wifi_sys::c_types::c_int, -) -> esp_wifi_sys::c_types::c_int { - todo!() -} - -pub(crate) unsafe extern "C" fn sleep_retention_entries_destroy_dummy( - _arg1: esp_wifi_sys::c_types::c_int, -) { - todo!() -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - Interrupt::WIFI_MAC, - interrupt::Priority::Priority1 - )); - unwrap!(interrupt::enable( - Interrupt::WIFI_PWR, - interrupt::Priority::Priority1 - )); - } -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32h2.rs b/esp-wifi/src/wifi/os_adapter_esp32h2.rs deleted file mode 100644 index 6706e081..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32h2.rs +++ /dev/null @@ -1,132 +0,0 @@ -use crate::hal::{ - interrupt, - peripherals::{self, Interrupt}, - riscv, -}; - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { - (*peripherals::INTPRI::PTR) - .cpu_int_enable - .modify(|r, w| w.bits(r.bits() | mask)); - } -} - -pub(crate) fn chip_ints_off(mask: u32) { - unsafe { - (*peripherals::INTPRI::PTR) - .cpu_int_enable - .modify(|r, w| w.bits(r.bits() & !mask)); - } -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - let res = if riscv::register::mstatus::read().mie() { - 1 - } else { - 0 - }; - riscv::interrupt::disable(); - - trace!( - "wifi_int_disable wifi_int_mux {:?} - return {}", - wifi_int_mux, - res, - ); - - res -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - trace!( - "wifi_int_restore wifi_int_mux {:?} tmp {}", - wifi_int_mux, - tmp - ); - - if tmp == 1 { - riscv::interrupt::enable(); - } -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - _intr_source: u32, - _intr_num: u32, - _intr_prio: i32, -) { - // this gets called with - // INFO - set_intr 0 2 1 1 (WIFI_PWR) - // INFO - set_intr 0 0 1 1 (WIFI_MAC) - - // we do nothing here since all the interrupts are already - // configured in `setup_timer_isr` and messing with the interrupts will - // get us into trouble -} - -pub(crate) unsafe extern "C" fn regdma_link_set_write_wait_content_dummy( - _arg1: *mut esp_wifi_sys::c_types::c_void, - _arg2: u32, - _arg3: u32, -) { - todo!() -} - -pub(crate) unsafe extern "C" fn sleep_retention_find_link_by_id_dummy( - _arg1: esp_wifi_sys::c_types::c_int, -) -> *mut esp_wifi_sys::c_types::c_void { - todo!() -} - -pub(crate) unsafe extern "C" fn sleep_retention_entries_create_dummy( - _arg1: *const esp_wifi_sys::c_types::c_void, - _arg2: esp_wifi_sys::c_types::c_int, - _arg3: esp_wifi_sys::c_types::c_int, - _arg4: esp_wifi_sys::c_types::c_int, -) -> esp_wifi_sys::c_types::c_int { - todo!() -} - -pub(crate) unsafe extern "C" fn sleep_retention_entries_destroy_dummy( - _arg1: esp_wifi_sys::c_types::c_int, -) { - todo!() -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32s2.rs b/esp-wifi/src/wifi/os_adapter_esp32s2.rs deleted file mode 100644 index 57b4bb2d..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32s2.rs +++ /dev/null @@ -1,92 +0,0 @@ -#![allow(unused_variables)] -#![allow(dead_code)] -#![allow(non_snake_case)] - -use crate::hal::{interrupt, peripherals}; - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { crate::hal::xtensa_lx::interrupt::enable_mask(mask) }; -} - -pub(crate) fn chip_ints_off(mask: u32) { - crate::hal::xtensa_lx::interrupt::disable_mask(mask); -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - core::mem::transmute(critical_section::acquire()) -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - critical_section::release(core::mem::transmute(tmp)) -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - intr_source: u32, - intr_num: u32, - _intr_prio: i32, -) { - extern "C" { - fn intr_matrix_set(cpu_no: u32, model_num: u32, intr_num: u32); - } - // Force to bind WiFi interrupt to CPU0 - intr_matrix_set(0, intr_source, intr_num); -} - -pub(crate) unsafe extern "C" fn phy_common_clock_disable() { - crate::common_adapter::chip_specific::phy_disable_clock(); -} - -pub(crate) unsafe extern "C" fn phy_common_clock_enable() { - crate::common_adapter::chip_specific::phy_enable_clock(); -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_PWR, - interrupt::Priority::Priority1, - )); - } -} diff --git a/esp-wifi/src/wifi/os_adapter_esp32s3.rs b/esp-wifi/src/wifi/os_adapter_esp32s3.rs deleted file mode 100644 index 937634e0..00000000 --- a/esp-wifi/src/wifi/os_adapter_esp32s3.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![allow(unused_variables)] -#![allow(dead_code)] -#![allow(non_snake_case)] - -use crate::hal::{interrupt, peripherals}; - -pub(crate) fn chip_ints_on(mask: u32) { - unsafe { crate::hal::xtensa_lx::interrupt::enable_mask(mask) }; -} - -pub(crate) fn chip_ints_off(mask: u32) { - crate::hal::xtensa_lx::interrupt::disable_mask(mask); -} - -pub(crate) unsafe extern "C" fn wifi_int_disable( - wifi_int_mux: *mut crate::binary::c_types::c_void, -) -> u32 { - core::mem::transmute(critical_section::acquire()) -} - -pub(crate) unsafe extern "C" fn wifi_int_restore( - wifi_int_mux: *mut crate::binary::c_types::c_void, - tmp: u32, -) { - critical_section::release(core::mem::transmute(tmp)) -} - -pub(crate) unsafe extern "C" fn set_intr( - _cpu_no: i32, - intr_source: u32, - intr_num: u32, - _intr_prio: i32, -) { - extern "C" { - fn intr_matrix_set(cpu_no: u32, model_num: u32, intr_num: u32); - } - // Force to bind WiFi interrupt to CPU0 - intr_matrix_set(0, intr_source, intr_num); -} - -/**************************************************************************** - * Name: esp_set_isr - * - * Description: - * Register interrupt function - * - * Input Parameters: - * n - Interrupt ID - * f - Interrupt function - * arg - Function private data - * - * Returned Value: - * None - * - ****************************************************************************/ -pub unsafe extern "C" fn set_isr( - n: i32, - f: *mut crate::binary::c_types::c_void, - arg: *mut crate::binary::c_types::c_void, -) { - trace!("set_isr - interrupt {} function {:?} arg {:?}", n, f, arg); - - match n { - 0 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - 1 => { - crate::wifi::ISR_INTERRUPT_1 = (f, arg); - } - _ => panic!("set_isr - unsupported interrupt number {}", n), - } - #[cfg(feature = "wifi")] - { - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_MAC, - interrupt::Priority::Priority1, - )); - unwrap!(interrupt::enable( - peripherals::Interrupt::WIFI_PWR, - interrupt::Priority::Priority1, - )); - } -} diff --git a/esp-wifi/src/wifi/state.rs b/esp-wifi/src/wifi/state.rs deleted file mode 100644 index 5ef60794..00000000 --- a/esp-wifi/src/wifi/state.rs +++ /dev/null @@ -1,84 +0,0 @@ -use super::WifiEvent; - -use core::sync::atomic::Ordering; -use portable_atomic_enum::atomic_enum; - -/// Wifi interface state -#[atomic_enum] -#[derive(PartialEq, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum WifiState { - StaStarted, - StaConnected, - StaDisconnected, - StaStopped, - - ApStarted, - ApStopped, - - Invalid, -} - -impl From for WifiState { - fn from(event: WifiEvent) -> WifiState { - match event { - WifiEvent::StaStart => WifiState::StaStarted, - WifiEvent::StaConnected => WifiState::StaConnected, - WifiEvent::StaDisconnected => WifiState::StaDisconnected, - WifiEvent::StaStop => WifiState::StaStopped, - WifiEvent::ApStart => WifiState::ApStarted, - WifiEvent::ApStop => WifiState::ApStopped, - _ => WifiState::Invalid, - } - } -} - -pub(crate) static STA_STATE: AtomicWifiState = AtomicWifiState::new(WifiState::Invalid); -pub(crate) static AP_STATE: AtomicWifiState = AtomicWifiState::new(WifiState::Invalid); - -/// Get the current state of the AP -pub fn get_ap_state() -> WifiState { - AP_STATE.load(Ordering::Relaxed) -} - -/// Get the current state of the STA -pub fn get_sta_state() -> WifiState { - STA_STATE.load(Ordering::Relaxed) -} - -pub(crate) fn update_state(event: WifiEvent) { - match event { - WifiEvent::StaConnected - | WifiEvent::StaDisconnected - | WifiEvent::StaStart - | WifiEvent::StaStop => STA_STATE.store(WifiState::from(event), Ordering::Relaxed), - - WifiEvent::ApStart | WifiEvent::ApStop => { - AP_STATE.store(WifiState::from(event), Ordering::Relaxed) - } - - other => debug!("Unhandled event: {:?}", other), - } -} - -#[cfg(feature = "async")] -pub(crate) fn reset_ap_state() { - AP_STATE.store(WifiState::Invalid, Ordering::Relaxed) -} - -#[cfg(feature = "async")] -pub(crate) fn reset_sta_state() { - STA_STATE.store(WifiState::Invalid, Ordering::Relaxed) -} - -/// Returns the current state of the WiFi stack. -/// -/// This does not support AP-STA mode. Use one of `get_sta_state` or `get_ap_state` instead. -pub fn get_wifi_state() -> WifiState { - use super::WifiMode; - match WifiMode::current() { - Ok(WifiMode::Sta) => get_sta_state(), - Ok(WifiMode::Ap) => get_ap_state(), - _ => WifiState::Invalid, - } -} diff --git a/esp-wifi/src/wifi/utils.rs b/esp-wifi/src/wifi/utils.rs deleted file mode 100644 index 06b93c57..00000000 --- a/esp-wifi/src/wifi/utils.rs +++ /dev/null @@ -1,97 +0,0 @@ -//! Convenience utilities for non-async code - -#[cfg(feature = "dhcpv4")] -use smoltcp::socket::dhcpv4::Socket as Dhcpv4Socket; -use smoltcp::{ - iface::{Config, Interface, SocketSet, SocketStorage}, - time::Instant, - wire::{EthernetAddress, HardwareAddress}, -}; - -use crate::current_millis; -use crate::EspWifiInitialization; - -use super::{WifiApDevice, WifiController, WifiDevice, WifiDeviceMode, WifiError, WifiStaDevice}; - -fn setup_iface<'a, MODE: WifiDeviceMode>( - device: &mut WifiDevice<'_, MODE>, - mode: MODE, - storage: &'a mut [SocketStorage<'a>], -) -> (Interface, SocketSet<'a>) { - let mac = mode.mac_address(); - let hw_address = HardwareAddress::Ethernet(EthernetAddress::from_bytes(&mac)); - - let config = Config::new(hw_address); - let iface = Interface::new( - config, - device, - Instant::from_millis(current_millis() as i64), - ); - - #[allow(unused_mut)] - let mut socket_set = SocketSet::new(storage); - - #[cfg(feature = "dhcpv4")] - if mode.mode().is_sta() { - // only add DHCP client in STA mode - let dhcp_socket = Dhcpv4Socket::new(); - socket_set.add(dhcp_socket); - } - - (iface, socket_set) -} - -/// Convenient way to create an `smoltcp` ethernet interface -/// You can use the provided macros to create and pass a suitable backing storage. -pub fn create_network_interface<'a, 'd, MODE: WifiDeviceMode>( - inited: &EspWifiInitialization, - device: impl crate::hal::peripheral::Peripheral

+ 'd, - mode: MODE, - storage: &'a mut [SocketStorage<'a>], -) -> Result< - ( - Interface, - WifiDevice<'d, MODE>, - WifiController<'d>, - SocketSet<'a>, - ), - WifiError, -> { - let (mut device, controller) = crate::wifi::new_with_mode(inited, device, mode)?; - - let (iface, socket_set) = setup_iface(&mut device, mode, storage); - - Ok((iface, device, controller, socket_set)) -} - -pub struct ApStaInterface<'a, 'd> { - pub ap_interface: Interface, - pub sta_interface: Interface, - pub ap_device: WifiDevice<'d, WifiApDevice>, - pub sta_device: WifiDevice<'d, WifiStaDevice>, - pub controller: WifiController<'d>, - pub ap_socket_set: SocketSet<'a>, - pub sta_socket_set: SocketSet<'a>, -} - -pub fn create_ap_sta_network_interface<'a, 'd>( - inited: &EspWifiInitialization, - device: impl crate::hal::peripheral::Peripheral

+ 'd, - ap_storage: &'a mut [SocketStorage<'a>], - sta_storage: &'a mut [SocketStorage<'a>], -) -> Result, WifiError> { - let (mut ap_device, mut sta_device, controller) = crate::wifi::new_ap_sta(inited, device)?; - - let (ap_interface, ap_socket_set) = setup_iface(&mut ap_device, WifiApDevice, ap_storage); - let (sta_interface, sta_socket_set) = setup_iface(&mut sta_device, WifiStaDevice, sta_storage); - - Ok(ApStaInterface { - ap_interface, - sta_interface, - ap_device, - sta_device, - controller, - ap_socket_set, - sta_socket_set, - }) -} diff --git a/esp-wifi/src/wifi_interface.rs b/esp-wifi/src/wifi_interface.rs deleted file mode 100644 index 950d9fc3..00000000 --- a/esp-wifi/src/wifi_interface.rs +++ /dev/null @@ -1,951 +0,0 @@ -//! Non-async Networking primitives for TCP/UDP communication. - -use core::cell::RefCell; -use core::fmt::Display; -#[cfg(feature = "tcp")] -use embedded_io::ErrorType; -#[cfg(feature = "tcp")] -use embedded_io::{Read, Write}; - -use crate::wifi::ipv4; -use smoltcp::iface::{Interface, SocketHandle, SocketSet}; -#[cfg(feature = "dhcpv4")] -use smoltcp::socket::dhcpv4::Socket as Dhcpv4Socket; -#[cfg(feature = "tcp")] -use smoltcp::socket::tcp::Socket as TcpSocket; -use smoltcp::time::Instant; -#[cfg(feature = "dns")] -use smoltcp::wire::DnsQueryType; -#[cfg(feature = "udp")] -use smoltcp::wire::IpEndpoint; -use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address}; - -use crate::current_millis; -use crate::wifi::{WifiDevice, WifiDeviceMode}; - -use core::borrow::BorrowMut; - -#[cfg(feature = "tcp")] -const LOCAL_PORT_MIN: u16 = 41000; -#[cfg(feature = "tcp")] -const LOCAL_PORT_MAX: u16 = 65535; - -/// Non-async TCP/IP network stack -/// -/// Mostly a convenience wrapper for `smoltcp` -pub struct WifiStack<'a, MODE: WifiDeviceMode> { - device: RefCell>, // TODO allow non static lifetime - network_interface: RefCell, - sockets: RefCell>, - current_millis_fn: fn() -> u64, - #[cfg(feature = "tcp")] - local_port: RefCell, - pub(crate) network_config: RefCell, - pub(crate) ip_info: RefCell>, - #[cfg(feature = "dhcpv4")] - pub(crate) dhcp_socket_handle: RefCell>, - #[cfg(feature = "dhcpv4")] - pub(crate) old_connected: RefCell, - #[cfg(feature = "dns")] - dns_socket_handle: RefCell>, -} - -impl<'a, MODE: WifiDeviceMode> WifiStack<'a, MODE> { - pub fn new( - network_interface: Interface, - device: WifiDevice<'static, MODE>, // TODO relax this lifetime requirement - #[allow(unused_mut)] mut sockets: SocketSet<'a>, - current_millis_fn: fn() -> u64, - ) -> WifiStack<'a, MODE> { - #[cfg(feature = "dhcpv4")] - let mut dhcp_socket_handle: Option = None; - #[cfg(feature = "dns")] - let mut dns_socket_handle: Option = None; - - #[cfg(any(feature = "dhcpv4", feature = "dns"))] - for (handle, socket) in sockets.iter_mut() { - match socket { - #[cfg(feature = "dhcpv4")] - smoltcp::socket::Socket::Dhcpv4(_) => dhcp_socket_handle = Some(handle), - #[cfg(feature = "dns")] - smoltcp::socket::Socket::Dns(_) => dns_socket_handle = Some(handle), - _ => {} - } - } - - let this = Self { - device: RefCell::new(device), - network_interface: RefCell::new(network_interface), - network_config: RefCell::new(ipv4::Configuration::Client( - ipv4::ClientConfiguration::DHCP(ipv4::DHCPClientSettings { - //FIXME: smoltcp currently doesn't have a way of giving a hostname through DHCP - hostname: Some(unwrap!("Espressif".try_into().ok())), - }), - )), - ip_info: RefCell::new(None), - #[cfg(feature = "dhcpv4")] - dhcp_socket_handle: RefCell::new(dhcp_socket_handle), - #[cfg(feature = "dhcpv4")] - old_connected: RefCell::new(false), - sockets: RefCell::new(sockets), - current_millis_fn, - #[cfg(feature = "tcp")] - local_port: RefCell::new( - (unsafe { crate::common_adapter::random() } - % (LOCAL_PORT_MAX - LOCAL_PORT_MIN) as u32) as u16 - + LOCAL_PORT_MIN, - ), - #[cfg(feature = "dns")] - dns_socket_handle: RefCell::new(dns_socket_handle), - }; - - this.reset(); - - this - } - - /// Update the interface configuration - pub fn update_iface_configuration( - &self, - conf: &ipv4::Configuration, - ) -> Result<(), WifiStackError> { - let mac = self.device.borrow().mac_address(); - let hw_address = smoltcp::wire::HardwareAddress::Ethernet( - smoltcp::wire::EthernetAddress::from_bytes(&mac), - ); - self.network_interface - .borrow_mut() - .set_hardware_addr(hw_address); - info!("Set hardware address: {:?}", hw_address); - - self.reset(); // reset IP address - - #[cfg(feature = "dhcpv4")] - { - let mut dhcp_socket_handle_ref = self.dhcp_socket_handle.borrow_mut(); - let mut sockets_ref = self.sockets.borrow_mut(); - - if let Some(dhcp_handle) = *dhcp_socket_handle_ref { - // remove the DHCP client if we use a static IP - if matches!( - conf, - ipv4::Configuration::Client(ipv4::ClientConfiguration::Fixed(_)) - ) { - sockets_ref.remove(dhcp_handle); - *dhcp_socket_handle_ref = None; - } - } - - // re-add the DHCP client if we use DHCP and it has been removed before - if matches!( - conf, - ipv4::Configuration::Client(ipv4::ClientConfiguration::DHCP(_)) - ) && dhcp_socket_handle_ref.is_none() - { - let dhcp_socket = Dhcpv4Socket::new(); - let dhcp_socket_handle = sockets_ref.add(dhcp_socket); - *dhcp_socket_handle_ref = Some(dhcp_socket_handle); - } - - if let Some(dhcp_handle) = *dhcp_socket_handle_ref { - let dhcp_socket = sockets_ref.get_mut::(dhcp_handle); - info!("Reset DHCP client"); - dhcp_socket.reset(); - } - } - - *self.network_config.borrow_mut() = conf.clone(); - Ok(()) - } - - /// Reset the stack - pub fn reset(&self) { - debug!("Reset TCP stack"); - - #[cfg(feature = "dhcpv4")] - { - let dhcp_socket_handle_ref = self.dhcp_socket_handle.borrow_mut(); - if let Some(dhcp_handle) = *dhcp_socket_handle_ref { - self.with_mut(|_, _, sockets| { - let dhcp_socket = sockets.get_mut::(dhcp_handle); - debug!("Reset DHCP client"); - dhcp_socket.reset(); - }); - } - } - - self.with_mut(|interface, _, _| { - interface.routes_mut().remove_default_ipv4_route(); - interface.update_ip_addrs(|addrs| { - addrs.clear(); - }); - - #[cfg(feature = "ipv6")] - { - unwrap!(interface.routes_mut().add_default_ipv6_route( - smoltcp::wire::Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0,) - )); - - let mut mac = [0u8; 6]; - match interface.hardware_addr() { - smoltcp::wire::HardwareAddress::Ethernet(hw_address) => { - mac.copy_from_slice(hw_address.as_bytes()); - } - } - - let a4 = ((mac[0] ^ 2) as u16) << 8 | mac[1] as u16; - let a5 = (mac[2] as u16) << 8 | 0xff; - let a6 = 0xfe << 8 | mac[3] as u16; - let a7 = (mac[4] as u16) << 8 | mac[5] as u16; - - info!( - "IPv6 link-local address fe80::{:x}:{:x}:{:x}:{:x}", - a4, a5, a6, a7 - ); - - interface.update_ip_addrs(|addrs| { - unwrap!(addrs.push(IpCidr::new( - smoltcp::wire::IpAddress::v6(0xfe80, 0, 0, 0, a4, a5, a6, a7), - 64, - ))); - }); - } - }); - } - - /// Retrieve all current IP addresses - pub fn get_ip_addresses(&self, f: impl FnOnce(&[smoltcp::wire::IpCidr])) { - self.with_mut(|interface, _, _| f(interface.ip_addrs())) - } - - /// Convenience function to poll the DHCP socket. - #[cfg(feature = "dhcpv4")] - pub fn poll_dhcp( - &self, - interface: &mut Interface, - sockets: &mut SocketSet<'a>, - ) -> Result<(), WifiStackError> { - let dhcp_socket_handle_ref = self.dhcp_socket_handle.borrow_mut(); - if let Some(dhcp_handle) = *dhcp_socket_handle_ref { - let dhcp_socket = sockets.get_mut::(dhcp_handle); - - let connected = match crate::wifi::get_sta_state() { - crate::wifi::WifiState::StaConnected => true, - _ => false, - }; - - if connected && !*self.old_connected.borrow() { - dhcp_socket.reset(); - } - - *self.old_connected.borrow_mut() = connected; - - let event = dhcp_socket.poll(); - if let Some(event) = event { - match event { - smoltcp::socket::dhcpv4::Event::Deconfigured => { - *self.ip_info.borrow_mut() = None; - interface.routes_mut().remove_default_ipv4_route(); - } - smoltcp::socket::dhcpv4::Event::Configured(config) => { - let dns = config.dns_servers.get(0); - *self.ip_info.borrow_mut() = Some(ipv4::IpInfo { - ip: config.address.address().0.into(), - subnet: ipv4::Subnet { - gateway: unwrap!(config.router).0.into(), - mask: ipv4::Mask(config.address.prefix_len()), - }, - dns: dns.map(|x| x.0.into()), - secondary_dns: config.dns_servers.get(1).map(|x| x.0.into()), - }); - - let address = config.address; - interface.borrow_mut().update_ip_addrs(|addrs| { - unwrap!(addrs.push(smoltcp::wire::IpCidr::Ipv4(address))); - }); - if let Some(route) = config.router { - unwrap!(interface.routes_mut().add_default_ipv4_route(route)); - } - - #[cfg(feature = "dns")] - if let (Some(&dns), Some(dns_handle)) = - (dns, *self.dns_socket_handle.borrow()) - { - sockets - .get_mut::(dns_handle) - .update_servers(&[dns.into()]); - } - } - } - } - } - - Ok(()) - } - - /// Create a new [Socket] - #[cfg(feature = "tcp")] - pub fn get_socket<'s>( - &'s self, - rx_buffer: &'a mut [u8], - tx_buffer: &'a mut [u8], - ) -> Socket<'s, 'a, MODE> - where - 'a: 's, - { - let socket = TcpSocket::new( - smoltcp::socket::tcp::SocketBuffer::new(rx_buffer), - smoltcp::socket::tcp::SocketBuffer::new(tx_buffer), - ); - - let socket_handle = - self.with_mut(|_interface, _device, sockets| sockets.borrow_mut().add(socket)); - - Socket { - socket_handle, - network: self, - } - } - - /// Create a new [UdpSocket] - #[cfg(feature = "udp")] - pub fn get_udp_socket<'s>( - &'s self, - rx_meta: &'a mut [smoltcp::socket::udp::PacketMetadata], - rx_buffer: &'a mut [u8], - tx_meta: &'a mut [smoltcp::socket::udp::PacketMetadata], - tx_buffer: &'a mut [u8], - ) -> UdpSocket<'s, 'a, MODE> - where - 'a: 's, - { - let socket = smoltcp::socket::udp::Socket::new( - smoltcp::socket::udp::PacketBuffer::new(rx_meta, rx_buffer), - smoltcp::socket::udp::PacketBuffer::new(tx_meta, tx_buffer), - ); - - let socket_handle = - self.with_mut(|_interface, _device, sockets| sockets.borrow_mut().add(socket)); - - UdpSocket { - socket_handle, - network: self, - } - } - - /// Check if DNS is configured - #[cfg(feature = "dns")] - pub fn is_dns_configured(&self) -> bool { - self.dns_socket_handle.borrow().is_some() - } - - /// Configure DNS - #[cfg(feature = "dns")] - pub fn configure_dns( - &'a self, - servers: &[IpAddress], - query_storage: &'a mut [Option], - ) { - if let Some(old_handle) = self.dns_socket_handle.take() { - self.with_mut(|_interface, _device, sockets| sockets.remove(old_handle)); - // the returned socket get dropped and frees a slot for the new one - } - - let dns = smoltcp::socket::dns::Socket::new(servers, query_storage); - let handle = self.with_mut(|_interface, _device, sockets| sockets.add(dns)); - self.dns_socket_handle.replace(Some(handle)); - } - - /// Update the DNS servers - #[cfg(feature = "dns")] - pub fn update_dns_servers(&self, servers: &[IpAddress]) { - if let Some(dns_handle) = *self.dns_socket_handle.borrow_mut() { - self.with_mut(|_interface, _device, sockets| { - sockets - .get_mut::(dns_handle) - .update_servers(servers); - }); - } - } - - /// Perform a DNS query - #[cfg(feature = "dns")] - pub fn dns_query( - &self, - name: &str, - query_type: DnsQueryType, - ) -> Result, WifiStackError> - { - use smoltcp::socket::dns; - - match query_type { - // check if name is already an IP - DnsQueryType::A => { - if let Ok(ip) = name.parse::() { - return Ok([ip.into()].into_iter().collect()); - } - } - #[cfg(feature = "ipv6")] - DnsQueryType::Aaaa => { - if let Ok(ip) = name.parse::() { - return Ok([ip.into()].into_iter().collect()); - } - } - _ => {} - } - - let Some(dns_handle) = *self.dns_socket_handle.borrow() else { - return Err(WifiStackError::DnsNotConfigured); - }; - - let query = self.with_mut(|interface, _device, sockets| { - sockets - .get_mut::(dns_handle) - .start_query(interface.context(), name, query_type) - .map_err(|e| WifiStackError::DnsQueryError(e)) - })?; - - loop { - self.work(); - - let result = self.with_mut(|_interface, _device, sockets| { - sockets - .get_mut::(dns_handle) - .get_query_result(query) - }); - - match result { - Ok(addrs) => return Ok(addrs), // query finished - Err(dns::GetQueryResultError::Pending) => {} // query not finished - Err(_) => return Err(WifiStackError::DnsQueryFailed), - } - } - } - - /// Let the stack make progress - /// - /// Make sure to regularly call this function. - pub fn work(&self) { - loop { - if let false = self.with_mut(|interface, device, sockets| { - let network_config = self.network_config.borrow().clone(); - if let ipv4::Configuration::Client(ipv4::ClientConfiguration::DHCP(_)) = - network_config - { - #[cfg(feature = "dhcpv4")] - self.poll_dhcp(interface, sockets).ok(); - } else if let ipv4::Configuration::Client(ipv4::ClientConfiguration::Fixed( - settings, - )) = network_config - { - let addr = Ipv4Address::from_bytes(&settings.ip.octets()); - if !interface.has_ip_addr(addr) { - let gateway = Ipv4Address::from_bytes(&settings.subnet.gateway.octets()); - interface.routes_mut().add_default_ipv4_route(gateway).ok(); - interface.update_ip_addrs(|addrs| { - unwrap!(addrs.push(IpCidr::new(addr.into(), settings.subnet.mask.0))); - }); - } - } - interface.poll( - Instant::from_millis((self.current_millis_fn)() as i64), - device, - sockets, - ) - }) { - break; - } - } - } - - #[cfg(feature = "tcp")] - fn next_local_port(&self) -> u16 { - self.local_port.replace_with(|local_port| { - if *local_port >= LOCAL_PORT_MAX { - LOCAL_PORT_MIN - } else { - *local_port + 1 - } - }); - *self.local_port.borrow() - } - - #[allow(unused)] - fn with(&self, f: impl FnOnce(&Interface, &WifiDevice, &SocketSet<'a>) -> R) -> R { - f( - &self.network_interface.borrow(), - &self.device.borrow(), - &self.sockets.borrow(), - ) - } - - fn with_mut( - &self, - f: impl FnOnce(&mut Interface, &mut WifiDevice, &mut SocketSet<'a>) -> R, - ) -> R { - f( - &mut self.network_interface.borrow_mut(), - &mut self.device.borrow_mut(), - &mut self.sockets.borrow_mut(), - ) - } -} - -/// Errors returned by functions in this module -#[derive(Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum WifiStackError { - Unknown(i32), - InitializationError(crate::InitializationError), - DeviceError(crate::wifi::WifiError), - MissingIp, - #[cfg(feature = "dns")] - DnsNotConfigured, - #[cfg(feature = "dns")] - DnsQueryError(smoltcp::socket::dns::StartQueryError), - #[cfg(feature = "dns")] - DnsQueryFailed, -} - -impl Display for WifiStackError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{:?}", self) - } -} - -/// [current_millis] as an Instant -pub fn timestamp() -> Instant { - Instant::from_millis(current_millis() as i64) -} - -impl WifiStack<'_, MODE> { - pub fn get_iface_configuration(&self) -> Result { - Ok(self.network_config.borrow().clone()) - } - - pub fn set_iface_configuration( - &mut self, - conf: &ipv4::Configuration, - ) -> Result<(), WifiStackError> { - self.update_iface_configuration(conf) - } - - pub fn is_iface_up(&self) -> bool { - self.ip_info.borrow().is_some() - } - - pub fn get_ip_info(&self) -> Result { - self.ip_info.borrow().ok_or(WifiStackError::MissingIp) - } -} - -/// A TCP socket -#[cfg(feature = "tcp")] -pub struct Socket<'s, 'n: 's, MODE: WifiDeviceMode> { - socket_handle: SocketHandle, - network: &'s WifiStack<'n, MODE>, -} - -#[cfg(feature = "tcp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> Socket<'s, 'n, MODE> { - /// Connect the socket - pub fn open<'i>(&'i mut self, addr: IpAddress, port: u16) -> Result<(), IoError> - where - 's: 'i, - { - { - let res = self.network.with_mut(|interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - let cx = interface.context(); - let remote_endpoint = (addr, port); - sock.set_ack_delay(Some(smoltcp::time::Duration::from_millis(100))); - sock.connect(cx, remote_endpoint, self.network.next_local_port()) - }); - - res.map_err(|e| IoError::ConnectError(e))?; - } - - loop { - let can_send = self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - if sock.can_send() { - true - } else { - false - } - }); - - if can_send { - break; - } - - self.work(); - } - - Ok(()) - } - - /// Listen on the given port. This blocks until there is a peer connected - pub fn listen<'i>(&'i mut self, port: u16) -> Result<(), IoError> - where - 's: 'i, - { - { - let res = self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - sock.listen(port) - }); - - res.map_err(|e| IoError::ListenError(e))?; - } - - loop { - let can_send = self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - if sock.can_send() { - true - } else { - false - } - }); - - if can_send { - break; - } - - self.work(); - } - - Ok(()) - } - - /// Listen on the given port. This doesn't block - pub fn listen_unblocking<'i>(&'i mut self, port: u16) -> Result<(), IoError> - where - 's: 'i, - { - { - let res = self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - sock.listen(port) - }); - - res.map_err(|e| IoError::ListenError(e))?; - } - - self.work(); - Ok(()) - } - - /// Closes the socket - pub fn close(&mut self) { - self.network.with_mut(|_interface, _device, sockets| { - sockets.get_mut::(self.socket_handle).close(); - }); - - self.work(); - } - - /// Disconnect the socket - pub fn disconnect(&mut self) { - self.network.with_mut(|_interface, _device, sockets| { - sockets.get_mut::(self.socket_handle).abort(); - }); - - self.work(); - } - - /// Checks if the socket is currently open - pub fn is_open(&mut self) -> bool { - self.network.with_mut(|_interface, _device, sockets| { - sockets.get_mut::(self.socket_handle).is_open() - }) - } - - /// Checks if the socket is currently connected - pub fn is_connected(&mut self) -> bool { - self.network.with_mut(|_interface, _device, sockets| { - let socket = sockets.get_mut::(self.socket_handle); - - socket.may_recv() && socket.may_send() - }) - } - - /// Delegates to [WifiStack::work] - pub fn work(&mut self) { - self.network.work() - } -} - -#[cfg(feature = "tcp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> Drop for Socket<'s, 'n, MODE> { - fn drop(&mut self) { - self.network - .with_mut(|_interface, _device, sockets| sockets.remove(self.socket_handle)); - } -} - -/// IO Errors -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum IoError { - SocketClosed, - #[cfg(feature = "igmp")] - MultiCastError(smoltcp::iface::MulticastError), - #[cfg(feature = "tcp")] - TcpRecvError, - #[cfg(feature = "udp")] - UdpRecvError(smoltcp::socket::udp::RecvError), - #[cfg(feature = "tcp")] - TcpSendError(smoltcp::socket::tcp::SendError), - #[cfg(feature = "udp")] - UdpSendError(smoltcp::socket::udp::SendError), - #[cfg(feature = "tcp")] - ConnectError(smoltcp::socket::tcp::ConnectError), - #[cfg(feature = "udp")] - BindError(smoltcp::socket::udp::BindError), - #[cfg(feature = "tcp")] - ListenError(smoltcp::socket::tcp::ListenError), -} - -impl embedded_io::Error for IoError { - fn kind(&self) -> embedded_io::ErrorKind { - embedded_io::ErrorKind::Other - } -} - -#[cfg(feature = "tcp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> ErrorType for Socket<'s, 'n, MODE> { - type Error = IoError; -} - -#[cfg(feature = "tcp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> Read for Socket<'s, 'n, MODE> { - fn read(&mut self, buf: &mut [u8]) -> Result { - self.network.with_mut(|interface, device, sockets| { - use smoltcp::socket::tcp::RecvError; - - loop { - interface.poll(timestamp(), device, sockets); - let socket = sockets.get_mut::(self.socket_handle); - - match socket.recv_slice(buf) { - Ok(0) => continue, // no data - Ok(n) => return Ok(n), - Err(RecvError::Finished) => return Err(IoError::SocketClosed), // eof - Err(RecvError::InvalidState) => return Err(IoError::TcpRecvError), - } - } - }) - } -} - -#[cfg(feature = "tcp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> Write for Socket<'s, 'n, MODE> { - fn write(&mut self, buf: &[u8]) -> Result { - loop { - let (may_send, is_open, can_send) = - self.network.with_mut(|interface, device, sockets| { - interface.poll( - Instant::from_millis((self.network.current_millis_fn)() as i64), - device, - sockets, - ); - - let socket = sockets.get_mut::(self.socket_handle); - - (socket.may_send(), socket.is_open(), socket.can_send()) - }); - - if may_send { - break; - } - - if !is_open || !can_send { - return Err(IoError::SocketClosed); - } - } - - let mut written = 0; - loop { - self.flush()?; - - self.network.with_mut(|_interface, _device, sockets| { - sockets - .get_mut::(self.socket_handle) - .send_slice(&buf[written..]) - .map(|len| written += len) - .map_err(IoError::TcpSendError) - })?; - - if written >= buf.len() { - break; - } - } - - Ok(written) - } - - fn flush(&mut self) -> Result<(), Self::Error> { - loop { - let res = self.network.with_mut(|interface, device, sockets| { - interface.poll( - Instant::from_millis((self.network.current_millis_fn)() as i64), - device, - sockets, - ) - }); - - if let false = res { - break; - } - } - - Ok(()) - } -} - -/// A UDP socket -#[cfg(feature = "udp")] -pub struct UdpSocket<'s, 'n: 's, MODE: WifiDeviceMode> { - socket_handle: SocketHandle, - network: &'s WifiStack<'n, MODE>, -} - -#[cfg(feature = "udp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> UdpSocket<'s, 'n, MODE> { - /// Binds the socket to the given port - pub fn bind<'i>(&'i mut self, port: u16) -> Result<(), IoError> - where - 's: 'i, - { - self.work(); - - { - let res = self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - sock.bind(port) - }); - - if let Err(err) = res { - return Err(IoError::BindError(err)); - } - } - - loop { - let can_send = self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - if sock.can_send() { - true - } else { - false - } - }); - - if can_send { - break; - } - - self.work(); - } - - Ok(()) - } - - /// Close the socket - pub fn close(&mut self) { - self.network.with_mut(|_interface, _device, sockets| { - sockets - .get_mut::(self.socket_handle) - .close(); - }); - - self.work(); - } - - /// Sends data on the socket to the given address - pub fn send(&mut self, addr: IpAddress, port: u16, data: &[u8]) -> Result<(), IoError> { - loop { - self.work(); - - let (can_send, packet_capacity, payload_capacity) = - self.network.with_mut(|_interface, _device, sockets| { - let sock = sockets.get_mut::(self.socket_handle); - ( - sock.can_send(), - sock.packet_send_capacity(), - sock.payload_send_capacity(), - ) - }); - - if can_send && packet_capacity > 0 && payload_capacity > data.len() { - break; - } - } - - self.network - .with_mut(|_interface, _device, sockets| { - let endpoint = (addr, port); - let endpoint: IpEndpoint = endpoint.into(); - - sockets - .get_mut::(self.socket_handle) - .send_slice(data, endpoint) - }) - .map_err(|e| IoError::UdpSendError(e))?; - - self.work(); - - Ok(()) - } - - /// Receives a single datagram message on the socket - pub fn receive(&mut self, data: &mut [u8]) -> Result<(usize, IpAddress, u16), IoError> { - self.work(); - - let res = self.network.with_mut(|_interface, _device, sockets| { - sockets - .get_mut::(self.socket_handle) - .recv_slice(data) - }); - - match res { - Ok((len, endpoint)) => { - let addr = endpoint.endpoint.addr; - Ok((len, addr, endpoint.endpoint.port)) - } - Err(e) => Err(IoError::UdpRecvError(e)), - } - } - - /// This function specifies a new multicast group for this socket to join - #[cfg(feature = "igmp")] - pub fn join_multicast_group(&mut self, addr: IpAddress) -> Result { - self.work(); - - let res = self.network.with_mut(|interface, device, _| { - interface.join_multicast_group( - device, - addr, - Instant::from_millis((self.network.current_millis_fn)() as i64), - ) - }); - - self.work(); - - res.map_err(|e| IoError::MultiCastError(e)) - } - - /// Delegates to [WifiStack::work] - pub fn work(&mut self) { - self.network.work() - } -} - -#[cfg(feature = "udp")] -impl<'s, 'n: 's, MODE: WifiDeviceMode> Drop for UdpSocket<'s, 'n, MODE> { - fn drop(&mut self) { - self.network - .with_mut(|_, _, sockets| sockets.borrow_mut().remove(self.socket_handle)); - } -} diff --git a/examples-util/util.rs b/examples-util/util.rs deleted file mode 100644 index 59f76324..00000000 --- a/examples-util/util.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow(unused)] - -pub use esp_hal as hal; - -#[cfg(any( - feature = "esp32c2", - feature = "esp32c3", - feature = "esp32c6", - feature = "esp32h2" -))] -pub type BootButton = crate::hal::gpio::Gpio9>; -#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] -pub type BootButton = crate::hal::gpio::Gpio0>; - -#[cfg(feature = "esp32c3")] -pub const SOC_NAME: &str = "ESP32-C3"; -#[cfg(feature = "esp32c2")] -pub const SOC_NAME: &str = "ESP32-C2"; -#[cfg(feature = "esp32c6")] -pub const SOC_NAME: &str = "ESP32-C6"; -#[cfg(feature = "esp32h2")] -pub const SOC_NAME: &str = "ESP32-H2"; -#[cfg(feature = "esp32")] -pub const SOC_NAME: &str = "ESP32"; -#[cfg(feature = "esp32s3")] -pub const SOC_NAME: &str = "ESP32-S3"; diff --git a/extras/bench-server/.gitignore b/extras/bench-server/.gitignore deleted file mode 100644 index ea8c4bf7..00000000 --- a/extras/bench-server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/extras/bench-server/Cargo.toml b/extras/bench-server/Cargo.toml deleted file mode 100644 index 56fee5a1..00000000 --- a/extras/bench-server/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "bench-server" -version = "0.1.0" -edition = "2021" - -[dependencies] -pretty_env_logger = "0.5.0" -log = "0.4.0" \ No newline at end of file diff --git a/extras/bench-server/src/main.rs b/extras/bench-server/src/main.rs deleted file mode 100644 index 21ab6486..00000000 --- a/extras/bench-server/src/main.rs +++ /dev/null @@ -1,87 +0,0 @@ -use std::io::{Read, Write}; -use std::net::{TcpListener, TcpStream}; -use std::thread::spawn; -use std::time::Duration; - -use log::info; - -fn main() { - pretty_env_logger::init(); - spawn(|| rx_listen()); - spawn(|| rxtx_listen()); - tx_listen(); -} - -fn tx_listen() { - let listener = TcpListener::bind("0.0.0.0:4321").unwrap(); - loop { - let (socket, addr) = listener.accept().unwrap(); - info!("tx: received connection from: {}", addr); - spawn(|| tx_conn(socket)); - } -} - -fn tx_conn(mut socket: TcpStream) { - socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap(); - socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap(); - - let buf = [0; 1024]; - loop { - if let Err(e) = socket.write_all(&buf) { - info!("tx: failed to write to socket; err = {:?}", e); - return; - } - } -} - -fn rx_listen() { - let listener = TcpListener::bind("0.0.0.0:4322").unwrap(); - loop { - let (socket, addr) = listener.accept().unwrap(); - info!("rx: received connection from: {}", addr); - spawn(|| rx_conn(socket)); - } -} - -fn rx_conn(mut socket: TcpStream) { - socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap(); - socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap(); - - let mut buf = [0; 1024]; - loop { - if let Err(e) = socket.read_exact(&mut buf) { - info!("rx: failed to read from socket; err = {:?}", e); - return; - } - } -} - -fn rxtx_listen() { - let listener = TcpListener::bind("0.0.0.0:4323").unwrap(); - loop { - let (socket, addr) = listener.accept().unwrap(); - info!("rxtx: received connection from: {}", addr); - spawn(|| rxtx_conn(socket)); - } -} - -fn rxtx_conn(mut socket: TcpStream) { - socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap(); - socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap(); - - let mut buf = [0; 1024]; - loop { - match socket.read(&mut buf) { - Ok(n) => { - if let Err(e) = socket.write_all(&buf[..n]) { - info!("rxtx: failed to write to socket; err = {:?}", e); - return; - } - } - Err(e) => { - info!("rxtx: failed to read from socket; err = {:?}", e); - return; - } - } - } -} \ No newline at end of file diff --git a/extras/esp-wifishark/.gitignore b/extras/esp-wifishark/.gitignore deleted file mode 100644 index ea8c4bf7..00000000 --- a/extras/esp-wifishark/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/extras/esp-wifishark/Cargo.toml b/extras/esp-wifishark/Cargo.toml deleted file mode 100644 index 1c53cf56..00000000 --- a/extras/esp-wifishark/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "esp-wifishark" -version = "0.1.0" -edition = "2021" - -[dependencies] -r-extcap = "0.2.2" -pcap-file = "2.0.0" -serialport = "4.2.1" -clap = { version = "4.3.5", features = ["derive"] } -lazy_static = "1.4.0" diff --git a/extras/esp-wifishark/README.md b/extras/esp-wifishark/README.md deleted file mode 100644 index 1a10a828..00000000 --- a/extras/esp-wifishark/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# esp-wifishark - -This is an extcap to be used with esp-wifi and the `dump-packets` feature. - -To use it build via `cargo build --release` and copy the resulting executable to the Wireshark's `extcap` folder. - -Then you should see two new capture interfaces in Wireshark -- esp-wifi HCI capture (for Bluetooth HCI) -- esp-wifi Ethernet capture (for WiFi traffic) - -If you are running an application using esp-wifi's `dump-packets` feature and logging at INFO level active these capture interfaces can connect via serialport to give you insights on what is going on. - -By default it tries to identify exactly one serialport. If that doesn't work for you, you can configure the serialport via the Wireshark UI. diff --git a/extras/esp-wifishark/src/main.rs b/extras/esp-wifishark/src/main.rs deleted file mode 100644 index 6d541c8f..00000000 --- a/extras/esp-wifishark/src/main.rs +++ /dev/null @@ -1,175 +0,0 @@ -use std::{ - io::{stdout, BufRead, BufReader, Write}, - time::{Duration, SystemTime, UNIX_EPOCH}, -}; - -use clap::Parser; -use lazy_static::lazy_static; -use pcap_file::{ - pcap::{PcapHeader, PcapPacket, PcapWriter}, - DataLink, -}; -use r_extcap::{ - config::StringConfig, - controls::{synchronous::ExtcapControlSender, ControlCommand, ControlPacket}, - interface::{Dlt, Interface, Metadata}, - ExtcapStep, -}; - -#[derive(Debug, Parser)] -pub struct AppArgs { - #[command(flatten)] - extcap: r_extcap::ExtcapArgs, - - #[arg(long, default_value = "")] - serialport: String, -} - -lazy_static! { - static ref METADATA: Metadata = Metadata { - help_url: "http://github.com/esp-rs/esp-wifi".into(), - display_description: "esp-wifi".into(), - ..r_extcap::cargo_metadata!() - }; - static ref WIFI_CAPTURE_INTERFACE: Interface = Interface { - value: "wifi".into(), - display: "esp-wifi Ethernet capture".into(), - dlt: Dlt { - data_link_type: DataLink::USER0, - name: "USER0".into(), - display: "Ethernet".into(), - }, - }; - static ref BT_CAPTURE_INTERFACE: Interface = Interface { - value: "bt".into(), - display: "esp-wifi HCI capture".into(), - dlt: Dlt { - data_link_type: DataLink::USER1, - name: "USER1".into(), - display: "HCI".into(), - }, - }; - static ref CONFIG_SERIALPORT: StringConfig = StringConfig::builder() - .config_number(1) - .call("serialport") - .display("Serialport") - .tooltip("Serialport to connect to") - .required(false) - .placeholder("") - .build(); -} - -fn main() { - let args = AppArgs::parse(); - - if !args.extcap.capture { - if let Some(_filter) = args.extcap.extcap_capture_filter { - std::process::exit(0); - } - } - - match args.extcap.run().unwrap() { - ExtcapStep::Interfaces(interfaces_step) => { - interfaces_step.list_interfaces( - &METADATA, - &[&*WIFI_CAPTURE_INTERFACE, &*BT_CAPTURE_INTERFACE], - &[], - ); - } - ExtcapStep::Dlts(dlts_step) => { - dlts_step - .print_from_interfaces(&[&*WIFI_CAPTURE_INTERFACE, &*BT_CAPTURE_INTERFACE]) - .unwrap(); - } - ExtcapStep::Config(config_step) => config_step.list_configs(&[&*CONFIG_SERIALPORT]), - ExtcapStep::ReloadConfig(_reload_config_step) => { - panic!("Unsupported operation"); - } - ExtcapStep::Capture(capture_step) => { - let (data_link, prefix) = if capture_step.interface == WIFI_CAPTURE_INTERFACE.value { - (DataLink::ETHERNET, "@WIFIFRAME [") - } else { - (DataLink::BLUETOOTH_HCI_H4, "@HCIFRAME [") - }; - - let mut controls = ( - capture_step.spawn_channel_control_reader(), - capture_step.new_control_sender(), - ); - - if let (Some(control_reader), Some(_control_sender)) = &mut controls { - let packet = control_reader.read_packet().unwrap(); - assert_eq!(packet.command, ControlCommand::Initialized); - } - - let pcap_header = PcapHeader { - datalink: data_link, - endianness: pcap_file::Endianness::Big, - ..Default::default() - }; - let mut pcap_writer = PcapWriter::with_header(capture_step.fifo, pcap_header).unwrap(); - - let serialport = if args.serialport.is_empty() { - let ports = serialport::available_ports().unwrap(); - if ports.len() != 1 { - panic!("There are more or less than one serial ports. Don't know which one to use."); - } - ports[0].port_name.clone() - } else { - args.serialport.clone() - }; - - let port = serialport::new(serialport, 115_200) - .timeout(Duration::from_millis(100)) - .open() - .expect("Failed to open port"); - let mut buf_read = BufReader::new(port); - - let mut packet = Vec::::new(); - let mut line = String::new(); - - loop { - if let (Some(control_reader), Some(control_sender)) = &mut controls { - if let Some(control_packet) = control_reader.try_read_packet() { - handle_control_packet(&control_packet, control_sender).unwrap(); - } - } - - packet.clear(); - line.clear(); - if let Ok(len) = buf_read.read_line(&mut line) { - if len > 0 { - if line.contains(prefix) { - let start = line.find(prefix).unwrap() + prefix.len(); - let end = line.find("]").unwrap(); - let line = line[start..end].to_string(); - for hex in line.split(", ") { - let byte = u8::from_str_radix(hex, 10).unwrap(); - packet.push(byte); - } - } - - if packet.len() > 0 { - pcap_writer - .write_packet(&PcapPacket::new( - SystemTime::now().duration_since(UNIX_EPOCH).unwrap(), - packet.len() as u32, - &packet, - )) - .unwrap(); - } - stdout().flush().unwrap(); - } - } - } - } - }; -} - -fn handle_control_packet( - _control_packet: &ControlPacket<'_>, - _control_sender: &mut ExtcapControlSender, -) -> Result<(), ()> { - // currently nothing to do here - Ok(()) -} diff --git a/run_tests.bat b/run_tests.bat deleted file mode 100644 index 9e80940f..00000000 --- a/run_tests.bat +++ /dev/null @@ -1,92 +0,0 @@ -mkdir tmp -mkdir tmp\esp32 -mkdir tmp\esp32s2 -mkdir tmp\esp32s3 -mkdir tmp\esp32c2 -mkdir tmp\esp32c3 -mkdir tmp\esp32c6 -mkdir tmp\esp32h2 - -cd esp-wifi -cargo +esp build --release --example esp_now_broadcaster --target xtensa-esp32-none-elf --features esp32,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now -cargo +esp build --release --example test_esp_now --target xtensa-esp32-none-elf --features esp32,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now -cargo +esp build --release --example open_access_point --target xtensa-esp32-none-elf --features esp32,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now,utils,smoltcp,tcp -cargo +esp build --release --example test_connect --target xtensa-esp32-none-elf --features esp32,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now,utils,smoltcp,tcp -cargo +esp build --release --example test_ble --target xtensa-esp32-none-elf --features esp32,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,ble -copy ..\target\xtensa-esp32-none-elf\release\examples\esp_now_broadcaster ..\tmp\esp32 -copy ..\target\xtensa-esp32-none-elf\release\examples\test_esp_now ..\tmp\esp32 -copy ..\target\xtensa-esp32-none-elf\release\examples\open_access_point ..\tmp\esp32 -copy ..\target\xtensa-esp32-none-elf\release\examples\test_connect ..\tmp\esp32 -copy ..\target\xtensa-esp32-none-elf\release\examples\test_ble ..\tmp\esp32 - -cargo +esp build --release --example esp_now_broadcaster --target xtensa-esp32s2-none-elf --features esp32s2,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now -cargo +esp build --release --example test_esp_now --target xtensa-esp32s2-none-elf --features esp32s2,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now -cargo +esp build --release --example open_access_point --target xtensa-esp32s2-none-elf --features esp32s2,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now,utils,smoltcp,tcp -cargo +esp build --release --example test_connect --target xtensa-esp32s2-none-elf --features esp32s2,esp-hal/default,esp-hal/embassy-time-timg0,esp-hal/embassy-executor-thread,wifi,esp-now,utils,smoltcp,tcp -copy ..\target\xtensa-esp32s2-none-elf\release\examples\esp_now_broadcaster ..\tmp\esp32s2 -copy ..\target\xtensa-esp32s2-none-elf\release\examples\test_esp_now ..\tmp\esp32s2 -copy ..\target\xtensa-esp32s2-none-elf\release\examples\open_access_point ..\tmp\esp32s2 -copy ..\target\xtensa-esp32s2-none-elf\release\examples\test_connect ..\tmp\esp32s2 - -cargo +esp build --release --example esp_now_broadcaster --target xtensa-esp32s3-none-elf --features esp32s3,esp32-hal/default,esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread,wifi,esp-now -cargo +esp build --release --example test_esp_now --target xtensa-esp32s3-none-elf --features esp32s3,esp32-hal/default,esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread,wifi,esp-now -cargo +esp build --release --example open_access_point --target xtensa-esp32s3-none-elf --features esp32s3,esp32-hal/default,esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread,wifi,esp-now,utils,smoltcp,tcp -cargo +esp build --release --example test_connect --target xtensa-esp32s3-none-elf --features esp32s3,esp32-hal/default,esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread,wifi,esp-now,utils,smoltcp,tcp -cargo +esp build --release --example test_ble --target xtensa-esp32s3-none-elf --features esp32s3,esp32-hal/default,esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread,ble -copy ..\target\xtensa-esp32s3-none-elf\release\examples\esp_now_broadcaster ..\tmp\esp32s3 -copy ..\target\xtensa-esp32s3-none-elf\release\examples\test_esp_now ..\tmp\esp32s3 -copy ..\target\xtensa-esp32s3-none-elf\release\examples\open_access_point ..\tmp\esp32s3 -copy ..\target\xtensa-esp32s3-none-elf\release\examples\test_connect ..\tmp\esp32s3 -copy ..\target\xtensa-esp32s3-none-elf\release\examples\test_ble ..\tmp\esp32s3 - -cargo +nightly build --release --example esp_now_broadcaster --target riscv32imc-unknown-none-elf --features esp32c2,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now -cargo +nightly build --release --example test_esp_now --target riscv32imc-unknown-none-elf --features esp32c2,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now -cargo +nightly build --release --example open_access_point --target riscv32imc-unknown-none-elf --features esp32c2,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now,utils,smoltcp,tcp -cargo +nightly build --release --example test_connect --target riscv32imc-unknown-none-elf --features esp32c2,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now,utils,smoltcp,tcp -cargo +nightly build --release --example test_ble --target riscv32imc-unknown-none-elf --features esp32c2,esp-hal/default,esp-hal/embassy-time-timg0,ble -copy ..\target\riscv32imc-unknown-none-elf\release\examples\esp_now_broadcaster ..\tmp\esp32c2 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\test_esp_now ..\tmp\esp32c2 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\open_access_point ..\tmp\esp32c2 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\test_connect ..\tmp\esp32c2 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\test_ble ..\tmp\esp32c2 - -cargo +nightly build --release --example esp_now_broadcaster --target riscv32imc-unknown-none-elf --features esp32c3,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now -cargo +nightly build --release --example test_esp_now --target riscv32imc-unknown-none-elf --features esp32c3,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now -cargo +nightly build --release --example open_access_point --target riscv32imc-unknown-none-elf --features esp32c3,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now,utils,smoltcp,tcp -cargo +nightly build --release --example test_connect --target riscv32imc-unknown-none-elf --features esp32c3,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now,utils,smoltcp,tcp -cargo +nightly build --release --example test_ble --target riscv32imc-unknown-none-elf --features esp32c3,esp-hal/default,esp-hal/embassy-time-timg0,ble -copy ..\target\riscv32imc-unknown-none-elf\release\examples\esp_now_broadcaster ..\tmp\esp32c3 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\test_esp_now ..\tmp\esp32c3 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\open_access_point ..\tmp\esp32c3 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\test_connect ..\tmp\esp32c3 -copy ..\target\riscv32imc-unknown-none-elf\release\examples\test_ble ..\tmp\esp32c3 - -cargo +nightly build --release --example esp_now_broadcaster --target riscv32imac-unknown-none-elf --features esp32c6,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now -cargo +nightly build --release --example test_esp_now --target riscv32imac-unknown-none-elf --features esp32c6,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now -cargo +nightly build --release --example open_access_point --target riscv32imac-unknown-none-elf --features esp32c6,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now,utils,smoltcp,tcp -cargo +nightly build --release --example test_connect --target riscv32imac-unknown-none-elf --features esp32c6,esp-hal/default,esp-hal/embassy-time-timg0,wifi,esp-now,utils,smoltcp,tcp -cargo +nightly build --release --example test_ble --target riscv32imac-unknown-none-elf --features esp32c6,esp-hal/default,esp-hal/embassy-time-timg0,ble -copy ..\target\riscv32imac-unknown-none-elf\release\examples\esp_now_broadcaster ..\tmp\esp32c6 -copy ..\target\riscv32imac-unknown-none-elf\release\examples\test_esp_now ..\tmp\esp32c6 -copy ..\target\riscv32imac-unknown-none-elf\release\examples\open_access_point ..\tmp\esp32c6 -copy ..\target\riscv32imac-unknown-none-elf\release\examples\test_connect ..\tmp\esp32c6 -copy ..\target\riscv32imac-unknown-none-elf\release\examples\test_ble ..\tmp\esp32c6 - -cargo +nightly build --release --example test_ble --target riscv32imac-unknown-none-elf --no-default-features --features esp32h2,esp-hal/default,esp-hal/embassy-time-timg0,ble -copy ..\target\riscv32imac-unknown-none-elf\release\examples\test_ble ..\tmp\esp32h2 - -cd ..\tmp -echo "Connect ESP32, ESP32-C2, ESP32-C3, ESP32-C6" -pause -esp-testrun --esp32=esp32 --esp32c2=esp32c2 --esp32c3=esp32c3 --esp32c6=esp32c6 - -echo "Connect ESP32, ESP32-S2, ESP32-S3, ESP32-C3" -pause -esp-testrun --esp32=esp32 --esp32s2=esp32s2 --esp32s3=esp32s3 --esp32c3=esp32c3 - -echo "Connect ESP32-H2" -pause -esp-testrun --esp32h2=esp32h2 - -cd .. -rd /q /s tmp diff --git a/smoketest.bat b/smoketest.bat deleted file mode 100644 index 2764c2a1..00000000 --- a/smoketest.bat +++ /dev/null @@ -1,177 +0,0 @@ -REM A simple script to help in smoke-testing. -REM Not really useful to users. - -@echo off -echo Make sure to have the env-vars SSID, PASSWORD, STATIC_IP and GATEWAY_IP set. -echo Use CTRL-C to exit an example and start the next one. - -cd esp-wifi - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=3 -set CARGO_PROFILE_RELEASE_LTO=off -echo. -echo Connect ESP32-C3 -pause -cargo +nightly esp32c3 --example ble --release --features "ble" -pause -cargo +nightly esp32c3 --example embassy_ble --release --features "async,ble" -pause -cargo +nightly esp32c3 --example dhcp --release --features "wifi" -pause -cargo +nightly esp32c3 --example static_ip --release --features "wifi" -pause -cargo +nightly esp32c3 --example embassy_dhcp --release --features "async,wifi,embassy-net" -pause -echo [esp-wifi] >..\cfg.toml -echo heap_size = 70000 >>..\cfg.toml -cargo +nightly esp32c3 --example coex --release --features "wifi,ble,coex" -pause -del /q ..\cfg.toml -cargo +nightly esp32c3 --example esp_now --release --features "esp-now" -pause -cargo +nightly esp32c3 --example embassy_esp_now --release --features "async,esp-now" -pause -cargo +nightly esp32c3 --example access_point --release --features "wifi" -pause -cargo +nightly esp32c3 --example embassy_access_point --release --features "async,wifi,embassy-net" -pause - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=3 -set CARGO_PROFILE_RELEASE_LTO=off -echo. -echo Connect ESP32 -pause -cargo +esp esp32 --example ble --release --features "ble" -pause -cargo +esp esp32 --example embassy_ble --release --features "async,ble" -pause -cargo +esp esp32 --example dhcp --release --features "wifi" -pause -cargo +esp esp32 --example static_ip --release --features "wifi" -pause -cargo +esp esp32 --example embassy_dhcp --release --features "async,wifi,embassy-net" -pause -cargo +esp esp32 --example coex --release --features "wifi,ble,coex" -pause -cargo +esp esp32 --example esp_now --release --features "esp-now" -pause -cargo +esp esp32 --example embassy_esp_now --release --features "async,esp-now" -pause -cargo +esp esp32 --example access_point --release --features "wifi" -pause -cargo +esp esp32 --example embassy_access_point --release --features "async,wifi,embassy-net" -pause - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=3 -set CARGO_PROFILE_RELEASE_LTO=off -echo. -echo Connect ESP32-S3 -pause -cargo +esp esp32s3 --example ble --release --features "ble" -pause -cargo +esp esp32s3 --example embassy_ble --release --features "async,ble" -pause -cargo +esp esp32s3 --example dhcp --release --features "wifi" -pause -cargo +esp esp32s3 --example static_ip --release --features "wifi" -pause -cargo +esp esp32s3 --example embassy_dhcp --release --features "async,wifi,embassy-net" -pause -cargo +esp esp32s3 --example coex --release --features "wifi,ble,coex" -pause -cargo +esp esp32s3 --example esp_now --release --features "esp-now" -pause -cargo +esp esp32s3 --example embassy_esp_now --release --features "async,esp-now" -pause -cargo +esp esp32s3 --example access_point --release --features "wifi" -pause -cargo +esp esp32s3 --example embassy_access_point --release --features "async,wifi,embassy-net" -pause - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=2 -set CARGO_PROFILE_RELEASE_LTO=off -echo. -echo Connect ESP32-S2 -pause -cargo +esp esp32s2 --example dhcp --release --features "wifi" -pause -cargo +esp esp32s2 --example static_ip --release --features "wifi" -pause -cargo +esp esp32s2 --example embassy_dhcp --release --features "async,wifi,embassy-net" -pause -cargo +esp esp32s2 --example esp_now --release --features "esp-now" -pause -cargo +esp esp32s2 --example embassy_esp_now --release --features "async,esp-now" -pause -cargo +esp esp32s2 --example access_point --release --features "wifi" -pause -cargo +esp esp32s2 --example embassy_access_point --release --features "async,wifi,embassy-net" -pause - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=3 -set CARGO_PROFILE_RELEASE_LTO=false -echo. -echo Connect ESP32-C2 -pause -cargo +nightly esp32c2 --example ble --release --features "ble" -pause -cargo +nightly esp32c2 --example embassy_ble --release --features "async,ble" -pause -cargo +nightly esp32c2 --example dhcp --release --features "wifi" -pause -cargo +nightly esp32c2 --example static_ip --release --features "wifi" -pause -cargo +nightly esp32c2 --example embassy_dhcp --release --features "async,wifi,embassy-net" -pause -echo [esp-wifi] >..\cfg.toml -echo heap_size = 70000 >>..\cfg.toml -cargo +nightly esp32c2 --example coex --release --features "wifi,ble,coex" -pause -del /q ..\cfg.toml -cargo +nightly esp32c2 --example esp_now --release --features "esp-now" -pause -cargo +nightly esp32c2 --example embassy_esp_now --release --features "async,esp-now" -pause -cargo +nightly esp32c2 --example access_point --release --features "wifi" -pause -cargo +nightly esp32c2 --example embassy_access_point --release --features "async,wifi,embassy-net" -pause - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=3 -set CARGO_PROFILE_RELEASE_LTO=off -echo. -echo Connect ESP32-C6 -pause -cargo +nightly esp32c6 --example ble --release --features "ble" -pause -cargo +nightly esp32c6 --example embassy_ble --release --features "async,ble" -pause -cargo +nightly esp32c6 --example dhcp --release --features "wifi" -pause -cargo +nightly esp32c6 --example static_ip --release --features "wifi" -pause -cargo +nightly esp32c6 --example embassy_dhcp --release --features "async,wifi,embassy-net" -pause -echo [esp-wifi] >..\cfg.toml -echo heap_size = 80000 >>..\cfg.toml -echo tx_queue_size = 10 >>..\cfg.toml -cargo +nightly esp32c6 --example coex --release --features "wifi,ble,coex" -pause -del /q ..\cfg.toml -cargo +nightly esp32c6 --example esp_now --release --features "esp-now" -pause -cargo +nightly esp32c6 --example embassy_esp_now --release --features "async,esp-now" -pause -cargo +nightly esp32c6 --example access_point --release --features "wifi" -pause -cargo +nightly esp32c6 --example embassy_access_point --release --features "async,wifi,embassy-net" -pause - -set CARGO_PROFILE_RELEASE_OPT_LEVEL=3 -echo. -echo Connect ESP32-H2 -pause -cargo +nightly esp32h2 --example ble --release --no-default-features --features "ble" -pause -cargo +nightly esp32h2 --example embassy_ble --release --no-default-features --features "async,ble" -pause From d0f46a4cfcba168719274b1abaf65b43d61365bd Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Mon, 27 May 2024 08:35:31 +0200 Subject: [PATCH 2/2] Remove CI, issue_handler and changelog check --- .github/workflows/changelog.yml | 21 ---- .github/workflows/ci.yml | 147 ---------------------------- .github/workflows/issue_handler.yml | 16 --- 3 files changed, 184 deletions(-) delete mode 100644 .github/workflows/changelog.yml delete mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/issue_handler.yml diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml deleted file mode 100644 index 09f498ac..00000000 --- a/.github/workflows/changelog.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Change log check - -on: - pull_request: - # Run on labeled/unlabeled in addition to defaults to detect - # adding/removing skip-changelog labels. - types: [opened, reopened, labeled, unlabeled, synchronize] - -jobs: - changelog: - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - uses: dangoslen/changelog-enforcer@v3 - with: - changeLogPath: CHANGELOG.md - skipLabels: "skip-changelog" - missingUpdateErrorMessage: "Please add a changelog entry in the CHANGELOG.md file." \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index d391f6b0..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,147 +0,0 @@ -name: CI - -on: - pull_request: - branches: - - main - paths-ignore: - - "**/CHANGELOG.md" - - "**/README.md" - push: - branches: - - main - paths-ignore: - - "**/CHANGELOG.md" - - "**/README.md" - workflow_dispatch: - -env: - CARGO_TERM_COLOR: always - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Examples: - SSID: "" - PASSWORD: "" - STATIC_IP: "" - GATEWAY_IP: "" - HOST_IP: "" - DEFMT_LOG: "trace" - -# Cancel any currently running workflows from the same PR, branch, or -# tag when a new workflow is triggered. -# -# https://stackoverflow.com/a/66336834 -concurrency: - cancel-in-progress: true - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - -jobs: - formatting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: esp-rs/xtensa-toolchain@v1.5 - with: - default: true - buildtargets: esp32 - ldproxy: false - - uses: Swatinem/rust-cache@v2 - - - name: check-fmt - run: cargo fmt --check - - docs_rs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: remove rust-toolchain.toml - run: rm rust-toolchain.toml - - uses: dtolnay/rust-toolchain@v1 - with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf,riscv32imafc-unknown-none-elf - toolchain: nightly - components: rust-src - - uses: Swatinem/rust-cache@v2 - - - name: install docs-rs - run: cargo install cargo-docs-rs - - name: docs-rs - run: cd esp-wifi && cargo docs-rs - - builds: - strategy: - matrix: - chip: ["esp32", "esp32s2", "esp32s3", "esp32c2", "esp32c3", "esp32c6", "esp32h2"] - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: esp-rs/xtensa-toolchain@v1.5 - with: - default: true - ldproxy: false - - uses: Swatinem/rust-cache@v2 - - - name: build - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} - - name: build (common features) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --features=async,wifi,esp-now,embassy-net,log,esp-hal/embassy-time-timg0 - - name: build (common features + defmt) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --no-default-features --features=async,wifi,esp-now,embassy-net,defmt,esp-hal/embassy-time-timg0 - - name: build (all possible network options) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && for combo in {ipv4,},{ipv6,},{tcp,},{udp,},{igmp,},{dhcpv4,} ; do cargo b${{ matrix.chip }} --release --no-default-features --features=wifi,wifi-logs,$combo ; done - - name: build (access_point) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=access_point --features=wifi - - name: build (access_point_with_sta) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=access_point_with_sta --features=wifi - - name: build (dhcp) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=dhcp --features=wifi - - name: build (bench) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=bench --features=wifi - - name: build (static_ip) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=static_ip --features=wifi - - name: build (esp_now) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=esp_now --features=esp-now - - name: build (embassy_esp_now) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_esp_now --features=async,esp-now,esp-hal/embassy-time-timg0 - - name: build (embassy_esp_now_duplex) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_esp_now_duplex --features=async,esp-now,esp-hal/embassy-time-timg0 - - name: build (embassy_dhcp) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_dhcp --features=async,wifi,embassy-net,esp-hal/embassy-time-timg0 - - name: build (embassy_bench) - if: ${{ matrix.chip != 'esp32h2' && matrix.chip != 'esp32s2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_bench --features=async,wifi,embassy-net,esp-hal/embassy-time-timg0 - - name: build (embassy_access_point) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_access_point --features=async,wifi,embassy-net,esp-hal/embassy-time-timg0 - - name: build (embassy_access_point_with_sta) - if: ${{ matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_access_point_with_sta --features=async,wifi,embassy-net,esp-hal/embassy-time-timg0 - - - name: build (common features + ble) - if: ${{ matrix.chip != 'esp32s2' && matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --features=async,wifi,ble,esp-now,embassy-net,log,esp-hal/embassy-time-timg0 - - name: build (common features + ble + defmt) - if: ${{ matrix.chip != 'esp32s2' && matrix.chip != 'esp32h2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --no-default-features --features=async,wifi,ble,esp-now,embassy-net,defmt,esp-hal/embassy-time-timg0 - - name: build (ble) - if: ${{ matrix.chip != 'esp32s2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=ble --no-default-features --features=ble - - name: build (embassy_ble) - if: ${{ matrix.chip != 'esp32s2' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=embassy_ble --no-default-features --features=async,ble,esp-hal/embassy-time-timg0 - - name: build (coex) - if: ${{ matrix.chip == 'esp32' || matrix.chip == 'esp32s3' || matrix.chip == 'esp32c3' }} - run: cd esp-wifi && cargo b${{ matrix.chip }} --release --example=coex --features=wifi,ble,coex diff --git a/.github/workflows/issue_handler.yml b/.github/workflows/issue_handler.yml deleted file mode 100644 index 978e8042..00000000 --- a/.github/workflows/issue_handler.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Add new issues to project - -on: - issues: - types: - - opened - -jobs: - add-to-project: - name: Add issue to project - runs-on: ubuntu-latest - steps: - - uses: actions/add-to-project@v0.5.0 - with: - project-url: https://github.com/orgs/esp-rs/projects/2 - github-token: ${{ secrets.PAT }}