Init
This commit is contained in:
		
							
								
								
									
										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.
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user