commit 55ed793c121b995eda320f7ca21b1e8838fe03ce Author: baldeau Date: Mon Feb 24 23:16:48 2025 +0100 initial commit diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9ee7f3b Binary files /dev/null and b/.DS_Store differ diff --git a/.assets/ferris.webp b/.assets/ferris.webp new file mode 100644 index 0000000..7ebafca Binary files /dev/null and b/.assets/ferris.webp differ diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..d08aa9b --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,15 @@ +[build] +target = "thumbv7em-none-eabihf" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +rustflags = [ + "-C", + "link-arg=-Tlink.x", + "-C", + "link-arg=-Tdefmt.x", + "-C", + "link-arg=--nmagic", +] + +[env] +DEFMT_LOG = "trace" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e11bf7f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1676 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "as-slice" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" +dependencies = [ + "generic-array 0.12.4", + "generic-array 0.13.3", + "generic-array 0.14.7", + "stable_deref_trait", +] + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "assign-resources" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c0fc5119624f5c171d084b6a1bd3b6447dfadab980bb0d84717906239b77f85" + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atomic-pool" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c5fc22e05ec2884db458bf307dc7b278c9428888d2b6e6fad9c0ae7804f5f6" +dependencies = [ + "as-slice 0.1.5", + "as-slice 0.2.1", + "atomic-polyfill", + "stable_deref_trait", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byterepr" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7eb1a05c2ec66850db33d8dd2119626aef815662a074656a74bbe47a562fdf4" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-default" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core 0.20.10", + "darling_macro 0.20.10", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.94", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core 0.13.4", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core 0.20.10", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "defmt" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "defmt-parser" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab697b3dbbc1750b7c8b821aa6f6e7f2480b47a99bc057a2ed7b170ebef0c51" +dependencies = [ + "critical-section", + "defmt", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fea5ef5bed4d3468dfd44f5c9fa4cda8f54c86d4fb4ae683eacf9d39e2ea12" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-sync 0.6.2", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90327bcc66333a507f89ecc4e2d911b265c45f5c9bc241f98eee076752d35ac6" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" +dependencies = [ + "darling 0.20.10", + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" + +[[package]] +name = "embassy-hal-internal" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef3bac31ec146321248a169e9c7b5799f1e0b3829c7a9b324cb4600a7438f59" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4818c32afec43e3cae234f324bad9a976c9aa7501022d26ff60a4017a1a006b7" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync 0.6.2", +] + +[[package]] +name = "embassy-nrf" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7494efe1e0183568327c7e681d4b77ed5241921dcb5976426d9a65b65a0c81" +dependencies = [ + "bitflags 2.8.0", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "document-features", + "embassy-embedded-hal", + "embassy-hal-internal", + "embassy-sync 0.6.2", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nrf-pac", + "rand_core", +] + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-sync" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "embedded-io-async", + "futures-sink", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-time" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f820157f198ada183ad62e0a66f554c610cdcd1a9f27d4b316358103ced7a1f8" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d45f5d833b6d98bd2aab0c2de70b18bfaa10faf661a1578fd8e5dfb15eb7eba" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc55c748d16908a65b166d09ce976575fb8852cf60ccd06174092b41064d8f83" +dependencies = [ + "embassy-executor", + "heapless", +] + +[[package]] +name = "embassy-usb" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d0b882133fa684b9d4652351cd7aac5afe8a2c2bf4a7da59f442ff61087cda2" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync 0.6.2", + "embassy-usb-driver", + "heapless", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd" +dependencies = [ + "const-default", + "critical-section", + "linked_list_allocator", + "rlsf", +] + +[[package]] +name = "embedded-dma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "fixed" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "flatbuffers" +version = "23.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dac53e22462d78c16d64a1cd22371b54cc3fe94aa15e7886a2fa6e5d1ab8640" +dependencies = [ + "bitflags 1.3.2", + "rustc_version 0.4.1", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "linked_list_allocator" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "log" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "lsm6ds3tr" +version = "0.3.0" +source = "git+https://avoid.sh/PetActivityMonitor/lsm6ds3tr.git?rev=b368f6200c3ec9a84114e8ca137eb5fe0aa08e29#b368f6200c3ec9a84114e8ca137eb5fe0aa08e29" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", + "heapless", +] + +[[package]] +name = "lsm6ds3tr_demo" +version = "0.1.0" +dependencies = [ + "assign-resources", + "atomic-pool", + "cortex-m", + "cortex-m-rt", + "defmt", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-nrf", + "embassy-sync 0.5.0", + "embassy-time", + "embassy-usb", + "embedded-alloc", + "embedded-hal 1.0.0", + "embedded-hal-async", + "fixed", + "heapless", + "libm", + "lsm6ds3tr", + "nalgebra 0.33.2", + "nrf-softdevice", + "nrf-softdevice-s140", + "nrf52840-hal", + "panic-probe", + "static_cell", + "usb-device 0.2.9", + "usbd-serial", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "microflow" +version = "0.1.3" +dependencies = [ + "libm", + "microflow-macros", + "nalgebra 0.33.2", + "simba 0.9.0", +] + +[[package]] +name = "microflow-macros" +version = "0.1.1" +dependencies = [ + "byterepr", + "flatbuffers", + "nalgebra 0.32.6", + "proc-macro-error", + "proc-macro2", + "quote", + "simba 0.8.1", + "structmeta", + "syn 2.0.94", +] + +[[package]] +name = "nalgebra" +version = "0.32.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba 0.8.1", + "typenum", +] + +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba 0.9.0", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nrf-hal-common" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea48ed7f0843fe6ec5aac0c42701e9194adfa1ee82ce6d028d64e5f68542be4" +dependencies = [ + "cast", + "cfg-if", + "cortex-m", + "embedded-dma", + "embedded-hal 0.2.7", + "embedded-storage", + "fixed", + "nb 1.1.0", + "nrf-usbd", + "nrf52840-pac", + "rand_core", + "void", +] + +[[package]] +name = "nrf-pac" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "nrf-softdevice" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225a21d963b2382617dbbff5953dc8c6c43fe56db5c5155f4d20a30c50c2766d" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "embassy-futures", + "embassy-sync 0.5.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "futures", + "heapless", + "nrf-softdevice-macro", + "nrf-softdevice-s140", + "nrf52840-pac", + "num_enum", +] + +[[package]] +name = "nrf-softdevice-macro" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af0752f2f12e202fa29f5a8d2f6dcc8a421c7a7e368d9dab7feb6bfe24ff0e9" +dependencies = [ + "Inflector", + "darling 0.13.4", + "proc-macro2", + "quote", + "syn 1.0.109", + "uuid", +] + +[[package]] +name = "nrf-softdevice-s140" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea93a1e11efdafcf914ed6b81b5be0cd99ee8ff6c3060102265ea863a355393" + +[[package]] +name = "nrf-usbd" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b2907c0b3ec4d264981c1fc5a2321d51c463d5a63d386e573f00e84d5495e6" +dependencies = [ + "cortex-m", + "critical-section", + "usb-device 0.2.9", + "vcell", +] + +[[package]] +name = "nrf52840-hal" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709f85690f7f8d04612a18838785ee9176e1292ce3e53f0c68692b4cf5b4948e" +dependencies = [ + "embedded-hal 0.2.7", + "nrf-hal-common", + "nrf52840-pac", +] + +[[package]] +name = "nrf52840-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "once_cell" +version = "1.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" + +[[package]] +name = "panic-probe" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0" +dependencies = [ + "cortex-m", + "defmt", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[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.94", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rlsf" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf" +dependencies = [ + "cfg-if", + "const-default", + "libc", + "svgbobdoc", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.24", +] + +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "simba" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "structmeta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329" +dependencies = [ + "proc-macro2", + "quote", + "structmeta-derive", + "syn 2.0.94", +] + +[[package]] +name = "structmeta-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "svgbobdoc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" +dependencies = [ + "base64", + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-width", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tflite_demo" +version = "0.1.0" +dependencies = [ + "assign-resources", + "atomic-pool", + "cortex-m", + "cortex-m-rt", + "defmt", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-nrf", + "embassy-sync 0.5.0", + "embassy-time", + "embassy-usb", + "embedded-alloc", + "embedded-hal 1.0.0", + "embedded-hal-async", + "fixed", + "heapless", + "libm", + "lsm6ds3tr", + "microflow", + "nalgebra 0.33.2", + "nrf-softdevice", + "nrf-softdevice-s140", + "nrf52840-hal", + "panic-probe", + "static_cell", + "usb-device 0.2.9", + "usbd-serial", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "usb-device" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f291ab53d428685cc780f08a2eb9d5d6ff58622db2b36e239a4f715f1e184c" +dependencies = [ + "serde", + "ssmarshal", + "usb-device 0.3.2", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee54712c5d778d2fb2da43b1ce5a7b5060886ef7b09891baeb4bf36910a3ed" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb573c76e7884035ac5e1ab4a81234c187a82b6100140af0ab45757650ccda38" +dependencies = [ + "byteorder", + "hashbrown", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[package]] +name = "usbd-serial" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db75519b86287f12dcf0d171c7cf4ecc839149fe9f3b720ac4cfce52959e1dfe" +dependencies = [ + "embedded-hal 0.2.7", + "nb 0.1.3", + "usb-device 0.2.9", +] + +[[package]] +name = "uuid" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "wide" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.94", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..98538a7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,78 @@ +[workspace] +members = ["tflite_demo", "lsm6ds3tr_demo"] + +[workspace.features] +default = ["ble-l2cap", "ble-gatt-server", "ble-gatt-client", "ble-sec"] + +ble-l2cap = ["nrf-softdevice/ble-l2cap"] +ble-gatt-server = ["nrf-softdevice/ble-gatt-server"] +ble-gatt-client = ["nrf-softdevice/ble-gatt-client"] +ble-sec = ["nrf-softdevice/ble-sec"] + +nrf52840 = [ + "embassy-nrf/nrf52840", + "nrf-softdevice/nrf52840", + "nrf-softdevice/s140", + "dep:nrf-softdevice-s140", +] + +[workspace.dependencies] +assign-resources = "0.4.1" +embassy-futures = { version = "0.1.0" } +embassy-usb = { version = "0.3.0", features = ["defmt"] } +embassy-executor = { version = "0.7.0", features = [ + "task-arena-size-32768", + "arch-cortex-m", + "executor-thread", + "executor-interrupt", + "defmt", +] } +embassy-time = { version = "0.4.0", features = [ + "defmt", + "defmt-timestamp-uptime", +] } +embassy-nrf = { version = "0.3.1", features = [ + "defmt", + "nrf52840", + "time-driver-rtc1", + "gpiote", + "unstable-pac", + "time", + "reset-pin-as-gpio", +] } +embassy-embedded-hal = "0.3.0" +cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7.0" +defmt = "0.3" +defmt-rtt = "0.4" +panic-probe = { version = "0.3", features = ["print-defmt"] } +nrf52840-hal = "0.16.0" +usb-device = "0.2.7" +usbd-serial = "0.1.0" +microflow = { path = "../microflow-rs" } +nalgebra = { version = "0.33.2", default-features = false, features = [ + "macros", +] } +libm = "0.2" +panic-halt = "1.0.0" +heapless = "0.8.0" +lsm6ds3tr = { git = "https://avoid.sh/PetActivityMonitor/lsm6ds3tr.git", rev = "b368f6200c3ec9a84114e8ca137eb5fe0aa08e29", features = [ + "defmt", +] } +embassy-sync = { version = "0.5.0" } +embedded-storage = "0.3.0" +embedded-hal = "1.0.0" +embedded-hal-async = { version = "1.0.0" } +embedded-alloc = "0.6.0" +nrf-softdevice = { version = "0.1.0", features = [ + "defmt", + "ble-peripheral", + "ble-central", + "critical-section-impl", + "nrf52840", + "s140", +] } +nrf-softdevice-s140 = { version = "0.1.1" } +fixed = "1.24.0" +atomic-pool = "1.0.1" +static_cell = "2.0.0" diff --git a/README.md b/README.md new file mode 100644 index 0000000..a038089 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# xiao_pet_activity_analyser + + + +Blazingly fast and efficient pet activity analyser! + +## Supported Microcontrollers + +- Seeed XIAO BLE + +## Mac Tooling + +List connected devices: + +```bash +ioreg -p IOUSB +``` + +Screen the controller: + +```bash +screen /dev/tty./dev/tty.usbmodempet11 +``` diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..d4dbebf --- /dev/null +++ b/build.rs @@ -0,0 +1,6 @@ +fn main() { + // Rebuild if memory.x file was rebuild. + // Linker seems to pick it up automatically. + // (via the include in link.x which is added with a linker argument!) + println!("cargo:rerun-if-changed=memory.x"); +} \ No newline at end of file diff --git a/build_and_flash.sh b/build_and_flash.sh new file mode 100755 index 0000000..fd4f77b --- /dev/null +++ b/build_and_flash.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +COM_PORT=/dev/cu.usbmodem2101 + +echo -e "bootloader" > $COM_PORT + +sleep 1s + +while getopts 'abc:h' opt; do + case "$opt" in + ?|h) + echo "Usage: $(basename $0) crate_name" + exit 1 + ;; + esac +done +shift "$(($OPTIND -1))" +CRATE=$1 + +cargo build -p $CRATE --release +arm-none-eabi-objcopy -O ihex target/thumbv7em-none-eabihf/release/$CRATE target/$CRATE.hex +adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0x0123 --application target/$CRATE.hex target/$CRATE.zip +# Use our custom reboot system to boot the controller into serial-only DFU mode. +# echo -e "bootloader" > $COM_PORT +# Wait for the reboot. +# sleep 1s +adafruit-nrfutil --verbose dfu serial -pkg target/$CRATE.zip -p $COM_PORT -b 115200 --singlebank \ No newline at end of file diff --git a/flashing_time.py b/flashing_time.py new file mode 100755 index 0000000..7784ed7 --- /dev/null +++ b/flashing_time.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +from subprocess import run + +# requires pySerial: +# python -m pip install pyserial +import serial + +# grab the port for the seeed nrf52 (only connect one at a time) +data = run("ls /dev/ | grep 'cu.usbmodem'", capture_output=True, shell=True, text=True) + +ser = serial.Serial("/dev/" + data.stdout.strip(), 1200) +# send 16 null characters as reset signal to enter the bootloader +ser.write(b"\x00" * 16) +ser.close() diff --git a/lsm6ds3tr_demo/.DS_Store b/lsm6ds3tr_demo/.DS_Store new file mode 100644 index 0000000..9ad35ee Binary files /dev/null and b/lsm6ds3tr_demo/.DS_Store differ diff --git a/lsm6ds3tr_demo/Cargo.toml b/lsm6ds3tr_demo/Cargo.toml new file mode 100644 index 0000000..e10e7df --- /dev/null +++ b/lsm6ds3tr_demo/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "lsm6ds3tr_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true +nrf52840-hal.workspace = true +usb-device.workspace = true +usbd-serial.workspace = true +libm.workspace = true +nalgebra.workspace = true +heapless.workspace = true +lsm6ds3tr.workspace = true +defmt.workspace = true +defmt-rtt.workspace = true +embedded-alloc.workspace = true +embedded-hal.workspace = true +embedded-hal-async.workspace = true +nrf-softdevice.workspace = true +nrf-softdevice-s140.workspace = true +embassy-nrf.workspace = true +embassy-time.workspace = true +embassy-executor.workspace = true +embassy-sync.workspace = true +embassy-embedded-hal.workspace = true +fixed.workspace = true +atomic-pool.workspace = true +static_cell.workspace = true +embassy-usb.workspace = true +embassy-futures.workspace = true +panic-probe.workspace = true +assign-resources.workspace = true diff --git a/lsm6ds3tr_demo/src/common.rs b/lsm6ds3tr_demo/src/common.rs new file mode 100644 index 0000000..eb65974 --- /dev/null +++ b/lsm6ds3tr_demo/src/common.rs @@ -0,0 +1,4 @@ +#![macro_use] + +use defmt_rtt as _; // global logger +use embassy_nrf as _; // time driver diff --git a/lsm6ds3tr_demo/src/main.rs b/lsm6ds3tr_demo/src/main.rs new file mode 100644 index 0000000..e51f594 --- /dev/null +++ b/lsm6ds3tr_demo/src/main.rs @@ -0,0 +1,284 @@ +#![no_main] +#![no_std] + +use assign_resources::assign_resources; +use core::fmt::Write; +use defmt::{dbg, info, unwrap}; +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; +use embassy_nrf::usb::Driver; +use embassy_nrf::{bind_interrupts, peripherals, twim, usb, Peripherals}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::{Duration, Timer}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; +use embassy_usb::driver::EndpointError; +use embassy_usb::{Builder, Config, UsbDevice}; +use heapless::String; +use lsm6ds3tr::interface::I2cInterface; +use lsm6ds3tr::{ + registers::{GyroSampleRate, GyroScale}, + AccelSampleRate, AccelScale, AccelSettings, GyroSettings, LsmSettings, LSM6DS3TR, +}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +mod usb_dfu; + +bind_interrupts!(struct Irqs { + USBD => usb::InterruptHandler; + CLOCK_POWER => usb::vbus_detect::InterruptHandler; +}); + +assign_resources! { + imu: ImuResources { + spi: SPI2, + } +} + +bind_interrupts!(struct IrqsTest { + // SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler; + TWISPI0 => twim::InterruptHandler; +}); + +static I2C_BUS: StaticCell>> = + StaticCell::new(); + +type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + // let resources = split_resources!(p); + + // setup_dfu_over_usb(&spawner, p.USBD); + + // Create the driver, from the HAL. + let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); + + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Umbrella Corporation"); + config.product = Some("Secret Project"); + config.serial_number = Some("11880"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + static STATE: StaticCell = StaticCell::new(); + let state = STATE.init(State::new()); + + // Create embassy-usb DeviceBuilder using the driver and config. + static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); + static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); + static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); + static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); + let mut builder = Builder::new( + driver, + config, + &mut CONFIG_DESC.init([0; 256])[..], + &mut BOS_DESC.init([0; 256])[..], + &mut MSOS_DESC.init([0; 128])[..], + &mut CONTROL_BUF.init([0; 128])[..], + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, state, 64); + + // Build the builder. + let usb = builder.build(); + + unwrap!(spawner.spawn(usb_task(usb))); + + let mut led_red = Output::new(p.P0_06, Level::Low, OutputDrive::Standard); + + let mut pin = Output::new(p.P1_08, Level::High, OutputDrive::HighDrive); + pin.set_high(); + + Timer::after_millis(100).await; + + let sda_pin = p.P0_07; + let scl_pin = p.P0_27; + + let mut imuConfig = twim::Config::default(); + // This limits the ADXL355 ODR to 200Hz max. + imuConfig.frequency = twim::Frequency::K400; + // Internal pullups for SCL and SDA must be enabled. + imuConfig.scl_pullup = true; + imuConfig.sda_pullup = true; + + let i2c = twim::Twim::new(p.TWISPI0, IrqsTest, sda_pin, scl_pin, imuConfig); + + let settings = LsmSettings::basic() + .with_gyro( + GyroSettings::new() + .with_sample_rate(GyroSampleRate::_104Hz) + .with_scale(GyroScale::_2000DPS), + ) + .with_accel( + AccelSettings::new() + .with_sample_rate(AccelSampleRate::_104Hz) + .with_scale(AccelScale::_4G), + ); + + let mut imu = LSM6DS3TR::new(I2cInterface::new(i2c)).with_settings(settings); + imu.init().expect("LSM6DS3TR-C initialization failure!"); + + let blink_fut = async { + loop { + Timer::after_millis(500).await; + + if let (Ok(xyz_a), Ok(xyz_g)) = (imu.read_accel_raw(), imu.read_gyro()) { + class.wait_connection().await; + info!("Connected"); + + let temp = imu.read_temp().expect("Error reading temperature data."); + + let mut accel_data = String::<32>::new(); + if write!( + accel_data, + "Accel: x:{} y:{} z:{}\r\n", + xyz_a.x, xyz_a.y, xyz_a.z + ) + .is_ok() + { + if let Err(e) = class.write_packet(accel_data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + let mut gyro_data = String::<32>::new(); + if write!( + gyro_data, + "Gyro: x:{} y:{} z:{}\r\n", + xyz_g.x, xyz_g.y, xyz_g.z + ) + .is_ok() + { + if let Err(e) = class.write_packet(gyro_data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + + let mut temp_data = String::<32>::new(); + if write!(temp_data, "Degrees C1 = {}\r\n", temp).is_ok() { + if let Err(e) = class.write_packet(temp_data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + } else { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Error: Could not read imu data. \r\n").is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + } + } + }; + + blink_fut.await; +} + +#[embassy_executor::task] +async fn led_blinking_task(resources: ImuResources) { + loop {} +} + +#[embassy_executor::task] +async fn usb_task(mut device: UsbDevice<'static, MyDriver>) { + device.run().await; +} + +#[embassy_executor::task] +async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } +} + +#[embassy_executor::task] +async fn gyro_task(mut class: CdcAcmClass<'static, MyDriver>, p: &'static Peripherals) { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } +} + +#[embassy_executor::task] +async fn print_task(mut class: CdcAcmClass<'static, MyDriver>, text: &'static str) { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", text).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + info!("Disconnected"); +} + +#[embassy_executor::task] +async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) { + loop { + class.wait_connection().await; + info!("Connected :)"); + let _ = echo(&mut class).await; + info!("Disconnected :("); + } +} + +struct Disconnected {} + +impl From for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn echo(class: &mut CdcAcmClass<'static, MyDriver>) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + info!("data: {:x}", data); + class.write_packet(data).await?; + } +} diff --git a/lsm6ds3tr_demo/src/usb_dfu.rs b/lsm6ds3tr_demo/src/usb_dfu.rs new file mode 100644 index 0000000..a8bcfd0 --- /dev/null +++ b/lsm6ds3tr_demo/src/usb_dfu.rs @@ -0,0 +1,157 @@ +use crate::Irqs; +use core::fmt::Write; +use defmt::{info, unwrap}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_nrf::peripherals::USBD; +use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect}; +use embassy_nrf::usb::{Driver, Instance}; +use embassy_nrf::{pac, peripherals}; +use embassy_time::{Duration, Timer}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; +use embassy_usb::driver::EndpointError; +use embassy_usb::{Builder, Config}; +use heapless::String; + +use {defmt_rtt as _, panic_probe as _}; + +const MAGIC_REBOOT_MESSAGE: &str = "bootloader"; + +type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; + +/// Creates a usb serial device. +/// Sending it [MAGIC_REBOOT_MESSAGE] will reboot the device +/// into serial-only-dfu mode. +pub fn setup_dfu_over_usb(spawner: &Spawner, usbd: USBD) { + spawner.spawn(dfu_over_usb(usbd, *spawner)).unwrap(); +} + +#[embassy_executor::task] +async fn dfu_over_usb(usbd: USBD, spawner: Spawner) { + pac::CLOCK.tasks_hfclkstart().write_value(1); + while pac::CLOCK.events_hfclkstarted().read() != 1 {} + + // Create the driver, from the HAL. + let driver = Driver::new(usbd, Irqs, HardwareVbusDetect::new(Irqs)); + + // Create embassy-usb Config + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-serial example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut msos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut state = State::new(); + + let mut builder = Builder::new( + driver, + config, + &mut config_descriptor, + &mut bos_descriptor, + &mut msos_descriptor, + &mut control_buf, + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Do stuff with the class! + // let reboot_fut = async { + // loop { + // class.wait_connection().await; + // let _ = reboot_on_magic_message(&mut class).await; + // } + // }; + + let print_fut = async { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } + }; + + join(usb_fut, print_fut).await; +} + +struct Disconnected {} + +impl From for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn reboot_on_magic_message<'d, T: Instance + 'd, P: VbusDetect + 'd>( + class: &mut CdcAcmClass<'d, Driver<'d, T, P>>, +) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + + if data == MAGIC_REBOOT_MESSAGE.as_bytes() { + // Reboot the controller in DFU mode. + // The magic number has been taken from the arduino bootloader: + // https://github.com/mike1808/PIO_SEEED_Adafruit_nRF52_Arduino/blob/master/cores/nRF5/wiring.c#L26 + let dfu_magic_serial_only_reset = 0x4E; + pac::POWER + .gpregret() + .write(|w| w.0 = dfu_magic_serial_only_reset); + cortex_m::peripheral::SCB::sys_reset(); + } + } +} + +#[embassy_executor::task] +async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } +} diff --git a/memory.x b/memory.x new file mode 100644 index 0000000..7328124 --- /dev/null +++ b/memory.x @@ -0,0 +1,20 @@ +MEMORY +{ + /* https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsds_s140%2FSDS%2Fs1xx%2Fmem_usage%2Fmem_resource_reqs.html&cp=5_7_4_0_13_0_0 */ + + /* Need to leave space for the SoftDevice + These values are confirmed working for S140 7.3.0 + + They were extracted from the Arduino IDE plugin linked indirectly at https://wiki.seeedstudio.com/XIAO_BLE/ + */ + FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xED000 - 0x27000 + + /* SRAM required by Softdevice depend on + * - Attribute Table Size (Number of Services and Characteristics) + * - Vendor UUID count + * - Max ATT MTU + * - Concurrent connection peripheral + central + secure links + * - Event Len, HVN queue, Write CMD queue + */ + RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 +} \ No newline at end of file diff --git a/tflite_demo/.DS_Store b/tflite_demo/.DS_Store new file mode 100644 index 0000000..6696195 Binary files /dev/null and b/tflite_demo/.DS_Store differ diff --git a/tflite_demo/Cargo.toml b/tflite_demo/Cargo.toml new file mode 100644 index 0000000..ce7f9bb --- /dev/null +++ b/tflite_demo/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "tflite_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true +nrf52840-hal.workspace = true +usb-device.workspace = true +usbd-serial.workspace = true +microflow.workspace = true +libm.workspace = true +nalgebra.workspace = true +heapless.workspace = true +lsm6ds3tr.workspace = true +defmt.workspace = true +defmt-rtt.workspace = true +embedded-alloc.workspace = true +embedded-hal.workspace = true +embedded-hal-async.workspace = true +nrf-softdevice.workspace = true +nrf-softdevice-s140.workspace = true +embassy-nrf.workspace = true +embassy-time.workspace = true +embassy-executor.workspace = true +embassy-sync.workspace = true +embassy-embedded-hal.workspace = true +fixed.workspace = true +atomic-pool.workspace = true +static_cell.workspace = true +embassy-usb.workspace = true +embassy-futures.workspace = true +panic-probe.workspace = true +assign-resources.workspace = true diff --git a/tflite_demo/features/speech.rs b/tflite_demo/features/speech.rs new file mode 100644 index 0000000..7141b9f --- /dev/null +++ b/tflite_demo/features/speech.rs @@ -0,0 +1,219 @@ +use nalgebra::matrix; + +use microflow::buffer::Buffer2D; + +pub const YES: Buffer2D = matrix![ + 116, 98, 118, 95, 106, 85, 101, 81, 67, -18, -33, -12, -26, -128, 9, 34, 56, 45, 9, -12, 5, 30, + 23, 28, 0, -18, 0, -128, -60, -50, -50, -37, -60, -60, -50, -26, -33, -50, -33, -50, 83, 61, + 81, 55, 76, 61, 73, 64, 38, -8, -37, -20, -18, -20, 48, 29, 52, 41, 55, 18, 25, 37, 44, 37, 8, + 15, -6, -60, -128, -50, -37, -37, -18, -37, -26, -29, -37, -60, -50, -60, 95, 59, 52, -4, 54, + -18, 68, 43, 31, -18, -26, -33, -37, -29, 33, 7, -3, 8, 26, 24, 36, 6, 36, 23, 14, 8, -29, -37, + -37, -37, -50, -50, -26, -8, -26, -37, -18, -37, -60, -77, 50, 48, 83, 44, 56, -128, -33, -60, + 1, -26, -60, -43, -14, -23, -18, -43, -26, -33, 13, -77, -43, -77, -33, -37, 16, -12, -37, -50, + -50, -77, -20, -43, -60, -128, -60, -77, -37, -77, -60, -128, 37, -10, 65, -7, 28, -128, 10, + -77, -37, -128, -77, -128, -77, -43, -128, -128, -77, -128, -128, -128, -128, -128, -14, -128, + -43, -50, -37, -77, -128, -128, -77, -43, -29, -43, -20, -60, -37, -43, -50, -128, -77, -128, + -18, -128, -60, -128, -128, -128, -77, -128, -77, -128, -128, -128, -60, -37, -20, -128, -60, + -128, -128, -128, -60, -128, -77, -60, -128, -50, -60, -128, -77, -128, -50, -60, -37, -60, + -50, -77, -77, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -37, -128, + -128, -128, -128, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -77, -60, -128, -128, -50, -128, -50, -128, -50, -128, -77, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -77, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -77, -128, -77, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -128, -128, -128, + -77, -50, -128, -128, -77, -77, -128, -128, -128, -50, -128, 85, 43, 65, 53, 69, 60, 45, 3, 46, + -12, 9, -23, 32, -1, -128, -128, -128, -128, -1, 37, 38, 33, 43, 36, 58, 70, 68, 39, 6, 10, 32, + 6, 8, -23, -77, -128, -29, -128, -77, -128, 101, 87, 102, 91, 110, 88, 101, 83, 110, 95, 111, + 83, 81, 84, 106, 90, 93, 82, 98, 91, 108, 95, 118, 97, 118, 97, 116, 96, 113, 90, 110, 96, 107, + 85, 94, 66, 69, 36, 29, 0, 100, 60, 105, 68, 92, 93, 113, 92, 107, 85, 107, 83, 104, 91, 105, + 85, 112, 88, 101, 80, 101, 79, 96, 80, 98, 80, 105, 83, 98, 81, 103, 71, 100, 79, 83, 78, 91, + 47, 50, 13, 108, 81, 93, 78, 98, 76, 105, 76, 98, 40, 77, 72, 81, 62, 93, 77, 96, 80, 98, 61, + 97, 69, 88, 61, 71, 56, 98, 68, 97, 72, 89, 51, 81, 61, 88, 75, 86, 56, 48, 13, 71, 22, 84, 66, + 76, -7, 48, 61, 77, 62, 91, 65, 95, 74, 88, 59, 75, 58, 83, 55, 87, 55, 76, 43, 76, -3, 56, 60, + 79, 57, 71, 54, 82, 33, 74, 71, 91, 45, 18, -7, 61, 56, 77, 41, 73, 42, 82, 49, 59, 63, 82, 65, + 66, 38, 83, 34, 48, -8, 46, 20, 54, 33, 54, 6, 48, 16, 60, 37, 58, 22, 58, 14, 65, 53, 75, -4, + 42, 16, 16, -50, 22, -128, 80, 54, 43, -50, 42, -128, -10, -77, 28, -29, 68, 43, 73, 2, 25, + -60, 47, 14, 45, 7, 66, 4, 62, 37, 71, 7, 46, -10, 44, 22, 55, 53, 57, -29, 26, -10, -3, -128, + 38, -128, 46, -10, 16, -128, -10, -26, 60, -7, 65, 38, 70, -60, 35, -8, 42, -29, 6, -128, 34, + -128, 36, -60, 44, -12, -2, -128, -7, -60, -60, -128, -23, -128, 31, -33, 22, -77, -37, -43, + -128, -128, 3, -128, -23, -128, 17, -77, 43, -77, -7, -128, -20, -128, 17, -43, 32, -128, -43, + -128, -128, -77, 21, -128, -50, -128, -128, -128, -128, -128, -128, -128, -37, -128, -16, -128, + -50, -26, -6, -128, -128, -128, -128, -128, -23, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -16, -128, 36, -7, 16, -128, -128, -128, -128, -128, -77, -128, -37, -128, -50, + -128, -128, -128, -128, -128, -18, -128, 11, -128, -16, -77, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -26, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -20, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -50, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -1, -18, 5, -128, 40, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 4, -128, 63, 66, 75, -128, 70, 60, 34, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 87, 86, 95, 76, 91, 62, 72, -6, -50, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, 64, 83, 104, 70, 98, 90, 111, 89, 109, 80, 71, -128, -128, -128, -128, -128, -20, + -6, 27, 33, 86, 88, 108, 75, 108, 76, 98, 64, 75, 61, 71, 66, 85, -1, -77, -128, 46, 61, 92, + 69, 100, 93, 113, 80, 108, 93, 113, 91, 110, 80, 85, 15, -33, -128, 12, -50, 34, 50, 70, 55, + 84, 72, 108, 81, 111, 88, 100, 80, 84, 73, 97, 86, 99, 65, 85, 43, 96, 78, 107, 94, 118, 98, + 115, 92, 118, 94, 111, 93, 111, 86, 99, 52, 32, -16, 48, 31, 81, 74, 85, 64, 78, 64, 98, 70, + 110, 92, 96, 73, 100, 72, 94, 73, 98, 76, 85, 67, 101, 83, 101, 83, 112, 89, 98, 85, 105, 78, + 98, 72, 102, 80, 95, 23, 19, -8, 52, 57, 103, 91, 95, 65, 74, 8, 77, 49, 96, 76, 100, 87, 105, + 81, 94, 62, 94, 78, 81, 72, 99, 82, 101, 78, 108, 65, 82, 70, 100, 63, 79, 58, 80, 59, 87, 48, + 50, 57, 93, 67, 86, 80, 103, 56, 77, 31, 81, 57, 62, 41, 96, 85, 91, 71, 101, 76, 89, 78, 95, + 76, 96, 79, 103, 81, 103, 48, 70, 57, 88, 66, 84, 11, 85, 67, 104, 37, 38, 67, 90, 54, 81, 62, + 90, 52, 78, -60, 54, -8, 68, 40, 55, 8, 77, 52, 66, 31, 55, 13, 60, 26, 69, 42, 63, -29, 57, + -128, -3, -128, 3, -128, -29, -60, 52, -43, 63, 56, 86, 75, 95, 75, 85, 63, 82, 10, 50, -128, + 31, -77, 0, -77, -23, -128, 12, -77, 51, -3, 58, -14, 44, 0, 48, 4, 53, 47, 28, -128, -128, + -128, -37, -128, -3, -128, 49, 61, 100, 90, 117, 88, 107, 94, 112, 64, 96, 83, -128, -128, 7, + -128, -77, -128, -23, -128, -23, -128, 16, -37, 65, -8, 48, 20, 14, -77, 57, -18, -43, -128, + -128, -128, -128, -128, -128, -128, 24, 12, 74, 76, 105, 76, 99, 80, 108, 79, 103, 85, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 42, -128, -8, -128, -50, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -60, -128, -128, 5, 73, 53, 93, 70, 101, + 73, 94, 57, 86, 66, -18, -128, -128, -128, -128, -128, -128, -128, -128, -128, -50, -128, 36, + -128, -128, -128, -128, -128, -20, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, 23, 37, 75, 54, 97, 70, 83, 52, 85, 65, 7, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -43, -128, 23, -128, -43, -128, -33, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -26, -37, 65, 33, 76, 37, 73, 50, 77, 47, -12, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -7, -14, -4, -128, -14, -128, 18, -60, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -26, -60, 71, 42, 68, 53, 81, 49, + 73, 36, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -18, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 15, -26, 44, -18, 59, 39, 57, 20, 62, 26, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, 49, -128, 30, 8, 69, 27, 62, 38, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -43, -128, 28, -37, 48, -10, + 48, 11, 74, 37, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -77, -128, 11, -128, -7, -60, -77, -4, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -8, -128, -50, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128 +]; + +pub const NO: Buffer2D = matrix![ + 103, 78, 64, 76, 75, 54, 53, 67, 77, 60, 56, 70, 76, 71, 68, 58, 74, 32, 23, -2, -18, 11, 13, + 15, 9, 20, 5, -7, -18, -2, -10, -18, -10, -12, 9, 7, -33, -12, -4, -18, 57, 17, 55, 62, 70, 45, + 61, 37, 67, 52, 48, 47, 55, 46, 57, 47, 73, 17, 27, 20, 19, 8, 15, -6, -1, 10, -12, -29, -6, + -23, -18, -3, -1, 5, 3, -4, -12, -8, -1, -14, 65, 48, 58, 43, 48, 19, 39, 39, 57, 57, 58, 55, + 67, 58, 49, 50, 70, 27, 9, 16, 37, 4, 25, 4, 11, 9, 7, -33, -7, -12, 3, -6, -29, -7, -7, -18, + -12, -18, -2, -1, 0, 31, 60, -8, 51, 59, 70, 40, 71, 57, 52, 38, 66, 48, 17, 6, 59, 8, 15, 7, + 18, 4, 18, -23, -8, -4, -3, -12, -3, -26, 1, 10, 2, -29, -29, -37, -7, -4, 6, -33, 67, 44, 59, + -4, 64, 51, 68, 55, 74, 9, 40, 15, 57, 33, 60, 18, 40, 25, 27, -20, 25, -16, 6, 17, -10, -12, + -23, -43, -23, -23, -29, -37, -4, -16, -16, -60, -20, -23, -10, -29, -12, 15, 12, -37, 27, 15, + 61, 44, 50, 8, 48, 22, 49, -18, 46, 33, 42, 34, 46, -8, 4, -18, -43, -43, -10, 1, -10, -16, + -10, -77, -16, -33, 11, -26, -23, -37, 0, -8, -16, -29, 42, 40, 68, 24, 47, 46, 53, -128, 30, + 2, 42, 21, 21, -4, 43, 2, 43, 5, 32, -26, 7, -37, -43, -23, -2, -8, 2, -37, -50, -60, -1, -7, + -33, -77, -6, -18, -16, -50, -12, -33, 53, 8, 52, 18, 51, 35, 69, 26, 44, 8, 27, -128, 21, -33, + 17, -14, 38, -128, -14, -18, 17, -20, -14, -37, 8, -60, -33, -33, -33, -43, -12, -29, -12, + -128, -33, -60, -26, -77, -26, -50, 57, 29, 11, 30, 53, -10, 45, 15, 18, -10, 42, 2, 31, -29, + 10, -4, 42, -37, -50, -128, -4, -43, -20, -77, -14, -26, -33, -128, -12, -43, -8, -33, -33, + -60, -43, -77, -12, -60, -26, -50, 40, -23, 36, 35, 50, -2, 37, 27, 26, -77, 49, -7, 28, -43, + 6, 11, 41, -37, 33, -26, -14, -12, -6, -33, -16, -26, -20, -77, -14, -43, -8, -50, -14, -37, + -26, -77, -26, -77, -14, -29, 50, -60, 25, -26, 57, 38, 51, 1, 50, 1, 53, -18, 30, -23, 11, + -128, 18, -43, 20, -26, -10, -26, -12, -128, -50, -60, -37, -77, -20, -43, -50, -128, -77, + -128, -77, -128, -33, -77, -20, -60, 53, -10, -37, -128, 10, -128, 60, 18, -8, 13, 37, -37, 8, + -128, 3, -77, 32, -29, 14, 10, -12, -77, -37, -77, -37, -60, -23, -128, -43, -50, -16, -77, -6, + -33, 0, -60, -43, -128, -16, -60, 20, -2, 51, 19, 43, 2, 63, 20, 60, -4, 42, -50, 4, -128, 2, + -3, 32, -33, -26, -128, -18, -128, -33, -43, -7, -60, -50, -77, -29, -77, -23, -128, -16, -26, + -23, -60, -37, -77, -37, -128, -1, -33, 39, 48, 60, 5, 8, -128, 44, 11, 4, 0, 13, -77, -2, -20, + 33, -128, -33, -77, -8, -128, -14, -128, -33, -18, -12, -77, -16, -128, -37, -128, -12, -77, + -60, -128, -23, -60, -23, -128, 36, -50, 46, -128, 66, 39, 18, -14, -12, -77, -20, -6, 24, + -128, 28, -26, 21, -77, -6, -33, 1, -128, -43, -128, -1, -50, -37, -128, -50, -128, -33, -128, + -18, -128, -60, -8, -7, -60, -60, -128, -6, -29, 20, -1, 73, 40, -43, -14, 33, -43, 33, -3, 15, + -29, 29, -43, 20, -60, -29, -128, -20, -26, 4, -77, -16, -60, -33, -50, -29, -128, -60, -128, + -77, -128, -37, -50, 0, -77, -33, -128, 39, 8, 47, 10, 62, 16, 2, 1, 10, 7, 4, -7, 6, -128, + -77, -50, 19, -77, -77, -128, -77, -128, -50, -128, -60, -60, -33, -50, -37, -128, -128, -128, + -60, -128, -37, -60, -18, -128, -33, -77, 37, 23, 29, -128, -128, -128, -16, -128, -16, -33, + 21, -20, -8, -60, -2, -60, 11, -128, -50, -128, -50, -128, -29, -77, -16, -128, -26, -128, -50, + -77, -43, -128, -128, -128, -50, -128, -33, -128, -33, -50, -23, -128, 24, -128, -128, -77, 4, + -23, 32, -128, 1, -26, -14, -128, 10, -77, -4, -128, 1, -50, -8, -77, -77, -77, -23, -128, -50, + -43, -33, -128, -43, -128, -128, -128, -43, -128, -50, -128, -128, -128, 44, 15, 14, -128, 9, + -128, 21, 0, 29, -7, 18, -7, -7, -128, -33, -50, 14, -60, -60, -128, -60, -128, -37, -128, -43, + -128, -20, -128, -50, -128, -43, -77, -26, -128, -60, -50, -60, -128, -77, -128, -3, -128, 14, + -77, -26, 11, 47, -77, -7, -77, 45, -43, -12, 14, 37, -60, 22, -4, 5, -77, -14, -128, -10, -60, + 22, -77, -12, -60, -50, -128, -60, -128, -60, -128, -43, -128, -50, -128, -77, -50, 27, -37, + 33, -128, 4, -29, -4, -50, -20, -128, 6, -37, -33, -128, -50, -128, 34, 15, -43, -128, -20, + -50, -3, -37, -37, -77, -77, -128, -43, -128, -128, -128, 4, -26, -26, 27, 0, -128, -29, -60, + 35, -26, 23, -128, -29, -77, 19, 14, 28, -128, -16, -7, 31, -1, 17, 11, 60, 44, 8, 11, 18, + -128, -33, -60, -1, -128, -43, -128, -23, -128, -128, -128, 59, 43, 35, 61, 37, -77, -77, -50, + 116, 88, 98, 69, 78, 53, 78, 40, 48, 7, 29, -18, -2, -14, 5, 12, 65, 35, 31, -12, 33, -2, -6, + -1, 44, -29, -14, -60, -4, -43, -37, -128, 29, 18, 38, 51, 8, -128, -12, -37, 115, 91, 113, 77, + 89, 36, 60, 44, 49, 36, 27, 31, 63, 30, 62, 14, 55, 49, 42, 0, 45, 17, -23, 1, 30, -37, -50, + -77, -8, -60, 9, -60, -12, -50, 13, 4, 23, -6, 28, 13, 107, 78, 101, 73, 89, 46, 63, 17, 34, + -43, -6, 30, 67, 40, 77, 21, 53, 39, 38, 12, -6, 5, 28, -2, 18, -43, 0, -128, -29, -77, 18, + -128, -2, -77, 39, 35, 38, 35, 50, 29, 100, 70, 94, 69, 86, 50, 45, 38, 45, 12, 58, 64, 74, 36, + 77, 45, 78, 62, 8, -60, 38, 6, 21, 7, 8, -37, -1, -20, 48, -37, 8, -10, 8, 13, 45, 39, 38, 22, + 49, 25, 94, 63, 87, 66, 84, -128, 29, 20, 55, 51, 80, 36, 62, 30, 81, 72, 68, 37, 51, 27, 54, + 22, 16, -29, 4, 9, 57, 15, 35, -43, -77, -20, 4, 6, 37, -1, 40, 31, 47, 14, 89, 68, 96, 83, + 111, 96, 115, 87, 99, 76, 105, 84, 105, 86, 113, 91, 108, 87, 110, 78, 80, 46, 22, 74, 88, 72, + 103, 86, 80, 68, 48, 24, 68, 48, 55, 36, 108, 90, 90, 63, 83, 63, 87, 64, 90, 92, 113, 88, 102, + 79, 109, 83, 100, 89, 109, 60, 56, 21, 75, 62, 81, 45, 63, 73, 93, 65, 94, 80, 89, 81, 73, 3, + 43, 60, 102, 70, 84, 67, 99, 74, 78, 57, 79, 50, 93, 82, 98, 56, 77, 70, 91, 71, 85, 82, 86, + 13, 45, -18, 48, 40, 53, 28, 85, 60, 65, 52, 86, 78, 76, 46, 73, 19, 35, 54, 75, 40, 71, 60, + 82, 37, 69, 42, 62, 40, 96, 70, 85, 77, 70, 68, 103, 84, 94, 69, 81, -128, -128, -128, -43, + -37, 40, 2, 48, 45, 76, 37, 65, 16, 43, 18, 58, 20, 27, 12, 71, 31, 53, 44, 88, 47, 50, 33, 39, + 8, 89, 57, 88, 69, 72, 63, 100, 68, 81, -77, -10, -128, -128, -128, -128, -128, 13, -77, 8, 27, + 60, 28, 41, -128, -37, -128, 28, -43, -18, -128, 47, -37, 45, 27, 51, -29, 15, 39, 52, 30, 49, + -33, 65, 15, 76, 71, 90, 19, 46, -128, -16, -128, -128, -128, -128, -128, -128, -128, -18, + -128, -20, -128, 32, -128, 21, -33, 45, -128, -128, -128, -12, -128, -6, -14, 43, -128, -128, + -128, -128, -128, 52, -18, 69, -43, 78, 55, 42, -128, -29, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, 14, -128, -16, -128, -128, -128, 7, -128, -128, -128, -128, -128, + -128, -128, 12, -128, -128, -128, -128, -16, 59, -50, 35, -128, 42, 0, 47, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -33, -128, -23, -128, -128, -128, + -23, -128, -128, -128, -128, -128, -128, -128, -33, -128, -128, -128, -128, -128, -128, -128, + -8, -128, 36, -50, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -37, -128, -128, -60, -10, -128, -128, -128, -128, -128, -128, -128, + 21, -128, -128, -128, -128, -128, -128, -128, -128, -128, -12, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -77, -128, -128, -128, -29, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -29, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -50, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128 +]; diff --git a/tflite_demo/models/.DS_Store b/tflite_demo/models/.DS_Store new file mode 100644 index 0000000..311bf6f Binary files /dev/null and b/tflite_demo/models/.DS_Store differ diff --git a/tflite_demo/models/gesture_model.tflite b/tflite_demo/models/gesture_model.tflite new file mode 100644 index 0000000..43e3407 Binary files /dev/null and b/tflite_demo/models/gesture_model.tflite differ diff --git a/tflite_demo/models/sine.tflite b/tflite_demo/models/sine.tflite new file mode 100644 index 0000000..5dee2c7 Binary files /dev/null and b/tflite_demo/models/sine.tflite differ diff --git a/tflite_demo/models/speech.tflite b/tflite_demo/models/speech.tflite new file mode 100644 index 0000000..4d10b2e Binary files /dev/null and b/tflite_demo/models/speech.tflite differ diff --git a/tflite_demo/src/common.rs b/tflite_demo/src/common.rs new file mode 100644 index 0000000..eb65974 --- /dev/null +++ b/tflite_demo/src/common.rs @@ -0,0 +1,4 @@ +#![macro_use] + +use defmt_rtt as _; // global logger +use embassy_nrf as _; // time driver diff --git a/tflite_demo/src/main.rs b/tflite_demo/src/main.rs new file mode 100644 index 0000000..e0e169d --- /dev/null +++ b/tflite_demo/src/main.rs @@ -0,0 +1,285 @@ +#![no_main] +#![no_std] + +use assign_resources::assign_resources; +use core::fmt::Write; +use defmt::{dbg, info, unwrap}; +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; +use embassy_nrf::usb::Driver; +use embassy_nrf::{bind_interrupts, peripherals, twim, usb, Peripherals}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::{Duration, Timer}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; +use embassy_usb::driver::EndpointError; +use embassy_usb::{Builder, Config, UsbDevice}; +use heapless::String; +use lsm6ds3tr::interface::I2cInterface; +use lsm6ds3tr::{ + registers::{GyroSampleRate, GyroScale}, + AccelSampleRate, AccelScale, AccelSettings, GyroSettings, LsmSettings, LSM6DS3TR, +}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +mod usb_dfu; + +bind_interrupts!(struct Irqs { + USBD => usb::InterruptHandler; + CLOCK_POWER => usb::vbus_detect::InterruptHandler; +}); + +assign_resources! { + imu: ImuResources { + spi: SPI2, + } +} + +bind_interrupts!(struct IrqsTest { + // SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler; + TWISPI0 => twim::InterruptHandler; +}); + +static I2C_BUS: StaticCell>> = + StaticCell::new(); + +type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + // let resources = split_resources!(p); + + // setup_dfu_over_usb(&spawner, p.USBD); + + // Create the driver, from the HAL. + let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); + + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Umbrella Corporation"); + config.product = Some("Secret Project"); + config.serial_number = Some("11880"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + static STATE: StaticCell = StaticCell::new(); + let state = STATE.init(State::new()); + + // Create embassy-usb DeviceBuilder using the driver and config. + static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); + static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); + static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); + static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); + let mut builder = Builder::new( + driver, + config, + &mut CONFIG_DESC.init([0; 256])[..], + &mut BOS_DESC.init([0; 256])[..], + &mut MSOS_DESC.init([0; 128])[..], + &mut CONTROL_BUF.init([0; 128])[..], + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, state, 64); + + // Build the builder. + let usb = builder.build(); + + unwrap!(spawner.spawn(usb_task(usb))); + + let mut led_red = Output::new(p.P0_06, Level::Low, OutputDrive::Standard); + + let mut pin = Output::new(p.P1_08, Level::High, OutputDrive::HighDrive); + pin.set_high(); + + Timer::after_millis(100).await; + + let sda_pin = p.P0_07; + let scl_pin = p.P0_27; + + let mut imuConfig = twim::Config::default(); + // This limits the ADXL355 ODR to 200Hz max. + imuConfig.frequency = twim::Frequency::K400; + // Internal pullups for SCL and SDA must be enabled. + imuConfig.scl_pullup = true; + imuConfig.sda_pullup = true; + + let i2c = twim::Twim::new(p.TWISPI0, IrqsTest, sda_pin, scl_pin, imuConfig); + + let settings = LsmSettings::basic() + .with_gyro( + GyroSettings::new() + .with_sample_rate(GyroSampleRate::_104Hz) + .with_scale(GyroScale::_2000DPS), + ) + .with_accel( + AccelSettings::new() + .with_sample_rate(AccelSampleRate::_104Hz) + .with_scale(AccelScale::_4G), + ); + + let mut imu = LSM6DS3TR::new(I2cInterface::new(i2c)).with_settings(settings); + imu.init().expect("LSM6DS3TR-C initialization failure!"); + + let blink_fut = async { + loop { + Timer::after_millis(500).await; + + if let (Ok(xyz_a), Ok(xyz_g)) = (imu.read_accel_raw(), imu.read_gyro()) { + class.wait_connection().await; + info!("Connected"); + + let temp = imu.read_temp().expect("Error reading temperature data."); + // imu.read_temp() + + let mut accel_data = String::<32>::new(); + if write!( + accel_data, + "Accel: x:{} y:{} z:{}\r\n", + xyz_a.x, xyz_a.y, xyz_a.z + ) + .is_ok() + { + if let Err(e) = class.write_packet(accel_data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + let mut gyro_data = String::<32>::new(); + if write!( + gyro_data, + "Gyro: x:{} y:{} z:{}\r\n", + xyz_g.x, xyz_g.y, xyz_g.z + ) + .is_ok() + { + if let Err(e) = class.write_packet(gyro_data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + + let mut temp_data = String::<32>::new(); + if write!(temp_data, "Degrees C1 = {}\r\n", temp).is_ok() { + if let Err(e) = class.write_packet(temp_data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + } else { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Error: Could not read imu data. \r\n").is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + } + } + }; + + blink_fut.await; +} + +#[embassy_executor::task] +async fn led_blinking_task(resources: ImuResources) { + loop {} +} + +#[embassy_executor::task] +async fn usb_task(mut device: UsbDevice<'static, MyDriver>) { + device.run().await; +} + +#[embassy_executor::task] +async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } +} + +#[embassy_executor::task] +async fn gyro_task(mut class: CdcAcmClass<'static, MyDriver>, p: &'static Peripherals) { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } +} + +#[embassy_executor::task] +async fn print_task(mut class: CdcAcmClass<'static, MyDriver>, text: &'static str) { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", text).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + info!("Disconnected"); +} + +#[embassy_executor::task] +async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) { + loop { + class.wait_connection().await; + info!("Connected :)"); + let _ = echo(&mut class).await; + info!("Disconnected :("); + } +} + +struct Disconnected {} + +impl From for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn echo(class: &mut CdcAcmClass<'static, MyDriver>) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + info!("data: {:x}", data); + class.write_packet(data).await?; + } +} diff --git a/tflite_demo/src/usb_dfu.rs b/tflite_demo/src/usb_dfu.rs new file mode 100644 index 0000000..a8bcfd0 --- /dev/null +++ b/tflite_demo/src/usb_dfu.rs @@ -0,0 +1,157 @@ +use crate::Irqs; +use core::fmt::Write; +use defmt::{info, unwrap}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_nrf::peripherals::USBD; +use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect}; +use embassy_nrf::usb::{Driver, Instance}; +use embassy_nrf::{pac, peripherals}; +use embassy_time::{Duration, Timer}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; +use embassy_usb::driver::EndpointError; +use embassy_usb::{Builder, Config}; +use heapless::String; + +use {defmt_rtt as _, panic_probe as _}; + +const MAGIC_REBOOT_MESSAGE: &str = "bootloader"; + +type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; + +/// Creates a usb serial device. +/// Sending it [MAGIC_REBOOT_MESSAGE] will reboot the device +/// into serial-only-dfu mode. +pub fn setup_dfu_over_usb(spawner: &Spawner, usbd: USBD) { + spawner.spawn(dfu_over_usb(usbd, *spawner)).unwrap(); +} + +#[embassy_executor::task] +async fn dfu_over_usb(usbd: USBD, spawner: Spawner) { + pac::CLOCK.tasks_hfclkstart().write_value(1); + while pac::CLOCK.events_hfclkstarted().read() != 1 {} + + // Create the driver, from the HAL. + let driver = Driver::new(usbd, Irqs, HardwareVbusDetect::new(Irqs)); + + // Create embassy-usb Config + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-serial example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut msos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut state = State::new(); + + let mut builder = Builder::new( + driver, + config, + &mut config_descriptor, + &mut bos_descriptor, + &mut msos_descriptor, + &mut control_buf, + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Do stuff with the class! + // let reboot_fut = async { + // loop { + // class.wait_connection().await; + // let _ = reboot_on_magic_message(&mut class).await; + // } + // }; + + let print_fut = async { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } + }; + + join(usb_fut, print_fut).await; +} + +struct Disconnected {} + +impl From for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn reboot_on_magic_message<'d, T: Instance + 'd, P: VbusDetect + 'd>( + class: &mut CdcAcmClass<'d, Driver<'d, T, P>>, +) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + + if data == MAGIC_REBOOT_MESSAGE.as_bytes() { + // Reboot the controller in DFU mode. + // The magic number has been taken from the arduino bootloader: + // https://github.com/mike1808/PIO_SEEED_Adafruit_nRF52_Arduino/blob/master/cores/nRF5/wiring.c#L26 + let dfu_magic_serial_only_reset = 0x4E; + pac::POWER + .gpregret() + .write(|w| w.0 = dfu_magic_serial_only_reset); + cortex_m::peripheral::SCB::sys_reset(); + } + } +} + +#[embassy_executor::task] +async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) { + let mut count = 1; + loop { + class.wait_connection().await; + info!("Connected"); + + let mut data = String::<32>::new(); + if write!(data, "Count: {}\r\n", count).is_ok() { + if let Err(e) = class.write_packet(data.as_bytes()).await { + info!("Failed to write to serial console: {:?}", e); + } + } + count += 1; + + // Add a delay of 1 second + Timer::after(Duration::from_secs(1)).await; + + info!("Disconnected"); + } +}