Compare commits

..
31 Commits
Author SHA1 Message Date
reed f7b8586424 refactor: move storage initialization to the start_config function 2026-08-17 21:41:49 -05:00
reed d70b35dd92 refactor: use IntEnum instead of a custom implementation for ConfigKey in config.rs 2026-08-17 21:14:00 -05:00
reed 69669f2011 feat: initialize the config service 2026-08-17 21:10:15 -05:00
reed 41647f8d39 chore: remove unused #![feature] 2026-08-17 17:38:01 -05:00
reed 1b7c5e875f style: organize deps 2026-08-17 17:38:01 -05:00
reed aed1e41665 feat: use the embedded-rpc library for the wifi service 2026-08-17 17:38:00 -05:00
reed 8695d0abfa feat: log the error with the wifi config 2026-08-17 17:37:59 -05:00
reed 02a4559268 style: fmt 2026-08-16 22:31:30 -05:00
reed 5216228f88 refactor: rename HttpApiService.serve() to HttpApiService.run() 2026-08-16 22:31:29 -05:00
reed a360aa6b30 refactor: moved the wifi code to a wifi service 2026-08-16 22:31:27 -05:00
reed 851a4d7ff9 chore: cargo update 2026-08-15 23:17:52 -05:00
reed 823e758987 feat: add the clock functionality with NTP support 2026-08-15 23:17:42 -05:00
reed c9a67ea925 chore: update deps 2026-08-15 22:12:29 -05:00
reed 83f467d5c8 refactor: restructure the picoserve code into HttpApiService 2026-08-15 21:23:16 -05:00
reed 6b0e40a926 docs: update old comment 2026-08-10 18:52:38 -05:00
reed 74ae6c40d4 feat: losen the tolerance for the shaft hub clearance diameter on the shaft mount 2026-07-21 18:35:20 -05:00
reed 6f51150803 feat: add counter bore holes for the screws going into the extrusion on the drive_shaft_bar_adapter 2026-07-21 18:35:19 -05:00
reed 3a9e2e5096 feat: angle the track on the drive_shaft_mount to make it more printable 2026-07-21 18:35:18 -05:00
reed 05329e58ad fix: losen tolerance for the extrusion because we are not going for a friction fit 2026-07-21 00:57:16 -05:00
reed 54fa950986 feat: add 1mm of tolerance for the unsupported shaft hub center cutout 2026-07-20 20:05:34 -05:00
reed f4f16c9acd chore: add a outputName for the 3dfiles derivation 2026-07-20 19:19:50 -05:00
reed 927d29da87 feat: add a printable overhand for the track in the adapter 2026-07-20 19:18:24 -05:00
reed 06b1939f72 feat: add a seem channel for the mount 2026-07-20 19:18:02 -05:00
reed 40e4d3500d docs(cad): add TODOs for v2 of the cad objects 2026-07-16 01:35:16 -05:00
reed ec816cc443 feat(cad): add a tolerance for the shaft and correct PolarLocations usage 2026-07-16 01:34:42 -05:00
reed febb91c123 feat(cad): add tracks for the extrusion 2026-06-29 21:41:40 -05:00
reed a690efc920 feat(cad): make drive_shaft_bar_adapter a cylinder 2026-06-29 21:05:50 -05:00
reed 1761e56e1a feat(cad): build the drive_shaft_bar_adapter part in 3d instead of 2d sides with PolarLocations 2026-06-29 20:59:06 -05:00
reed 2bc95a9dd5 feat(cad): create the drive_shaft_bar_adapter part with a temporary implementation 2026-06-29 19:46:28 -05:00
reed 32db86d3cf refactor(cad): wrap the drive_shaft_mount code in a function for organization 2026-06-29 19:45:02 -05:00
reed bb7d3eaeae refactor(cad): change the builder variable to the name of the part 2026-06-25 15:35:19 -05:00
10 changed files with 739 additions and 249 deletions
Generated
+170 -72
View File
@@ -86,7 +86,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9"
dependencies = [
"btuuid",
"defmt 1.1.0",
"defmt 1.1.1",
"embassy-sync 0.8.0",
"embedded-io 0.7.1",
"embedded-io-async 0.7.0",
@@ -158,6 +158,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "cobs"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
dependencies = [
"thiserror",
]
[[package]]
name = "const-default"
version = "1.0.0"
@@ -185,10 +194,14 @@ name = "cover-theif"
version = "0.1.0"
dependencies = [
"critical-section",
"defmt 1.1.0",
"defmt 1.1.1",
"embassy-embedded-hal",
"embassy-executor",
"embassy-futures",
"embassy-net",
"embassy-sync 0.8.0",
"embassy-time",
"embedded-rpc",
"esp-alloc",
"esp-backtrace",
"esp-bootloader-esp-idf",
@@ -196,7 +209,16 @@ dependencies = [
"esp-println",
"esp-radio",
"esp-rtos",
"esp-storage",
"int-enum",
"picoserve",
"portable-atomic",
"postcard",
"sequential-storage",
"serde",
"sntpc",
"sntpc-net-embassy",
"sntpc-time-embassy",
"static_cell",
]
@@ -334,14 +356,14 @@ version = "0.3.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
name = "defmt"
version = "1.1.0"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f"
checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
dependencies = [
"bitflags 1.3.2",
"defmt-macros",
@@ -349,12 +371,11 @@ dependencies = [
[[package]]
name = "defmt-macros"
version = "1.1.0"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b"
checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
dependencies = [
"defmt-parser",
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.117",
@@ -425,9 +446,11 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce"
dependencies = [
"defmt 1.1.1",
"embassy-futures",
"embassy-hal-internal",
"embassy-sync 0.8.0",
"embassy-time",
"embedded-hal 0.2.7",
"embedded-hal 1.0.0",
"embedded-hal-async",
@@ -444,7 +467,7 @@ checksum = "5d0d3b15c9d7dc4fec1d8cb77112472fb008b3b28c51ad23838d83587a6d2f1e"
dependencies = [
"cordyceps",
"critical-section",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embassy-executor-macros",
"embassy-executor-timer-queue",
@@ -474,7 +497,7 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -492,7 +515,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "347bc855bdbdf50ed9c5a1d80e8204badb0ba149b8732dde38e1e9708ed9d313"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embassy-net-driver",
"embassy-sync 0.8.0",
@@ -549,7 +572,7 @@ checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81"
dependencies = [
"cfg-if",
"critical-section",
"defmt 1.1.0",
"defmt 1.1.1",
"embedded-io-async 0.7.0",
"futures-core",
"futures-sink",
@@ -564,7 +587,7 @@ checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a"
dependencies = [
"cfg-if",
"critical-section",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embassy-time-driver",
"embedded-hal 0.2.7",
@@ -641,7 +664,7 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -660,7 +683,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"embedded-io 0.7.1",
]
@@ -683,6 +706,15 @@ dependencies = [
"embedded-nal",
]
[[package]]
name = "embedded-rpc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "691855ab7f974e2aaa87433e0f6e5967a959f312c486f6f929ff1cda14c7f80d"
dependencies = [
"embassy-sync 0.8.0",
]
[[package]]
name = "embedded-storage"
version = "0.3.1"
@@ -704,7 +736,7 @@ version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "839c4174b41e75c8f7306110b2c51996a293b8d1d850edd529011841d9fede7d"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"enumset_derive",
]
@@ -734,7 +766,7 @@ checksum = "46ced060d4085858283df950b80a4da2348e1707d7d07b1e966308582dae79f5"
dependencies = [
"allocator-api2",
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"enumset",
"esp-config",
@@ -750,7 +782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37950e24b2dfd98f1581102d1798281d4d9547af881e6bffc2c2b534c026ec8f"
dependencies = [
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"esp-config",
"esp-metadata-generated",
@@ -767,7 +799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35ffc117c3a9859835d89d0e90f5ee9886ce2264a71a849a7a22ab5308f6653c"
dependencies = [
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embedded-storage",
"esp-config",
@@ -802,7 +834,7 @@ dependencies = [
"bytemuck",
"cfg-if",
"critical-section",
"defmt 1.1.0",
"defmt 1.1.1",
"delegate",
"digest",
"document-features",
@@ -875,7 +907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c0a29815cd105ae1a02f3d0c6e7aafda9504a41effae17fac4c3f827719228"
dependencies = [
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embassy-sync 0.8.0",
"esp-config",
@@ -892,7 +924,7 @@ version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42dee1e9ac7c3539bf6464db1707b0edd7557168f98278cf3c84fe70e63c6ce6"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"esp-metadata-generated",
"esp-sync",
@@ -909,7 +941,7 @@ dependencies = [
"allocator-api2",
"bt-hci",
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"docsplay",
"document-features",
"embassy-net-driver",
@@ -961,7 +993,7 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66a814ae91452de56a5e74f69aebfee40579511756837d3774a56fd24cf0ab79"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"riscv",
"riscv-rt",
@@ -987,7 +1019,7 @@ checksum = "551f90766e1527edaa0c91e8d559e9e2a60397b545e93357ac61fb31845e5712"
dependencies = [
"allocator-api2",
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embassy-executor",
"embassy-sync 0.8.0",
@@ -1006,6 +1038,22 @@ dependencies = [
"xtensa-lx",
]
[[package]]
name = "esp-storage"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cf2b3f00c9f94b27c62a4f5296b19470c3a083c687c8146e554a459f9bee596"
dependencies = [
"defmt 1.1.1",
"document-features",
"embedded-storage",
"esp-hal",
"esp-hal-procmacros",
"esp-metadata-generated",
"esp-rom-sys",
"esp-sync",
]
[[package]]
name = "esp-sync"
version = "0.2.1"
@@ -1013,7 +1061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4736bfbbb9e3f6353344e14fc61b6d18d3b877c3286914cf8c0a037be0ed224"
dependencies = [
"cfg-if",
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"embassy-sync 0.6.2",
"embassy-sync 0.7.2",
@@ -1029,7 +1077,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2556f38f5292d9735d4e156e276815fc001c9a0a2be0544a575c5fb867129d24"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1038,7 +1086,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4b3eb3435dae84de611d4384639e61eed862818223e93fa70c525cb6a70127f"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1047,7 +1095,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b290846b53db9a3965866964260220b67f2c41cc2dbc0b377e7136239fe168a7"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1056,7 +1104,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57649401fc2f906a16e2268de88693724a125adcd0eba89b594a157affcee2d5"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1065,7 +1113,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cf1be2e311f4b4e75b5507c6b007ffc3fcb8c6cb57f83cc6a9569ecdcf58484"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1074,7 +1122,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a9a7f1bc51e7026c3012cda4f11d8799e5e0c0bb3be85797462219def6c26e"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1083,7 +1131,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d8321f44b57d8112cbd8607cc83b85783b9195289acb45532728e3e229e7786"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
]
[[package]]
@@ -1092,7 +1140,7 @@ version = "0.40.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5726e07689249d1a2cb7c492077bc424837fb68a64f7eb5d46569325352e9428"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1102,7 +1150,7 @@ version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef0b623533bbaa37e348c18b6b41cfd5b47c3cb64a4b9e44f0295941d62aa2e"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1112,7 +1160,7 @@ version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21e89ed62cf6c043a6d29c520b02a13b359ec8a75d67b65d4330ed717d15fe97"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1122,7 +1170,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6f8ba56195df10224263c60ceb93b4578450019ee838b7338039a281117cb02"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1132,7 +1180,7 @@ version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58f34ff2633968c12125efc7f4f8f101078d5d34c7cb60eab82268db20986f9"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1142,7 +1190,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a926616351b1edfdb50b7ea6451a8dff0c7515c6ceb687063af7d32b117ec0d"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1152,7 +1200,7 @@ version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5bab026020ed4606ce113b6fde598dbc48f7eefcc46e9469ece77cc2b1aa4be"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1162,7 +1210,7 @@ version = "0.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ad6f21cdf6ec7b06b7f7e0fbe51f0d975fd6a5fa67c3f8a5a910d3981af531"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1172,7 +1220,7 @@ version = "0.35.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b4b8c4e4d9f187553ecdb7173edec7b2deb2beea106eedefecdb1654b8ee25a"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"vcell",
]
@@ -1321,7 +1369,7 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"hash32 0.3.1",
"stable_deref_trait",
]
@@ -1384,6 +1432,18 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "int-enum"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e366a1634cccc76b4cfd3e7580de9b605e4d93f1edac48d786c1f867c0def495"
dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
"syn 2.0.117",
]
[[package]]
name = "itoa"
version = "1.0.18"
@@ -1554,12 +1614,12 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "picoserve"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4976908c758efc04289ad266181f22e252b67daac2710581da9f5aa7a3207a"
checksum = "4aaf10aff74fc2b847b186ae037e91412f5b17a5224ba162a2c1bb41f3f48f86"
dependencies = [
"const-sha1",
"defmt 1.1.0",
"defmt 1.1.1",
"embassy-net",
"embassy-time",
"embedded-io-async 0.7.0",
@@ -1611,9 +1671,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "portable-atomic"
version = "1.13.1"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
[[package]]
name = "portable-atomic-util"
@@ -1645,6 +1705,16 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "postcard"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
dependencies = [
"cobs",
"serde",
]
[[package]]
name = "proc-macro-crate"
version = "3.5.0"
@@ -1654,28 +1724,6 @@ dependencies = [
"toml_edit",
]
[[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 2.0.117",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
@@ -1685,6 +1733,18 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "proc-macro2-diagnostics"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
"version_check",
]
[[package]]
name = "quote"
version = "1.0.45"
@@ -1765,7 +1825,7 @@ version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d07b9f3a0eff773fc4df11f44ada4fa302e529bff4b7fe7e6a4b98a65ce9174"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"riscv",
"riscv-pac",
"riscv-rt-macros",
@@ -1826,6 +1886,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sequential-storage"
version = "8.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e750f14f4f6e5a81277c66311713a56106c8df0196df62a634d1fc806556832b"
dependencies = [
"embedded-storage-async",
]
[[package]]
name = "serde"
version = "1.0.228"
@@ -1916,6 +1985,35 @@ dependencies = [
"managed",
]
[[package]]
name = "sntpc"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "294278b134cd7d06d7f22eca970aebe38707864c080f66547f9ad26327534af3"
dependencies = [
"cfg-if",
]
[[package]]
name = "sntpc-net-embassy"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97d4addcbed51e6aa5178ba85834d1748b70da0f3df4552382a10afbfe285ae3"
dependencies = [
"embassy-net",
"sntpc",
]
[[package]]
name = "sntpc-time-embassy"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "184c354de440d7b2e95a547eb16f2527a1eba1bb666f322782cdb4d4668fc66f"
dependencies = [
"embassy-time",
"sntpc",
]
[[package]]
name = "somni-expr"
version = "0.2.0"
@@ -2254,7 +2352,7 @@ version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "409a9b4629d429e995cde4dfbd9fe562ccae66f7624514e200733fc5d0ea8905"
dependencies = [
"defmt 1.1.0",
"defmt 1.1.1",
"document-features",
"xtensa-lx",
"xtensa-lx-rt-proc-macros",
+21 -5
View File
@@ -18,7 +18,7 @@ esp-rtos = { version = "0.3.0", features = [
"esp32c6",
] }
defmt = "1.1.0"
defmt = "1.1.1"
esp-bootloader-esp-idf = { version = "0.5.0", features = ["defmt", "esp32c6"] }
embassy-executor = { version = "0.10.0", features = ["defmt"] }
@@ -31,10 +31,15 @@ esp-backtrace = { version = "0.19.0", features = [
] }
esp-println = { version = "0.17.0", features = ["defmt-espflash", "esp32c6"] }
critical-section = "1.2.0"
static_cell = "2.1.1"
embassy-sync = { version = "0.8.0", features = ["defmt"] }
embassy-futures = { version = "0.1.2", features = ["defmt"] }
embassy-embedded-hal = { version = "0.6.0", features = ["defmt", "time"] }
embedded-rpc = "0.2.0"
embassy-net = { version = "0.9.0", features = [
critical-section = "1.2.0"
static_cell = { version = "2.1.1", features = ["nightly"] }
embassy-net = { version = "0.9.1", features = [
"defmt",
"dhcpv4-hostname",
"medium-ethernet",
@@ -50,7 +55,18 @@ esp-radio = { version = "0.18.0", features = [
"wifi",
] }
picoserve = { version = "0.18", features = ["defmt", "embassy", "json"] }
sntpc = { version = "0.11", default-features = false }
sntpc-net-embassy = { version = "0.11", default-features = false }
sntpc-time-embassy = { version = "0.6" }
portable-atomic = "1.15.0"
picoserve = { version = "0.19", features = ["defmt", "embassy", "json"] }
sequential-storage = "8.0"
esp-storage = { version = "0.9", features = ["defmt", "esp32c6"] }
postcard = { version = "1.1", default-features = false }
serde = { version = "1.0", default-features = false, features = ["derive"] }
int-enum = "1.2.0"
# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html
+98 -27
View File
@@ -1,34 +1,37 @@
# pyright: reportUnusedCallResult=false, reportWildcardImportFromLibrary=false
from math import radians, sin
from build123d import *
bearing_offset = 20
bearing_diameter = 22
bearing_through_hole_diameter = 15
bearing_height = 7
shaft_clearance_diameter = 25
def build_drive_shaft_mount():
bearing_offset = 20
bearing_diameter = 22
bearing_through_hole_diameter = 15
bearing_height = 7
shaft_clearance_diameter = 25.5
core_width = 40
thickness = 20
core_width = 40
thickness = 20
screw_blocks_width = thickness
screw_blocks_height = bearing_offset
screw_blocks_radius = 3
screw_blocks_width = thickness
screw_blocks_height = bearing_offset
screw_blocks_radius = 3
screw_head_diameter = 8.5
screw_head_depth = 5
screw_body_diameter = 5
screw_head_diameter = 8.5
screw_head_depth = 5
screw_body_diameter = 5
track_width = 6.2
track_height = 1.8
track_width = 6.1
track_height = 1.4
track_angle = 30
assert (bearing_offset - bearing_diameter / 2) > 0
assert (core_width - bearing_diameter) > 0
assert (screw_blocks_width - (screw_blocks_radius * 2)) >= 0
assert (bearing_offset - screw_blocks_height) >= 0
assert (bearing_offset - bearing_diameter / 2) > 0
assert (core_width - bearing_diameter) > 0
assert (screw_blocks_width - (screw_blocks_radius * 2)) >= 0
assert (bearing_offset - screw_blocks_height) >= 0
with BuildPart() as builder:
with BuildSketch() as sketch:
with BuildPart() as drive_shaft_mount:
with BuildSketch():
with BuildLine() as profile:
l1 = Line(
(0,0),
@@ -73,14 +76,82 @@ with BuildPart() as builder:
extrude(amount=thickness / 2)
mirror(about=Plane.XY)
with Locations((0, bearing_offset, builder.faces().sort_by(Axis.Z)[-1].center().Z)):
Hole(bearing_diameter / 2, (thickness / 2) + (bearing_height / 2))
with Locations((0, bearing_offset, drive_shaft_mount.faces().sort_by(Axis.Z)[-1].center().Z)):
Hole(shaft_clearance_diameter / 2, (thickness / 2) - (bearing_height / 2))
Hole(bearing_diameter / 2, (thickness / 2) + (bearing_height / 2))
# this is a seem channel
with BuildSketch(Location((0, bearing_offset + bearing_diameter / 2, drive_shaft_mount.faces().sort_by(Axis.Z)[-1].center().Z))):
Triangle(A=90, b=1, c=1)
extrude(amount=-((thickness / 2) + (bearing_height / 2)), mode=Mode.SUBTRACT)
Box(core_width + (screw_blocks_width * 2), track_width, track_height, (90, 0, 0), (Align.CENTER, Align.CENTER, Align.MIN))
with BuildPart() as track:
Box(core_width + (screw_blocks_width * 2), track_width + ((sin(radians(track_angle))/sin(radians(90-track_angle))) * track_height * 2) - 0.012, track_height, (90, 0, 0), (Align.CENTER, Align.CENTER, Align.MIN))
chamfer(track.edges().filter_by(Axis.X).sort_by(Axis.Y)[:2], track_height - 0.01, angle=track_angle)
with Locations(builder.faces().filter_by(Plane.XZ).sort_by(Axis.Y)[-2:]):
with Locations(drive_shaft_mount.faces().filter_by(Plane.XZ).sort_by(Axis.Y)[-2:]):
CounterBoreHole(screw_body_diameter / 2, screw_head_diameter / 2, screw_head_depth)
assert builder.part is not None
export_step(builder.part, "drive shaft mount.step")
return drive_shaft_mount
def build_drive_shaft_bar_adapter():
ext_size = 20.2
ext_track_width = 6.2
ext_track_height = 1.8
height = 60
thickness = 10
ext_screw_hole_diam = 6
ext_screw_hole_head_diam = 10.5
ext_screw_hole_head_depth = 1
ext_screw_hole_offset = 10
shaft_hub_bore_diam = 8
shaft_hub_center_diam = 14
shaft_hub_center_depth = 3
# if you where to draw a square around the center of the shaft hub this var is the length of the sides and each corner is the center of a screw hole
shaft_hub_screw_spacing = 16
shaft_hub_screw_diam = 4
# the depth of the screw holes into the shaft hub
shaft_hub_screw_depth = 8
shaft_hub_screw_head_depth = 4
shaft_hub_screw_head_diam = 7
with BuildPart() as drive_shaft_bar_adapter:
Cylinder((ext_size / 2) + thickness, height, align=(Align.CENTER, Align.CENTER, Align.MIN))
# cut out space for the extrusion
with BuildSketch(Plane((0, 0, thickness))):
Rectangle(ext_size, ext_size)
with PolarLocations(ext_size / 2, 4):
Rectangle(ext_track_height, ext_track_width, align=(Align.MAX, Align.CENTER), mode=Mode.SUBTRACT)
extrude(amount=height - thickness, mode=Mode.SUBTRACT)
# extrusion screw holes
screws_origin = Location((0, 0, height - ext_screw_hole_offset))
with Locations(screws_origin):
with BuildPart(screws_origin, mode=Mode.SUBTRACT) as ext_track_cut_out:
Box(ext_size, ext_size, ext_screw_hole_diam + 8)
chamfer(ext_track_cut_out.edges(), 3)
with PolarLocations((ext_size / 2) + thickness, 4):
with Locations(Rotation(0, 90, 0)):
CounterBoreHole(ext_screw_hole_diam / 2, ext_screw_hole_head_diam / 2, ext_screw_hole_head_depth)
# shaft interface
with Locations(drive_shaft_bar_adapter.faces().filter_by(Plane.XY).sort_by(Axis.Z)[1].offset(shaft_hub_screw_head_depth)):
l = shaft_hub_screw_spacing / 2
with Locations((-l, -l), (-l, l), (l, -l), (l, l)):
CounterBoreHole(shaft_hub_screw_diam / 2, shaft_hub_screw_head_diam / 2, shaft_hub_screw_head_depth, thickness + shaft_hub_screw_depth)
with Locations(drive_shaft_bar_adapter.faces().sort_by(Axis.Z)[0].center()):
Hole((shaft_hub_bore_diam + 0.5) / 2)
Hole(shaft_hub_center_diam / 2, shaft_hub_center_depth)
return drive_shaft_bar_adapter
drive_shaft_mount = build_drive_shaft_mount()
assert drive_shaft_mount.part is not None
export_step(drive_shaft_mount.part, "drive shaft mount.step")
drive_shaft_bar_adapter = build_drive_shaft_bar_adapter()
assert drive_shaft_bar_adapter.part is not None
export_step(drive_shaft_bar_adapter.part, "drive shaft bar adapter.step")
+2
View File
@@ -43,6 +43,8 @@
enable = true;
builder = ./cad/build.py;
outputName = "cover-theif-3dfiles";
devShell.name = "cad";
package.name = "3dfiles";
};
+20 -104
View File
@@ -6,20 +6,20 @@
holding buffers for the duration of a data transfer."
)]
#![deny(clippy::large_stack_frames)]
#![feature(impl_trait_in_assoc_type)]
use defmt::{error, info};
use cover_theif::wifi::start_wifi;
use defmt::info;
use embassy_executor::Spawner;
use embassy_net::Runner;
use embassy_time::{Duration, Timer};
use esp_backtrace as _;
use esp_hal::clock::CpuClock;
use esp_hal::timer::timg::TimerGroup;
use esp_println as _;
use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
use picoserve::routing::get;
use picoserve::{AppBuilder, AppRouter};
use cover_theif::{
clock,
http_api::{HttpApiProps, HttpApiService},
};
extern crate alloc;
@@ -27,29 +27,6 @@ extern crate alloc;
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf::esp_app_desc!();
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
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
}};
}
const SSID: &str = env!("SSID");
const PASSWORD: &str = env!("PASSWORD");
struct AppProps;
impl AppBuilder for AppProps {
type PathRouter = impl picoserve::routing::PathRouter;
fn build_app(self) -> picoserve::Router<Self::PathRouter> {
picoserve::Router::new().route("/", get(|| async move { "Hello World" }))
}
}
#[allow(
clippy::large_stack_frames,
reason = "it's not unusual to allocate larger buffers etc. in main"
@@ -71,56 +48,19 @@ async fn main(spawner: Spawner) -> ! {
info!("Embassy initialized!");
let wifi_config = esp_radio::wifi::Config::Station(
StationConfig::default()
.with_ssid(SSID)
.with_password(PASSWORD.into()),
let net_stack = start_wifi(spawner, peripherals.WIFI);
spawner.spawn(clock::ntp_upkeep_service(net_stack).unwrap());
spawner.spawn(
http_api_serve_task(HttpApiService::new(
net_stack,
Default::default(),
Default::default(),
))
.unwrap(),
);
let (wifi_controller, wifi_interfaces) = esp_radio::wifi::new(
peripherals.WIFI,
ControllerConfig::default().with_initial_config(wifi_config),
)
.expect("Failed to initialize Wi-Fi controller");
let mut dhcp_config = embassy_net::DhcpConfig::default();
dhcp_config.hostname = Some("cover-theif".try_into().unwrap());
let net_config = embassy_net::Config::dhcpv4(dhcp_config);
let rng = esp_hal::rng::Rng::new();
let seed = (rng.random() as u64) << 32 | rng.random() as u64;
let (net_stack, net_runner) = embassy_net::new(
wifi_interfaces.station,
net_config,
mk_static!(
embassy_net::StackResources<3>,
embassy_net::StackResources::<3>::new()
),
seed,
);
spawner.spawn(connection(wifi_controller).unwrap());
spawner.spawn(net_task(net_runner).unwrap());
net_stack.wait_config_up().await;
if let Some(config) = net_stack.config_v4() {
info!("Got IP: {}", config.address);
}
let app = mk_static!(AppRouter<AppProps>, AppProps.build_app());
let port = 80;
let mut tcp_rx_buffer = [0; 1024];
let mut tcp_tx_buffer = [0; 1024];
let mut http_buffer = [0; 2048];
let web_serve_config = picoserve::Config::const_default().keep_connection_alive();
picoserve::Server::new(app, &web_serve_config, &mut http_buffer)
.listen_and_serve(0, net_stack, port, &mut tcp_rx_buffer, &mut tcp_tx_buffer)
.await;
loop {
info!("Hello world");
Timer::after(Duration::from_secs(1)).await;
@@ -130,30 +70,6 @@ async fn main(spawner: Spawner) -> ! {
}
#[embassy_executor::task]
async fn connection(mut controller: WifiController<'static>) {
info!("start connection task");
loop {
info!("About to connect...");
match controller.connect_async().await {
Ok(info) => {
info!("Wifi connected to {:?}", info);
// wait until we're no longer connected
let info = controller.wait_for_disconnect_async().await.ok();
info!("Disconnected: {:?}", info);
}
Err(e) => {
error!("Failed to connect to wifi: {:?}", e);
}
}
Timer::after(Duration::from_millis(5000)).await
}
}
#[embassy_executor::task]
async fn net_task(mut runner: Runner<'static, Interface<'static>>) {
runner.run().await
async fn http_api_serve_task(mut service: HttpApiService<'static, HttpApiProps>) {
service.run().await;
}
+72
View File
@@ -0,0 +1,72 @@
use core::net::SocketAddr;
use embassy_net::udp::{PacketMetadata, UdpSocket};
use embassy_time::{Duration, Timer};
use portable_atomic::{AtomicU64, Ordering};
use sntpc::{NtpContext, get_time};
use sntpc_net_embassy::UdpSocketWrapper;
use sntpc_time_embassy::EmbassyTimestampGenerator;
// NTP server (pool.ntp.org is the usual choice)
const NTP_SERVER: &str = "pool.ntp.org";
const NTP_PORT: u16 = 123;
static NTP_BOOT_OFFSET: AtomicU64 = AtomicU64::new(0);
pub async fn fetch_ntp_time(stack: embassy_net::Stack<'static>) -> Result<u64, &'static str> {
// Resolve the NTP server hostname
let server_addr = stack
.dns_query(NTP_SERVER, embassy_net::dns::DnsQueryType::A)
.await
.map_err(|_| "DNS resolution failed")?
.first()
.copied()
.ok_or("No DNS result")?;
let socket_addr = SocketAddr::new(server_addr.into(), NTP_PORT);
// Allocate UDP buffers (can be small — SNTP packets are tiny)
let mut rx_meta = [PacketMetadata::EMPTY; 16];
let mut rx_buf = [0u8; 48];
let mut tx_meta = [PacketMetadata::EMPTY; 16];
let mut tx_buf = [0u8; 48];
let mut socket = UdpSocket::new(stack, &mut rx_meta, &mut rx_buf, &mut tx_meta, &mut tx_buf);
socket.bind(0).map_err(|_| "bind failed")?;
let wrapped = UdpSocketWrapper::from(socket);
let ctx = NtpContext::new(EmbassyTimestampGenerator::default());
let result = get_time(socket_addr, &wrapped, ctx)
.await
.map_err(|_| "SNTP request failed")?;
// result.sec is the NTP timestamp in seconds since 1900-01-01.
// Unix epoch is 1900-01-01 + 70 years = 2_208_988_800 seconds.
const NTP_UNIX_OFFSET: u64 = 2_208_988_800;
let unix_secs = result.sec().saturating_sub(NTP_UNIX_OFFSET);
Ok(unix_secs)
}
pub fn now() -> embassy_time::Instant {
embassy_time::Instant::now() + Duration::from_secs(NTP_BOOT_OFFSET.load(Ordering::Relaxed))
}
#[embassy_executor::task]
pub async fn ntp_upkeep_service(stack: embassy_net::Stack<'static>) {
loop {
match fetch_ntp_time(stack).await {
Ok(unix_secs) => {
NTP_BOOT_OFFSET.store(
unix_secs - embassy_time::Instant::now().as_secs(),
portable_atomic::Ordering::Relaxed,
);
Timer::after(Duration::from_secs(6 * 60 * 60)).await
}
Err(err) => {
defmt::error!("Failed to sync the clock from NTP: {}", err);
Timer::after(Duration::from_secs(10)).await
}
}
}
}
+77
View File
@@ -0,0 +1,77 @@
use embassy_embedded_hal::adapter::BlockingAsync;
use embassy_executor::Spawner;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embedded_rpc::RpcService;
use esp_hal::peripherals::FLASH;
use esp_storage::FlashStorage;
use int_enum::IntEnum;
use sequential_storage::{
cache::{Cache, Uncached},
map::{Key, MapConfig, MapStorage, SerializationError},
};
pub enum ConfigCommand {
SetStationCreds(),
}
impl ConfigCommand {
pub async fn set_station_creds() {}
}
pub static CONFIG_SERVICE: RpcService<CriticalSectionRawMutex, ConfigCommand, ()> =
RpcService::new();
pub async fn start_config(spawner: Spawner, flash: FLASH<'static>) {
let storage = MapStorage::<ConfigKey, _, _>::new(
BlockingAsync::new(FlashStorage::new(flash)),
const { MapConfig::new(0x3F_0000..0x40_0000) },
Cache::new_uncached(),
);
spawner.spawn(config_handler(storage).unwrap());
}
#[embassy_executor::task]
async fn config_handler(mut storage: MapStorage<ConfigKey, BlockingAsync<FlashStorage<'static>>, Cache<Uncached, Uncached, Uncached, ConfigKey>>) {
let mut data_buffer = [0u8; 256];
loop {
let (req, served) = CONFIG_SERVICE.serve().await;
match req {
ConfigCommand::SetStationCreds() => {
todo!()
// if storage
// .store_item(&mut data_buffer, &ConfigKey::Wifi, )
// .await
// .is_ok()
// {
// served.respond(());
// }
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, IntEnum)]
#[repr(u8)]
enum ConfigKey {
Wifi,
}
impl Key for ConfigKey {
fn get_len(_: &[u8]) -> Result<usize, SerializationError> {
Ok(1)
}
fn serialize_into(&self, buffer: &mut [u8]) -> Result<usize, SerializationError> {
let val = buffer.get_mut(0).ok_or(SerializationError::BufferTooSmall)?;
*val = self.clone().into();
Ok(1)
}
fn deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError> {
let val = *buffer.get(0).ok_or(SerializationError::BufferTooSmall)?;
Ok((val.try_into().map_err(|_| {SerializationError::InvalidData})?, 1))
}
}
+70
View File
@@ -0,0 +1,70 @@
use embassy_net::Stack;
use picoserve::routing::get;
use picoserve::{AppBuilder, AppRouter, Config};
#[derive(Default)]
pub struct HttpApiProps;
impl AppBuilder for HttpApiProps {
type PathRouter = impl picoserve::routing::PathRouter;
fn build_app(self) -> picoserve::Router<Self::PathRouter> {
picoserve::Router::new().route("/", get(|| async move { "Hello World" }))
}
}
pub struct HttpApiConfig {
pub port: u16,
pub web_serve_config: Config,
}
impl Default for HttpApiConfig {
fn default() -> Self {
Self {
port: 80,
web_serve_config: Config::const_default().keep_connection_alive(),
}
}
}
pub struct HttpApiService<'a, AB: AppBuilder> {
config: HttpApiConfig,
net_stack: Stack<'a>,
app: AppRouter<AB>,
tcp_rx_buffer: [u8; 1024],
tcp_tx_buffer: [u8; 1024],
http_buffer: [u8; 2048],
}
impl<'a, AB: AppBuilder> HttpApiService<'a, AB> {
pub fn new(net_stack: Stack<'a>, config: HttpApiConfig, app: AB) -> Self {
Self {
config: config,
net_stack: net_stack,
app: app.build_app(),
tcp_rx_buffer: [0; 1024],
tcp_tx_buffer: [0; 1024],
http_buffer: [0; 2048],
}
}
pub async fn run(&mut self) {
picoserve::Server::new(
&self.app,
&self.config.web_serve_config,
&mut self.http_buffer,
)
.listen_and_serve(
0,
self.net_stack,
self.config.port,
&mut self.tcp_rx_buffer,
&mut self.tcp_tx_buffer,
)
.await;
}
}
+26
View File
@@ -1 +1,27 @@
#![no_std]
#![deny(
clippy::mem_forget,
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::large_stack_frames)]
#![feature(impl_trait_in_assoc_type)]
pub mod http_api;
pub mod clock;
pub mod wifi;
pub mod config;
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
#[macro_export]
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
}};
}
+142
View File
@@ -0,0 +1,142 @@
use defmt::{error, info};
use embassy_executor::Spawner;
use embassy_futures::select::{Either, select};
use embassy_net::{Runner, Stack};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_time::{Duration, Timer};
use embedded_rpc::{RequestDroppedError, RpcService};
use esp_hal::peripherals::WIFI;
use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
pub enum WifiCommand {
SetStationConfig(esp_radio::wifi::Config),
SetDhcpConfig(embassy_net::DhcpConfig),
}
impl WifiCommand {
pub async fn set_station_config(
config: esp_radio::wifi::Config,
) -> Result<(), RequestDroppedError> {
WIFI_SERVICE
.request(WifiCommand::SetStationConfig(config))
.await
}
}
pub static WIFI_SERVICE: RpcService<CriticalSectionRawMutex, WifiCommand, ()> = RpcService::new();
pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
let wifi_config = esp_radio::wifi::Config::Station(StationConfig::default());
let (wifi_controller, wifi_interfaces) = esp_radio::wifi::new(
wifi,
ControllerConfig::default().with_initial_config(wifi_config),
)
.expect("Failed to initialize Wi-Fi controller");
let mut dhcp_config = embassy_net::DhcpConfig::default();
dhcp_config.hostname = Some("cover-theif".try_into().unwrap());
let net_config = embassy_net::Config::dhcpv4(dhcp_config);
let rng = esp_hal::rng::Rng::new();
let seed = (rng.random() as u64) << 32 | rng.random() as u64;
let (net_stack, net_runner) = embassy_net::new(
wifi_interfaces.station,
net_config,
crate::mk_static!(
embassy_net::StackResources<3>,
embassy_net::StackResources::<3>::new()
),
seed,
);
spawner.spawn(net_task(net_runner).unwrap());
spawner.spawn(wifi_handler(wifi_controller).unwrap());
spawner.spawn(ip_logger(net_stack).unwrap());
spawner.spawn(handler(net_stack).unwrap());
net_stack
}
#[embassy_executor::task]
async fn handler(net_stack: Stack<'static>) {
loop {
let (req, served) = WIFI_SERVICE.serve().await;
match req {
WifiCommand::SetStationConfig(config) => {
if WIFI_HANDLER_RPC.request(config).await.is_err() {
continue;
}
}
WifiCommand::SetDhcpConfig(dhcp_config) => {
net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(dhcp_config));
}
}
served.respond(());
}
}
static WIFI_HANDLER_RPC: RpcService<CriticalSectionRawMutex, esp_radio::wifi::Config, ()> =
RpcService::new();
#[embassy_executor::task]
async fn wifi_handler(mut controller: WifiController<'static>) {
let connection = async |controller: &mut WifiController<'static>| {
info!("Connecting to WiFi...");
match controller.connect_async().await {
Ok(info) => {
info!("Wifi connected to {:?}", info);
// wait until we're no longer connected
let info = controller.wait_for_disconnect_async().await.ok();
info!("Disconnected: {:?}", info);
}
Err(e) => {
error!("Failed to connect to wifi: {:?}", e);
}
}
};
loop {
if let Either::First((req, served)) =
select(WIFI_HANDLER_RPC.serve(), connection(&mut controller)).await
{
if controller.set_config(&req).is_ok() {
served.respond(());
}
}
}
}
#[embassy_executor::task]
async fn ip_logger(net_stack: Stack<'static>) {
loop {
info!("Getting IP address...");
net_stack.wait_config_up().await;
match net_stack.config_v4() {
Some(info) => {
info!("Got IP: {:?}", info);
// wait until we're no longer connected
net_stack.wait_config_down().await;
info!("Address no longer configured");
}
None => {
error!("Failed to configure an address");
}
}
Timer::after(Duration::from_millis(5000)).await
}
}
#[embassy_executor::task]
async fn net_task(mut runner: Runner<'static, Interface<'static>>) {
runner.run().await
}