diff --git a/devenv.nix b/devenv.nix index f0d0888..8175e24 100644 --- a/devenv.nix +++ b/devenv.nix @@ -34,6 +34,7 @@ in { espup # tool for installing esp-rs toolchain rustup # rust installer, required by espup rust-analyzer + bacon rustfmt espflash # flash binary to esp python3 diff --git a/sensors/Cargo.lock b/sensors/Cargo.lock index 152d776..8fa7119 100644 --- a/sensors/Cargo.lock +++ b/sensors/Cargo.lock @@ -8,12 +8,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c583acf993cf4245c4acb0a2cc2ab1f9cc097de73411bb6d3647ff6af2b1013d" -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - [[package]] name = "autocfg" version = "1.5.0" @@ -63,14 +57,14 @@ dependencies = [ [[package]] name = "bt-hci" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb938a3b4c5cc6c2409275bad789c0346a0495fa071a0acc5d72b9bd3175a2f7" +checksum = "40f2166cc54c410ddc0d0dafb3cf8dd536bcbae6bddfcc12c020c5ee4de518de" dependencies = [ "btuuid", "embassy-sync 0.7.2", - "embedded-io 0.6.1", - "embedded-io-async 0.6.1", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", "futures-intrusive", "heapless 0.9.2", ] @@ -238,6 +232,26 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "docsplay" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8547ea80db62c5bb9d7796fcce5e6e07d1136bdc1a02269095061e806758fab4" +dependencies = [ + "docsplay-macros", +] + +[[package]] +name = "docsplay-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11772ed3eb3db124d826f3abeadf5a791a557f62c19b123e3f07288158a71fdd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "document-features" version = "0.2.12" @@ -487,8 +501,7 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "esp-alloc" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641e43d6a60244429117ef2fa7a47182120c7561336ea01f6fb08d634f46bae1" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "allocator-api2", "cfg-if", @@ -503,8 +516,7 @@ dependencies = [ [[package]] name = "esp-backtrace" version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3318413fb566c7227387f67736cf70cd74d80a11f2bb31c7b95a9eb48d079669" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "cfg-if", "document-features", @@ -520,8 +532,7 @@ dependencies = [ [[package]] name = "esp-bootloader-esp-idf" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a56964ab5479ac20c9cf76fa3b0d3f2233b20b5d8554e81ef5d65f63c20567" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "cfg-if", "document-features", @@ -538,8 +549,7 @@ dependencies = [ [[package]] name = "esp-config" version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102871054f8dd98202177b9890cb4b71d0c6fe1f1413b7a379a8e0841fc2473c" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "document-features", "esp-metadata-generated", @@ -551,8 +561,7 @@ dependencies = [ [[package]] name = "esp-hal" version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54786287c0a61ca0f78cb0c338a39427551d1be229103b4444591796c579e093" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "bitfield", "bitflags", @@ -606,8 +615,7 @@ dependencies = [ [[package]] name = "esp-hal-procmacros" version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e025a7a7a0affdb4ff913b5c4494aef96ee03d085bf83c27453ae3a71d50da6" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "document-features", "proc-macro-crate", @@ -620,14 +628,12 @@ dependencies = [ [[package]] name = "esp-metadata-generated" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a93e39c8ad8d390d248dc7b9f4b59a873f313bf535218b8e2351356972399e3" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" [[package]] name = "esp-phy" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1facf348e1e251517278fc0f5dc134e95e518251f5796cfbb532ca226a29bf" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "cfg-if", "document-features", @@ -635,15 +641,14 @@ dependencies = [ "esp-hal", "esp-metadata-generated", "esp-sync", - "esp-wifi-sys", + "esp-wifi-sys-esp32", "log", ] [[package]] name = "esp-println" version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a30e6c9fbcc01c348d46706fef8131c7775ab84c254a3cd65d0cd3f6414d592" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "document-features", "esp-metadata-generated", @@ -655,13 +660,14 @@ dependencies = [ [[package]] name = "esp-radio" version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684c4de2f8907b73c9b891fbda65286a86d34fced4b856f36a7896c211f2f265" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "allocator-api2", "bt-hci", "cfg-if", + "docsplay", "document-features", + "embassy-sync 0.7.2", "embedded-io 0.6.1", "embedded-io 0.7.1", "embedded-io-async 0.6.1", @@ -674,7 +680,13 @@ dependencies = [ "esp-phy", "esp-radio-rtos-driver", "esp-sync", - "esp-wifi-sys", + "esp-wifi-sys-esp32", + "esp-wifi-sys-esp32c2", + "esp-wifi-sys-esp32c3", + "esp-wifi-sys-esp32c6", + "esp-wifi-sys-esp32h2", + "esp-wifi-sys-esp32s2", + "esp-wifi-sys-esp32s3", "heapless 0.9.2", "instability", "log", @@ -688,14 +700,17 @@ dependencies = [ [[package]] name = "esp-radio-rtos-driver" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "543bc31d1851afd062357e7810c1a9633f282fd3993583499a841ab497cbca6c" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" +dependencies = [ + "cfg-if", + "esp-sync", + "portable-atomic", +] [[package]] name = "esp-riscv-rt" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502744a5b1e7268d27fd2a4e56ad45efe42ead517d6c517a6961540de949b0ee" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "document-features", "riscv", @@ -705,8 +720,7 @@ dependencies = [ [[package]] name = "esp-rom-sys" version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd66cccc6dd2d13e9f33668a57717ab14a6d217180ec112e6be533de93e7ecbf" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "cfg-if", "document-features", @@ -716,8 +730,7 @@ dependencies = [ [[package]] name = "esp-rtos" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ec711c8d06e79c67b75d01595539e86b0aac209643af98ca87a12250428b3" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "allocator-api2", "cfg-if", @@ -732,16 +745,18 @@ dependencies = [ "esp-hal-procmacros", "esp-metadata-generated", "esp-radio-rtos-driver", + "esp-rom-sys", "esp-sync", "log", "portable-atomic", + "riscv", + "xtensa-lx", ] [[package]] name = "esp-sync" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44974639b4e88914f83fe60d2832c00276657d7d857628fdfc966cc7302e8a8" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "cfg-if", "document-features", @@ -753,20 +768,65 @@ dependencies = [ ] [[package]] -name = "esp-wifi-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b6544f6f0cb86169d1f93ba2101a8d50358a040c5043676ed86b793e09b12c" +name = "esp-wifi-sys-esp32" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" +dependencies = [ + "log", +] + +[[package]] +name = "esp-wifi-sys-esp32c2" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" +dependencies = [ + "log", +] + +[[package]] +name = "esp-wifi-sys-esp32c3" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" +dependencies = [ + "log", +] + +[[package]] +name = "esp-wifi-sys-esp32c6" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" +dependencies = [ + "log", +] + +[[package]] +name = "esp-wifi-sys-esp32h2" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" +dependencies = [ + "log", +] + +[[package]] +name = "esp-wifi-sys-esp32s2" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" +dependencies = [ + "log", +] + +[[package]] +name = "esp-wifi-sys-esp32s3" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-wifi-sys?rev=e7b72a1#e7b72a199147c1dc8beb47a0b01938791e866c98" dependencies = [ - "anyhow", "log", ] [[package]] name = "esp32" version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b76170a463d18f888a1ad258031901036fd827a9ef126733053ba5f8739fb0c8" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -775,8 +835,7 @@ dependencies = [ [[package]] name = "esp32c2" version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62cf8932966b8d445b6f1832977b468178f0a84effb2e9fda89f60c24d45aa3" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -785,8 +844,7 @@ dependencies = [ [[package]] name = "esp32c3" version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356af3771d0d6536c735bf71136594f4d1cbb506abf6e0c51a6639e9bf4e7988" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -795,8 +853,7 @@ dependencies = [ [[package]] name = "esp32c6" version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f5e511df672d79cd63365c92045135e01ba952b6bddd25b660baff5e1110f6b" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -805,8 +862,7 @@ dependencies = [ [[package]] name = "esp32h2" version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed4a50bbd1380931e095e0973b9b12f782a9c481f2edf1f7c42e7eb4ff736d6d" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -815,8 +871,7 @@ dependencies = [ [[package]] name = "esp32s2" version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98574d4c577fbe888fe3e6df7fc80d25a05624d9998f7d7de1500ae21fcca78f" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -825,8 +880,7 @@ dependencies = [ [[package]] name = "esp32s3" version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1810d8ee4845ef87542af981e38eb80ab531d0ef1061e1486014ab7af74c337a" +source = "git+https://github.com/esp-rs/esp-pacs?rev=284111a#284111a606d1e36de06e3284351aa1acf7b056d4" dependencies = [ "critical-section", "vcell", @@ -1585,15 +1639,15 @@ dependencies = [ [[package]] name = "trouble-host" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b5d5992d07744e464b294ccf2dd6d96285bd61c267c4e0307d1f7057a8cd7f" +checksum = "1df7817cead4b83dfbeeaa59736ecbc97c30b21dc3bfc0cc2ce8a6687f70b37a" dependencies = [ "bt-hci", "embassy-futures", "embassy-sync 0.7.2", "embassy-time", - "embedded-io 0.6.1", + "embedded-io 0.7.1", "futures", "heapless 0.9.2", "rand_core 0.6.4", @@ -1604,9 +1658,9 @@ dependencies = [ [[package]] name = "trouble-host-macros" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcb85bec3a8393c22ca1a7c25c82c2d33689ab412f3487c492fd01a033ede7c2" +checksum = "2d809ae05f510cf8f1d863749281eb28e049d9ae4ad52d92ea7a0ac068a0e17c" dependencies = [ "convert_case", "darling 0.20.11", @@ -1761,8 +1815,7 @@ dependencies = [ [[package]] name = "xtensa-lx" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e012d667b0aa6d2592ace8ef145a98bff3e76cca7a644f4181ecd7a916ed289b" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "critical-section", ] @@ -1770,8 +1823,7 @@ dependencies = [ [[package]] name = "xtensa-lx-rt" version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8709f037fb123fe7ff146d2bce86f9dc0dfc53045c016bfd9d703317b6502845" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "document-features", "xtensa-lx", @@ -1781,8 +1833,7 @@ dependencies = [ [[package]] name = "xtensa-lx-rt-proc-macros" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fb42cd29c42f8744c74276e9f5bee7b06685bbe5b88df891516d72cb320450" +source = "git+https://github.com/esp-rs/esp-hal?rev=6168bc7#6168bc775349ba35e3c27bb527defccb22a44658" dependencies = [ "proc-macro2", "quote", diff --git a/sensors/Cargo.toml b/sensors/Cargo.toml index 6dc6f1d..775cd57 100644 --- a/sensors/Cargo.toml +++ b/sensors/Cargo.toml @@ -20,9 +20,10 @@ bench = false compensation = [] [dependencies] -esp-hal = { version = "1.0.0", features = ["log-04", "esp32", "unstable"] } +# esp-rs/esp-hal rev 6168bc7 (6168bc775349ba35e3c27bb527defccb22a44658) latest main at 25/02/2026 +esp-hal = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7", features = ["log-04", "esp32", "unstable"] } -esp-rtos = { version = "0.2.0", features = [ +esp-rtos = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7", features = [ "log-04", "embassy", "esp-alloc", @@ -30,29 +31,29 @@ esp-rtos = { version = "0.2.0", features = [ "esp32", ] } -esp-bootloader-esp-idf = { version = "0.4.0", features = ["log-04", "esp32"] } +esp-bootloader-esp-idf = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7", features = ["log-04", "esp32"] } log = "0.4.27" -bt-hci = "0.6.0" +bt-hci = "0.8.0" embassy-executor = { version = "0.9.1", features = ["log"] } embassy-time = { version = "0.5.0", features = ["log"] } embedded-io = "0.7.1" embedded-io-async = "0.7.0" -esp-alloc = "0.9.0" -esp-backtrace = { version = "0.18.1", features = [ +esp-alloc = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7" } +esp-backtrace = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7", features = [ "esp32", "panic-handler", "println", ] } -esp-println = { version = "0.16.1", features = ["esp32", "log-04"] } -esp-radio = { version = "0.17.0", features = [ +esp-println = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7", features = ["esp32", "log-04"] } +esp-radio = { git = "https://github.com/esp-rs/esp-hal", rev = "6168bc7", features = [ "ble", "log-04", "esp-alloc", "esp32", "unstable", ] } -trouble-host = { version = "0.5.0", features = ["gatt"] } +trouble-host = { version = "0.6.0", features = ["gatt"] } critical-section = "1.2.0" static_cell = "2.1.1" diff --git a/sensors/src/bin/main.rs b/sensors/src/bin/main.rs index bc906b4..3c05e56 100644 --- a/sensors/src/bin/main.rs +++ b/sensors/src/bin/main.rs @@ -5,12 +5,28 @@ reason = "mem::forget is generally not safe to do with esp_hal types, especially those \ holding buffers for the duration of a data transfer." )] +#![deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::panic_in_result_fn, + clippy::todo, + clippy::unimplemented, + clippy::unreachable, + clippy::indexing_slicing, + clippy::arithmetic_side_effects, + clippy::manual_assert, + clippy::assertions_on_constants, + clippy::unnecessary_unwrap +)] use alloc::boxed::Box; use bt_hci::controller::ExternalController; use embassy_executor::Spawner; use esp_backtrace as _; -use esp_hal::{clock::CpuClock, timer::timg::TimerGroup}; +use esp_hal::{ + clock::CpuClock, interrupt::software::SoftwareInterruptControl, timer::timg::TimerGroup, +}; use esp_radio::ble::controller::BleConnector; use log::info; use sensors::init_adcs; @@ -31,11 +47,13 @@ async fn main(spawner: Spawner) { esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 98768); let timg0 = TimerGroup::new(peripherals.TIMG0); - esp_rtos::start(timg0.timer0); + let sw = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); + esp_rtos::start(timg0.timer0, sw.software_interrupt0); info!("Embassy initialized!"); - let radio_init = esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller"); - let transport = BleConnector::new(&radio_init, peripherals.BT, Default::default()).unwrap(); + let transport = + // SAFETY: bro its the default config dawg how would it be invalid + unsafe { BleConnector::new(peripherals.BT, Default::default()).unwrap_unchecked() }; let ble_controller = ExternalController::<_, 20>::new(transport); let (adc, flexes, battery) = init_adcs( @@ -49,22 +67,25 @@ async fn main(spawner: Spawner) { ); let adc: &'static sensors::Adc1Mutex = Box::leak(Box::new(adc)); - info!("spawning flex task"); - spawner - .spawn(sensors::fingers::flex(adc, flexes)) - .expect("cannot spawn flex task"); - info!("spawning gyro task"); - spawner - .spawn(sensors::gyro::gyro( - peripherals.I2C0, - peripherals.GPIO21, - peripherals.GPIO22, - )) - .expect("cannot spawn gyro task"); - info!("spawning battery task"); - spawner - .spawn(sensors::battery::battery(adc, battery)) - .expect("cannot spawn battery task"); + unsafe { + // SAFETY: all of these tasks spawn once + info!("spawning flex task"); + spawner + .spawn(sensors::fingers::flex(adc, flexes)) + .unwrap_unchecked(); + info!("spawning gyro task"); + spawner + .spawn(sensors::gyro::gyro( + peripherals.I2C0, + peripherals.GPIO21, + peripherals.GPIO22, + )) + .unwrap_unchecked(); + info!("spawning battery task"); + spawner + .spawn(sensors::battery::battery(adc, battery)) + .unwrap_unchecked(); + } sensors::ble::run(ble_controller).await; } diff --git a/sensors/src/ble.rs b/sensors/src/ble.rs index 32fdf3c..a1812af 100644 --- a/sensors/src/ble.rs +++ b/sensors/src/ble.rs @@ -1,3 +1,7 @@ +#![allow(clippy::needless_borrows_for_generic_args)] + +use core::num::Saturating; + use embassy_futures::{ join::join, select::{Either, select, select3}, @@ -8,6 +12,7 @@ use log::{error, info, warn}; use trouble_host::prelude::*; use crate::{ + backtrace, battery::BATTERY_SIGNAL, fingers::{COMPENSATING, FLEX_SIGNAL}, gyro::{GYRO_SIGNAL, QUATERNION_SIGNAL}, @@ -32,25 +37,18 @@ struct GloveData { } const DATA_SIZE: usize = 50; // combined sizes of all fields -#[derive(Debug)] -struct NotEnoughSize; impl GloveData { - fn encode(&self, buf: &mut [u8]) -> Result<(), NotEnoughSize> { - if buf.len() >= DATA_SIZE { - self.fingers - .iter() - .flat_map(|u| u.to_be_bytes()) - .chain(self.quaternion.iter().flat_map(|f| f.to_be_bytes())) - .chain(self.acceleration.iter().flat_map(|f| f.to_be_bytes())) - .chain(self.gyroscope.iter().flat_map(|f| f.to_be_bytes())) - .enumerate() - .for_each(|(ptr, b)| { - buf[ptr] = b; - }); - Ok(()) - } else { - Err(NotEnoughSize) - } + fn encode_into(&self, buf: &mut [u8; DATA_SIZE]) { + self.fingers + .iter() + .flat_map(|u| u.to_be_bytes()) + .chain(self.quaternion.iter().flat_map(|f| f.to_be_bytes())) + .chain(self.acceleration.iter().flat_map(|f| f.to_be_bytes())) + .chain(self.gyroscope.iter().flat_map(|f| f.to_be_bytes())) + .zip(buf.iter_mut()) + .for_each(|(src, dest)| { + *dest = src; + }); } } @@ -72,7 +70,9 @@ where async fn ble_task(mut runner: Runner<'_, C, P>) { loop { if let Err(e) = runner.run().await { - panic!("[ble_task] error: {:?}", e); + error!("[ble_task] error: {:?}", e); + backtrace!("ble_task"); + // no break, keep retrying } } } @@ -91,14 +91,18 @@ where } = stack.build(); info!("Starting advertising and GATT service"); - let server = Server::new_with_config(GapConfig::Peripheral(PeripheralConfig { - name: "SignGoGlove", - appearance: &appearance::power_device::GENERIC_POWER_DEVICE, - })) - .unwrap(); + let server = unsafe { + // SAFETY: `new_with_config` returns Err() if its name is >22 bytes long, which "SignGoGlove" is not. + Server::new_with_config(GapConfig::Peripheral(PeripheralConfig { + name: "SignGoGlove", + appearance: &appearance::power_device::GENERIC_POWER_DEVICE, + })) + .unwrap_unchecked() + }; let _ = join(ble_task(runner), async { loop { + let mut backoff_duration = Saturating(10); match advertise("SignGoGlove", &mut peripheral, &server).await { Ok(conn) => { // set up tasks when the connection is established to a central, so they don't run when no one is connected. @@ -110,7 +114,10 @@ where select3(event, sens, bat).await; } Err(e) => { - panic!("[adv] error: {:?}", e); + error!("[adv] error: {:?}", e); + backtrace!("adv"); + Timer::after_millis(backoff_duration.0).await; + backoff_duration *= 2; } } } @@ -136,7 +143,8 @@ async fn advertise<'values, 'server, C: Controller>( .advertise( &Default::default(), Advertisement::ConnectableScannableUndirected { - adv_data: &advertiser_data[..len], + // SAFETY: `len` is always shorter than `advertiser_data.len()` + adv_data: unsafe { advertiser_data.get(..len).unwrap_unchecked() }, scan_data: &[], }, ) @@ -155,7 +163,7 @@ async fn gatt_events_task( server: &Server<'_>, conn: &GattConnection<'_, '_, P>, ) -> Result<(), Error> { - let sensor_data = &server.service.data; + let sensor_data = server.service.data; let reason = loop { match conn.next().await { @@ -164,7 +172,7 @@ async fn gatt_events_task( match &event { GattEvent::Read(event) => { if event.handle() == sensor_data.handle { - let value = server.get(sensor_data); + let value = server.get(&sensor_data); info!( "[gatt] Read Event to Sensor Data Characteristic: {:?}", value @@ -212,8 +220,8 @@ async fn notify_sensor( stack: &Stack<'_, C, P>, ) { info!("[BLE Sensor] task started!"); - let sensor_data = &server.service.data; - let compensation = &server.service.finger_compensation; + let sensor_data = server.service.data; + let compensation = server.service.finger_compensation; loop { let data = { let gyro = wait_or_default(GYRO_SIGNAL.wait(), Duration::from_millis(50)).await; @@ -227,10 +235,7 @@ async fn notify_sensor( }; let data_slice = { let mut buf = [67u8; DATA_SIZE]; // six sevennn - if let Err(e) = data.encode(&mut buf) { - error!("[BLE Sensor] error encoding glove data: {e:?}"); - continue; - } + data.encode_into(&mut buf); buf }; if let Err(e) = sensor_data.notify(conn, &data_slice).await { @@ -256,7 +261,7 @@ async fn notify_sensor( } async fn notify_battery(server: &Server<'_>, conn: &GattConnection<'_, '_, P>) { info!("[BLE Battery] task started!"); - let battery_data = &server.service.battery; + let battery_data = server.service.battery; loop { let bat = wait_or_default(BATTERY_SIGNAL.wait(), Duration::from_millis(100)).await; if let Err(e) = battery_data.notify(conn, &bat).await { diff --git a/sensors/src/fingers.rs b/sensors/src/fingers.rs index d58d85a..dc4dee8 100644 --- a/sensors/src/fingers.rs +++ b/sensors/src/fingers.rs @@ -78,11 +78,11 @@ fn compensate(#[allow(unused_mut)] mut i: [u16; 5]) -> ([u16; 5], Compensation) let edges = [left_edge, right_edge]; let divisors = edges.iter().filter(|&&x| x != 0).count(); - if divisors > 0 { - edges.into_iter().sum::() / divisors as u16 - } else { - 0 - } + edges + .into_iter() + .sum::() + .checked_div(divisors as u16) + .unwrap_or_default() } let mut zeroed_copy = i; @@ -106,12 +106,13 @@ fn compensate(#[allow(unused_mut)] mut i: [u16; 5]) -> ([u16; 5], Compensation) .enumerate() .filter_map(|(i, x)| { if *x == 0 { - Some((i, avg_closest(&zeroed_copy, i))) + Some(avg_closest(&zeroed_copy, i)) } else { None } }) - .for_each(|(idx, replace)| i[idx] = replace); + .zip(i.iter_mut()) + .for_each(|(replace, i_idx)| *i_idx = replace) } (i, comp) } diff --git a/sensors/src/gyro.rs b/sensors/src/gyro.rs index 6f7dcb7..a5dfe9a 100644 --- a/sensors/src/gyro.rs +++ b/sensors/src/gyro.rs @@ -1,4 +1,4 @@ -use core::fmt::Debug; +use core::{fmt::Debug, num::Saturating}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal}; use embassy_time::{Duration, Timer}; @@ -24,7 +24,7 @@ use mpu6050_dmp::{ sensor_async::Mpu6050, }; -use crate::{timeout, timeout_ms}; +use crate::{backtrace, timeout, timeout_ms}; type QuaternionRepr = [f32; 4]; type AccelRepr = [f32; 3]; @@ -202,8 +202,9 @@ where #[embassy_executor::task] pub async fn gyro(i2c: I2C0<'static>, sda: GPIO21<'static>, scl: GPIO22<'static>) { let config = Config::default().with_frequency(Rate::from_khz(400)); - let mut i2c = I2c::new(i2c, config) - .expect("cannot create i2c") + // SAFETY: `I2c::new(..)` errors when passed in an invalid config, however we do pass in a + // valid config. + let mut i2c = unsafe { I2c::new(i2c, config).unwrap_unchecked() } .with_sda(sda) .with_scl(scl) .into_async(); @@ -222,9 +223,9 @@ pub async fn gyro(i2c: I2C0<'static>, sda: GPIO21<'static>, scl: GPIO22<'static> } }; - let mut errors = 0; + let mut errors = Saturating(0); loop { - if errors > 5 { + if errors > Saturating(5) { error!("attempting to restart the mpu driver"); i2c = gyro.release(); continue 'init; @@ -252,6 +253,7 @@ pub async fn gyro(i2c: I2C0<'static>, sda: GPIO21<'static>, scl: GPIO22<'static> "fifo buffer has {} elements instead of {len} elements!", b.len() ); + backtrace!(); errors += 1; continue; } @@ -261,7 +263,13 @@ pub async fn gyro(i2c: I2C0<'static>, sda: GPIO21<'static>, scl: GPIO22<'static> continue; } }; - let q = Quaternion::from_bytes(&res_buf[..16]).unwrap().normalize(); + let q = unsafe { + // SAFETY: b's len() is already checked in the match statement above + // SAFETY: `Quaternion::from_bytes` returns `None` if bytes is not 16 bytes + // long excactly. + Quaternion::from_bytes(res_buf.get(..16).unwrap_unchecked()).unwrap_unchecked() + } + .normalize(); info!("Gyro: {:?}", q); let q = [q.x, q.y, q.z, q.w]; QUATERNION_SIGNAL.signal(q); diff --git a/sensors/src/lib.rs b/sensors/src/lib.rs index d170bc1..02fe069 100644 --- a/sensors/src/lib.rs +++ b/sensors/src/lib.rs @@ -1,5 +1,19 @@ #![no_std] #![feature(cold_path)] +#![deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::panic_in_result_fn, + clippy::todo, + clippy::unimplemented, + clippy::unreachable, + clippy::indexing_slicing, + clippy::arithmetic_side_effects, + clippy::manual_assert, + clippy::assertions_on_constants, + clippy::unnecessary_unwrap +)] use crate::fingers::FlexSensors; use embassy_futures::select::{Either, select}; @@ -37,6 +51,23 @@ macro_rules! try_await { } }; } +#[macro_export] +macro_rules! backtrace { + ($prefix: literal) => { + let bt = esp_backtrace::Backtrace::capture(); + log::error!("[{}] Stack trace:", $prefix); + for frame in bt.frames().iter().take(10) { + log::error!("[{}] --> 0x{:x}", $prefix, frame.program_counter()); + } + }; + () => { + let bt = esp_backtrace::Backtrace::capture(); + log::error!("Stack trace:"); + for frame in bt.frames().iter().take(10) { + log::error!(" --> 0x{:x}", frame.program_counter()); + } + }; +} pub fn init_adcs( adc1: ADC1<'static>,