From 834df8bb78fe15c1a91b974ab01e8ebcd88f8d06 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu <sam@rfc1149.net> Date: Thu, 25 Jan 2024 17:11:51 +0100 Subject: [PATCH] Migrate from RTIC to Embassy --- .cargo/config.toml | 17 -- Cargo.lock | 504 ++++++++++++++++++++++++++++++--------------- Cargo.toml | 10 +- memory.x | 4 - src/encoders.rs | 72 +++---- src/main.rs | 252 ++++++++++------------- src/tb6612fng.rs | 107 +++++----- 7 files changed, 537 insertions(+), 429 deletions(-) delete mode 100644 memory.x diff --git a/.cargo/config.toml b/.cargo/config.toml index 4fb4ef8..6c3c3f8 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,25 +1,8 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] runner = "probe-rs run --chip stm32f103c8" rustflags = [ - # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x - # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 "-C", "link-arg=--nmagic", - - # LLD (shipped with the Rust toolchain) is used as the default linker "-C", "link-arg=-Tlink.x", - - # if you run into problems with LLD switch to the GNU linker by commenting out - # this line - # "-C", "linker=arm-none-eabi-ld", - - # if you need to link to pre-compiled C libraries provided by a C toolchain - # use GCC as the linker by commenting out both lines above and then - # uncommenting the three lines below - # "-C", "linker=arm-none-eabi-gcc", - # "-C", "link-arg=-Wl,-Tlink.x", - # "-C", "link-arg=-nostartfiles", - - # defmt "-C", "link-arg=-Tdefmt.x", ] diff --git a/Cargo.lock b/Cargo.lock index bd630dc..23b0532 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,13 +3,10 @@ version = 3 [[package]] -name = "atomic-polyfill" -version = "1.0.3" +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" -dependencies = [ - "critical-section", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bare-metal" @@ -21,10 +18,10 @@ dependencies = [ ] [[package]] -name = "bare-metal" -version = "1.0.0" +name = "bit_field" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" [[package]] name = "bitfield" @@ -45,6 +42,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" dependencies = [ "bitflags", + "defmt", "embedded-hal 0.2.7", "nb 1.1.0", "vcell", @@ -68,7 +66,7 @@ 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", @@ -101,6 +99,41 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +[[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 = "dc-motor-driver-hat" version = "0.1.0" @@ -109,12 +142,10 @@ dependencies = [ "cortex-m-rt", "defmt", "defmt-rtt", - "embedded-hal 0.2.7", + "embassy-executor", + "embassy-stm32", + "embassy-time", "panic-probe", - "rtic", - "rtic-monotonics", - "rtic-sync", - "stm32f1xx-hal", ] [[package]] @@ -160,12 +191,170 @@ dependencies = [ ] [[package]] -name = "embedded-dma" -version = "0.2.0" +name = "document-features" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" dependencies = [ - "stable_deref_trait", + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.4.1" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +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#fb22b46ebb40c16e35c651c0dacf810126856927" + +[[package]] +name = "embassy-hal-internal" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +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#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "bit_field", + "bxcan", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "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#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embassy-time" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +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#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy#fb22b46ebb40c16e35c651c0dacf810126856927" +dependencies = [ + "defmt", ] [[package]] @@ -185,28 +374,86 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" [[package]] -name = "equivalent" -version = "1.0.1" +name = "embedded-hal-async" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] [[package]] -name = "fugit" -version = "0.3.7" +name = "embedded-hal-nb" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" dependencies = [ - "gcd", + "embedded-hal 1.0.0", + "nb 1.1.0", ] [[package]] -name = "fugit-timer" -version = "0.1.3" +name = "embedded-io" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9607bfc4c388f9d629704f56ede4a007546cad417b3bcd6fc7c87dc7edce04a" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" dependencies = [ - "fugit", - "nb 1.1.0", + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", ] [[package]] @@ -215,6 +462,29 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.30" @@ -228,17 +498,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", ] -[[package]] -name = "gcd" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" - [[package]] name = "hash32" version = "0.3.1" @@ -248,12 +514,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - [[package]] name = "heapless" version = "0.8.0" @@ -265,14 +525,16 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "2.1.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "nb" @@ -289,6 +551,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + [[package]] name = "panic-probe" version = "0.3.1" @@ -311,12 +582,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "portable-atomic" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -360,83 +625,10 @@ dependencies = [ ] [[package]] -name = "rtic" -version = "2.0.1" +name = "rand_core" +version = "0.6.4" 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" -dependencies = [ - "critical-section", -] - -[[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.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058c2397dbd5bb4c5650a0e368c3920953e458805ff5097a0511b8147b3619d7" -dependencies = [ - "atomic-polyfill", - "cfg-if", - "cortex-m", - "embedded-hal 1.0.0", - "fugit", - "rtic-time", -] - -[[package]] -name = "rtic-sync" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a243123bcfb0bbbbf27b89c13de35670875a8725ec69763062e8a5903e69e93" -dependencies = [ - "critical-section", - "heapless", - "portable-atomic", - "rtic-common", -] - -[[package]] -name = "rtic-time" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b232e7aebc045cfea81cdd164bc2727a10aca9a4568d406d0a5661cdfd0f19" -dependencies = [ - "critical-section", - "futures-util", - "rtic-common", -] +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "rustc_version" @@ -447,6 +639,12 @@ dependencies = [ "semver", ] +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + [[package]] name = "semver" version = "0.9.0" @@ -469,47 +667,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "stm32-usbd" -version = "0.6.0" +name = "stm32-fmc" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c94998f166d66b210a164648a0b7866428d8f1e0740bf8a4c5edd89d4750c1" +checksum = "830ed60f33e6194ecb377f5d6ab765dc0e37e7b65e765f1fa87df13336658d63" dependencies = [ - "cortex-m", - "usb-device", - "vcell", + "embedded-hal 0.2.7", ] [[package]] -name = "stm32f1" -version = "0.15.1" +name = "stm32-metapac" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dc80735831c28fe85384e1e28428fb6d201f67c696e369a239ed9c5eba369d" +checksum = "deabea56a8821dcea05d0109f3ab3135f31eb572444e5da203d06149c594c8c6" dependencies = [ - "bare-metal 1.0.0", "cortex-m", "cortex-m-rt", - "vcell", ] [[package]] -name = "stm32f1xx-hal" +name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30845662b9ce46a2ec04da97666a2b32458bee5032bb0452d0caf1536a96a542" -dependencies = [ - "bitflags", - "bxcan", - "cortex-m", - "cortex-m-rt", - "embedded-dma", - "embedded-hal 0.2.7", - "fugit", - "fugit-timer", - "nb 1.1.0", - "stm32-usbd", - "stm32f1", - "void", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" @@ -559,12 +739,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "usb-device" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" - [[package]] name = "vcell" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index 3f40ff7..478c8b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,16 +5,14 @@ authors = ["Samuel Tardieu <sam@rfc1149.net>"] edition = "2021" [dependencies] -cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } +cortex-m = { version = "0.7.7", features = ["critical-section-single-core", "inline-asm"] } cortex-m-rt = "0.7.3" defmt = "0.3.5" defmt-rtt = "0.4.0" -embedded-hal = "0.2.7" +embassy-executor = { git = "https://github.com/embassy-rs/embassy", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-stm32 = { git = "https://github.com/embassy-rs/embassy", features = ["defmt", "stm32f103c8", "unstable-pac", "time-driver-tim4", "memory-x"] } +embassy-time = { git = "https://github.com/embassy-rs/embassy", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } panic-probe = { version = "0.3.1", features = ["print-defmt"] } -rtic = { version = "2.0.1", features = ["thumbv7-backend"] } -rtic-monotonics = { version = "1.5.0", features = ["cortex-m-systick"] } -rtic-sync = "1.2.0" -stm32f1xx-hal = { version = "0.10.0", features = ["stm32f103"] } [profile.release] codegen-units = 1 diff --git a/memory.x b/memory.x deleted file mode 100644 index 576fbde..0000000 --- a/memory.x +++ /dev/null @@ -1,4 +0,0 @@ -MEMORY { - FLASH : ORIGIN = 0x08000000, LENGTH = 64M - RAM : ORIGIN = 0x20000000, LENGTH = 20k -} diff --git a/src/encoders.rs b/src/encoders.rs index 289903a..8e6742a 100644 --- a/src/encoders.rs +++ b/src/encoders.rs @@ -1,64 +1,60 @@ -use cortex_m::prelude::_embedded_hal_Qei; -pub use embedded_hal::Direction; -use stm32f1xx_hal::{ - afio::MAPR, - gpio::{PA0, PA1, PA6, PA7}, - pac::{TIM2, TIM3}, - qei::{Qei, QeiOptions}, - rcc::Clocks, - timer::{Tim2NoRemap, Tim3NoRemap, Timer}, +use embassy_stm32::{ + peripherals::{PA0, PA1, PA6, PA7, TIM2, TIM3}, + timer::{ + low_level::GeneralPurpose16bitInstance, + qei::{Direction, Qei, QeiPin}, + }, }; -pub struct Encoders { - left: Qei<TIM3, Tim3NoRemap, (PA6, PA7)>, - right: Qei<TIM2, Tim2NoRemap, (PA0, PA1)>, +pub struct Encoders<'a> { + left: Qei<'a, TIM3>, + right: Qei<'a, TIM2>, count_left: u16, count_right: u16, } -#[derive(Debug)] pub struct EncoderValue { count: u16, direction: Direction, } -impl Encoders { - pub fn new( - pa0: PA0, - pa1: PA1, - pa6: PA6, - pa7: PA7, - tim2: TIM2, - tim3: TIM3, - mapr: &mut MAPR, - clocks: &Clocks, - ) -> Self { - let options = QeiOptions::default(); - let qei = Self { - left: Timer::new(tim3, clocks).qei((pa6, pa7), mapr, options), - right: Timer::new(tim2, clocks).qei((pa0, pa1), mapr, options), +impl core::fmt::Debug for EncoderValue { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!( + f, + "{} ({})", + self.count, + if matches!(self.direction, Direction::Upcounting) { + "upcounting" + } else { + "downcounting" + } + ) + } +} + +impl Encoders<'_> { + pub fn new(pa0: PA0, pa1: PA1, pa6: PA6, pa7: PA7, tim2: TIM2, tim3: TIM3) -> Self { + let left = Qei::new(tim3, QeiPin::new_ch1(pa6), QeiPin::new_ch2(pa7)); + let right = Qei::new(tim2, QeiPin::new_ch1(pa0), QeiPin::new_ch2(pa1)); + TIM2::regs_gp16().ccer().modify(|w| w.set_ccp(1, true)); + Self { + left, + right, count_left: 0, count_right: 0, - }; - // Unsafe needed, see <https://github.com/stm32-rs/stm32f1xx-hal/issues/478> - unsafe { - stm32f1xx_hal::pac::Peripherals::steal() - .TIM2 - .ccer - .modify(|_, w| w.cc2p().set_bit()); } - qei } pub fn read(&self) -> (EncoderValue, EncoderValue) { ( EncoderValue { count: self.left.count(), - direction: self.left.direction(), + direction: self.left.read_direction(), }, EncoderValue { count: self.right.count(), - direction: self.right.direction(), + direction: self.right.read_direction(), }, ) } diff --git a/src/main.rs b/src/main.rs index 17d9c18..6218331 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,156 +1,124 @@ #![no_std] #![no_main] -#![feature(type_alias_impl_trait)] + +use crate::{ + encoders::Encoders, + tb6612fng::{Movement, Tb6612fng}, +}; +use defmt_rtt as _; +use embassy_executor::Spawner; +use embassy_stm32::{ + bind_interrupts, + dma::NoDma, + gpio::{Level, Output, Speed}, + peripherals::{PB15, USART2}, + time::{khz, mhz}, + usart::{self, Uart}, + Config, +}; +use embassy_time::Timer; +use panic_probe as _; mod encoders; mod tb6612fng; -#[rtic::app(device = pac, dispatchers = [])] -mod app { - use crate::encoders::Encoders; - use crate::tb6612fng::{Movement, Tb6612fng}; - use defmt_rtt as _; - use panic_probe as _; - use rtic_monotonics::systick::Systick; - use stm32f1xx_hal::{ - gpio::{Output, PinState, PB15}, - pac, - prelude::*, - serial::{self, Serial}, - }; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local) { - defmt::info!("Program starting"); - - let cp = cx.core; - let dp = cx.device; - - // Configure sysclk at 72MhZ, from HSI - let rcc = dp.RCC.constrain(); - let mut flash = dp.FLASH.constrain(); - let clocks = rcc - .cfgr - .use_hse(8.MHz()) - .sysclk(72.MHz()) - .freeze(&mut flash.acr); - - let systick_token = rtic_monotonics::create_systick_token!(); - Systick::start(cp.SYST, 72_000_000, systick_token); - - let mut gpioa = dp.GPIOA.split(); - let mut gpiob = dp.GPIOB.split(); - let mut afio = dp.AFIO.constrain(); - - let led = gpiob - .pb15 - .into_push_pull_output_with_state(&mut gpiob.crh, PinState::High); - blink::spawn(led).ok().unwrap(); - - let motors = Tb6612fng::new( - gpioa.pa4, - gpioa.pa5, - gpioa.pa10, - gpioa.pa11, - gpiob.pb5, - gpiob.pb6, - gpiob.pb8, - &mut gpioa.crl, - &mut gpioa.crh, - &mut gpiob.crl, - &mut gpiob.crh, - &mut afio.mapr, - dp.TIM1, - &clocks, - 100.kHz(), - ); - calibrate_motors::spawn(motors).ok().unwrap(); - - let tx = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl); - let rx = gpioa.pa3; - let mut serial = Serial::new( - dp.USART2, - (tx, rx), - &mut afio.mapr, - serial::Config::default().baudrate(115200.bps()), - &clocks, - ); - serial.tx.bwrite_all(b"Hello, world\r\n").unwrap(); - - let encoders = Encoders::new( - gpioa.pa0, - gpioa.pa1, - gpioa.pa6, - gpioa.pa7, - dp.TIM2, - dp.TIM3, - &mut afio.mapr, - &clocks, - ); - debug_encoders::spawn(encoders).ok().unwrap(); - - (Shared {}, Local {}) - } +bind_interrupts!(struct Irqs { + USART2 => usart::InterruptHandler<USART2>; +}); + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let mut config = Config::default(); + config.rcc.hse = Some(mhz(8)); + config.rcc.sys_ck = Some(mhz(72)); + let p = embassy_stm32::init(config); + + defmt::info!("Program starting"); + + spawner.spawn(blink(p.PB15)).unwrap(); + + let motors = Tb6612fng::new( + p.PA4, + p.PA5, + p.PA10, + p.PA11, + p.PB5, + p.PB6, + p.PB8, + p.TIM1, + khz(100), + ); + spawner.spawn(calibrate_motors(motors)).unwrap(); + + let mut serial = Uart::new( + p.USART2, + p.PA3, + p.PA2, + Irqs, + p.DMA1_CH7, + NoDma, + Default::default(), + ) + .unwrap(); + serial.write(b"Hello, world\r\n").await.unwrap(); + + let encoders = Encoders::new(p.PA0, p.PA1, p.PA6, p.PA7, p.TIM2, p.TIM3); + spawner.spawn(debug_encoders(encoders)).unwrap(); +} - #[task] - async fn blink(_cx: blink::Context, mut led: PB15<Output>) { - loop { - for _ in 0..6 { - led.toggle(); - Systick::delay(200.millis()).await; - } - Systick::delay(1.secs()).await; +#[embassy_executor::task] +async fn blink(pin: PB15) { + let mut led = Output::new(pin, Level::High, Speed::Low); + loop { + for _ in 0..6 { + led.toggle(); + Timer::after_millis(200).await; } + Timer::after_secs(1).await; } +} - #[task] - async fn calibrate_motors(_cx: calibrate_motors::Context, mut motors: Tb6612fng) { - let max = motors.max_pwm(); - defmt::info!("Will start motors in 1 second – max duty cycle is {}", max); - Systick::delay(1.secs()).await; - motors.move_both(Movement::Stop, Movement::Stop); - motors.standby_leave(); - let speed = (max / 2) as i32; - let (forward, backward) = (Movement::Advance(speed), Movement::Advance(-speed)); - defmt::info!("Left motor, forward 10%"); - motors.move_both(forward, Movement::Stop); - Systick::delay(1.secs()).await; - defmt::info!("Left motor, backward 10%"); - motors.move_both(backward, Movement::Stop); - Systick::delay(1.secs()).await; - defmt::info!("Right motor, forward 10%"); - motors.move_both(Movement::Stop, forward); - Systick::delay(1.secs()).await; - defmt::info!("Right motor, backward 10%"); - motors.move_both(Movement::Stop, backward); - Systick::delay(1.secs()).await; - for i in 0..100 { - let val = max as i32 * i as i32 / 100; - motors.move_both(Movement::Advance(val), Movement::Advance(val)); - Systick::delay(30.millis()).await; - } - motors.move_both(Movement::Brake, Movement::Brake); - defmt::info!("Returning to standby mode"); - motors.standby_enter(); +#[embassy_executor::task] +async fn calibrate_motors(mut motors: Tb6612fng<'static>) { + let max = motors.max_pwm(); + defmt::info!("Will start motors in 1 second – max duty cycle is {}", max); + Timer::after_secs(1).await; + motors.move_both(Movement::Stop, Movement::Stop); + motors.standby_leave(); + let speed = max / 2; + let (forward, backward) = (Movement::Advance(speed), Movement::Advance(-speed)); + defmt::info!("Left motor, forward 10%"); + motors.move_both(forward, Movement::Stop); + Timer::after_secs(1).await; + defmt::info!("Left motor, backward 10%"); + motors.move_both(backward, Movement::Stop); + Timer::after_secs(1).await; + defmt::info!("Right motor, forward 10%"); + motors.move_both(Movement::Stop, forward); + Timer::after_secs(1).await; + defmt::info!("Right motor, backward 10%"); + motors.move_both(Movement::Stop, backward); + Timer::after_secs(1).await; + for i in 0..100 { + let val = max * i / 100; + motors.move_both(Movement::Advance(val), Movement::Advance(val)); + Timer::after_millis(30).await; } + motors.move_both(Movement::Brake, Movement::Brake); + defmt::info!("Returning to standby mode"); + motors.standby_enter(); +} - #[task] - async fn debug_encoders(_cx: debug_encoders::Context, mut encoders: Encoders) { - loop { - let (left, right) = encoders.read(); - defmt::info!( - "left = {:?}, right = {:?}", - defmt::Debug2Format(&left), - defmt::Debug2Format(&right) - ); - defmt::info!("ticks = {:?}", encoders.ticks()); - Systick::delay(100.millis()).await; - } +#[embassy_executor::task] +async fn debug_encoders(mut encoders: Encoders<'static>) { + loop { + let (left, right) = encoders.read(); + defmt::info!( + "left = {:?}, right = {:?}", + defmt::Debug2Format(&left), + defmt::Debug2Format(&right) + ); + defmt::info!("ticks = {:?}", encoders.ticks()); + Timer::after_millis(100).await; } } diff --git a/src/tb6612fng.rs b/src/tb6612fng.rs index ff637ec..1661e5e 100644 --- a/src/tb6612fng.rs +++ b/src/tb6612fng.rs @@ -1,27 +1,22 @@ use core::ops::Neg; -use rtic_monotonics::systick::fugit::Hertz; -use stm32f1xx_hal::{ - afio::MAPR, - gpio::{Alternate, Cr, Output, Pin, PinState, PA10, PA11, PA4, PA5, PB5, PB6, PB8}, - pac::TIM1, - prelude::*, - rcc::Clocks, - timer::{Ch, Channel, PwmHz, Tim1NoRemap}, +use embassy_stm32::{ + gpio::{Level, Output, OutputType, Speed}, + peripherals::{PA10, PA11, PA4, PA5, PB5, PB6, PB8, TIM1}, + time::Hertz, + timer::{ + simple_pwm::{PwmPin, SimplePwm}, + Channel, + }, }; -pub struct Tb6612fng { - pwm: PwmHz< - TIM1, - Tim1NoRemap, - (Ch<2>, Ch<3>), - (Pin<'A', 10, Alternate>, Pin<'A', 11, Alternate>), - >, - a1: PA4<Output>, - a2: PA5<Output>, - b1: PB5<Output>, - b2: PB6<Output>, - standby: PB8<Output>, +pub struct Tb6612fng<'a> { + pwm: SimplePwm<'a, TIM1>, + a1: Output<'a>, + a2: Output<'a>, + b1: Output<'a>, + b2: Output<'a>, + standby: Output<'a>, } #[derive(Clone, Copy)] @@ -43,7 +38,8 @@ impl Neg for Movement { } } -impl Tb6612fng { +impl Tb6612fng<'_> { + #[allow(clippy::too_many_arguments)] pub fn new( pa4: PA4, pa5: PA5, @@ -52,27 +48,28 @@ impl Tb6612fng { pb5: PB5, pb6: PB6, pb8: PB8, - gpioa_crl: &mut Cr<'A', false>, - gpioa_crh: &mut Cr<'A', true>, - gpiob_crl: &mut Cr<'B', false>, - gpiob_crh: &mut Cr<'B', true>, - mapr: &mut MAPR, tim1: TIM1, - clocks: &Clocks, - freq: Hertz<u32>, + freq: Hertz, ) -> Self { - let standby = pb8.into_push_pull_output_with_state(gpiob_crh, PinState::Low); - let a1 = pa4.into_push_pull_output_with_state(gpioa_crl, PinState::Low); - let a2 = pa5.into_push_pull_output_with_state(gpioa_crl, PinState::Low); - let b1 = pb5.into_push_pull_output_with_state(gpiob_crl, PinState::Low); - let b2 = pb6.into_push_pull_output_with_state(gpiob_crl, PinState::Low); - let ch3 = pa10.into_alternate_push_pull(gpioa_crh); - let ch4 = pa11.into_alternate_push_pull(gpioa_crh); - let pins = (ch3, ch4); - let mut pwm = tim1.pwm_hz(pins, mapr, freq, clocks); - pwm.enable(Channel::C3); - pwm.enable(Channel::C4); - Tb6612fng { + let standby = Output::new(pb8, Level::Low, Speed::Low); + let a1 = Output::new(pa4, Level::Low, Speed::Low); + let a2 = Output::new(pa5, Level::Low, Speed::Low); + let b1 = Output::new(pb5, Level::Low, Speed::Low); + let b2 = Output::new(pb6, Level::Low, Speed::Low); + let ch3 = PwmPin::new_ch3(pa10, OutputType::PushPull); + let ch4 = PwmPin::new_ch4(pa11, OutputType::PushPull); + let mut pwm = SimplePwm::new( + tim1, + None, + None, + Some(ch3), + Some(ch4), + freq, + Default::default(), + ); + pwm.enable(Channel::Ch3); + pwm.enable(Channel::Ch4); + Self { pwm, a1, a2, @@ -96,17 +93,17 @@ impl Tb6612fng { } pub fn move_right(&mut self, value: Movement) { - let (i1, i2, duty) = self.into_command(value); - self.a1.set_state(i1); - self.a2.set_state(i2); - self.pwm.set_duty(Channel::C3, duty); + let (i1, i2, duty) = self.make_command(value); + self.a1.set_level(i1); + self.a2.set_level(i2); + self.pwm.set_duty(Channel::Ch3, duty); } pub fn move_left(&mut self, value: Movement) { - let (i1, i2, duty) = self.into_command(-value); - self.b1.set_state(i1); - self.b2.set_state(i2); - self.pwm.set_duty(Channel::C4, duty); + let (i1, i2, duty) = self.make_command(-value); + self.b1.set_level(i1); + self.b2.set_level(i2); + self.pwm.set_duty(Channel::Ch4, duty); } pub fn move_both(&mut self, left: Movement, right: Movement) { @@ -114,17 +111,13 @@ impl Tb6612fng { self.move_right(right); } - fn into_command(&self, movement: Movement) -> (PinState, PinState, u16) { + fn make_command(&self, movement: Movement) -> (Level, Level, u16) { let max_duty = self.max_pwm(); match movement { - Movement::Brake | Movement::Advance(0) => { - (PinState::High, PinState::High, max_duty as u16) - } - Movement::Stop => (PinState::Low, PinState::Low, 0), - Movement::Advance(v) if v > 0 => { - (PinState::High, PinState::Low, v.min(max_duty) as u16) - } - Movement::Advance(v) => (PinState::Low, PinState::High, (-v).min(max_duty) as u16), + Movement::Brake | Movement::Advance(0) => (Level::High, Level::High, max_duty as u16), + Movement::Stop => (Level::Low, Level::Low, 0), + Movement::Advance(v) if v > 0 => (Level::High, Level::Low, v.min(max_duty) as u16), + Movement::Advance(v) => (Level::Low, Level::High, (-v).min(max_duty) as u16), } } } -- GitLab