From f2fda10c7a34bbc2ea1f037adcfd851bdcb1132c Mon Sep 17 00:00:00 2001 From: Priec Date: Wed, 5 Nov 2025 21:03:30 +0100 Subject: [PATCH] Tx only does not work --- dma_gpio2/.cargo/config.toml | 15 + dma_gpio2/.gitignore | 1 + dma_gpio2/Cargo.lock | 1422 +++++++++++++++++ dma_gpio2/Cargo.toml | 29 + dma_gpio2/LICENSE-APACHE | 201 +++ dma_gpio2/LICENSE-MIT | 23 + dma_gpio2/Makefile | 23 + dma_gpio2/README.md | 232 +++ dma_gpio2/src/bin/main.rs | 102 ++ dma_gpio2/src/config.rs | 16 + dma_gpio2/src/lib.rs | 4 + dma_gpio2/src/software_uart/debug.rs | 43 + dma_gpio2/src/software_uart/dma_timer.rs | 49 + .../src/software_uart/gpio_dma_uart_tx.rs | 27 + dma_gpio2/src/software_uart/mod.rs | 11 + dma_gpio2/src/software_uart/uart_emulation.rs | 151 ++ dma_gpio2/tests/integration.rs | 16 + 17 files changed, 2365 insertions(+) create mode 100644 dma_gpio2/.cargo/config.toml create mode 100644 dma_gpio2/.gitignore create mode 100644 dma_gpio2/Cargo.lock create mode 100644 dma_gpio2/Cargo.toml create mode 100644 dma_gpio2/LICENSE-APACHE create mode 100644 dma_gpio2/LICENSE-MIT create mode 100644 dma_gpio2/Makefile create mode 100644 dma_gpio2/README.md create mode 100644 dma_gpio2/src/bin/main.rs create mode 100644 dma_gpio2/src/config.rs create mode 100644 dma_gpio2/src/lib.rs create mode 100644 dma_gpio2/src/software_uart/debug.rs create mode 100644 dma_gpio2/src/software_uart/dma_timer.rs create mode 100644 dma_gpio2/src/software_uart/gpio_dma_uart_tx.rs create mode 100644 dma_gpio2/src/software_uart/mod.rs create mode 100644 dma_gpio2/src/software_uart/uart_emulation.rs create mode 100644 dma_gpio2/tests/integration.rs diff --git a/dma_gpio2/.cargo/config.toml b/dma_gpio2/.cargo/config.toml new file mode 100644 index 0000000..ac6a5dc --- /dev/null +++ b/dma_gpio2/.cargo/config.toml @@ -0,0 +1,15 @@ +[build] +target = "thumbv8m.main-none-eabihf" + +[target.thumbv8m.main-none-eabihf] +runner = "probe-rs run --chip STM32U575ZITxQ" + +rustflags = [ + "-C", "linker=rust-lld", + "-C", "link-arg=-Tlink.x", + "-C", "link-arg=-Tdefmt.x", + "-C", "link-arg=--nmagic", +] + +[package.metadata.cargo-flash] +chip = "STM32U575ZIT" diff --git a/dma_gpio2/.gitignore b/dma_gpio2/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/dma_gpio2/.gitignore @@ -0,0 +1 @@ +/target diff --git a/dma_gpio2/Cargo.lock b/dma_gpio2/Cargo.lock new file mode 100644 index 0000000..2cf9391 --- /dev/null +++ b/dma_gpio2/Cargo.lock @@ -0,0 +1,1422 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "block-device-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c051592f59fe68053524b4c4935249b806f72c1f544cfb7abe4f57c3be258e" +dependencies = [ + "aligned", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.107", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "defmt" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e" +dependencies = [ + "critical-section", + "defmt 1.0.1", +] + +[[package]] +name = "dma_gpio" +version = "0.1.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "defmt-rtt", + "embassy-executor", + "embassy-futures", + "embassy-hal-internal", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-graphics", + "embedded-hal 1.0.0", + "heapless 0.9.1", + "micromath", + "panic-halt", + "panic-probe", + "static_cell", + "tinybmp", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "defmt 1.0.1", + "embassy-futures", + "embassy-hal-internal", + "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.9.1" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "cordyceps", + "cortex-m", + "critical-section", + "document-features", + "embassy-executor-macros", + "embassy-executor-timer-queue", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.7.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" + +[[package]] +name = "embassy-futures" +version = "0.1.2" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" + +[[package]] +name = "embassy-hal-internal" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.0.1", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.2" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-stm32" +version = "0.4.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "aligned", + "bit_field", + "bitflags 2.10.0", + "block-device-driver", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.0.1", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embassy-usb-synopsys-otg", + "embedded-can", + "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-util", + "heapless 0.9.1", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core 0.6.4", + "rand_core 0.9.3", + "sdio-host", + "static_assertions", + "stm32-fmc", + "stm32-metapac", + "vcell", + "volatile-register", +] + +[[package]] +name = "embassy-sync" +version = "0.7.2" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.0.1", + "embedded-io-async", + "futures-core", + "futures-sink", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.0.1", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.1" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "embassy-executor-timer-queue", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-usb" +version = "0.5.1" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-usb-driver", + "embedded-io-async", + "heapless 0.8.0", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "defmt 1.0.1", + "embedded-io-async", +] + +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.3.1" +source = "git+https://github.com/embassy-rs/embassy.git?branch=main#9b1add3d83e98c6c9ae9230bf35cd89bba530a20" +dependencies = [ + "critical-section", + "defmt 1.0.1", + "embassy-sync", + "embassy-usb-driver", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-graphics" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" +dependencies = [ + "az", + "byteorder", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-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" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt 0.3.100", + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "generator" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1edcd5a338e64688fbdcb7531a846cfd3476a54784dcb918a0844682bc7ada5" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "micromath" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "panic-halt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11" + +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt 1.0.1", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "sdio-host" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b328e2cb950eeccd55b7f55c3a963691455dcd044cfb5354f0c5e68d2c2d6ee2" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "stm32-fmc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "18.0.0" +source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-b9f6b0c542d85ee695d71c35ced195e0cef51ac0#9b8fb67703361e2237b6c1ec4f1ee5949223d412" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 0.3.100", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tinybmp" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df43af2cb7b369009aa14144959bb4f2720ab62034c9073242f2d3a186c2edb6" +dependencies = [ + "embedded-graphics", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f291ab53d428685cc780f08a2eb9d5d6ff58622db2b36e239a4f715f1e184c" +dependencies = [ + "serde", + "ssmarshal", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee54712c5d778d2fb2da43b1ce5a7b5060886ef7b09891baeb4bf36910a3ed" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb573c76e7884035ac5e1ab4a81234c187a82b6100140af0ab45757650ccda38" +dependencies = [ + "byteorder", + "hashbrown", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core", + "windows-link 0.1.3", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.107", +] diff --git a/dma_gpio2/Cargo.toml b/dma_gpio2/Cargo.toml new file mode 100644 index 0000000..a13e99c --- /dev/null +++ b/dma_gpio2/Cargo.toml @@ -0,0 +1,29 @@ +[package] +authors = ["Priec "] +name = "dma_gpio" +edition = "2024" +version = "0.1.0" + + +[dependencies] +cortex-m = { version = "0.7.7", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.5" +panic-halt = "1.0.0" + +embassy-executor = { git = "https://github.com/embassy-rs/embassy.git", branch = "main", features = ["arch-cortex-m", "executor-thread"] } +embassy-futures = { git = "https://github.com/embassy-rs/embassy.git", branch = "main" } +embassy-sync = { git = "https://github.com/embassy-rs/embassy.git", branch = "main" } +embassy-time = { git = "https://github.com/embassy-rs/embassy.git", branch = "main", features = ["tick-hz-32_768"] } +embassy-hal-internal = { git = "https://github.com/embassy-rs/embassy.git", branch = "main" } +embassy-usb = { git = "https://github.com/embassy-rs/embassy.git", branch = "main" } +embassy-stm32 = { git = "https://github.com/embassy-rs/embassy.git", branch = "main", features = ["unstable-pac", "stm32u575zi", "time-driver-tim2", "memory-x", "defmt"] } + +embedded-hal = "1.0.0" +embedded-graphics = "0.8.1" +heapless = { version = "0.9.1", default-features = false } +micromath = "2.1.0" +tinybmp = "0.6.0" +panic-probe = { version = "1.0.0", features = ["defmt"] } +defmt-rtt = "1.1.0" +defmt = "1.0.1" +static_cell = "2.1.1" diff --git a/dma_gpio2/LICENSE-APACHE b/dma_gpio2/LICENSE-APACHE new file mode 100644 index 0000000..11069ed --- /dev/null +++ b/dma_gpio2/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/dma_gpio2/LICENSE-MIT b/dma_gpio2/LICENSE-MIT new file mode 100644 index 0000000..468cd79 --- /dev/null +++ b/dma_gpio2/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/dma_gpio2/Makefile b/dma_gpio2/Makefile new file mode 100644 index 0000000..dfa5ac1 --- /dev/null +++ b/dma_gpio2/Makefile @@ -0,0 +1,23 @@ +TARGET = thumbv8m.main-none-eabihf +CHIP = STM32U575ZI +BIN = stm32u5-blinky +MODE ?= release +TARGET_DIR = target/$(TARGET)/$(MODE) +ELF = $(TARGET_DIR)/$(BIN) +PROBE = probe-rs + +.PHONY: all build flash clean empty + +all: build + +build: + cargo build --$(MODE) + +flash: build + $(PROBE) run --chip $(CHIP) $(ELF) + +empty: + $(PROBE) erase --chip $(CHIP) + +clean: + cargo clean diff --git a/dma_gpio2/README.md b/dma_gpio2/README.md new file mode 100644 index 0000000..05d63c4 --- /dev/null +++ b/dma_gpio2/README.md @@ -0,0 +1,232 @@ +# `app-template` + +> Quickly set up a [`probe-rs`] + [`defmt`] + [`flip-link`] embedded project + +[`probe-rs`]: https://crates.io/crates/probe-rs +[`defmt`]: https://github.com/knurling-rs/defmt +[`flip-link`]: https://github.com/knurling-rs/flip-link + +## Dependencies + +### 1. `flip-link`: + +```bash +cargo install flip-link +``` + +### 2. `probe-rs`: + +Install probe-rs by following the instructions at . + +### 3. [`cargo-generate`]: + +```bash +cargo install cargo-generate +``` + +[`cargo-generate`]: https://crates.io/crates/cargo-generate + +> *Note:* You can also just clone this repository instead of using `cargo-generate`, but this involves additional manual adjustments. + +## Setup + +### 1. Initialize the project template + +```bash +cargo generate \ + --git https://github.com/knurling-rs/app-template \ + --branch main \ + --name my-app +``` + +If you look into your new `my-app` folder, you'll find that there are a few `TODO`s in the files marking the properties you need to set. + +Let's walk through them together now. + +### 2. Set `probe-rs` chip + +Pick a chip from ` probe-rs chip list` and enter it into `.cargo/config.toml`. + +If, for example, you have a nRF52840 Development Kit as used in one of [our exercises], replace `{{chip}}` with `nRF52840_xxAA`. + +[our workshops]: https://rust-exercises.ferrous-systems.com + +```diff + # .cargo/config.toml +-runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format=oneline"] ++runner = ["probe-rs", "run", "--chip", "nRF52840_xxAA", "--log-format=oneline"] +``` + +### 3. Adjust the compilation target + +In `.cargo/config.toml`, pick the right compilation target for your board. + +```diff + # .cargo/config.toml + [build] +-target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +-# target = "thumbv7m-none-eabi" # Cortex-M3 +-# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +-# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) ++target = "thumbv7em-none-eabihf" # Cortex-M4F (with FPU) +``` + +Add the target with `rustup`. + +```bash +rustup target add thumbv7em-none-eabihf +``` + +### 4. Add a HAL as a dependency + +In `Cargo.toml`, list the Hardware Abstraction Layer (HAL) for your board as a dependency. + +For the nRF52840 you'll want to use the [`nrf52840-hal`]. + +[`nrf52840-hal`]: https://crates.io/crates/nrf52840-hal + +```diff + # Cargo.toml + [dependencies] +-# some-hal = "1.2.3" ++nrf52840-hal = "0.14.0" +``` + +⚠️ Note for RP2040 users ⚠️ + +You will need to not just specify the `rp-hal` HAL, but a BSP (board support crate) which includes a second stage bootloader. Please find a list of available BSPs [here](https://github.com/rp-rs/rp-hal-boards#packages). + +### 5. Import your HAL + +Now that you have selected a HAL, fix the HAL import in `src/lib.rs` + +```diff + // my-app/src/lib.rs +-// use some_hal as _; // memory layout ++use nrf52840_hal as _; // memory layout +``` + +### (6. Get a linker script) + +Some HAL crates require that you manually copy over a file called `memory.x` from the HAL to the root of your project. For nrf52840-hal, this is done automatically so no action is needed. For other HAL crates, see their documentation on where to find an example file. + +The `memory.x` file should look something like: + +```text +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 1024K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} +``` + +The `memory.x` file is included in the `cortex-m-rt` linker script `link.x`, and so `link.x` is the one you should tell `rustc` to use (see the `.cargo/config.toml` file where we do that). + +### 7. Run! + +You are now all set to `cargo-run` your first `defmt`-powered application! +There are some examples in the `src/bin` directory. + +Start by `cargo run`-ning `my-app/src/bin/hello.rs`: + +```console +$ # `rb` is an alias for `run --bin` +$ cargo rb hello + Finished `dev` profile [optimized + debuginfo] target(s) in 0.01s + Running `probe-rs run --chip nrf52840_xxaa --log-format=oneline target/thumbv6m-none-eabi/debug/hello` + Erasing ✔ 100% [####################] 8.00 KiB @ 15.79 KiB/s (took 1s) + Programming ✔ 100% [####################] 8.00 KiB @ 13.19 KiB/s (took 1s) Finished in 1.11s +Hello, world! + +$ echo $? +0 +``` + +If you're running out of memory (`flip-link` bails with an overflow error), you can decrease the size of the device memory buffer by setting the `DEFMT_RTT_BUFFER_SIZE` environment variable. The default value is 1024 bytes, and powers of two should be used for optimal performance: + +```console +$ DEFMT_RTT_BUFFER_SIZE=64 cargo rb hello +``` + +### (8. Set `rust-analyzer.linkedProjects`) + +If you are using [rust-analyzer] with VS Code for IDE-like features you can add following configuration to your `.vscode/settings.json` to make it work transparently across workspaces. Find the details of this option in the [RA docs]. + +```json +{ + "rust-analyzer.linkedProjects": [ + "Cargo.toml", + "firmware/Cargo.toml", + ] +} +``` + +[RA docs]: https://rust-analyzer.github.io/manual.html#configuration +[rust-analyzer]: https://rust-analyzer.github.io/ + +## Running tests + +The template comes configured for running unit tests and integration tests on the target. + +Unit tests reside in the library crate and can test private API; the initial set of unit tests are in `src/lib.rs`. +`cargo test --lib` will run those unit tests. + +```console +$ cargo test --lib + Compiling example v0.1.0 (./knurling-rs/example) + Finished `test` profile [optimized + debuginfo] target(s) in 0.15s + Running unittests src/lib.rs (target/thumbv6m-none-eabi/debug/deps/example-2b0d0e25d141bf57) + Erasing ✔ 100% [####################] 8.00 KiB @ 15.99 KiB/s (took 1s) + Programming ✔ 100% [####################] 8.00 KiB @ 13.33 KiB/s (took 1s) Finished in 1.10s +(1/1) running `it_works`... +all tests passed! +``` + +Integration tests reside in the `tests` directory; the initial set of integration tests are in `tests/integration.rs`. +`cargo test --test integration` will run those integration tests. +Note that the argument of the `--test` flag must match the name of the test file in the `tests` directory. + +```console +$ cargo test --test integration + Compiling example v0.1.0 (./knurling-rs/example) + Finished `test` profile [optimized + debuginfo] target(s) in 0.10s + Running tests/integration.rs (target/thumbv6m-none-eabi/debug/deps/integration-aaaff41151f6a722) + Erasing ✔ 100% [####################] 8.00 KiB @ 16.03 KiB/s (took 0s) + Programming ✔ 100% [####################] 8.00 KiB @ 13.19 KiB/s (took 1s) Finished in 1.11s +(1/1) running `it_works`... +all tests passed! +``` + +Note that to add a new test file to the `tests` directory you also need to add a new `[[test]]` section to `Cargo.toml`. + +To run all the tests via `cargo test` the tests need to be explicitly disabled for all the existing binary targets. +See `Cargo.toml` for details on how to do this. + +## Support + +`app-template` is part of the [Knurling] project, [Ferrous Systems]' effort at +improving tooling used to develop for embedded systems. + +If you think that our work is useful, consider sponsoring it via [GitHub +Sponsors]. + +## License + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +licensed as above, without any additional terms or conditions. + +[Knurling]: https://knurling.ferrous-systems.com +[Ferrous Systems]: https://ferrous-systems.com/ +[GitHub Sponsors]: https://github.com/sponsors/knurling-rs diff --git a/dma_gpio2/src/bin/main.rs b/dma_gpio2/src/bin/main.rs new file mode 100644 index 0000000..34b5c41 --- /dev/null +++ b/dma_gpio2/src/bin/main.rs @@ -0,0 +1,102 @@ +// src/bin/main.rs +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_futures::yield_now; +use embassy_stm32::dma::Request; +use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed}; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; +use embassy_time::{Duration, Timer}; +use embassy_stm32::dma::{TransferOptions, WritableRingBuffer}; +use dma_gpio::software_uart::{ + dma_timer::init_tim6_for_uart, + gpio_dma_uart_tx::encode_uart_frames, + debug::dump_tim6_regs, +}; +use dma_gpio::config::{BAUD, TX_PIN_BIT, RX_OVERSAMPLE, TX_OVERSAMPLE}; +use dma_gpio::config::{TX_RING_BYTES, RX_RING_BYTES, PIPE_RX_SIZE}; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +// kapitola 17.4.11 - 2 casovace pre 2 DMA +pub const TIM6_UP_REQ: Request = 4; // Table 137: tim6_upd_dma, strana 687 STM32U5xx datasheet + +static TX_RING: StaticCell<[u32; TX_RING_BYTES]> = StaticCell::new(); + +use core::future::poll_fn; +use core::task::Poll; + +async fn wait_for_space<'a, W: embassy_stm32::dma::word::Word>( + ring: &mut embassy_stm32::dma::WritableRingBuffer<'a, W>, + min_free: usize, +) { + poll_fn(|cx| { + let used = ring.len().unwrap_or(0); + let cap = ring.capacity(); + if cap - used > min_free { + Poll::Ready(()) + } else { + ring.set_waker(cx.waker()); + Poll::Pending + } + }).await +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hehe"); + + let _rx = Input::new(p.PA3, Pull::Up); + let _tx = Output::new(p.PA2, Level::High, Speed::VeryHigh); + + init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE); + dump_tim6_regs(); + + // Safe one-time init from StaticCell + let tx_ring_mem: &mut [u32; TX_RING_BYTES] = TX_RING.init([0; TX_RING_BYTES]); + + // Create and start the TX DMA ring in main. + // let bsrr_ptr = embassy_stm32::pac::GPIOA.bsrr().as_ptr() as *mut u32; + let odr_ptr = embassy_stm32::pac::GPIOA.odr().as_ptr() as *mut u32; + let mut tx_opts = TransferOptions::default(); + tx_opts.half_transfer_ir = true; + tx_opts.complete_transfer_ir = true; + + // SAFETY: tx_ring_mem is exclusive + let mut tx_ring = unsafe { + WritableRingBuffer::new( + p.GPDMA1_CH0, + TIM6_UP_REQ, + odr_ptr, + tx_ring_mem, + tx_opts, + ) + }; + // Start DMA + tx_ring.start(); + info!("TX DMA ring started"); + + let mut frame_buf = [0u32; 4096]; + + loop { + info!("tick start"); + Timer::after(Duration::from_millis(400)).await; + info!("tick end"); + + let used = encode_uart_frames(TX_PIN_BIT, b"Hello marshmallow\r\n", &mut frame_buf).await; + + // Wait for DMA to free space, async style + wait_for_space(&mut tx_ring, used / 2).await; + + if let Err(e) = tx_ring.write_exact(&frame_buf[..used]).await { + warn!("DMA ring write error: {:?}", e); + } else { + info!("Frame queued to DMA ring"); + } + + yield_now().await; + } +} diff --git a/dma_gpio2/src/config.rs b/dma_gpio2/src/config.rs new file mode 100644 index 0000000..19b14e6 --- /dev/null +++ b/dma_gpio2/src/config.rs @@ -0,0 +1,16 @@ +// src/config.rs +use crate::software_uart::uart_emulation::{Parity, StopBits, UartConfig}; + +pub const BAUD: u32 = 9_600; +pub const TX_PIN_BIT: u8 = 2; // PA2 +pub const TX_OVERSAMPLE: u16 = 1; +pub const RX_OVERSAMPLE: u16 = 16; +pub const RX_RING_BYTES: usize = 4096; +pub const TX_RING_BYTES: usize = 4096; +pub const PIPE_RX_SIZE: usize = 256; + +pub const UART_CFG: UartConfig = UartConfig { + data_bits: 8, + parity: Parity::None, + stop_bits: StopBits::One, +}; diff --git a/dma_gpio2/src/lib.rs b/dma_gpio2/src/lib.rs new file mode 100644 index 0000000..9123142 --- /dev/null +++ b/dma_gpio2/src/lib.rs @@ -0,0 +1,4 @@ +#![no_std] + +pub mod software_uart; +pub mod config; diff --git a/dma_gpio2/src/software_uart/debug.rs b/dma_gpio2/src/software_uart/debug.rs new file mode 100644 index 0000000..ae6a256 --- /dev/null +++ b/dma_gpio2/src/software_uart/debug.rs @@ -0,0 +1,43 @@ +// src/software_uart/debug.rs +use defmt::info; + +pub fn dump_tim6_regs() { + use embassy_stm32::pac::timer::TimBasic; + let tim = unsafe { TimBasic::from_ptr(0x4000_1000usize as _) }; + let sr = tim.sr().read(); + let dier = tim.dier().read(); + let cr1 = tim.cr1().read(); + let arr = tim.arr().read().arr(); + let psc = tim.psc().read(); + info!( + "TIM6: CR1.CEN={} DIER.UDE={} SR.UIF={} PSC={} ARR={}", + cr1.cen(), + dier.ude(), + sr.uif(), + psc, + arr + ); +} + +pub fn dump_dma_ch0_regs() { + use embassy_stm32::pac::gpdma::Gpdma; + let dma = unsafe { Gpdma::from_ptr(0x4002_0000usize as _) }; + let ch = dma.ch(0); + let cr = ch.cr().read(); + let tr1 = ch.tr1().read(); + let tr2 = ch.tr2().read(); + let br1 = ch.br1().read(); + info!( + "GPDMA1_CH0: EN={} PRIO={} SDW={} DDW={} SINC={} DINC={} REQSEL={} SWREQ={} DREQ={} BNDT={}", + cr.en(), + cr.prio(), + tr1.sdw(), + tr1.ddw(), + tr1.sinc(), + tr1.dinc(), + tr2.reqsel(), + tr2.swreq(), + tr2.dreq(), + br1.bndt() + ); +} diff --git a/dma_gpio2/src/software_uart/dma_timer.rs b/dma_gpio2/src/software_uart/dma_timer.rs new file mode 100644 index 0000000..a04e34d --- /dev/null +++ b/dma_gpio2/src/software_uart/dma_timer.rs @@ -0,0 +1,49 @@ +// src/dma_timer.rs + +use embassy_stm32::{ + peripherals::TIM6, + rcc, + timer::low_level::Timer, + Peri, +}; +use core::mem; +use embassy_stm32::timer::BasicInstance; +use embassy_stm32::pac::timer::vals::Urs; + +/// Initializes TIM6 to tick at `baud * oversample` frequency. +/// Each TIM6 update event triggers one DMA beat. +pub fn init_tim6_for_uart<'d>(tim6: Peri<'d, TIM6>, baud: u32, oversample: u16) { + rcc::enable_and_reset::(); + let ll = Timer::new(tim6); + configure_basic_timer(&ll, baud, oversample); + mem::forget(ll); +} + +// Shared internal helper — identical CR1/ARR setup +fn configure_basic_timer(ll: &Timer<'_, T>, baud: u32, oversample: u16) { + let f_timer = rcc::frequency::().0; + let target = baud.saturating_mul(oversample.max(1) as u32).max(1); + + // Compute ARR (prescaler = 0) + let mut arr = (f_timer / target).saturating_sub(1) as u16; + if arr == 0 { arr = 1; } + + ll.regs_basic().cr1().write(|w| { + w.set_cen(false); + w.set_opm(false); + w.set_udis(false); + w.set_urs(Urs::ANY_EVENT); + }); + + ll.regs_basic().psc().write_value(0u16); + ll.regs_basic().arr().write(|w| w.set_arr(arr)); + ll.regs_basic().dier().modify(|w| w.set_ude(true)); + ll.regs_basic().egr().write(|w| w.set_ug(true)); + + ll.regs_basic().cr1().write(|w| { + w.set_opm(false); + w.set_cen(true); + w.set_udis(false); + w.set_urs(Urs::ANY_EVENT); + }); +} diff --git a/dma_gpio2/src/software_uart/gpio_dma_uart_tx.rs b/dma_gpio2/src/software_uart/gpio_dma_uart_tx.rs new file mode 100644 index 0000000..e317dff --- /dev/null +++ b/dma_gpio2/src/software_uart/gpio_dma_uart_tx.rs @@ -0,0 +1,27 @@ +// src/software_uart/gpio_dma_uart_tx.rs +use embassy_futures::yield_now; +use crate::software_uart::uart_emulation::encode_uart_byte_cfg; +use crate::config::UART_CFG; + +pub async fn encode_uart_frames<'a>( + pin_bit: u8, + bytes: &[u8], + out_buf: &'a mut [u32], +) -> usize { + let mut offset = 0; + for &b in bytes { + let mut frame = [0u32; 12]; + let used = encode_uart_byte_cfg(pin_bit, b, &UART_CFG, &mut frame); + + if offset + used <= out_buf.len() { + out_buf[offset..offset + used].copy_from_slice(&frame[..used]); + offset += used; + } else { + break; + } + + // cooperative async yield + yield_now().await; + } + offset +} diff --git a/dma_gpio2/src/software_uart/mod.rs b/dma_gpio2/src/software_uart/mod.rs new file mode 100644 index 0000000..4fcb25d --- /dev/null +++ b/dma_gpio2/src/software_uart/mod.rs @@ -0,0 +1,11 @@ +// src/software_uart/mod.rs + +pub mod gpio_dma_uart_tx; +pub mod dma_timer; +pub mod uart_emulation; +pub mod debug; + +pub use gpio_dma_uart_tx::*; +pub use dma_timer::*; +pub use uart_emulation::*; +pub use debug::*; diff --git a/dma_gpio2/src/software_uart/uart_emulation.rs b/dma_gpio2/src/software_uart/uart_emulation.rs new file mode 100644 index 0000000..8d677e5 --- /dev/null +++ b/dma_gpio2/src/software_uart/uart_emulation.rs @@ -0,0 +1,151 @@ +// src/software_uart/uart_emulation.rs +use heapless::Vec; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Parity { + None, + Even, + Odd, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum StopBits { + One, + Two, +} + +#[derive(Clone, Copy, Debug)] +pub struct UartConfig { + pub data_bits: u8, + pub parity: Parity, + pub stop_bits: StopBits, +} + +impl Default for UartConfig { + fn default() -> Self { + Self { + data_bits: 8, + parity: Parity::None, + stop_bits: StopBits::One, + } + } +} + +/// Encodes one byte into a sequence of GPIO BSRR words +pub fn encode_uart_byte_cfg( + pin_bit: u8, + data: u8, + cfg: &UartConfig, + out: &mut [u32; 12], +) -> usize { + // GPIOx_BSRR register str. 636 kap. 13.4.7 + let set_high = |bit: u8| -> u32 { 1u32 << bit }; + let set_low = |bit: u8| -> u32 { 0 }; + // let set_low = |bit: u8| -> u32 { 1u32 << (bit as u32 + 16) }; + + let mut idx = 0usize; + + // START bit (LOW) + out[idx] = set_low(pin_bit); + idx += 1; + + // Data bits, LSB-first + let nbits = cfg.data_bits.clamp(5, 8); + for i in 0..nbits { + let one = ((data >> i) & 1) != 0; + out[idx] = if one { set_high(pin_bit) } else { set_low(pin_bit) }; + idx += 1; + } + + // Parity + match cfg.parity { + Parity::None => {} + Parity::Even | Parity::Odd => { + let mask: u8 = if nbits == 8 { 0xFF } else { (1u16 << nbits) as u8 - 1 }; + let ones = (data & mask).count_ones() & 1; + let par_bit_is_one = match cfg.parity { + Parity::Even => ones == 1, + Parity::Odd => ones == 0, + _ => false, + }; + out[idx] = if par_bit_is_one { + set_high(pin_bit) + } else { + set_low(pin_bit) + }; + idx += 1; + } + } + + // STOP bits (HIGH) + let stop_ticks = match cfg.stop_bits { + StopBits::One => 1usize, + StopBits::Two => 2usize, + }; + for _ in 0..stop_ticks { + out[idx] = set_high(pin_bit); + idx += 1; + } + + idx +} + +/// Decode an oversampled stream of logic levels into UART bytes. +pub fn decode_uart_samples( + samples: &[u8], + oversample: u16, + cfg: &UartConfig, +) -> heapless::Vec { + + let mut out = Vec::::new(); + let mut idx = 0usize; + let nbits = cfg.data_bits as usize; + + while idx + (oversample as usize * (nbits + 3)) < samples.len() { + // Wait for start bit (falling edge: high -> low) + if samples[idx] != 0 && samples[idx + 1] == 0 { + // Align to middle of start bit + idx += (oversample / 2) as usize; + + // Sanity check start bit really low + if samples.get(idx).copied().unwrap_or(1) != 0 { + idx += 1; + continue; + } + + // Sample data bits + let mut data: u8 = 0; + for bit in 0..nbits { + idx += oversample as usize; + let bit_val = samples + .get(idx) + .map(|&b| if b != 0 { 1u8 } else { 0u8 }) + .unwrap_or(1); + data |= bit_val << bit; + } + + // Parity: skip / verify + match cfg.parity { + Parity::None => {} + Parity::Even | Parity::Odd => { + idx += oversample as usize; + // You can optionally add parity check here if needed + } + } + + // Move past stop bits + let stop_skip = match cfg.stop_bits { + StopBits::One => oversample as usize, + StopBits::Two => (oversample * 2) as usize, + }; + idx += stop_skip; + + // Push decoded byte + let _ = out.push(data); + } else { + idx += 1; + } + } + + out +} diff --git a/dma_gpio2/tests/integration.rs b/dma_gpio2/tests/integration.rs new file mode 100644 index 0000000..1f33de6 --- /dev/null +++ b/dma_gpio2/tests/integration.rs @@ -0,0 +1,16 @@ +#![no_std] +#![no_main] + +use stm32u5_blinky as _; // memory layout + panic handler + +// See https://crates.io/crates/defmt-test/0.3.0 for more documentation (e.g. about the 'state' +// feature) +#[defmt_test::tests] +mod tests { + use defmt::assert; + + #[test] + fn it_works() { + assert!(true) + } +}