diff --git a/README.md b/README.md index aa84fb8f..7c5f847a 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,37 @@ # esp-wifi -Wi-Fi/BTLE coexistence is implemented but currently only works (to some extent) on ESP32-C3 and ESP32-S3. In general COEX shouldn't be used currently. - -Minimum supported Rust compiler version: 1.72.0.0 - -This uses the WiFi drivers from https://github.com/esp-rs/esp-wireless-drivers-3rdparty - -## Version used - -v5.1-rc2-4-gc570f67461 commit c570f674610479fc5e070c8db6d181b73ddf60a8 - -https://github.com/esp-rs/esp-wireless-drivers-3rdparty/ (commit 976e9cc6c0725e8325a7e3a362d113559238c45c) +A WiFi, BLE and ESP-NOW driver for Espressif microcontrollers. ## Current support -If a cell contains am em dash (—) this means that the particular feature is not present for a chip. A check mark (✓) means that some driver implementation exists. An empty cell means that the feature is present in the chip but not implemented yet. +If a cell contains am 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 its 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 | ✓ | ✓ | ˜ | ✓ | | ESP32-S2 | ✓ | — | — | ✓ | | ESP32-S3 | ✓ | ✓ | ✓ | ✓ | | ESP32-C3 | ✓ | ✓ | ✓ | ✓ | | ESP32-C2 | ✓ | ✓ | | ✓ | | ESP32-C6 | ✓ | | | ✓ | +Minimum supported Rust compiler version: 1.72.0.0 ## Usage ### Importing -For now this is not available on _crates.io_. Until then you need to import via git, cloning locally, etc. +Ensure that the right features are enabled for your chip. See the examples for more examples. ```toml [dependencies.esp-wifi] -git = "https://github.com/esp-rs/esp-wifi.git" - -# `esp-wifi` is in active development. It is often a good idea to lock it to a specific commit -rev = "c7ca849274cf3d7a08b49c260bb46693c91c85c0" - # A supported chip needs to be specified, as well as specific use-case features features = ["esp32s3", "wifi", "esp-now"] ``` ### Link configuration -> [!IMPORTANT] -> Make sure to include the rom functions for your target: +Make sure to include the rom functions for your target: ```toml # .cargo/config.toml @@ -55,14 +40,12 @@ rustflags = [ "-C", "link-arg=-Trom_functions.x", ] ``` -> [!NOTE] -> At 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. +At 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 -> [!IMPORTANT] -> Link time optimization is not yet recommended for use, please ensure `lto = "off"` is in your `Cargo.toml` for both release and debug profiles. +Link time optimization is not yet recommended for use, please ensure `lto = "off"` is in your `Cargo.toml` for both release and debug profiles. It is necessary to build with optimization level 2 or 3 since otherwise it might not even be able to connect or advertise. @@ -79,8 +62,17 @@ lto = "off" ``` +### Xtensa considerations + +Within this crate, `CCOMPARE0` CPU timer is used for timing, ensure that in your application you are not using this CPU timer. + +## USB-SERIAL-JTAG -### Features +When using USB-SERIAL-JTAG you have to activate the feature `phy-enable-usb`. + +Don't use this feature if your are _not_ using USB-SERIAL-JTAG since it might reduce WiFi performance. + +## Features | Feature | Meaning | | -------------- | --------------------------------------------------------------------------------------------------- | @@ -95,7 +87,7 @@ lto = "off" | mtu-XXX | Set MTU to XXX, XXX can be 746, 1492, 1500, 1514. Defaults to 1492 | | big-heap | Reserve more heap memory for the drivers | | ipv6 | IPv6 support | -| phy-enable-usb | See _Using Serial-JTAG_ below | +| phy-enable-usb | See _USB-SERIAL-JTAG_ below | | ps-min-modem | Enable modem sleep | | log | Route log output to the `log` crate | | log-defmt | Route log output to the `defmt` crate | @@ -104,139 +96,23 @@ lto = "off" 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) -### Serial-JTAG -> [!IMPORTANT] -> On ESP32-C3 / ESP32-S3 when using Serial-JTAG you have to activate the feature `phy-enable-usb`. -> -> Don't use this feature if your are _not_ using Serial-JTAG since it might reduce WiFi performance. - -### Tuning +## 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](docs/tuning.md) for details - -### What works? - -- scanning for WiFi access points -- connect to WiFi access point -- providing an HCI interface -- create an open access point - -### Notes on ESP32-C2 / ESP32-C3 / ESP32-C6 support - -- uses SYSTIMER as the main timer -- doesn't work in direct-boot mode - -### Notes on ESP32 / ESP32-S2 / ESP32-S3 support - -- The WiFi logs only print the format string - not the actual values. -- The code runs on a single core and might currently not be multi-core safe! - -On ESP32 / ESP32-S2 / ESP32-S3 currently TIMG1/TIMER0 is used as the main timer so you can't use it for anything else. -Additionally it uses CCOMPARE0 - so don't touch that, too. - -### opt-level for Xtensa targets - -Currently your mileage might vary a lot for different opt-levels on Xtensa targets! -If something doesn't work as expected try a different opt-level. - +See [Tuning](https://github.com/esp-rs/esp-wifi/blob/main/docs/tuning.md) for details ## Examples -To build these ensure you are in the `examples-esp32XXX` directory matching your target as othewise the `config.toml` will not apply - -### dhcp - -- set SSID and PASSWORD env variable -- gets an ip address via DHCP -- performs an HTTP get request to some "random" server - -`cargo run --example dhcp --release --features "embedded-svc,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 run --example static_ip --release --features "embedded-svc,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) +See [Examples](https://github.com/esp-rs/esp-wifi/blob/main/examples.md) for details. -`cargo run --example ble --release --features "ble"` - -**NOTE:** ESP32-S2 doesn't support bluetooth, for ESP32-C6 bluetooth support isn't implemented yet - -### async_ble - -- same as `ble` but async - -`cargo run --example async_ble --release --features "async,ble"` - -**NOTE:** ESP32-S2 doesn't support bluetooth, for ESP32-C6 bluetooth support isn't implemented yet - -### 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 run --example coex --release --features "embedded-svc,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 run --example esp_now --release --features "esp-now"` - -### embassy_esp_now - -- broadcasts, receives and sends messages via esp-now in an async way - -`cargo run --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 run --example embassy_esp_now_duplex --release --features "async,esp-now"` - -### embassy_dhcp - -- Read and Write to sockets over WiFi asyncronously using embassy-executor. - -`cargo run --example embassy_dhcp --release --features "async,embedded-svc,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 run --example access_point --release --features "embedded-svc,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 run --example embassy_access_point --release --features "async,embedded-svc,wifi,embassy-net"` +## Missing / To be done +- Make CoEx work on ESP32 (it kind of works when commenting out setting the country in wifi_start, probably some mis-compilation since it then crashes in a totally different code path) +- Combined SoftAP/STA mode +- Support for non-open SoftAP +- Direct-boot mode isn't supported +- On Xtensa, the WiFi logs only print the format string - not the actual values. See [esp-rs/rust#177](https://github.com/esp-rs/rust/issues/177) ## Directory Structure @@ -247,12 +123,13 @@ To build these ensure you are in the `examples-esp32XXX` directory matching your - `timer_compat.rs`: code to emulate timer related functionality - `examples/*.rs`: examples -## Missing / To be done +## Driver version + +This uses the WiFi drivers from https://github.com/esp-rs/esp-wireless-drivers-3rdparty + +v5.1-rc2-4-gc570f67461 commit c570f674610479fc5e070c8db6d181b73ddf60a8 -- lots of refactoring -- make CoEx work on ESP32 (it kind of works when commenting out setting the country in wifi_start, probably some mis-compilation since it then crashes in a totally different code path) -- combined SoftAP/STA mode -- support for non-open SoftAP +https://github.com/esp-rs/esp-wireless-drivers-3rdparty/ (commit 976e9cc6c0725e8325a7e3a362d113559238c45c) ## License diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index fd51aff5..8e619ebb 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -4,7 +4,6 @@ #![feature(linkage)] #![cfg_attr(feature = "async", feature(async_fn_in_trait))] #![cfg_attr(feature = "async", allow(incomplete_features))] - #![doc = include_str!("../../README.md")] // MUST be the first module @@ -90,6 +89,7 @@ use timer::{get_systimer_count, TICKS_PER_SECOND}; #[cfg(all(feature = "embedded-svc", feature = "wifi"))] pub mod wifi_interface; +/// Return the current systimer time in milliseconds pub fn current_millis() -> u64 { get_systimer_count() / (TICKS_PER_SECOND / 1000) } @@ -119,6 +119,7 @@ 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, @@ -176,10 +177,12 @@ pub type EspWifiTimer = hal::timer::Timer for InitializationError { } } +/// 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 { diff --git a/examples.md b/examples.md new file mode 100644 index 00000000..43c392f7 --- /dev/null +++ b/examples.md @@ -0,0 +1,94 @@ +## Examples + +To build these ensure you are in the `examples-esp32XXX` directory matching your target as othewise the `config.toml` will not apply + +### dhcp + +- set SSID and PASSWORD env variable +- gets an ip address via DHCP +- performs an HTTP get request to some "random" server + +`cargo run --example dhcp --release --features "embedded-svc,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 run --example static_ip --release --features "embedded-svc,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 run --example ble --release --features "ble"` + +**NOTE:** ESP32-S2 doesn't support bluetooth, for ESP32-C6 bluetooth support isn't implemented yet + +### async_ble + +- same as `ble` but async + +`cargo run --example async_ble --release --features "async,ble"` + +**NOTE:** ESP32-S2 doesn't support bluetooth, for ESP32-C6 bluetooth support isn't implemented yet + +### 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 run --example coex --release --features "embedded-svc,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 run --example esp_now --release --features "esp-now"` + +### embassy_esp_now + +- broadcasts, receives and sends messages via esp-now in an async way + +`cargo run --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 run --example embassy_esp_now_duplex --release --features "async,esp-now"` + +### embassy_dhcp + +- Read and Write to sockets over WiFi asyncronously using embassy-executor. + +`cargo run --example embassy_dhcp --release --features "async,embedded-svc,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 run --example access_point --release --features "embedded-svc,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 run --example embassy_access_point --release --features "async,embedded-svc,wifi,embassy-net"` \ No newline at end of file