├── rhai ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ └── main.rs ├── alloc ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ └── main.rs ├── blinky ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ └── main.rs ├── i2c-sht31 ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ ├── main.rs │ └── sht3x.rs ├── smartled ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ └── main.rs ├── embassy_ble ├── rust-toolchain.toml ├── .cargo │ └── config.toml ├── README.md ├── Cargo.toml └── src │ └── main.rs ├── embassy_blinky ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ └── main.rs ├── embassy_wifi ├── rust-toolchain.toml ├── README.md ├── .cargo │ └── config.toml ├── Cargo.toml └── src │ └── main.rs ├── .gitignore ├── LICENSE └── README.md /rhai/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /alloc/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /blinky/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /i2c-sht31/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /smartled/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /embassy_ble/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /embassy_blinky/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /embassy_wifi/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rust-src"] 4 | -------------------------------------------------------------------------------- /smartled/README.md: -------------------------------------------------------------------------------- 1 | # SMART LED 2 | 3 | This example shows how to use the RMT to light an RGB LED, such as the WS2812. 4 | 5 | > 这个例子展示了如何利用 RMT 点亮 RGB LED,例如 WS2812。 6 | -------------------------------------------------------------------------------- /i2c-sht31/README.md: -------------------------------------------------------------------------------- 1 | # Smartled 2 | 3 | This example shows how to connect the SHT31 temperature and humidity sensor using the I2C interface. 4 | 5 | > 这个例子展示了如何使用 I2C 接口连接 SHT31 温湿度传感器。 6 | -------------------------------------------------------------------------------- /embassy_wifi/README.md: -------------------------------------------------------------------------------- 1 | # Embassy WIFI 2 | 3 | This example shows how to turn on basic WIFI support in the [Embassy](https://github.com/embassy-rs/embassy) framework. 4 | 5 | > 这个例子演示了如何在 [Embassy](https://github.com/embassy-rs/embassy) 框架下开启最基本的 WIFI 支持。 6 | -------------------------------------------------------------------------------- /rhai/README.md: -------------------------------------------------------------------------------- 1 | # Rhai 2 | 3 | [Rhai](https://rhai.rs/) is a tiny, simple and fast embedded scripting language for Rust that gives you a safe and easy way to add scripting to your applications. 4 | 5 | > [Rhai](https://rhai.rs/)是 Rust 的一种小巧、简单而快速的嵌入式脚本语言,它为你提供了一种安全而简便的方法来为你的应用程序添加脚本。 6 | -------------------------------------------------------------------------------- /embassy_blinky/README.md: -------------------------------------------------------------------------------- 1 | # Embassy Blinky 2 | 3 | [Embassy](https://github.com/embassy-rs/embassy) is an embedded runtime framework that supports `async/await` for simple and efficient multitasking in embedded systems. 4 | 5 | > [Embassy](https://github.com/embassy-rs/embassy) 是一个支持 `async/await` 的嵌入式运行框架, 能够在嵌入式系统中实现简单高效的多任务处理。 6 | -------------------------------------------------------------------------------- /blinky/README.md: -------------------------------------------------------------------------------- 1 | # Blinky 2 | 3 | This is the simplest example that demonstrates how to light the LEDs and how to output the logs. The default chip model is esp32c6, you need to modify the `Cargo.toml` file and the `.cargo/config.toml` file. 4 | 5 | > 这是一个最简单的示例,演示了如何点亮LED和如何输出日志。默认的芯片型号是 esp32c6, 你需要修改 `Cargo.toml` 文件和 `.cargo/config.toml` 文件。 6 | -------------------------------------------------------------------------------- /alloc/README.md: -------------------------------------------------------------------------------- 1 | # Alloc 2 | 3 | After setting up the heap allocator, we can use the types of collections, containers, etc., such as String, Vec, BTreeMap, Box, etc. in [alloc](https://doc.rust-lang.org/stable/alloc/index.html). 4 | 5 | > 设置堆分配器后,我们就可以使用 [alloc](https://doc.rust-lang.org/stable/alloc/index.html) 中的集合、容器等类型,例如 String,Vec,BTreeMap,Box 等。 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 8 | Cargo.lock 9 | 10 | # These are backup files generated by rustfmt 11 | **/*.rs.bk 12 | 13 | # MSVC Windows builds of rustc generate these, which store debugging information 14 | *.pdb 15 | 16 | # We'll ignore VS Code settings (at least for now...) 17 | **/.vscode/settings.json 18 | 19 | # Ignore generated documentation 20 | docs/ 21 | -------------------------------------------------------------------------------- /alloc/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /blinky/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /rhai/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /smartled/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /embassy_ble/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /embassy_wifi/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /i2c-sht31/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /embassy_blinky/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_arch = "riscv32")'] 2 | runner = "espflash flash --monitor" 3 | rustflags = [ 4 | "-C", "link-arg=-Tlinkall.x", 5 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 6 | # NOTE: May negatively impact performance of produced code 7 | "-C", "force-frame-pointers", 8 | # with defmt 9 | # "-C", "link-arg=-Tdefmt.x", 10 | ] 11 | 12 | [env] 13 | ESP_LOG="INFO" 14 | 15 | [build] 16 | # esp32c3 17 | # target = "riscv32imc-unknown-none-elf" 18 | # esp32c6 19 | target = "riscv32imac-unknown-none-elf" 20 | 21 | [unstable] 22 | build-std = ["alloc", "core"] 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 danclive 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /blinky/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky" 3 | version = "0.0.0" 4 | description = "blinky" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | ] 16 | 17 | log = [ 18 | "dep:log", 19 | "esp-bootloader-esp-idf/log-04", 20 | "esp-hal/log-04", 21 | "esp-println/log-04", 22 | "esp-backtrace/println", 23 | ] 24 | 25 | defmt = [ 26 | "dep:defmt", 27 | "esp-bootloader-esp-idf/defmt", 28 | "esp-hal/defmt", 29 | "esp-println/defmt-espflash", 30 | "esp-backtrace/defmt", 31 | ] 32 | 33 | jtag = ["esp-println/jtag-serial"] 34 | uart = ["esp-println/uart"] 35 | 36 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3"] 37 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6"] 38 | 39 | [dependencies] 40 | esp-bootloader-esp-idf = { version = "0.4.0" } 41 | esp-hal = { version = "1.0.0", features = ["unstable"] } 42 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 43 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 44 | 45 | defmt = { version = "1.0.1", optional = true } 46 | log = { version = "0.4", optional = true } 47 | -------------------------------------------------------------------------------- /embassy_ble/README.md: -------------------------------------------------------------------------------- 1 | # Embassy WIFI 2 | 3 | This example shows how to turn on basic WIFI support in the [Embassy](https://github.com/embassy-rs/embassy) framework. 4 | 5 | > 这个例子演示了如何在 [Embassy](https://github.com/embassy-rs/embassy) 框架下开启最基本的 WIFI 支持。 6 | 7 | This example is modified from [embassy_blinky](../embassy_blinky). If you are just starting out, I suggest you read [embassy_blinky](../embassy_blinky) before continuing down the page 8 | 9 | > 这个例子是在 [embassy_blinky](../embassy_blinky) 的基础上修改而来的。如果你是刚开始,我建议你先阅读 [embassy_blinky](../embassy_blinky) 的内容,再继续往下阅读。 10 | 11 | To turn on basic WIFI support, we just need to add the following to `Cargo.toml`: 12 | 13 | > 开启 WIFI 基本的支持,我们只需要在 `Cargo.toml` 中添加以下内容: 14 | 15 | ```toml 16 | [features] 17 | default = [ 18 | ... 19 | "wifi", 20 | ] 21 | 22 | log = [ 23 | ... 24 | "esp-wifi?/log", 25 | ] 26 | 27 | defmt = [ 28 | ... 29 | "esp-wifi?/defmt", 30 | "embassy-net?/defmt" 31 | ] 32 | 33 | esp32c3 = [..., "esp-wifi?/esp32c3"] 34 | esp32c6 = [..., "esp-wifi?/esp32c6"] 35 | 36 | [dependencies] 37 | esp-wifi = { version = "0.12.0", default-features = false, features = [ 38 | "esp-alloc", "wifi", "smoltcp", "utils"], optional = true } 39 | embassy-net = { version = "0.6.0", features = ["tcp", "udp", "dhcpv4", "medium-ethernet"], optional = true } 40 | 41 | static_cell = "2.1.0" 42 | esp-alloc = { version = "0.6" } 43 | ``` 44 | -------------------------------------------------------------------------------- /i2c-sht31/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "i2c-sht31" 3 | version = "0.0.0" 4 | description = "i2c-sht31" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | ] 16 | 17 | log = [ 18 | "dep:log", 19 | "esp-bootloader-esp-idf/log-04", 20 | "esp-hal/log-04", 21 | "esp-println/log-04", 22 | "esp-backtrace/println", 23 | ] 24 | 25 | defmt = [ 26 | "dep:defmt", 27 | "esp-bootloader-esp-idf/defmt", 28 | "esp-hal/defmt", 29 | "esp-println/defmt-espflash", 30 | "esp-backtrace/defmt", 31 | ] 32 | 33 | jtag = ["esp-println/jtag-serial"] 34 | uart = ["esp-println/uart"] 35 | 36 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3"] 37 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6"] 38 | 39 | [dependencies] 40 | esp-bootloader-esp-idf = { version = "0.4.0" } 41 | esp-hal = { version = "1.0.0", features = ["unstable"] } 42 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 43 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 44 | 45 | defmt = { version = "1.0.1", optional = true } 46 | log = { version = "0.4", optional = true } 47 | 48 | embedded-hal = "1.0" 49 | bitflags = "2.10" 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP Examples 2 | 3 | Some examples of [esp-hal](https://github.com/esp-rs/esp-hal). 4 | 5 | > 一些使用 [esp-hal](https://github.com/esp-rs/esp-hal) 的例子: 6 | 7 | - [x] [blinky](blinky): Blinks an LED and output logs 8 | - [x] [embassy_blinky](embassy_blinky): Use embassy to blinks an LED and output logs 9 | - [x] [embassy_wifi](embassy_wifi): Use embassy to connect to wifi 10 | - [x] [alloc](alloc): How to set heap allocator, use String,Vec,BTreeMap,Box, and use json. 11 | - [x] [rhai](rhai): Rhai is an embedded scripting language. 12 | - [x] [smartled](smartled): Easily light RGB LEDs using the RMT output channel. 13 | - [x] [i2c-sht31](i2c-sht31): Connecting the SHT31 temperature and humidity sensor using I2C interface. 14 | 15 | Unlike the examples that come with esp-hal, each example is separate and handles dependencies, so you can just copy an example to get a quick start on your project. 16 | 17 | > 不同于 esp-hal 自带的示例,这里每一个示例都是单独的、处理好依赖的,你可以直接复制某个示例快速开始项目。 18 | 19 | You can check the README.md file in each example for more information. 20 | 21 | > 你可以查看每个示例中的 README.md 文件了解更多信息。 22 | 23 | But, I only have the esp32c3 and esp32c6 development boards at the moment, these examples are only tested the esp32c3 and esp32c6, maybe in the future I'll add more chip models. For other chip models, you may have to make some changes to the Cargo.toml file and the .cargo/config.toml file. 24 | 25 | > 但是,目前我只有 esp32c3 和 scp32c6 的开发板,这些示例只在这两个型号上进行了测试,也许未来会添加更多芯片型号。对于其他芯片型号,你可能需要修改 Cargo.toml 文件和 .cargo/config.toml 文件。 26 | -------------------------------------------------------------------------------- /smartled/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "smartled" 3 | version = "0.0.0" 4 | description = "smartled" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | "smartled" 16 | ] 17 | 18 | log = [ 19 | "dep:log", 20 | "esp-bootloader-esp-idf/log-04", 21 | "esp-hal/log-04", 22 | "esp-println/log-04", 23 | "esp-backtrace/println", 24 | ] 25 | 26 | defmt = [ 27 | "dep:defmt", 28 | "esp-bootloader-esp-idf/defmt", 29 | "esp-hal/defmt", 30 | "esp-println/defmt-espflash", 31 | "esp-backtrace/defmt", 32 | "esp-hal-smartled?/defmt" 33 | ] 34 | 35 | jtag = ["esp-println/jtag-serial"] 36 | uart = ["esp-println/uart"] 37 | 38 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3", "esp-hal-smartled?/esp32c3"] 39 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6", "esp-hal-smartled?/esp32c6"] 40 | 41 | smartled = [ 42 | "esp-hal-smartled", 43 | "smart-leds", 44 | ] 45 | 46 | [dependencies] 47 | esp-bootloader-esp-idf = { version = "0.4.0" } 48 | esp-hal = { version = "1.0.0", features = ["unstable"] } 49 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 50 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 51 | 52 | defmt = { version = "1.0.1", optional = true } 53 | log = { version = "0.4", optional = true } 54 | 55 | esp-hal-smartled = { version = "0.16", optional = true} 56 | smart-leds = { version = "0.4", optional = true} 57 | -------------------------------------------------------------------------------- /alloc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "alloc" 3 | version = "0.0.0" 4 | description = "alloc" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | "alloc" 16 | ] 17 | 18 | log = [ 19 | "dep:log", 20 | "esp-bootloader-esp-idf/log-04", 21 | "esp-hal/log-04", 22 | "esp-println/log-04", 23 | "esp-backtrace/println", 24 | ] 25 | 26 | defmt = [ 27 | "dep:defmt", 28 | "esp-bootloader-esp-idf/defmt", 29 | "esp-hal/defmt", 30 | "esp-println/defmt-espflash", 31 | "esp-backtrace/defmt", 32 | ] 33 | 34 | jtag = ["esp-println/jtag-serial"] 35 | uart = ["esp-println/uart"] 36 | 37 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3"] 38 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6"] 39 | 40 | alloc = [ 41 | "esp-alloc", 42 | "serde/alloc", 43 | "serde_json/alloc" 44 | ] 45 | 46 | [dependencies] 47 | esp-bootloader-esp-idf = { version = "0.4.0" } 48 | esp-hal = { version = "1.0.0", features = ["unstable"] } 49 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 50 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 51 | 52 | defmt = { version = "1.0.1", optional = true } 53 | log = { version = "0.4", optional = true } 54 | 55 | esp-alloc = { version = "0.9", optional = true } 56 | 57 | serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } 58 | serde_json = { version = "1.0", default-features = false, optional = true } 59 | -------------------------------------------------------------------------------- /blinky/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Blinks an LED 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | use esp_hal::{ 11 | clock::CpuClock, 12 | delay::Delay, 13 | gpio::{Level, Output, OutputConfig}, 14 | main, 15 | time::Duration, 16 | }; 17 | 18 | use esp_backtrace as _; 19 | use esp_println::println; 20 | 21 | esp_bootloader_esp_idf::esp_app_desc!(); 22 | 23 | #[main] 24 | fn main() -> ! { 25 | #[cfg(feature = "log")] 26 | { 27 | // The default log level can be specified here. 28 | // You can see the esp-println documentation: https://docs.rs/esp-println 29 | esp_println::logger::init_logger(log::LevelFilter::Info); 30 | } 31 | 32 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 33 | let peripherals = esp_hal::init(config); 34 | 35 | // use esp_println 36 | println!("hello world!"); 37 | 38 | // use log 39 | #[cfg(feature = "log")] 40 | { 41 | log::error!("this is error message"); 42 | log::warn!("this is warn message"); 43 | log::info!("this is info message"); 44 | log::debug!("this is debug message"); 45 | log::trace!("this is trace message"); 46 | } 47 | 48 | // Set GPIO0 as an output, and set its state high initially. 49 | let mut led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 50 | 51 | // Initialize the Delay peripheral, and use it to toggle the LED state in a 52 | // loop. 53 | let delay = Delay::new(); 54 | 55 | loop { 56 | println!("loop!"); 57 | led.toggle(); 58 | delay.delay_millis(500); 59 | led.toggle(); 60 | // or using `fugit` duration 61 | delay.delay(Duration::from_secs(2)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /embassy_blinky/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embassy_blinky" 3 | version = "0.0.0" 4 | description = "embassy_blinky" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | "embassy" 16 | ] 17 | 18 | log = [ 19 | "dep:log", 20 | "esp-bootloader-esp-idf/log-04", 21 | "esp-hal/log-04", 22 | "esp-println/log-04", 23 | "esp-backtrace/println", 24 | "esp-rtos?/log-04", 25 | "embassy-executor?/log", 26 | ] 27 | 28 | defmt = [ 29 | "dep:defmt", 30 | "esp-bootloader-esp-idf/defmt", 31 | "esp-hal/defmt", 32 | "esp-println/defmt-espflash", 33 | "esp-backtrace/defmt", 34 | "esp-rtos?/defmt", 35 | "embassy-executor?/defmt", 36 | ] 37 | 38 | jtag = ["esp-println/jtag-serial"] 39 | uart = ["esp-println/uart"] 40 | 41 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3", "esp-rtos?/esp32c3"] 42 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6", "esp-rtos?/esp32c6"] 43 | 44 | embassy = [ 45 | "embassy-executor", 46 | "embassy-time", 47 | "esp-rtos/embassy", 48 | ] 49 | 50 | [dependencies] 51 | esp-bootloader-esp-idf = { version = "0.4.0" } 52 | esp-hal = { version = "1.0.0", features = ["unstable"] } 53 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 54 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 55 | esp-rtos = { version = "0.2", optional = true } 56 | 57 | defmt = { version = "1.0.1", optional = true } 58 | log = { version = "0.4", optional = true } 59 | 60 | embassy-executor = { version = "0.9", features = ["arch-riscv32"], optional = true } 61 | embassy-time = { version = "0.5", optional = true } 62 | -------------------------------------------------------------------------------- /rhai/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rhai-example" 3 | version = "0.0.0" 4 | description = "rhai example" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | "alloc", 16 | "rhai" 17 | ] 18 | 19 | log = [ 20 | "dep:log", 21 | "esp-bootloader-esp-idf/log-04", 22 | "esp-hal/log-04", 23 | "esp-println/log-04", 24 | "esp-backtrace/println", 25 | ] 26 | 27 | defmt = [ 28 | "dep:defmt", 29 | "esp-bootloader-esp-idf/defmt", 30 | "esp-hal/defmt", 31 | "esp-println/defmt-espflash", 32 | "esp-backtrace/defmt", 33 | ] 34 | 35 | jtag = ["esp-println/jtag-serial"] 36 | uart = ["esp-println/uart"] 37 | 38 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3"] 39 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6"] 40 | 41 | alloc = [ 42 | "esp-alloc", 43 | ] 44 | 45 | rhai = [ 46 | "dep:rhai", 47 | "rhai/f32_float", 48 | "rhai/only_i32" 49 | ] 50 | 51 | [dependencies] 52 | esp-bootloader-esp-idf = { version = "0.4.0" } 53 | esp-hal = { version = "1.0.0", features = ["unstable"] } 54 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 55 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 56 | 57 | defmt = { version = "1.0.1", optional = true } 58 | log = { version = "0.4", optional = true } 59 | 60 | esp-alloc = { version = "0.9", optional = true } 61 | 62 | rhai = { version = "1.23", default-features = false, features = ["no_std"], optional = true } 63 | critical-section = "1.2" 64 | 65 | [profile.release] 66 | lto = "fat" # turn on Link-Time Optimizations 67 | codegen-units = 1 # trade compile time with maximum optimization 68 | opt-level = "z" # optimize for size 69 | -------------------------------------------------------------------------------- /embassy_ble/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embassy_ble" 3 | version = "0.0.0" 4 | description = "embassy_ble" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | "embassy", 16 | "ble", 17 | ] 18 | 19 | log = [ 20 | "dep:log", 21 | "esp-hal/log-04", 22 | "esp-println/log-04", 23 | "esp-backtrace/println", 24 | "embassy-executor?/log", 25 | "esp-wifi?/log-04", 26 | ] 27 | 28 | defmt = [ 29 | "dep:defmt", 30 | "esp-hal/defmt", 31 | "esp-println/defmt-espflash", 32 | "esp-backtrace/defmt", 33 | "embassy-executor?/defmt", 34 | "esp-wifi?/defmt", 35 | ] 36 | 37 | jtag = ["esp-println/jtag-serial"] 38 | uart = ["esp-println/uart"] 39 | 40 | esp32c3 = ["esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3", "esp-wifi?/esp32c3", "esp-hal-embassy?/esp32c3"] 41 | esp32c6 = ["esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6", "esp-wifi?/esp32c6", "esp-hal-embassy?/esp32c6"] 42 | 43 | embassy = [ 44 | "esp-hal-embassy", 45 | "embassy-executor", 46 | "embassy-time", 47 | "embassy-executor/task-arena-size-20480" 48 | ] 49 | 50 | ble = [ 51 | "esp-wifi/ble", 52 | ] 53 | 54 | [dependencies] 55 | esp-hal = { version = "1.0.0-rc.0", features = ["unstable"] } 56 | esp-println = { version = "0.15.0", default-features = false, features = ["critical-section", "colors"] } 57 | esp-backtrace = { version = "0.17.0", features = ["panic-handler", "exception-handler"] } 58 | 59 | defmt = { version = "1.0.1", optional = true } 60 | log = { version = "0.4", optional = true } 61 | 62 | esp-hal-embassy = { version = "0.9", optional = true } 63 | embassy-executor = { version = "0.7", package = "embassy-executor", features = ["arch-riscv32"], optional = true } 64 | embassy-time = { version = "0.4", optional = true } 65 | 66 | esp-wifi = { version = "0.15", optional = true } 67 | bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ "macros", "async"] } 68 | 69 | static_cell = "2.1.0" 70 | esp-alloc = { version = "0.8" } 71 | -------------------------------------------------------------------------------- /smartled/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Blinks an LED 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | use esp_hal::{ 11 | clock::CpuClock, 12 | delay::Delay, 13 | main, 14 | rmt::Rmt, 15 | time::{Duration, Rate}, 16 | }; 17 | 18 | use esp_backtrace as _; 19 | use esp_println::println; 20 | 21 | esp_bootloader_esp_idf::esp_app_desc!(); 22 | 23 | #[main] 24 | fn main() -> ! { 25 | #[cfg(feature = "log")] 26 | { 27 | // The default log level can be specified here. 28 | // You can see the esp-println documentation: https://docs.rs/esp-println 29 | esp_println::logger::init_logger(log::LevelFilter::Info); 30 | } 31 | 32 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 33 | let peripherals = esp_hal::init(config); 34 | 35 | // use esp_println 36 | println!("hello world!"); 37 | 38 | // use log 39 | #[cfg(feature = "log")] 40 | { 41 | log::error!("this is error message"); 42 | log::warn!("this is warn message"); 43 | log::info!("this is info message"); 44 | log::debug!("this is debug message"); 45 | log::trace!("this is trace message"); 46 | } 47 | 48 | let rmt: Rmt<'_, esp_hal::Blocking> = 49 | Rmt::new(peripherals.RMT, Rate::from_mhz(80)).expect("Failed to initialize RMT"); 50 | 51 | use esp_hal_smartled::{smart_led_buffer, SmartLedsAdapter}; 52 | // see https://docs.rs/smart-leds/latest/smart_leds/ 53 | use smart_leds::{colors::*, SmartLedsWrite}; 54 | 55 | let rmt_buffer = smart_led_buffer!(1); 56 | let mut led = SmartLedsAdapter::new(rmt.channel0, peripherals.GPIO8, rmt_buffer); 57 | 58 | let colors = [ 59 | WHITE, SILVER, GRAY, BLACK, RED, MAROON, YELLOW, OLIVE, LIME, GREEN, AQUA, TEAL, BLUE, 60 | NAVY, FUCHSIA, PURPLE, 61 | ]; 62 | 63 | // Initialize the Delay peripheral, and use it to toggle the LED state in a 64 | // loop. 65 | let delay = Delay::new(); 66 | 67 | loop { 68 | println!("loop!"); 69 | 70 | for color in colors { 71 | let data = [color; 1]; 72 | led.write(data).unwrap(); 73 | 74 | delay.delay_millis(500); 75 | } 76 | 77 | // or using `fugit` duration 78 | delay.delay(Duration::from_secs(2)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /embassy_wifi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embassy_wifi" 3 | version = "0.0.0" 4 | description = "embassy_wifi" 5 | readme = "README.md" 6 | keywords = ["esp-hal", "esp32"] 7 | license = "MIT" 8 | edition = "2024" 9 | 10 | [features] 11 | default = [ 12 | "esp32c6", 13 | "jtag", 14 | "log", 15 | "embassy", 16 | "wifi", 17 | ] 18 | 19 | log = [ 20 | "dep:log", 21 | "esp-bootloader-esp-idf/log-04", 22 | "esp-hal/log-04", 23 | "esp-println/log-04", 24 | "esp-backtrace/println", 25 | "esp-rtos/log-04", 26 | "embassy-executor?/log", 27 | "esp-radio?/log-04", 28 | ] 29 | 30 | defmt = [ 31 | "dep:defmt", 32 | "esp-bootloader-esp-idf/defmt", 33 | "esp-hal/defmt", 34 | "esp-println/defmt-espflash", 35 | "esp-backtrace/defmt", 36 | "esp-rtos/defmt", 37 | "embassy-executor?/defmt", 38 | "esp-radio?/defmt", 39 | "embassy-net?/defmt" 40 | ] 41 | 42 | jtag = ["esp-println/jtag-serial"] 43 | uart = ["esp-println/uart"] 44 | 45 | esp32c3 = ["esp-bootloader-esp-idf/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3", "esp-rtos/esp32c3", "esp-radio?/esp32c3",] 46 | esp32c6 = ["esp-bootloader-esp-idf/esp32c6", "esp-hal/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6", "esp-rtos/esp32c6", "esp-radio?/esp32c6", ] 47 | 48 | embassy = [ 49 | "embassy-executor", 50 | "embassy-time", 51 | "esp-rtos/embassy", 52 | ] 53 | 54 | wifi = [ 55 | "esp-radio", 56 | "esp-radio/wifi", 57 | "esp-radio/smoltcp", 58 | "esp-radio/csi", 59 | "esp-rtos/esp-radio", 60 | "embassy-net", 61 | ] 62 | 63 | [dependencies] 64 | esp-bootloader-esp-idf = { version = "0.4.0" } 65 | esp-hal = { version = "1.0.0", features = ["unstable"] } 66 | esp-println = { version = "0.16.1", default-features = false, features = ["critical-section", "colors"] } 67 | esp-backtrace = { version = "0.18.1", features = ["panic-handler"] } 68 | esp-rtos = { version = "0.2" } 69 | 70 | defmt = { version = "1.0.1", optional = true } 71 | log = { version = "0.4", optional = true } 72 | 73 | embassy-executor = { version = "0.9", features = ["arch-riscv32"], optional = true } 74 | embassy-time = { version = "0.5", optional = true } 75 | 76 | esp-radio = { version = "0.17", features = ["unstable", "wifi"], optional = true } 77 | embassy-net = { version = "0.7.0", features = ["tcp", "udp", "dhcpv4", "medium-ethernet"], optional = true } 78 | 79 | static_cell = "2.1.0" 80 | esp-alloc = { version = "0.9" } 81 | -------------------------------------------------------------------------------- /i2c-sht31/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Blinks an LED 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | use esp_hal::{ 11 | clock::CpuClock, 12 | delay::Delay, 13 | gpio::{Level, Output, OutputConfig}, 14 | i2c::master::{BusTimeout, Config as I2cConfig, I2c}, 15 | main, 16 | time::{Duration, Rate}, 17 | }; 18 | 19 | use esp_backtrace as _; 20 | use esp_println::println; 21 | 22 | use sht3x::{Address, Sht3x}; 23 | 24 | pub mod sht3x; 25 | 26 | esp_bootloader_esp_idf::esp_app_desc!(); 27 | 28 | #[main] 29 | fn main() -> ! { 30 | #[cfg(feature = "log")] 31 | { 32 | // The default log level can be specified here. 33 | // You can see the esp-println documentation: https://docs.rs/esp-println 34 | esp_println::logger::init_logger(log::LevelFilter::Info); 35 | } 36 | 37 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 38 | let peripherals = esp_hal::init(config); 39 | 40 | // use esp_println 41 | println!("hello world!"); 42 | 43 | // use log 44 | #[cfg(feature = "log")] 45 | { 46 | log::error!("this is error message"); 47 | log::warn!("this is warn message"); 48 | log::info!("this is info message"); 49 | log::debug!("this is debug message"); 50 | log::trace!("this is trace message"); 51 | } 52 | 53 | // Set GPIO0 as an output, and set its state high initially. 54 | let mut led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 55 | 56 | // Initialize the Delay peripheral, and use it to toggle the LED state in a 57 | // loop. 58 | let delay = Delay::new(); 59 | 60 | let mut i2c = I2c::new( 61 | peripherals.I2C0, 62 | I2cConfig::default() 63 | .with_frequency(Rate::from_khz(100)) 64 | .with_timeout(BusTimeout::Maximum), 65 | ) 66 | .unwrap() 67 | .with_sda(peripherals.GPIO4) 68 | .with_scl(peripherals.GPIO5); 69 | 70 | let mut sht3x = Sht3x::new(Address::Low, delay); 71 | 72 | loop { 73 | println!("loop!"); 74 | led.toggle(); 75 | delay.delay_millis(500); 76 | led.toggle(); 77 | // or using `fugit` duration 78 | delay.delay(Duration::from_secs(2)); 79 | 80 | let res = sht3x.measure( 81 | &mut i2c, 82 | sht3x::ClockStretch::Enabled, 83 | sht3x::Repeatability::High, 84 | ); 85 | println!("sht3x.measure: {:?}", res); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /embassy_blinky/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Blinks an LED 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | use esp_hal::interrupt::software::SoftwareInterruptControl; 11 | use esp_hal::{ 12 | clock::CpuClock, 13 | gpio::{Level, Output, OutputConfig}, 14 | timer::timg::TimerGroup, 15 | }; 16 | 17 | use esp_backtrace as _; 18 | use esp_println::println; 19 | 20 | use embassy_executor::Spawner; 21 | use embassy_time::{Duration, Timer}; 22 | 23 | esp_bootloader_esp_idf::esp_app_desc!(); 24 | 25 | #[esp_rtos::main] 26 | async fn main(spawner: Spawner) { 27 | #[cfg(feature = "log")] 28 | { 29 | // The default log level can be specified here. 30 | // You can see the esp-println documentation: https://docs.rs/esp-println 31 | esp_println::logger::init_logger(log::LevelFilter::Info); 32 | } 33 | 34 | println!("Init!"); 35 | 36 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 37 | let peripherals = esp_hal::init(config); 38 | 39 | // use esp_println 40 | println!("hello world!"); 41 | 42 | // use log 43 | #[cfg(feature = "log")] 44 | { 45 | log::error!("this is error message"); 46 | log::warn!("this is warn message"); 47 | log::info!("this is info message"); 48 | log::debug!("this is debug message"); 49 | log::trace!("this is trace message"); 50 | } 51 | 52 | // Set GPIO0 as an output, and set its state high initially. 53 | let led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 54 | 55 | let timg0 = TimerGroup::new(peripherals.TIMG0); 56 | let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); 57 | esp_rtos::start(timg0.timer0, sw_int.software_interrupt0); 58 | 59 | println!("embassy init!"); 60 | 61 | spawner.spawn(run()).ok(); 62 | spawner.spawn(toggle(led)).ok(); 63 | 64 | loop { 65 | println!("main loop!"); 66 | Timer::after(Duration::from_millis(5_000)).await; 67 | esp_hal::riscv::asm::wfi(); 68 | } 69 | } 70 | 71 | #[embassy_executor::task] 72 | async fn run() { 73 | loop { 74 | println!("task loop!"); 75 | Timer::after(Duration::from_millis(1_000)).await; 76 | } 77 | } 78 | 79 | #[embassy_executor::task] 80 | async fn toggle(mut led: Output<'static>) { 81 | loop { 82 | println!("toggle loop!"); 83 | led.toggle(); 84 | Timer::after_secs(1).await; 85 | led.toggle(); 86 | Timer::after_secs(2).await; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /alloc/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Blinks an LED 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | extern crate alloc; 11 | 12 | use core::ptr::addr_of_mut; 13 | 14 | use esp_hal::{ 15 | clock::CpuClock, 16 | delay::Delay, 17 | gpio::{Level, Output, OutputConfig}, 18 | main, 19 | time::Duration, 20 | }; 21 | 22 | use esp_backtrace as _; 23 | use esp_println::println; 24 | 25 | fn init_heap() { 26 | const HEAP_SIZE: usize = 64 * 1024; 27 | static mut HEAP: core::mem::MaybeUninit<[u8; HEAP_SIZE]> = core::mem::MaybeUninit::uninit(); 28 | 29 | unsafe { 30 | esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( 31 | addr_of_mut!(HEAP) as *mut u8, 32 | HEAP_SIZE, 33 | esp_alloc::MemoryCapability::Internal.into(), 34 | )); 35 | } 36 | } 37 | 38 | esp_bootloader_esp_idf::esp_app_desc!(); 39 | 40 | #[main] 41 | fn main() -> ! { 42 | init_heap(); 43 | 44 | #[cfg(feature = "log")] 45 | { 46 | // The default log level can be specified here. 47 | // You can see the esp-println documentation: https://docs.rs/esp-println 48 | esp_println::logger::init_logger(log::LevelFilter::Info); 49 | } 50 | 51 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 52 | let peripherals = esp_hal::init(config); 53 | 54 | // use esp_println 55 | println!("hello world!"); 56 | 57 | // use log 58 | #[cfg(feature = "log")] 59 | { 60 | log::error!("this is error message"); 61 | log::warn!("this is warn message"); 62 | log::info!("this is info message"); 63 | log::debug!("this is debug message"); 64 | log::trace!("this is trace message"); 65 | } 66 | 67 | // Set GPIO0 as an output, and set its state high initially. 68 | let mut led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 69 | 70 | // Initialize the Delay peripheral, and use it to toggle the LED state in a 71 | // loop. 72 | let delay = Delay::new(); 73 | 74 | // alloc 75 | // see https://doc.rust-lang.org/stable/alloc/index.html 76 | { 77 | // use String 78 | use alloc::string::ToString; 79 | let s = "hello world!".to_string(); 80 | println!("{:?}", s); 81 | 82 | // use Vec 83 | let array = alloc::vec![0u8; 12]; 84 | println!("{:?}", array); 85 | 86 | // use BtreeMap 87 | let mut map = alloc::collections::BTreeMap::new(); 88 | map.insert("hello", "world"); 89 | println!("{:?}", map); 90 | 91 | // use Box 92 | let b = alloc::boxed::Box::new(12345678); 93 | println!("{:?}", b); 94 | } 95 | 96 | // json 97 | // see https://docs.rs/serde_json/1.0.116/serde_json/ 98 | { 99 | use alloc::string::ToString; 100 | use serde_json::json; 101 | 102 | let john = json!({ 103 | "name": "John Doe", 104 | "age": 43, 105 | "phones": [ 106 | "+44 1234567", 107 | "+44 2345678" 108 | ] 109 | }); 110 | 111 | println!("first phone number: {}", john["phones"][0]); 112 | 113 | // Convert to a string of JSON and print it out 114 | println!("{}", john.to_string()); 115 | 116 | let p: Person = serde_json::from_str(&john.to_string()).unwrap(); 117 | 118 | // Do things just like with any other Rust data structure. 119 | println!("Please call {} at the number {}", p.name, p.phones[0]); 120 | } 121 | 122 | loop { 123 | println!("loop!"); 124 | led.toggle(); 125 | delay.delay_millis(500); 126 | led.toggle(); 127 | // or using `fugit` duration 128 | delay.delay(Duration::from_secs(2)); 129 | } 130 | } 131 | 132 | use alloc::string::String; 133 | use alloc::vec::Vec; 134 | use serde::{Deserialize, Serialize}; 135 | 136 | #[derive(Serialize, Deserialize)] 137 | struct Person { 138 | name: String, 139 | age: u8, 140 | phones: Vec, 141 | } 142 | -------------------------------------------------------------------------------- /rhai/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Blinks an LED 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | extern crate alloc; 11 | 12 | use core::ptr::addr_of_mut; 13 | 14 | use esp_backtrace as _; 15 | use esp_hal::{ 16 | clock::CpuClock, 17 | delay::Delay, 18 | gpio::{Level, Output, OutputConfig}, 19 | main, 20 | time::Duration, 21 | }; 22 | use esp_println::println; 23 | 24 | fn init_heap() { 25 | const HEAP_SIZE: usize = 128 * 1024; 26 | static mut HEAP: core::mem::MaybeUninit<[u8; HEAP_SIZE]> = core::mem::MaybeUninit::uninit(); 27 | 28 | unsafe { 29 | esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( 30 | addr_of_mut!(HEAP) as *mut u8, 31 | HEAP_SIZE, 32 | esp_alloc::MemoryCapability::Internal.into(), 33 | )); 34 | } 35 | } 36 | 37 | use core::cell::RefCell; 38 | use critical_section::Mutex; 39 | 40 | static LED: Mutex>>> = Mutex::new(RefCell::new(None)); 41 | 42 | fn toggle_led() { 43 | critical_section::with(|cs| { 44 | if let Some(led) = LED.borrow_ref_mut(cs).as_mut() { 45 | led.toggle(); 46 | } 47 | }) 48 | } 49 | 50 | // Normal function that returns a standard type 51 | // Remember to use 'ImmutableString' and not 'String' 52 | fn add_len(x: i32, s: rhai::ImmutableString) -> i32 { 53 | x + s.len() as i32 54 | } 55 | // Alternatively, '&str' maps directly to 'ImmutableString' 56 | fn add_len_count(x: i32, s: &str, c: i32) -> i32 { 57 | x + s.len() as i32 * c 58 | } 59 | // Function that returns a 'Dynamic' value 60 | fn get_any_value() -> rhai::Dynamic { 61 | 42_i32.into() // standard types can use '.into()' 62 | } 63 | 64 | esp_bootloader_esp_idf::esp_app_desc!(); 65 | 66 | #[main] 67 | fn main() -> ! { 68 | init_heap(); 69 | 70 | #[cfg(feature = "log")] 71 | { 72 | // The default log level can be specified here. 73 | // You can see the esp-println documentation: https://docs.rs/esp-println 74 | esp_println::logger::init_logger(log::LevelFilter::Info); 75 | } 76 | 77 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 78 | let peripherals = esp_hal::init(config); 79 | 80 | // use esp_println 81 | println!("hello world!"); 82 | 83 | // use log 84 | #[cfg(feature = "log")] 85 | { 86 | log::error!("this is error message"); 87 | log::warn!("this is warn message"); 88 | log::info!("this is info message"); 89 | log::debug!("this is debug message"); 90 | log::trace!("this is trace message"); 91 | } 92 | 93 | // Set GPIO0 as an output, and set its state high initially. 94 | let mut led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 95 | 96 | led.set_high(); 97 | 98 | critical_section::with(|cs| { 99 | LED.borrow_ref_mut(cs).replace(led); 100 | }); 101 | 102 | // Initialize the Delay peripheral, and use it to toggle the LED state in a 103 | // loop. 104 | let delay = Delay::new(); 105 | 106 | // alloc 107 | // see https://doc.rust-lang.org/stable/alloc/index.html 108 | { 109 | // use String 110 | use alloc::string::ToString; 111 | let s = "hello world!".to_string(); 112 | println!("{:?}", s); 113 | 114 | // use Vec 115 | let array = alloc::vec![0u8; 12]; 116 | println!("{:?}", array); 117 | 118 | // use BtreeMap 119 | let mut map = alloc::collections::BTreeMap::new(); 120 | map.insert("hello", "world"); 121 | println!("{:?}", map); 122 | 123 | // use Box 124 | let b = alloc::boxed::Box::new(12345678); 125 | println!("{:?}", b); 126 | } 127 | 128 | // rhai 129 | // see https://rhai.rs/ 130 | let mut engine = rhai::Engine::new(); 131 | 132 | // sprint and debug 133 | // see https://rhai.rs/book/language/print-debug.html 134 | { 135 | engine.on_print(|s| println!("{s}")); 136 | engine.on_debug(|s, src, pos| match (src, pos) { 137 | (Some(source), rhai::Position::NONE) => println!("{source} | {s}"), 138 | (Some(source), pos) => println!("{source} @ {pos:?} | {s}"), 139 | (None, rhai::Position::NONE) => println!("{s}"), 140 | (None, pos) => println!("{pos:?} | {s}"), 141 | }); 142 | } 143 | 144 | // Register rust function 145 | // see https://rhai.rs/book/rust/functions.html 146 | { 147 | engine.register_fn("toggle", toggle_led); 148 | 149 | engine 150 | .register_fn("add", add_len) 151 | .register_fn("add", add_len_count) 152 | .register_fn("add", get_any_value) 153 | .register_fn("inc", |x: i32| { 154 | // closure is also OK! 155 | x + 1 156 | }) 157 | .register_fn("log", |label: &str, x: i32| { 158 | println!("{label} = {x}"); 159 | }); 160 | 161 | let result = engine.eval::(r#"add(40, "xx")"#).unwrap(); 162 | 163 | println!("Answer: {result}"); // prints 42 164 | 165 | let result = engine.eval::(r#"add(40, "x", 2)"#).unwrap(); 166 | 167 | println!("Answer: {result}"); // prints 42 168 | 169 | let result = engine.eval::("add()").unwrap(); 170 | 171 | println!("Answer: {result}"); // prints 42 172 | 173 | let result = engine.eval::("inc(41)").unwrap(); 174 | 175 | println!("Answer: {result}"); // prints 42 176 | 177 | engine.run(r#"log("value", 42)"#).unwrap(); // prints "value = 42" 178 | } 179 | 180 | let ast = engine 181 | .compile( 182 | r#" 183 | fn get_message() { 184 | "Hello!" // greeting message 185 | } 186 | 187 | fn say_hello() { 188 | print(get_message()); // prints message 189 | } 190 | 191 | say_hello(); 192 | toggle(); 193 | "#, 194 | ) 195 | .unwrap(); 196 | 197 | loop { 198 | println!("loop!"); 199 | engine.run_ast(&ast).unwrap(); 200 | delay.delay_millis(500); 201 | engine.run_ast(&ast).unwrap(); 202 | // or using `fugit` duration 203 | delay.delay(Duration::from_secs(2)); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /embassy_ble/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Connect to wifi and use TCP 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | extern crate alloc; 11 | 12 | use core::cell::RefCell; 13 | use core::ptr::addr_of_mut; 14 | 15 | use esp_hal::{ 16 | clock::CpuClock, 17 | gpio::{Input, InputConfig, Level, Output, OutputConfig, Pull}, 18 | rng::Rng, 19 | time, 20 | timer::timg::TimerGroup, 21 | }; 22 | 23 | use esp_backtrace as _; 24 | use esp_println::println; 25 | 26 | use embassy_executor::Spawner; 27 | use embassy_time::{Duration, Timer}; 28 | 29 | use esp_wifi::{EspWifiController, ble::controller::BleConnector, init}; 30 | 31 | use bleps::{ 32 | ad_structure::{ 33 | AdStructure, BR_EDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE, create_advertising_data, 34 | }, 35 | async_attribute_server::AttributeServer, 36 | asynch::Ble, 37 | attribute_server::NotificationData, 38 | gatt, 39 | }; 40 | 41 | macro_rules! mk_static { 42 | ($t:ty,$val:expr) => {{ 43 | static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); 44 | #[deny(unused_attributes)] 45 | let x = STATIC_CELL.uninit().write(($val)); 46 | x 47 | }}; 48 | } 49 | 50 | fn init_heap() { 51 | const HEAP_SIZE: usize = 64 * 1024; 52 | static mut HEAP: core::mem::MaybeUninit<[u8; HEAP_SIZE]> = core::mem::MaybeUninit::uninit(); 53 | 54 | unsafe { 55 | esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( 56 | addr_of_mut!(HEAP) as *mut u8, 57 | HEAP_SIZE, 58 | esp_alloc::MemoryCapability::Internal.into(), 59 | )); 60 | } 61 | } 62 | 63 | #[esp_hal_embassy::main] 64 | async fn main(spawner: Spawner) { 65 | init_heap(); 66 | 67 | #[cfg(feature = "log")] 68 | { 69 | // The default log level can be specified here. 70 | // You can see the esp-println documentation: https://docs.rs/esp-println 71 | esp_println::logger::init_logger(log::LevelFilter::Info); 72 | } 73 | 74 | println!("Init!"); 75 | 76 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 77 | let peripherals = esp_hal::init(config); 78 | 79 | // init wifi 80 | let timer1 = TimerGroup::new(peripherals.TIMG1); 81 | let rng = Rng::new(peripherals.RNG); 82 | 83 | let esp_wifi_ctrl = &*mk_static!( 84 | EspWifiController<'static>, 85 | init(timer1.timer0, rng).unwrap() 86 | ); 87 | // let init = &*singleton!(:EspWifiController<'static> = init(timer1.timer0, rng, peripherals.RADIO_CLK).unwrap()).unwrap(); 88 | 89 | let bluetooth = peripherals.BT; 90 | 91 | let connector = BleConnector::new(esp_wifi_ctrl, bluetooth); 92 | 93 | let now = || time::Instant::now().duration_since_epoch().as_millis(); 94 | let mut ble = Ble::new(connector, now); 95 | println!("Connector created"); 96 | 97 | // use esp_println 98 | println!("hello world!"); 99 | 100 | // use log 101 | #[cfg(feature = "log")] 102 | { 103 | log::error!("this is error message"); 104 | log::warn!("this is warn message"); 105 | log::info!("this is info message"); 106 | log::debug!("this is debug message"); 107 | log::trace!("this is trace message"); 108 | } 109 | 110 | // Set GPIO0 as an output, and set its state high initially. 111 | let led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 112 | 113 | let button = Input::new( 114 | peripherals.GPIO9, 115 | InputConfig::default().with_pull(Pull::Down), 116 | ); 117 | 118 | let timg0 = TimerGroup::new(peripherals.TIMG0); 119 | esp_hal_embassy::init(timg0.timer0); 120 | 121 | println!("embassy init!"); 122 | 123 | spawner.spawn(run()).ok(); 124 | spawner.spawn(toggle(led)).ok(); 125 | 126 | let pin_ref = RefCell::new(button); 127 | let pin_ref = &pin_ref; 128 | 129 | loop { 130 | println!("{:?}", ble.init().await); 131 | println!("{:?}", ble.cmd_set_le_advertising_parameters().await); 132 | println!( 133 | "{:?}", 134 | ble.cmd_set_le_advertising_data( 135 | create_advertising_data(&[ 136 | AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED), 137 | AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]), 138 | AdStructure::CompleteLocalName(esp_hal::chip!()), 139 | AdStructure::ServiceData16 { 140 | uuid: 0x1809, 141 | data: b"ESP-BLE", 142 | }, 143 | ]) 144 | .unwrap() 145 | ) 146 | .await 147 | ); 148 | println!("{:?}", ble.cmd_set_le_advertise_enable(true).await); 149 | 150 | println!("started advertising"); 151 | 152 | let mut rf = |_offset: usize, data: &mut [u8]| { 153 | data[..20].copy_from_slice(&b"Hello Bare-Metal BLE"[..]); 154 | 17 155 | }; 156 | let mut wf = |offset: usize, data: &[u8]| { 157 | println!("RECEIVED: {} {:?}", offset, data); 158 | }; 159 | 160 | let mut wf2 = |offset: usize, data: &[u8]| { 161 | println!("RECEIVED: {} {:?}", offset, data); 162 | }; 163 | 164 | let mut rf3 = |_offset: usize, data: &mut [u8]| { 165 | data[..5].copy_from_slice(&b"Hola!"[..]); 166 | 5 167 | }; 168 | let mut wf3 = |offset: usize, data: &[u8]| { 169 | println!("RECEIVED: Offset {}, data {:?}", offset, data); 170 | }; 171 | 172 | gatt!([service { 173 | uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", 174 | characteristics: [ 175 | characteristic { 176 | uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38", 177 | read: rf, 178 | write: wf, 179 | }, 180 | characteristic { 181 | uuid: "957312e0-2354-11eb-9f10-fbc30a62cf38", 182 | write: wf2, 183 | }, 184 | characteristic { 185 | name: "my_characteristic", 186 | uuid: "987312e0-2354-11eb-9f10-fbc30a62cf38", 187 | notify: true, 188 | read: rf3, 189 | write: wf3, 190 | }, 191 | ], 192 | },]); 193 | 194 | let mut rng = bleps::no_rng::NoRng; 195 | let mut srv = AttributeServer::new(&mut ble, &mut gatt_attributes, &mut rng); 196 | 197 | let counter = RefCell::new(0u8); 198 | let counter = &counter; 199 | 200 | let mut notifier = || { 201 | // TODO how to check if notifications are enabled for the characteristic? 202 | // maybe pass something into the closure which just can query the characteristic 203 | // value probably passing in the attribute server won't work? 204 | 205 | async { 206 | let mut button = pin_ref.borrow_mut(); 207 | button.wait_for_rising_edge().await; 208 | println!("button pressed"); 209 | 210 | println!("sending notification"); 211 | let mut data = [0u8; 13]; 212 | data.copy_from_slice(b"Notification0"); 213 | { 214 | let mut counter = counter.borrow_mut(); 215 | data[data.len() - 1] += *counter; 216 | *counter = (*counter + 1) % 10; 217 | } 218 | NotificationData::new(my_characteristic_handle, &data) 219 | } 220 | }; 221 | 222 | srv.run(&mut notifier).await.unwrap(); 223 | } 224 | } 225 | 226 | #[embassy_executor::task] 227 | async fn run() { 228 | loop { 229 | println!("task loop!"); 230 | Timer::after(Duration::from_millis(1_000)).await; 231 | } 232 | } 233 | 234 | #[embassy_executor::task] 235 | async fn toggle(mut led: Output<'static>) { 236 | loop { 237 | println!("toggle loop!"); 238 | led.toggle(); 239 | Timer::after_secs(1).await; 240 | led.toggle(); 241 | Timer::after_secs(2).await; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /embassy_wifi/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Connect to wifi and use TCP 2 | //! 3 | //! This assumes that a LED is connected to the pin assigned to `led`. (GPIO8) 4 | 5 | //% CHIPS: esp32c3 esp32c6 6 | 7 | #![no_std] 8 | #![no_main] 9 | 10 | extern crate alloc; 11 | 12 | use esp_hal::interrupt::software::SoftwareInterruptControl; 13 | use esp_hal::{ 14 | clock::CpuClock, 15 | gpio::{Level, Output, OutputConfig}, 16 | ram, 17 | rng::Rng, 18 | timer::timg::TimerGroup, 19 | }; 20 | 21 | use esp_alloc as _; 22 | use esp_backtrace as _; 23 | use esp_println::println; 24 | 25 | use embassy_executor::Spawner; 26 | use embassy_time::{Duration, Timer}; 27 | 28 | use esp_radio::{ 29 | Controller, 30 | wifi::{ 31 | ClientConfig, ModeConfig, ScanConfig, WifiController, WifiDevice, WifiEvent, WifiStaState, 32 | }, 33 | }; 34 | 35 | use embassy_net::{Config, Ipv4Address, Runner, Stack, StackResources, tcp::TcpSocket}; 36 | 37 | // const SSID: &str = env!("SSID"); 38 | // const PASSWORD: &str = env!("PASSWORD"); 39 | const SSID: &str = "HOME_2"; 40 | const PASSWORD: &str = "lalala123456"; 41 | 42 | macro_rules! mk_static { 43 | ($t:ty,$val:expr) => {{ 44 | static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); 45 | #[deny(unused_attributes)] 46 | let x = STATIC_CELL.uninit().write(($val)); 47 | x 48 | }}; 49 | } 50 | 51 | esp_bootloader_esp_idf::esp_app_desc!(); 52 | 53 | #[esp_rtos::main] 54 | async fn main(spawner: Spawner) { 55 | #[cfg(feature = "log")] 56 | { 57 | // The default log level can be specified here. 58 | // You can see the esp-println documentation: https://docs.rs/esp-println 59 | esp_println::logger::init_logger(log::LevelFilter::Info); 60 | } 61 | 62 | println!("Init!"); 63 | 64 | let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 65 | let peripherals = esp_hal::init(config); 66 | 67 | esp_alloc::heap_allocator!(#[ram(reclaimed)] size: 64 * 1024); 68 | esp_alloc::heap_allocator!(size: 36 * 1024); 69 | 70 | let timg0 = TimerGroup::new(peripherals.TIMG0); 71 | let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); 72 | esp_rtos::start(timg0.timer0, sw_int.software_interrupt0); 73 | 74 | println!("esp_rtos start!"); 75 | 76 | let esp_radio_ctrl = &*mk_static!(Controller<'static>, esp_radio::init().unwrap()); 77 | 78 | let (controller, interfaces) = 79 | esp_radio::wifi::new(esp_radio_ctrl, peripherals.WIFI, Default::default()).unwrap(); 80 | let wifi_interface = interfaces.sta; 81 | 82 | let config = Config::dhcpv4(Default::default()); 83 | 84 | let rng = Rng::new(); 85 | let seed = (rng.random() as u64) << 32 | rng.random() as u64; 86 | 87 | // Init network stack 88 | let (stack, runner) = embassy_net::new( 89 | wifi_interface, 90 | config, 91 | mk_static!(StackResources<8>, StackResources::<8>::new()), 92 | seed, 93 | ); 94 | 95 | // use esp_println 96 | println!("hello world!"); 97 | 98 | // use log 99 | #[cfg(feature = "log")] 100 | { 101 | log::error!("this is error message"); 102 | log::warn!("this is warn message"); 103 | log::info!("this is info message"); 104 | log::debug!("this is debug message"); 105 | log::trace!("this is trace message"); 106 | } 107 | 108 | // Set GPIO0 as an output, and set its state high initially. 109 | let led = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default()); 110 | 111 | spawner.spawn(run()).ok(); 112 | spawner.spawn(toggle(led)).ok(); 113 | 114 | spawner.spawn(connection(controller)).ok(); 115 | spawner.spawn(net_task(runner)).ok(); 116 | spawner.spawn(tcp(stack)).ok(); 117 | 118 | loop { 119 | println!("main loop!"); 120 | Timer::after(Duration::from_millis(5_000)).await; 121 | } 122 | } 123 | 124 | #[embassy_executor::task] 125 | async fn run() { 126 | loop { 127 | println!("task loop!"); 128 | Timer::after(Duration::from_millis(1_000)).await; 129 | } 130 | } 131 | 132 | #[embassy_executor::task] 133 | async fn toggle(mut led: Output<'static>) { 134 | loop { 135 | println!("toggle loop!"); 136 | led.toggle(); 137 | Timer::after_secs(1).await; 138 | led.toggle(); 139 | Timer::after_secs(2).await; 140 | } 141 | } 142 | 143 | #[embassy_executor::task] 144 | async fn connection(mut controller: WifiController<'static>) { 145 | println!("start connection task"); 146 | println!("Device capabilities: {:?}", controller.capabilities()); 147 | loop { 148 | match esp_radio::wifi::sta_state() { 149 | WifiStaState::Connected => { 150 | // wait until we're no longer connected 151 | controller.wait_for_event(WifiEvent::StaDisconnected).await; 152 | Timer::after(Duration::from_millis(5000)).await 153 | } 154 | WifiStaState::Disconnected => { 155 | println!("Disconnected"); 156 | } 157 | _ => {} 158 | } 159 | if !matches!(controller.is_started(), Ok(true)) { 160 | let client_config = ModeConfig::Client( 161 | ClientConfig::default() 162 | .with_ssid(SSID.into()) 163 | .with_password(PASSWORD.into()), 164 | ); 165 | controller.set_config(&client_config).unwrap(); 166 | println!("Starting wifi"); 167 | controller.start_async().await.unwrap(); 168 | println!("Wifi started!"); 169 | 170 | println!("Scan"); 171 | let scan_config = ScanConfig::default().with_max(10); 172 | let result = controller 173 | .scan_with_config_async(scan_config) 174 | .await 175 | .unwrap(); 176 | for ap in result { 177 | println!("{:?}", ap); 178 | } 179 | } 180 | println!("About to connect..."); 181 | 182 | match controller.connect_async().await { 183 | Ok(_) => println!("Wifi connected!"), 184 | Err(e) => { 185 | println!("Failed to connect to wifi: {e:?}"); 186 | Timer::after(Duration::from_millis(5000)).await 187 | } 188 | } 189 | } 190 | } 191 | 192 | #[embassy_executor::task] 193 | async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { 194 | runner.run().await 195 | } 196 | 197 | #[embassy_executor::task] 198 | async fn tcp(stack: Stack<'static>) { 199 | let mut rx_buffer = [0; 4096]; 200 | let mut tx_buffer = [0; 4096]; 201 | 202 | loop { 203 | if stack.is_link_up() { 204 | break; 205 | } 206 | Timer::after(Duration::from_millis(500)).await; 207 | } 208 | 209 | println!("Waiting to get IP address..."); 210 | loop { 211 | if let Some(config) = stack.config_v4() { 212 | println!("Got IP: {}", config.address); 213 | break; 214 | } 215 | Timer::after(Duration::from_millis(500)).await; 216 | } 217 | 218 | loop { 219 | Timer::after(Duration::from_millis(1_000)).await; 220 | 221 | let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); 222 | 223 | socket.set_timeout(Some(Duration::from_secs(10))); 224 | 225 | let remote_endpoint = (Ipv4Address::new(142, 250, 185, 115), 80); 226 | println!("connecting..."); 227 | let r = socket.connect(remote_endpoint).await; 228 | if let Err(e) = r { 229 | println!("connect error: {:?}", e); 230 | continue; 231 | } 232 | println!("connected!"); 233 | let mut buf = [0; 1024]; 234 | loop { 235 | let r = write_all( 236 | &mut socket, 237 | b"GET / HTTP/1.0\r\nHost: www.mobile-j.de\r\n\r\n", 238 | ) 239 | .await; 240 | if let Err(e) = r { 241 | println!("write error: {:?}", e); 242 | break; 243 | } 244 | 245 | let n = match socket.read(&mut buf).await { 246 | Ok(0) => { 247 | println!("read EOF"); 248 | break; 249 | } 250 | Ok(n) => n, 251 | Err(e) => { 252 | println!("read error: {:?}", e); 253 | break; 254 | } 255 | }; 256 | println!("{}", core::str::from_utf8(&buf[..n]).unwrap()); 257 | } 258 | Timer::after(Duration::from_millis(3000)).await; 259 | } 260 | } 261 | 262 | async fn write_all(socket: &mut TcpSocket<'_>, buf: &[u8]) -> Result<(), embassy_net::tcp::Error> { 263 | let mut buf = buf; 264 | while !buf.is_empty() { 265 | match socket.write(buf).await { 266 | Ok(0) => panic!("write() returned Ok(0)"), 267 | Ok(n) => buf = &buf[n..], 268 | Err(e) => return Err(e), 269 | } 270 | } 271 | Ok(()) 272 | } 273 | -------------------------------------------------------------------------------- /i2c-sht31/src/sht3x.rs: -------------------------------------------------------------------------------- 1 | use bitflags::bitflags; 2 | use embedded_hal::delay::DelayNs; 3 | use embedded_hal::i2c::I2c; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct Sht3x { 7 | address: Address, 8 | delay: D, 9 | } 10 | 11 | // 2.2 Timing Specification for the Sensor System 12 | // Table 4 13 | // TODO: Support longer times needed with lower voltage (Table 5). 14 | const SOFT_RESET_TIME_MS: u8 = 1; 15 | 16 | // 4: Operation and Communication 17 | const COMMAND_WAIT_TIME_MS: u8 = 1; 18 | 19 | impl Sht3x { 20 | /// Creates a new driver. 21 | pub const fn new(address: Address, delay: D) -> Self { 22 | Self { address, delay } 23 | } 24 | 25 | /// Send an I2C command. 26 | fn command( 27 | &mut self, 28 | i2c: &mut I2C, 29 | command: Command, 30 | wait_time: Option, 31 | ) -> Result<(), Error> { 32 | let cmd_bytes = command.value().to_be_bytes(); 33 | i2c.write(self.address as u8, &cmd_bytes) 34 | .map_err(Error::I2c)?; 35 | 36 | self.delay 37 | .delay_ms(wait_time.unwrap_or(0).max(COMMAND_WAIT_TIME_MS).into()); 38 | 39 | Ok(()) 40 | } 41 | 42 | /// Take a temperature and humidity measurement. 43 | pub fn measure( 44 | &mut self, 45 | i2c: &mut I2C, 46 | cs: ClockStretch, 47 | rpt: Repeatability, 48 | ) -> Result> { 49 | self.command(i2c, Command::SingleShot(cs, rpt), Some(rpt.max_duration()))?; 50 | let mut buf = [0; 6]; 51 | i2c.read(self.address as u8, &mut buf).map_err(Error::I2c)?; 52 | 53 | let temperature = check_crc::([buf[0], buf[1]], buf[2]).map(convert_temperature)?; 54 | let humidity = check_crc::([buf[3], buf[4]], buf[5]).map(convert_humidity)?; 55 | 56 | Ok(Measurement { 57 | temperature, 58 | humidity, 59 | }) 60 | } 61 | 62 | /// Soft reset the sensor. 63 | pub fn reset(&mut self, i2c: &mut I2C) -> Result<(), Error> { 64 | self.command(i2c, Command::SoftReset, Some(SOFT_RESET_TIME_MS)) 65 | } 66 | 67 | /// Read the status register. 68 | pub fn status(&mut self, i2c: &mut I2C) -> Result> { 69 | self.command(i2c, Command::Status, None)?; 70 | let mut buf = [0; 3]; 71 | i2c.read(self.address as u8, &mut buf).map_err(Error::I2c)?; 72 | 73 | let status = check_crc::([buf[0], buf[1]], buf[2])?; 74 | Ok(Status::from_bits_truncate(status)) 75 | } 76 | 77 | /// Clear the status register. 78 | pub fn clear_status(&mut self, i2c: &mut I2C) -> Result<(), Error> { 79 | self.command(i2c, Command::ClearStatus, None) 80 | } 81 | } 82 | 83 | const fn convert_temperature(raw: u16) -> i32 { 84 | -4500 + (17500 * raw as i32) / 65535 85 | } 86 | 87 | const fn convert_humidity(raw: u16) -> u16 { 88 | ((10000 * raw as u32) / 65535) as u16 89 | } 90 | 91 | /// Compare the CRC of the input array to the given CRC checksum. 92 | fn check_crc(data: [u8; 2], crc: u8) -> Result> { 93 | let calculated_crc = crc8(data); 94 | 95 | if calculated_crc == crc { 96 | Ok(u16::from_be_bytes(data)) 97 | } else { 98 | Err(Error::Crc) 99 | } 100 | } 101 | 102 | /// Calculate the CRC8 checksum for the given input array. 103 | fn crc8(data: [u8; 2]) -> u8 { 104 | let mut crc: u8 = 0xff; 105 | 106 | for byte in data { 107 | crc ^= byte; 108 | 109 | for _ in 0..8 { 110 | if crc & 0x80 > 0 { 111 | crc = (crc << 1) ^ 0x31; 112 | } else { 113 | crc <<= 1; 114 | } 115 | } 116 | } 117 | 118 | crc 119 | } 120 | 121 | /// Errors 122 | #[derive(Debug)] 123 | pub enum Error { 124 | /// Wrong CRC 125 | Crc, 126 | /// I2C bus error 127 | I2c(E), 128 | } 129 | 130 | /// I2C address 131 | #[derive(Debug, Copy, Clone)] 132 | pub enum Address { 133 | /// Address pin held high 134 | High = 0x45, 135 | /// Address pin held low 136 | Low = 0x44, 137 | } 138 | 139 | /// Clock stretching 140 | #[derive(Debug)] 141 | pub enum ClockStretch { 142 | Enabled, 143 | Disabled, 144 | } 145 | 146 | /// Periodic data acquisition rate 147 | #[allow(non_camel_case_types, unused)] 148 | enum Rate { 149 | /// 0.5 measurements per second 150 | R0_5, 151 | /// 1 measurement per second 152 | R1, 153 | /// 2 measurements per second 154 | R2, 155 | /// 4 measurements per second 156 | R4, 157 | /// 10 measurements per second 158 | R10, 159 | } 160 | 161 | #[derive(Copy, Clone)] 162 | pub enum Repeatability { 163 | High, 164 | Medium, 165 | Low, 166 | } 167 | 168 | impl Repeatability { 169 | /// Maximum measurement duration in milliseconds 170 | const fn max_duration(&self) -> u8 { 171 | match *self { 172 | Repeatability::Low => 4, 173 | Repeatability::Medium => 6, 174 | Repeatability::High => 15, 175 | } 176 | } 177 | } 178 | 179 | #[allow(unused)] 180 | enum Command { 181 | SingleShot(ClockStretch, Repeatability), 182 | Periodic(Rate, Repeatability), 183 | FetchData, 184 | PeriodicWithART, 185 | Break, 186 | SoftReset, 187 | HeaterEnable, 188 | HeaterDisable, 189 | Status, 190 | ClearStatus, 191 | } 192 | 193 | impl Command { 194 | const fn value(&self) -> u16 { 195 | use ClockStretch::Disabled as CSDisabled; 196 | use ClockStretch::Enabled as CSEnabled; 197 | use Rate::*; 198 | use Repeatability::*; 199 | match *self { 200 | // 4.3 Measurement Commands for Single Shot Data Acquisition Mode 201 | // Table 8 202 | Command::SingleShot(CSEnabled, High) => 0x2C06, 203 | Command::SingleShot(CSEnabled, Medium) => 0x2C0D, 204 | Command::SingleShot(CSEnabled, Low) => 0x2C10, 205 | Command::SingleShot(CSDisabled, High) => 0x2400, 206 | Command::SingleShot(CSDisabled, Medium) => 0x240B, 207 | Command::SingleShot(CSDisabled, Low) => 0x2416, 208 | 209 | // 4.5 Measurement Commands for Periodic Data Acquisition Mode 210 | // Table 9 211 | Command::Periodic(R0_5, High) => 0x2032, 212 | Command::Periodic(R0_5, Medium) => 0x2024, 213 | Command::Periodic(R0_5, Low) => 0x202F, 214 | Command::Periodic(R1, High) => 0x2130, 215 | Command::Periodic(R1, Medium) => 0x2126, 216 | Command::Periodic(R1, Low) => 0x212D, 217 | Command::Periodic(R2, High) => 0x2236, 218 | Command::Periodic(R2, Medium) => 0x2220, 219 | Command::Periodic(R2, Low) => 0x222B, 220 | Command::Periodic(R4, High) => 0x2334, 221 | Command::Periodic(R4, Medium) => 0x2322, 222 | Command::Periodic(R4, Low) => 0x2329, 223 | Command::Periodic(R10, High) => 0x2737, 224 | Command::Periodic(R10, Medium) => 0x2721, 225 | Command::Periodic(R10, Low) => 0x272A, 226 | 227 | // 4.6 Readout of Measurement Results for Periodic Mode 228 | // Table 10 229 | Command::FetchData => 0xE000, 230 | 231 | // 4.7 ART command 232 | // Table 11 233 | Command::PeriodicWithART => 0x2B32, 234 | 235 | // 4.8 Break command 236 | // Table 12 237 | Command::Break => 0x3093, 238 | 239 | // 4.9 Reset 240 | // Table 13 241 | Command::SoftReset => 0x30A2, 242 | 243 | // 4.10 Heater 244 | // Table 15 245 | Command::HeaterEnable => 0x306D, 246 | Command::HeaterDisable => 0x3066, 247 | 248 | // 4.11 Status register 249 | // Table 16 250 | Command::Status => 0xF32D, 251 | // Table 18 252 | Command::ClearStatus => 0x3041, 253 | } 254 | } 255 | } 256 | 257 | #[derive(Debug)] 258 | pub struct Measurement { 259 | pub temperature: i32, 260 | pub humidity: u16, 261 | } 262 | 263 | bitflags! { 264 | /// Status register 265 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 266 | pub struct Status: u16 { 267 | /// Alert pending status 268 | const ALERT_PENDING = 1 << 15; 269 | /// Heater status 270 | const HEATER = 1 << 13; 271 | /// RH tracking alert 272 | const RH_TRACKING_ALERT = 1 << 11; 273 | /// T tracking alert 274 | const T_TRACKING_ALERT = 1 << 10; 275 | /// System reset detected 276 | const SYSTEM_RESET_DETECTED = 1 << 4; 277 | /// Command status 278 | const COMMAND = 1 << 1; 279 | /// Write data checksum status 280 | const WRITE_DATA_CHECKSUM = 1 << 0; 281 | } 282 | } 283 | 284 | #[cfg(test)] 285 | mod tests { 286 | use super::*; 287 | 288 | #[test] 289 | fn test_crc() { 290 | assert_eq!(crc8([0xBE, 0xEF]), 0x92); 291 | } 292 | } 293 | --------------------------------------------------------------------------------