commit 283a4bcd1434d1e773857c4a50bf766fda1b8561
parent 235dd59bdc9aaeae4ce3d243a4af9592382a750f
Author: Daniel Barlow <dan@telent.net>
Date: Mon, 19 Jan 2026 19:40:07 +0000
Add 'vendor/esp-hal-ota/' from commit '57adf08fef483420bf44389594dc3355e766e8ab'
git-subtree-dir: vendor/esp-hal-ota
git-subtree-mainline: 235dd59bdc9aaeae4ce3d243a4af9592382a750f
git-subtree-split: 57adf08fef483420bf44389594dc3355e766e8ab
Diffstat:
39 files changed, 3781 insertions(+), 0 deletions(-)
diff --git a/vendor/esp-hal-ota/.gitignore b/vendor/esp-hal-ota/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/vendor/esp-hal-ota/Cargo.lock b/vendor/esp-hal-ota/Cargo.lock
@@ -0,0 +1,215 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "defmt"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
+dependencies = [
+ "bitflags",
+ "defmt-macros",
+]
+
+[[package]]
+name = "defmt-macros"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
+dependencies = [
+ "defmt-parser",
+ "proc-macro-error2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "defmt-parser"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
+dependencies = [
+ "thiserror",
+]
+
+[[package]]
+name = "embedded-storage"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032"
+
+[[package]]
+name = "esp-hal-ota"
+version = "0.4.5"
+dependencies = [
+ "defmt",
+ "embedded-storage",
+ "esp32",
+ "esp32c2",
+ "esp32c3",
+ "esp32c6",
+ "esp32h2",
+ "esp32s2",
+ "esp32s3",
+ "log",
+]
+
+[[package]]
+name = "esp32"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b76170a463d18f888a1ad258031901036fd827a9ef126733053ba5f8739fb0c8"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32c2"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e62cf8932966b8d445b6f1832977b468178f0a84effb2e9fda89f60c24d45aa3"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32c3"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "356af3771d0d6536c735bf71136594f4d1cbb506abf6e0c51a6639e9bf4e7988"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32c6"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f5e511df672d79cd63365c92045135e01ba952b6bddd25b660baff5e1110f6b"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32h2"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed4a50bbd1380931e095e0973b9b12f782a9c481f2edf1f7c42e7eb4ff736d6d"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32s2"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98574d4c577fbe888fe3e6df7fc80d25a05624d9998f7d7de1500ae21fcca78f"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32s3"
+version = "0.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1810d8ee4845ef87542af981e38eb80ab531d0ef1061e1486014ab7af74c337a"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "log"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+
+[[package]]
+name = "proc-macro-error-attr2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "proc-macro-error2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
+dependencies = [
+ "proc-macro-error-attr2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "vcell"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
diff --git a/vendor/esp-hal-ota/Cargo.toml b/vendor/esp-hal-ota/Cargo.toml
@@ -0,0 +1,41 @@
+[package]
+name = "esp-hal-ota"
+version = "0.4.5"
+edition = "2024"
+license = "MIT"
+description = "OTA library for esp-hal"
+repository = "https://github.com/filipton/esp-hal-ota"
+
+[lib]
+
+[dependencies]
+embedded-storage = "0.3.1"
+log = { version = "0.4.28", optional = true }
+defmt = { version = "1.0.1", optional = true }
+
+esp32 = { version = "0.39.0", optional = true }
+
+esp32s2 = { version = "0.30.0", optional = true }
+esp32s3 = { version = "0.34.0", optional = true }
+
+esp32c2 = { version = "0.28.0", optional = true }
+esp32c3 = { version = "0.31.0", optional = true }
+esp32c6 = { version = "0.22.0", optional = true }
+
+esp32h2 = { version = "0.18.0", optional = true }
+
+[features]
+default = []
+log = ["dep:log"]
+defmt = ["dep:defmt"]
+
+esp32 = ["dep:esp32"]
+
+esp32s2 = ["dep:esp32s2"]
+esp32s3 = ["dep:esp32s3"]
+
+esp32c2 = ["dep:esp32c2"]
+esp32c3 = ["dep:esp32c3"]
+esp32c6 = ["dep:esp32c6"]
+
+esp32h2 = ["dep:esp32h2"]
diff --git a/vendor/esp-hal-ota/LICENSE b/vendor/esp-hal-ota/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) [year] [fullname]
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/esp-hal-ota/README.md b/vendor/esp-hal-ota/README.md
@@ -0,0 +1,77 @@
+# esp-hal-ota
+OTA for esp-hal (no-std).
+
+[](https://crates.io/crates/esp-hal-ota)
+[]()
+
+## Limitations
+I cannot test if it works properly on esp32s2,esp32c2,esp32c6 and esp32h2.
+But esp32s3, esp32c3 and esp32 are working perfectly fine.
+
+## Features
+- Obviously OTA updates
+- Dynamic partitions reading (so no macros, no reading from partitions.csv) - fully automatic
+- Checking currently booted partition (using some pointer magic from ESP-IDF)
+- CRC32 verification
+
+## Getting started
+- Create `partitions.csv` file in project root (copy `partitions.csv.template` file)
+- In your project edit `./.cargo/config.toml` file and append `--partition-table ./partitions.csv` to the `runner` attribute
+- Optionally append `--erase-parts otadata` to `./cargo/config.toml` to fix some ota issues
+
+```toml
+[target.xtensa-esp32s3-none-elf]
+runner = "espflash flash --monitor --partition-table ./partitions.csv --erase-parts otadata"
+```
+
+## Example
+To see real-world example look at `./examples` and `./simple-ota-server` dirs.
+
+```rust
+let flash_size = 1234; // get it from OTA server
+let target_crc = 65436743; // get it from OTA server
+
+let mut ota = Ota::new(FlashStorage::new()).unwrap();
+ota.ota_begin(flash_size, target_crc);
+
+let mut buf = [0; 4096];
+loop {
+ let n = read_next_chunk(&mut buf);
+ if n == 0 {
+ break;
+ }
+
+ let res = ota.ota_write_chunk(&buf[..n]);
+ if res == Ok(true) { // end of flash
+ if ota.ota_flush(true, true).is_ok() { // true if you want to verify crc reading flash, and true if you want rollbacks
+ esp_hal::reset::software_reset();
+ }
+ }
+
+ let progress = (ota.get_ota_progress() * 100) as u8;
+ log::info!("progress: {}%", progress);
+}
+```
+
+### Running example
+- You can compile your .bin file using esp-flash
+```bash
+espflash save-image --chip esp32c3 ./target/riscv32imc-unknown-none-elf/debug/esp-hal-ota-example ../simple-ota-server/firmware.bin
+```
+
+This will generate .bin file from build file for chip.
+
+## Todo
+- [x] Fully working library
+- [x] Simple example
+- [x] Better errors
+- [x] Other esp32's (like esp32c3, esp32s2, etc..)
+- [x] Rollbacks
+
+## Resources
+- https://github.com/esp-rs/espflash (this led me to esp-idf-part)
+- https://github.com/esp-rs/esp-idf-part
+- https://github.com/espressif/esp-idf/blob/master/docs/en/api-reference/system/ota.rst (especially Python API)
+- https://github.com/python/cpython/blob/main/Modules/binascii.c (internal_crc32)
+- https://github.com/espressif/esp-idf/blob/master/components/app_update/esp_ota_ops.c#L552 (esp get current partition (paddr))
+- https://github.com/bjoernQ/esp32c3-ota-experiment (i've only seen this after first experiments, so haven't looked at it yet)
diff --git a/vendor/esp-hal-ota/examples/.cargo/config.toml b/vendor/esp-hal-ota/examples/.cargo/config.toml
@@ -0,0 +1,25 @@
+[alias]
+esp32c3 = "run --no-default-features --features=esp32c3 --target=riscv32imc-unknown-none-elf"
+esp32s3 = "run --no-default-features --features=esp32s3 --target=xtensa-esp32s3-none-elf"
+esp32 = "run --no-default-features --features=esp32 --target=xtensa-esp32-none-elf"
+
+[target.'cfg(target_arch = "riscv32")']
+runner = "espflash flash --monitor --partition-table ./partitions.csv --erase-parts otadata"
+rustflags = [
+ "-C", "force-frame-pointers",
+]
+
+[target.'cfg(target_arch = "xtensa")']
+runner = "espflash flash --monitor --partition-table ./partitions.csv --erase-parts otadata"
+rustflags = [
+ "-C", "link-arg=-nostartfiles",
+]
+
+[build]
+target = "xtensa-esp32s3-none-elf" #default esp32s3
+
+[env]
+ESP_LOG="INFO"
+
+[unstable]
+build-std = ["core", "alloc"]
diff --git a/vendor/esp-hal-ota/examples/.env.example b/vendor/esp-hal-ota/examples/.env.example
@@ -0,0 +1,3 @@
+SSID=
+PSK=
+OTA_IP=
diff --git a/vendor/esp-hal-ota/examples/.gitignore b/vendor/esp-hal-ota/examples/.gitignore
@@ -0,0 +1,12 @@
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
+.env
+out*.bin
diff --git a/vendor/esp-hal-ota/examples/Cargo.lock b/vendor/esp-hal-ota/examples/Cargo.lock
@@ -0,0 +1,1758 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "allocator-api2"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78200ac3468a57d333cd0ea5dd398e25111194dcacd49208afca95c629a6311d"
+
+[[package]]
+name = "anyhow"
+version = "1.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "bitfield"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db1bcd90f88eabbf0cadbfb87a45bceeaebcd3b4bc9e43da379cd2ef0162590d"
+dependencies = [
+ "bitfield-macros",
+]
+
+[[package]]
+name = "bitfield-macros"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3787a07661997bfc05dd3431e379c0188573f78857080cf682e1393ab8e4d64c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bt-hci"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb938a3b4c5cc6c2409275bad789c0346a0495fa071a0acc5d72b9bd3175a2f7"
+dependencies = [
+ "btuuid",
+ "embassy-sync 0.7.2",
+ "embedded-io 0.6.1",
+ "embedded-io-async 0.6.1",
+ "futures-intrusive",
+ "heapless 0.8.0",
+]
+
+[[package]]
+name = "btuuid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0acfef8a77a02866e04f7e2ad3f4c7b32d575696c49c4bbad742b4aecb8e4a3"
+
+[[package]]
+name = "bytemuck"
+version = "1.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
+
+[[package]]
+name = "const-default"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "darling"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "delegate"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9b6483c2bbed26f97861cf57651d4f2b731964a28cd2257f934a4b452480d21"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "document-features"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
+[[package]]
+name = "embassy-embedded-hal"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8"
+dependencies = [
+ "embassy-futures",
+ "embassy-hal-internal",
+ "embassy-sync 0.7.2",
+ "embedded-hal 0.2.7",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+ "embedded-storage",
+ "embedded-storage-async",
+ "nb 1.1.0",
+]
+
+[[package]]
+name = "embassy-executor"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06070468370195e0e86f241c8e5004356d696590a678d47d6676795b2e439c6b"
+dependencies = [
+ "critical-section",
+ "document-features",
+ "embassy-executor-macros",
+ "embassy-executor-timer-queue",
+]
+
+[[package]]
+name = "embassy-executor-macros"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfdddc3a04226828316bf31393b6903ee162238576b1584ee2669af215d55472"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "embassy-executor-timer-queue"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c"
+
+[[package]]
+name = "embassy-futures"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01"
+
+[[package]]
+name = "embassy-hal-internal"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "embassy-net"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0558a231a47e7d4a06a28b5278c92e860f1200f24821d2f365a2f40fe3f3c7b2"
+dependencies = [
+ "document-features",
+ "embassy-net-driver",
+ "embassy-sync 0.7.2",
+ "embassy-time",
+ "embedded-io-async 0.6.1",
+ "embedded-nal-async",
+ "heapless 0.8.0",
+ "managed",
+ "smoltcp",
+]
+
+[[package]]
+name = "embassy-net-driver"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d"
+
+[[package]]
+name = "embassy-sync"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049"
+dependencies = [
+ "cfg-if",
+ "critical-section",
+ "embedded-io-async 0.6.1",
+ "futures-sink",
+ "futures-util",
+ "heapless 0.8.0",
+]
+
+[[package]]
+name = "embassy-sync"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b"
+dependencies = [
+ "cfg-if",
+ "critical-section",
+ "embedded-io-async 0.6.1",
+ "futures-core",
+ "futures-sink",
+ "heapless 0.8.0",
+]
+
+[[package]]
+name = "embassy-time"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65"
+dependencies = [
+ "cfg-if",
+ "critical-section",
+ "document-features",
+ "embassy-time-driver",
+ "embedded-hal 0.2.7",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+ "futures-core",
+]
+
+[[package]]
+name = "embassy-time-driver"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6"
+dependencies = [
+ "document-features",
+]
+
+[[package]]
+name = "embassy-time-queue-utils"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80e2ee86063bd028a420a5fb5898c18c87a8898026da1d4c852af2c443d0a454"
+dependencies = [
+ "embassy-executor-timer-queue",
+ "heapless 0.8.0",
+]
+
+[[package]]
+name = "embassy-usb-driver"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a"
+dependencies = [
+ "embedded-io-async 0.6.1",
+]
+
+[[package]]
+name = "embassy-usb-synopsys-otg"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "288751f8eaa44a5cf2613f13cee0ca8e06e6638cb96e897e6834702c79084b23"
+dependencies = [
+ "critical-section",
+ "embassy-sync 0.7.2",
+ "embassy-usb-driver",
+]
+
+[[package]]
+name = "embedded-can"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438"
+dependencies = [
+ "nb 1.1.0",
+]
+
+[[package]]
+name = "embedded-hal"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
+dependencies = [
+ "nb 0.1.3",
+ "void",
+]
+
+[[package]]
+name = "embedded-hal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
+
+[[package]]
+name = "embedded-hal-async"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
+dependencies = [
+ "embedded-hal 1.0.0",
+]
+
+[[package]]
+name = "embedded-io"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+
+[[package]]
+name = "embedded-io"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7"
+
+[[package]]
+name = "embedded-io-async"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f"
+dependencies = [
+ "embedded-io 0.6.1",
+]
+
+[[package]]
+name = "embedded-io-async"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0"
+dependencies = [
+ "embedded-io 0.7.1",
+]
+
+[[package]]
+name = "embedded-nal"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c56a28be191a992f28f178ec338a0bf02f63d7803244add736d026a471e6ed77"
+dependencies = [
+ "nb 1.1.0",
+]
+
+[[package]]
+name = "embedded-nal-async"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76959917cd2b86f40a98c28dd5624eddd1fa69d746241c8257eac428d83cb211"
+dependencies = [
+ "embedded-io-async 0.6.1",
+ "embedded-nal",
+]
+
+[[package]]
+name = "embedded-storage"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032"
+
+[[package]]
+name = "embedded-storage-async"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc"
+dependencies = [
+ "embedded-storage",
+]
+
+[[package]]
+name = "enumset"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11a6b7c3d347de0a9f7bfd2f853be43fe32fa6fac30c70f6d6d67a1e936b87ee"
+dependencies = [
+ "enumset_derive",
+]
+
+[[package]]
+name = "enumset_derive"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6da3ea9e1d1a3b1593e15781f930120e72aa7501610b2f82e5b6739c72e8eac5"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "esp-alloc"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "641e43d6a60244429117ef2fa7a47182120c7561336ea01f6fb08d634f46bae1"
+dependencies = [
+ "allocator-api2",
+ "cfg-if",
+ "document-features",
+ "enumset",
+ "esp-config",
+ "esp-sync",
+ "linked_list_allocator",
+ "rlsf",
+]
+
+[[package]]
+name = "esp-backtrace"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdd8a541e17aa485d82df547f03c77b89f78cb110f59dea67cc90733d67e3678"
+dependencies = [
+ "cfg-if",
+ "document-features",
+ "esp-config",
+ "esp-metadata-generated",
+ "esp-println",
+ "heapless 0.9.1",
+ "riscv",
+ "semihosting",
+ "xtensa-lx",
+]
+
+[[package]]
+name = "esp-bootloader-esp-idf"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c319c4a24fb44ef4c5f9854ff3dc6010eb8f15a6613d024227aa2355e3f6a334"
+dependencies = [
+ "cfg-if",
+ "document-features",
+ "embedded-storage",
+ "esp-config",
+ "esp-rom-sys",
+ "jiff",
+ "log",
+ "strum",
+]
+
+[[package]]
+name = "esp-config"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "289fde78fff1ff500e81efbdf958b1dae1614eacc61cc5560b0a3e03a25f266e"
+dependencies = [
+ "document-features",
+ "esp-metadata-generated",
+ "serde",
+ "serde_yaml",
+ "somni-expr",
+]
+
+[[package]]
+name = "esp-hal"
+version = "1.0.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f75242d788e67fc7ce51308019c0ff5d5103f989721577bb566b02710ef1ba79"
+dependencies = [
+ "bitfield",
+ "bitflags 2.9.1",
+ "bytemuck",
+ "cfg-if",
+ "critical-section",
+ "delegate",
+ "digest",
+ "document-features",
+ "embassy-embedded-hal",
+ "embassy-futures",
+ "embassy-sync 0.7.2",
+ "embassy-usb-driver",
+ "embassy-usb-synopsys-otg",
+ "embedded-can",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+ "embedded-io 0.6.1",
+ "embedded-io 0.7.1",
+ "embedded-io-async 0.6.1",
+ "embedded-io-async 0.7.0",
+ "enumset",
+ "esp-config",
+ "esp-hal-procmacros",
+ "esp-metadata-generated",
+ "esp-riscv-rt",
+ "esp-rom-sys",
+ "esp-sync",
+ "esp-synopsys-usb-otg",
+ "esp32",
+ "esp32c2",
+ "esp32c3",
+ "esp32c6",
+ "esp32h2",
+ "esp32s2",
+ "esp32s3",
+ "fugit",
+ "instability",
+ "nb 1.1.0",
+ "paste",
+ "portable-atomic",
+ "rand_core 0.6.4",
+ "rand_core 0.9.3",
+ "riscv",
+ "sha1",
+ "sha2",
+ "strum",
+ "ufmt-write",
+ "xtensa-lx",
+ "xtensa-lx-rt",
+]
+
+[[package]]
+name = "esp-hal-ota"
+version = "0.4.5"
+dependencies = [
+ "embedded-storage",
+ "esp32",
+ "esp32c3",
+ "esp32s3",
+ "log",
+]
+
+[[package]]
+name = "esp-hal-ota-example"
+version = "0.1.0"
+dependencies = [
+ "dotenvy",
+ "embassy-executor",
+ "embassy-net",
+ "embassy-time",
+ "esp-alloc",
+ "esp-backtrace",
+ "esp-bootloader-esp-idf",
+ "esp-hal",
+ "esp-hal-ota",
+ "esp-println",
+ "esp-radio",
+ "esp-rtos",
+ "esp-storage",
+ "log",
+ "static_cell",
+]
+
+[[package]]
+name = "esp-hal-procmacros"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fd82a6506fb08d53a1086d165d92f085717aa9c59e67ac87a9e6f8acdcf6897"
+dependencies = [
+ "document-features",
+ "object",
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+ "termcolor",
+]
+
+[[package]]
+name = "esp-metadata-generated"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b18b1787dd3adea642fb529dd83fe558a08ace365bbaede4643a8959992900f4"
+
+[[package]]
+name = "esp-phy"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62199c3e50eefcf53b8f3c690946582a124f7137b45bd1b14eb4b90a3fec2dd7"
+dependencies = [
+ "cfg-if",
+ "document-features",
+ "esp-config",
+ "esp-hal",
+ "esp-metadata-generated",
+ "esp-sync",
+ "esp-wifi-sys",
+]
+
+[[package]]
+name = "esp-println"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dcd18cbb132db6eb30d7c96bd831c3b6916894210f4528321f69fa66178b331"
+dependencies = [
+ "document-features",
+ "esp-metadata-generated",
+ "esp-sync",
+ "log",
+ "portable-atomic",
+]
+
+[[package]]
+name = "esp-radio"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d83744f57d19a7190a538ad42025da7f53940c3aca71cbcd92275095d671e254"
+dependencies = [
+ "allocator-api2",
+ "bt-hci",
+ "cfg-if",
+ "document-features",
+ "embassy-net-driver",
+ "embedded-io 0.6.1",
+ "embedded-io 0.7.1",
+ "embedded-io-async 0.6.1",
+ "embedded-io-async 0.7.0",
+ "enumset",
+ "esp-alloc",
+ "esp-config",
+ "esp-hal",
+ "esp-hal-procmacros",
+ "esp-metadata-generated",
+ "esp-phy",
+ "esp-radio-rtos-driver",
+ "esp-sync",
+ "esp-wifi-sys",
+ "heapless 0.9.1",
+ "instability",
+ "num-derive",
+ "num-traits",
+ "portable-atomic",
+ "portable_atomic_enum",
+ "xtensa-lx-rt",
+]
+
+[[package]]
+name = "esp-radio-rtos-driver"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab031e544f6bc086c2d7aba89276e6a47ce6bb5614ae3c88a1c12a4ab4f8f25c"
+
+[[package]]
+name = "esp-riscv-rt"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "502744a5b1e7268d27fd2a4e56ad45efe42ead517d6c517a6961540de949b0ee"
+dependencies = [
+ "document-features",
+ "riscv",
+ "riscv-rt",
+]
+
+[[package]]
+name = "esp-rom-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01bafc39f59d56610b38ed0f63b16abeb8b357b8f546507d0d6c50c1a494f530"
+dependencies = [
+ "cfg-if",
+ "document-features",
+ "esp-metadata-generated",
+]
+
+[[package]]
+name = "esp-rtos"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7844233ccdf92eaf4134c08c56c1b4a874f7d59e6249c579e912ecc6c9312fda"
+dependencies = [
+ "allocator-api2",
+ "cfg-if",
+ "document-features",
+ "embassy-executor",
+ "embassy-sync 0.7.2",
+ "embassy-time-driver",
+ "embassy-time-queue-utils",
+ "esp-config",
+ "esp-hal",
+ "esp-hal-procmacros",
+ "esp-metadata-generated",
+ "esp-radio-rtos-driver",
+ "esp-sync",
+ "portable-atomic",
+]
+
+[[package]]
+name = "esp-storage"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ac4c20d28188fc31ad34008ad3a94dd7d828e5fef0c83c265bdb7dac168d512"
+dependencies = [
+ "document-features",
+ "embedded-storage",
+ "esp-hal",
+ "esp-hal-procmacros",
+ "esp-metadata-generated",
+ "esp-rom-sys",
+ "esp-sync",
+]
+
+[[package]]
+name = "esp-sync"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b977b028ae5959f0b2daf6602a1d751723b2d329c7251daf869ad382c8ed1543"
+dependencies = [
+ "cfg-if",
+ "document-features",
+ "embassy-sync 0.6.2",
+ "embassy-sync 0.7.2",
+ "esp-metadata-generated",
+ "riscv",
+ "xtensa-lx",
+]
+
+[[package]]
+name = "esp-synopsys-usb-otg"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8938451cb19032f13365328ea66ab38c8d16deecdf322067442297110eb74468"
+dependencies = [
+ "critical-section",
+ "embedded-hal 0.2.7",
+ "ral-registers",
+ "usb-device",
+ "vcell",
+]
+
+[[package]]
+name = "esp-wifi-sys"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89b6544f6f0cb86169d1f93ba2101a8d50358a040c5043676ed86b793e09b12c"
+dependencies = [
+ "anyhow",
+]
+
+[[package]]
+name = "esp32"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b76170a463d18f888a1ad258031901036fd827a9ef126733053ba5f8739fb0c8"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "esp32c2"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e62cf8932966b8d445b6f1832977b468178f0a84effb2e9fda89f60c24d45aa3"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "esp32c3"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "356af3771d0d6536c735bf71136594f4d1cbb506abf6e0c51a6639e9bf4e7988"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "esp32c6"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f5e511df672d79cd63365c92045135e01ba952b6bddd25b660baff5e1110f6b"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "esp32h2"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed4a50bbd1380931e095e0973b9b12f782a9c481f2edf1f7c42e7eb4ff736d6d"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "esp32s2"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98574d4c577fbe888fe3e6df7fc80d25a05624d9998f7d7de1500ae21fcca78f"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "esp32s3"
+version = "0.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1810d8ee4845ef87542af981e38eb80ab531d0ef1061e1486014ab7af74c337a"
+dependencies = [
+ "critical-section",
+ "vcell",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "fugit"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
+dependencies = [
+ "gcd",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-intrusive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
+dependencies = [
+ "futures-core",
+ "lock_api",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "gcd"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "hash32"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
+
+[[package]]
+name = "heapless"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
+dependencies = [
+ "hash32",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "heapless"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1edcd5a338e64688fbdcb7531a846cfd3476a54784dcb918a0844682bc7ada5"
+dependencies = [
+ "hash32",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "indexmap"
+version = "2.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "indoc"
+version = "2.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
+
+[[package]]
+name = "instability"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a"
+dependencies = [
+ "darling",
+ "indoc",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "jiff"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
+dependencies = [
+ "jiff-static",
+ "log",
+ "portable-atomic",
+ "portable-atomic-util",
+ "serde",
+]
+
+[[package]]
+name = "jiff-static"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.177"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
+
+[[package]]
+name = "linked_list_allocator"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
+
+[[package]]
+name = "litrs"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
+
+[[package]]
+name = "lock_api"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+
+[[package]]
+name = "managed"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "nb"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
+dependencies = [
+ "nb 1.1.0",
+]
+
+[[package]]
+name = "nb"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
+
+[[package]]
+name = "num-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "object"
+version = "0.37.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "portable-atomic"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
+
+[[package]]
+name = "portable-atomic-util"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
+dependencies = [
+ "portable-atomic",
+]
+
+[[package]]
+name = "portable_atomic_enum"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30d48f60c43e0120bb2bb48589a16d4bed2f4b911be41e299f2d0fc0e0e20885"
+dependencies = [
+ "portable-atomic",
+ "portable_atomic_enum_macros",
+]
+
+[[package]]
+name = "portable_atomic_enum_macros"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a33fa6ec7f2047f572d49317cca19c87195de99c6e5b6ee492da701cfe02b053"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
+dependencies = [
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "ral-registers"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46b71a9d9206e8b46714c74255adcaea8b11e0350c1d8456165073c3f75fc81a"
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
+[[package]]
+name = "rand_core"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+
+[[package]]
+name = "riscv"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b05cfa3f7b30c84536a9025150d44d26b8e1cc20ddf436448d74cd9591eefb25"
+dependencies = [
+ "critical-section",
+ "embedded-hal 1.0.0",
+ "paste",
+ "riscv-macros",
+ "riscv-pac",
+]
+
+[[package]]
+name = "riscv-macros"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d323d13972c1b104aa036bc692cd08b822c8bbf23d79a27c526095856499799"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "riscv-pac"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436"
+
+[[package]]
+name = "riscv-rt"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d07b9f3a0eff773fc4df11f44ada4fa302e529bff4b7fe7e6a4b98a65ce9174"
+dependencies = [
+ "riscv",
+ "riscv-pac",
+ "riscv-rt-macros",
+ "riscv-target-parser",
+]
+
+[[package]]
+name = "riscv-rt-macros"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15c3138fdd8d128b2d81829842a3e0ce771b3712f7b6318ed1476b0695e7d330"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "riscv-target-parser"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1376b15f3ff160e9b1e8ea564ce427f2f6fcf77528cc0a8bf405cb476f9cea7"
+
+[[package]]
+name = "rlsf"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf"
+dependencies = [
+ "cfg-if",
+ "const-default",
+ "libc",
+ "svgbobdoc",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
+
+[[package]]
+name = "ryu"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "semihosting"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3e1c7d2b77d80283c750a39c52f1ab4d17234e8f30bca43550f5b2375f41d5f"
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "serde_yaml"
+version = "0.9.34+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
+dependencies = [
+ "indexmap",
+ "itoa",
+ "ryu",
+ "serde",
+ "unsafe-libyaml",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "smoltcp"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb"
+dependencies = [
+ "bitflags 1.3.2",
+ "byteorder",
+ "cfg-if",
+ "heapless 0.8.0",
+ "managed",
+]
+
+[[package]]
+name = "somni-expr"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ed9b7648d5e8b2df6c5e49940c54bcdd2b4dd71eafc6e8f1c714eb4581b0f53"
+dependencies = [
+ "somni-parser",
+]
+
+[[package]]
+name = "somni-parser"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74ee90f60ebcade244355ed4ff4077e364b251508c3462af386a9ee96c5a5492"
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "static_cell"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23"
+dependencies = [
+ "portable-atomic",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "strum"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
+dependencies = [
+ "strum_macros",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 2.0.101",
+]
+
+[[package]]
+name = "svgbobdoc"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50"
+dependencies = [
+ "base64",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "unicode-width",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.23.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d"
+dependencies = [
+ "indexmap",
+ "toml_datetime",
+ "toml_parser",
+ "winnow",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
+dependencies = [
+ "winnow",
+]
+
+[[package]]
+name = "typenum"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
+
+[[package]]
+name = "ufmt-write"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+
+[[package]]
+name = "unsafe-libyaml"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
+
+[[package]]
+name = "usb-device"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6"
+dependencies = [
+ "heapless 0.8.0",
+ "portable-atomic",
+]
+
+[[package]]
+name = "vcell"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "winnow"
+version = "0.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "xtensa-lx"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e012d667b0aa6d2592ace8ef145a98bff3e76cca7a644f4181ecd7a916ed289b"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
+name = "xtensa-lx-rt"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8709f037fb123fe7ff146d2bce86f9dc0dfc53045c016bfd9d703317b6502845"
+dependencies = [
+ "document-features",
+ "xtensa-lx",
+ "xtensa-lx-rt-proc-macros",
+]
+
+[[package]]
+name = "xtensa-lx-rt-proc-macros"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96fb42cd29c42f8744c74276e9f5bee7b06685bbe5b88df891516d72cb320450"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
diff --git a/vendor/esp-hal-ota/examples/Cargo.toml b/vendor/esp-hal-ota/examples/Cargo.toml
@@ -0,0 +1,45 @@
+[package]
+name = "esp-hal-ota-example"
+version = "0.1.0"
+authors = ["filipton <filipton12@gmail.com>"]
+edition = "2024"
+license = "MIT OR Apache-2.0"
+
+[dependencies]
+esp-backtrace = { version = "0.18.0", features = [ "panic-handler", "println" ] }
+esp-hal = { version = "1.0.0-rc.1", features = ["unstable"] }
+esp-println = { version = "0.16.0", features = ["log-04"] }
+log = { version = "0.4.28" }
+esp-radio = { version = "0.16.0", features = [ "unstable", "wifi", "ble" ] }
+esp-rtos = { version = "0.1.0", features = ["esp-radio", "embassy"] }
+embassy-executor = { version = "0.9.1", package = "embassy-executor", features = ["arch-riscv32"] }
+embassy-net = { version = "0.7.1", features = ["tcp", "udp", "dhcpv4", "medium-ethernet"] }
+embassy-time = { version = "0.5.0" }
+esp-storage = { version = "0.8.0", features = [] }
+esp-hal-ota = { path = "../", features = ["log"] }
+static_cell = { version = "2.1.1", features = ["nightly"] }
+esp-alloc = "0.9.0"
+esp-bootloader-esp-idf = { version = "0.3.0", features = ["log-04"] }
+
+[build-dependencies]
+dotenvy = "0.15.7"
+
+[profile.dev]
+# Rust debug is too slow.
+# For debug builds always builds with some optimization
+opt-level = "s"
+
+[profile.release]
+codegen-units = 1 # LLVM can perform better optimizations using a single thread
+debug = 2
+debug-assertions = false
+incremental = false
+lto = 'fat'
+opt-level = 2
+overflow-checks = false
+
+[features]
+default = ["esp32s3"]
+esp32s3 = ["esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-println/esp32s3", "esp-radio/esp32s3", "esp-rtos/esp32s3", "esp-storage/esp32s3", "esp-hal-ota/esp32s3", "esp-bootloader-esp-idf/esp32s3"]
+esp32c3 = ["esp-backtrace/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-radio/esp32c3", "esp-rtos/esp32c3", "esp-storage/esp32c3", "esp-hal-ota/esp32c3", "esp-bootloader-esp-idf/esp32c3"]
+esp32 = ["esp-backtrace/esp32", "esp-hal/esp32", "esp-println/esp32", "esp-radio/esp32", "esp-rtos/esp32", "esp-storage/esp32", "esp-hal-ota/esp32", "esp-bootloader-esp-idf/esp32"]
diff --git a/vendor/esp-hal-ota/examples/build.rs b/vendor/esp-hal-ota/examples/build.rs
@@ -0,0 +1,10 @@
+fn main() {
+ println!("cargo:rerun-if-changed=*.env*");
+ if let Ok(mut iter) = dotenvy::dotenv_iter() {
+ while let Some(Ok((key, value))) = iter.next() {
+ println!("cargo:rustc-env={key}={value}");
+ }
+ }
+
+ println!("cargo:rustc-link-arg-bins=-Tlinkall.x");
+}
diff --git a/vendor/esp-hal-ota/examples/esp-ota-test.py b/vendor/esp-hal-ota/examples/esp-ota-test.py
@@ -0,0 +1,16 @@
+import sys
+import os
+
+idf_path = os.environ["IDF_PATH"] # get value of IDF_PATH from environment
+otatool_dir = os.path.join(idf_path, "components", "app_update") # otatool.py lives in $IDF_PATH/components/app_update
+
+sys.path.append(otatool_dir) # this enables Python to find otatool module
+from otatool import * # import all names inside otatool module
+
+target = OtatoolTarget("/dev/ttyACM0")
+target.switch_ota_partition(0)
+#print(target._get_otadata_info())
+
+#target.erase_otadata()
+#target.erase_ota_partition(1)
+#target.switch_ota_partition(1)
diff --git a/vendor/esp-hal-ota/examples/partitions.csv b/vendor/esp-hal-ota/examples/partitions.csv
@@ -0,0 +1,8 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x4000,
+otadata, data, ota, 0xd000, 0x2000,
+phy_init, data, phy, 0xf000, 0x1000,
+factory, app, factory, 0x10000, 0x100000,
+ota_0, app, ota_0, 0x110000, 0x100000,
+ota_1, app, ota_1, 0x210000, 0x100000,
+#ota_2, app, ota_2, 0x310000, 0x10000,
diff --git a/vendor/esp-hal-ota/examples/rust-toolchain.toml b/vendor/esp-hal-ota/examples/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+channel = "esp"
diff --git a/vendor/esp-hal-ota/examples/src/main.rs b/vendor/esp-hal-ota/examples/src/main.rs
@@ -0,0 +1,267 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+extern crate alloc;
+use core::str::FromStr;
+use embassy_executor::Spawner;
+use embassy_net::{Config, Runner, Stack, StackResources, tcp::TcpSocket};
+use embassy_time::{Duration, Timer};
+use esp_backtrace as _;
+use esp_hal::timer::timg::TimerGroup;
+use esp_hal_ota::Ota;
+use esp_radio::{
+ Controller,
+ wifi::{ClientConfig, ModeConfig, WifiController, WifiDevice, WifiEvent, WifiStaState},
+};
+use esp_storage::FlashStorage;
+
+const WIFI_SSID: &'static str = env!("SSID");
+const WIFI_PSK: &'static str = env!("PSK");
+const OTA_SERVER_IP: &'static str = env!("OTA_IP");
+
+const RX_BUFFER_SIZE: usize = 16384;
+const TX_BUFFER_SIZE: usize = 16384;
+static mut TX_BUFF: [u8; TX_BUFFER_SIZE] = [0; TX_BUFFER_SIZE];
+static mut RX_BUFF: [u8; RX_BUFFER_SIZE] = [0; RX_BUFFER_SIZE];
+
+macro_rules! mk_static {
+ ($t:ty,$val:expr) => {{
+ static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
+ #[deny(unused_attributes)]
+ let x = STATIC_CELL.uninit().write(($val));
+ x
+ }};
+}
+
+esp_bootloader_esp_idf::esp_app_desc!();
+
+#[esp_rtos::main]
+async fn main(spawner: Spawner) {
+ #[cfg(not(feature = "esp32"))]
+ {
+ esp_alloc::heap_allocator!(size: 150 * 1024);
+ }
+
+ #[cfg(feature = "esp32")]
+ {
+ static mut HEAP: core::mem::MaybeUninit<[u8; 30 * 1024]> = core::mem::MaybeUninit::uninit();
+
+ #[unsafe(link_section = ".dram2_uninit")]
+ static mut HEAP2: core::mem::MaybeUninit<[u8; 64 * 1024]> =
+ core::mem::MaybeUninit::uninit();
+
+ unsafe {
+ #[allow(static_mut_refs)]
+ esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new(
+ HEAP.as_mut_ptr() as *mut u8,
+ core::mem::size_of_val(&*core::ptr::addr_of!(HEAP)),
+ esp_alloc::MemoryCapability::Internal.into(),
+ ));
+
+ #[allow(static_mut_refs)]
+ esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new(
+ HEAP2.as_mut_ptr() as *mut u8,
+ core::mem::size_of_val(&*core::ptr::addr_of!(HEAP2)),
+ esp_alloc::MemoryCapability::Internal.into(),
+ ));
+ }
+ }
+
+ let peripherals = esp_hal::init(esp_hal::Config::default());
+ //let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
+
+ esp_println::logger::init_logger_from_env();
+ //log::set_max_level(log::LevelFilter::Info); // only for esp32s3??
+
+ let timg0 = TimerGroup::new(peripherals.TIMG0);
+
+ #[cfg(any(feature = "esp32s3", feature = "esp32"))]
+ esp_rtos::start(timg0.timer0);
+
+ #[cfg(feature = "esp32c3")]
+ let software_interrupt =
+ esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
+
+ #[cfg(feature = "esp32c3")]
+ esp_rtos::start(timg0.timer0, software_interrupt.software_interrupt0);
+
+ let init = &*mk_static!(Controller<'static>, esp_radio::init().unwrap());
+
+ let wifi = peripherals.WIFI;
+ let (controller, interfaces) = esp_radio::wifi::new(&init, wifi, Default::default()).unwrap();
+
+ let config = Config::dhcpv4(Default::default());
+ let seed = 69420;
+
+ let (stack, runner) = embassy_net::new(
+ interfaces.sta,
+ config,
+ {
+ static STATIC_CELL: static_cell::StaticCell<StackResources<3>> =
+ static_cell::StaticCell::new();
+ STATIC_CELL.uninit().write(StackResources::<3>::new())
+ },
+ seed,
+ );
+
+ spawner
+ .spawn(connection(controller, stack))
+ .expect("connection spawn");
+ spawner.spawn(net_task(runner)).expect("net task spawn");
+
+ // mark ota partition valid
+ {
+ let mut ota = Ota::new(FlashStorage::new(unsafe {
+ peripherals.FLASH.clone_unchecked()
+ }))
+ .expect("Cannot create ota");
+ _ = ota.ota_mark_app_valid(); //do not unwrap here if using factory/test partition
+ }
+
+ loop {
+ log::info!("Wait for wifi!");
+ Timer::after(Duration::from_secs(1)).await;
+
+ if let Some(config) = stack.config_v4() {
+ log::info!("Got IP: {}", config.address);
+ break;
+ }
+ }
+
+ let mut socket = unsafe {
+ TcpSocket::new(
+ stack,
+ &mut *core::ptr::addr_of_mut!(RX_BUFF),
+ &mut *core::ptr::addr_of_mut!(TX_BUFF),
+ )
+ };
+
+ let ip = embassy_net::IpEndpoint::from_str(OTA_SERVER_IP).expect("Wrong ip addr");
+ socket.connect(ip).await.expect("Cannot connect!");
+ let mut ota_buff = [0; 4096 * 2];
+ socket
+ .read(&mut ota_buff[..4])
+ .await
+ .expect("Cannot read firmware size!");
+ let flash_size = u32::from_le_bytes(ota_buff[..4].try_into().unwrap());
+
+ socket
+ .read(&mut ota_buff[..4])
+ .await
+ .expect("Cannot read target crc!");
+ let target_crc = u32::from_le_bytes(ota_buff[..4].try_into().unwrap());
+
+ log::info!("flash_size: {flash_size}");
+ log::info!("target_crc: {target_crc}");
+
+ let mut ota = Ota::new(FlashStorage::new(unsafe {
+ peripherals.FLASH.clone_unchecked()
+ }))
+ .expect("Cannot create ota");
+ ota.ota_begin(flash_size, target_crc).unwrap();
+
+ let mut bytes_read: usize = 0;
+ loop {
+ let bytes_to_read = 8192.min(flash_size - bytes_read as u32);
+ let res = read_exact(&mut socket, &mut ota_buff[..bytes_to_read as usize]).await;
+ if let Ok(_) = res {
+ bytes_read += bytes_to_read as usize;
+ if bytes_to_read == 0 {
+ break;
+ }
+
+ let res = ota.ota_write_chunk(&ota_buff[..bytes_to_read as usize]);
+ _ = socket.write(&[0]).await;
+
+ match res {
+ Ok(true) => {
+ let res = ota.ota_flush(false, true);
+ if let Err(e) = res {
+ log::error!("Ota flush error: {e:?}");
+ break;
+ }
+
+ log::info!("Ota OK! Rebooting in 1s!");
+ Timer::after_millis(1000).await;
+ esp_hal::system::software_reset();
+ }
+ Err(e) => {
+ log::error!("Ota write error: {e:?}");
+ break;
+ }
+ _ => {}
+ }
+ }
+
+ log::info!("Progress: {}%", (ota.get_ota_progress() * 100.0) as u8);
+ }
+
+ loop {
+ log::info!("bump");
+ Timer::after_millis(15000).await;
+ }
+}
+
+#[embassy_executor::task]
+async fn connection(mut controller: WifiController<'static>, stack: Stack<'static>) {
+ log::info!("start connection task");
+ log::info!("Device capabilities: {:?}", controller.capabilities());
+ loop {
+ if esp_radio::wifi::sta_state() == WifiStaState::Connected {
+ // 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 = ModeConfig::Client(
+ ClientConfig::default()
+ .with_ssid(WIFI_SSID.try_into().expect("Wifi ssid parse"))
+ .with_password(WIFI_PSK.try_into().expect("Wifi psk parse")),
+ );
+ controller.set_config(&client_config).unwrap();
+ log::info!("Starting wifi");
+ controller.start_async().await.unwrap();
+ log::info!("Wifi started!");
+ }
+ log::info!("About to connect...");
+
+ match controller.connect_async().await {
+ Ok(_) => {
+ log::info!("Wifi connected!");
+
+ loop {
+ if stack.is_link_up() {
+ break;
+ }
+ Timer::after(Duration::from_millis(500)).await;
+ }
+ }
+ Err(e) => {
+ log::info!("Failed to connect to wifi: {e:?}");
+ Timer::after(Duration::from_millis(5000)).await
+ }
+ }
+ }
+}
+
+#[embassy_executor::task]
+async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
+ runner.run().await
+}
+
+pub async fn read_exact(
+ socket: &mut TcpSocket<'_>,
+ mut buf: &mut [u8],
+) -> Result<(), embassy_net::tcp::Error> {
+ while !buf.is_empty() {
+ match socket.read(buf).await {
+ Ok(0) => return Err(embassy_net::tcp::Error::ConnectionReset),
+ Ok(n) => {
+ buf = &mut buf[n..];
+ }
+ Err(e) => return Err(e),
+ }
+ }
+ Ok(())
+}
diff --git a/vendor/esp-hal-ota/partition-reader/Cargo.lock b/vendor/esp-hal-ota/partition-reader/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "partition-reader"
+version = "0.1.0"
diff --git a/vendor/esp-hal-ota/partition-reader/Cargo.toml b/vendor/esp-hal-ota/partition-reader/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "partition-reader"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/vendor/esp-hal-ota/partition-reader/part.bin b/vendor/esp-hal-ota/partition-reader/part.bin
Binary files differ.
diff --git a/vendor/esp-hal-ota/partition-reader/src/main.rs b/vendor/esp-hal-ota/partition-reader/src/main.rs
@@ -0,0 +1,24 @@
+const PARTITION_BYTES: &[u8] = include_bytes!("../part.bin");
+
+fn main() {
+ let chunks = PARTITION_BYTES.chunks(32);
+ for chunk in chunks {
+ if chunk == &[0xFF; 32] {
+ break;
+ }
+
+ let magic = &chunk[0..2];
+ if magic != &[0xAA, 0x50] {
+ continue;
+ }
+
+ let p_type = &chunk[2];
+ let p_subtype = &chunk[3];
+ let p_offset = u32::from_le_bytes(chunk[4..8].try_into().unwrap());
+ let p_size = u32::from_le_bytes(chunk[8..12].try_into().unwrap());
+ let p_name = core::str::from_utf8(&chunk[12..28]).unwrap();
+ let p_flags = u32::from_le_bytes(chunk[28..32].try_into().unwrap());
+
+ println!("{magic:?} {p_type} {p_subtype} {p_offset} {p_size} {p_name} {p_flags}");
+ }
+}
diff --git a/vendor/esp-hal-ota/partitions.csv.template b/vendor/esp-hal-ota/partitions.csv.template
@@ -0,0 +1,6 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x4000,
+otadata, data, ota, 0xd000, 0x2000,
+phy_init, data, phy, 0xf000, 0x1000,
+ota_0, app, ota_0, 0x10000, 0x100000,
+ota_1, app, ota_1, 0x110000, 0x100000,
diff --git a/vendor/esp-hal-ota/simple-ota-server/Cargo.lock b/vendor/esp-hal-ota/simple-ota-server/Cargo.lock
@@ -0,0 +1,25 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "simple-ota-server"
+version = "0.1.0"
+dependencies = [
+ "crc32fast",
+]
diff --git a/vendor/esp-hal-ota/simple-ota-server/Cargo.toml b/vendor/esp-hal-ota/simple-ota-server/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "simple-ota-server"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+crc32fast = "1.4.2"
diff --git a/vendor/esp-hal-ota/simple-ota-server/firmware.bin b/vendor/esp-hal-ota/simple-ota-server/firmware.bin
Binary files differ.
diff --git a/vendor/esp-hal-ota/simple-ota-server/src/main.rs b/vendor/esp-hal-ota/simple-ota-server/src/main.rs
@@ -0,0 +1,30 @@
+use std::{
+ io::{Read, Write},
+ net::TcpListener,
+};
+
+fn main() {
+ let binary = std::fs::read("./firmware.bin").unwrap();
+ let binary_crc = crc32fast::hash(&binary);
+
+ println!("BINARY_SIZE: {}", binary.len());
+ println!("BINARY CRC32: {}", binary_crc);
+
+ let listener = TcpListener::bind("0.0.0.0:6969").unwrap();
+ for stream in listener.incoming() {
+ println!("Connection");
+ let mut stream = stream.unwrap();
+
+ _ = stream.write_all(&(binary.len() as u32).to_le_bytes());
+ _ = stream.write_all(&binary_crc.to_le_bytes());
+
+ let chunks = binary.chunks(4096 * 2);
+ let mut buf = [0; 1];
+ for chunk in chunks {
+ println!("Writing: {}", chunk.len());
+
+ _ = stream.write_all(chunk);
+ _ = stream.read_exact(&mut buf);
+ }
+ }
+}
diff --git a/vendor/esp-hal-ota/src/crc32.rs b/vendor/esp-hal-ota/src/crc32.rs
@@ -0,0 +1,44 @@
+const CRC_32_TAB: [u32; 256] = [
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+];
+
+pub fn calc_crc32(buf: &[u8], mut crc: u32) -> u32 {
+ crc = !crc;
+ for &elem in buf {
+ let crc_idx = (crc ^ elem as u32) & 0xFF;
+ crc = CRC_32_TAB[crc_idx as usize] ^ (crc >> 8);
+ }
+
+ crc ^ 0xFFFFFFFF
+}
diff --git a/vendor/esp-hal-ota/src/helpers.rs b/vendor/esp-hal-ota/src/helpers.rs
@@ -0,0 +1,33 @@
+#[inline(always)]
+/// Helper funcion!
+/// Change seq to partition number
+pub const fn seq_to_part(seq: u32, partitions_count: usize) -> usize {
+ ((seq as usize).saturating_sub(1)) % partitions_count
+}
+
+#[inline(always)]
+/// Helper funcion!
+/// If crc of seq is correct it returns seq, otherwise default value is returned
+pub fn seq_or_default(seq: &[u8], crc: u32, default: u32) -> u32 {
+ let crc_calc = crate::crc32::calc_crc32(seq, 0xFFFFFFFF);
+ if crc == crc_calc {
+ return u32::from_le_bytes(seq.try_into().expect("Wrong size?"));
+ }
+
+ default
+}
+
+#[inline(always)]
+/// Helper function!
+/// Check if crc is correct for given seq
+pub fn is_crc_seq_correct(seq: u32, crc: u32) -> bool {
+ let bytes = unsafe {
+ let mut buf = [0; 4]; //u32
+ core::ptr::copy_nonoverlapping(&seq as *const u32 as *const u8, buf.as_mut_ptr(), 4);
+
+ buf
+ };
+
+ let crc_calc = crate::crc32::calc_crc32(&bytes, 0xFFFFFFFF);
+ crc == crc_calc
+}
diff --git a/vendor/esp-hal-ota/src/lib.rs b/vendor/esp-hal-ota/src/lib.rs
@@ -0,0 +1,453 @@
+#![no_std]
+#![cfg_attr(any(feature = "esp32", feature = "esp32s2"), feature(concat_idents))]
+#![cfg_attr(feature = "esp32", feature(asm_experimental_arch))]
+#![doc = include_str!("../README.md")]
+
+#[macro_use]
+mod logging;
+
+use embedded_storage::{ReadStorage, Storage};
+pub use structs::*;
+
+pub mod crc32;
+pub mod helpers;
+pub mod mmu_hal;
+pub mod mmu_ll;
+pub mod structs;
+
+const PART_OFFSET: u32 = 0x8000;
+const PART_SIZE: u32 = 0xc00;
+const FIRST_OTA_PART_SUBTYPE: u8 = 0x10;
+const OTA_VERIFY_READ_SIZE: usize = 256;
+
+pub struct Ota<S>
+where
+ S: ReadStorage + Storage,
+{
+ flash: S,
+
+ progress: Option<FlashProgress>,
+ pinfo: PartitionInfo,
+}
+
+pub struct ProgressDetails {
+ pub remaining: u32,
+ pub last_crc: u32,
+}
+
+#[derive(Debug)]
+pub struct OtaConfiguratuion {
+ partition_table_offset: u32,
+}
+impl OtaConfiguratuion {
+ /// Create default configuration of the [`Ota`] process.
+ ///
+ /// Notably this uses the default partition table offset of `0x8000`
+ pub const fn new() -> Self {
+ Self {
+ partition_table_offset: PART_OFFSET,
+ }
+ }
+
+ /// Set custom partition table offset
+ pub const fn with_partition_table_offset(self, partition_table_offset: u32) -> Self {
+ Self {
+ partition_table_offset,
+ ..self
+ }
+ }
+}
+impl Default for OtaConfiguratuion {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<S> Ota<S>
+where
+ S: ReadStorage + Storage,
+{
+ pub fn new(flash: S) -> Result<Self> {
+ Self::with_configuration(flash, OtaConfiguratuion::new())
+ }
+
+ pub fn with_configuration(mut flash: S, config: OtaConfiguratuion) -> Result<Self> {
+ let pinfo = Self::read_partitions(&mut flash, config.partition_table_offset)?;
+ if pinfo.ota_partitions_count < 2 {
+ error!("Not enough OTA partitions! (>= 2)");
+
+ return Err(OtaError::NotEnoughPartitions);
+ }
+
+ Ok(Ota {
+ flash,
+ progress: None,
+ pinfo,
+ })
+ }
+
+ fn get_partitions(&self) -> &[(u32, u32)] {
+ &self.pinfo.ota_partitions[..self.pinfo.ota_partitions_count]
+ }
+
+ /// To begin ota update (need to provide flash size)
+ pub fn ota_begin(&mut self, size: u32, target_crc: u32) -> Result<()> {
+ let next_part = self.get_next_ota_partition().unwrap_or(0);
+
+ let ota_offset = self.get_partitions()[next_part].0;
+ self.progress = Some(FlashProgress {
+ last_crc: 0,
+ flash_size: size,
+ remaining: size,
+ flash_offset: ota_offset,
+ target_partition: next_part,
+ target_crc,
+ });
+
+ Ok(())
+ }
+
+ /// Resumes an OTA update after progress has been lost
+ pub fn ota_resume(
+ &mut self,
+ flash_size: u32,
+ remaining: u32,
+ target_crc: u32,
+ last_crc: u32,
+ verify_crc: bool,
+ ) -> Result<()> {
+ let next_part = self.get_next_ota_partition().unwrap_or(0);
+ let ota_offset = self.get_partitions()[next_part].0;
+
+ if verify_crc {
+ let mut calc_crc = 0;
+ let mut bytes = [0; OTA_VERIFY_READ_SIZE];
+ let mut written = flash_size - remaining;
+ let mut partition_offset = ota_offset;
+
+ loop {
+ let n = written.min(OTA_VERIFY_READ_SIZE as u32);
+ if n == 0 {
+ break;
+ }
+
+ _ = self.flash.read(partition_offset, &mut bytes[..n as usize]);
+ partition_offset += n;
+ written -= n;
+
+ calc_crc = crc32::calc_crc32(&bytes[..n as usize], calc_crc);
+ }
+
+ if calc_crc != last_crc {
+ return Err(OtaError::WrongCRC);
+ }
+ }
+
+ self.progress = Some(FlashProgress {
+ last_crc,
+ flash_size,
+ remaining,
+ flash_offset: ota_offset + (flash_size - remaining),
+ target_partition: next_part,
+ target_crc,
+ });
+
+ Ok(())
+ }
+
+ /// Returns progress details to save for resumption later
+ pub fn get_progress_details(&self) -> Option<ProgressDetails> {
+ if self.progress.is_none() {
+ warn!("[OTA] Cannot get progress details!");
+
+ return None;
+ }
+
+ let progress = self.progress.as_ref().unwrap();
+ Some(ProgressDetails {
+ remaining: progress.remaining,
+ last_crc: progress.last_crc,
+ })
+ }
+
+ /// Returns ota progress in f32 (0..1)
+ pub fn get_ota_progress(&self) -> f32 {
+ if self.progress.is_none() {
+ warn!("[OTA] Cannot get ota progress! Seems like update wasn't started yet.");
+
+ return 0.0;
+ }
+
+ let progress = self.progress.as_ref().unwrap();
+ (progress.flash_size - progress.remaining) as f32 / progress.flash_size as f32
+ }
+
+ /// Writes next firmware chunk
+ pub fn ota_write_chunk(&mut self, chunk: &[u8]) -> Result<bool> {
+ let progress = self.progress.as_mut().ok_or(OtaError::OtaNotStarted)?;
+
+ if progress.remaining == 0 {
+ return Ok(true);
+ }
+
+ let write_size = chunk.len() as u32;
+ let write_size = write_size.min(progress.remaining) as usize;
+
+ self.flash
+ .write(progress.flash_offset, &chunk[..write_size])
+ .map_err(|_| OtaError::FlashRWError)?;
+
+ debug!(
+ "[OTA] Wrote {} bytes to ota partition at 0x{:x}",
+ write_size, progress.flash_offset
+ );
+
+ progress.last_crc = crc32::calc_crc32(&chunk[..write_size], progress.last_crc);
+
+ progress.flash_offset += write_size as u32;
+ progress.remaining -= write_size as u32;
+ Ok(progress.remaining == 0)
+ }
+
+ /// verify - should it read flash and check crc
+ /// rollback - if rollbacks enable (will set ota_state to ESP_OTA_IMG_NEW)
+ pub fn ota_flush(&mut self, verify: bool, rollback: bool) -> Result<()> {
+ if verify && !self.ota_verify()? {
+ error!("[OTA] Verify failed! Not flushing...");
+
+ return Err(OtaError::OtaVerifyError);
+ }
+
+ let progress = self.progress.clone().ok_or(OtaError::OtaNotStarted)?;
+
+ if progress.target_crc != progress.last_crc {
+ warn!("[OTA] Calculated crc: {}", progress.last_crc);
+ warn!("[OTA] Target crc: {}", progress.target_crc);
+ error!("[OTA] Crc check failed! Cant finish ota update...");
+
+ return Err(OtaError::WrongCRC);
+ }
+
+ let img_state = match rollback {
+ true => OtaImgState::EspOtaImgNew,
+ false => OtaImgState::EspOtaImgUndefined,
+ };
+
+ self.set_target_ota_boot_partition(progress.target_partition, img_state);
+ Ok(())
+ }
+
+ /// It reads written flash and checks crc
+ pub fn ota_verify(&mut self) -> Result<bool> {
+ let progress = self.progress.clone().ok_or(OtaError::OtaNotStarted)?;
+
+ let mut calc_crc = 0;
+ let mut bytes = [0; OTA_VERIFY_READ_SIZE];
+
+ let mut partition_offset = self.pinfo.ota_partitions[progress.target_partition].0;
+ let mut remaining = progress.flash_size;
+
+ loop {
+ let n = remaining.min(OTA_VERIFY_READ_SIZE as u32);
+ if n == 0 {
+ break;
+ }
+
+ _ = self.flash.read(partition_offset, &mut bytes[..n as usize]);
+ partition_offset += n;
+ remaining -= n;
+
+ calc_crc = crc32::calc_crc32(&bytes[..n as usize], calc_crc);
+ }
+
+ Ok(calc_crc == progress.target_crc)
+ }
+
+ /// Sets ota boot target partition
+ pub fn set_target_ota_boot_partition(&mut self, target: usize, state: OtaImgState) {
+ let (slot1, slot2) = self.get_ota_boot_entries();
+ let (seq1, seq2) = (slot1.seq, slot2.seq);
+
+ let mut target_seq = seq1.max(seq2);
+ while helpers::seq_to_part(target_seq, self.pinfo.ota_partitions_count) != target
+ || target_seq == 0
+ {
+ target_seq += 1;
+ }
+
+ let flash = &mut self.flash;
+ let target_crc = crc32::calc_crc32(&target_seq.to_le_bytes(), 0xFFFFFFFF);
+ if seq1 > seq2 {
+ let offset = self.pinfo.otadata_offset + (self.pinfo.otadata_size >> 1);
+
+ _ = flash.write(offset, &target_seq.to_le_bytes());
+ _ = flash.write(offset + 32 - 4 - 4, &(state as u32).to_le_bytes());
+ _ = flash.write(offset + 32 - 4, &target_crc.to_le_bytes());
+ } else {
+ _ = flash.write(self.pinfo.otadata_offset, &target_seq.to_le_bytes());
+ _ = flash.write(
+ self.pinfo.otadata_offset + 32 - 4 - 4,
+ &(state as u32).to_le_bytes(),
+ );
+ _ = flash.write(
+ self.pinfo.otadata_offset + 32 - 4,
+ &target_crc.to_le_bytes(),
+ );
+ }
+ }
+
+ pub fn set_ota_state(&mut self, slot: u8, state: OtaImgState) -> Result<()> {
+ let offset = match slot {
+ 1 => self.pinfo.otadata_offset,
+ 2 => self.pinfo.otadata_offset + (self.pinfo.otadata_size >> 1),
+ _ => {
+ error!("Use slot1 or slot2!");
+ return Err(OtaError::CannotFindCurrentBootPartition);
+ }
+ };
+
+ _ = self
+ .flash
+ .write(offset + 32 - 4 - 4, &(state as u32).to_le_bytes());
+
+ Ok(())
+ }
+
+ /// Returns current OTA boot sequences
+ ///
+ /// NOTE: if crc doesn't match, it returns 0 for that seq
+ /// NOTE: [Entry struct (link to .h file)](https://github.com/espressif/esp-idf/blob/master/components/bootloader_support/include/esp_flash_partitions.h#L66)
+ pub fn get_ota_boot_entries(&mut self) -> (EspOtaSelectEntry, EspOtaSelectEntry) {
+ let mut bytes = [0; 32];
+ _ = self.flash.read(self.pinfo.otadata_offset, &mut bytes);
+ let mut slot1: EspOtaSelectEntry =
+ unsafe { core::ptr::read(bytes.as_ptr() as *const EspOtaSelectEntry) };
+ slot1.check_crc();
+
+ _ = self.flash.read(
+ self.pinfo.otadata_offset + (self.pinfo.otadata_size >> 1),
+ &mut bytes,
+ );
+ let mut slot2: EspOtaSelectEntry =
+ unsafe { core::ptr::read(bytes.as_ptr() as *const EspOtaSelectEntry) };
+ slot2.check_crc();
+
+ (slot1, slot2)
+ }
+
+ /// Returns currently booted partition index
+ pub fn get_currently_booted_partition(&self) -> Option<usize> {
+ mmu_hal::esp_get_current_running_partition(self.get_partitions())
+ }
+
+ /// BUG: this wont work if user has ota partitions not starting from ota0
+ /// or if user skips some ota partitions: ota0, ota2, ota3...
+ pub fn get_next_ota_partition(&self) -> Option<usize> {
+ let curr_part = mmu_hal::esp_get_current_running_partition(self.get_partitions());
+ curr_part.map(|next_part| (next_part + 1) % self.pinfo.ota_partitions_count)
+ }
+
+ fn get_current_slot(&mut self) -> Result<(u8, EspOtaSelectEntry)> {
+ let (slot1, slot2) = self.get_ota_boot_entries();
+ let current_partition = self
+ .get_currently_booted_partition()
+ .ok_or(OtaError::CannotFindCurrentBootPartition)?;
+
+ let slot1_part = helpers::seq_to_part(slot1.seq, self.pinfo.ota_partitions_count);
+ let slot2_part = helpers::seq_to_part(slot2.seq, self.pinfo.ota_partitions_count);
+ if current_partition == slot1_part {
+ return Ok((1, slot1));
+ } else if current_partition == slot2_part {
+ return Ok((2, slot2));
+ }
+
+ Err(OtaError::CannotFindCurrentBootPartition)
+ }
+
+ pub fn get_ota_image_state(&mut self) -> Result<OtaImgState> {
+ let (slot1, slot2) = self.get_ota_boot_entries();
+ let current_partition = self
+ .get_currently_booted_partition()
+ .ok_or(OtaError::CannotFindCurrentBootPartition)?;
+
+ let slot1_part = helpers::seq_to_part(slot1.seq, self.pinfo.ota_partitions_count);
+ let slot2_part = helpers::seq_to_part(slot2.seq, self.pinfo.ota_partitions_count);
+ if current_partition == slot1_part {
+ return Ok(slot1.ota_state);
+ } else if current_partition == slot2_part {
+ return Ok(slot2.ota_state);
+ }
+
+ Err(OtaError::CannotFindCurrentBootPartition)
+ }
+
+ pub fn ota_mark_app_valid(&mut self) -> Result<()> {
+ let (current_slot_nmb, current_slot) = self.get_current_slot()?;
+ if current_slot.ota_state != OtaImgState::EspOtaImgValid {
+ self.set_ota_state(current_slot_nmb, OtaImgState::EspOtaImgValid)?;
+
+ info!("Marked current slot as valid!");
+ }
+
+ Ok(())
+ }
+
+ pub fn ota_mark_app_invalid_rollback(&mut self) -> Result<()> {
+ let (current_slot_nmb, current_slot) = self.get_current_slot()?;
+ if current_slot.ota_state != OtaImgState::EspOtaImgValid {
+ self.set_ota_state(current_slot_nmb, OtaImgState::EspOtaImgInvalid)?;
+
+ info!("Marked current slot as invalid!");
+ }
+
+ Ok(())
+ }
+
+ fn read_partitions(flash: &mut S, partition_table_offset: u32) -> Result<PartitionInfo> {
+ let mut tmp_pinfo = PartitionInfo {
+ ota_partitions: [(0, 0); 16],
+ ota_partitions_count: 0,
+ otadata_size: 0,
+ otadata_offset: 0,
+ };
+
+ let mut bytes = [0xFF; 32];
+ let mut last_ota_part: i8 = -1;
+ for read_offset in (0..PART_SIZE).step_by(32) {
+ _ = flash.read(partition_table_offset + read_offset, &mut bytes);
+ if bytes == [0xFF; 32] {
+ break;
+ }
+
+ let magic = &bytes[0..2];
+ if magic != [0xAA, 0x50] {
+ continue;
+ }
+
+ let p_type = &bytes[2];
+ let p_subtype = &bytes[3];
+ let p_offset = u32::from_le_bytes(bytes[4..8].try_into().unwrap());
+ let p_size = u32::from_le_bytes(bytes[8..12].try_into().unwrap());
+ //let p_name = core::str::from_utf8(&bytes[12..28]).unwrap();
+ //let p_flags = u32::from_le_bytes(bytes[28..32].try_into().unwrap());
+ //log::info!("{magic:?} {p_type} {p_subtype} {p_offset} {p_size} {p_name} {p_flags}");
+
+ if *p_type == 0 && *p_subtype >= FIRST_OTA_PART_SUBTYPE {
+ let ota_part_idx = *p_subtype - FIRST_OTA_PART_SUBTYPE;
+ if ota_part_idx as i8 - last_ota_part != 1 {
+ return Err(OtaError::WrongOTAPArtitionOrder);
+ }
+
+ last_ota_part = ota_part_idx as i8;
+ tmp_pinfo.ota_partitions[tmp_pinfo.ota_partitions_count] = (p_offset, p_size);
+ tmp_pinfo.ota_partitions_count += 1;
+ } else if *p_type == 1 && *p_subtype == 0 {
+ //otadata
+ tmp_pinfo.otadata_offset = p_offset;
+ tmp_pinfo.otadata_size = p_size;
+ }
+ }
+
+ Ok(tmp_pinfo)
+ }
+}
diff --git a/vendor/esp-hal-ota/src/logging.rs b/vendor/esp-hal-ota/src/logging.rs
@@ -0,0 +1,35 @@
+macro_rules! debug {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::debug!($($arg)*);
+ #[cfg(feature = "log")]
+ log::debug!($($arg)*);
+ };
+}
+
+macro_rules! info {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::info!($($arg)*);
+ #[cfg(feature = "log")]
+ log::info!($($arg)*);
+ };
+}
+
+macro_rules! warn {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::warn!($($arg)*);
+ #[cfg(feature = "log")]
+ log::warn!($($arg)*);
+ };
+}
+
+macro_rules! error {
+ ($($arg:tt)*) => {
+ #[cfg(feature = "defmt")]
+ defmt::error!($($arg)*);
+ #[cfg(feature = "log")]
+ log::error!($($arg)*);
+ };
+}
diff --git a/vendor/esp-hal-ota/src/mmu_hal.rs b/vendor/esp-hal-ota/src/mmu_hal.rs
@@ -0,0 +1,50 @@
+pub const MMU_PAGE_8KB: u32 = 0x2000;
+pub const MMU_PAGE_16KB: u32 = 0x4000;
+pub const MMU_PAGE_32KB: u32 = 0x8000;
+pub const MMU_PAGE_64KB: u32 = 0x10000;
+
+fn mmu_hal_pages_to_bytes(mmu_id: u32, page_num: u32) -> u32 {
+ let mmu_page_size = crate::mmu_ll::mmu_ll_get_page_size(mmu_id);
+ let shift_code = match mmu_page_size {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ _ => panic!("WRONG MMU_PAGE_SIZE! 0x{:X?}", mmu_page_size),
+ };
+
+ page_num << shift_code
+}
+
+pub fn esp_get_current_running_partition(partitions: &[(u32, u32)]) -> Option<usize> {
+ // NOTE:
+ // mmu_id is always 0 because s_vaddr_to_paddr is using 0 for all targets
+ // except esp32p4 (per SOC_MMU_PER_EXT_MEM_TARGET define)
+ //
+ // https://github.com/espressif/esp-idf/blob/b5ac4fbdf9e9fb320bb0a98ee4fbaa18f8566f37/components/esp_mm/esp_mmu_map.c#L754
+ let mmu_id = 0;
+
+ let ptr = esp_get_current_running_partition as *const () as *const u32;
+ let entry_id = crate::mmu_ll::mmu_ll_get_entry_id(mmu_id, ptr as u32);
+
+ if !crate::mmu_ll::mmu_ll_check_entry_valid(mmu_id, entry_id) {
+ error!("mmu_ll_check_entry_valid failed!");
+
+ return None;
+ }
+
+ // page_num is always 1
+ // https://github.com/espressif/esp-idf/blob/master/components/hal/mmu_hal.c#L129
+ let page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1);
+ let offset = (ptr as u32) % page_size_in_bytes;
+
+ let paddr_base = crate::mmu_ll::mmu_ll_entry_id_to_paddr_base(mmu_id, entry_id);
+ let paddr = paddr_base | offset;
+
+ for (i, part) in partitions.iter().enumerate() {
+ if paddr >= part.0 && paddr < part.0 + part.1 {
+ return Some(i);
+ }
+ }
+
+ None
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32.rs
@@ -0,0 +1,101 @@
+const SOC_MMU_VADDR_MASK: u32 = 0x3FFFFF;
+const SOC_MMU_INVALID: u32 = 1 << 8;
+const MMU_LL_PSRAM_ENTRY_START_ID: u32 = 1152;
+const SOC_IRAM0_CACHE_ADDRESS_LOW: u32 = 0x400D0000;
+const SOC_IRAM0_CACHE_ADDRESS_HIGH: u32 = 0x40400000;
+const SOC_IRAM1_CACHE_ADDRESS_LOW: u32 = 0x40400000;
+const SOC_IRAM1_CACHE_ADDRESS_HIGH: u32 = 0x40800000;
+const SOC_IROM0_CACHE_ADDRESS_LOW: u32 = 0x40800000;
+const SOC_IROM0_CACHE_ADDRESS_HIGH: u32 = 0x40C00000;
+const SOC_DRAM1_CACHE_ADDRESS_LOW: u32 = 0x3F800000;
+const SOC_DRAM1_CACHE_ADDRESS_HIGH: u32 = 0x3FC00000;
+const SOC_DROM0_CACHE_ADDRESS_LOW: u32 = 0x3F400000;
+const SOC_DROM0_CACHE_ADDRESS_HIGH: u32 = 0x3F800000;
+const DPORT_PRO_FLASH_MMU_TABLE: u32 = 0x3FF10000;
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ crate::mmu_hal::MMU_PAGE_64KB
+}
+
+pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
+ let mut offset = 0;
+ let mut shift_code = 0;
+ let mut vaddr_mask = 0;
+
+ if soc_address_in_bus!(SOC_DROM0_CACHE, vaddr) {
+ offset = 0;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_IRAM0_CACHE, vaddr) {
+ offset = 64;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_IRAM1_CACHE, vaddr) {
+ offset = 128;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_IROM0_CACHE, vaddr) {
+ offset = 192;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_DRAM1_CACHE, vaddr) {
+ offset = MMU_LL_PSRAM_ENTRY_START_ID;
+ shift_code = 15;
+ vaddr_mask = SOC_MMU_VADDR_MASK >> 1;
+ } else {
+ error!("mmu_ll_get_entry_id failed!");
+ }
+
+ offset + ((vaddr & vaddr_mask) >> shift_code)
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+ let level = unsafe { dport_interrupt_disable() };
+ let mmu_val = unsafe { *(DPORT_PRO_FLASH_MMU_TABLE as *const u32).offset(entry_id as isize) };
+ unsafe { dport_interrupt_restore(level) };
+
+ if entry_id >= MMU_LL_PSRAM_ENTRY_START_ID {
+ mmu_val << 15
+ } else {
+ mmu_val << 16
+ }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let level = unsafe { dport_interrupt_disable() };
+ let mmu_val = unsafe { *(DPORT_PRO_FLASH_MMU_TABLE as *const u32).offset(entry_id as isize) };
+ unsafe { dport_interrupt_restore(level) };
+
+ (mmu_val & SOC_MMU_INVALID) == 0
+}
+
+// NOTE:Idk if required!
+// Only used when using second core etc.
+
+const SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL: u32 = 5;
+#[inline(always)]
+unsafe fn dport_interrupt_disable() -> u32 {
+ let level: u32;
+
+ unsafe {
+ core::arch::asm!(
+ "rsil {0}, {1}",
+ out(reg) level,
+ const SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL,
+ options(nomem, nostack)
+ );
+ }
+
+ level
+}
+
+#[inline(always)]
+unsafe fn dport_interrupt_restore(level: u32) {
+ unsafe {
+ core::arch::asm!(
+ "wsr.ps {0}; rsync",
+ in(reg) level,
+ options(nomem, nostack)
+ );
+ }
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32c2.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32c2.rs
@@ -0,0 +1,55 @@
+use crate::mmu_hal::{MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB};
+
+const DR_REG_MMU_TABLE: u32 = 0x600c5000;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x3f;
+const SOC_MMU_INVALID: u32 = 1 << 6;
+
+fn soc_mmu_vaddr_mask(mmu_id: u32) -> u32 {
+ mmu_ll_get_page_size(mmu_id) * 64 - 1
+}
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ let extmem = unsafe { &*esp32c2::EXTMEM::ptr() };
+ let cache_mmu_page_size = extmem.cache_conf_misc().read().cache_mmu_page_size().bits();
+ match cache_mmu_page_size {
+ 0 => MMU_PAGE_16KB,
+ 1 => MMU_PAGE_32KB,
+ _ => MMU_PAGE_64KB,
+ }
+}
+
+pub fn mmu_ll_get_entry_id(mmu_id: u32, vaddr: u32) -> u32 {
+ let shift_code = match mmu_ll_get_page_size(mmu_id) {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ _ => {
+ error!("mmu_ll_get_entry_id failed!");
+
+ 0
+ }
+ };
+
+ (vaddr & soc_mmu_vaddr_mask(mmu_id)) >> shift_code
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(mmu_id: u32, entry_id: u32) -> u32 {
+ let shift_code = match mmu_ll_get_page_size(mmu_id) {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ _ => {
+ error!("mmu_ll_entry_id_to_paddr_base failed!");
+
+ 0
+ }
+ };
+
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << shift_code }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_INVALID) == 0 }
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32c3.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32c3.rs
@@ -0,0 +1,22 @@
+const SOC_MMU_VADDR_MASK: u32 = 0x7FFFFF;
+const DR_REG_MMU_TABLE: u32 = 0x600c5000;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0xff;
+const SOC_MMU_INVALID: u32 = 1 << 8;
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ crate::mmu_hal::MMU_PAGE_64KB
+}
+
+pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
+ (vaddr & SOC_MMU_VADDR_MASK) >> 16
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << 16 }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_INVALID) == 0 }
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32c6.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32c6.rs
@@ -0,0 +1,79 @@
+use crate::mmu_hal::{MMU_PAGE_8KB, MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB};
+
+const SOC_MMU_ENTRY_NUM: u32 = 256;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x1ff;
+const SOC_MMU_VALID: u32 = 1 << 9;
+
+fn soc_mmu_vaddr_mask(mmu_id: u32) -> u32 {
+ mmu_ll_get_page_size(mmu_id) * SOC_MMU_ENTRY_NUM - 1
+}
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ let spi_mem = unsafe { &*esp32c6::SPI0::ptr() };
+ let page_size_code = spi_mem.mmu_power_ctrl().read().spi_mmu_page_size().bits();
+
+ match page_size_code {
+ 0 => MMU_PAGE_64KB,
+ 1 => MMU_PAGE_32KB,
+ 2 => MMU_PAGE_16KB,
+ _ => MMU_PAGE_8KB,
+ }
+}
+
+pub fn mmu_ll_get_entry_id(mmu_id: u32, vaddr: u32) -> u32 {
+ let shift_code = match mmu_ll_get_page_size(mmu_id) {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ MMU_PAGE_8KB => 13,
+ _ => {
+ error!("mmu_ll_get_entry_id failed!");
+
+ 0
+ }
+ };
+
+ (vaddr & soc_mmu_vaddr_mask(mmu_id)) >> shift_code
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(mmu_id: u32, entry_id: u32) -> u32 {
+ let shift_code = match mmu_ll_get_page_size(mmu_id) {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ MMU_PAGE_8KB => 13,
+ _ => {
+ error!("mmu_ll_entry_id_to_paddr_base failed!");
+
+ 0
+ }
+ };
+
+ let spi_mem = unsafe { &*esp32c6::SPI0::ptr() };
+ spi_mem
+ .mmu_item_index()
+ .write(|w| unsafe { w.spi_mmu_item_index().bits(entry_id) });
+
+ let mmu_item_content = spi_mem
+ .mmu_item_content()
+ .read()
+ .spi_mmu_item_content()
+ .bits();
+
+ (mmu_item_content & SOC_MMU_VALID_VAL_MASK) << shift_code
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let spi_mem = unsafe { &*esp32c6::SPI0::ptr() };
+ spi_mem
+ .mmu_item_index()
+ .write(|w| unsafe { w.spi_mmu_item_index().bits(entry_id) });
+
+ let mmu_item_content = spi_mem
+ .mmu_item_content()
+ .read()
+ .spi_mmu_item_content()
+ .bits();
+
+ (mmu_item_content & SOC_MMU_VALID) != 0
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32h2.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32h2.rs
@@ -0,0 +1,79 @@
+use crate::mmu_hal::{MMU_PAGE_8KB, MMU_PAGE_16KB, MMU_PAGE_32KB, MMU_PAGE_64KB};
+
+const SOC_MMU_ENTRY_NUM: u32 = 256;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x1ff;
+const SOC_MMU_VALID: u32 = 1 << 9;
+
+fn soc_mmu_vaddr_mask(mmu_id: u32) -> u32 {
+ mmu_ll_get_page_size(mmu_id) * SOC_MMU_ENTRY_NUM - 1
+}
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ let spi_mem = unsafe { &*esp32h2::SPI0::ptr() };
+ let page_size_code = spi_mem.mmu_power_ctrl().read().spi_mmu_page_size().bits();
+
+ match page_size_code {
+ 0 => MMU_PAGE_64KB,
+ 1 => MMU_PAGE_32KB,
+ 2 => MMU_PAGE_16KB,
+ _ => MMU_PAGE_8KB,
+ }
+}
+
+pub fn mmu_ll_get_entry_id(mmu_id: u32, vaddr: u32) -> u32 {
+ let shift_code = match mmu_ll_get_page_size(mmu_id) {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ MMU_PAGE_8KB => 13,
+ _ => {
+ error!("mmu_ll_get_entry_id failed!");
+
+ 0
+ }
+ };
+
+ (vaddr & soc_mmu_vaddr_mask(mmu_id)) >> shift_code
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(mmu_id: u32, entry_id: u32) -> u32 {
+ let shift_code = match mmu_ll_get_page_size(mmu_id) {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ MMU_PAGE_8KB => 13,
+ _ => {
+ error!("mmu_ll_entry_id_to_paddr_base failed!");
+
+ 0
+ }
+ };
+
+ let spi_mem = unsafe { &*esp32h2::SPI0::ptr() };
+ spi_mem
+ .mmu_item_index()
+ .write(|w| unsafe { w.spi_mmu_item_index().bits(entry_id) });
+
+ let mmu_item_content = spi_mem
+ .mmu_item_content()
+ .read()
+ .spi_mmu_item_content()
+ .bits();
+
+ (mmu_item_content & SOC_MMU_VALID_VAL_MASK) << shift_code
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let spi_mem = unsafe { &*esp32h2::SPI0::ptr() };
+ spi_mem
+ .mmu_item_index()
+ .write(|w| unsafe { w.spi_mmu_item_index().bits(entry_id) });
+
+ let mmu_item_content = spi_mem
+ .mmu_item_content()
+ .read()
+ .spi_mmu_item_content()
+ .bits();
+
+ (mmu_item_content & SOC_MMU_VALID) != 0
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32s2.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32s2.rs
@@ -0,0 +1,58 @@
+const SOC_MMU_VADDR_MASK: u32 = 0x3FFFFF;
+const DR_REG_MMU_TABLE: u32 = 0x61801000;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
+const SOC_MMU_INVALID: u32 = 1 << 14;
+const SOC_IRAM0_CACHE_ADDRESS_LOW: u32 = 0x40080000;
+const SOC_IRAM0_CACHE_ADDRESS_HIGH: u32 = 0x40400000;
+const SOC_IRAM1_ADDRESS_LOW: u32 = 0x40400000;
+const SOC_IRAM1_ADDRESS_HIGH: u32 = 0x40800000;
+const SOC_DROM0_ADDRESS_LOW: u32 = 0x3f000000;
+const SOC_DROM0_ADDRESS_HIGH: u32 = 0x3f400000;
+const SOC_DRAM0_CACHE_ADDRESS_LOW: u32 = 0x3fc00000;
+const SOC_DRAM0_CACHE_ADDRESS_HIGH: u32 = 0x3ff80000;
+const SOC_DRAM1_ADDRESS_LOW: u32 = 0x3f800000;
+const SOC_DRAM1_ADDRESS_HIGH: u32 = 0x3fc00000;
+const SOC_DPORT_CACHE_ADDRESS_LOW: u32 = 0x3f500000;
+const SOC_DPORT_CACHE_ADDRESS_HIGH: u32 = 0x3f800000;
+const PRO_CACHE_IBUS0_MMU_START: u32 = 0;
+const PRO_CACHE_IBUS1_MMU_START: u32 = 0x100;
+const PRO_CACHE_IBUS2_MMU_START: u32 = 0x200;
+const PRO_CACHE_DBUS0_MMU_START: u32 = 0x300;
+const PRO_CACHE_DBUS1_MMU_START: u32 = 0x400;
+const PRO_CACHE_DBUS2_MMU_START: u32 = 0x500;
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ crate::mmu_hal::MMU_PAGE_64KB
+}
+
+pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
+ let offset = if soc_address_in_bus!(SOC_DROM0, vaddr) {
+ PRO_CACHE_IBUS2_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_IRAM0_CACHE, vaddr) {
+ PRO_CACHE_IBUS0_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_IRAM1, vaddr) {
+ PRO_CACHE_IBUS1_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_DPORT_CACHE, vaddr) {
+ PRO_CACHE_DBUS2_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_DRAM1, vaddr) {
+ PRO_CACHE_DBUS1_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_DRAM0_CACHE, vaddr) {
+ PRO_CACHE_DBUS0_MMU_START / 4
+ } else {
+ error!("mmu_ll_get_entry_id failed!");
+
+ 0
+ };
+
+ offset + ((vaddr & SOC_MMU_VADDR_MASK) >> 16)
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << 16 }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_INVALID) == 0 }
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/esp32s3.rs b/vendor/esp-hal-ota/src/mmu_ll/esp32s3.rs
@@ -0,0 +1,22 @@
+const SOC_MMU_VADDR_MASK: u32 = 0x1FFFFFF;
+const DR_REG_MMU_TABLE: u32 = 0x600C5000;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
+const SOC_MMU_INVALID: u32 = 1 << 14;
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ crate::mmu_hal::MMU_PAGE_64KB
+}
+
+pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
+ (vaddr & SOC_MMU_VADDR_MASK) >> 16
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << 16 }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_INVALID) == 0 }
+}
diff --git a/vendor/esp-hal-ota/src/mmu_ll/mod.rs b/vendor/esp-hal-ota/src/mmu_ll/mod.rs
@@ -0,0 +1,64 @@
+#[cfg(any(feature = "esp32", feature = "esp32s2"))]
+macro_rules! soc_address_in_bus {
+ ($bus_name:ident, $vaddr:ident) => {{
+ (concat_idents!($bus_name, _ADDRESS_LOW)..concat_idents!($bus_name, _ADDRESS_HIGH))
+ .contains(&$vaddr)
+ }};
+}
+
+#[cfg(feature = "esp32")]
+mod esp32;
+#[cfg(feature = "esp32")]
+pub use esp32::*;
+
+#[cfg(feature = "esp32s2")]
+mod esp32s2;
+#[cfg(feature = "esp32s2")]
+pub use esp32s2::*;
+
+#[cfg(feature = "esp32s3")]
+mod esp32s3;
+#[cfg(feature = "esp32s3")]
+pub use esp32s3::*;
+
+#[cfg(feature = "esp32c2")]
+mod esp32c2;
+#[cfg(feature = "esp32c2")]
+pub use esp32c2::*;
+
+#[cfg(feature = "esp32c3")]
+mod esp32c3;
+#[cfg(feature = "esp32c3")]
+pub use esp32c3::*;
+
+#[cfg(feature = "esp32c6")]
+mod esp32c6;
+#[cfg(feature = "esp32c6")]
+pub use esp32c6::*;
+
+#[cfg(feature = "esp32h2")]
+mod esp32h2;
+#[cfg(feature = "esp32h2")]
+pub use esp32h2::*;
+
+#[cfg(not(any(
+ feature = "esp32",
+ feature = "esp32s2",
+ feature = "esp32s3",
+ feature = "esp32c2",
+ feature = "esp32c3",
+ feature = "esp32c6",
+ feature = "esp32h2"
+)))]
+mod not_selected;
+
+#[cfg(not(any(
+ feature = "esp32",
+ feature = "esp32s2",
+ feature = "esp32s3",
+ feature = "esp32c2",
+ feature = "esp32c3",
+ feature = "esp32c6",
+ feature = "esp32h2"
+)))]
+pub use not_selected::*;
diff --git a/vendor/esp-hal-ota/src/mmu_ll/not_selected.rs b/vendor/esp-hal-ota/src/mmu_ll/not_selected.rs
@@ -0,0 +1,15 @@
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ 0
+}
+
+pub fn mmu_ll_get_entry_id(_mmu_id: u32, _vaddr: u32) -> u32 {
+ 0
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, _entry_id: u32) -> u32 {
+ 0
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, _entry_id: u32) -> bool {
+ false
+}
diff --git a/vendor/esp-hal-ota/src/structs.rs b/vendor/esp-hal-ota/src/structs.rs
@@ -0,0 +1,63 @@
+pub(crate) type Result<T> = core::result::Result<T, OtaError>;
+
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum OtaError {
+ NotEnoughPartitions,
+ OtaNotStarted,
+ FlashRWError,
+ WrongCRC,
+ WrongOTAPArtitionOrder,
+ OtaVerifyError,
+ CannotFindCurrentBootPartition,
+}
+
+#[derive(Clone)]
+pub struct FlashProgress {
+ pub last_crc: u32,
+ pub flash_offset: u32,
+ pub flash_size: u32,
+ pub remaining: u32,
+
+ pub target_partition: usize,
+ pub target_crc: u32,
+}
+
+#[derive(Debug)]
+pub struct PartitionInfo {
+ pub ota_partitions: [(u32, u32); 16],
+ pub ota_partitions_count: usize,
+
+ pub otadata_offset: u32,
+ pub otadata_size: u32,
+}
+
+#[repr(u32)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum OtaImgState {
+ EspOtaImgNew = 0x0,
+ EspOtaImgPendingVerify = 0x1,
+ EspOtaImgValid = 0x2,
+ EspOtaImgInvalid = 0x3,
+ EspOtaImgAborted = 0x4,
+ EspOtaImgUndefined = 0xFFFFFFFF,
+}
+
+#[repr(C)]
+#[derive(Debug)]
+pub struct EspOtaSelectEntry {
+ pub seq: u32,
+ pub seq_label: [u8; 20],
+ pub ota_state: OtaImgState,
+ pub crc: u32,
+}
+
+impl EspOtaSelectEntry {
+ /// Check if crc(of seq) is correct, if not - its setting seq to 0
+ pub fn check_crc(&mut self) {
+ if !crate::helpers::is_crc_seq_correct(self.seq, self.crc) {
+ self.seq = 0; // set seq to 0 if crc not correct!
+ }
+ }
+}