diff --git a/.vscode/launch.json b/.vscode/launch.json index 1bbc31964..8fd858e4b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -67,7 +67,7 @@ "flashingConfig": { "flashingEnabled": true, "resetAfterFlashing": true, - "haltAfterReset": true, + "haltAfterReset": false, }, "coreConfigs": [ { diff --git a/Cargo.lock b/Cargo.lock index 84b67dec4..9b633ea81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,30 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + [[package]] name = "atomic-polyfill" version = "1.0.3" @@ -17,6 +35,18 @@ dependencies = [ "critical-section", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[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" @@ -27,10 +57,25 @@ dependencies = [ ] [[package]] -name = "bare-metal" -version = "1.0.0" +name = "bit-set" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" [[package]] name = "bitfield" @@ -44,6 +89,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + [[package]] name = "bitvec" version = "1.0.1" @@ -57,16 +108,28 @@ dependencies = [ ] [[package]] -name = "byteorder" -version = "1.4.3" +name = "bxcan" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" +dependencies = [ + "bitflags 1.3.2", + "embedded-hal 0.2.7", + "nb 1.1.0", + "vcell", +] [[package]] -name = "cast" -version = "0.3.0" +name = "bytemuck" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cfg-if" @@ -74,13 +137,23 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "cortex-m" version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" dependencies = [ - "bare-metal 0.2.5", + "bare-metal", "bitfield", "critical-section", "embedded-hal 0.2.7", @@ -109,9 +182,9 @@ dependencies = [ [[package]] name = "crc-any" -version = "2.4.3" +version = "2.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774646b687f63643eb0f4bf13dc263cb581c8c9e57973b6ddf78bda3994d88df" +checksum = "c01a5e1f881f6fb6099a7bdf949e946719fd4f1fefa56264890574febf0eb6d0" dependencies = [ "debug-helper", ] @@ -122,6 +195,47 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.48", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.48", +] + [[package]] name = "debug-helper" version = "0.3.13" @@ -134,7 +248,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a2d011b2fee29fb7d659b83c43fce9a2cb4df453e16d441a51448e448f3f98" dependencies = [ - "bitflags", + "bitflags 1.3.2", "defmt-macros", ] @@ -148,7 +262,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.48", ] [[package]] @@ -170,6 +284,42 @@ dependencies = [ "defmt", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "document-features" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +dependencies = [ + "litrs", +] + [[package]] name = "either" version = "1.9.0" @@ -177,22 +327,226 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] -name = "embedded-alloc" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddae17915accbac2cfbc64ea0ae6e3b330e6ea124ba108dada63646fd3c6f815" +name = "embassy-embedded-hal" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" dependencies = [ + "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.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "cortex-m", "critical-section", - "linked_list_allocator", + "defmt", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", ] [[package]] -name = "embedded-dma" +name = "embassy-executor-macros" +version = "0.4.1" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" + +[[package]] +name = "embassy-hal-internal" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-rp" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "atomic-polyfill", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "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-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "fixed", + "futures", + "nb 1.1.0", + "pio", + "pio-proc", + "rand_core", + "rp-pac", + "rp2040-boot2", +] + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "bit_field", + "bxcan", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "stm32-fmc", + "stm32-metapac", + "vcell", +] + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-time" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +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 = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" + +[[package]] +name = "embassy-usb" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-usb-driver", + "heapless", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#686069b4c97b201e4fd444785d784b9836ee2271" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-alloc" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +checksum = "ddae17915accbac2cfbc64ea0ae6e3b330e6ea124ba108dada63646fd3c6f815" dependencies = [ - "stable_deref_trait", + "critical-section", + "linked_list_allocator", ] [[package]] @@ -210,12 +564,67 @@ name = "embedded-hal" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.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.0" +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 = "156d7a2fdd98ebbf9ae579cbceca3058cff946e13f8e17b90e3511db0508c723" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] [[package]] name = "encode_unicode" @@ -230,105 +639,197 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "frunk" -version = "0.4.2" +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a351b59e12f97b4176ee78497dff72e4276fb1ceb13e19056aca7fa0206287" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "frunk_core", - "frunk_derives", + "libc", + "windows-sys", ] [[package]] -name = "frunk_core" -version = "0.4.2" +name = "fixed" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af2469fab0bd07e64ccf0ad57a1438f63160c69b2e57f04a439653d68eb558d6" +checksum = "02c69ce7e7c0f17aa18fdd9d0de39727adb9c6281f2ad12f57cbe54ae6e76e7d" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] [[package]] -name = "frunk_derives" +name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fa992f1656e1707946bbba340ad244f0814009ef8c0118eb7b658395f19a2e" -dependencies = [ - "frunk_proc_macro_helpers", - "quote", - "syn 2.0.31", -] +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] -name = "frunk_proc_macro_helpers" -version = "0.1.2" +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b54add839292b743aeda6ebedbd8b11e93404f902c56223e51b9ec18a13d2c" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ - "frunk_core", - "proc-macro2", - "quote", - "syn 2.0.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "fugit" -version = "0.3.7" +name = "futures-channel" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ - "gcd", + "futures-core", + "futures-sink", ] [[package]] -name = "funty" -version = "2.0.0" +name = "futures-core" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] -name = "futures-core" -version = "0.3.28" +name = "futures-io" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", ] [[package]] -name = "gcd" -version = "2.3.0" +name = "getrandom" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "half" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +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.14.0" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[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 = "hermit-abi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" + +[[package]] +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", ] +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + [[package]] name = "itertools" version = "0.10.5" @@ -338,18 +839,94 @@ dependencies = [ "either", ] +[[package]] +name = "lalrpop" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +dependencies = [ + "ascii-canvas", + "bit-set", + "diff", + "ena", + "is-terminal", + "itertools", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.6.29", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "lalrpop-util" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +dependencies = [ + "regex", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] + [[package]] name = "linked_list_allocator" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + [[package]] name = "nb" version = "0.1.3" @@ -365,6 +942,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + [[package]] name = "num_enum" version = "0.5.11" @@ -376,11 +968,11 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "num_enum_derive 0.7.0", + "num_enum_derive 0.7.2", ] [[package]] @@ -396,15 +988,21 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.48", ] +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "packed_struct" version = "0.10.1" @@ -446,12 +1044,54 @@ dependencies = [ "rtt-target 0.3.1", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "paste" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -475,6 +1115,50 @@ dependencies = [ "paste", ] +[[package]] +name = "pio-parser" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77532c2b8279aef98dfc7207ef15298a5a3d6b6cc76ccc8b65913d69f3a8dd6b" +dependencies = [ + "lalrpop", + "lalrpop-util", + "pio", + "regex-syntax 0.6.29", +] + +[[package]] +name = "pio-proc" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b04dc870fb3a4fd8b3e4ca8c61b53bc8ac4eb78b66805d2b3c2e5c4829e0d7a" +dependencies = [ + "codespan-reporting", + "lalrpop-util", + "pio", + "pio-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "regex-syntax 0.6.29", + "syn 1.0.109", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +dependencies = [ + "critical-section", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -494,102 +1178,163 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", ] [[package]] -name = "proc-macro2" -version = "1.0.66" +name = "regex" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ - "unicode-ident", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.8.2", ] [[package]] -name = "quote" -version = "1.0.33" +name = "regex-automata" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ - "proc-macro2", + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", ] [[package]] -name = "radium" -version = "0.7.0" +name = "regex-syntax" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] -name = "rand_core" -version = "0.6.4" +name = "regex-syntax" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rmk" -version = "0.0.6" +version = "0.1.0" dependencies = [ "byteorder", + "embassy-sync", + "embassy-time", + "embassy-usb", "embedded-alloc", "embedded-hal 1.0.0", "embedded-storage", "log", - "num_enum 0.7.0", + "num_enum 0.7.2", "packed_struct", - "rtic-monotonics", - "usb-device", + "static_cell", "usbd-hid", ] [[package]] name = "rmk-rp2040" -version = "0.0.3" +version = "0.1.0" dependencies = [ "cortex-m", "cortex-m-rt", "defmt", "defmt-rtt", - "embedded-hal 0.2.7", + "embassy-executor", + "embassy-futures", + "embassy-rp", + "embassy-time", + "embedded-hal 1.0.0", + "embedded-storage", "log", + "packed_struct", "panic-probe", + "portable-atomic", "rmk", - "rp-pico", - "rtic", - "rtic-monotonics", + "static_cell", ] [[package]] name = "rmk-stm32h7" -version = "0.0.3" +version = "0.1.0" dependencies = [ "cortex-m", "cortex-m-rt", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-time", "embedded-storage", "log", "packed_struct", "panic-rtt-target", "rmk", - "rtic", - "rtic-monotonics", - "rtt-target 0.4.0", - "stm32h7xx-hal", + "rtt-target 0.5.0", + "static_cell", ] [[package]] -name = "rp-pico" -version = "0.8.0" +name = "rp-pac" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6341771e6f8e5d130b2b3cbc23435b7847761adf198af09f4b2a60407d43bd56" +checksum = "f30f6c4c846269293db805e9c77864ff7b923395b480550df44f0868e3765337" dependencies = [ + "cortex-m", "cortex-m-rt", - "fugit", - "rp2040-boot2", - "rp2040-hal", - "usb-device", ] [[package]] @@ -602,146 +1347,63 @@ dependencies = [ ] [[package]] -name = "rp2040-hal" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ec610f738b69100fbe75f3b835501b669d41c889ac9a62ef284f8e6d1f17385" -dependencies = [ - "cortex-m", - "critical-section", - "embedded-dma", - "embedded-hal 0.2.7", - "frunk", - "fugit", - "itertools", - "nb 1.1.0", - "paste", - "pio", - "rand_core", - "rp2040-hal-macros", - "rp2040-pac", - "usb-device", - "vcell", - "void", -] - -[[package]] -name = "rp2040-hal-macros" -version = "0.1.0" +name = "rtt-target" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86479063e497efe1ae81995ef9071f54fd1c7427e04d6c5b84cde545ff672a5e" +checksum = "065d6058bb1204f51a562a67209e1817cf714759d5cf845aa45c75fa7b0b9d9b" dependencies = [ - "cortex-m-rt", - "proc-macro2", - "quote", - "syn 1.0.109", + "ufmt-write", ] [[package]] -name = "rp2040-pac" +name = "rtt-target" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d9d8375815f543f54835d01160d4e47f9e2cae75f17ff8f1ec19ce1da96e4c" -dependencies = [ - "cortex-m", - "cortex-m-rt", - "critical-section", - "vcell", -] - -[[package]] -name = "rtic" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "857ce76a2517808a303bcb7e5b6d4a9c1d84e5de88b302aec2e53744633c0f4d" -dependencies = [ - "atomic-polyfill", - "bare-metal 1.0.0", - "cortex-m", - "critical-section", - "rtic-core", - "rtic-macros", -] - -[[package]] -name = "rtic-common" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0786b50b81ef9d2a944a000f60405bb28bf30cd45da2d182f3fe636b2321f35c" +checksum = "10b34c9e6832388e45f3c01f1bb60a016384a0a4ad80cdd7d34913bed25037f0" dependencies = [ "critical-section", + "ufmt-write", ] [[package]] -name = "rtic-core" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42" - -[[package]] -name = "rtic-macros" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8617533990b728e31bc65fcec8fec51fa1b4000fb33189ebeb05fb9d8625444d" -dependencies = [ - "indexmap", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rtic-monotonics" -version = "1.1.0" +name = "rustc_version" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e9f99e2119d5bdd927c45a31ef9e8d9888f02ede3e357bcbd7ab79c426e02d" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "atomic-polyfill", - "cfg-if", - "cortex-m", - "fugit", - "rtic-time", + "semver", ] [[package]] -name = "rtic-time" -version = "1.0.0" +name = "rustix" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55127cfa37ad32522eca2b70a12298bdb035c75ee3a4e403af8773ffe1a64bd3" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "critical-section", - "futures-util", - "rtic-common", + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] -name = "rtt-target" -version = "0.3.1" +name = "rustversion" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065d6058bb1204f51a562a67209e1817cf714759d5cf845aa45c75fa7b0b9d9b" -dependencies = [ - "ufmt-write", -] +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] -name = "rtt-target" -version = "0.4.0" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afa12c77ba1b9bf560e4039a9b9a08bb9cde0e9e6923955eeb917dd8d5cf303" -dependencies = [ - "critical-section", - "ufmt-write", -] +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "rustc_version" -version = "0.2.3" +name = "sdio-host" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" [[package]] name = "semver" @@ -760,24 +1422,36 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.48", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smallvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" + [[package]] name = "ssmarshal" version = "1.0.0" @@ -795,37 +1469,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "stm32h7" -version = "0.15.1" +name = "static_cell" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa6ba4cf83bf80d3eb25f098ea5e790a0a1fcb5e357442259b231e412c2d3ca0" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "stm32-fmc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830ed60f33e6194ecb377f5d6ab765dc0e37e7b65e765f1fa87df13336658d63" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "362f288cd8341e9209587b889c385f323e82fc237b60c272868965bb879bb9b1" +checksum = "deabea56a8821dcea05d0109f3ab3135f31eb572444e5da203d06149c594c8c6" dependencies = [ - "bare-metal 1.0.0", "cortex-m", "cortex-m-rt", - "vcell", ] [[package]] -name = "stm32h7xx-hal" -version = "0.15.1" +name = "string_cache" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08bcfbdbe4458133f2fd55994a5c4f1b4bf28084f0218e93cdbc19d7c70219f" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ - "bare-metal 1.0.0", - "cast", - "cortex-m", - "embedded-dma", - "embedded-hal 0.2.7", - "embedded-storage", - "fugit", - "nb 1.1.0", - "paste", - "stm32h7", - "synopsys-usb-otg", - "void", + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared", + "precomputed-hash", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.109" @@ -839,9 +1528,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.31" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -849,43 +1538,66 @@ dependencies = [ ] [[package]] -name = "synopsys-usb-otg" -version = "0.3.2" +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "term" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678f3707a7b1fd4863023292c42f73c6bab0e9b0096f41ae612d1af0ff221b45" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" dependencies = [ - "cortex-m", - "embedded-hal 0.2.7", - "usb-device", - "vcell", + "dirs-next", + "rustversion", + "winapi", ] [[package]] -name = "tap" -version = "1.0.1" +name = "termcolor" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.48", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "ufmt-write" version = "0.1.0" @@ -894,9 +1606,21 @@ checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "usb-device" @@ -959,13 +1683,173 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "volatile-register" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" dependencies = [ "vcell", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "wyz" version = "0.5.1" diff --git a/README.md b/README.md index 2f57874c9..e3274164c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ Keyboard firmware for cortex-m, with layer/dynamic keymap/vial support, written in Rust and tested on stm32 and rp2040. +## News + +Rmk just released version 0.1.0, migrate to [Embassy](https://github.com/embassy-rs/embassy)! By migrating to Embassy, Rmk now has better async support, supports more MCUs much easier APIs than before. For examples using Embassy, check [`boards`](https://github.com/HaoboGu/rmk/tree/main/boards) folder! + ## Prerequisites This crate requires **nightly** Rust. `openocd`(stm32) or `probe-rs`(rp2040) is used for flashing & debugging. @@ -73,8 +77,15 @@ A lot of todos at the list, any contributions are welcomed :) - [x] system/media keys - [x] vial support - [x] eeprom -- [ ] support embassy runtime -- [ ] macro +- [ ] keyboard macro - [ ] encoder - [ ] RGB -- [ ] cli tools \ No newline at end of file +- [ ] cli tools + +## License +Rmk is licensed under either of + +- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) + +at your option. \ No newline at end of file diff --git a/boards/rp2040/Cargo.toml b/boards/rp2040/Cargo.toml index 0bbcb491d..532c7403d 100644 --- a/boards/rp2040/Cargo.toml +++ b/boards/rp2040/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["per-package-target"] [package] name = "rmk-rp2040" -version = "0.0.3" +version = "0.1.0" authors = ["Haobo Gu "] description = "Keyboard firmware written in Rust" homepage = "https://github.com/haobogu/rmk" @@ -14,32 +14,45 @@ license = "MIT OR Apache-2.0" forced-target = "thumbv6m-none-eabi" [dependencies] -rmk = { version = "0.0.6", path = "../../rmk", features = [ +rmk = { version = "0.1.0", path = "../../rmk", features = [ "eeprom", "col2row", ] } +embassy-time = { version = "0.3.0", git = "https://github.com/embassy-rs/embassy", features = [ + "defmt", + "defmt-timestamp-uptime", +] } +embassy-rp = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy", features = [ + "defmt", + "time-driver", + "critical-section-impl", +] } +embassy-executor = { version = "0.5.0", git = "https://github.com/embassy-rs/embassy", features = [ + "defmt", + "arch-cortex-m", + "executor-thread", + "integrated-timers", +] } +embassy-futures = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy" } -# Use pico as the BSP crate -rp-pico = "0.8" - +cortex-m = { version = "0.7.7", features = ["inline-asm"] } +cortex-m-rt = "0.7.3" defmt = "0.3" defmt-rtt = "0.4" -panic-probe = { version = "0.3", features = ["print-defmt"] } - -# Workspace dependencies -embedded-hal = { version = "0.2.7", features = ["unproven"] } -cortex-m = "0.7.7" -cortex-m-rt = "0.7.3" +embedded-hal = { version = "1.0.0", features = ["defmt-03"] } +embedded-storage = "0.3" log = "0.4.19" -rtic = { version = "2.0.0", features = ["thumbv6-backend"] } -rtic-monotonics = { version = "1.0.0", features = ["cortex-m-systick"] } +panic-probe = { version = "0.3", features = ["print-defmt"] } +portable-atomic = { version = "1.5", features = ["critical-section"] } +packed_struct = { version = "0.10.1", default-features = false } +static_cell = { version = "2" } [features] # avoid having to use --allow-multiple-definition linker flag # on macOS with Apple Silicon at least -default = ["rp-pico/disable-intrinsics"] +# default = ["rp-pico/disable-intrinsics"] [[bin]] name = "rmk-rp2040" test = false -bench = false \ No newline at end of file +bench = false diff --git a/boards/rp2040/src/keymap.rs b/boards/rp2040/src/keymap.rs index 2da774aa0..40dd1b3f7 100644 --- a/boards/rp2040/src/keymap.rs +++ b/boards/rp2040/src/keymap.rs @@ -1,9 +1,10 @@ use rmk::action::KeyAction; use rmk::{a, k, layer, mo}; -const COL: usize = 3; -const ROW: usize = 4; -const NUM_LAYER: usize = 2; +pub(crate) const COL: usize = 3; +pub(crate) const ROW: usize = 4; +pub(crate) const NUM_LAYER: usize = 2; +#[rustfmt::skip] pub static KEYMAP: [[[KeyAction; COL]; ROW]; NUM_LAYER] = [ layer!([ [k!(A), k!(B), k!(C)], diff --git a/boards/rp2040/src/macros.rs b/boards/rp2040/src/macros.rs new file mode 100644 index 000000000..37938a024 --- /dev/null +++ b/boards/rp2040/src/macros.rs @@ -0,0 +1,12 @@ +macro_rules! config_matrix_pins_rp { + (peripherals: $p:ident, input: [$($in_pin:ident), *], output: [$($out_pin:ident), +]) => { + { + let mut output_pins = [$(Output::new(AnyPin::from($p.$out_pin), embassy_rp::gpio::Level::Low)), +]; + let input_pins = [$(Input::new(AnyPin::from($p.$in_pin), embassy_rp::gpio::Pull::Down)), +]; + output_pins.iter_mut().for_each(|p| { + p.set_low(); + }); + (input_pins, output_pins) + } + }; +} \ No newline at end of file diff --git a/boards/rp2040/src/main.rs b/boards/rp2040/src/main.rs index d89a8b25e..20b6a5f2a 100644 --- a/boards/rp2040/src/main.rs +++ b/boards/rp2040/src/main.rs @@ -1,169 +1,108 @@ -#![no_std] #![no_main] +#![no_std] #![feature(type_alias_impl_trait)] +#[macro_use] mod keymap; +#[macro_use] +mod macros; + +use core::cell::RefCell; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_rp::{ + bind_interrupts, + flash::{Blocking, Flash}, + gpio::{AnyPin, Input, Output}, + peripherals::{self, USB}, + usb::{Driver, InterruptHandler}, +}; +use embassy_time::Timer; + +use defmt::*; use defmt_rtt as _; use panic_probe as _; - -#[rtic::app( - device = rp_pico::hal::pac, - dispatchers = [TIMER_IRQ_1] -)] -mod app { - use defmt::*; - use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; - use rmk::{ - config::KEYBOARD_CONFIG, eeprom::EepromStorageConfig, flash::EmptyFlashWrapper, - initialize_keyboard_and_usb_device, keyboard::Keyboard, usb::KeyboardUsbDevice, - usb_device::class_prelude::UsbBusAllocator, - }; - use rp_pico::{ - hal::{ - clocks::init_clocks_and_plls, gpio::*, sio, sio::Sio, usb::UsbBus, watchdog::Watchdog, - }, - Pins, XOSC_CRYSTAL_FREQ, - }; - use rtic_monotonics::systick::*; - - // Static usb bus instance - static mut USB_BUS: Option> = None; - - #[shared] - struct Shared { - usb_device: KeyboardUsbDevice<'static, UsbBus>, - } - - #[local] - struct Local { - led: Pin, PullDown>, - keyboard: Keyboard< - Pin, PullDown>, - Pin, PullDown>, - EmptyFlashWrapper, - 0, - 4, - 3, - 2, +use rmk::{eeprom::EepromStorageConfig, initialize_keyboard_and_usb_device, keymap::KeyMap}; +use static_cell::StaticCell; + +use crate::keymap::{COL, NUM_LAYER, ROW}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + +// static SUSPENDED: AtomicBool = AtomicBool::new(false); +const FLASH_SECTOR_15_ADDR: u32 = 15 * 8192; +const EEPROM_SIZE: usize = 128; +const FLASH_SIZE: usize = 2 * 1024 * 1024; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Rmk start!"); + // Initialize peripherals + let p = embassy_rp::init(Default::default()); + + // Create the usb driver, from the HAL + let driver = Driver::new(p.USB, Irqs); + + // Pin config + let (input_pins, output_pins) = config_matrix_pins_rp!(peripherals: p, input: [PIN_6, PIN_7, PIN_8, PIN_9], output: [PIN_19, PIN_20, PIN_21]); + + // Keymap + eeprom config + static MY_KEYMAP: StaticCell< + RefCell< + KeyMap< + Flash, + EEPROM_SIZE, + ROW, + COL, + NUM_LAYER, + >, >, - } - - #[init] - fn init(c: init::Context) -> (Shared, Local) { - // Soft-reset does not release the hardware spinlocks - // Release them now to avoid a deadlock after debug or watchdog reset - unsafe { - sio::spinlock_reset(); - } - - // Initialize the systick interrupt & obtain the token to prove that we did - let systick_mono_token = rtic_monotonics::create_systick_token!(); - // Default rp2040 clock-rate is 125MHz - Systick::start(c.core.SYST, 125_000_000, systick_mono_token); - - let mut resets = c.device.RESETS; - // Initialize clocks - let mut watchdog = Watchdog::new(c.device.WATCHDOG); - let clocks = init_clocks_and_plls( - XOSC_CRYSTAL_FREQ, - c.device.XOSC, - c.device.CLOCKS, - c.device.PLL_SYS, - c.device.PLL_USB, - &mut resets, - &mut watchdog, - ) - .ok() - .unwrap(); - - // GPIO config - let sio = Sio::new(c.device.SIO); - let pins = Pins::new( - c.device.IO_BANK0, - c.device.PADS_BANK0, - sio.gpio_bank0, - &mut resets, - ); - let mut led = pins.led.into_push_pull_output(); - led.set_low().unwrap(); - - // Usb config - let usb_bus = UsbBusAllocator::new(UsbBus::new( - c.device.USBCTRL_REGS, - c.device.USBCTRL_DPRAM, - clocks.usb_clock, - true, - &mut resets, - )); - - unsafe { - USB_BUS = Some(usb_bus); + > = StaticCell::new(); + let eeprom_storage_config = EepromStorageConfig { + start_addr: FLASH_SECTOR_15_ADDR, + storage_size: 8192, // uses 8KB for eeprom + page_size: 32, + }; + // Use internal flash to emulate eeprom + // let f = Flash::new_blocking(p.FLASH); + let flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(p.FLASH); + // let mut flash = Flash::new_blocking(p.FLASH); + let keymap = MY_KEYMAP.init(RefCell::new(KeyMap::new( + crate::keymap::KEYMAP, + Some(flash), + eeprom_storage_config, + None, + ))); + + // Initialize all utilities: keyboard, usb and keymap + let (mut keyboard, mut usb_device, vial) = initialize_keyboard_and_usb_device::< + Driver<'_, USB>, + Input<'_, AnyPin>, + Output<'_, AnyPin>, + Flash, + EEPROM_SIZE, + ROW, + COL, + NUM_LAYER, + >(driver, input_pins, output_pins, keymap); + + let usb_fut = usb_device.device.run(); + let keyboard_fut = async { + loop { + let _ = keyboard.keyboard_task().await; + keyboard.send_report(&mut usb_device.keyboard_hid).await; + keyboard.send_media_report(&mut usb_device.other_hid).await; } + }; - // Matrix config - let gp6 = pins.gpio6.into_pull_down_input().into_dyn_pin(); - let gp7 = pins.gpio7.into_pull_down_input().into_dyn_pin(); - let gp8 = pins.gpio8.into_pull_down_input().into_dyn_pin(); - let gp9 = pins.gpio9.into_pull_down_input().into_dyn_pin(); - let gp19 = pins - .gpio19 - .into_push_pull_output_in_state(PinState::Low) - .into_dyn_pin(); - let gp20 = pins - .gpio20 - .into_push_pull_output_in_state(PinState::Low) - .into_dyn_pin(); - let gp21 = pins - .gpio21 - .into_push_pull_output_in_state(PinState::Low) - .into_dyn_pin(); - let output_pins = [gp19, gp20, gp21]; - let input_pins = [gp6, gp7, gp8, gp9]; - - let (keyboard, usb_device) = initialize_keyboard_and_usb_device( - unsafe { USB_BUS.as_ref().unwrap() }, - &KEYBOARD_CONFIG, - None, - EepromStorageConfig::default(), - None, - input_pins, - output_pins, - crate::keymap::KEYMAP, - ); - - // Spawn heartbeat task - scan::spawn().ok(); - - (Shared { usb_device }, Local { led, keyboard }) - } - - #[task(local = [keyboard, led], priority = 1, shared = [usb_device])] - async fn scan(mut cx: scan::Context) { - // Keyboard scan task - info!("Start matrix scanning"); + let via_fut = async { loop { - cx.local.keyboard.keyboard_task().await.unwrap(); - cx.shared.usb_device.lock(|usb_device| { - // Send keyboard report - cx.local.keyboard.send_report(usb_device); - - // Process via report - cx.local.keyboard.process_via_report(usb_device); - }); - - // Blink LED - let _ = cx.local.led.toggle(); - - // Scanning frequency: 10KHZ - Systick::delay(100.micros()).await; + vial.process_via_report(&mut usb_device.via_hid).await; + Timer::after_millis(1).await; } - } - - #[task(binds = USBCTRL_IRQ, priority = 2, shared = [usb_device])] - fn usb_poll(mut cx: usb_poll::Context) { - cx.shared.usb_device.lock(|usb_device| { - usb_device.usb_poll(); - }); - } + }; + join(usb_fut, join(keyboard_fut, via_fut)).await; } diff --git a/boards/stm32h7/.cargo/config.toml b/boards/stm32h7/.cargo/config.toml index 7381a2854..c6eb38be2 100644 --- a/boards/stm32h7/.cargo/config.toml +++ b/boards/stm32h7/.cargo/config.toml @@ -5,7 +5,7 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # uncomment ONE of these three option to make `cargo run` start a GDB session # which option to pick depends on your system -runner = "arm-none-eabi-gdb -q -x openocd.gdb" +runner = "probe-rs run --chip STM32H7B0VBTx" # runner = "gdb-multiarch -q -x openocd.gdb" # runner = "gdb -q -x openocd.gdb" diff --git a/boards/stm32h7/Cargo.toml b/boards/stm32h7/Cargo.toml index c902264ee..c9508ad15 100644 --- a/boards/stm32h7/Cargo.toml +++ b/boards/stm32h7/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["per-package-target"] [package] name = "rmk-stm32h7" -version = "0.0.3" +version = "0.1.0" authors = ["Haobo Gu "] description = "Keyboard firmware written in Rust" homepage = "https://github.com/haobogu/rmk" @@ -14,26 +14,39 @@ license = "MIT OR Apache-2.0" forced-target = "thumbv7em-none-eabihf" [dependencies] -rmk = { version = "0.0.6", path = "../../rmk", features = [ +rmk = { version = "0.1.0", path = "../../rmk", features = [ "eeprom", "col2row", ] } -stm32h7xx-hal = { version = "0.15.1", features = [ - "stm32h7b0", - "rt", - "log-rtt", - "usb_hs", -] } -# Workspace dependencies -cortex-m = "0.7.7" +cortex-m = { version = "0.7.7", features = ['critical-section-single-core'] } cortex-m-rt = "0.7.3" panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } -rtt-target = "0.4.0" +embassy-time = { version = "0.3", git = "https://github.com/embassy-rs/embassy", features = [ + # "tick-hz-1_000_000", + "tick-hz-32_768", +] } +embassy-stm32 = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy", features = [ + "stm32h7b0vb", + "time-driver-any", + "exti", + "time", +] } +embassy-executor = { version = "0.5.0", git = "https://github.com/embassy-rs/embassy", features = [ + "arch-cortex-m", + "executor-thread", + "integrated-timers", +] } +embassy-futures = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy" } +rtt-target = "0.5.0" log = "0.4.19" -rtic = { version = "2.0.1", features = ["thumbv7-backend"] } -rtic-monotonics = { version = "1.0.0", features = ["cortex-m-systick"] } packed_struct = { version = "0.10.1", default-features = false } embedded-storage = { version = "0.3" } +static_cell = { version = "2" } + +# defmt deps +# defmt = "0.3.5" +# defmt-rtt = "0.4.0" +# panic-probe = "0.3.1" [[bin]] name = "rmk-stm32h7" diff --git a/boards/stm32h7/build.rs b/boards/stm32h7/build.rs index cbcc6944a..6177bbbeb 100644 --- a/boards/stm32h7/build.rs +++ b/boards/stm32h7/build.rs @@ -41,5 +41,8 @@ fn main() { // Set the linker script to the one provided by cortex-m-rt. println!("cargo:rustc-link-arg=-Tlink.x"); + // Set the extra linker script from defmt + // println!("cargo:rustc-link-arg=-Tdefmt.x"); + println!("cargo:rustc-linker=flip-link"); } diff --git a/boards/stm32h7/src/flash.rs b/boards/stm32h7/src/flash.rs deleted file mode 100644 index 74e6c2cad..000000000 --- a/boards/stm32h7/src/flash.rs +++ /dev/null @@ -1,45 +0,0 @@ -use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; -use stm32h7xx_hal::flash::{Error, LockedFlashBank, UnlockedFlashBank}; - -/// rmk::Keyboard requires `NorFlash` trait to emulate the eeprom, but `stm32h7xx-hal` doesn't implement `NorFlash` for it's internal flash. -pub struct FlashWrapper { - locked_flash: LockedFlashBank, -} - -impl FlashWrapper { - pub fn new(locked: LockedFlashBank) -> Self { - Self { - locked_flash: locked, - } - } -} - -impl ErrorType for FlashWrapper { - type Error = Error; -} - -impl NorFlash for FlashWrapper { - const WRITE_SIZE: usize = UnlockedFlashBank::WRITE_SIZE; - const ERASE_SIZE: usize = UnlockedFlashBank::ERASE_SIZE; - - fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { - let mut unlocked = self.locked_flash.unlocked(); - unlocked.erase(from, to) - } - - fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { - let mut unlocked = self.locked_flash.unlocked(); - unlocked.write(offset, bytes) - } -} - -impl ReadNorFlash for FlashWrapper { - const READ_SIZE: usize = 1; - fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { - self.locked_flash.read(offset, bytes) - } - - fn capacity(&self) -> usize { - self.locked_flash.capacity() - } -} diff --git a/boards/stm32h7/src/macros.rs b/boards/stm32h7/src/macros.rs index 02fedc0d2..7808d3a49 100644 --- a/boards/stm32h7/src/macros.rs +++ b/boards/stm32h7/src/macros.rs @@ -1,5 +1,6 @@ -macro_rules! config_matrix_pins { - (input: [$($in_port:ident.$in_pin:ident), *], output: [$($out_port: ident.$out_pin: ident), +]) => { +// DEPRECIATED +macro_rules! _config_matrix_pins { + (input: [$($in_port:ident.$in_pin:ident), *], output: [$($out_port:ident.$out_pin:ident), +]) => { { $( let $in_pin = $in_port.$in_pin.into_pull_down_input().erase(); @@ -17,3 +18,15 @@ macro_rules! config_matrix_pins { }; } +macro_rules! config_matrix_pins_stm32 { + (peripherals: $p:ident, input: [$($in_pin:ident), *], output: [$($out_pin:ident), +]) => { + { + let mut output_pins = [$(Output::new($p.$out_pin, embassy_stm32::gpio::Level::Low, embassy_stm32::gpio::Speed::VeryHigh).degrade()), +]; + let input_pins = [$(Input::new($p.$in_pin, embassy_stm32::gpio::Pull::Down).degrade()), +]; + output_pins.iter_mut().for_each(|p| { + p.set_low(); + }); + (input_pins, output_pins) + } + }; +} diff --git a/boards/stm32h7/src/main.rs b/boards/stm32h7/src/main.rs index 8aec34a39..83dae4977 100644 --- a/boards/stm32h7/src/main.rs +++ b/boards/stm32h7/src/main.rs @@ -8,165 +8,136 @@ mod macros; mod keymap; #[macro_use] pub mod rtt_logger; -mod flash; +use core::{cell::RefCell, sync::atomic::AtomicBool}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_stm32::{ + bind_interrupts, + flash::{Blocking, Flash}, + gpio::{AnyPin, Input, Output}, + peripherals::USB_OTG_HS, + time::Hertz, + usb_otg::{Driver, InterruptHandler}, + Config, +}; +use embassy_time::Timer; +use log::info; use panic_rtt_target as _; -use rtic::app; +use rmk::{eeprom::EepromStorageConfig, initialize_keyboard_and_usb_device, keymap::KeyMap}; +use static_cell::StaticCell; -#[app(device = stm32h7xx_hal::pac, peripherals = true)] -mod app { - use crate::{ - flash::FlashWrapper, - keymap::{COL, NUM_LAYER, ROW}, - rtt_logger, - }; - use log::info; - use rmk::eeprom::EepromStorageConfig; - use rmk::keyboard::Keyboard; - use rmk::usb::KeyboardUsbDevice; - use rmk::{config::KEYBOARD_CONFIG, initialize_keyboard_and_usb_device}; - use rtic_monotonics::systick::*; - use stm32h7xx_hal::{ - gpio::{ErasedPin, Input, Output, PE3}, - pac::rcc::cdccip2r::USBSEL_A::Hsi48, - prelude::*, - usb_hs::{UsbBus, USB1}, - }; +use crate::keymap::{COL, NUM_LAYER, ROW}; - static mut EP_MEMORY: [u32; 1024] = [0; 1024]; - const FLASH_SECTOR_15_ADDR: u32 = 15 * 8192; - const EEPROM_SIZE: usize = 256; +bind_interrupts!(struct Irqs { + OTG_HS => InterruptHandler; +}); - #[shared] - struct Shared { - usb_device: KeyboardUsbDevice<'static, UsbBus>, - led: PE3, - } +static SUSPENDED: AtomicBool = AtomicBool::new(false); +const FLASH_SECTOR_15_ADDR: u32 = 15 * 8192; +const EEPROM_SIZE: usize = 128; - #[local] - struct Local { - keyboard: Keyboard< - ErasedPin, - ErasedPin, - FlashWrapper, - EEPROM_SIZE, - ROW, - COL, - NUM_LAYER, - >, +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + if cfg!(debug_assertions) { + rtt_logger::init(log::LevelFilter::Info); } - - #[init] - fn init(cx: init::Context) -> (Shared, Local) { - if cfg!(debug_assertions) { - rtt_logger::init(log::LevelFilter::Info); - } - - let cp = cx.core; - let dp = cx.device; - - // Initialize the systick interrupt & obtain the token to prove that we did - let systick_mono_token = rtic_monotonics::create_systick_token!(); - // Default clock rate is 225MHz - Systick::start(cp.SYST, 225_000_000, systick_mono_token); - - // Power config - let pwr = dp.PWR.constrain(); - let pwrcfg = pwr.freeze(); - - // Clock config - let rcc = dp.RCC.constrain(); - let mut ccdr = rcc - .use_hse(25.MHz()) - .sys_ck(225.MHz()) - .hclk(225.MHz()) - .per_ck(225.MHz()) - .freeze(pwrcfg, &dp.SYSCFG); - // Check HSI 48MHZ - let _ = ccdr.clocks.hsi48_ck().expect("HSI48 must run"); - // Config HSI - ccdr.peripheral.kernel_usb_clk_mux(Hsi48); - - // GPIO config - let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA); - let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE); - let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD); - let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); - - // USB config - let usb_dm = gpioa.pa11.into_analog(); - let usb_dp = gpioa.pa12.into_analog(); - let usb: USB1 = USB1::new( - dp.OTG1_HS_GLOBAL, - dp.OTG1_HS_DEVICE, - dp.OTG1_HS_PWRCLK, - usb_dm, - usb_dp, - ccdr.peripheral.USB1OTG, - &ccdr.clocks, - ); - let usb_allocator = cortex_m::singleton!( - : rmk::usb_device::class_prelude::UsbBusAllocator> = - UsbBus::new(usb, unsafe { &mut EP_MEMORY }) - ) - .unwrap(); - - // Initialize keyboard matrix pins - let (input_pins, output_pins) = config_matrix_pins!(input: [gpiod.pd9, gpiod.pd8, gpiob.pb13, gpiob.pb12], output: [gpioe.pe13,gpioe.pe14,gpioe.pe15]); - - // Get flash for eeprom - let (flash, _) = dp.FLASH.split(); - let internal_flash = crate::flash::FlashWrapper::new(flash); - let storage_config = EepromStorageConfig { - start_addr: FLASH_SECTOR_15_ADDR, - storage_size: 8192, - page_size: 16, - }; - - // Initialize keyboard - let (keyboard, usb_device) = initialize_keyboard_and_usb_device( - usb_allocator, - &KEYBOARD_CONFIG, - Some(internal_flash), - storage_config, - None, - input_pins, - output_pins, - crate::keymap::KEYMAP, - ); - - // Led config - let mut led = gpioe.pe3.into_push_pull_output(); - led.set_high(); - - // Spawn keyboard task - scan::spawn().ok(); - - // RTIC resources - (Shared { usb_device, led }, Local { keyboard }) + info!("Rmk start!"); + // RCC config + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = Some(HSIPrescaler::DIV1); + config.rcc.csi = true; + // Needed for USB + config.rcc.hsi48 = Some(Hsi48Config { + sync_from_usb: true, + }); + // External oscillator 25MHZ + config.rcc.hse = Some(Hse { + freq: Hertz(25_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll1 = Some(Pll { + source: PllSource::HSE, + prediv: PllPreDiv::DIV5, + mul: PllMul::MUL112, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV2), + divr: Some(PllDiv::DIV2), + }); + config.rcc.sys = Sysclk::PLL1_P; + config.rcc.ahb_pre = AHBPrescaler::DIV2; + config.rcc.apb1_pre = APBPrescaler::DIV2; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.apb3_pre = APBPrescaler::DIV2; + config.rcc.apb4_pre = APBPrescaler::DIV2; + config.rcc.voltage_scale = VoltageScale::Scale0; } - #[task(local = [keyboard], shared = [usb_device])] - async fn scan(mut cx: scan::Context) { - // Keyboard scan task - info!("Start matrix scanning"); + // Initialize peripherals + let p = embassy_stm32::init(config); + + // Usb config + static EP_OUT_BUFFER: StaticCell<[u8; 1024]> = StaticCell::new(); + let mut usb_config = embassy_stm32::usb_otg::Config::default(); + usb_config.vbus_detection = false; + let driver = Driver::new_fs( + p.USB_OTG_HS, + Irqs, + p.PA12, + p.PA11, + &mut EP_OUT_BUFFER.init([0; 1024])[..], + usb_config, + ); + + // Pin config + let (input_pins, output_pins) = config_matrix_pins_stm32!(peripherals: p, input: [PD9, PD8, PB13, PB12], output: [PE13, PE14, PE15]); + + // Keymap + eeprom config + static MY_KEYMAP: StaticCell< + RefCell, EEPROM_SIZE, ROW, COL, NUM_LAYER>>, + > = StaticCell::new(); + let eeprom_storage_config = EepromStorageConfig { + start_addr: FLASH_SECTOR_15_ADDR, + storage_size: 8192, // uses 8KB for eeprom + page_size: 32, + }; + // Use internal flash to emulate eeprom + let f = Flash::new_blocking(p.FLASH); + let keymap = MY_KEYMAP.init(RefCell::new(KeyMap::new( + crate::keymap::KEYMAP, + Some(f), + eeprom_storage_config, + None, + ))); + + // Initialize all utilities: keyboard, usb and keymap + let (mut keyboard, mut usb_device, vial) = initialize_keyboard_and_usb_device::< + Driver<'_, USB_OTG_HS>, + Input<'_, AnyPin>, + Output<'_, AnyPin>, + Flash<'_, Blocking>, + EEPROM_SIZE, + ROW, + COL, + NUM_LAYER, + >(driver, input_pins, output_pins, keymap); + + let usb_fut = usb_device.device.run(); + let keyboard_fut = async { loop { - cx.local.keyboard.keyboard_task().await.unwrap(); - cx.shared.usb_device.lock(|usb_device| { - // Send keyboard report - cx.local.keyboard.send_report(usb_device); - // Process via report - cx.local.keyboard.process_via_report(usb_device); - }); - // Scanning frequency: 10KHZ - Systick::delay(100.micros()).await; + let _ = keyboard.keyboard_task().await; + keyboard.send_report(&mut usb_device.keyboard_hid).await; + keyboard.send_media_report(&mut usb_device.other_hid).await; } - } + }; - #[task(binds = OTG_HS, shared = [usb_device])] - fn usb_poll(mut cx: usb_poll::Context) { - cx.shared.usb_device.lock(|usb_device| { - usb_device.usb_poll(); - }); - } + let via_fut = async { + loop { + vial.process_via_report(&mut usb_device.via_hid).await; + Timer::after_millis(1).await; + } + }; + join(usb_fut, join(keyboard_fut, via_fut)).await; } diff --git a/rmk/Cargo.toml b/rmk/Cargo.toml index 6f4efe298..628cb4f66 100644 --- a/rmk/Cargo.toml +++ b/rmk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rmk" -version = "0.0.6" +version = "0.1.0" authors = ["Haobo Gu "] description = "Keyboard firmware written in Rust" homepage = "https://github.com/haobogu/rmk" @@ -11,18 +11,21 @@ license = "MIT OR Apache-2.0" [dependencies] embedded-hal = "1.0.0" -embedded-storage = { version = "0.3" } -num_enum = { version = "0.7.0", default-features = false } -log = "0.4.19" -rtic-monotonics = { version = "1.0.0", features = [ - "cortex-m-systick", - "systick-10khz", +embedded-storage = "0.3" +embedded-alloc = "0.5" +embassy-time = { version = "0.3", git = "https://github.com/embassy-rs/embassy" } +embassy-usb = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy", features = [ + "usbd-hid", + "max-interface-count-8", + "max-handler-count-8", ] } -usb-device = "0.2.9" +embassy-sync = { version = "0.5.0", git = "https://github.com/embassy-rs/embassy" } +num_enum = { version = "0.7", default-features = false } +log = "0.4" +static_cell = { version = "2" } usbd-hid = "0.6.1" -packed_struct = { version = "0.10.1", default-features = false } +packed_struct = { version = "0.10", default-features = false } byteorder = { version = "1.4", default-features = false } -embedded-alloc = "0.5.0" [features] default = ["col2row"] diff --git a/rmk/src/config.rs b/rmk/src/config.rs deleted file mode 100644 index f8c0ce5ac..000000000 --- a/rmk/src/config.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub mod usb_config; - -use usb_config::UsbHidConfig; - -pub struct KeyboardConfig<'a> { - pub usb_config: UsbHidConfig<'a>, - pub enable_eeprom: bool, -} - -pub static KEYBOARD_CONFIG: KeyboardConfig = KeyboardConfig { - usb_config: UsbHidConfig { - pid: 0x4643, - vid: 0x4C4B, - manufacturer: "RMK", - product: "RMK product", - serial_number: "vial:f64c2b3c:000001", - }, - enable_eeprom: true, -}; diff --git a/rmk/src/config/usb_config.rs b/rmk/src/config/usb_config.rs deleted file mode 100644 index a7b493e0d..000000000 --- a/rmk/src/config/usb_config.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub struct UsbHidConfig<'a> { - pub pid: u16, - pub vid: u16, - pub manufacturer: &'a str, - pub product: &'a str, - pub serial_number: &'a str, -} diff --git a/rmk/src/debounce.rs b/rmk/src/debounce.rs index 622195898..ed0ffd8df 100644 --- a/rmk/src/debounce.rs +++ b/rmk/src/debounce.rs @@ -1,5 +1,6 @@ +use embassy_time::Instant; + use crate::matrix::KeyState; -use rtic_monotonics::{systick::Systick, Monotonic}; /// Default DEBOUNCE_THRESHOLD in ms. static DEBOUNCE_THRESHOLD: u16 = 10; @@ -55,7 +56,7 @@ impl key_state: &mut KeyState, ) { // Record debounce state per ms - let cur_tick = Systick::now().ticks(); + let cur_tick = Instant::now().as_ticks() as u32; let elapsed_ms = (cur_tick - self.last_tick) as u16; if elapsed_ms > 0 { diff --git a/rmk/src/eeprom.rs b/rmk/src/eeprom.rs index f7569ac09..5e9dab946 100644 --- a/rmk/src/eeprom.rs +++ b/rmk/src/eeprom.rs @@ -234,7 +234,8 @@ impl Eeprom { let mut buf = vec![0xFF_u8; self.storage_config.page_size as usize]; buf[..bytes.len()].copy_from_slice(&bytes); debug!( - "EEPROM write storage at 0x{:X}: {:02X?} ", + "EEPROM write storage length {:?} at 0x{:X}: {:X?} ", + buf.len(), self.storage_config.start_addr + self.pos, buf, ); @@ -247,7 +248,7 @@ impl Eeprom { Ok(_) => self.pos += self.storage_config.page_size, Err(e) => { error!( - "Failed to write record to storage at {:X}: {:?}", + "Failed to write record to storage at 0x{:X}: {:?}", self.storage_config.start_addr + self.pos, e ) diff --git a/rmk/src/keyboard.rs b/rmk/src/keyboard.rs index 7714921c8..5e6cf0f01 100644 --- a/rmk/src/keyboard.rs +++ b/rmk/src/keyboard.rs @@ -1,25 +1,20 @@ use crate::{ action::{Action, KeyAction}, - eeprom::{eeconfig::Eeconfig, Eeprom, EepromStorageConfig}, keycode::{KeyCode, ModifierCombination}, keymap::KeyMap, matrix::{KeyState, Matrix}, - usb::KeyboardUsbDevice, - via::{descriptor::ViaReport, process::process_via_packet}, + usb::descriptor::ViaReport, }; -use core::convert::Infallible; -use embedded_alloc::Heap; +use core::{cell::RefCell, convert::Infallible}; +use embassy_time::Timer; +use embassy_usb::{class::hid::HidReaderWriter, driver::Driver}; use embedded_hal::digital::{InputPin, OutputPin}; use embedded_storage::nor_flash::NorFlash; -use log::{debug, warn}; -use rtic_monotonics::systick::*; -use usb_device::class_prelude::UsbBus; +use log::{debug, error, warn}; use usbd_hid::descriptor::{KeyboardReport, MediaKeyboardReport, SystemControlReport}; -#[global_allocator] -static HEAP: Heap = Heap::empty(); - pub struct Keyboard< + 'a, In: InputPin, Out: OutputPin, F: NorFlash, @@ -35,7 +30,7 @@ pub struct Keyboard< matrix: Matrix, /// Keymap - pub keymap: KeyMap, + pub keymap: &'a RefCell>, /// Keyboard internal hid report buf report: KeyboardReport, @@ -43,8 +38,6 @@ pub struct Keyboard< /// Media internal report media_report: MediaKeyboardReport, - eeprom: Option>, - /// System control internal report system_control_report: SystemControlReport, @@ -62,6 +55,7 @@ pub struct Keyboard< } impl< + 'a, In: InputPin, Out: OutputPin, F: NorFlash, @@ -69,47 +63,17 @@ impl< const ROW: usize, const COL: usize, const NUM_LAYER: usize, - > Keyboard + > Keyboard<'a, In, Out, F, EEPROM_SIZE, ROW, COL, NUM_LAYER> { #[cfg(feature = "col2row")] pub fn new( input_pins: [In; ROW], output_pins: [Out; COL], - storage: Option, - eeprom_storage_config: EepromStorageConfig, - eeconfig: Option, - mut keymap: [[[KeyAction; COL]; ROW]; NUM_LAYER], + keymap: &'a RefCell>, ) -> Self { - // Initialize the allocator at the very beginning of the initialization of the keyboard - { - use core::mem::MaybeUninit; - // 1KB heap size - const HEAP_SIZE: usize = 1024; - // Check page_size and heap size - assert!((eeprom_storage_config.page_size as usize) < HEAP_SIZE); - static mut HEAP_MEM: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; - unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) } - } - - let eeprom = match storage { - Some(s) => { - let e = Eeprom::new(s, eeprom_storage_config, eeconfig, &keymap); - // If eeprom is initialized, read keymap from it. - match e { - Some(e) => { - e.read_keymap(&mut keymap); - Some(e) - } - None => None, - } - } - None => None, - }; - Keyboard { matrix: Matrix::new(input_pins, output_pins), - keymap: KeyMap::new(keymap), - eeprom, + keymap, report: KeyboardReport { modifier: 0, reserved: 0, @@ -172,35 +136,39 @@ impl< } /// Send hid report. The report is sent only when key state changes. - pub fn send_report(&mut self, usb_device: &KeyboardUsbDevice<'_, B>) { - // TODO: refine changed, separate hid/media/system + pub async fn send_report<'d, D: Driver<'d>>( + &mut self, + hid_interface: &mut HidReaderWriter<'d, D, 1, 8>, + ) { if self.need_send_key_report { - usb_device.send_keyboard_report(&self.report); + // usb_device.send_keyboard_report(&self.report).await; + match hid_interface.write_serialize(&self.report).await { + Ok(()) => {} + Err(e) => error!("Send keyboard report error: {:?}", e), + }; // Reset report key states for bit in &mut self.report.keycodes { *bit = 0; } self.need_send_key_report = false; } + } + pub async fn send_media_report<'d, D: Driver<'d>>( + &mut self, + hid_interface: &mut HidReaderWriter<'d, D, 1, 8>, + ) { if self.need_send_consumer_control_report { debug!("Sending consumer report: {:?}", self.media_report); - usb_device.send_consumer_control_report(&self.media_report); + match hid_interface.write_serialize(&self.media_report).await { + Ok(()) => {} + Err(e) => error!("Send media(consumer control) report error: {:?}", e), + }; self.media_report.usage_id = 0; self.need_send_consumer_control_report = false; } } - /// Read hid report. - pub fn process_via_report(&mut self, usb_device: &mut KeyboardUsbDevice<'_, B>) { - if usb_device.read_via_report(&mut self.via_report) > 0 { - process_via_packet(&mut self.via_report, &mut self.keymap, &mut self.eeprom); - - // Send via report back after processing - usb_device.send_via_report(&self.via_report); - } - } - /// Main keyboard task, it scans matrix, processes active keys /// If there is any change of key states, set self.changed=true pub async fn keyboard_task(&mut self) -> Result<(), Infallible> { @@ -229,7 +197,10 @@ impl< // Process key let key_state = self.matrix.get_key_state(row, col); - let action = self.keymap.get_action_with_layer_cache(row, col, key_state); + let action = self + .keymap + .borrow_mut() + .get_action_with_layer_cache(row, col, key_state); match action { KeyAction::No | KeyAction::Transparent => (), KeyAction::Single(a) => self.process_key_action_normal(a, key_state), @@ -263,13 +234,13 @@ impl< // Turn off a layer temporarily when the key is pressed // Reactivate the layer after the key is released if key_state.changed && key_state.pressed { - self.keymap.deactivate_layer(layer_num); + self.keymap.borrow_mut().deactivate_layer(layer_num); } } Action::LayerToggle(layer_num) => { // Toggle a layer when the key is release if key_state.changed && !key_state.pressed { - self.keymap.toggle_layer(layer_num); + self.keymap.borrow_mut().toggle_layer(layer_num); } } _ => (), @@ -298,7 +269,7 @@ impl< // TODO: need to trigger hid send manually, then, release the key to perform a tap operation // Wait 10ms, then send release - Systick::delay(10.millis()).await; + Timer::after_millis(10).await; key_state.pressed = false; self.process_key_action_normal(action, key_state); @@ -344,9 +315,9 @@ impl< return; } if key_state.pressed { - self.keymap.activate_layer(layer_num); + self.keymap.borrow_mut().activate_layer(layer_num); } else { - self.keymap.deactivate_layer(layer_num); + self.keymap.borrow_mut().deactivate_layer(layer_num); } } diff --git a/rmk/src/keymap.rs b/rmk/src/keymap.rs index 26de2b235..aa29baed0 100644 --- a/rmk/src/keymap.rs +++ b/rmk/src/keymap.rs @@ -1,6 +1,15 @@ -use crate::{action::KeyAction, matrix::KeyState}; +use crate::{ + action::KeyAction, + eeprom::{eeconfig::Eeconfig, Eeprom, EepromStorageConfig}, + matrix::KeyState, +}; +use embedded_alloc::Heap; +use embedded_storage::nor_flash::NorFlash; use log::warn; +#[global_allocator] +static HEAP: Heap = Heap::empty(); + pub struct KeyMapConfig { /// Number of rows. pub row: usize, @@ -14,7 +23,13 @@ pub struct KeyMapConfig { /// The conception of KeyMap in rmk is borrowed from qmk: . /// Keymap should be bind to the actual pcb matrix definition. /// RMK detects hardware key strokes, uses (row,col) to retrieve the action from KeyMap. -pub struct KeyMap { +pub struct KeyMap< + F: NorFlash, + const EEPROM_SIZE: usize, + const ROW: usize, + const COL: usize, + const NUM_LAYER: usize, +> { /// Layers pub(crate) layers: [[[KeyAction; COL]; ROW]; NUM_LAYER], /// Current state of each layer @@ -23,16 +38,58 @@ pub struct KeyMap { default_layer: u8, /// Layer cache layer_cache: [[u8; COL]; ROW], + /// Eeprom for storing keymap + pub(crate) eeprom: Option>, } -impl KeyMap { +impl< + F: NorFlash, + const EEPROM_SIZE: usize, + const ROW: usize, + const COL: usize, + const NUM_LAYER: usize, + > KeyMap +{ /// Initialize a keymap from a matrix of actions - pub fn new(action_map: [[[KeyAction; COL]; ROW]; NUM_LAYER]) -> KeyMap { + pub fn new( + mut action_map: [[[KeyAction; COL]; ROW]; NUM_LAYER], + storage: Option, + eeprom_storage_config: EepromStorageConfig, + eeconfig: Option, + ) -> KeyMap { + // Initialize the allocator at the very beginning of the initialization of the keymap + { + use core::mem::MaybeUninit; + // 1KB heap size + const HEAP_SIZE: usize = 512; + // Check page_size and heap size + assert!((eeprom_storage_config.page_size as usize) < HEAP_SIZE); + static mut HEAP_MEM: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; + unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) } + } + + // Initialize eeprom, if success, re-load keymap from it + let eeprom = match storage { + Some(s) => { + let e = Eeprom::new(s, eeprom_storage_config, eeconfig, &mut action_map); + // If eeprom is initialized, read keymap from it. + match e { + Some(e) => { + e.read_keymap(&mut action_map); + Some(e) + } + None => None, + } + } + None => None, + }; + KeyMap { layers: action_map, layer_state: [false; NUM_LAYER], default_layer: 0, layer_cache: [[0; COL]; ROW], + eeprom, } } diff --git a/rmk/src/lib.rs b/rmk/src/lib.rs index 9d6b8f515..df5c37649 100644 --- a/rmk/src/lib.rs +++ b/rmk/src/lib.rs @@ -6,21 +6,20 @@ // Enable std in test #![cfg_attr(not(test), no_std)] -use action::KeyAction; -use config::KeyboardConfig; -use core::convert::Infallible; -use eeprom::{eeconfig::Eeconfig, EepromStorageConfig}; +use core::{cell::RefCell, convert::Infallible}; +use embassy_usb::driver::Driver; use embedded_hal::digital::{InputPin, OutputPin}; use embedded_storage::nor_flash::NorFlash; use keyboard::Keyboard; +use keymap::KeyMap; use usb::KeyboardUsbDevice; -use usb_device::class_prelude::{UsbBus, UsbBusAllocator}; -pub use usb_device; +pub use embassy_sync; +pub use embassy_usb; pub use usbd_hid; +use via::process::VialService; pub mod action; -pub mod config; pub mod debounce; pub mod eeprom; pub mod flash; @@ -34,8 +33,7 @@ pub mod via; /// Initialize keyboard core and keyboard usb device pub fn initialize_keyboard_and_usb_device< - 'a, - B: UsbBus, + D: Driver<'static>, In: InputPin, Out: OutputPin, F: NorFlash, @@ -44,27 +42,18 @@ pub fn initialize_keyboard_and_usb_device< const COL: usize, const NUM_LAYER: usize, >( - usb_allocator: &'a UsbBusAllocator, - config: &KeyboardConfig<'a>, - storage: Option, - eeprom_storage_config: EepromStorageConfig, - eeconfig: Option, + driver: D, input_pins: [In; ROW], output_pins: [Out; COL], - keymap: [[[KeyAction; COL]; ROW]; NUM_LAYER], + keymap: &'static RefCell>, ) -> ( Keyboard, - KeyboardUsbDevice<'a, B>, + KeyboardUsbDevice<'static, D>, + VialService<'static, F, EEPROM_SIZE, ROW, COL, NUM_LAYER>, ) { ( - Keyboard::new( - input_pins, - output_pins, - storage, - eeprom_storage_config, - eeconfig, - keymap, - ), - KeyboardUsbDevice::new(usb_allocator, config), + Keyboard::new(input_pins, output_pins, keymap), + KeyboardUsbDevice::new(driver), + VialService::new(keymap), ) } diff --git a/rmk/src/matrix.rs b/rmk/src/matrix.rs index 9a4d6aa2d..f64a268ad 100644 --- a/rmk/src/matrix.rs +++ b/rmk/src/matrix.rs @@ -1,14 +1,14 @@ use crate::debounce::Debouncer; use core::convert::Infallible; use embedded_hal::digital::{InputPin, OutputPin}; -use rtic_monotonics::{systick::*, Monotonic}; +use embassy_time::{Instant, Duration, Timer}; /// KeyState represents the state of a key. #[derive(Copy, Clone, Debug)] pub struct KeyState { pub pressed: bool, pub changed: bool, - pub hold_start: Option<::Instant>, + pub hold_start: Option, } impl Default for KeyState { @@ -27,12 +27,12 @@ impl KeyState { } pub fn start_timer(&mut self) { - self.hold_start = Some(Systick::now()); + self.hold_start = Some(Instant::now()); } - pub fn elapsed(&self) -> Option<::Duration> { + pub fn elapsed(&self) -> Option { match self.hold_start { - Some(t) => Systick::now().checked_duration_since(t), + Some(t) => Instant::now().checked_duration_since(t), None => None, } } @@ -87,7 +87,7 @@ impl< for (out_idx, out_pin) in self.output_pins.iter_mut().enumerate() { // Pull up output pin, wait 1us ensuring the change comes into effect out_pin.set_high()?; - Systick::delay(1.micros()).await; + Timer::after_micros(1).await; for (in_idx, in_pin) in self.input_pins.iter_mut().enumerate() { // Check input pins and debounce self.debouncer.debounce( diff --git a/rmk/src/usb.rs b/rmk/src/usb.rs index c88fddcd4..0450a1306 100644 --- a/rmk/src/usb.rs +++ b/rmk/src/usb.rs @@ -1,147 +1,193 @@ -use log::error; -use usb_device::{ - class_prelude::{UsbBus, UsbBusAllocator}, - prelude::{UsbDevice, UsbDeviceBuilder, UsbVidPid}, - UsbError, -}; -use usbd_hid::{ - descriptor::{KeyboardReport, MediaKeyboardReport, SerializedDescriptor, SystemControlReport}, - hid_class::{ - HIDClass, HidClassSettings, HidCountryCode, HidProtocol, HidSubClass, ProtocolModeConfig, - }, +use core::sync::atomic::{AtomicBool, Ordering}; +use embassy_usb::{ + class::hid::{Config, HidReaderWriter, ReportId, RequestHandler, State}, + control::OutResponse, + driver::Driver, + Builder, Handler, UsbDevice, }; +use log::info; +use static_cell::StaticCell; +use usbd_hid::descriptor::{KeyboardReport, MediaKeyboardReport, SerializedDescriptor}; + +pub mod descriptor; -use crate::{config::KeyboardConfig, via::descriptor::ViaReport}; +use crate::usb::descriptor::ViaReport; + +static SUSPENDED: AtomicBool = AtomicBool::new(false); // TODO: Use a composite hid device for Keyboard + Mouse + System control + Consumer control // In this case, report id should be used. // The keyboard usb device should have 3 hid instances: // 1. Boot keyboard: 1 endpoint in -// 2. Composite keyboard: Keyboard + Mouse + System control + Consumer control: 1 endpoint in -// 3. Raw hid communication: used to communicate with via: 2 endpoints(in/out) -pub struct KeyboardUsbDevice<'a, B: UsbBus> { - /// Usb hid instance - hid: HIDClass<'a, B>, - /// Consumer control hid instance - consumer_control_hid: HIDClass<'a, B>, - /// System control hid instance - system_control_hid: HIDClass<'a, B>, - /// Via communication instance - via_hid: HIDClass<'a, B>, - /// Usb device instance - usb_device: UsbDevice<'a, B>, +// 2. Other: Mouse + System control + Consumer control: 1 endpoint in +// 3. Via: used to communicate with via: 2 endpoints(in/out) +pub struct KeyboardUsbDevice<'d, D: Driver<'d>> { + pub device: UsbDevice<'d, D>, + pub keyboard_hid: HidReaderWriter<'d, D, 1, 8>, + pub other_hid: HidReaderWriter<'d, D, 1, 8>, + pub via_hid: HidReaderWriter<'d, D, 32, 32>, } -impl<'a, B: UsbBus> KeyboardUsbDevice<'a, B> { - pub fn new(usb_allocator: &'a UsbBusAllocator, config: &KeyboardConfig<'a>) -> Self { - KeyboardUsbDevice { - hid: HIDClass::new_ep_in_with_settings( - usb_allocator, - KeyboardReport::desc(), - 10, - HidClassSettings { - subclass: HidSubClass::Boot, - protocol: HidProtocol::Keyboard, - config: ProtocolModeConfig::ForceBoot, - locale: HidCountryCode::NotSupported, - }, - ), - consumer_control_hid: HIDClass::new_ep_in_with_settings( - usb_allocator, - MediaKeyboardReport::desc(), - 10, - HidClassSettings { - subclass: HidSubClass::NoSubClass, - protocol: HidProtocol::Keyboard, - config: ProtocolModeConfig::DefaultBehavior, - locale: HidCountryCode::NotSupported, - }, - ), - system_control_hid: HIDClass::new_ep_in_with_settings( - usb_allocator, - SystemControlReport::desc(), - 10, - HidClassSettings { - subclass: HidSubClass::NoSubClass, - protocol: HidProtocol::Keyboard, - config: ProtocolModeConfig::DefaultBehavior, - locale: HidCountryCode::NotSupported, - }, - ), - via_hid: HIDClass::new(usb_allocator, ViaReport::desc(), 10), - usb_device: UsbDeviceBuilder::new( - usb_allocator, - UsbVidPid(config.usb_config.vid, config.usb_config.pid), - ) - .manufacturer(config.usb_config.manufacturer) - .product(config.usb_config.product) - .serial_number(config.usb_config.serial_number) - .max_power(500) - // .composite_with_iads() // Only used when the usb device is a composite device, like HID + MSC - .supports_remote_wakeup(true) - .build(), - } +impl> KeyboardUsbDevice<'static, D> { + pub fn new(driver: D) -> Self { + // Create embassy-usb Config + let mut usb_config = embassy_usb::Config::new(0xc0de, 0xcafe); + usb_config.manufacturer = Some("rmk"); + usb_config.product = Some("demo keyboard"); + usb_config.serial_number = Some("00000001"); + + // Create embassy-usb DeviceBuilder using the driver and config. + static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); + 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(); + + // UsbDevice builder + let mut builder = Builder::new( + driver, + usb_config, + &mut DEVICE_DESC.init([0; 256])[..], + &mut CONFIG_DESC.init([0; 256])[..], + &mut BOS_DESC.init([0; 256])[..], + &mut MSOS_DESC.init([0; 128])[..], + &mut CONTROL_BUF.init([0; 128])[..], + ); + + static device_handler: StaticCell = StaticCell::new(); + builder.handler(device_handler.init(MyDeviceHandler::new())); + + // Create classes on the builder. + static request_handler: MyRequestHandler = MyRequestHandler {}; + + // Initialize two hid interfaces: keyboard & via + let keyboard_hid_config = Config { + report_descriptor: KeyboardReport::desc(), + request_handler: Some(&request_handler), + poll_ms: 60, + max_packet_size: 64, + }; + static KEYBOARD_HID_STATE: StaticCell = StaticCell::new(); + let keyboard_hid: HidReaderWriter<'_, D, 1, 8> = HidReaderWriter::new( + &mut builder, + KEYBOARD_HID_STATE.init(State::new()), + keyboard_hid_config, + ); + + let other_hid_config = Config { + report_descriptor: MediaKeyboardReport::desc(), + request_handler: Some(&request_handler), + poll_ms: 60, + max_packet_size: 64, + }; + static OTHER_HID_STATE: StaticCell = StaticCell::new(); + let other_hid: HidReaderWriter<'_, D, 1, 8> = HidReaderWriter::new( + &mut builder, + OTHER_HID_STATE.init(State::new()), + other_hid_config, + ); + + let via_config = Config { + report_descriptor: ViaReport::desc(), + request_handler: Some(&request_handler), + poll_ms: 60, + max_packet_size: 64, + }; + static VIA_STATE: StaticCell = StaticCell::new(); + let via_hid: HidReaderWriter<'_, D, 32, 32> = + HidReaderWriter::new(&mut builder, VIA_STATE.init(State::new()), via_config); + + // Build usb device + let usb = builder.build(); + return Self { + device: usb, + keyboard_hid, + other_hid, + via_hid, + }; } +} - /// Usb polling - pub fn usb_poll(&mut self) { - self.usb_device.poll(&mut [ - &mut self.hid, - &mut self.consumer_control_hid, - &mut self.system_control_hid, - &mut self.via_hid, - ]); +struct MyRequestHandler {} + +impl RequestHandler for MyRequestHandler { + fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option { + info!("Get report for {:?}", id); + None } - /// Read via report, returns the length of the report, 0 if no report is available. - pub fn read_via_report(&mut self, report: &mut ViaReport) -> usize { - // Use output_data: host to device data - match self.via_hid.pull_raw_output(&mut report.output_data) { - Ok(l) => l, - Err(UsbError::WouldBlock) => 0, - Err(e) => { - error!("Read via report error: {:?}", e); - 0 - } - } + fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { + info!("Set report for {:?}: {:?}", id, data); + OutResponse::Accepted } - pub fn send_via_report(&self, report: &ViaReport) -> usize { - // Use output_data: host to device data - match self.via_hid.push_input(report) { - Ok(l) => l, - Err(UsbError::WouldBlock) => 0, - Err(e) => { - error!("Send via report error: {:?}", e); - 0 - } + fn set_idle_ms(&self, id: Option, dur: u32) { + info!("Set idle rate for {:?} to {:?}", id, dur); + } + + fn get_idle_ms(&self, id: Option) -> Option { + info!("Get idle rate for {:?}", id); + None + } +} + +struct MyDeviceHandler { + configured: AtomicBool, +} + +impl MyDeviceHandler { + fn new() -> Self { + MyDeviceHandler { + configured: AtomicBool::new(false), } } +} - /// Send keyboard hid report - pub fn send_keyboard_report(&self, report: &KeyboardReport) { - match self.hid.push_input(report) { - Ok(_) => (), - Err(UsbError::WouldBlock) => (), - Err(e) => error!("Send keyboard report error: {:?}", e), +impl Handler for MyDeviceHandler { + fn enabled(&mut self, enabled: bool) { + self.configured.store(false, Ordering::Relaxed); + SUSPENDED.store(false, Ordering::Release); + if enabled { + info!("Device enabled"); + } else { + info!("Device disabled"); } } - /// Send consumer control report, commonly used in keyboard media control - pub fn send_consumer_control_report(&self, report: &MediaKeyboardReport) { - match self.consumer_control_hid.push_input(report) { - Ok(_) => (), - Err(UsbError::WouldBlock) => (), - Err(e) => error!("Send consumer control report error: {:?}", e), + fn reset(&mut self) { + self.configured.store(false, Ordering::Relaxed); + info!("Bus reset, the Vbus current limit is 100mA"); + } + + fn addressed(&mut self, addr: u8) { + self.configured.store(false, Ordering::Relaxed); + info!("USB address set to: {}", addr); + } + + fn configured(&mut self, configured: bool) { + self.configured.store(configured, Ordering::Relaxed); + if configured { + info!( + "Device configured, it may now draw up to the configured current limit from Vbus." + ) + } else { + info!("Device is no longer configured, the Vbus current limit is 100mA."); } } - /// Send system control report - pub fn send_system_control_report(&self, report: &SystemControlReport) { - match self.system_control_hid.push_input(report) { - Ok(_) => (), - Err(UsbError::WouldBlock) => (), - Err(e) => error!("Send system control report error: {:?}", e), + fn suspended(&mut self, suspended: bool) { + if suspended { + info!("Device suspended, the Vbus current limit is 500µA (or 2.5mA for high-power devices with remote wakeup enabled)."); + SUSPENDED.store(true, Ordering::Release); + } else { + SUSPENDED.store(false, Ordering::Release); + if self.configured.load(Ordering::Relaxed) { + info!( + "Device resumed, it may now draw up to the configured current limit from Vbus" + ); + } else { + info!("Device resumed, the Vbus current limit is 100mA"); + } } } } diff --git a/rmk/src/usb/descriptor.rs b/rmk/src/usb/descriptor.rs new file mode 100644 index 000000000..0cbe5f770 --- /dev/null +++ b/rmk/src/usb/descriptor.rs @@ -0,0 +1,59 @@ +use usbd_hid::descriptor::generator_prelude::*; + +#[gen_hid_descriptor( + (collection = APPLICATION, usage_page = 0xFF60, usage = 0x61) = { + (usage = 0x62, logical_min = 0x0) = { + #[item_settings data,variable,absolute] input_data=input; + }; + (usage = 0x63, logical_min = 0x0) = { + #[item_settings data,variable,absolute] output_data=output; + }; + } +)] +pub struct ViaReport { + pub input_data: [u8; 32], + pub output_data: [u8; 32], +} + +// TODO: Composite hid report +// KeyboardReport describes a report and its companion descriptor that can be +// used to send keyboard button presses to a host and receive the status of the +// keyboard LEDs. +// #[gen_hid_descriptor( +// (report_id = 0x01, collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = KEYBOARD) = { +// (usage_page = KEYBOARD, usage_min = 0xE0, usage_max = 0xE7) = { +// #[packed_bits 8] #[item_settings data,variable,absolute] modifier=input; +// }; +// (usage_min = 0x00, usage_max = 0xFF) = { +// #[item_settings constant,variable,absolute] reserved=input; +// }; +// (usage_page = LEDS, usage_min = 0x01, usage_max = 0x05) = { +// #[packed_bits 5] #[item_settings data,variable,absolute] leds=output; +// }; +// (usage_page = KEYBOARD, usage_min = 0x00, usage_max = 0xDD) = { +// #[item_settings data,array,absolute] keycodes=input; +// }; +// }, +// (report_id = 0x02, collection = APPLICATION, usage_page = CONSUMER, usage = CONSUMER_CONTROL) = { +// (usage_page = CONSUMER, usage_min = 0x00, usage_max = 0x514) = { +// #[item_settings data,array,absolute,not_null] usage_id=input; +// }; +// }, +// (report_id = 0x03, collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = SYSTEM_CONTROL) = { +// (usage_min = 0x81, usage_max = 0xB7, logical_min = 1) = { +// #[item_settings data,array,absolute,not_null] usage_id=input; +// }; +// } +// )] +// #[allow(dead_code)] +// pub struct MyKeyboardReport { +// pub modifier: u8, +// pub reserved: u8, +// pub leds: u8, +// pub keycodes: [u8; 6], +// pub usage_id: u16, +// } + +// impl AsInputReport for MyKeyboardReport { + +// } \ No newline at end of file diff --git a/rmk/src/usb_backup.rs b/rmk/src/usb_backup.rs new file mode 100644 index 000000000..0df16f589 --- /dev/null +++ b/rmk/src/usb_backup.rs @@ -0,0 +1,148 @@ +// DEPRECIATED +// use log::error; +// use usb_device::{ +// class_prelude::{UsbBus, UsbBusAllocator}, +// prelude::{UsbDevice, UsbDeviceBuilder, UsbVidPid}, +// UsbError, +// }; +// use usbd_hid::{ +// descriptor::{KeyboardReport, MediaKeyboardReport, SerializedDescriptor, SystemControlReport}, +// hid_class::{ +// HIDClass, HidClassSettings, HidCountryCode, HidProtocol, HidSubClass, ProtocolModeConfig, +// }, +// }; + +// use crate::{config::KeyboardConfig, via::descriptor::ViaReport}; + +// // TODO: Use a composite hid device for Keyboard + Mouse + System control + Consumer control +// // In this case, report id should be used. +// // The keyboard usb device should have 3 hid instances: +// // 1. Boot keyboard: 1 endpoint in +// // 2. Composite keyboard: Keyboard + Mouse + System control + Consumer control: 1 endpoint in +// // 3. Raw hid communication: used to communicate with via: 2 endpoints(in/out) +// pub struct KeyboardUsbDevice<'a, B: UsbBus> { +// /// Usb hid instance +// hid: HIDClass<'a, B>, +// /// Consumer control hid instance +// consumer_control_hid: HIDClass<'a, B>, +// /// System control hid instance +// system_control_hid: HIDClass<'a, B>, +// /// Via communication instance +// via_hid: HIDClass<'a, B>, +// /// Usb device instance +// usb_device: UsbDevice<'a, B>, +// } + +// impl<'a, B: UsbBus> KeyboardUsbDevice<'a, B> { +// pub fn new(usb_allocator: &'a UsbBusAllocator, config: &KeyboardConfig<'a>) -> Self { +// KeyboardUsbDevice { +// hid: HIDClass::new_ep_in_with_settings( +// usb_allocator, +// KeyboardReport::desc(), +// 10, +// HidClassSettings { +// subclass: HidSubClass::Boot, +// protocol: HidProtocol::Keyboard, +// config: ProtocolModeConfig::ForceBoot, +// locale: HidCountryCode::NotSupported, +// }, +// ), +// consumer_control_hid: HIDClass::new_ep_in_with_settings( +// usb_allocator, +// MediaKeyboardReport::desc(), +// 10, +// HidClassSettings { +// subclass: HidSubClass::NoSubClass, +// protocol: HidProtocol::Keyboard, +// config: ProtocolModeConfig::DefaultBehavior, +// locale: HidCountryCode::NotSupported, +// }, +// ), +// system_control_hid: HIDClass::new_ep_in_with_settings( +// usb_allocator, +// SystemControlReport::desc(), +// 10, +// HidClassSettings { +// subclass: HidSubClass::NoSubClass, +// protocol: HidProtocol::Keyboard, +// config: ProtocolModeConfig::DefaultBehavior, +// locale: HidCountryCode::NotSupported, +// }, +// ), +// via_hid: HIDClass::new(usb_allocator, ViaReport::desc(), 10), +// usb_device: UsbDeviceBuilder::new( +// usb_allocator, +// UsbVidPid(config.usb_config.vid, config.usb_config.pid), +// ) +// .manufacturer(config.usb_config.manufacturer) +// .product(config.usb_config.product) +// .serial_number(config.usb_config.serial_number) +// .max_power(500) +// // .composite_with_iads() // Only used when the usb device is a composite device, like HID + MSC +// .supports_remote_wakeup(true) +// .build(), +// } +// } + +// /// Usb polling +// pub fn usb_poll(&mut self) { +// self.usb_device.poll(&mut [ +// &mut self.hid, +// &mut self.consumer_control_hid, +// &mut self.system_control_hid, +// &mut self.via_hid, +// ]); +// } + +// /// Read via report, returns the length of the report, 0 if no report is available. +// pub fn read_via_report(&mut self, report: &mut ViaReport) -> usize { +// // Use output_data: host to device data +// match self.via_hid.pull_raw_output(&mut report.output_data) { +// Ok(l) => l, +// Err(UsbError::WouldBlock) => 0, +// Err(e) => { +// error!("Read via report error: {:?}", e); +// 0 +// } +// } +// } + +// pub fn send_via_report(&self, report: &ViaReport) -> usize { +// // Use output_data: host to device data +// match self.via_hid.push_input(report) { +// Ok(l) => l, +// Err(UsbError::WouldBlock) => 0, +// Err(e) => { +// error!("Send via report error: {:?}", e); +// 0 +// } +// } +// } + +// /// Send keyboard hid report +// pub fn send_keyboard_report(&self, report: &KeyboardReport) { +// match self.hid.push_input(report) { +// Ok(_) => (), +// Err(UsbError::WouldBlock) => (), +// Err(e) => error!("Send keyboard report error: {:?}", e), +// } +// } + +// /// Send consumer control report, commonly used in keyboard media control +// pub fn send_consumer_control_report(&self, report: &MediaKeyboardReport) { +// match self.consumer_control_hid.push_input(report) { +// Ok(_) => (), +// Err(UsbError::WouldBlock) => (), +// Err(e) => error!("Send consumer control report error: {:?}", e), +// } +// } + +// /// Send system control report +// pub fn send_system_control_report(&self, report: &SystemControlReport) { +// match self.system_control_hid.push_input(report) { +// Ok(_) => (), +// Err(UsbError::WouldBlock) => (), +// Err(e) => error!("Send system control report error: {:?}", e), +// } +// } +// } diff --git a/rmk/src/via.rs b/rmk/src/via.rs index 03d0960e4..f2b4e4f8d 100644 --- a/rmk/src/via.rs +++ b/rmk/src/via.rs @@ -1,7 +1,4 @@ -use log::error; - -pub(crate) mod descriptor; pub(crate) mod keycode_convert; -pub(crate) mod process; +pub mod process; mod protocol; mod vial; \ No newline at end of file diff --git a/rmk/src/via/descriptor.rs b/rmk/src/via/descriptor.rs deleted file mode 100644 index 865b76508..000000000 --- a/rmk/src/via/descriptor.rs +++ /dev/null @@ -1,16 +0,0 @@ -use usbd_hid::descriptor::generator_prelude::*; - -#[gen_hid_descriptor( - (collection = APPLICATION, usage_page = 0xFF60, usage = 0x61) = { - (usage = 0x62, logical_min = 0x0) = { - #[item_settings data,variable,absolute] input_data=input; - }; - (usage = 0x63, logical_min = 0x0) = { - #[item_settings data,variable,absolute] output_data=output; - }; - } -)] -pub struct ViaReport { - pub input_data: [u8; 32], - pub output_data: [u8; 32], -} diff --git a/rmk/src/via/process.rs b/rmk/src/via/process.rs index 17b561d4f..e4ec3cb72 100644 --- a/rmk/src/via/process.rs +++ b/rmk/src/via/process.rs @@ -1,14 +1,76 @@ -use super::{descriptor::*, protocol::*, *}; +use core::cell::RefCell; + +use super::{protocol::*, vial::process_vial}; use crate::{ - eeprom::Eeprom, keymap::KeyMap, + usb::descriptor::ViaReport, via::keycode_convert::{from_via_keycode, to_via_keycode}, }; use byteorder::{BigEndian, ByteOrder, LittleEndian}; +use embassy_time::Instant; +use embassy_usb::{ + class::hid::{HidReaderWriter, ReadError}, + driver::Driver, +}; use embedded_storage::nor_flash::NorFlash; -use log::{debug, info, warn}; +use log::{debug, error, info, warn}; use num_enum::{FromPrimitive, TryFromPrimitive}; -use rtic_monotonics::{systick::Systick, Monotonic}; + +pub struct VialService< + 'a, + F: NorFlash, + const EEPROM_SIZE: usize, + const ROW: usize, + const COL: usize, + const NUM_LAYER: usize, +> { + // VialService holds a reference of keymap, for updating + pub keymap: &'a RefCell>, +} + +impl< + 'a, + F: NorFlash, + const EEPROM_SIZE: usize, + const ROW: usize, + const COL: usize, + const NUM_LAYER: usize, + > VialService<'a, F, EEPROM_SIZE, ROW, COL, NUM_LAYER> +{ + pub fn new(keymap: &'a RefCell>) -> Self { + Self { keymap } + } + + pub async fn process_via_report>( + &self, + hid_interface: &mut HidReaderWriter<'a, D, 32, 32>, + ) { + let mut via_report = ViaReport { + input_data: [0; 32], + output_data: [0; 32], + }; + match hid_interface.read(&mut via_report.output_data).await { + Ok(_) => { + { + process_via_packet(&mut via_report, &mut self.keymap.borrow_mut()); + } + + // Send via report back after processing + match hid_interface.write_serialize(&mut via_report).await { + Ok(_) => {} + Err(e) => { + error!("Send via report error: {:?}", e); + } + } + } + Err(e) => { + if e != ReadError::Disabled { + error!("Read via report error: {:?}", e); + } + } + } + } +} pub fn process_via_packet< F: NorFlash, @@ -18,8 +80,7 @@ pub fn process_via_packet< const NUM_LAYER: usize, >( report: &mut ViaReport, - keymap: &mut KeyMap, - eeprom: &mut Option>, + keymap: &mut KeyMap, ) { let command_id = report.output_data[0]; @@ -36,7 +97,7 @@ pub fn process_via_packet< match ViaKeyboardInfo::try_from_primitive(report.output_data[1]) { Ok(v) => match v { ViaKeyboardInfo::Uptime => { - let value = Systick::now().ticks(); + let value = Instant::now().as_ticks() as u32; BigEndian::write_u32(&mut report.input_data[2..6], value); } ViaKeyboardInfo::LayoutOptions => { @@ -60,7 +121,7 @@ pub fn process_via_packet< Ok(v) => match v { ViaKeyboardInfo::LayoutOptions => { let layout_option = BigEndian::read_u32(&report.output_data[2..6]); - match eeprom { + match &mut keymap.eeprom { Some(e) => e.set_layout_option(layout_option), None => (), } @@ -97,7 +158,7 @@ pub fn process_via_packet< keycode, row, col, layer, action ); keymap.set_action_at(row, col, layer, action.clone()); - match eeprom { + match &mut keymap.eeprom { Some(e) => e.set_keymap_action(row, col, layer, action), None => (), } @@ -198,7 +259,7 @@ pub fn process_via_packet< "Setting keymap buffer of offset: {}, row,col,layer: {},{},{}", offset, row, col, layer ); - match eeprom { + match &mut keymap.eeprom { Some(e) => e.set_keymap_action(row, col, layer, action), None => (), } @@ -210,7 +271,7 @@ pub fn process_via_packet< ViaCommand::DynamicKeymapSetEncoder => { warn!("Keymap get encoder -- not supported"); } - ViaCommand::Vial => vial::process_vial(report), + ViaCommand::Vial => process_vial(report), ViaCommand::Unhandled => report.input_data[0] = ViaCommand::Unhandled as u8, } } diff --git a/rmk/src/via/vial.rs b/rmk/src/via/vial.rs index 91df6b797..eb3804403 100644 --- a/rmk/src/via/vial.rs +++ b/rmk/src/via/vial.rs @@ -2,7 +2,7 @@ use byteorder::{ByteOrder, LittleEndian}; use log::debug; use num_enum::FromPrimitive; -use super::descriptor::ViaReport; +use crate::usb::descriptor::ViaReport; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, FromPrimitive)] #[repr(u8)]