mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
Add Monotonic for i.MX RT chip family
This commit is contained in:
parent
a7f81262f6
commit
2fd3b3c404
13 changed files with 1251 additions and 1 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -156,6 +156,7 @@ jobs:
|
||||||
|
|
||||||
- name: Configure rust target (v6, v7)
|
- name: Configure rust target (v6, v7)
|
||||||
run: |
|
run: |
|
||||||
|
rustup target add thumbv7em-none-eabihf
|
||||||
rustup target add thumbv7m-none-eabi
|
rustup target add thumbv7m-none-eabi
|
||||||
rustup target add thumbv6m-none-eabi
|
rustup target add thumbv6m-none-eabi
|
||||||
rustup component add rust-src
|
rustup component add rust-src
|
||||||
|
|
6
examples/teensy4_blinky/.cargo/config.toml
Normal file
6
examples/teensy4_blinky/.cargo/config.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[target.thumbv7em-none-eabihf]
|
||||||
|
runner = "python3 run.py"
|
||||||
|
rustflags = ["-C", "link-arg=-Tt4link.x"]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
target = "thumbv7em-none-eabihf" # Teensy 4
|
603
examples/teensy4_blinky/Cargo.lock
generated
Normal file
603
examples/teensy4_blinky/Cargo.lock
generated
Normal file
|
@ -0,0 +1,603 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bare-metal"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bare-metal"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bbqueue"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd3baa8859d1a4c7411039a75c0599a4640ef1c9a8fc811e4325b00e6cfe0a55"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitfield"
|
||||||
|
version = "0.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m"
|
||||||
|
version = "0.7.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
|
||||||
|
dependencies = [
|
||||||
|
"bare-metal 0.2.5",
|
||||||
|
"bitfield",
|
||||||
|
"critical-section",
|
||||||
|
"embedded-hal 0.2.7",
|
||||||
|
"volatile-register",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m-rt"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m-rt-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m-rt-macros"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8a2d011b2fee29fb7d659b83c43fce9a2cb4df453e16d441a51448e448f3f98"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"defmt-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt-macros"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54f0216f6c5acb5ae1a47050a6645024e6edafc2ee32d421955eccfef12ef92e"
|
||||||
|
dependencies = [
|
||||||
|
"defmt-parser",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.38",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt-parser"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "269924c02afd7f94bc4cecbfa5c379f6ffcf9766b3408fe63d22c728654eccd0"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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-rc.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2894bc2f0457b8ca3d6b8ab8aad64d9337583672494013457f86c5a9146c0e22"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fugit"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
|
||||||
|
dependencies = [
|
||||||
|
"gcd",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"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 = "hashbrown"
|
||||||
|
version = "0.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-blinky"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-hal 0.2.7",
|
||||||
|
"imxrt-log",
|
||||||
|
"log",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"rtic",
|
||||||
|
"rtic-monotonics",
|
||||||
|
"teensy4-bsp",
|
||||||
|
"teensy4-panic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-boot-gen"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e90bcb04a4619e58f8662d6d993b6318d04416936550cd3d721938d254f5fe19"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-dma"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0be4dc99cfca9c88c3478be3cba16ca3e3b2bde180e1dd69f7d04f470d6412a4"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m",
|
||||||
|
"ral-registers",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-hal"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b48e06b1cd447190708b1e25c3bdc9bb34ef35d5930d39a03d36a3e788fffd81"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"embedded-hal 0.2.7",
|
||||||
|
"fugit",
|
||||||
|
"imxrt-dma",
|
||||||
|
"imxrt-iomuxc",
|
||||||
|
"imxrt-ral",
|
||||||
|
"imxrt-usbd",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-iomuxc"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcc265810697eb1ae9003f2c32da7b389b465a8485a934941a9d72be16713f60"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-log"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa66f5d6331f47afc29af176d337c5556e677549a0dc7aef5692134d81372d69"
|
||||||
|
dependencies = [
|
||||||
|
"bbqueue",
|
||||||
|
"critical-section",
|
||||||
|
"defmt",
|
||||||
|
"imxrt-hal",
|
||||||
|
"imxrt-usbd",
|
||||||
|
"log",
|
||||||
|
"usb-device",
|
||||||
|
"usbd-serial",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-ral"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fb8b67f5867258a62fcbfa51ae0985d7fa2d5ffdb5b9c4f559b0af110300369"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m",
|
||||||
|
"ral-registers",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-rt"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ab95fbf48de9bd0f127ecdae1b482f4250c7c1258ff6dec484c4df92ae293c8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cortex-m-rt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imxrt-usbd"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1212c31e391faaad032fdc248427e0cfb000c59ddeb00b3f95ca16a63942b83"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cortex-m",
|
||||||
|
"ral-registers",
|
||||||
|
"usb-device",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
|
[[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 = "pin-project-lite"
|
||||||
|
version = "0.2.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||||
|
|
||||||
|
[[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.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ral-registers"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46b71a9d9206e8b46714c74255adcaea8b11e0350c1d8456165073c3f75fc81a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtic"
|
||||||
|
version = "2.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"bare-metal 1.0.0",
|
||||||
|
"cortex-m",
|
||||||
|
"critical-section",
|
||||||
|
"rtic-core",
|
||||||
|
"rtic-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtic-common"
|
||||||
|
version = "1.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
"portable-atomic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtic-monotonics"
|
||||||
|
version = "1.2.1"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"cfg-if",
|
||||||
|
"cortex-m",
|
||||||
|
"embedded-hal 1.0.0-rc.1",
|
||||||
|
"fugit",
|
||||||
|
"imxrt-ral",
|
||||||
|
"log",
|
||||||
|
"rtic-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtic-time"
|
||||||
|
version = "1.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
"futures-util",
|
||||||
|
"rtic-common",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "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.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "teensy4-bsp"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a920208238f8ee2d2a4e29fdaf923a4025750a76baab845be96ec1d4ef184be8"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m",
|
||||||
|
"imxrt-hal",
|
||||||
|
"imxrt-log",
|
||||||
|
"imxrt-ral",
|
||||||
|
"imxrt-rt",
|
||||||
|
"teensy4-fcb",
|
||||||
|
"teensy4-pins",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "teensy4-fcb"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8007b6d680b853afd7aa5a4b2be509efac0b5063698a87f274206955afbf1d0f"
|
||||||
|
dependencies = [
|
||||||
|
"imxrt-boot-gen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "teensy4-panic"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c733a579f17557d093df6714a57d61841e9cbaa222384ca7ee1fbb334888c20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "teensy4-pins"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a50cc992551983c0034014d58873af2153921cd22601c2194ae93f763f5ba06"
|
||||||
|
dependencies = [
|
||||||
|
"imxrt-iomuxc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.38",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
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 = "usbd-serial"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db75519b86287f12dcf0d171c7cf4ecc839149fe9f3b720ac4cfce52959e1dfe"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-hal 0.2.7",
|
||||||
|
"nb 0.1.3",
|
||||||
|
"usb-device",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
]
|
52
examples/teensy4_blinky/Cargo.toml
Normal file
52
examples/teensy4_blinky/Cargo.toml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
[package]
|
||||||
|
authors = ["Finomnis <finomnis@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
readme = "README.md"
|
||||||
|
name = "imxrt-blinky"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[dependencies.rtic]
|
||||||
|
path = "../../rtic"
|
||||||
|
version = "2.0.1"
|
||||||
|
features = ["thumbv7-backend"]
|
||||||
|
|
||||||
|
[dependencies.rtic-monotonics]
|
||||||
|
path = "../../rtic-monotonics"
|
||||||
|
version = "1.2.1"
|
||||||
|
features = ["imxrt_gpt1"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
embedded-hal = "0.2.7"
|
||||||
|
teensy4-panic = { version = "0.2.3", default-features = false }
|
||||||
|
|
||||||
|
[dependencies.teensy4-bsp]
|
||||||
|
features = ["rt"]
|
||||||
|
version = "0.4.4"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
nb = "1.1.0" # Async
|
||||||
|
imxrt-log = { version = "0.1.1", default-features = false, features = [
|
||||||
|
"log",
|
||||||
|
"lpuart",
|
||||||
|
] }
|
||||||
|
log = "0.4.20"
|
||||||
|
|
||||||
|
# this lets you use `cargo fix`!
|
||||||
|
[[bin]]
|
||||||
|
name = "imxrt-blinky"
|
||||||
|
test = false
|
||||||
|
bench = false
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
codegen-units = 16
|
||||||
|
debug = true
|
||||||
|
lto = false
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "s" # optimize for size
|
||||||
|
codegen-units = 1 # better optimizations
|
||||||
|
debug = true # symbols are nice and they don't increase the size on Flash
|
||||||
|
lto = true # better optimizations
|
25
examples/teensy4_blinky/README.md
Normal file
25
examples/teensy4_blinky/README.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Teensy4 RTIC Blink example
|
||||||
|
|
||||||
|
Working example of simple LED blinking application for Teensy4. Example uses monotonics API and peripherials access.
|
||||||
|
|
||||||
|
## How-to
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
The following hardware is required for the examples:
|
||||||
|
- A [Teensy 4.0](https://www.pjrc.com/store/teensy40.html)/[Teensy 4.1](https://www.pjrc.com/store/teensy41.html)/[Teensy MicroMod](https://www.sparkfun.com/products/16402) development board
|
||||||
|
|
||||||
|
The following software tools have to be installed:
|
||||||
|
- Python3 (as `python3`, or modify `run.py` to use the `python` binary)
|
||||||
|
- [`cargo-binutils`](https://crates.io/crates/cargo-binutils)
|
||||||
|
- [`teensy_loader_cli`](https://www.pjrc.com/teensy/loader_cli.html)
|
||||||
|
|
||||||
|
|
||||||
|
### Run
|
||||||
|
|
||||||
|
- Connect the Teensy to PC via USB cable.
|
||||||
|
- Press the `Reset`/`Boot` button on the Teensy.
|
||||||
|
- Run:
|
||||||
|
```bash
|
||||||
|
cargo run --release
|
||||||
|
```
|
42
examples/teensy4_blinky/examples/common/mod.rs
Normal file
42
examples/teensy4_blinky/examples/common/mod.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
macro_rules! uart_panic_handler {
|
||||||
|
($uart: ident, $tx_pin: ident, $rx_pin: ident, $baud: expr) => {
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &::core::panic::PanicInfo) -> ! {
|
||||||
|
use ::core::fmt::Write as _;
|
||||||
|
use ::embedded_hal::serial::Write as _;
|
||||||
|
|
||||||
|
let ::teensy4_bsp::board::Resources {
|
||||||
|
$uart: uart, pins, ..
|
||||||
|
} = ::teensy4_bsp::board::t40(unsafe { ::teensy4_bsp::ral::Instances::instances() });
|
||||||
|
|
||||||
|
let uart = ::teensy4_bsp::board::lpuart(uart, pins.$tx_pin, pins.$rx_pin, $baud);
|
||||||
|
|
||||||
|
struct UartWriter<P, const N: u8> {
|
||||||
|
uart: ::teensy4_bsp::hal::lpuart::Lpuart<P, N>,
|
||||||
|
}
|
||||||
|
impl<P, const N: u8> ::core::fmt::Write for UartWriter<P, N> {
|
||||||
|
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
|
||||||
|
for &b in s.as_bytes() {
|
||||||
|
if b == b'\n' {
|
||||||
|
let _ = ::nb::block!(self.uart.write(b'\r'));
|
||||||
|
}
|
||||||
|
let _ = ::nb::block!(self.uart.write(b));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut uart = UartWriter { uart };
|
||||||
|
|
||||||
|
::core::writeln!(uart).ok();
|
||||||
|
::core::writeln!(uart, "{}", info).ok();
|
||||||
|
::core::writeln!(uart).ok();
|
||||||
|
|
||||||
|
let _ = ::nb::block!(uart.uart.flush());
|
||||||
|
|
||||||
|
::teensy4_panic::sos()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use uart_panic_handler;
|
113
examples/teensy4_blinky/examples/with_logs.rs
Normal file
113
examples/teensy4_blinky/examples/with_logs.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#![deny(warnings)]
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
common::uart_panic_handler!(lpuart6, p1, p0, 115200);
|
||||||
|
|
||||||
|
use teensy4_bsp as bsp;
|
||||||
|
|
||||||
|
use bsp::board;
|
||||||
|
use bsp::hal;
|
||||||
|
use bsp::logging;
|
||||||
|
|
||||||
|
use embedded_hal::serial::Write;
|
||||||
|
|
||||||
|
use rtic_monotonics::imxrt::Gpt1 as Mono;
|
||||||
|
use rtic_monotonics::imxrt::*;
|
||||||
|
use rtic_monotonics::Monotonic;
|
||||||
|
|
||||||
|
#[rtic::app(device = teensy4_bsp, dispatchers = [LPSPI1])]
|
||||||
|
mod app {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const LOG_POLL_INTERVAL: u32 = board::PERCLK_FREQUENCY / 100;
|
||||||
|
const LOG_DMA_CHANNEL: usize = 0;
|
||||||
|
|
||||||
|
#[shared]
|
||||||
|
struct Shared {}
|
||||||
|
|
||||||
|
#[local]
|
||||||
|
struct Local {
|
||||||
|
led: board::Led,
|
||||||
|
poll_log: hal::pit::Pit<3>,
|
||||||
|
log_poller: logging::Poller,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init(cx: init::Context) -> (Shared, Local) {
|
||||||
|
let board::Resources {
|
||||||
|
mut dma,
|
||||||
|
pit: (_, _, _, mut poll_log),
|
||||||
|
pins,
|
||||||
|
lpuart6,
|
||||||
|
mut gpio2,
|
||||||
|
mut gpt1,
|
||||||
|
..
|
||||||
|
} = board::t40(cx.device);
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
let log_dma = dma[LOG_DMA_CHANNEL].take().unwrap();
|
||||||
|
let mut log_uart = board::lpuart(lpuart6, pins.p1, pins.p0, 115200);
|
||||||
|
for &ch in "\r\n===== Teensy4 Rtic Blinky =====\r\n\r\n".as_bytes() {
|
||||||
|
nb::block!(log_uart.write(ch)).unwrap();
|
||||||
|
}
|
||||||
|
nb::block!(log_uart.flush()).unwrap();
|
||||||
|
let log_poller =
|
||||||
|
logging::log::lpuart(log_uart, log_dma, logging::Interrupts::Enabled).unwrap();
|
||||||
|
poll_log.set_interrupt_enable(true);
|
||||||
|
poll_log.set_load_timer_value(LOG_POLL_INTERVAL);
|
||||||
|
poll_log.enable();
|
||||||
|
|
||||||
|
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||||
|
gpt1.set_clock_source(hal::gpt::ClockSource::PeripheralClock);
|
||||||
|
let gpt1_mono_token = rtic_monotonics::create_imxrt_gpt1_token!();
|
||||||
|
Mono::start(board::PERCLK_FREQUENCY, gpt1.release(), gpt1_mono_token);
|
||||||
|
|
||||||
|
// Setup LED
|
||||||
|
let led = board::led(&mut gpio2, pins.p13);
|
||||||
|
led.set();
|
||||||
|
|
||||||
|
// Schedule the blinking task
|
||||||
|
blink::spawn().ok();
|
||||||
|
|
||||||
|
(
|
||||||
|
Shared {},
|
||||||
|
Local {
|
||||||
|
log_poller,
|
||||||
|
poll_log,
|
||||||
|
led,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[task(local = [led])]
|
||||||
|
async fn blink(cx: blink::Context) {
|
||||||
|
let blink::LocalResources { led, .. } = cx.local;
|
||||||
|
|
||||||
|
let mut next_update = Mono::now();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
led.toggle();
|
||||||
|
log::info!("Time: {}", Mono::now());
|
||||||
|
next_update += 1000.millis();
|
||||||
|
Mono::delay_until(next_update).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[task(binds = PIT, priority = 1, local = [poll_log, log_poller])]
|
||||||
|
fn logger(cx: logger::Context) {
|
||||||
|
let logger::LocalResources {
|
||||||
|
poll_log,
|
||||||
|
log_poller,
|
||||||
|
..
|
||||||
|
} = cx.local;
|
||||||
|
|
||||||
|
if poll_log.is_elapsed() {
|
||||||
|
poll_log.clear_elapsed();
|
||||||
|
|
||||||
|
log_poller.poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
examples/teensy4_blinky/run.py
Normal file
29
examples/teensy4_blinky/run.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Please provide the binary as first argument!")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
binary = sys.argv[1]
|
||||||
|
print(f"Flashing {binary} ...")
|
||||||
|
|
||||||
|
with TemporaryDirectory() as tmpdir:
|
||||||
|
tmpdir = Path(tmpdir)
|
||||||
|
hexfile = tmpdir / "firmware.hex"
|
||||||
|
|
||||||
|
subprocess.run(["rust-objcopy", "-O", "ihex", binary, hexfile], check=True)
|
||||||
|
subprocess.run(["teensy_loader_cli", "--mcu=imxrt1062", "-wv", hexfile], check=True)
|
||||||
|
|
||||||
|
print("Teensy successfully flashed.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
62
examples/teensy4_blinky/src/main.rs
Normal file
62
examples/teensy4_blinky/src/main.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#![deny(unsafe_code)]
|
||||||
|
#![deny(warnings)]
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_: &::core::panic::PanicInfo) -> ! {
|
||||||
|
::teensy4_panic::sos()
|
||||||
|
}
|
||||||
|
|
||||||
|
use teensy4_bsp::{board, hal};
|
||||||
|
|
||||||
|
use rtic_monotonics::imxrt::Gpt1 as Mono;
|
||||||
|
use rtic_monotonics::imxrt::*;
|
||||||
|
|
||||||
|
#[rtic::app(device = teensy4_bsp, dispatchers = [LPSPI1])]
|
||||||
|
mod app {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[shared]
|
||||||
|
struct Shared {}
|
||||||
|
|
||||||
|
#[local]
|
||||||
|
struct Local {
|
||||||
|
led: board::Led,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init(cx: init::Context) -> (Shared, Local) {
|
||||||
|
let board::Resources {
|
||||||
|
pins,
|
||||||
|
mut gpio2,
|
||||||
|
mut gpt1,
|
||||||
|
..
|
||||||
|
} = board::t40(cx.device);
|
||||||
|
|
||||||
|
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||||
|
gpt1.set_clock_source(hal::gpt::ClockSource::PeripheralClock);
|
||||||
|
let gpt1_mono_token = rtic_monotonics::create_imxrt_gpt1_token!();
|
||||||
|
Mono::start(board::PERCLK_FREQUENCY, gpt1.release(), gpt1_mono_token);
|
||||||
|
|
||||||
|
// Setup LED
|
||||||
|
let led = board::led(&mut gpio2, pins.p13);
|
||||||
|
led.set();
|
||||||
|
|
||||||
|
// Schedule the blinking task
|
||||||
|
blink::spawn().ok();
|
||||||
|
|
||||||
|
(Shared {}, Local { led })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[task(local = [led])]
|
||||||
|
async fn blink(cx: blink::Context) {
|
||||||
|
let blink::LocalResources { led, .. } = cx.local;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
led.toggle();
|
||||||
|
Mono::delay(1000.millis()).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- i.MX RT support
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix STM32 rollover race condition
|
- Fix STM32 rollover race condition
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rtic-monotonics"
|
name = "rtic-monotonics"
|
||||||
version = "1.2.0"
|
version = "1.2.1"
|
||||||
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
|
@ -45,6 +45,9 @@ nrf9160-pac = { version = "0.12.2", optional = true }
|
||||||
# STM32
|
# STM32
|
||||||
stm32-metapac = { version = "14.0.0", optional = true }
|
stm32-metapac = { version = "14.0.0", optional = true }
|
||||||
|
|
||||||
|
# i.MX RT
|
||||||
|
imxrt-ral = { version = "0.5.3", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
proc-macro2 = { version = "1.0.36", optional = true }
|
proc-macro2 = { version = "1.0.36", optional = true }
|
||||||
quote = { version = "1.0.15", optional = true }
|
quote = { version = "1.0.15", optional = true }
|
||||||
|
@ -74,6 +77,12 @@ nrf5340-app = ["dep:cortex-m", "dep:nrf5340-app-pac", "dep:critical-section"]
|
||||||
nrf5340-net = ["dep:cortex-m", "dep:nrf5340-net-pac", "dep:critical-section"]
|
nrf5340-net = ["dep:cortex-m", "dep:nrf5340-net-pac", "dep:critical-section"]
|
||||||
nrf9160 = ["dep:cortex-m", "dep:nrf9160-pac", "dep:critical-section"]
|
nrf9160 = ["dep:cortex-m", "dep:nrf9160-pac", "dep:critical-section"]
|
||||||
|
|
||||||
|
# i.MX RT Timers
|
||||||
|
# Use as `features = ["imxrt_gpt1"]`
|
||||||
|
imxrt = ["dep:cortex-m", "dep:imxrt-ral"]
|
||||||
|
imxrt_gpt1 = ["imxrt"]
|
||||||
|
imxrt_gpt2 = ["imxrt"]
|
||||||
|
|
||||||
# STM32 timers
|
# STM32 timers
|
||||||
# Use as `features = ["stm32g081kb", "stm32_tim15"]`
|
# Use as `features = ["stm32g081kb", "stm32_tim15"]`
|
||||||
stm32_tim2 = []
|
stm32_tim2 = []
|
||||||
|
|
300
rtic-monotonics/src/imxrt.rs
Normal file
300
rtic-monotonics/src/imxrt.rs
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
//! [`Monotonic`] impl for the i.MX RT.
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use rtic_monotonics::imxrt::*;
|
||||||
|
//! use rtic_monotonics::imxrt::Gpt1 as Mono;
|
||||||
|
//!
|
||||||
|
//! fn init() {
|
||||||
|
//! // Obtain ownership of the timer register block
|
||||||
|
//! let gpt1 = unsafe { imxrt_ral::gpt::GPT1::instance() };
|
||||||
|
//!
|
||||||
|
//! // Configure the timer clock source and determine its tick rate
|
||||||
|
//! let timer_tickrate_hz = 1_000_000;
|
||||||
|
//!
|
||||||
|
//! // Generate timer token to ensure correct timer interrupt handler is used
|
||||||
|
//! let token = rtic_monotonics::create_imxrt_gpt1_token!();
|
||||||
|
//!
|
||||||
|
//! // Start the monotonic
|
||||||
|
//! Mono::start(timer_tickrate_hz, gpt1, token);
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! async fn usage() {
|
||||||
|
//! loop {
|
||||||
|
//! // Use the monotonic
|
||||||
|
//! let timestamp = Mono::now().ticks();
|
||||||
|
//! Mono::delay(100.millis()).await;
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use crate::{Monotonic, TimeoutError, TimerQueue};
|
||||||
|
use atomic_polyfill::{compiler_fence, AtomicU32, Ordering};
|
||||||
|
pub use fugit::{self, ExtU64};
|
||||||
|
|
||||||
|
use imxrt_ral as ral;
|
||||||
|
|
||||||
|
const TIMER_HZ: u32 = 1_000_000;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! __internal_create_imxrt_timer_interrupt {
|
||||||
|
($mono_timer:ident, $timer:ident, $timer_token:ident) => {{
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
unsafe extern "C" fn $timer() {
|
||||||
|
$crate::imxrt::$mono_timer::__tq().on_monotonic_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct $timer_token;
|
||||||
|
|
||||||
|
unsafe impl $crate::InterruptToken<$crate::imxrt::$mono_timer> for $timer_token {}
|
||||||
|
|
||||||
|
$timer_token
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register GPT1 interrupt for the monotonic.
|
||||||
|
#[cfg(feature = "imxrt_gpt1")]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! create_imxrt_gpt1_token {
|
||||||
|
() => {{
|
||||||
|
$crate::__internal_create_imxrt_timer_interrupt!(Gpt1, GPT1, Gpt1Token)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register GPT2 interrupt for the monotonic.
|
||||||
|
#[cfg(feature = "imxrt_gpt2")]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! create_imxrt_gpt2_token {
|
||||||
|
() => {{
|
||||||
|
$crate::__internal_create_imxrt_timer_interrupt!(Gpt2, GPT2, Gpt2Token)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Credits to the `time-driver` of `embassy-stm32`.
|
||||||
|
//
|
||||||
|
// Clock timekeeping works with something we call "periods", which are time intervals
|
||||||
|
// of 2^31 ticks. The Clock counter value is 32 bits, so one "overflow cycle" is 2 periods.
|
||||||
|
//
|
||||||
|
// A `period` count is maintained in parallel to the Timer hardware `counter`, like this:
|
||||||
|
// - `period` and `counter` start at 0
|
||||||
|
// - `period` is incremented on overflow (at counter value 0)
|
||||||
|
// - `period` is incremented "midway" between overflows (at counter value 0x8000_0000)
|
||||||
|
//
|
||||||
|
// Therefore, when `period` is even, counter is in 0..0x7FFF_FFFF. When odd, counter is in 0x8000_0000..0xFFFF_FFFF
|
||||||
|
// This allows for now() to return the correct value even if it races an overflow.
|
||||||
|
//
|
||||||
|
// To get `now()`, `period` is read first, then `counter` is read. If the counter value matches
|
||||||
|
// the expected range for the `period` parity, we're done. If it doesn't, this means that
|
||||||
|
// a new period start has raced us between reading `period` and `counter`, so we assume the `counter` value
|
||||||
|
// corresponds to the next period.
|
||||||
|
//
|
||||||
|
// `period` is a 32bit integer, so it overflows on 2^32 * 2^31 / 1_000_000 seconds of uptime, which is 292471 years.
|
||||||
|
fn calc_now(period: u32, counter: u32) -> u64 {
|
||||||
|
(u64::from(period) << 31) + u64::from(counter ^ ((period & 1) << 31))
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! make_timer {
|
||||||
|
($mono_name:ident, $timer:ident, $period:ident, $tq:ident$(, doc: ($($doc:tt)*))?) => {
|
||||||
|
/// Monotonic timer queue implementation.
|
||||||
|
$(
|
||||||
|
#[cfg_attr(docsrs, doc(cfg($($doc)*)))]
|
||||||
|
)?
|
||||||
|
|
||||||
|
pub struct $mono_name;
|
||||||
|
|
||||||
|
use ral::gpt::$timer;
|
||||||
|
|
||||||
|
/// Number of 2^31 periods elapsed since boot.
|
||||||
|
static $period: AtomicU32 = AtomicU32::new(0);
|
||||||
|
static $tq: TimerQueue<$mono_name> = TimerQueue::new();
|
||||||
|
|
||||||
|
impl $mono_name {
|
||||||
|
/// Starts the monotonic timer.
|
||||||
|
/// - `tick_freq_hz`: The tick frequency of the given timer.
|
||||||
|
/// - `gpt`: The GPT timer register block instance.
|
||||||
|
/// - `_interrupt_token`: Required for correct timer interrupt handling.
|
||||||
|
/// This method must be called only once.
|
||||||
|
pub fn start(tick_freq_hz: u32, gpt: $timer, _interrupt_token: impl crate::InterruptToken<Self>) {
|
||||||
|
// Find a prescaler that creates our desired tick frequency
|
||||||
|
let previous_prescaler = ral::read_reg!(ral::gpt, gpt, PR, PRESCALER) + 1;
|
||||||
|
let previous_clock_freq = tick_freq_hz * previous_prescaler;
|
||||||
|
assert!((previous_clock_freq % TIMER_HZ) == 0,
|
||||||
|
"Unable to find a fitting prescaler value!\n Input: {}/{}\n Desired: {}",
|
||||||
|
previous_clock_freq, previous_prescaler, TIMER_HZ);
|
||||||
|
let prescaler = previous_clock_freq / TIMER_HZ;
|
||||||
|
assert!(prescaler > 0);
|
||||||
|
assert!(prescaler <= 4096);
|
||||||
|
|
||||||
|
// Disable the timer.
|
||||||
|
ral::modify_reg!(ral::gpt, gpt, CR, EN: 0);
|
||||||
|
// Clear all status registers.
|
||||||
|
ral::write_reg!(ral::gpt, gpt, SR, 0b11_1111);
|
||||||
|
|
||||||
|
// Base configuration
|
||||||
|
ral::modify_reg!(ral::gpt, gpt, CR,
|
||||||
|
ENMOD: 1, // Clear timer state
|
||||||
|
FRR: 1, // Free-Run mode
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reset period
|
||||||
|
$period.store(0, Ordering::Relaxed);
|
||||||
|
|
||||||
|
// Prescaler
|
||||||
|
ral::modify_reg!(ral::gpt, gpt, PR,
|
||||||
|
PRESCALER: (prescaler - 1), // Scale to our desired clock rate
|
||||||
|
);
|
||||||
|
|
||||||
|
// Enable interrupts
|
||||||
|
ral::write_reg!(ral::gpt, gpt, IR,
|
||||||
|
ROVIE: 1, // Rollover interrupt
|
||||||
|
OF1IE: 1, // Timer compare 1 interrupt (for half-periods)
|
||||||
|
OF2IE: 1, // Timer compare 2 interrupt (for dynamic wakeup)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Configure half-period interrupt
|
||||||
|
ral::write_reg!(ral::gpt, gpt, OCR[0], 0x8000_0000);
|
||||||
|
|
||||||
|
// Dynamic interrupt register; for now initialize to zero
|
||||||
|
// so it gets combined with rollover interrupt
|
||||||
|
ral::write_reg!(ral::gpt, gpt, OCR[1], 0x0000_0000);
|
||||||
|
|
||||||
|
// Enable the timer
|
||||||
|
ral::modify_reg!(ral::gpt, gpt, CR, EN: 1);
|
||||||
|
ral::modify_reg!(ral::gpt, gpt, CR,
|
||||||
|
ENMOD: 0, // Keep state when disabled
|
||||||
|
);
|
||||||
|
|
||||||
|
$tq.initialize(Self {});
|
||||||
|
|
||||||
|
// SAFETY: We take full ownership of the peripheral and interrupt vector,
|
||||||
|
// plus we are not using any external shared resources so we won't impact
|
||||||
|
// basepri/source masking based critical sections.
|
||||||
|
unsafe {
|
||||||
|
crate::set_monotonic_prio(ral::NVIC_PRIO_BITS, ral::Interrupt::$timer);
|
||||||
|
cortex_m::peripheral::NVIC::unmask(ral::Interrupt::$timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to access the underlying timer queue
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn __tq() -> &'static TimerQueue<$mono_name> {
|
||||||
|
&$tq
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delay for some duration of time.
|
||||||
|
#[inline]
|
||||||
|
pub async fn delay(duration: <Self as Monotonic>::Duration) {
|
||||||
|
$tq.delay(duration).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Timeout at a specific time.
|
||||||
|
pub async fn timeout_at<F: core::future::Future>(
|
||||||
|
instant: <Self as rtic_time::Monotonic>::Instant,
|
||||||
|
future: F,
|
||||||
|
) -> Result<F::Output, TimeoutError> {
|
||||||
|
$tq.timeout_at(instant, future).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Timeout after a specific duration.
|
||||||
|
#[inline]
|
||||||
|
pub async fn timeout_after<F: core::future::Future>(
|
||||||
|
duration: <Self as Monotonic>::Duration,
|
||||||
|
future: F,
|
||||||
|
) -> Result<F::Output, TimeoutError> {
|
||||||
|
$tq.timeout_after(duration, future).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delay to some specific time instant.
|
||||||
|
#[inline]
|
||||||
|
pub async fn delay_until(instant: <Self as Monotonic>::Instant) {
|
||||||
|
$tq.delay_until(instant).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "embedded-hal-async")]
|
||||||
|
impl embedded_hal_async::delay::DelayUs for $mono_name {
|
||||||
|
#[inline]
|
||||||
|
async fn delay_us(&mut self, us: u32) {
|
||||||
|
Self::delay((us as u64).micros()).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
async fn delay_ms(&mut self, ms: u32) {
|
||||||
|
Self::delay((ms as u64).millis()).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl embedded_hal::delay::DelayUs for $mono_name {
|
||||||
|
fn delay_us(&mut self, us: u32) {
|
||||||
|
let done = Self::now() + (us as u64).micros();
|
||||||
|
while Self::now() < done {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Monotonic for $mono_name {
|
||||||
|
type Instant = fugit::TimerInstantU64<TIMER_HZ>;
|
||||||
|
type Duration = fugit::TimerDurationU64<TIMER_HZ>;
|
||||||
|
|
||||||
|
const ZERO: Self::Instant = Self::Instant::from_ticks(0);
|
||||||
|
|
||||||
|
fn now() -> Self::Instant {
|
||||||
|
let gpt = unsafe{ $timer::instance() };
|
||||||
|
|
||||||
|
// Important: period **must** be read first.
|
||||||
|
let period = $period.load(Ordering::Relaxed);
|
||||||
|
compiler_fence(Ordering::Acquire);
|
||||||
|
let counter = ral::read_reg!(ral::gpt, gpt, CNT);
|
||||||
|
|
||||||
|
Self::Instant::from_ticks(calc_now(period, counter))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_compare(instant: Self::Instant) {
|
||||||
|
let gpt = unsafe{ $timer::instance() };
|
||||||
|
|
||||||
|
// Set the timer regardless of whether it is multiple periods in the future,
|
||||||
|
// or even already in the past.
|
||||||
|
// The worst thing that can happen is a spurious wakeup, and with a timer
|
||||||
|
// period of half an hour, this is hardly a problem.
|
||||||
|
|
||||||
|
let ticks = instant.duration_since_epoch().ticks();
|
||||||
|
let ticks_wrapped = ticks as u32;
|
||||||
|
|
||||||
|
ral::write_reg!(ral::gpt, gpt, OCR[1], ticks_wrapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_compare_flag() {
|
||||||
|
let gpt = unsafe{ $timer::instance() };
|
||||||
|
ral::write_reg!(ral::gpt, gpt, SR, OF2: 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pend_interrupt() {
|
||||||
|
cortex_m::peripheral::NVIC::pend(ral::Interrupt::$timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_interrupt() {
|
||||||
|
let gpt = unsafe{ $timer::instance() };
|
||||||
|
|
||||||
|
let (rollover, half_rollover) = ral::read_reg!(ral::gpt, gpt, SR, ROV, OF1);
|
||||||
|
|
||||||
|
if rollover != 0 {
|
||||||
|
$period.fetch_add(1, Ordering::Relaxed);
|
||||||
|
ral::write_reg!(ral::gpt, gpt, SR, ROV: 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if half_rollover != 0 {
|
||||||
|
$period.fetch_add(1, Ordering::Relaxed);
|
||||||
|
ral::write_reg!(ral::gpt, gpt, SR, OF1: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "imxrt_gpt1")]
|
||||||
|
make_timer!(Gpt1, GPT1, GPT1_HALFPERIODS, GPT1_TQ);
|
||||||
|
|
||||||
|
#[cfg(feature = "imxrt_gpt2")]
|
||||||
|
make_timer!(Gpt2, GPT2, GPT2_HALFPERIODS, GPT2_TQ);
|
|
@ -33,6 +33,9 @@ pub mod systick;
|
||||||
#[cfg(feature = "rp2040")]
|
#[cfg(feature = "rp2040")]
|
||||||
pub mod rp2040;
|
pub mod rp2040;
|
||||||
|
|
||||||
|
#[cfg(feature = "imxrt")]
|
||||||
|
pub mod imxrt;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "nrf52810",
|
feature = "nrf52810",
|
||||||
feature = "nrf52811",
|
feature = "nrf52811",
|
||||||
|
@ -64,6 +67,7 @@ pub(crate) const fn cortex_logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 {
|
||||||
feature = "nrf5340-app",
|
feature = "nrf5340-app",
|
||||||
feature = "nrf5340-net",
|
feature = "nrf5340-net",
|
||||||
feature = "nrf9160",
|
feature = "nrf9160",
|
||||||
|
feature = "imxrt",
|
||||||
stm32,
|
stm32,
|
||||||
))]
|
))]
|
||||||
pub(crate) unsafe fn set_monotonic_prio(
|
pub(crate) unsafe fn set_monotonic_prio(
|
||||||
|
|
Loading…
Reference in a new issue