Repo for designs & driver for a TA7642 powered lightning detector

feat: Embassy driver

+1986 -1
+21
.tangled/workflows/test.yml
··· 1 + when: 2 + - event: ["push", "pull_request"] 3 + branch: main 4 + 5 + engine: nixery 6 + 7 + dependencies: 8 + nixpkgs: 9 + - clang 10 + - cargo 11 + - rustfmt 12 + - protobuf 13 + - cargo-nextest 14 + 15 + steps: 16 + - name: Format check 17 + command: cargo fmt --all --check 18 + - name: Tests 19 + command: cargo nextest run --workspace --locked --no-fail-fast 20 + - name: Doc Tests 21 + command: cargo test --workspace --locked --doc --no-fail-fast
+1158
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 4 4 + 5 + [[package]] 6 + name = "aho-corasick" 7 + version = "1.1.4" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" 10 + dependencies = [ 11 + "memchr", 12 + ] 13 + 14 + [[package]] 15 + name = "arrayvec" 16 + version = "0.7.6" 17 + source = "registry+https://github.com/rust-lang/crates.io-index" 18 + checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 19 + 20 + [[package]] 21 + name = "ascii-canvas" 22 + version = "4.0.0" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" 25 + dependencies = [ 26 + "term", 27 + ] 28 + 29 + [[package]] 30 + name = "autocfg" 31 + version = "1.5.0" 32 + source = "registry+https://github.com/rust-lang/crates.io-index" 33 + checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 34 + 35 + [[package]] 36 + name = "az" 37 + version = "1.3.0" 38 + source = "registry+https://github.com/rust-lang/crates.io-index" 39 + checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" 40 + 41 + [[package]] 42 + name = "bare-metal" 43 + version = "0.2.5" 44 + source = "registry+https://github.com/rust-lang/crates.io-index" 45 + checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" 46 + dependencies = [ 47 + "rustc_version", 48 + ] 49 + 50 + [[package]] 51 + name = "bit-set" 52 + version = "0.8.0" 53 + source = "registry+https://github.com/rust-lang/crates.io-index" 54 + checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" 55 + dependencies = [ 56 + "bit-vec", 57 + ] 58 + 59 + [[package]] 60 + name = "bit-vec" 61 + version = "0.8.0" 62 + source = "registry+https://github.com/rust-lang/crates.io-index" 63 + checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" 64 + 65 + [[package]] 66 + name = "bitfield" 67 + version = "0.13.2" 68 + source = "registry+https://github.com/rust-lang/crates.io-index" 69 + checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" 70 + 71 + [[package]] 72 + name = "bitflags" 73 + version = "2.10.0" 74 + source = "registry+https://github.com/rust-lang/crates.io-index" 75 + checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" 76 + 77 + [[package]] 78 + name = "block-buffer" 79 + version = "0.10.4" 80 + source = "registry+https://github.com/rust-lang/crates.io-index" 81 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 82 + dependencies = [ 83 + "generic-array", 84 + ] 85 + 86 + [[package]] 87 + name = "bytemuck" 88 + version = "1.24.0" 89 + source = "registry+https://github.com/rust-lang/crates.io-index" 90 + checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" 91 + 92 + [[package]] 93 + name = "byteorder" 94 + version = "1.5.0" 95 + source = "registry+https://github.com/rust-lang/crates.io-index" 96 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 97 + 98 + [[package]] 99 + name = "cfg-if" 100 + version = "1.0.4" 101 + source = "registry+https://github.com/rust-lang/crates.io-index" 102 + checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 103 + 104 + [[package]] 105 + name = "codespan-reporting" 106 + version = "0.11.1" 107 + source = "registry+https://github.com/rust-lang/crates.io-index" 108 + checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 109 + dependencies = [ 110 + "termcolor", 111 + "unicode-width", 112 + ] 113 + 114 + [[package]] 115 + name = "cortex-m" 116 + version = "0.7.7" 117 + source = "registry+https://github.com/rust-lang/crates.io-index" 118 + checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" 119 + dependencies = [ 120 + "bare-metal", 121 + "bitfield", 122 + "embedded-hal 0.2.7", 123 + "volatile-register", 124 + ] 125 + 126 + [[package]] 127 + name = "cortex-m-rt" 128 + version = "0.7.5" 129 + source = "registry+https://github.com/rust-lang/crates.io-index" 130 + checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" 131 + dependencies = [ 132 + "cortex-m-rt-macros", 133 + ] 134 + 135 + [[package]] 136 + name = "cortex-m-rt-macros" 137 + version = "0.7.5" 138 + source = "registry+https://github.com/rust-lang/crates.io-index" 139 + checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" 140 + dependencies = [ 141 + "proc-macro2", 142 + "quote", 143 + "syn", 144 + ] 145 + 146 + [[package]] 147 + name = "cpufeatures" 148 + version = "0.2.17" 149 + source = "registry+https://github.com/rust-lang/crates.io-index" 150 + checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 151 + dependencies = [ 152 + "libc", 153 + ] 154 + 155 + [[package]] 156 + name = "crc-any" 157 + version = "2.5.0" 158 + source = "registry+https://github.com/rust-lang/crates.io-index" 159 + checksum = "a62ec9ff5f7965e4d7280bd5482acd20aadb50d632cf6c1d74493856b011fa73" 160 + dependencies = [ 161 + "debug-helper", 162 + ] 163 + 164 + [[package]] 165 + name = "critical-section" 166 + version = "1.2.0" 167 + source = "registry+https://github.com/rust-lang/crates.io-index" 168 + checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" 169 + 170 + [[package]] 171 + name = "crunchy" 172 + version = "0.2.4" 173 + source = "registry+https://github.com/rust-lang/crates.io-index" 174 + checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" 175 + 176 + [[package]] 177 + name = "crypto-common" 178 + version = "0.1.7" 179 + source = "registry+https://github.com/rust-lang/crates.io-index" 180 + checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" 181 + dependencies = [ 182 + "generic-array", 183 + "typenum", 184 + ] 185 + 186 + [[package]] 187 + name = "debug-helper" 188 + version = "0.3.13" 189 + source = "registry+https://github.com/rust-lang/crates.io-index" 190 + checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" 191 + 192 + [[package]] 193 + name = "digest" 194 + version = "0.10.7" 195 + source = "registry+https://github.com/rust-lang/crates.io-index" 196 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 197 + dependencies = [ 198 + "block-buffer", 199 + "crypto-common", 200 + ] 201 + 202 + [[package]] 203 + name = "document-features" 204 + version = "0.2.12" 205 + source = "registry+https://github.com/rust-lang/crates.io-index" 206 + checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" 207 + dependencies = [ 208 + "litrs", 209 + ] 210 + 211 + [[package]] 212 + name = "either" 213 + version = "1.15.0" 214 + source = "registry+https://github.com/rust-lang/crates.io-index" 215 + checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 216 + 217 + [[package]] 218 + name = "embassy-embedded-hal" 219 + version = "0.5.0" 220 + source = "registry+https://github.com/rust-lang/crates.io-index" 221 + checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" 222 + dependencies = [ 223 + "embassy-futures", 224 + "embassy-hal-internal", 225 + "embassy-sync", 226 + "embedded-hal 0.2.7", 227 + "embedded-hal 1.0.0", 228 + "embedded-hal-async", 229 + "embedded-storage", 230 + "embedded-storage-async", 231 + "nb 1.1.0", 232 + ] 233 + 234 + [[package]] 235 + name = "embassy-executor-timer-queue" 236 + version = "0.1.0" 237 + source = "registry+https://github.com/rust-lang/crates.io-index" 238 + checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" 239 + 240 + [[package]] 241 + name = "embassy-futures" 242 + version = "0.1.2" 243 + source = "registry+https://github.com/rust-lang/crates.io-index" 244 + checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" 245 + 246 + [[package]] 247 + name = "embassy-hal-internal" 248 + version = "0.3.0" 249 + source = "registry+https://github.com/rust-lang/crates.io-index" 250 + checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" 251 + dependencies = [ 252 + "cortex-m", 253 + "critical-section", 254 + "num-traits", 255 + ] 256 + 257 + [[package]] 258 + name = "embassy-rp" 259 + version = "0.9.0" 260 + source = "registry+https://github.com/rust-lang/crates.io-index" 261 + checksum = "af8d5ac11a8bc209d359ad98bb10a10f786471dd474790f3a4f991c77ae94f6f" 262 + dependencies = [ 263 + "cfg-if", 264 + "cortex-m", 265 + "cortex-m-rt", 266 + "critical-section", 267 + "document-features", 268 + "embassy-embedded-hal", 269 + "embassy-futures", 270 + "embassy-hal-internal", 271 + "embassy-sync", 272 + "embassy-time", 273 + "embassy-usb-driver", 274 + "embedded-hal 0.2.7", 275 + "embedded-hal 1.0.0", 276 + "embedded-hal-async", 277 + "embedded-hal-nb", 278 + "embedded-io", 279 + "embedded-io-async", 280 + "embedded-storage", 281 + "embedded-storage-async", 282 + "fixed", 283 + "nb 1.1.0", 284 + "pio", 285 + "rand_core 0.6.4", 286 + "rand_core 0.9.5", 287 + "rp-pac", 288 + "rp2040-boot2", 289 + "sha2-const-stable", 290 + "smart-leds", 291 + ] 292 + 293 + [[package]] 294 + name = "embassy-strike-driver" 295 + version = "0.1.0" 296 + dependencies = [ 297 + "critical-section", 298 + "embassy-rp", 299 + "embassy-sync", 300 + "embassy-time", 301 + "heapless 0.9.2", 302 + "pollster", 303 + ] 304 + 305 + [[package]] 306 + name = "embassy-sync" 307 + version = "0.7.2" 308 + source = "registry+https://github.com/rust-lang/crates.io-index" 309 + checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" 310 + dependencies = [ 311 + "cfg-if", 312 + "critical-section", 313 + "embedded-io-async", 314 + "futures-core", 315 + "futures-sink", 316 + "heapless 0.8.0", 317 + ] 318 + 319 + [[package]] 320 + name = "embassy-time" 321 + version = "0.5.0" 322 + source = "registry+https://github.com/rust-lang/crates.io-index" 323 + checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" 324 + dependencies = [ 325 + "cfg-if", 326 + "critical-section", 327 + "document-features", 328 + "embassy-time-driver", 329 + "embassy-time-queue-utils", 330 + "embedded-hal 0.2.7", 331 + "embedded-hal 1.0.0", 332 + "embedded-hal-async", 333 + "futures-core", 334 + ] 335 + 336 + [[package]] 337 + name = "embassy-time-driver" 338 + version = "0.2.1" 339 + source = "registry+https://github.com/rust-lang/crates.io-index" 340 + checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" 341 + dependencies = [ 342 + "document-features", 343 + ] 344 + 345 + [[package]] 346 + name = "embassy-time-queue-utils" 347 + version = "0.3.0" 348 + source = "registry+https://github.com/rust-lang/crates.io-index" 349 + checksum = "80e2ee86063bd028a420a5fb5898c18c87a8898026da1d4c852af2c443d0a454" 350 + dependencies = [ 351 + "embassy-executor-timer-queue", 352 + "heapless 0.8.0", 353 + ] 354 + 355 + [[package]] 356 + name = "embassy-usb-driver" 357 + version = "0.2.0" 358 + source = "registry+https://github.com/rust-lang/crates.io-index" 359 + checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" 360 + dependencies = [ 361 + "embedded-io-async", 362 + ] 363 + 364 + [[package]] 365 + name = "embedded-hal" 366 + version = "0.2.7" 367 + source = "registry+https://github.com/rust-lang/crates.io-index" 368 + checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" 369 + dependencies = [ 370 + "nb 0.1.3", 371 + "void", 372 + ] 373 + 374 + [[package]] 375 + name = "embedded-hal" 376 + version = "1.0.0" 377 + source = "registry+https://github.com/rust-lang/crates.io-index" 378 + checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" 379 + 380 + [[package]] 381 + name = "embedded-hal-async" 382 + version = "1.0.0" 383 + source = "registry+https://github.com/rust-lang/crates.io-index" 384 + checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" 385 + dependencies = [ 386 + "embedded-hal 1.0.0", 387 + ] 388 + 389 + [[package]] 390 + name = "embedded-hal-nb" 391 + version = "1.0.0" 392 + source = "registry+https://github.com/rust-lang/crates.io-index" 393 + checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" 394 + dependencies = [ 395 + "embedded-hal 1.0.0", 396 + "nb 1.1.0", 397 + ] 398 + 399 + [[package]] 400 + name = "embedded-io" 401 + version = "0.6.1" 402 + source = "registry+https://github.com/rust-lang/crates.io-index" 403 + checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" 404 + 405 + [[package]] 406 + name = "embedded-io-async" 407 + version = "0.6.1" 408 + source = "registry+https://github.com/rust-lang/crates.io-index" 409 + checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" 410 + dependencies = [ 411 + "embedded-io", 412 + ] 413 + 414 + [[package]] 415 + name = "embedded-storage" 416 + version = "0.3.1" 417 + source = "registry+https://github.com/rust-lang/crates.io-index" 418 + checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" 419 + 420 + [[package]] 421 + name = "embedded-storage-async" 422 + version = "0.4.1" 423 + source = "registry+https://github.com/rust-lang/crates.io-index" 424 + checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" 425 + dependencies = [ 426 + "embedded-storage", 427 + ] 428 + 429 + [[package]] 430 + name = "ena" 431 + version = "0.14.3" 432 + source = "registry+https://github.com/rust-lang/crates.io-index" 433 + checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" 434 + dependencies = [ 435 + "log", 436 + ] 437 + 438 + [[package]] 439 + name = "equivalent" 440 + version = "1.0.2" 441 + source = "registry+https://github.com/rust-lang/crates.io-index" 442 + checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 443 + 444 + [[package]] 445 + name = "fixed" 446 + version = "1.30.0" 447 + source = "registry+https://github.com/rust-lang/crates.io-index" 448 + checksum = "c566da967934c6c7ee0458a9773de9b2a685bd2ce26a3b28ddfc740e640182f5" 449 + dependencies = [ 450 + "az", 451 + "bytemuck", 452 + "half", 453 + "typenum", 454 + ] 455 + 456 + [[package]] 457 + name = "fixedbitset" 458 + version = "0.5.7" 459 + source = "registry+https://github.com/rust-lang/crates.io-index" 460 + checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" 461 + 462 + [[package]] 463 + name = "futures-core" 464 + version = "0.3.31" 465 + source = "registry+https://github.com/rust-lang/crates.io-index" 466 + checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 467 + 468 + [[package]] 469 + name = "futures-sink" 470 + version = "0.3.31" 471 + source = "registry+https://github.com/rust-lang/crates.io-index" 472 + checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 473 + 474 + [[package]] 475 + name = "generic-array" 476 + version = "0.14.7" 477 + source = "registry+https://github.com/rust-lang/crates.io-index" 478 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 479 + dependencies = [ 480 + "typenum", 481 + "version_check", 482 + ] 483 + 484 + [[package]] 485 + name = "half" 486 + version = "2.7.1" 487 + source = "registry+https://github.com/rust-lang/crates.io-index" 488 + checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" 489 + dependencies = [ 490 + "cfg-if", 491 + "crunchy", 492 + "zerocopy", 493 + ] 494 + 495 + [[package]] 496 + name = "hash32" 497 + version = "0.3.1" 498 + source = "registry+https://github.com/rust-lang/crates.io-index" 499 + checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" 500 + dependencies = [ 501 + "byteorder", 502 + ] 503 + 504 + [[package]] 505 + name = "hashbrown" 506 + version = "0.16.1" 507 + source = "registry+https://github.com/rust-lang/crates.io-index" 508 + checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" 509 + 510 + [[package]] 511 + name = "heapless" 512 + version = "0.8.0" 513 + source = "registry+https://github.com/rust-lang/crates.io-index" 514 + checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" 515 + dependencies = [ 516 + "hash32", 517 + "stable_deref_trait", 518 + ] 519 + 520 + [[package]] 521 + name = "heapless" 522 + version = "0.9.2" 523 + source = "registry+https://github.com/rust-lang/crates.io-index" 524 + checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" 525 + dependencies = [ 526 + "hash32", 527 + "stable_deref_trait", 528 + ] 529 + 530 + [[package]] 531 + name = "indexmap" 532 + version = "2.13.0" 533 + source = "registry+https://github.com/rust-lang/crates.io-index" 534 + checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" 535 + dependencies = [ 536 + "equivalent", 537 + "hashbrown", 538 + ] 539 + 540 + [[package]] 541 + name = "itertools" 542 + version = "0.14.0" 543 + source = "registry+https://github.com/rust-lang/crates.io-index" 544 + checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" 545 + dependencies = [ 546 + "either", 547 + ] 548 + 549 + [[package]] 550 + name = "keccak" 551 + version = "0.1.5" 552 + source = "registry+https://github.com/rust-lang/crates.io-index" 553 + checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" 554 + dependencies = [ 555 + "cpufeatures", 556 + ] 557 + 558 + [[package]] 559 + name = "lalrpop" 560 + version = "0.22.2" 561 + source = "registry+https://github.com/rust-lang/crates.io-index" 562 + checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" 563 + dependencies = [ 564 + "ascii-canvas", 565 + "bit-set", 566 + "ena", 567 + "itertools", 568 + "lalrpop-util", 569 + "petgraph", 570 + "pico-args", 571 + "regex", 572 + "regex-syntax", 573 + "sha3", 574 + "string_cache", 575 + "term", 576 + "unicode-xid", 577 + "walkdir", 578 + ] 579 + 580 + [[package]] 581 + name = "lalrpop-util" 582 + version = "0.22.2" 583 + source = "registry+https://github.com/rust-lang/crates.io-index" 584 + checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" 585 + dependencies = [ 586 + "regex-automata", 587 + "rustversion", 588 + ] 589 + 590 + [[package]] 591 + name = "libc" 592 + version = "0.2.180" 593 + source = "registry+https://github.com/rust-lang/crates.io-index" 594 + checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" 595 + 596 + [[package]] 597 + name = "litrs" 598 + version = "1.0.0" 599 + source = "registry+https://github.com/rust-lang/crates.io-index" 600 + checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" 601 + 602 + [[package]] 603 + name = "lock_api" 604 + version = "0.4.14" 605 + source = "registry+https://github.com/rust-lang/crates.io-index" 606 + checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" 607 + dependencies = [ 608 + "scopeguard", 609 + ] 610 + 611 + [[package]] 612 + name = "log" 613 + version = "0.4.29" 614 + source = "registry+https://github.com/rust-lang/crates.io-index" 615 + checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" 616 + 617 + [[package]] 618 + name = "memchr" 619 + version = "2.7.6" 620 + source = "registry+https://github.com/rust-lang/crates.io-index" 621 + checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" 622 + 623 + [[package]] 624 + name = "nb" 625 + version = "0.1.3" 626 + source = "registry+https://github.com/rust-lang/crates.io-index" 627 + checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" 628 + dependencies = [ 629 + "nb 1.1.0", 630 + ] 631 + 632 + [[package]] 633 + name = "nb" 634 + version = "1.1.0" 635 + source = "registry+https://github.com/rust-lang/crates.io-index" 636 + checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" 637 + 638 + [[package]] 639 + name = "new_debug_unreachable" 640 + version = "1.0.6" 641 + source = "registry+https://github.com/rust-lang/crates.io-index" 642 + checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 643 + 644 + [[package]] 645 + name = "num-traits" 646 + version = "0.2.19" 647 + source = "registry+https://github.com/rust-lang/crates.io-index" 648 + checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 649 + dependencies = [ 650 + "autocfg", 651 + ] 652 + 653 + [[package]] 654 + name = "num_enum" 655 + version = "0.7.5" 656 + source = "registry+https://github.com/rust-lang/crates.io-index" 657 + checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" 658 + dependencies = [ 659 + "num_enum_derive", 660 + "rustversion", 661 + ] 662 + 663 + [[package]] 664 + name = "num_enum_derive" 665 + version = "0.7.5" 666 + source = "registry+https://github.com/rust-lang/crates.io-index" 667 + checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" 668 + dependencies = [ 669 + "proc-macro2", 670 + "quote", 671 + "syn", 672 + ] 673 + 674 + [[package]] 675 + name = "parking_lot" 676 + version = "0.12.5" 677 + source = "registry+https://github.com/rust-lang/crates.io-index" 678 + checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" 679 + dependencies = [ 680 + "lock_api", 681 + "parking_lot_core", 682 + ] 683 + 684 + [[package]] 685 + name = "parking_lot_core" 686 + version = "0.9.12" 687 + source = "registry+https://github.com/rust-lang/crates.io-index" 688 + checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" 689 + dependencies = [ 690 + "cfg-if", 691 + "libc", 692 + "redox_syscall", 693 + "smallvec", 694 + "windows-link", 695 + ] 696 + 697 + [[package]] 698 + name = "paste" 699 + version = "1.0.15" 700 + source = "registry+https://github.com/rust-lang/crates.io-index" 701 + checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 702 + 703 + [[package]] 704 + name = "petgraph" 705 + version = "0.7.1" 706 + source = "registry+https://github.com/rust-lang/crates.io-index" 707 + checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" 708 + dependencies = [ 709 + "fixedbitset", 710 + "indexmap", 711 + ] 712 + 713 + [[package]] 714 + name = "phf_shared" 715 + version = "0.11.3" 716 + source = "registry+https://github.com/rust-lang/crates.io-index" 717 + checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" 718 + dependencies = [ 719 + "siphasher", 720 + ] 721 + 722 + [[package]] 723 + name = "pico-args" 724 + version = "0.5.0" 725 + source = "registry+https://github.com/rust-lang/crates.io-index" 726 + checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" 727 + 728 + [[package]] 729 + name = "pio" 730 + version = "0.3.0" 731 + source = "registry+https://github.com/rust-lang/crates.io-index" 732 + checksum = "d0ba4153cee9585abc451271aa437d9e8defdea8b468d48ba6b8f098cbe03d7f" 733 + dependencies = [ 734 + "pio-core", 735 + "pio-proc", 736 + ] 737 + 738 + [[package]] 739 + name = "pio-core" 740 + version = "0.3.0" 741 + source = "registry+https://github.com/rust-lang/crates.io-index" 742 + checksum = "61d90fddc3d67f21bbf93683bc461b05d6a29c708caf3ffb79947d7ff7095406" 743 + dependencies = [ 744 + "arrayvec", 745 + "num_enum", 746 + "paste", 747 + ] 748 + 749 + [[package]] 750 + name = "pio-parser" 751 + version = "0.3.0" 752 + source = "registry+https://github.com/rust-lang/crates.io-index" 753 + checksum = "825266c1eaddf54f636d06eefa4bf3c99d774c14ec46a4a6c6e5128a0f10d205" 754 + dependencies = [ 755 + "lalrpop", 756 + "lalrpop-util", 757 + "pio-core", 758 + ] 759 + 760 + [[package]] 761 + name = "pio-proc" 762 + version = "0.3.0" 763 + source = "registry+https://github.com/rust-lang/crates.io-index" 764 + checksum = "ed4a76571f5fe51af43cc80ac870fe0c79cc0cdd686b9002a6c4c84bfdd0176b" 765 + dependencies = [ 766 + "codespan-reporting", 767 + "lalrpop-util", 768 + "pio-core", 769 + "pio-parser", 770 + "proc-macro-error2", 771 + "proc-macro2", 772 + "quote", 773 + "syn", 774 + ] 775 + 776 + [[package]] 777 + name = "pollster" 778 + version = "0.4.0" 779 + source = "registry+https://github.com/rust-lang/crates.io-index" 780 + checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" 781 + dependencies = [ 782 + "pollster-macro", 783 + ] 784 + 785 + [[package]] 786 + name = "pollster-macro" 787 + version = "0.4.0" 788 + source = "registry+https://github.com/rust-lang/crates.io-index" 789 + checksum = "ac5da421106a50887c5b51d20806867db377fbb86bacf478ee0500a912e0c113" 790 + dependencies = [ 791 + "proc-macro2", 792 + "quote", 793 + "syn", 794 + ] 795 + 796 + [[package]] 797 + name = "precomputed-hash" 798 + version = "0.1.1" 799 + source = "registry+https://github.com/rust-lang/crates.io-index" 800 + checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" 801 + 802 + [[package]] 803 + name = "proc-macro-error-attr2" 804 + version = "2.0.0" 805 + source = "registry+https://github.com/rust-lang/crates.io-index" 806 + checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 807 + dependencies = [ 808 + "proc-macro2", 809 + "quote", 810 + ] 811 + 812 + [[package]] 813 + name = "proc-macro-error2" 814 + version = "2.0.1" 815 + source = "registry+https://github.com/rust-lang/crates.io-index" 816 + checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 817 + dependencies = [ 818 + "proc-macro-error-attr2", 819 + "proc-macro2", 820 + "quote", 821 + "syn", 822 + ] 823 + 824 + [[package]] 825 + name = "proc-macro2" 826 + version = "1.0.106" 827 + source = "registry+https://github.com/rust-lang/crates.io-index" 828 + checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" 829 + dependencies = [ 830 + "unicode-ident", 831 + ] 832 + 833 + [[package]] 834 + name = "quote" 835 + version = "1.0.44" 836 + source = "registry+https://github.com/rust-lang/crates.io-index" 837 + checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" 838 + dependencies = [ 839 + "proc-macro2", 840 + ] 841 + 842 + [[package]] 843 + name = "rand_core" 844 + version = "0.6.4" 845 + source = "registry+https://github.com/rust-lang/crates.io-index" 846 + checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 847 + 848 + [[package]] 849 + name = "rand_core" 850 + version = "0.9.5" 851 + source = "registry+https://github.com/rust-lang/crates.io-index" 852 + checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" 853 + 854 + [[package]] 855 + name = "redox_syscall" 856 + version = "0.5.18" 857 + source = "registry+https://github.com/rust-lang/crates.io-index" 858 + checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" 859 + dependencies = [ 860 + "bitflags", 861 + ] 862 + 863 + [[package]] 864 + name = "regex" 865 + version = "1.12.2" 866 + source = "registry+https://github.com/rust-lang/crates.io-index" 867 + checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" 868 + dependencies = [ 869 + "aho-corasick", 870 + "memchr", 871 + "regex-automata", 872 + "regex-syntax", 873 + ] 874 + 875 + [[package]] 876 + name = "regex-automata" 877 + version = "0.4.13" 878 + source = "registry+https://github.com/rust-lang/crates.io-index" 879 + checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" 880 + dependencies = [ 881 + "aho-corasick", 882 + "memchr", 883 + "regex-syntax", 884 + ] 885 + 886 + [[package]] 887 + name = "regex-syntax" 888 + version = "0.8.8" 889 + source = "registry+https://github.com/rust-lang/crates.io-index" 890 + checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" 891 + 892 + [[package]] 893 + name = "rgb" 894 + version = "0.8.52" 895 + source = "registry+https://github.com/rust-lang/crates.io-index" 896 + checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" 897 + 898 + [[package]] 899 + name = "rp-pac" 900 + version = "7.0.0" 901 + source = "registry+https://github.com/rust-lang/crates.io-index" 902 + checksum = "8af65855c40b2c35079514c5489abffc0429347fef25d8467ff98ad84b4322d3" 903 + dependencies = [ 904 + "cortex-m", 905 + "cortex-m-rt", 906 + ] 907 + 908 + [[package]] 909 + name = "rp2040-boot2" 910 + version = "0.3.0" 911 + source = "registry+https://github.com/rust-lang/crates.io-index" 912 + checksum = "7c92f344f63f950ee36cf4080050e4dce850839b9175da38f9d2ffb69b4dbb21" 913 + dependencies = [ 914 + "crc-any", 915 + ] 916 + 917 + [[package]] 918 + name = "rustc_version" 919 + version = "0.2.3" 920 + source = "registry+https://github.com/rust-lang/crates.io-index" 921 + checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 922 + dependencies = [ 923 + "semver", 924 + ] 925 + 926 + [[package]] 927 + name = "rustversion" 928 + version = "1.0.22" 929 + source = "registry+https://github.com/rust-lang/crates.io-index" 930 + checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 931 + 932 + [[package]] 933 + name = "same-file" 934 + version = "1.0.6" 935 + source = "registry+https://github.com/rust-lang/crates.io-index" 936 + checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 937 + dependencies = [ 938 + "winapi-util", 939 + ] 940 + 941 + [[package]] 942 + name = "scopeguard" 943 + version = "1.2.0" 944 + source = "registry+https://github.com/rust-lang/crates.io-index" 945 + checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 946 + 947 + [[package]] 948 + name = "semver" 949 + version = "0.9.0" 950 + source = "registry+https://github.com/rust-lang/crates.io-index" 951 + checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 952 + dependencies = [ 953 + "semver-parser", 954 + ] 955 + 956 + [[package]] 957 + name = "semver-parser" 958 + version = "0.7.0" 959 + source = "registry+https://github.com/rust-lang/crates.io-index" 960 + checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 961 + 962 + [[package]] 963 + name = "sha2-const-stable" 964 + version = "0.1.0" 965 + source = "registry+https://github.com/rust-lang/crates.io-index" 966 + checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" 967 + 968 + [[package]] 969 + name = "sha3" 970 + version = "0.10.8" 971 + source = "registry+https://github.com/rust-lang/crates.io-index" 972 + checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 973 + dependencies = [ 974 + "digest", 975 + "keccak", 976 + ] 977 + 978 + [[package]] 979 + name = "siphasher" 980 + version = "1.0.1" 981 + source = "registry+https://github.com/rust-lang/crates.io-index" 982 + checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" 983 + 984 + [[package]] 985 + name = "smallvec" 986 + version = "1.15.1" 987 + source = "registry+https://github.com/rust-lang/crates.io-index" 988 + checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 989 + 990 + [[package]] 991 + name = "smart-leds" 992 + version = "0.4.0" 993 + source = "registry+https://github.com/rust-lang/crates.io-index" 994 + checksum = "66df34e571fa9993fa6f99131a374d58ca3d694b75f9baac93458fe0d6057bf0" 995 + dependencies = [ 996 + "smart-leds-trait", 997 + ] 998 + 999 + [[package]] 1000 + name = "smart-leds-trait" 1001 + version = "0.3.2" 1002 + source = "registry+https://github.com/rust-lang/crates.io-index" 1003 + checksum = "a7f4441a131924d58da6b83a7ad765c460e64630cce504376c3a87a2558c487f" 1004 + dependencies = [ 1005 + "rgb", 1006 + ] 1007 + 1008 + [[package]] 1009 + name = "stable_deref_trait" 1010 + version = "1.2.1" 1011 + source = "registry+https://github.com/rust-lang/crates.io-index" 1012 + checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" 1013 + 1014 + [[package]] 1015 + name = "string_cache" 1016 + version = "0.8.9" 1017 + source = "registry+https://github.com/rust-lang/crates.io-index" 1018 + checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" 1019 + dependencies = [ 1020 + "new_debug_unreachable", 1021 + "parking_lot", 1022 + "phf_shared", 1023 + "precomputed-hash", 1024 + ] 1025 + 1026 + [[package]] 1027 + name = "syn" 1028 + version = "2.0.114" 1029 + source = "registry+https://github.com/rust-lang/crates.io-index" 1030 + checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" 1031 + dependencies = [ 1032 + "proc-macro2", 1033 + "quote", 1034 + "unicode-ident", 1035 + ] 1036 + 1037 + [[package]] 1038 + name = "term" 1039 + version = "1.2.1" 1040 + source = "registry+https://github.com/rust-lang/crates.io-index" 1041 + checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" 1042 + dependencies = [ 1043 + "windows-sys", 1044 + ] 1045 + 1046 + [[package]] 1047 + name = "termcolor" 1048 + version = "1.4.1" 1049 + source = "registry+https://github.com/rust-lang/crates.io-index" 1050 + checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 1051 + dependencies = [ 1052 + "winapi-util", 1053 + ] 1054 + 1055 + [[package]] 1056 + name = "typenum" 1057 + version = "1.19.0" 1058 + source = "registry+https://github.com/rust-lang/crates.io-index" 1059 + checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" 1060 + 1061 + [[package]] 1062 + name = "unicode-ident" 1063 + version = "1.0.22" 1064 + source = "registry+https://github.com/rust-lang/crates.io-index" 1065 + checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" 1066 + 1067 + [[package]] 1068 + name = "unicode-width" 1069 + version = "0.1.14" 1070 + source = "registry+https://github.com/rust-lang/crates.io-index" 1071 + checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 1072 + 1073 + [[package]] 1074 + name = "unicode-xid" 1075 + version = "0.2.6" 1076 + source = "registry+https://github.com/rust-lang/crates.io-index" 1077 + checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 1078 + 1079 + [[package]] 1080 + name = "vcell" 1081 + version = "0.1.3" 1082 + source = "registry+https://github.com/rust-lang/crates.io-index" 1083 + checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" 1084 + 1085 + [[package]] 1086 + name = "version_check" 1087 + version = "0.9.5" 1088 + source = "registry+https://github.com/rust-lang/crates.io-index" 1089 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1090 + 1091 + [[package]] 1092 + name = "void" 1093 + version = "1.0.2" 1094 + source = "registry+https://github.com/rust-lang/crates.io-index" 1095 + checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1096 + 1097 + [[package]] 1098 + name = "volatile-register" 1099 + version = "0.2.2" 1100 + source = "registry+https://github.com/rust-lang/crates.io-index" 1101 + checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" 1102 + dependencies = [ 1103 + "vcell", 1104 + ] 1105 + 1106 + [[package]] 1107 + name = "walkdir" 1108 + version = "2.5.0" 1109 + source = "registry+https://github.com/rust-lang/crates.io-index" 1110 + checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 1111 + dependencies = [ 1112 + "same-file", 1113 + "winapi-util", 1114 + ] 1115 + 1116 + [[package]] 1117 + name = "winapi-util" 1118 + version = "0.1.11" 1119 + source = "registry+https://github.com/rust-lang/crates.io-index" 1120 + checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" 1121 + dependencies = [ 1122 + "windows-sys", 1123 + ] 1124 + 1125 + [[package]] 1126 + name = "windows-link" 1127 + version = "0.2.1" 1128 + source = "registry+https://github.com/rust-lang/crates.io-index" 1129 + checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 1130 + 1131 + [[package]] 1132 + name = "windows-sys" 1133 + version = "0.61.2" 1134 + source = "registry+https://github.com/rust-lang/crates.io-index" 1135 + checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" 1136 + dependencies = [ 1137 + "windows-link", 1138 + ] 1139 + 1140 + [[package]] 1141 + name = "zerocopy" 1142 + version = "0.8.33" 1143 + source = "registry+https://github.com/rust-lang/crates.io-index" 1144 + checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" 1145 + dependencies = [ 1146 + "zerocopy-derive", 1147 + ] 1148 + 1149 + [[package]] 1150 + name = "zerocopy-derive" 1151 + version = "0.8.33" 1152 + source = "registry+https://github.com/rust-lang/crates.io-index" 1153 + checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" 1154 + dependencies = [ 1155 + "proc-macro2", 1156 + "quote", 1157 + "syn", 1158 + ]
+17
Cargo.toml
··· 1 + [workspace] 2 + resolver = "3" 3 + members = ["embassy-strike-driver"] 4 + 5 + [workspace.package] 6 + authors = ["Sachy.dev <sachymetsu@tutamail.com>"] 7 + edition = "2024" 8 + repository = "https://tangled.org/sachy.dev/strike-sensor" 9 + version = "0.1.0" 10 + license = "AGPL-3.0-only" 11 + rust-version = "1.91.0" 12 + 13 + [workspace.dependencies] 14 + embassy-time = "0.5" 15 + embassy-sync = "0.7" 16 + embassy-rp = "0.9" 17 + defmt = "1"
+5 -1
README.md
··· 4 4 5 5 The sensor designs can be found in the [kicad](./kicad) folder. 6 6 7 + ## Driver 8 + 9 + Currently, the driver needs to be tested and coded according to how the new PCB/circuit behaves, so this will require a bit of work before considered "ready". 10 + 7 11 ## Licenses 8 12 9 - The sensor hardware designs are licensed under the [CERN Open Hardware Licence Version 2 - Strongly Reciprocal](./kicad/LICENSE-CERN-OHL-S) license. 13 + The sensor hardware designs are licensed under the [CERN Open Hardware Licence Version 2 - Strongly Reciprocal](./kicad/LICENSE-CERN-OHL-S) license. ⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢
+27
embassy-strike-driver/Cargo.toml
··· 1 + [package] 2 + name = "embassy-strike-driver" 3 + authors.workspace = true 4 + edition.workspace = true 5 + repository.workspace = true 6 + version.workspace = true 7 + license.workspace = true 8 + rust-version.workspace = true 9 + 10 + [features] 11 + default = [] 12 + alloc = [] 13 + heapless = ["dep:heapless"] 14 + rp2040 = ["dep:embassy-rp", "embassy-rp/rp2040"] 15 + rp235xa = ["dep:embassy-rp", "embassy-rp/rp235xa"] 16 + rp235xb = ["dep:embassy-rp", "embassy-rp/rp235xb"] 17 + 18 + [dependencies] 19 + embassy-time.workspace = true 20 + embassy-sync.workspace = true 21 + embassy-rp = { workspace = true, optional = true } 22 + heapless = { version = "0.9.2", optional = true } 23 + 24 + [dev-dependencies] 25 + embassy-time = { workspace = true, features = ["mock-driver", "generic-queue-8"] } 26 + critical-section = { version = "1.1", features = ["std"] } 27 + pollster = { version = "0.4", features = ["macro"] }
+29
embassy-strike-driver/src/analysis.rs
··· 1 + use crate::{BLOCK_SIZE, traits::BufferMut}; 2 + 3 + pub fn analyse_buffer_by_stepped_windows<B: BufferMut<usize>>( 4 + threshold: u16, 5 + buf: &[u16], 6 + average: u16, 7 + peaks: &mut B, 8 + ) -> u16 { 9 + const CHUNK_SIZE: usize = BLOCK_SIZE / 32; 10 + const CHUNK_STEP: usize = CHUNK_SIZE / 2; 11 + 12 + let mut total = 0u32; 13 + let mut len = 0u32; 14 + 15 + for (i, window) in buf.windows(CHUNK_SIZE).enumerate().step_by(CHUNK_STEP) { 16 + let window_total = window.iter().copied().sum::<u16>(); 17 + let window_avg = window_total / CHUNK_SIZE as u16; 18 + let diff = average.saturating_sub(window_avg); 19 + 20 + if diff > threshold { 21 + peaks.push(i); 22 + } else { 23 + total += window_total as u32; 24 + len += CHUNK_SIZE as u32; 25 + } 26 + } 27 + 28 + (total / len) as u16 29 + }
+119
embassy-strike-driver/src/drivers.rs
··· 1 + #[cfg(any(feature = "rp2040", feature = "rp235xa", feature = "rp235xb"))] 2 + pub mod rp { 3 + use embassy_rp::{ 4 + Peri, 5 + adc::{self, Adc, AdcPin, Async, InterruptHandler}, 6 + dma, 7 + interrupt::typelevel::{ADC_IRQ_FIFO, Binding}, 8 + peripherals::ADC, pwm::{self, ChannelBPin, Pwm, Slice}, 9 + }; 10 + use embassy_sync::{blocking_mutex::raw::RawMutex, mutex::Mutex}; 11 + 12 + use crate::traits::{AdcSource, PwmSource}; 13 + 14 + struct AdcInner<'device, T: dma::Channel> { 15 + adc: Adc<'device, Async>, 16 + pin: adc::Channel<'device>, 17 + dma: Peri<'device, T>, 18 + } 19 + 20 + pub struct RpAdcDriver<'device, M: RawMutex, T: dma::Channel> { 21 + inner: Mutex<M, AdcInner<'device, T>>, 22 + } 23 + 24 + impl<T: dma::Channel> AdcInner<'_, T> { 25 + /// Samples at 100Khz, or 10us per sample. If a sampling fails due to conversion error, 26 + /// it tries again until the sampling succeeds. 27 + async fn read_many(&mut self, buf: &mut [u16]) { 28 + let mut retries: u32 = 5; 29 + 30 + while self 31 + .adc 32 + .read_many(&mut self.pin, buf, 480, self.dma.reborrow()) 33 + .await 34 + .is_err() 35 + { 36 + retries -= 1; 37 + 38 + if retries == 0 { 39 + panic!("ADC not configured or connected correctly."); 40 + } 41 + } 42 + } 43 + } 44 + 45 + impl<'device, M: RawMutex, T: dma::Channel> RpAdcDriver<'device, M, T> { 46 + pub fn new( 47 + inner: Peri<'device, ADC>, 48 + pin: Peri<'device, impl AdcPin + 'device>, 49 + dma: Peri<'device, T>, 50 + irqs: impl Binding<ADC_IRQ_FIFO, InterruptHandler>, 51 + ) -> Self { 52 + Self { 53 + inner: Mutex::new(AdcInner { 54 + adc: Adc::new(inner, irqs, adc::Config::default()), 55 + pin: adc::Channel::new_pin(pin, embassy_rp::gpio::Pull::None), 56 + dma, 57 + }), 58 + } 59 + } 60 + } 61 + 62 + impl<'device, M: RawMutex, T: dma::Channel> AdcSource for RpAdcDriver<'device, M, T> { 63 + async fn sample_average(&self, samples: &mut [u16]) -> u16 { 64 + self.sample(samples).await; 65 + 66 + let len = samples.len() as u32; 67 + 68 + (samples.iter().copied().map(u32::from).sum::<u32>() / len) as u16 69 + } 70 + 71 + async fn sample(&self, samples: &mut [u16]) { 72 + self.inner.lock().await.read_many(samples).await; 73 + } 74 + } 75 + 76 + pub struct PwmDriver<'device> { 77 + config: pwm::Config, 78 + pwm: Pwm<'device>, 79 + } 80 + 81 + impl<'device> PwmDriver<'device> { 82 + pub fn new<T>( 83 + slice: Peri<'device, T>, 84 + b: Peri<'device, impl ChannelBPin<T>>, 85 + ) -> Self 86 + where 87 + T: Slice, 88 + { 89 + let mut config = pwm::Config::default(); 90 + config.top = u8::MAX as u16; 91 + let pwm = Pwm::new_output_b(slice, b, config.clone()); 92 + 93 + Self { pwm, config } 94 + } 95 + } 96 + 97 + impl PwmSource for PwmDriver<'_> { 98 + fn set_duty(&mut self, duty: u16) { 99 + self.config.compare_b = duty.clamp(0, self.config.top); 100 + self.pwm.set_config(&self.config); 101 + } 102 + 103 + fn enable(&mut self) { 104 + self.config.enable = true; 105 + self.pwm.set_config(&self.config); 106 + } 107 + 108 + fn disable(&mut self) { 109 + self.config.enable = false; 110 + self.pwm.set_config(&self.config); 111 + } 112 + } 113 + 114 + impl Drop for PwmDriver<'_> { 115 + fn drop(&mut self) { 116 + self.disable(); 117 + } 118 + } 119 + }
+540
embassy-strike-driver/src/lib.rs
··· 1 + //! A generalised Embassy driver for the Strike Sensor v1 2 + //! ⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢ 3 + #![no_std] 4 + 5 + #[cfg(feature = "alloc")] 6 + extern crate alloc; 7 + 8 + mod analysis; 9 + pub mod drivers; 10 + pub mod traits; 11 + 12 + use core::cell::Cell; 13 + 14 + use embassy_sync::{ 15 + blocking_mutex::raw::NoopRawMutex, 16 + zerocopy_channel::{Channel, Receiver, Sender}, 17 + }; 18 + use embassy_time::{Duration, Instant, Ticker, Timer}; 19 + 20 + use crate::traits::{AdcSource, BufferMut, PwmSource, TimeSource}; 21 + 22 + pub const BLOCK_SIZE: usize = 512; 23 + pub type ZeroCopyChannel<'device> = Channel<'device, NoopRawMutex, (i64, [u16; BLOCK_SIZE])>; 24 + 25 + #[derive(Debug)] 26 + struct DetectorState { 27 + max_duty: Cell<u8>, 28 + duty: Cell<u8>, 29 + avg: Cell<u16>, 30 + strikes: Cell<u16>, 31 + warn_level: Cell<u16>, 32 + } 33 + 34 + impl Default for DetectorState { 35 + fn default() -> Self { 36 + Self { 37 + max_duty: Cell::new(0), 38 + duty: Cell::new(0), 39 + avg: Cell::new(0), 40 + strikes: Cell::new(0), 41 + warn_level: Cell::new(255), 42 + } 43 + } 44 + } 45 + 46 + #[derive(Debug)] 47 + pub struct DetectorConfig { 48 + blip_threshold: Cell<u16>, 49 + blip_size: Cell<usize>, 50 + } 51 + 52 + impl Default for DetectorConfig { 53 + fn default() -> Self { 54 + Self { 55 + blip_threshold: Cell::new(14), 56 + blip_size: Cell::new(2), 57 + } 58 + } 59 + } 60 + 61 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 62 + pub enum DetectorUpdate<'a> { 63 + Tick { 64 + timestamp: i64, 65 + level: u16, 66 + }, 67 + Detection { 68 + timestamp: i64, 69 + samples: &'a [u16], 70 + peaks: &'a [usize], 71 + }, 72 + } 73 + 74 + pub struct DetectorDriver<T: TimeSource, P: PwmSource, A: AdcSource> { 75 + state: DetectorState, 76 + config: DetectorConfig, 77 + timer_source: T, 78 + pwm: P, 79 + adc: A, 80 + } 81 + 82 + impl<T, P, A> DetectorDriver<T, P, A> 83 + where 84 + T: TimeSource, 85 + P: PwmSource, 86 + A: AdcSource, 87 + { 88 + pub fn new(config: DetectorConfig, timer_source: T, pwm: P, adc: A) -> Self { 89 + Self { 90 + state: Default::default(), 91 + config, 92 + timer_source, 93 + pwm, 94 + adc, 95 + } 96 + } 97 + 98 + pub fn reset_timer_source(&mut self) { 99 + self.timer_source = T::get_source(); 100 + } 101 + 102 + pub fn get_timestamp(&self) -> i64 { 103 + self.timer_source.timestamp() 104 + } 105 + 106 + pub fn set_blip_threshold(&self, threshold: u16) { 107 + self.config.blip_threshold.set(threshold); 108 + } 109 + 110 + pub fn set_blip_size(&self, size: usize) { 111 + self.config.blip_size.set(size); 112 + } 113 + 114 + pub async fn tune(&mut self, samples: &mut [u16]) { 115 + // info!("Tuning Detector for correct voltage settings"); 116 + let mut duty = 0; 117 + self.pwm.set_duty(duty); 118 + Timer::after_secs(2).await; 119 + let mut act_value = self.adc.sample_average(samples).await; 120 + 121 + // info!("initial ACT: {}", act_value); 122 + 123 + while act_value < 1364 { 124 + duty += 2; 125 + if duty >= 256 { 126 + duty = 0; 127 + self.pwm.set_duty(duty); 128 + Timer::after_secs(2).await; 129 + act_value = self.adc.sample_average(samples).await; 130 + // info!("Restarting tuning"); 131 + continue; 132 + } 133 + self.pwm.set_duty(duty); 134 + Timer::after_millis(250).await; 135 + act_value = self.adc.sample_average(samples).await; 136 + // info!("ACT: {}, Duty: {}", act_value, duty); 137 + } 138 + self.state.max_duty.set(duty as u8); 139 + duty = (duty / 3) * 2; 140 + self.pwm.set_duty(duty); 141 + self.state.duty.set(duty as u8); 142 + // info!("Set detection duty to: {}", duty); 143 + // Allow voltage level to stabilize after tuning 144 + Timer::after_secs(2).await; 145 + let avg = self.adc.sample_average(samples).await; 146 + self.state.avg.set(avg); 147 + } 148 + 149 + /// Samples and returns an `i64` timestamp. 150 + pub async fn sample_with_zerocopy<'a>( 151 + &self, 152 + dma: &mut Sender<'a, NoopRawMutex, (i64, [u16; BLOCK_SIZE])>, 153 + ) { 154 + loop { 155 + let (time, samples) = dma.send().await; 156 + *time = self.timer_source.timestamp(); 157 + self.adc.sample(samples).await; 158 + dma.send_done(); 159 + } 160 + } 161 + 162 + pub fn detect_from_sample<B, F>( 163 + &self, 164 + timestamp: i64, 165 + samples: &[u16], 166 + peaks: &mut B, 167 + update: F, 168 + ) where 169 + B: BufferMut<usize>, 170 + F: Fn(DetectorUpdate<'_>), 171 + { 172 + peaks.clear(); 173 + 174 + let new_avg = analysis::analyse_buffer_by_stepped_windows( 175 + self.config.blip_threshold.get(), 176 + samples, 177 + self.state.avg.get(), 178 + peaks, 179 + ); 180 + 181 + let blips = peaks.len(); 182 + 183 + if blips >= self.config.blip_size.get() { 184 + self.state 185 + .strikes 186 + .update(|strike| strike.saturating_add(32)); 187 + 188 + update(DetectorUpdate::Detection { 189 + timestamp, 190 + samples, 191 + peaks: peaks.as_slice(), 192 + }); 193 + } 194 + 195 + self.state.avg.set(new_avg); 196 + } 197 + 198 + pub async fn detect_with_zerocopy<'a, 'd, B, F>( 199 + &self, 200 + dma: &mut Receiver<'a, NoopRawMutex, (i64, [u16; BLOCK_SIZE])>, 201 + peaks: &'d mut B, 202 + update: F, 203 + ) where 204 + B: BufferMut<usize>, 205 + F: Fn(DetectorUpdate<'_>), 206 + { 207 + loop { 208 + let (timestamp, samples) = dma.receive().await; 209 + 210 + self.detect_from_sample(*timestamp, samples, peaks, &update); 211 + 212 + dma.receive_done(); 213 + } 214 + } 215 + 216 + pub async fn tick<F>(&self, update: F) 217 + where 218 + F: Fn(DetectorUpdate), 219 + { 220 + let mut inactive: Option<Instant> = None; 221 + let mut interval = Ticker::every(Duration::from_secs(1)); 222 + 223 + loop { 224 + interval.next().await; 225 + let strikes = self.state.strikes.get(); 226 + let mut warn_level = self.state.warn_level.get(); 227 + 228 + if strikes > 32 { 229 + warn_level = warn_level.saturating_add(strikes); 230 + } 231 + 232 + let decay = warn_level >> 8; 233 + 234 + self.state.strikes.set(0); 235 + self.state.warn_level.set(warn_level - decay); 236 + 237 + match inactive { 238 + Some(_) if decay > 0 => { 239 + inactive = None; 240 + } 241 + Some(val) if val.elapsed() >= Duration::from_secs(3600) => break, 242 + None if decay == 0 => { 243 + inactive = Some(Instant::now()); 244 + } 245 + None => { 246 + update(DetectorUpdate::Tick { 247 + timestamp: self.timer_source.timestamp(), 248 + level: warn_level - 255, 249 + }); 250 + } 251 + _ => continue, 252 + } 253 + } 254 + } 255 + } 256 + 257 + #[cfg(test)] 258 + mod tests { 259 + use core::future::poll_fn; 260 + use embassy_time::MockDriver; 261 + 262 + #[cfg(not(feature = "alloc"))] 263 + extern crate alloc; 264 + use super::*; 265 + 266 + #[derive(Debug, Default)] 267 + struct MockMachine { 268 + pwm: Cell<u16>, 269 + } 270 + 271 + impl MockMachine { 272 + fn adc_sample_avg(&self) -> u16 { 273 + self.pwm.get().saturating_mul(14) 274 + } 275 + } 276 + 277 + struct MockPwm<'a>(&'a MockMachine); 278 + 279 + impl PwmSource for MockPwm<'_> { 280 + fn set_duty(&mut self, duty: u16) { 281 + self.0.pwm.set(duty); 282 + } 283 + 284 + // These do nothing 285 + fn enable(&mut self) {} 286 + fn disable(&mut self) {} 287 + } 288 + 289 + struct MockAdc<'a>(&'a MockMachine); 290 + 291 + impl AdcSource for MockAdc<'_> { 292 + async fn sample(&self, samples: &mut [u16]) { 293 + samples.fill(self.0.adc_sample_avg()); 294 + } 295 + 296 + async fn sample_average(&self, _samples: &mut [u16]) -> u16 { 297 + self.0.adc_sample_avg() 298 + } 299 + } 300 + 301 + struct MockTimeSource; 302 + 303 + impl TimeSource for MockTimeSource { 304 + fn get_source() -> Self { 305 + Self 306 + } 307 + fn timestamp(&self) -> i64 { 308 + 0 309 + } 310 + } 311 + 312 + #[cfg(not(feature = "alloc"))] 313 + impl BufferMut<usize> for alloc::vec::Vec<usize> { 314 + fn push(&mut self, value: usize) { 315 + self.push(value); 316 + } 317 + 318 + fn clear(&mut self) { 319 + self.clear(); 320 + } 321 + 322 + fn len(&self) -> usize { 323 + self.len() 324 + } 325 + 326 + fn is_empty(&self) -> bool { 327 + self.is_empty() 328 + } 329 + 330 + fn as_slice(&self) -> &[usize] { 331 + self 332 + } 333 + } 334 + 335 + async fn tune_detector_manually<'a>( 336 + detector: &mut DetectorDriver<MockTimeSource, MockPwm<'a>, MockAdc<'a>>, 337 + buf: &mut [u16], 338 + driver: &MockDriver, 339 + ) { 340 + let mut tuning = core::pin::pin!(detector.tune(buf)); 341 + 342 + poll_fn(|cx| match tuning.as_mut().poll(cx) { 343 + core::task::Poll::Ready(_) => core::task::Poll::Ready(()), 344 + core::task::Poll::Pending => { 345 + cx.waker().wake_by_ref(); 346 + driver.advance(Duration::from_secs(2)); 347 + 348 + core::task::Poll::Pending 349 + } 350 + }) 351 + .await; 352 + } 353 + 354 + fn generate_signal(samples: &mut [u16]) { 355 + // Example voltage drop signal 356 + samples[5] -= 60; 357 + samples[6] -= 55; 358 + samples[7] -= 50; 359 + samples[8] -= 45; 360 + samples[9] -= 40; 361 + samples[10] -= 35; 362 + samples[11] -= 30; 363 + samples[12] -= 28; 364 + samples[13] -= 26; 365 + samples[14] -= 24; 366 + samples[15] -= 22; 367 + samples[16] -= 20; 368 + samples[17] -= 18; 369 + samples[18] -= 16; 370 + samples[19] -= 14; 371 + samples[20] -= 12; 372 + samples[21] -= 11; 373 + samples[22] -= 10; 374 + samples[23] -= 9; 375 + samples[24] -= 8; 376 + samples[25] -= 7; 377 + samples[26] -= 6; 378 + samples[27] -= 5; 379 + samples[28] -= 4; 380 + samples[29] -= 3; 381 + samples[30] -= 2; 382 + samples[31] -= 1; 383 + } 384 + 385 + #[pollster::test] 386 + async fn tuning_cycle_completes() { 387 + let driver = embassy_time::MockDriver::get(); 388 + driver.reset(); 389 + let device = MockMachine::default(); 390 + let pwm = MockPwm(&device); 391 + let adc = MockAdc(&device); 392 + 393 + let mut detector = DetectorDriver::new(Default::default(), MockTimeSource, pwm, adc); 394 + let mut buf = [0; 16]; 395 + 396 + tune_detector_manually(&mut detector, &mut buf, driver).await; 397 + 398 + assert_eq!(detector.state.max_duty.get(), 98); 399 + assert_eq!(detector.state.duty.get(), 64); 400 + assert_eq!(detector.adc.sample_average(&mut buf).await, 896); 401 + } 402 + 403 + #[pollster::test] 404 + async fn tick_updates_only_on_raised_levels() { 405 + let driver = embassy_time::MockDriver::get(); 406 + driver.reset(); 407 + let device = MockMachine::default(); 408 + let pwm = MockPwm(&device); 409 + let adc = MockAdc(&device); 410 + 411 + let detector = DetectorDriver::new(Default::default(), MockTimeSource, pwm, adc); 412 + 413 + detector.state.max_duty.set(98); 414 + detector.state.duty.set(64); 415 + detector.state.avg.set(896); 416 + 417 + { 418 + let mut tick = core::pin::pin!(detector.tick(|a| { 419 + assert_eq!( 420 + a, 421 + DetectorUpdate::Tick { 422 + timestamp: 0, 423 + level: 300 424 + } 425 + ); 426 + })); 427 + 428 + poll_fn(|cx| match tick.as_mut().poll(cx) { 429 + core::task::Poll::Ready(_) => core::task::Poll::Ready(()), 430 + core::task::Poll::Pending => { 431 + if detector.state.warn_level.get() > 255 { 432 + return core::task::Poll::Ready(()); 433 + } 434 + detector.state.strikes.set(300); 435 + driver.advance(Duration::from_secs(1)); 436 + cx.waker().wake_by_ref(); 437 + core::task::Poll::Pending 438 + } 439 + }) 440 + .await; 441 + } 442 + 443 + assert_eq!(detector.state.warn_level.get(), 553); 444 + } 445 + 446 + #[pollster::test] 447 + async fn detection_updates_only_on_large_enough_signals() { 448 + let driver = embassy_time::MockDriver::get(); 449 + driver.reset(); 450 + let device = MockMachine::default(); 451 + let pwm = MockPwm(&device); 452 + let adc = MockAdc(&device); 453 + 454 + let detector = DetectorDriver::new(Default::default(), MockTimeSource, pwm, adc); 455 + detector.pwm.0.pwm.set(64); 456 + detector.state.max_duty.set(98); 457 + detector.state.duty.set(64); 458 + detector.state.avg.set(896); 459 + 460 + let mut samples = alloc::vec![0; BLOCK_SIZE]; 461 + 462 + detector.adc.sample(&mut samples).await; 463 + 464 + samples[5] -= 3; 465 + samples[6] -= 1; 466 + 467 + let mut peaks = alloc::vec::Vec::with_capacity(512); 468 + 469 + let update = |_update: DetectorUpdate<'_>| { 470 + panic!("This update function shouldn't be called"); 471 + }; 472 + 473 + detector.detect_from_sample(0, &samples, &mut peaks, update); 474 + 475 + assert_eq!(peaks.len(), 0); 476 + 477 + generate_signal(&mut samples); 478 + 479 + let expected_peaks = alloc::vec![0, 8]; 480 + let called = Cell::new(false); 481 + 482 + let update = |update: DetectorUpdate<'_>| { 483 + called.set(true); 484 + assert_eq!( 485 + update, 486 + DetectorUpdate::Detection { 487 + timestamp: 0, 488 + samples: &samples, 489 + peaks: expected_peaks.as_slice() 490 + } 491 + ) 492 + }; 493 + 494 + detector.detect_from_sample(0, &samples, &mut peaks, update); 495 + 496 + assert_eq!(peaks.len(), 2); 497 + assert!(called.get()); 498 + } 499 + 500 + #[pollster::test] 501 + async fn detection_sensitivity_can_be_configured() { 502 + let driver = embassy_time::MockDriver::get(); 503 + driver.reset(); 504 + let device = MockMachine::default(); 505 + let pwm = MockPwm(&device); 506 + let adc = MockAdc(&device); 507 + 508 + let detector = DetectorDriver::new(Default::default(), MockTimeSource, pwm, adc); 509 + detector.pwm.0.pwm.set(64); 510 + detector.state.max_duty.set(98); 511 + detector.state.duty.set(64); 512 + detector.state.avg.set(896); 513 + 514 + let mut samples = alloc::vec![0; BLOCK_SIZE]; 515 + let mut peaks: alloc::vec::Vec<usize> = alloc::vec::Vec::with_capacity(BLOCK_SIZE); 516 + 517 + // Require bigger size blips. 518 + detector.config.blip_size.set(3); 519 + 520 + detector.adc.sample(&mut samples).await; 521 + generate_signal(&mut samples); 522 + 523 + detector.detect_from_sample(0, &samples, &mut peaks, |_update| { 524 + panic!("Update shouldn't be called"); 525 + }); 526 + 527 + assert_eq!(peaks.len(), 2); 528 + 529 + // Require bigger threshold for blip detection 530 + detector.config.blip_size.set(2); 531 + detector.config.blip_threshold.set(24); 532 + 533 + detector.detect_from_sample(0, &samples, &mut peaks, |_update| { 534 + panic!("Update shouldn't be called"); 535 + }); 536 + 537 + // Update didn't call because detected blip wasn't big enough 538 + assert_eq!(peaks.len(), 1); 539 + } 540 + }
+70
embassy-strike-driver/src/traits.rs
··· 1 + pub trait TimeSource { 2 + fn timestamp(&self) -> i64; 3 + fn get_source() -> Self; 4 + } 5 + 6 + pub trait AdcSource { 7 + fn sample_average(&self, samples: &mut [u16]) -> impl Future<Output = u16>; 8 + fn sample(&self, samples: &mut [u16]) -> impl Future<Output = ()>; 9 + } 10 + 11 + pub trait PwmSource { 12 + fn set_duty(&mut self, duty: u16); 13 + fn enable(&mut self); 14 + fn disable(&mut self); 15 + } 16 + 17 + /// A Mutable Buffer trait ⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁤⁢⁤⁤⁤⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁢⁤⁤⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁤⁢⁢⁤⁢⁢⁢⁤⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁤⁤⁢⁢⁤⁤⁢⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁤⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁤⁢⁤⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁤⁤⁢⁢⁢⁢⁢⁤⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁤⁤⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁤⁢⁤⁤⁤⁢⁤⁤⁤⁤⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁢⁢⁤⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁢⁤⁤⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁤⁢⁤⁢⁢⁤⁤⁢⁤⁢⁤⁢⁤⁢⁢⁢⁢⁤⁢⁤⁤⁢⁤⁢⁤⁢⁢⁢⁤⁤⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁤⁢⁢⁤⁤⁢⁢⁢⁤⁢⁢⁢⁤⁢⁤⁢⁢⁤⁢⁢⁢⁢⁤⁢⁢⁤⁢⁢⁤⁢⁢⁢⁤⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁤⁢⁤⁢⁢⁤⁢⁢⁢⁢⁢⁤⁢⁤⁢⁤⁢ 18 + pub trait BufferMut<T> { 19 + fn push(&mut self, value: T); 20 + fn clear(&mut self); 21 + fn as_slice(&self) -> &[T]; 22 + fn len(&self) -> usize; 23 + fn is_empty(&self) -> bool; 24 + } 25 + 26 + #[cfg(feature = "alloc")] 27 + impl<T> BufferMut<T> for alloc::vec::Vec<T> { 28 + fn push(&mut self, value: T) { 29 + self.push(value); 30 + } 31 + 32 + fn clear(&mut self) { 33 + self.clear(); 34 + } 35 + 36 + fn len(&self) -> usize { 37 + self.len() 38 + } 39 + 40 + fn is_empty(&self) -> bool { 41 + self.is_empty() 42 + } 43 + 44 + fn as_slice(&self) -> &[T] { 45 + self 46 + } 47 + } 48 + 49 + #[cfg(feature = "heapless")] 50 + impl<T> BufferMut<T> for heapless::Vec<T, crate::BLOCK_SIZE> { 51 + fn push(&mut self, value: T) { 52 + self.push(value).ok(); 53 + } 54 + 55 + fn clear(&mut self) { 56 + self.clear(); 57 + } 58 + 59 + fn as_slice(&self) -> &[T] { 60 + self 61 + } 62 + 63 + fn len(&self) -> usize { 64 + self.as_slice().len() 65 + } 66 + 67 + fn is_empty(&self) -> bool { 68 + self.is_empty() 69 + } 70 + }