diff --git a/.cargo/config.toml b/.cargo/config.toml index 596eacd..d08d472 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,10 +6,6 @@ runner = "espflash flash --monitor" ESP_LOGLEVEL="INFO" [build] -rustflags = [ - "-C", "link-arg=-nostartfiles", -] - target = "xtensa-esp32-none-elf" [unstable] diff --git a/Cargo.lock b/Cargo.lock index 4d4477a..87806b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,67 +3,51 @@ version = 3 [[package]] -name = "anstream" -version = "0.6.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.8" +name = "anyhow" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] -name = "anstyle-parse" -version = "0.2.5" +name = "as-slice" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" dependencies = [ - "utf8parse", + "generic-array 0.12.4", + "generic-array 0.13.3", + "generic-array 0.14.7", + "stable_deref_trait", ] [[package]] -name = "anstyle-query" -version = "1.1.1" +name = "as-slice" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" dependencies = [ - "windows-sys 0.52.0", + "stable_deref_trait", ] [[package]] -name = "anstyle-wincon" -version = "3.0.4" +name = "atomic-polyfill" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" dependencies = [ - "anstyle", - "windows-sys 0.52.0", + "critical-section", ] [[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - -[[package]] -name = "atomic-waker" -version = "1.1.2" +name = "atomic-pool" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "58c5fc22e05ec2884db458bf307dc7b278c9428888d2b6e6fad9c0ae7804f5f6" dependencies = [ - "portable-atomic", + "as-slice 0.1.5", + "as-slice 0.2.1", + "atomic-polyfill", + "stable_deref_trait", ] [[package]] @@ -78,7 +62,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa52a79abefbd509c7f2081c84c1191aa2b7e42f74c79557fd53e2a88902c4b2" dependencies = [ - "embedded-hal", + "embedded-hal 1.0.0", ] [[package]] @@ -114,6 +98,19 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bt-hci" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a6508c63d7d137e8188833d9ed3ca97e40d676cf5217874c8c1c24851b012d" +dependencies = [ + "embassy-sync 0.6.0", + "embedded-io", + "embedded-io-async", + "futures-intrusive", + "heapless", +] + [[package]] name = "bytemuck" version = "1.18.0" @@ -141,52 +138,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "clap" -version = "4.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "clap_lex" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" - -[[package]] -name = "colorchoice" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" - [[package]] name = "critical-section" version = "1.1.3" @@ -248,6 +199,110 @@ dependencies = [ "litrs", ] +[[package]] +name = "embassy-executor" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ed0e24bdd4a5f4ff1b72ee4f264b1d23e179ea71a77d984b5fd24877a2bbe1" +dependencies = [ + "critical-section", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d4c0c34b32c2c653c9eecce1cefaf8539dd9a54e61deb5499254f01e2fcac2" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" + +[[package]] +name = "embassy-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cf91dd36dfd623de32242af711fd294d41159f02130052fc93c5c5ba93febe" +dependencies = [ + "as-slice 0.2.1", + "atomic-pool", + "document-features", + "embassy-net-driver", + "embassy-sync 0.5.0", + "embassy-time", + "embedded-io-async", + "embedded-nal-async", + "futures", + "generic-array 0.14.7", + "heapless", + "log", + "managed", + "smoltcp", + "stable_deref_trait", +] + +[[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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-sync" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e0c49ff02ebe324faf3a8653ba91582e2d0a7fdef5bc88f449d5aa1bfcc05c" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-time" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "158080d48f824fad101d7b2fae2d83ac39e3f7a6fa01811034f7ab8ffc6e7309" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless", +] + [[package]] name = "embassy-time-driver" version = "0.1.0" @@ -257,13 +312,29 @@ dependencies = [ "document-features", ] +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" + [[package]] name = "embedded-can" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" dependencies = [ - "nb", + "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]] @@ -272,14 +343,23 @@ 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-hal-nb" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" dependencies = [ - "embedded-hal", - "nb", + "embedded-hal 1.0.0", + "nb 1.1.0", ] [[package]] @@ -288,13 +368,43 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io", +] + +[[package]] +name = "embedded-nal" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a943fad5ed3d3f8a00f1e80f6bba371f1e7f0df28ec38477535eb318dc19cc" +dependencies = [ + "nb 1.1.0", + "no-std-net", +] + +[[package]] +name = "embedded-nal-async" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72229137a4fc12d239b0b7f50f04b30790678da6d782a0f3f1909bf57ec4b759" +dependencies = [ + "embedded-io-async", + "embedded-nal", + "no-std-net", +] + [[package]] name = "enum-as-inner" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.79", @@ -329,11 +439,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "esp-alloc" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e44c0b0c0416865313f3fcb6c00f7bc8ecebef30459bec74dc272eb12e465e3f" +checksum = "5162b6e9cd99cc974ec2742da3cf8433e7332853ae10fec922d174ff20fa4c5f" dependencies = [ "critical-section", + "enumset", "linked_list_allocator", ] @@ -359,38 +470,55 @@ dependencies = [ "termcolor", ] +[[package]] +name = "esp-config" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eeb7365af80ce4f8a1a2536676daf4e3d1487ec7a5b2eda0e8c458b9ba8b266" +dependencies = [ + "document-features", +] + [[package]] name = "esp-hal" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f5393b8f7e7f055455d9f86706ddb675f943c12f12a7b80b8a79c3a94233ff" +checksum = "ef2983f6fd1fdbd19217019958517257a0b6495e8aa618cb505612cc7ead44ec" dependencies = [ "basic-toml", "bitfield", "bitflags 2.6.0", "bytemuck", "cfg-if", + "chrono", "critical-section", "delegate", "document-features", + "embassy-futures", + "embassy-sync 0.6.0", "embedded-can", - "embedded-hal", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", "embedded-hal-nb", "embedded-io", + "embedded-io-async", "enumset", "esp-build", + "esp-config", "esp-hal-procmacros", "esp-metadata", "esp-riscv-rt", "esp32", "fugit", "log", - "nb", + "nb 1.1.0", "paste", "portable-atomic", "rand_core", "serde", "strum", + "ufmt-write", "void", "xtensa-lx", "xtensa-lx-rt", @@ -398,33 +526,34 @@ dependencies = [ [[package]] name = "esp-hal-embassy" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e47f06e0d7ddf411c3a582ec8fdc4fbc91713aa14bad736618677df0ffb606" +checksum = "1d17e1b37de4605fdcadbb2a9701065e7d6ed376b473bf8eeac1d879a53b3470" dependencies = [ - "cfg-if", "critical-section", "document-features", + "embassy-executor", "embassy-time-driver", "esp-build", "esp-hal", "esp-hal-procmacros", "esp-metadata", + "log", "portable-atomic", "static_cell", ] [[package]] name = "esp-hal-procmacros" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eac531546027909a355fc9c2449f22c839955fa4b7f1976b64ddd04b2f22f83" +checksum = "34022a362a27f781b83852afd0c856a43e2ee5b4334cdc292bd80c9be482a1f5" dependencies = [ "darling", "document-features", "litrs", "proc-macro-crate", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.79", @@ -432,14 +561,12 @@ dependencies = [ [[package]] name = "esp-metadata" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b471bc61fa817ca4ae41a31d5d453258328b31e5ad82db72b473621d36cc4cb6" +checksum = "f9972bbb21dcafe430b87f92efc7a788978a2d17cf8f572d104beeb48602482a" dependencies = [ "anyhow", "basic-toml", - "clap", - "lazy_static", "serde", "strum", ] @@ -469,25 +596,28 @@ dependencies = [ [[package]] name = "esp-wifi" -version = "0.8.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97f76de64be01a074dec52112656cf656c05657ce5dc3fc5b376b7f06958130" +checksum = "44431e7946c560e7632f3d0241763681da1376b357f2cba1362be168bc38d162" dependencies = [ - "atomic-waker", + "bt-hci", "cfg-if", "critical-section", + "document-features", + "embassy-net-driver", + "embassy-sync 0.6.0", "embedded-io", + "embedded-io-async", "enumset", + "esp-alloc", "esp-build", + "esp-config", "esp-hal", - "esp-hal-embassy", "esp-metadata", "esp-wifi-sys", "fugit", - "futures-util", "heapless", "libm", - "linked_list_allocator", "log", "no-std-net", "num-derive", @@ -495,16 +625,17 @@ dependencies = [ "portable-atomic", "portable_atomic_enum", "smoltcp", - "toml-cfg", + "xtensa-lx-rt", ] [[package]] name = "esp-wifi-sys" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1829bd8c63b22a6d8a5485203a6e6bdc008897d9ee687aa6df8b57d2103a48d2" +checksum = "f339ddb1664812e79992a8231a3f8603456c80b769066313150831f2b0bf66e7" dependencies = [ "anyhow", + "log", ] [[package]] @@ -533,15 +664,69 @@ dependencies = [ "gcd", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + [[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 = [ - "portable-atomic", + "futures-core", + "lock_api", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", ] +[[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" @@ -555,6 +740,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", @@ -566,6 +753,34 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" +dependencies = [ + "typenum", +] + +[[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" @@ -592,12 +807,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -620,24 +829,12 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libm" version = "0.2.8" @@ -702,6 +899,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4bb1638d419e12f8b1c43d9e639abd0d1424285bdea2f76aa231e233c63cd3a" +[[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" @@ -789,34 +995,32 @@ dependencies = [ ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ + "proc-macro-error-attr2", "proc-macro2", "quote", - "version_check", + "syn 2.0.79", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -849,7 +1053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" dependencies = [ "critical-section", - "embedded-hal", + "embedded-hal 1.0.0", ] [[package]] @@ -986,7 +1190,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -1036,20 +1240,6 @@ dependencies = [ "toml_edit", ] -[[package]] -name = "toml-cfg" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c587298ddd135c156e92e8c3eae69614d6eecea8e2d8a09daab011e5e6a21d" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "serde", - "syn 2.0.79", - "toml", -] - [[package]] name = "toml_datetime" version = "0.6.8" @@ -1072,6 +1262,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "ublox" version = "0.4.5" @@ -1097,16 +1293,16 @@ dependencies = [ ] [[package]] -name = "unicode-ident" -version = "1.0.13" +name = "ufmt-write" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" [[package]] -name = "utf8parse" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "vcell" @@ -1132,10 +1328,16 @@ version = "0.1.0" dependencies = [ "anyhow", "axp192", + "embassy-executor", + "embassy-net", + "embassy-sync 0.6.0", + "embassy-time", "embedded-io", + "embedded-io-async", "esp-alloc", "esp-backtrace", "esp-hal", + "esp-hal-embassy", "esp-println", "esp-wifi", "heapless", @@ -1143,6 +1345,7 @@ dependencies = [ "serde", "serde_json", "smoltcp", + "static_cell", "ublox", ] @@ -1152,16 +1355,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", + "windows-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 28aa0a0..dc6ada8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,18 +10,14 @@ esp-backtrace = { version = "0.14.0", features = [ "exception-handler", "panic-handler", "println", + "custom-halt", ] } -esp-hal = { version = "0.20.1", features = [ "esp32", "embedded-io" ] } +esp-hal = { version = "0.21.0", features = ["esp32"] } esp-println = { version = "0.11.0", features = ["esp32", "log"] } log = { version = "0.4.21" } -esp-alloc = { version = "0.4.0" } +esp-alloc = { version = "0.5.0" } embedded-io = "0.6.1" -esp-wifi = { version = "0.8.0", features = [ - "esp32", - "phy-enable-usb", - "utils", - "wifi", -] } +esp-wifi = { version = "0.10.1", features = ["esp32", "embassy-net", "wifi", "tcp", "udp", "esp-alloc", "log", "ipv4", "icmp", "phy-enable-usb"] } heapless = { version = "0.8.0", default-features = false } smoltcp = { version = "0.11.0", default-features = false, features = [ "medium-ethernet", @@ -39,6 +35,13 @@ ublox = { version = "0.4.5", default-features = false, features = ["alloc", "ser serde = { version = "1.0.210", default-features = false, features = ["derive"] } serde_json = { version = "1.0.128", default-features = false, features = ["alloc"] } anyhow = { version = "1.0.89", default-features = false } +embassy-executor = { version = "0.6.0", features = ["executor-thread", "integrated-timers", "task-arena-size-8192"] } +embassy-time = { version = "0.3.2" } +esp-hal-embassy = { version = "0.4.0", features = ["esp32", "log"] } +embassy-net = { version = "0.4.0", features = ["dhcpv4", "dhcpv4-hostname", "dns", "log", "medium-ip", "proto-ipv4", "tcp", "udp"] } +static_cell = { version = "2.1.0", features = ["nightly"] } +embedded-io-async = { version = "0.6.1", features = ["alloc"] } +embassy-sync = "0.6.0" [profile.dev] # Rust debug is too slow. diff --git a/flake.nix b/flake.nix index 05a6f77..ba87c7d 100644 --- a/flake.nix +++ b/flake.nix @@ -59,7 +59,7 @@ craneLib = crane.mkLib pkgs; craneToolchain = craneLib.overrideToolchain rustToolchain; src = craneLib.cleanCargoSource ./.; - commonArgs = { + commonArgs = rec { inherit src; cargoVendorDir = craneLib.vendorMultipleCargoDeps { cargoLockList = [ @@ -79,13 +79,17 @@ strictDeps = true; doCheck = false; + dontCheck = true; dontPatchELF = true; cargoExtraArgs = "-Zbuild-std=core,alloc --target xtensa-esp32-none-elf"; - nativeBuildInputs = with pkgs; [ + buildInputs = with pkgs; [ + openssl + pkg-config esp-idf-esp32 ]; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (buildInputs ++ [ rustToolchain ]); }; cargoArtifacts = craneToolchain.buildDepsOnly commonArgs; diff --git a/nix/overlay.nix b/nix/overlay.nix index beaf00d..c9b63e0 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -1,14 +1,4 @@ final: prev: { rust-esp = prev.callPackage ./rust-esp.nix { }; rust-src-esp = prev.callPackage ./rust-src-esp.nix { }; - - esp-idf-esp32-with-clang = final.esp-idf-full.override { - toolsToInclude = [ - "esp-clang" - "xtensa-esp32-elf" - "esp32ulp-elf" - "openocd-esp32" - "xtensa-esp-elf-gdb" - ]; - }; } diff --git a/src/gps.rs b/src/gps.rs new file mode 100644 index 0000000..0787ea1 --- /dev/null +++ b/src/gps.rs @@ -0,0 +1,237 @@ +use alloc::{sync::Arc, vec::Vec}; +use anyhow::{anyhow, Result}; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; +use embassy_time::{Duration, Timer}; +use embedded_io_async::{Read as _, ReadReady as _, Write as _}; +use esp_hal::{peripherals::UART1, uart::Uart, Async}; +use log::{info, trace}; +use ublox::{GpsFix, PacketRef}; + +#[derive(Default, Debug, Clone, Copy, serde::Serialize)] +pub struct GpsCoords { + lat: f64, + lon: f64, + height: f64, + horiz_accuracy: u32, +} + +impl From> for GpsCoords { + fn from(nav: ublox::NavPvtRef<'_>) -> Self { + Self { + lat: nav.lat_degrees(), + lon: nav.lon_degrees(), + height: nav.height_meters(), + horiz_accuracy: nav.horiz_accuracy(), + } + } +} + +type GpsUart = Uart<'static, UART1, Async>; + +pub struct Gps { + uart: Arc>, + coords: Arc>>, +} + +impl Gps { + pub async fn new(mut uart: Uart<'static, UART1, Async>) -> Result { + uart_init::<_, BAUD>(&mut uart).await?; + + Ok(Self { + uart: Arc::new(Mutex::new(uart)), + coords: Arc::new(Mutex::new(Default::default())), + }) + } + + pub async fn get_coords(&self) -> Option { + *self.coords.lock().await + } + + pub async fn run(&self) -> ! { + let mut parser = { + let buf = Vec::::new(); + ublox::Parser::new(buf) + }; + let mut uart = self.uart.lock().await; + + loop { + let mut uart_buf = [0u8; 512]; + let len = { + let result = uart.read(&mut uart_buf).await; + match result { + Ok(len) => len, + Err(e) => { + log::error!("GPS Read failed: {:?}", e); + continue; + } + } + }; + let mut it = parser.consume(&uart_buf[..len]); + loop { + match it.next() { + Some(Ok(PacketRef::NavPvt(nav))) => { + trace!("Positional data: {:?}", nav); + let mut data = self.coords.lock().await; + *data = { + match nav.fix_type() { + GpsFix::Fix2D | GpsFix::Fix3D => Some(nav.into()), + _ => None, + } + }; + } + Some(Ok(packet)) => { + trace!("Received packet: {:?}", packet); + } + Some(Err(e)) => { + info!("GPS Error: {:?}", e); + } + None => { + // done processing current gps_data + break; + } + } + } + } + } +} + +async fn uart_init( + uart: &mut esp_hal::uart::Uart<'_, T, Async>, +) -> anyhow::Result<()> +where + T: esp_hal::uart::Instance, +{ + let gps_reset_packet = ublox::CfgRstBuilder { + nav_bbr_mask: ublox::NavBbrMask::all(), + reset_mode: ublox::ResetMode::ControlledSoftwareReset, + reserved1: 0, + } + .into_packet_bytes(); + info!("Resetting GPS..."); + uart.write_all(&gps_reset_packet) + .await + .map_err(|e| anyhow::anyhow!("Failed to write GPS reset packet: {:?}", e))?; + uart.flush().await.expect("Failed to flush GPS writer"); + uart.flush_tx().expect("Failed to flush GPS TX"); + + // wait for GPS to reset + Timer::after(Duration::from_millis(1000)).await; + + let gps_init_packet = ublox::CfgPrtUartBuilder { + portid: ublox::UartPortId::Uart1, + reserved0: 0, + tx_ready: 0, + mode: ublox::UartMode::new( + ublox::DataBits::Eight, + ublox::Parity::None, + ublox::StopBits::One, + ), + baud_rate: BAUD, + in_proto_mask: ublox::InProtoMask::all(), + out_proto_mask: ublox::OutProtoMask::UBLOX, + flags: 0, + reserved5: 0, + } + .into_packet_bytes(); + info!("Initializing GPS..."); + uart.write_all(&gps_init_packet) + .await + .map_err(|e| anyhow!("Failed to write GPS init packet: {:?}", e))?; + log::trace!("written init packet"); + uart_expect_ack(uart) + .await + .map_err(|e| anyhow!("Failed to receive GPS ACK: {:?}", e))?; + log::trace!("received ack"); + + //info!("Changing GPS baud rate to {}", GPS_TARGET_BAUD); + //uart.change_baud(GPS_TARGET_BAUD, ClockSource::Apb, &clocks); + + let nav5_init_packet = ublox::CfgNav5Builder { + mask: ublox::CfgNav5Params::DYN, + dyn_model: ublox::CfgNav5DynModel::Automotive, + ..Default::default() + } + .into_packet_bytes(); + info!("Setting GPS to automotive mode"); + uart.write_all(&nav5_init_packet) + .await + .map_err(|e| anyhow!("Failed to write NAV5 init packet: {:?}", e))?; + uart_expect_ack(uart) + .await + .map_err(|_| anyhow!("Failed to receive GPS ACK"))?; + + let gps_rate_init = ublox::CfgRateBuilder { + measure_rate_ms: 500, + nav_rate: 1, + time_ref: ublox::AlignmentToReferenceTime::Utc, + } + .into_packet_bytes(); + info!("Setting GPS rate to 500ms"); + uart.write_all(&gps_rate_init) + .await + .map_err(|e| anyhow!("Failed to write GPS rate init packet: {:?}", e))?; + uart_expect_ack(uart) + .await + .map_err(|_| anyhow!("Failed to receive GPS ACK"))?; + + let nav_pvt_rate_init = + ublox::CfgMsgSinglePortBuilder::set_rate_for::(1).into_packet_bytes(); + info!("Setting NAV-PVT rate to 1 every measurement cycle"); + uart.write_all(&nav_pvt_rate_init) + .await + .map_err(|e| anyhow!("Failed to write NAV-PVT rate init packet: {:?}", e))?; + uart_expect_ack(uart) + .await + .map_err(|_| anyhow!("Failed to receive GPS ACK"))?; + + info!("GPS initialized"); + Ok(()) +} + +async fn uart_expect_ack(uart: &mut esp_hal::uart::Uart<'_, T, Async>) -> anyhow::Result<()> +where + T: esp_hal::uart::Instance, +{ + const BUF_SIZE: usize = 128; + const MAX_ITERATIONS: usize = 1000; + let mut parser = ublox::Parser::new(Vec::new()); + + let mut i = 0; + loop { + if i >= MAX_ITERATIONS { + anyhow::bail!("Waiting for ACK timed out"); + } + + let ready = uart + .read_ready() + .map_err(|e| anyhow!("Failed to check UART read ready: {:?}", e))?; + if !ready { + Timer::after(Duration::from_millis(10)).await; + i += 1; + continue; + } + + let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE]; + let Ok(len) = uart.read(&mut buf).await else { + i += 1; + continue; + }; + let mut it = parser.consume(&buf[..len]); + loop { + match it.next() { + Some(Ok(ublox::PacketRef::AckAck(_))) | Some(Ok(ublox::PacketRef::MgaAck(_))) => { + return Ok(()) + } + Some(Ok(ublox::PacketRef::AckNak(_))) => anyhow::bail!("Received NAK from GPS"), + Some(Err(e)) => anyhow::bail!("GPS Error: {:?}", e), + None => { + // done processing packet + // not a valid ACK/NACK, continue to outer waiting loop + i = 0; + break; + } + _ => continue, + } + } + } +} diff --git a/src/main.rs b/src/main.rs index 5aee079..d9a3814 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,65 +1,63 @@ #![no_std] #![no_main] +#![feature(type_alias_impl_trait)] +#![feature(async_closure)] -use alloc::vec::Vec; +use alloc::boxed::Box; use anyhow::anyhow; -use embedded_io::{Read, ReadReady, Write}; +use core::str::FromStr; +use embassy_executor::{task, Spawner}; +use embassy_net::StackResources; +use embassy_sync::{blocking_mutex::raw::NoopRawMutex, channel}; +use embassy_time::{Duration, Timer}; +use embedded_io_async::{Read as _, ReadReady as _, Write as _}; use esp_backtrace as _; use esp_hal::{ - clock::ClockControl, - delay::Delay, - gpio::{Io, Level, Output}, - peripherals::Peripherals, + gpio::{Io, Output}, prelude::*, - system::SystemControl, - uart, + reset::software_reset, + rng::Rng, + uart, Async, +}; +use esp_hal_embassy::main; +use esp_wifi::{ + wifi::{ + utils::create_network_interface, ClientConfiguration, Configuration, WifiController, + WifiDevice, WifiEvent, WifiStaDevice, WifiState, + }, + EspWifiInitFor, }; use log::info; +use smoltcp::iface::SocketStorage; +use static_cell::make_static; extern crate alloc; -use core::mem::MaybeUninit; -#[global_allocator] -static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty(); +mod gps; -fn init_heap() { - const HEAP_SIZE: usize = 32 * 1024; - static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit(); +use gps::Gps; - unsafe { - ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE); +#[export_name = "custom_halt"] +pub fn custom_halt() -> ! { + loop { + software_reset(); } } -#[entry] -fn main() -> ! { - let peripherals = Peripherals::take(); - let system = SystemControl::new(peripherals.SYSTEM); +#[main] +async fn main_task(spawner: Spawner) { + let peripherals = esp_hal::init(esp_hal::Config::default()); + let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0); + esp_hal_embassy::init(timg0.timer0); - let clocks = ClockControl::max(system.clock_control).freeze(); - let delay = Delay::new(&clocks); - init_heap(); + esp_alloc::heap_allocator!(72 * 1024); esp_println::logger::init_logger_from_env(); - let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0, &clocks); - let _init = esp_wifi::initialize( - esp_wifi::EspWifiInitFor::Wifi, - timg0.timer0, - esp_hal::rng::Rng::new(peripherals.RNG), - peripherals.RADIO_CLK, - &clocks, - ) - .expect("Failed to initialize WiFi"); let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); - let psu_i2c = esp_hal::i2c::I2C::new( - peripherals.I2C0, - io.pins.gpio21, - io.pins.gpio22, - 100.kHz(), - &clocks, - ); + let psu_i2c = + esp_hal::i2c::I2c::new(peripherals.I2C0, io.pins.gpio21, io.pins.gpio22, 100.kHz()); let mut psu = axp192::Axp192::new(psu_i2c); psu.set_dcdc1_on(false).unwrap(); @@ -68,8 +66,57 @@ fn main() -> ! { psu.set_dcdc2_on(false).unwrap(); psu.set_exten_on(false).unwrap(); + let wifi_init = esp_wifi::init( + EspWifiInitFor::Wifi, + timg0.timer1, + Rng::new(peripherals.RNG), + peripherals.RADIO_CLK, + ) + .expect("Failed to initialize WiFi clocks"); + let mut socket_storage: [SocketStorage; 3] = Default::default(); + let (_wifi_interface, wifi_device, wifi_controller, _wifi_sockets) = create_network_interface( + &wifi_init, + peripherals.WIFI, + WifiStaDevice, + &mut socket_storage, + ) + .expect("Failed to create WiFi network interface"); + + let stack_resources: &mut StackResources<3> = Box::leak(Box::new(StackResources::new())); + let stack = make_static!(embassy_net::Stack::new( + wifi_device, + embassy_net::Config::dhcpv4(Default::default()), + stack_resources, + 1234u64, + )); + + spawner + .spawn(wifi_connection(wifi_controller)) + .expect("Failed to spawn WiFi connection task"); + spawner + .spawn(wifi_net_task(stack)) + .expect("Failed to spawn WiFi task"); + + //log::info!("Waiting for WiFi link..."); + //loop { + // if stack.is_link_up() { + // log::info!("WiFi link up"); + // break; + // } + // Timer::after(Duration::from_millis(500)).await; + //} + + //log::info!("Waiting for IP..."); + //loop { + // if let Some(config) = stack.config_v4() { + // log::info!("Got IP: {}", config.address); + // break; + // }; + // Timer::after(Duration::from_millis(500)).await; + //} + const GPS_BAUD: u32 = 9600; - let mut gps_uart = esp_hal::uart::Uart::new_with_config( + let gps_uart = esp_hal::uart::Uart::new_async_with_config( peripherals.UART1, uart::config::Config { baudrate: GPS_BAUD, @@ -79,16 +126,25 @@ fn main() -> ! { rx_timeout: Some(50), ..Default::default() }, - &clocks, - io.pins.gpio5, - io.pins.gpio36, + io.pins.gpio34, + io.pins.gpio32, ) .expect("Failed to initialize GPS UART"); - gps_init::<_, _, GPS_BAUD>(&mut gps_uart, &delay).expect("Failed to initialize GPS"); + let gps = { + let gps = gps::Gps::new(gps_uart) + .await + .expect("Failed to initialize GPS"); + make_static!(gps) + }; + spawner + .spawn(gps_task(gps)) + .expect("Failed to spawn GPS task"); + + let status_chan = channel::Channel::::new(); const MODEM_BAUD: u32 = 115_200; - let mut modem_uart = esp_hal::uart::Uart::new_with_config( + let mut modem_uart = esp_hal::uart::Uart::new_async_with_config( peripherals.UART2, uart::config::Config { baudrate: MODEM_BAUD, @@ -98,188 +154,82 @@ fn main() -> ! { rx_timeout: Some(50), ..Default::default() }, - &clocks, - io.pins.gpio27, io.pins.gpio26, + io.pins.gpio27, ) .expect("Failed to initialize modem UART"); - let mut modem_pwrkey = Output::new(io.pins.gpio4, Level::Low); - let mut modem_power_on = Output::new(io.pins.gpio25, Level::Low); + let mut modem_pwrkey = Output::new(io.pins.gpio4, esp_hal::gpio::Level::Low); + let mut modem_power_on = Output::new(io.pins.gpio25, esp_hal::gpio::Level::Low); - modem_init( - &mut modem_uart, - &mut modem_pwrkey, - &mut modem_power_on, - &delay, - ) - .expect("Failed to initialize modem"); - - let gps_buf = Vec::::new(); - let mut gps_parser = ublox::Parser::new(gps_buf); + modem_init(&mut modem_uart, &mut modem_pwrkey, &mut modem_power_on) + .await + .expect("Failed to initialize modem"); loop { - let mut gps_data = [0u8; 64]; - let len = gps_uart.read(&mut gps_data).unwrap(); - let mut it = gps_parser.consume(&gps_data[..len]); - loop { - match it.next() { - Some(Ok(packet)) => { - info!("GPS Packet: {:#?}", packet); - } - Some(Err(e)) => { - info!("GPS Error: {:?}", e); - } - None => { - // done processing current gps_data - break; - } - } - } + Timer::after(Duration::from_secs(1)).await; + info!("gps coords: {:?}", gps.get_coords().await); } } -fn gps_init( - gps_uart: &mut esp_hal::uart::Uart, - delay: &esp_hal::delay::Delay, -) -> anyhow::Result<()> -where - T: esp_hal::uart::Instance, - M: esp_hal::Mode, -{ - let gps_reset_packet = ublox::CfgRstBuilder { - nav_bbr_mask: ublox::NavBbrMask::all(), - reset_mode: ublox::ResetMode::ControlledSoftwareReset, - reserved1: 0, - } - .into_packet_bytes(); - info!("Resetting GPS..."); - gps_uart - .write_all(&gps_reset_packet) - .map_err(|e| anyhow::anyhow!("Failed to write GPS reset packet: {:?}", e))?; - - // wait for GPS to reset - delay.delay_millis(1000u32); - - let gps_init_packet = ublox::CfgPrtUartBuilder { - portid: ublox::UartPortId::Uart1, - reserved0: 0, - tx_ready: 0, - mode: ublox::UartMode::new( - ublox::DataBits::Eight, - ublox::Parity::None, - ublox::StopBits::One, - ), - baud_rate: BAUD, - in_proto_mask: ublox::InProtoMask::all(), - out_proto_mask: ublox::OutProtoMask::UBLOX, - flags: 0, - reserved5: 0, - } - .into_packet_bytes(); - info!("Initializing GPS..."); - gps_uart - .write_all(&gps_init_packet) - .map_err(|e| anyhow!("Failed to write GPS init packet: {:?}", e))?; - gps_expect_ack(gps_uart, delay).map_err(|e| anyhow!("Failed to receive GPS ACK: {:?}", e))?; - - //info!("Changing GPS baud rate to {}", GPS_TARGET_BAUD); - //gps_uart.change_baud(GPS_TARGET_BAUD, ClockSource::Apb, &clocks); - - let nav5_init_packet = ublox::CfgNav5Builder { - mask: ublox::CfgNav5Params::DYN, - dyn_model: ublox::CfgNav5DynModel::Automotive, - ..Default::default() - } - .into_packet_bytes(); - info!("Setting GPS to automotive mode"); - gps_uart - .write_all(&nav5_init_packet) - .map_err(|e| anyhow!("Failed to write NAV5 init packet: {:?}", e))?; - gps_expect_ack(gps_uart, delay).map_err(|_| anyhow!("Failed to receive GPS ACK"))?; - - let gps_rate_init = ublox::CfgRateBuilder { - measure_rate_ms: 500, - nav_rate: 1, - time_ref: ublox::AlignmentToReferenceTime::Utc, - } - .into_packet_bytes(); - info!("Setting GPS rate to 500ms"); - gps_uart - .write_all(&gps_rate_init) - .map_err(|e| anyhow!("Failed to write GPS rate init packet: {:?}", e))?; - gps_expect_ack(gps_uart, delay).map_err(|_| anyhow!("Failed to receive GPS ACK"))?; - - let nav_pvt_rate_init = - ublox::CfgMsgSinglePortBuilder::set_rate_for::(1).into_packet_bytes(); - info!("Setting NAV-PVT rate to 1 every measurement cycle"); - gps_uart - .write_all(&nav_pvt_rate_init) - .map_err(|e| anyhow!("Failed to write NAV-PVT rate init packet: {:?}", e))?; - gps_expect_ack(gps_uart, delay).map_err(|_| anyhow!("Failed to receive GPS ACK"))?; - - info!("GPS initialized"); - Ok(()) -} +enum StatusEvent {} -fn gps_expect_ack( - uart: &mut esp_hal::uart::Uart, - delay: &esp_hal::delay::Delay, -) -> anyhow::Result<()> -where - T: esp_hal::uart::Instance, - M: esp_hal::Mode, -{ - const BUF_SIZE: usize = 64; - const MAX_ITERATIONS: usize = 100_000; - let mut parser = ublox::Parser::new(Vec::new()); - - let mut i = 0; +#[task] +async fn wifi_connection(mut controller: WifiController<'static>) -> ! { loop { - if i >= MAX_ITERATIONS { - anyhow::bail!("Waiting for ACK timed out"); + if esp_wifi::wifi::get_wifi_state() == WifiState::StaConnected { + // wait until we're no longer connected + controller.wait_for_event(WifiEvent::StaDisconnected).await; + log::info!("WiFi disconnected"); + Timer::after(Duration::from_millis(5000)).await; } - let ready = uart - .read_ready() - .map_err(|e| anyhow!("Failed to check UART read ready: {:?}", e))?; - if !ready { - delay.delay_millis(10u32); - i += 1; - continue; + if !matches!(controller.is_started(), Ok(true)) { + let client_config = Configuration::Client(ClientConfiguration { + ssid: heapless::String::from_str("Gaia").expect("Failed to create SSID string"), + password: heapless::String::from_str(env!("WIFI_PASSWORD")) + .expect("Failed to create password string"), + ..Default::default() + }); + controller + .set_configuration(&client_config) + .expect("Failed to set WiFi configuration"); + log::info!("Starting WiFi..."); + controller + .start() + .await + .expect("Failed to start WiFi controller"); + log::info!("Started WiFi"); } - let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE]; - let len = uart.read(&mut buf).unwrap(); - let mut it = parser.consume(&buf[..len]); - loop { - match it.next() { - Some(Ok(ublox::PacketRef::AckAck(_))) | Some(Ok(ublox::PacketRef::MgaAck(_))) => { - return Ok(()) - } - Some(Ok(ublox::PacketRef::AckNak(_))) => anyhow::bail!("Received NAK from GPS"), - Some(Err(e)) => anyhow::bail!("GPS Error: {:?}", e), - None => { - // done processing packet - // not a valid ACK/NACK, continue to outer waiting loop - i = 0; - break; - } - _ => continue, + log::info!("Connecting to WiFi..."); + match controller.connect().await { + Ok(_) => log::info!("Wifi connected"), + Err(e) => { + log::error!("Failed to connect to WiFi: {:?}", e); + Timer::after(Duration::from_millis(5000)).await } } } } -fn modem_init( - uart: &mut esp_hal::uart::Uart, - pwrkey: &mut esp_hal::gpio::Output, - power_on: &mut esp_hal::gpio::Output, - delay: &esp_hal::delay::Delay, +#[task] +async fn wifi_net_task(stack: &'static embassy_net::Stack>) { + stack.run().await; +} + +#[task] +async fn gps_task(gps: &'static Gps<9600>) { + gps.run().await; +} + +async fn modem_init( + uart: &mut esp_hal::uart::Uart<'_, T, Async>, + pwrkey: &mut esp_hal::gpio::Output<'_, PK>, + power_on: &mut esp_hal::gpio::Output<'_, PO>, ) -> anyhow::Result<()> where T: esp_hal::uart::Instance, - M: esp_hal::Mode, PK: esp_hal::gpio::OutputPin, PO: esp_hal::gpio::OutputPin, { @@ -287,31 +237,29 @@ where power_on.set_high(); pwrkey.set_high(); - delay.delay_millis(100); + Timer::after(Duration::from_millis(100)).await; pwrkey.set_low(); - delay.delay_millis(1_000); + Timer::after(Duration::from_millis(1_000)).await; pwrkey.set_high(); - delay.delay_millis(8_000); + Timer::after(Duration::from_millis(8_000)).await; info!("Modem powered on, initializing..."); uart.flush_tx() .map_err(|e| anyhow!("Failed to flush modem TX: {:?}", e))?; - write!(uart, "AT\r\n").map_err(|e| anyhow!("Failed to write AT command: {:?}", e))?; - modem_expect_ack(uart, delay)?; + uart.write(b"AT\r\n") + .await + .map_err(|e| anyhow!("Failed to write AT command: {:?}", e))?; + modem_expect_ack(uart).await?; Ok(()) } -fn modem_expect_ack( - uart: &mut esp_hal::uart::Uart, - delay: &esp_hal::delay::Delay, -) -> anyhow::Result<()> +async fn modem_expect_ack(uart: &mut esp_hal::uart::Uart<'_, T, Async>) -> anyhow::Result<()> where T: esp_hal::uart::Instance, - M: esp_hal::Mode, { const MAX_ITERATIONS: usize = 100; let mut i = 0; @@ -325,7 +273,7 @@ where .read_ready() .map_err(|e| anyhow!("Failed to check UART read ready: {:?}", e))?; if !ready { - delay.delay_millis(10); + Timer::after(Duration::from_millis(10)).await; i += 1; continue; } @@ -333,6 +281,7 @@ where let mut buf = [0u8; 256]; let len = uart .read(&mut buf) + .await .map_err(|e| anyhow!("Failed to read modem response: {:?}", e))?; let response = core::str::from_utf8(&buf[..len])