From ce6adfac0fb08a6d3162c78552c5e658fae9b3a1 Mon Sep 17 00:00:00 2001 From: baldeau Date: Sun, 12 Jan 2025 00:22:13 +0100 Subject: [PATCH] update (experimenting) --- .DS_Store | Bin 6148 -> 6148 bytes .assets/ferris.webp | Bin 0 -> 50596 bytes Cargo.lock | 874 ++++++++++++++++++++++++++++++- Cargo.toml | 66 ++- README.md | 24 +- tflite_demo/.DS_Store | Bin 0 -> 6148 bytes tflite_demo/Cargo.toml | 15 +- tflite_demo/features/speech.rs | 219 ++++++++ tflite_demo/models/.DS_Store | Bin 0 -> 6148 bytes tflite_demo/models/speech.tflite | Bin 0 -> 18800 bytes tflite_demo/src/common.rs | 4 + tflite_demo/src/i2c.rs | 16 + tflite_demo/src/main.rs | 180 ++++++- 13 files changed, 1363 insertions(+), 35 deletions(-) create mode 100644 .assets/ferris.webp create mode 100644 tflite_demo/.DS_Store create mode 100644 tflite_demo/features/speech.rs create mode 100644 tflite_demo/models/.DS_Store create mode 100644 tflite_demo/models/speech.tflite create mode 100644 tflite_demo/src/common.rs create mode 100644 tflite_demo/src/i2c.rs diff --git a/.DS_Store b/.DS_Store index 72c0dce6a73dc3e6e6638e9e0aba4f064e9710db..9ee7f3bbecd6baa8caae1b3f75910df46d0bb4d0 100644 GIT binary patch delta 65 zcmZoMXfc@J&&azmU^g=(?`9qrOD1J*h7yJ}h8%`WAf3t(&yWHna~bl>f{XHU^7GOe S7#J8gJF(4Y+|17LmmdHamJpr* delta 32 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 literal 0 HcmV?d00001 diff --git a/Cargo.lock b/Cargo.lock index ad07676..8f52765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,25 @@ # 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 = "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" @@ -11,6 +30,48 @@ 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 = "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" @@ -32,6 +93,12 @@ 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" @@ -77,6 +144,12 @@ 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" @@ -86,7 +159,7 @@ dependencies = [ "bare-metal", "bitfield", "critical-section", - "embedded-hal", + "embedded-hal 0.2.7", "volatile-register", ] @@ -122,6 +195,298 @@ 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", + "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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca4a9380d03e61063067b8239f67d2fa9f108ede7c46b4273804f6b79e59a1d" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-sync", + "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.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8701436bf0dc453703175459805045d049bf7404df7a68e59d05c7fbd1f04" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b11dfbb15afc12c4171ac6e2994567c00881f61a0c13ada4429028a3c7f425f" +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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ec47cf8bab914018d4bd2b4f0aaeb46e4f52ab1e7985df88aeef2c6eda5aed" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "num-traits", +] + +[[package]] +name = "embassy-nrf" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2faba661a13ac3417714ef23aa191af65941586dee692dbffe76ff7d3529321b" +dependencies = [ + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "document-features", + "embassy-embedded-hal", + "embassy-hal-internal", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "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", + "nrf52805-pac", + "nrf52810-pac", + "nrf52811-pac", + "nrf52820-pac", + "nrf52832-pac", + "nrf52833-pac", + "nrf52840-pac", + "nrf5340-app-pac", + "nrf5340-net-pac", + "nrf9160-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", + "defmt", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-time" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "158080d48f824fad101d7b2fae2d83ac39e3f7a6fa01811034f7ab8ffc6e7309" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" + +[[package]] +name = "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" @@ -141,12 +506,51 @@ dependencies = [ "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 = "fixed" version = "1.28.0" @@ -169,6 +573,101 @@ dependencies = [ "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" @@ -198,12 +697,50 @@ dependencies = [ "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 = "lsm6ds3tr" +version = "0.3.0" +dependencies = [ + "embedded-hal 1.0.0", + "nrf52840-hal", +] + [[package]] name = "matrixmultiply" version = "0.3.9" @@ -214,6 +751,12 @@ dependencies = [ "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" @@ -306,7 +849,7 @@ dependencies = [ "cfg-if", "cortex-m", "embedded-dma", - "embedded-hal", + "embedded-hal 0.2.7", "embedded-storage", "fixed", "nb 1.1.0", @@ -316,6 +859,49 @@ dependencies = [ "void", ] +[[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", + "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" @@ -328,13 +914,79 @@ dependencies = [ "vcell", ] +[[package]] +name = "nrf52805-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2da657648039d59f4de6bc31b948dd3a5d03b32529a4d5d19d9e2dd9d4bfa6c" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf52810-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c26b12d5af17a9f4bb9a06ca9a1f814bca3d67bc8715b23f8dc230b09a227666" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf52811-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4179b2a7ed0b2fd5e109d0fab9b4fc55b3936b2a4916a9306d22e5bc8dc1fd8f" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf52820-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4791cff995e6419a5ad1aebc3b3c9539d79125ca85eb5bfd2cff9b470b81071" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf52832-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0242b685c9c15648fb803e155628f42ace457478b2cb930868f40cae2db925e0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf52833-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10e1358255b360cdc816dd7b6ef81be8c8499c0998277e5249bed222bd0f5241" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + [[package]] name = "nrf52840-hal" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "709f85690f7f8d04612a18838785ee9176e1292ce3e53f0c68692b4cf5b4948e" dependencies = [ - "embedded-hal", + "embedded-hal 0.2.7", "nrf-hal-common", "nrf52840-pac", ] @@ -350,6 +1002,39 @@ dependencies = [ "vcell", ] +[[package]] +name = "nrf5340-app-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c88824573cd150fe9f27c1a48cea31a8cb24d3322df488875775143618c087a" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf5340-net-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5c03e44df22fe5888109fe42e523162c7059adf4d30860f4f73ecc8b1fc16fe" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "nrf9160-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7344d74afb5684e00c48d175cad9619f36d629cfb0687d33b4d1bb86fba688f4" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + [[package]] name = "num-complex" version = "0.4.6" @@ -387,12 +1072,50 @@ 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 = "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" @@ -417,6 +1140,28 @@ dependencies = [ "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" @@ -447,6 +1192,47 @@ 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" @@ -526,6 +1312,27 @@ 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" @@ -549,6 +1356,19 @@ dependencies = [ "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" @@ -556,6 +1376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", + "quote", "unicode-ident", ] @@ -574,17 +1395,50 @@ dependencies = [ name = "tflite_demo" version = "0.1.0" dependencies = [ + "atomic-pool", "cortex-m", "cortex-m-rt", + "defmt", + "defmt-rtt", + "embassy-executor", + "embassy-nrf", + "embassy-sync", + "embassy-time", + "embedded-alloc", + "fixed", "heapless", "libm", + "lsm6ds3tr", "microflow", "nalgebra 0.33.2", + "nrf-softdevice", + "nrf-softdevice-s140", "nrf52840-hal", + "static_cell", "usb-device", "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" @@ -597,6 +1451,12 @@ 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" @@ -609,11 +1469,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db75519b86287f12dcf0d171c7cf4ecc839149fe9f3b720ac4cfce52959e1dfe" dependencies = [ - "embedded-hal", + "embedded-hal 0.2.7", "nb 0.1.3", "usb-device", ] +[[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" diff --git a/Cargo.toml b/Cargo.toml index 0f49a8e..018783b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,73 @@ [workspace] -members = [ - "tflite_demo" +members = ["tflite_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] -cortex-m = { version = "0.7.7", features = ["critical-section-single-core", "inline-asm"] } +cortex-m = { version = "0.7.7", features = [ + "critical-section-single-core", + "inline-asm", +] } cortex-m-rt = "0.7.2" nrf52840-hal = "0.16.0" usb-device = "0.2.7" usbd-serial = "0.1.0" microflow = { path = "../microflow-rs" } # microflow = "0.1.3" -nalgebra = { version = "0.33.2", default-features = false, features = ["macros"] } +nalgebra = { version = "0.33.2", default-features = false, features = [ + "macros", +] } libm = "0.2" panic-halt = "1.0.0" -heapless = "0.8.0" \ No newline at end of file +panic-probe = { version = "0.3.1", features = ["print-defmt"] } +heapless = "0.8.0" +lsm6ds3tr = { path = "../lsm6ds3tr-rs" } +embassy-sync = { version = "0.5.0" } +embassy-executor = { version = "0.5.0", features = [ + "arch-cortex-m", + "executor-thread", + "executor-interrupt", + "defmt", + "integrated-timers", +] } +embassy-time = { version = "0.3.0", features = [ + "defmt", + "defmt-timestamp-uptime", +] } +embassy-nrf = { version = "0.1.0", features = [ + "defmt", + "nrf52840", + "time-driver-rtc1", + "gpiote", + "time", +] } +defmt = "0.3.0" +defmt-rtt = "0.4.0" +embedded-storage = "0.3.0" +embedded-hal = "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 index 8f2056c..ab794c0 100644 --- a/README.md +++ b/README.md @@ -1 +1,23 @@ -# xiao_pet_tracker_rust \ No newline at end of file +# xiao_pet_tracker_rust + + + +Blazingly fast and efficient pet tracking! + +## 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/tflite_demo/.DS_Store b/tflite_demo/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f7c8aebc314c50a0d69ba8d48d308683d447ec4f GIT binary patch literal 6148 zcmeHKO;6iE5S>i|I3T1Pio^xU5?2H%lzxbd32@+wt8#!UwQ)qP8ZU|+a)=`NOn*$T z{U!Z7@Md>GO#>VORWs7;o1Kqc?OSWtOGK(ONZt~)h{%I7)|zM@5RS7>NzHj?fXa-a zX`M>abV1ovwm4oR1H5tdJLk=L3*Oi8yB>yRR1S(x)IZ_gXRWjN&W_?Q zX>ZtVz1h=w8KrrzZwk_+hm_OfG*9%fqX&6XnA*?=yr$Reww6bukDKi^|HJn7c+DSu zV*B0J`|-HxEv;_s9Cd$W7rDMRDV*OWPKhJc24nNn_sQ{a2ldPx} zME+(FT@hhG7!U?thyi!Lc?&Nzzf3C(2m`N|0X`pmC}ZHTvS^MDH0B8aY`|>~ z8K~QCi|_w~$KU^xMbZ-ngn|Ex0oB+K_d8gUyIZFg$9Js{{RU;>yvpKz2@G=;BbTq@ bWvCJOeKvrB!^$E&5cv@>G)N;1JSzjY9yD(` literal 0 HcmV?d00001 diff --git a/tflite_demo/Cargo.toml b/tflite_demo/Cargo.toml index 6090098..90c7091 100644 --- a/tflite_demo/Cargo.toml +++ b/tflite_demo/Cargo.toml @@ -14,4 +14,17 @@ usbd-serial.workspace = true microflow.workspace = true libm.workspace = true nalgebra.workspace = true -heapless.workspace = true \ No newline at end of file +heapless.workspace = true +lsm6ds3tr.workspace = true +defmt.workspace = true +defmt-rtt.workspace = true +embedded-alloc.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 +fixed.workspace = true +atomic-pool.workspace = true +static_cell.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 0000000000000000000000000000000000000000..311bf6fadaa605564deaac3e4c416f41f09fc506 GIT binary patch literal 6148 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 Result<(), Self::Error> { +// // Simulate reading data +// Ok(()) +// } + +// fn write(&mut self, _address: u8, _bytes: &[u8]) -> Result<(), Self::Error> { +// // Simulate writing data +// Ok(()) +// } +// } diff --git a/tflite_demo/src/main.rs b/tflite_demo/src/main.rs index e453313..75d6c97 100644 --- a/tflite_demo/src/main.rs +++ b/tflite_demo/src/main.rs @@ -1,17 +1,59 @@ #![no_main] #![no_std] -use hal::prelude::*; -use nrf52840_hal as hal; -use usb_device::class_prelude::UsbBusAllocator; +mod common; + +mod i2c; + use core::fmt::Write; -use hal::Rtc; +use embedded_alloc::LlffHeap; use libm::sinf; +use lsm6ds3tr::{ + interface::{I2cInterface, SpiInterface}, + LsmSettings, LSM6DS3TR, +}; +// use lsm6ds3tr::{interface::SpiInterface, AccelScale, LsmSettings, LSM6DS3TR}; use microflow::model; use nalgebra::matrix; +use nrf52840_hal::{self as hal, twim, Spim, Twim}; +// use nrf_softdevice::{ +// ble::{EncryptionInfo, IdentityKey, MasterId, Uuid}, +// Softdevice, +// }; +use usb_device::class_prelude::UsbBusAllocator; + +use nrf52840_hal::{ + gpio::Level, + prelude::{OutputPin, PinState, _embedded_hal_timer_CountDown}, + uarte::{Baudrate, Parity, Pins, Uarte}, + Rtc, +}; use heapless::String; +// const BATTERY_SERVICE: Uuid = Uuid::new_16(0x180f); +// const BATTERY_LEVEL: Uuid = Uuid::new_16(0x2a19); + +// const LED_SERVICE_UUID: Uuid = Uuid::new_16(0x112f); +// const LED_CONTROL_CHAR_UUID: Uuid = Uuid::new_16(0x321f); + +const RTC_FREQ_MHZ: f32 = 0.032_768; + +#[global_allocator] +static HEAP: LlffHeap = LlffHeap::empty(); + +// #[embassy_executor::task] +// async fn softdevice_task(sd: &'static Softdevice) { +// sd.run().await; +// } + +// #[derive(Debug, Clone, Copy)] +// struct Peer { +// master_id: MasterId, +// key: EncryptionInfo, +// peer_id: IdentityKey, +// } + #[panic_handler] // panicking behavior fn panic(_: &core::panic::PanicInfo) -> ! { reset_into_dfu(); @@ -20,11 +62,17 @@ fn panic(_: &core::panic::PanicInfo) -> ! { #[model("tflite_demo/models/sine.tflite")] struct Sine; +#[model("tflite_demo/models/speech.tflite")] +struct Speech; + /// Resets the device into Device Firmware Update mode (DFU). fn reset_into_dfu() -> ! { // Via https://devzone.nordicsemi.com/f/nordic-q-a/50839/start-dfu-mode-or-open_bootloader-from-application-by-function-call - unsafe { (*hal::pac::POWER::PTR).gpregret.write(|w| w.bits(0xB1)) }; - hal::pac::SCB::sys_reset(); + unsafe { + (*hal::pac::POWER::PTR).gpregret.write(|w| w.bits(0xB1)); + }; + + hal::pac::SCB::sys_reset() } #[derive(Clone, Copy)] @@ -36,28 +84,70 @@ enum LightState { #[cortex_m_rt::entry] fn main() -> ! { - let peripherals = hal::pac::Peripherals::take().unwrap(); - let port0 = hal::gpio::p0::Parts::new(peripherals.P0); - let mut led_red = port0.p0_26.into_push_pull_output(hal::gpio::Level::Low); - let mut led_green = port0.p0_30.into_push_pull_output(hal::gpio::Level::Low); - let mut led_blue = port0.p0_06.into_push_pull_output(hal::gpio::Level::Low); + { + use core::mem::MaybeUninit; + const HEAP_SIZE: usize = 1024; + static mut HEAP_MEM: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; + unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) } + } - let clocks = hal::clocks::Clocks::new(peripherals.CLOCK); + let p = hal::pac::Peripherals::take().unwrap(); + let port0 = hal::gpio::p0::Parts::new(p.P0); + let mut led_red = port0.p0_26.into_push_pull_output(Level::Low); + let mut led_green = port0.p0_30.into_push_pull_output(Level::Low); + let mut led_blue = port0.p0_06.into_push_pull_output(Level::Low); + + let clocks = hal::clocks::Clocks::new(p.CLOCK); let clocks = clocks.enable_ext_hfosc(); - let usb_peripheral = hal::usbd::UsbPeripheral::new(peripherals.USBD, &clocks); + let usb_peripheral = hal::usbd::UsbPeripheral::new(p.USBD, &clocks); let usb_bus = UsbBusAllocator::new(hal::usbd::Usbd::new(usb_peripheral)); let mut serial_port = usbd_serial::SerialPort::new(&usb_bus); - let rtc = Rtc::new(peripherals.RTC0, 0).unwrap(); + // let spiclk = port0.p0_24.into_push_pull_output(Level::Low).degrade(); + // let spimosi = port0.p0_23.into_push_pull_output(Level::Low).degrade(); + // let spimiso = port0.p0_22.into_floating_input().degrade(); + + // let pins = nrf52840_hal::spim::Pins { + // sck: Some(spiclk), + // miso: Some(spimiso), + // mosi: Some(spimosi), + // }; + + // let spim = Spim::new( + // p.SPIM2, + // pins, + // nrf52840_hal::spim::Frequency::K125, + // nrf52840_hal::spim::MODE_0, + // 0, + // ); + + // let spi_interface = SpiInterface::new(spim); + + // let settings = LsmSettings::basic(); + // let mut imu = LSM6DS3TR::new(spi_interface); + // imu.init().expect("Couldn't initialize the LSM6 sensor!"); + + let scl = port0.p0_27.into_floating_input().degrade(); + let sda = port0.p0_07.into_floating_input().degrade(); + + let pins = twim::Pins { scl: scl, sda: sda }; + + let i2c = Twim::new(p.TWIM0, pins, twim::Frequency::K100); + + let i2c_interface = I2cInterface::new(i2c); + + // let mut imu = LSM6DS3TR::new(I2cInterface::new("")); + + let rtc = Rtc::new(p.RTC0, 0).unwrap(); rtc.enable_counter(); let mut usb_device = usb_device::device::UsbDeviceBuilder::new( &usb_bus, usb_device::device::UsbVidPid(0x16c0, 0x27dd), ) - .manufacturer("Wumpftech") - .product("Wumpftech nRF52840") - .serial_number("wumpf1") + .manufacturer("HSRW") + .product("HSRW Pet Tracker nRF52840") + .serial_number("pet1") .device_class(usbd_serial::USB_CLASS_CDC) .max_packet_size_0(64) // makes control transfers 8x faster says https://github.com/nrf-rs/nrf-hal/blob/master/examples/usb/src/bin/serial.rs .build(); @@ -70,7 +160,7 @@ fn main() -> ! { // TIMER0 is reserved by Softdevice // https://devzone.nordicsemi.com/f/nordic-q-a/1160/soft-device-and-timers---how-do-they-work-together - let mut timer = hal::Timer::new(peripherals.TIMER1).into_periodic(); + let mut timer = hal::Timer::new(p.TIMER1).into_periodic(); timer.start(hal::Timer::::TICKS_PER_SECOND); let mut light = LightState::Red; @@ -93,13 +183,57 @@ fn main() -> ! { led_blue.set_state(PinState::High).unwrap(); } LightState::Blue => { - // led_red.set_state(PinState::High).unwrap(); - // led_green.set_state(PinState::High).unwrap(); - // led_blue.set_state(PinState::Low).unwrap(); + led_red.set_state(PinState::High).unwrap(); + led_green.set_state(PinState::High).unwrap(); + led_blue.set_state(PinState::Low).unwrap(); //reset_into_dfu(); } } + // if !usb_dev.poll(&mut [&mut serial]) { + // continue; + // } + + let mut buf = [0u8; 64]; + + match serial_port.read(&mut buf) { + Ok(count) if count > 0 => { + // Check if received data equals to 'reset' + for i in 0..count - 4 { + if buf[i] == b'r' + && buf[i + 1] == b'e' + && buf[i + 2] == b's' + && buf[i + 3] == b'e' + && buf[i + 4] == b't' + { + reset_into_dfu(); + } + } + + if buf[..12].iter().all(|&x| x == 0) { + reset_into_dfu(); + } + + // Echo back in upper case + for c in buf[0..count].iter_mut() { + if 0x61 <= *c && *c <= 0x7a { + *c &= !0x20; + } + } + + let mut write_offset = 0; + while write_offset < count { + match serial_port.write(&buf[write_offset..count]) { + Ok(len) if len > 0 => { + write_offset += len; + } + _ => {} + } + } + } + _ => {} + } + let text = y_predicted.to_bits(); let mut data = String::<32>::new(); @@ -113,13 +247,11 @@ fn main() -> ! { let _ = serial_port.write(data.as_bytes()); let _ = serial_port.write("\n".as_bytes()); - let _ = serial_port.write("Exact Y: ".as_bytes()); let _ = write!(data2, "data:{text2}"); let _ = serial_port.write(data2.as_bytes()); let _ = serial_port.write("\n".as_bytes()); - while timer.wait().is_err() { // TODO: sleep. // Spec says poll needs to be called at least every 10ms. @@ -127,4 +259,4 @@ fn main() -> ! { continue; } } -} \ No newline at end of file +}