Init
This commit is contained in:
commit
49b27a674e
8
.cargo/config
Normal file
8
.cargo/config
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[target.thumbv7m-none-eabi]
|
||||||
|
runner = 'arm-none-eabi-gdb'
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
target = "thumbv7m-none-eabi"
|
18
.gdbinit
Normal file
18
.gdbinit
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
target remote :3333
|
||||||
|
|
||||||
|
monitor arm semihosting enable
|
||||||
|
|
||||||
|
# # send captured ITM to the file itm.fifo
|
||||||
|
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
|
||||||
|
# # 8000000 must match the core clock frequency
|
||||||
|
# monitor tpiu config internal itm.fifo uart off 8000000
|
||||||
|
|
||||||
|
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
|
||||||
|
# # 2000000 is the frequency of the SWO pin
|
||||||
|
# monitor tpiu config external uart off 8000000 2000000
|
||||||
|
|
||||||
|
# # enable ITM port 0
|
||||||
|
# monitor itm port 0 on
|
||||||
|
|
||||||
|
load
|
||||||
|
step
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
515
Cargo.lock
generated
Normal file
515
Cargo.lock
generated
Normal file
|
@ -0,0 +1,515 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bare-metal"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version 0.2.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bare-metal"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
|
||||||
|
|
||||||
|
[[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 = "bxcan"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"embedded-hal",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"vcell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
"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",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m-rtic"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d696ae7390bdb9f7978f71ca7144256a2c4616240a6df9002da3c451f9fc8f02"
|
||||||
|
dependencies = [
|
||||||
|
"bare-metal 1.0.0",
|
||||||
|
"cortex-m",
|
||||||
|
"cortex-m-rtic-macros",
|
||||||
|
"heapless",
|
||||||
|
"rtic-core",
|
||||||
|
"rtic-monotonic",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m-rtic-macros"
|
||||||
|
version = "1.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eefb40b1ca901c759d29526e5c8a0a1b246c20caaa5b4cc5d0f0b94debecd4c7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rtic-syntax",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m-semihosting"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-alloc"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8931e47e33c5d3194fbcf9cc82df0919193bd2fa40008f388eb1d28fd9c9ea6b"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
"linked_list_allocator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-dma"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446"
|
||||||
|
dependencies = [
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "fugit"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
|
||||||
|
dependencies = [
|
||||||
|
"gcd",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fugit-timer"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9607bfc4c388f9d629704f56ede4a007546cad417b3bcd6fc7c87dc7edce04a"
|
||||||
|
dependencies = [
|
||||||
|
"fugit",
|
||||||
|
"nb 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gcd"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hello-can-stm32"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bxcan",
|
||||||
|
"cortex-m",
|
||||||
|
"cortex-m-rt",
|
||||||
|
"cortex-m-rtic",
|
||||||
|
"cortex-m-semihosting",
|
||||||
|
"embedded-alloc",
|
||||||
|
"embedded-hal",
|
||||||
|
"heapless",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"panic-halt",
|
||||||
|
"shared-bus-rtic",
|
||||||
|
"stm32f1xx-hal",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked_list_allocator"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "panic-halt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
"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 = "rtic-core"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtic-monotonic"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb8b0b822d1a366470b9cea83a1d4e788392db763539dc4ba022bcc787fece82"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtic-syntax"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f5e215601dc467752c2bddc6284a622c6f3d2bab569d992adcd5ab7e4cb9478"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||||
|
dependencies = [
|
||||||
|
"semver 1.0.20",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[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"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shared-bus-rtic"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb1899470d03c5728db375f63be8f2bbfb93d8c35ec932061f3b593434c2273b"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-hal",
|
||||||
|
"nb 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stm32-usbd"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6c94998f166d66b210a164648a0b7866428d8f1e0740bf8a4c5edd89d4750c1"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m",
|
||||||
|
"usb-device",
|
||||||
|
"vcell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stm32f1"
|
||||||
|
version = "0.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2dc80735831c28fe85384e1e28428fb6d201f67c696e369a239ed9c5eba369d"
|
||||||
|
dependencies = [
|
||||||
|
"bare-metal 1.0.0",
|
||||||
|
"cortex-m",
|
||||||
|
"cortex-m-rt",
|
||||||
|
"vcell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stm32f1xx-hal"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30845662b9ce46a2ec04da97666a2b32458bee5032bb0452d0caf1536a96a542"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"bxcan",
|
||||||
|
"cortex-m",
|
||||||
|
"cortex-m-rt",
|
||||||
|
"embedded-dma",
|
||||||
|
"embedded-hal",
|
||||||
|
"fugit",
|
||||||
|
"fugit-timer",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"stm32-usbd",
|
||||||
|
"stm32f1",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "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 = "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.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
|
||||||
|
dependencies = [
|
||||||
|
"vcell",
|
||||||
|
]
|
44
Cargo.toml
Normal file
44
Cargo.toml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
[package]
|
||||||
|
name = "hello-can-stm32"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
embedded-hal = "0.2.7"
|
||||||
|
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
|
||||||
|
cortex-m-rtic = "1.1.3"
|
||||||
|
panic-halt = "0.2.0"
|
||||||
|
cortex-m-semihosting = { version = "0.5.0" }
|
||||||
|
stm32f1xx-hal = { version = "0.10.0", features = ["rt", "stm32f103"] }
|
||||||
|
shared-bus-rtic = "0.2.2"
|
||||||
|
embedded-alloc = "0.5.0"
|
||||||
|
nb = "1.1.0"
|
||||||
|
cortex-m-rt = "0.7.3"
|
||||||
|
bxcan = "0.7.0"
|
||||||
|
heapless = "0.7.16"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
no-debug = ["cortex-m-semihosting/no-semihosting"]
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = "z"
|
||||||
|
codegen-units = 1
|
||||||
|
overflow-checks = false
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = "z"
|
||||||
|
codegen-units = 1
|
||||||
|
overflow-checks = false
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
opt-level = "z"
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.release.package."*"]
|
||||||
|
debug = true
|
||||||
|
opt-level = "z"
|
||||||
|
codegen-units = 1
|
18
build.rs
Normal file
18
build.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("memory.x"))
|
||||||
|
.unwrap();
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when memory.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=memory.x");
|
||||||
|
}
|
253
can-rtic.rs
Normal file
253
can-rtic.rs
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
//! Interrupt driven CAN transmitter with RTIC.
|
||||||
|
//!
|
||||||
|
//! CAN frames are allocated from a static memory pool and stored in a priority
|
||||||
|
//! queue (min heap) for transmisison. To start transmission the CAN TX
|
||||||
|
//! interrupt has to be triggered manually once. With each successful
|
||||||
|
//! transmission the interrupt is reentered and more data is fetched from the
|
||||||
|
//! queue.
|
||||||
|
//! Received frames are simply echoed back. In contrast to the naive `can-echo`
|
||||||
|
//! example all messages are also correctly prioritized by the transmit queue.
|
||||||
|
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use panic_halt as _;
|
||||||
|
|
||||||
|
use bxcan::Frame;
|
||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
|
use heapless::binary_heap::{BinaryHeap, Max};
|
||||||
|
|
||||||
|
use stm32f1xx_hal::pac::Interrupt;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PriorityFrame(Frame);
|
||||||
|
|
||||||
|
/// Ordering is based on the Identifier and frame type (data vs. remote) and can be used to sort
|
||||||
|
/// frames by priority.
|
||||||
|
impl Ord for PriorityFrame {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.0.priority().cmp(&other.0.priority())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for PriorityFrame {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for PriorityFrame {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.cmp(other) == Ordering::Equal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for PriorityFrame {}
|
||||||
|
|
||||||
|
fn enqueue_frame(queue: &mut BinaryHeap<PriorityFrame, Max, 16>, frame: Frame) {
|
||||||
|
queue.push(PriorityFrame(frame)).unwrap();
|
||||||
|
rtic::pend(Interrupt::USB_HP_CAN_TX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rtic::app(device = stm32f1xx_hal::pac)]
|
||||||
|
mod app {
|
||||||
|
use super::{enqueue_frame, PriorityFrame};
|
||||||
|
use bxcan::{filter::Mask32, ExtendedId, Fifo, Frame, Interrupts, Rx0, StandardId, Tx};
|
||||||
|
use heapless::binary_heap::{BinaryHeap, Max};
|
||||||
|
use stm32f1xx_hal::{can::Can, pac::CAN1, prelude::*};
|
||||||
|
|
||||||
|
#[local]
|
||||||
|
struct Local {
|
||||||
|
can_tx: Tx<Can<CAN1>>,
|
||||||
|
can_rx: Rx0<Can<CAN1>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[shared]
|
||||||
|
struct Shared {
|
||||||
|
can_tx_queue: BinaryHeap<PriorityFrame, Max, 16>,
|
||||||
|
tx_count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
|
let mut flash = cx.device.FLASH.constrain();
|
||||||
|
let rcc = cx.device.RCC.constrain();
|
||||||
|
|
||||||
|
let _clocks = rcc
|
||||||
|
.cfgr
|
||||||
|
.use_hse(8.MHz())
|
||||||
|
.sysclk(64.MHz())
|
||||||
|
.hclk(64.MHz())
|
||||||
|
.pclk1(16.MHz())
|
||||||
|
.pclk2(64.MHz())
|
||||||
|
.freeze(&mut flash.acr);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "connectivity"))]
|
||||||
|
let can = Can::new(cx.device.CAN1, cx.device.USB);
|
||||||
|
|
||||||
|
#[cfg(feature = "connectivity")]
|
||||||
|
let can = Can::new(cx.device.CAN1);
|
||||||
|
|
||||||
|
// Select pins for CAN1.
|
||||||
|
let mut gpioa = cx.device.GPIOA.split();
|
||||||
|
let can_rx_pin = gpioa.pa11.into_floating_input(&mut gpioa.crh);
|
||||||
|
let can_tx_pin = gpioa.pa12.into_alternate_push_pull(&mut gpioa.crh);
|
||||||
|
let mut afio = cx.device.AFIO.constrain();
|
||||||
|
can.assign_pins((can_tx_pin, can_rx_pin), &mut afio.mapr);
|
||||||
|
|
||||||
|
// APB1 (PCLK1): 16MHz, Bit rate: 1000kBit/s, Sample Point 87.5%
|
||||||
|
// Value was calculated with http://www.bittiming.can-wiki.info/
|
||||||
|
let mut can = bxcan::Can::builder(can)
|
||||||
|
.set_bit_timing(0x001c_0000)
|
||||||
|
.leave_disabled();
|
||||||
|
|
||||||
|
can.modify_filters()
|
||||||
|
.enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
|
||||||
|
|
||||||
|
// Sync to the bus and start normal operation.
|
||||||
|
can.enable_interrupts(
|
||||||
|
Interrupts::TRANSMIT_MAILBOX_EMPTY | Interrupts::FIFO0_MESSAGE_PENDING,
|
||||||
|
);
|
||||||
|
nb::block!(can.enable_non_blocking()).unwrap();
|
||||||
|
|
||||||
|
let (can_tx, can_rx, _) = can.split();
|
||||||
|
|
||||||
|
let can_tx_queue = BinaryHeap::new();
|
||||||
|
|
||||||
|
(
|
||||||
|
Shared {
|
||||||
|
can_tx_queue,
|
||||||
|
tx_count: 0,
|
||||||
|
},
|
||||||
|
Local { can_tx, can_rx },
|
||||||
|
init::Monotonics(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[idle(shared = [can_tx_queue, tx_count])]
|
||||||
|
fn idle(mut cx: idle::Context) -> ! {
|
||||||
|
let mut tx_queue = cx.shared.can_tx_queue;
|
||||||
|
|
||||||
|
// Enqueue some messages. Higher ID means lower priority.
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(9).unwrap(), []),
|
||||||
|
);
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(ExtendedId::new(9).unwrap(), []),
|
||||||
|
);
|
||||||
|
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(8).unwrap(), []),
|
||||||
|
);
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(ExtendedId::new(8).unwrap(), []),
|
||||||
|
);
|
||||||
|
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(0x7FF).unwrap(), []),
|
||||||
|
);
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(ExtendedId::new(0x1FFF_FFFF).unwrap(), []),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add some higher priority messages when 3 messages have been sent.
|
||||||
|
loop {
|
||||||
|
let tx_count = cx.shared.tx_count.lock(|tx_count| *tx_count);
|
||||||
|
|
||||||
|
if tx_count >= 3 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(3).unwrap(), []),
|
||||||
|
);
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(2).unwrap(), []),
|
||||||
|
);
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(1).unwrap(), []),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected bus traffic:
|
||||||
|
//
|
||||||
|
// 1. ID: 0x00000008 <- proper reordering happens
|
||||||
|
// 2. ID: 0x00000009
|
||||||
|
// 3. ID: 0x008
|
||||||
|
// 4. ID: 0x001 <- higher priority messages injected correctly
|
||||||
|
// 5. ID: 0x002
|
||||||
|
// 6. ID: 0x003
|
||||||
|
// 7. ID: 0x009
|
||||||
|
// 8. ID: 0x7FF
|
||||||
|
// 9. ID: 0x1FFFFFFF
|
||||||
|
//
|
||||||
|
// The output can look different if there are other nodes on bus the sending messages.
|
||||||
|
|
||||||
|
loop {
|
||||||
|
cortex_m::asm::nop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This ISR is triggered by each finished frame transmission.
|
||||||
|
#[task(binds = USB_HP_CAN_TX, local = [can_tx], shared = [can_tx_queue, tx_count])]
|
||||||
|
fn can_tx(cx: can_tx::Context) {
|
||||||
|
let tx = cx.local.can_tx;
|
||||||
|
let mut tx_queue = cx.shared.can_tx_queue;
|
||||||
|
let mut tx_count = cx.shared.tx_count;
|
||||||
|
|
||||||
|
tx.clear_interrupt_flags();
|
||||||
|
|
||||||
|
// There is now a free mailbox. Try to transmit pending frames until either
|
||||||
|
// the queue is empty or transmission would block the execution of this ISR.
|
||||||
|
(&mut tx_queue, &mut tx_count).lock(|tx_queue, tx_count| {
|
||||||
|
while let Some(frame) = tx_queue.peek() {
|
||||||
|
match tx.transmit(&frame.0) {
|
||||||
|
Ok(status) => match status.dequeued_frame() {
|
||||||
|
None => {
|
||||||
|
// Frame was successfully placed into a transmit buffer.
|
||||||
|
tx_queue.pop();
|
||||||
|
*tx_count += 1;
|
||||||
|
}
|
||||||
|
Some(pending_frame) => {
|
||||||
|
// A lower priority frame was replaced with our high priority frame.
|
||||||
|
// Put the low priority frame back in the transmit queue.
|
||||||
|
tx_queue.pop();
|
||||||
|
enqueue_frame(tx_queue, pending_frame.clone());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(nb::Error::WouldBlock) => break,
|
||||||
|
Err(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[task(binds = USB_LP_CAN_RX0, local = [can_rx], shared = [can_tx_queue])]
|
||||||
|
fn can_rx0(mut cx: can_rx0::Context) {
|
||||||
|
// Echo back received packages with correct priority ordering.
|
||||||
|
loop {
|
||||||
|
match cx.local.can_rx.receive() {
|
||||||
|
Ok(frame) => {
|
||||||
|
cx.shared.can_tx_queue.lock(|can_tx_queue| {
|
||||||
|
enqueue_frame(can_tx_queue, frame);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(nb::Error::WouldBlock) => break,
|
||||||
|
Err(nb::Error::Other(_)) => {} // Ignore overrun errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
memory.x
Normal file
6
memory.x
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/* Linker script for the STM32F103C6T6 */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 10K
|
||||||
|
}
|
13
openocd.cfg
Normal file
13
openocd.cfg
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Sample OpenOCD configuration for the STM32F3DISCOVERY development board
|
||||||
|
|
||||||
|
# Depending on the hardware revision you got you'll have to pick ONE of these
|
||||||
|
# interfaces. At any time only one interface should be commented out.
|
||||||
|
|
||||||
|
# Revision C (newer revision)
|
||||||
|
#source [find interface/stlink-v2-1.cfg]
|
||||||
|
source [find interface/stlink-v2.cfg]
|
||||||
|
|
||||||
|
# Revision A and B (older revisions)
|
||||||
|
# source [find interface/stlink-v2.cfg]
|
||||||
|
|
||||||
|
source [find target/stm32f1x.cfg]
|
40
openocd.gdb
Normal file
40
openocd.gdb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
target extended-remote :3333
|
||||||
|
|
||||||
|
# print demangled symbols
|
||||||
|
set print asm-demangle on
|
||||||
|
|
||||||
|
# set backtrace limit to not have infinite backtrace loops
|
||||||
|
set backtrace limit 32
|
||||||
|
|
||||||
|
# detect unhandled exceptions, hard faults and panics
|
||||||
|
break DefaultHandler
|
||||||
|
break HardFault
|
||||||
|
break rust_begin_unwind
|
||||||
|
# # run the next few lines so the panic message is printed immediately
|
||||||
|
# # the number needs to be adjusted for your panic handler
|
||||||
|
# commands $bpnum
|
||||||
|
# next 4
|
||||||
|
# end
|
||||||
|
|
||||||
|
# *try* to stop at the user entry point (it might be gone due to inlining)
|
||||||
|
break main
|
||||||
|
|
||||||
|
monitor arm semihosting enable
|
||||||
|
|
||||||
|
# # send captured ITM to the file itm.fifo
|
||||||
|
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
|
||||||
|
# # 8000000 must match the core clock frequency
|
||||||
|
# monitor tpiu config internal itm.txt uart off 8000000
|
||||||
|
|
||||||
|
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
|
||||||
|
# # 8000000 must match the core clock frequency
|
||||||
|
# # 2000000 is the frequency of the SWO pin
|
||||||
|
# monitor tpiu config external uart off 8000000 2000000
|
||||||
|
|
||||||
|
# # enable ITM port 0
|
||||||
|
# monitor itm port 0 on
|
||||||
|
|
||||||
|
load
|
||||||
|
|
||||||
|
# start the process but immediately halt the processor
|
||||||
|
stepi
|
271
src/main.rs
Normal file
271
src/main.rs
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use embedded_alloc::Heap;
|
||||||
|
use panic_halt as _;
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static HEAP: Heap = Heap::empty();
|
||||||
|
|
||||||
|
use bxcan::Frame;
|
||||||
|
use core::cmp::Ordering;
|
||||||
|
use heapless::binary_heap::{BinaryHeap, Max};
|
||||||
|
|
||||||
|
use stm32f1xx_hal::pac::Interrupt;
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PriorityFrame(Frame);
|
||||||
|
|
||||||
|
/// Ordering is based on the Identifier and frame type (data vs. remote) and can be used to sort
|
||||||
|
/// frames by priority.
|
||||||
|
impl Ord for PriorityFrame {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.0.priority().cmp(&other.0.priority())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for PriorityFrame {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for PriorityFrame {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.cmp(other) == Ordering::Equal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for PriorityFrame {}
|
||||||
|
|
||||||
|
fn enqueue_frame(queue: &mut BinaryHeap<PriorityFrame, Max, 16>, frame: Frame) {
|
||||||
|
queue.push(PriorityFrame(frame)).unwrap();
|
||||||
|
rtic::pend(Interrupt::USB_HP_CAN_TX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rtic::app(device = stm32f1xx_hal::pac)]
|
||||||
|
mod app {
|
||||||
|
use cortex_m_semihosting::hprintln;
|
||||||
|
use heapless::binary_heap::{BinaryHeap, Max};
|
||||||
|
|
||||||
|
use super::{enqueue_frame, PriorityFrame};
|
||||||
|
use bxcan::{filter::Mask32, Fifo, Frame, Interrupts, Rx0, StandardId, Tx};
|
||||||
|
use stm32f1xx_hal::{
|
||||||
|
can::Can,
|
||||||
|
device::TIM2,
|
||||||
|
gpio::{Output, Pin},
|
||||||
|
pac::CAN1,
|
||||||
|
prelude::*,
|
||||||
|
timer::Delay,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[shared]
|
||||||
|
struct Shared {
|
||||||
|
can_tx_queue: BinaryHeap<PriorityFrame, Max, 16>,
|
||||||
|
tx_count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[local]
|
||||||
|
struct Local {
|
||||||
|
can_tx: Tx<Can<CAN1>>,
|
||||||
|
can_rx: Rx0<Can<CAN1>>,
|
||||||
|
led: Pin<'C', 13, Output>,
|
||||||
|
delay: Delay<TIM2, 1000000>,
|
||||||
|
counter: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[init]
|
||||||
|
fn init(ctx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
|
let mut flash = ctx.device.FLASH.constrain();
|
||||||
|
let rcc = ctx.device.RCC.constrain();
|
||||||
|
|
||||||
|
// let clocks = rcc.cfgr.freeze(&mut flash.acr);
|
||||||
|
|
||||||
|
let clocks = rcc
|
||||||
|
.cfgr
|
||||||
|
.use_hse(8.MHz())
|
||||||
|
.sysclk(64.MHz())
|
||||||
|
.hclk(64.MHz())
|
||||||
|
.pclk1(16.MHz())
|
||||||
|
.pclk2(64.MHz())
|
||||||
|
.freeze(&mut flash.acr);
|
||||||
|
|
||||||
|
let can = Can::new(ctx.device.CAN1, ctx.device.USB);
|
||||||
|
let mut gpioa = ctx.device.GPIOA.split();
|
||||||
|
let can_rx_pin = gpioa.pa11.into_floating_input(&mut gpioa.crh);
|
||||||
|
let can_tx_pin = gpioa.pa12.into_alternate_push_pull(&mut gpioa.crh);
|
||||||
|
let mut afio = ctx.device.AFIO.constrain();
|
||||||
|
can.assign_pins((can_tx_pin, can_rx_pin), &mut afio.mapr);
|
||||||
|
|
||||||
|
// APB1 (PCLK1): 16MHz, Bit rate: 1000kBit/s, Sample Point 87.5%
|
||||||
|
// Value was calculated with http://www.bittiming.can-wiki.info/
|
||||||
|
let mut can = bxcan::Can::builder(can)
|
||||||
|
.set_bit_timing(0x001c_0000)
|
||||||
|
.leave_disabled();
|
||||||
|
|
||||||
|
can.modify_filters()
|
||||||
|
.enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
|
||||||
|
|
||||||
|
// Sync to the bus and start normal operation.
|
||||||
|
can.enable_interrupts(
|
||||||
|
Interrupts::TRANSMIT_MAILBOX_EMPTY | Interrupts::FIFO0_MESSAGE_PENDING,
|
||||||
|
);
|
||||||
|
|
||||||
|
nb::block!(can.enable_non_blocking()).unwrap();
|
||||||
|
|
||||||
|
let (can_tx, can_rx, _) = can.split();
|
||||||
|
|
||||||
|
let can_tx_queue = BinaryHeap::new();
|
||||||
|
|
||||||
|
let delay = ctx.device.TIM2.delay_us(&clocks);
|
||||||
|
|
||||||
|
let mut gpioc = ctx.device.GPIOC.split();
|
||||||
|
let led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
|
||||||
|
|
||||||
|
(
|
||||||
|
Shared {
|
||||||
|
can_tx_queue,
|
||||||
|
tx_count: 0,
|
||||||
|
},
|
||||||
|
Local {
|
||||||
|
can_tx,
|
||||||
|
can_rx,
|
||||||
|
led,
|
||||||
|
delay,
|
||||||
|
counter: 0,
|
||||||
|
},
|
||||||
|
init::Monotonics(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn speed2array(speed: i16) -> [u8; 8] {
|
||||||
|
let b = speed.to_be_bytes();
|
||||||
|
[b[0], b[1], b[0], b[1], b[0], b[1], b[0], b[1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[idle(shared = [can_tx_queue, tx_count], local = [delay])]
|
||||||
|
fn idle(mut cx: idle::Context) -> ! {
|
||||||
|
let mut tx_queue = cx.shared.can_tx_queue;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
for speed in 0..=30 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(0x1FF).unwrap(), speed2array(speed * 1000)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.local.delay.delay(100.millis());
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..10 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(0x1FF).unwrap(), speed2array(30000)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.local.delay.delay(100.millis());
|
||||||
|
}
|
||||||
|
|
||||||
|
for speed in 0..=30 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(
|
||||||
|
StandardId::new(0x1FF).unwrap(),
|
||||||
|
speed2array(30000 - (speed * 1000)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.local.delay.delay(100.millis());
|
||||||
|
}
|
||||||
|
|
||||||
|
for speed in 0..=30 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(0x1FF).unwrap(), speed2array(speed * 1000 * -1)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.local.delay.delay(100.millis());
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..10 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(StandardId::new(0x1FF).unwrap(), speed2array(30000 * -1)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.local.delay.delay(100.millis());
|
||||||
|
}
|
||||||
|
|
||||||
|
for speed in 0..=30 {
|
||||||
|
tx_queue.lock(|mut tx_queue| {
|
||||||
|
enqueue_frame(
|
||||||
|
&mut tx_queue,
|
||||||
|
Frame::new_data(
|
||||||
|
StandardId::new(0x1FF).unwrap(),
|
||||||
|
speed2array(( 30000 - (speed * 1000) ) * -1),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.local.delay.delay(100.millis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This ISR is triggered by each finished frame transmission.
|
||||||
|
#[task(binds = USB_HP_CAN_TX, local = [can_tx, led], shared = [can_tx_queue, tx_count])]
|
||||||
|
fn can_tx(cx: can_tx::Context) {
|
||||||
|
let tx = cx.local.can_tx;
|
||||||
|
let mut tx_queue = cx.shared.can_tx_queue;
|
||||||
|
let mut tx_count = cx.shared.tx_count;
|
||||||
|
|
||||||
|
tx.clear_interrupt_flags();
|
||||||
|
|
||||||
|
// There is now a free mailbox. Try to transmit pending frames until either
|
||||||
|
// the queue is empty or transmission would block the execution of this ISR.
|
||||||
|
(&mut tx_queue, &mut tx_count).lock(|tx_queue, tx_count| {
|
||||||
|
while let Some(frame) = tx_queue.peek() {
|
||||||
|
match tx.transmit(&frame.0) {
|
||||||
|
Ok(status) => match status.dequeued_frame() {
|
||||||
|
None => {
|
||||||
|
tx_queue.pop();
|
||||||
|
*tx_count += 1;
|
||||||
|
cx.local.led.toggle();
|
||||||
|
}
|
||||||
|
Some(pending_frame) => {
|
||||||
|
tx_queue.pop();
|
||||||
|
enqueue_frame(tx_queue, pending_frame.clone());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(nb::Error::WouldBlock) => break,
|
||||||
|
Err(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[task(binds = USB_LP_CAN_RX0, local = [can_rx], shared = [can_tx_queue])]
|
||||||
|
fn can_rx0(mut cx: can_rx0::Context) {
|
||||||
|
// Echo back received packages with correct priority ordering.
|
||||||
|
loop {
|
||||||
|
match cx.local.can_rx.receive() {
|
||||||
|
Ok(frame) => {
|
||||||
|
// let data = frame.data().unwrap();
|
||||||
|
}
|
||||||
|
Err(nb::Error::WouldBlock) => break,
|
||||||
|
Err(nb::Error::Other(_)) => {} // Ignore overrun errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user