Compare commits

..

2 Commits

Author SHA1 Message Date
Robin Mueller 5a2a070c48 continue with subsystem 2026-05-12 13:01:23 +02:00
Robin Mueller a0382a2f27 start adding ACS subsystem 2026-05-11 16:50:59 +02:00
20 changed files with 490 additions and 281 deletions
+97 -142
View File
@@ -13,9 +13,9 @@ dependencies = [
[[package]] [[package]]
name = "aligned" name = "aligned"
version = "0.4.3" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923"
dependencies = [ dependencies = [
"as-slice", "as-slice",
] ]
@@ -90,7 +90,7 @@ dependencies = [
"arbitrary-int 1.3.0", "arbitrary-int 1.3.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -202,7 +202,7 @@ checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -255,7 +255,7 @@ dependencies = [
"ident_case", "ident_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -266,7 +266,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -298,7 +298,7 @@ dependencies = [
"proc-macro-error2", "proc-macro-error2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -322,24 +322,25 @@ dependencies = [
[[package]] [[package]]
name = "defmt-test" name = "defmt-test"
version = "0.5.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d326e211b94939affafdf96f5c1baf8745b960037dcf763f813597d32b03d51" checksum = "24076cc7203c365e7febfcec15d6667a9ef780bd2c5fd3b2a197400df78f299b"
dependencies = [ dependencies = [
"cortex-m-rt",
"cortex-m-semihosting",
"defmt 1.0.1", "defmt 1.0.1",
"defmt-test-macros", "defmt-test-macros",
"semihosting",
] ]
[[package]] [[package]]
name = "defmt-test-macros" name = "defmt-test-macros"
version = "0.3.3" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a7563a5468e1a1bd97f44cb75b658c2feec75af2b1389e70f4c0677b8402edd" checksum = "fe5520fd36862f281c026abeaab153ebbc001717c29a9b8e5ba9704d8f3a879d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -350,7 +351,7 @@ checksum = "6178a82cf56c836a3ba61a7935cdb1c49bfaa6fa4327cd5bf554a503087de26b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -364,15 +365,14 @@ dependencies = [
[[package]] [[package]]
name = "embassy-embedded-hal" name = "embassy-embedded-hal"
version = "0.6.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8"
dependencies = [ dependencies = [
"defmt 1.0.1", "defmt 1.0.1",
"embassy-futures", "embassy-futures",
"embassy-hal-internal 0.4.0", "embassy-hal-internal",
"embassy-sync", "embassy-sync",
"embassy-time",
"embedded-hal 0.2.7", "embedded-hal 0.2.7",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"embedded-hal-async", "embedded-hal-async",
@@ -381,12 +381,6 @@ dependencies = [
"nb 1.1.0", "nb 1.1.0",
] ]
[[package]]
name = "embassy-executor-timer-queue"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c"
[[package]] [[package]]
name = "embassy-futures" name = "embassy-futures"
version = "0.1.2" version = "0.1.2"
@@ -395,18 +389,9 @@ checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01"
[[package]] [[package]]
name = "embassy-hal-internal" name = "embassy-hal-internal"
version = "0.4.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f10ce10a4dfdf6402d8e9bd63128986b96a736b1a0a6680547ed2ac55d55dba" checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a"
dependencies = [
"num-traits",
]
[[package]]
name = "embassy-hal-internal"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "568659fc53866d3d85c60fa33723fb751aa69e71507634fc2c19e7649432fb75"
dependencies = [ dependencies = [
"cortex-m", "cortex-m",
"critical-section", "critical-section",
@@ -425,9 +410,9 @@ dependencies = [
[[package]] [[package]]
name = "embassy-stm32" name = "embassy-stm32"
version = "0.6.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "486c0622deb5a519fc4d2cb8e3ef324f7568fcdfff201ff8fcab46557d663ceb" checksum = "0d972eab325cc96afee98f80a91ca6b00249b6356dc0fdbff68b70c200df9fae"
dependencies = [ dependencies = [
"aligned", "aligned",
"bit_field", "bit_field",
@@ -441,12 +426,10 @@ dependencies = [
"document-features", "document-features",
"embassy-embedded-hal", "embassy-embedded-hal",
"embassy-futures", "embassy-futures",
"embassy-hal-internal 0.5.0", "embassy-hal-internal",
"embassy-net-driver", "embassy-net-driver",
"embassy-sync", "embassy-sync",
"embassy-time", "embassy-time",
"embassy-time-driver",
"embassy-time-queue-utils",
"embassy-usb-driver", "embassy-usb-driver",
"embassy-usb-synopsys-otg", "embassy-usb-synopsys-otg",
"embedded-can", "embedded-can",
@@ -454,54 +437,50 @@ dependencies = [
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"embedded-hal-async", "embedded-hal-async",
"embedded-hal-nb", "embedded-hal-nb",
"embedded-io 0.7.1", "embedded-io",
"embedded-io-async 0.7.0", "embedded-io-async",
"embedded-storage", "embedded-storage",
"embedded-storage-async", "embedded-storage-async",
"futures-util", "futures-util",
"heapless 0.9.1",
"nb 1.1.0", "nb 1.1.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"rand_core 0.6.4", "rand_core 0.6.4",
"rand_core 0.9.3", "rand_core 0.9.3",
"regex",
"sdio-host", "sdio-host",
"static_assertions", "static_assertions",
"stm32-fmc", "stm32-fmc",
"stm32-metapac", "stm32-metapac",
"trait-set",
"vcell", "vcell",
"volatile-register", "volatile-register",
] ]
[[package]] [[package]]
name = "embassy-sync" name = "embassy-sync"
version = "0.8.0" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81" checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"critical-section", "critical-section",
"defmt 1.0.1", "defmt 1.0.1",
"embedded-io-async 0.7.0", "embedded-io-async",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"heapless 0.9.1", "heapless 0.8.0",
] ]
[[package]] [[package]]
name = "embassy-time" name = "embassy-time"
version = "0.5.1" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"critical-section", "critical-section",
"defmt 1.0.1", "defmt 1.0.1",
"document-features", "document-features",
"embassy-time-driver", "embassy-time-driver",
"embassy-time-queue-utils",
"embedded-hal 0.2.7", "embedded-hal 0.2.7",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"embedded-hal-async", "embedded-hal-async",
@@ -510,23 +489,13 @@ dependencies = [
[[package]] [[package]]
name = "embassy-time-driver" name = "embassy-time-driver"
version = "0.2.2" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6"
dependencies = [ dependencies = [
"document-features", "document-features",
] ]
[[package]]
name = "embassy-time-queue-utils"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168297bf80aaf114b3c9ad589bf38b01b3009b9af7f97cd18086c5bbf96f5693"
dependencies = [
"embassy-executor-timer-queue",
"heapless 0.9.1",
]
[[package]] [[package]]
name = "embassy-usb-driver" name = "embassy-usb-driver"
version = "0.2.0" version = "0.2.0"
@@ -534,14 +503,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a"
dependencies = [ dependencies = [
"defmt 1.0.1", "defmt 1.0.1",
"embedded-io-async 0.6.1", "embedded-io-async",
] ]
[[package]] [[package]]
name = "embassy-usb-synopsys-otg" name = "embassy-usb-synopsys-otg"
version = "0.3.2" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbe46f4083109c7ea12a03ca61095d1e87c76fec52c7ca9ee06a42935606dacb" checksum = "288751f8eaa44a5cf2613f13cee0ca8e06e6638cb96e897e6834702c79084b23"
dependencies = [ dependencies = [
"critical-section", "critical-section",
"defmt 1.0.1", "defmt 1.0.1",
@@ -609,14 +578,8 @@ name = "embedded-io"
version = "0.6.1" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
[[package]]
name = "embedded-io"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7"
dependencies = [ dependencies = [
"defmt 1.0.1", "defmt 0.3.100",
] ]
[[package]] [[package]]
@@ -625,17 +588,8 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f"
dependencies = [ dependencies = [
"embedded-io 0.6.1", "defmt 0.3.100",
] "embedded-io",
[[package]]
name = "embedded-io-async"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0"
dependencies = [
"defmt 1.0.1",
"embedded-io 0.7.1",
] ]
[[package]] [[package]]
@@ -671,7 +625,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -692,6 +646,15 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fugit"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
dependencies = [
"gcd",
]
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.31" version = "0.3.31"
@@ -722,6 +685,12 @@ dependencies = [
"pin-utils", "pin-utils",
] ]
[[package]]
name = "gcd"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]] [[package]]
name = "generator" name = "generator"
version = "0.8.7" version = "0.8.7"
@@ -923,7 +892,7 @@ checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -996,7 +965,7 @@ dependencies = [
"proc-macro-error-attr2", "proc-macro-error-attr2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -1029,18 +998,6 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
[[package]]
name = "regex"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.4.13" version = "0.4.13"
@@ -1098,7 +1055,20 @@ dependencies = [
"proc-macro-error2", "proc-macro-error2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
]
[[package]]
name = "rtic-monotonics"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99f9923ce32637ee40c0cb28fbbc2fad880d8aebea2d545918c6971ae9be3d17"
dependencies = [
"cfg-if",
"cortex-m",
"fugit",
"portable-atomic",
"rtic-time",
] ]
[[package]] [[package]]
@@ -1117,6 +1087,20 @@ dependencies = [
"rtic-common", "rtic-common",
] ]
[[package]]
name = "rtic-time"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61485474f5a23247ae1d4875f2bfe860be9b3030dbf87c232e50799e021429a1"
dependencies = [
"critical-section",
"embedded-hal 1.0.0",
"embedded-hal-async",
"fugit",
"futures-util",
"rtic-common",
]
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
@@ -1154,13 +1138,13 @@ dependencies = [
"defmt-rtt", "defmt-rtt",
"defmt-test", "defmt-test",
"embassy-stm32", "embassy-stm32",
"embassy-time",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"enumset", "enumset",
"heapless 0.9.1", "heapless 0.9.1",
"panic-probe", "panic-probe",
"postcard", "postcard",
"rtic", "rtic",
"rtic-monotonics",
"rtic-sync", "rtic-sync",
"serde", "serde",
"spacepackets", "spacepackets",
@@ -1186,12 +1170,6 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b328e2cb950eeccd55b7f55c3a963691455dcd044cfb5354f0c5e68d2c2d6ee2" checksum = "b328e2cb950eeccd55b7f55c3a963691455dcd044cfb5354f0c5e68d2c2d6ee2"
[[package]]
name = "semihosting"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8e4abf97879f4e80db69a9fba7bd64998e9bdad25f58ef045a778e191172fd4"
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.9.0" version = "0.9.0"
@@ -1240,7 +1218,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -1267,8 +1245,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]] [[package]]
name = "spacepackets" name = "spacepackets"
version = "0.17.0" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://egit.irs.uni-stuttgart.de/rust/spacepackets.git#2bc61677105765e69cc96bb1ff9960557c00fa8e"
checksum = "94979a990b4333f43667cba9fe9e72b9c4e9ada82e09fbe8fb250844358590cc"
dependencies = [ dependencies = [
"arbitrary-int 2.0.0", "arbitrary-int 2.0.0",
"bitbybit", "bitbybit",
@@ -1316,35 +1293,24 @@ dependencies = [
[[package]] [[package]]
name = "stm32-fmc" name = "stm32-fmc"
version = "0.4.0" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72692594faa67f052e5e06dd34460951c21e83bc55de4feb8d2666e2f15480a2" checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c"
dependencies = [ dependencies = [
"embedded-hal 1.0.0", "embedded-hal 0.2.7",
] ]
[[package]] [[package]]
name = "stm32-metapac" name = "stm32-metapac"
version = "21.0.0" version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74b78632cea498cfb28386a29f8bfae7476d6570a78733eb5fecbee66c2f4ce" checksum = "6fd8ec3a292a0d9fc4798416a61b21da5ae50341b2e7b8d12e662bf305366097"
dependencies = [ dependencies = [
"cortex-m", "cortex-m",
"cortex-m-rt", "cortex-m-rt",
"defmt 0.3.100", "defmt 0.3.100",
] ]
[[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]] [[package]]
name = "syn" name = "syn"
version = "2.0.108" version = "2.0.108"
@@ -1373,7 +1339,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -1434,17 +1400,6 @@ dependencies = [
"tracing-log", "tracing-log",
] ]
[[package]]
name = "trait-set"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b79e2e9c9ab44c6d7c20d5976961b47e8f49ac199154daa514b77cd1ab536625"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.22" version = "1.0.22"
@@ -1532,7 +1487,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -1543,7 +1498,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
[[package]] [[package]]
@@ -1621,5 +1576,5 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.108", "syn",
] ]
@@ -14,8 +14,7 @@ defmt-rtt = { version = "1" }
panic-probe = { version = "1", features = ["print-defmt"] } panic-probe = { version = "1", features = ["print-defmt"] }
embedded-hal = "1" embedded-hal = "1"
cortex-m-semihosting = "0.5.0" cortex-m-semihosting = "0.5.0"
embassy-stm32 = { version = "0.6", features = ["defmt", "stm32f303vc", "memory-x", "unstable-pac", "time-driver-any"] } embassy-stm32 = { version = "0.4", features = ["defmt", "stm32f303vc", "unstable-pac"] }
embassy-time = { version = "0.5", features = ["defmt", "generic-queue-16", "defmt-timestamp-uptime-ms"]}
enumset = "1" enumset = "1"
heapless = "0.9" heapless = "0.9"
spacepackets = { version = "0.17", default-features = false, features = ["defmt", "serde"] } spacepackets = { version = "0.17", default-features = false, features = ["defmt", "serde"] }
@@ -28,9 +27,10 @@ serde = { version = "1", default-features = false, features = ["derive"] }
rtic = { version = "2", features = ["thumbv7-backend"] } rtic = { version = "2", features = ["thumbv7-backend"] }
rtic-sync = { version = "1" } rtic-sync = { version = "1" }
rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }
[dev-dependencies] [dev-dependencies]
defmt-test = "0.5" defmt-test = "0.4"
# cargo test # cargo test
[profile.test] [profile.test]
@@ -0,0 +1,33 @@
/* Linker script for the STM32F303VCT6 */
MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 40K
}
/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* You may want to use this variable to locate the call stack and static
variables in different memory regions. Below is shown the default value */
/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */
/* You can use this symbol to customize the location of the .text section */
/* If omitted the .text section will be placed right after the .vector_table
section */
/* This is required only on microcontrollers that store some configuration right
after the vector table */
/* _stext = ORIGIN(FLASH) + 0x400; */
/* Example of putting non-initialized variables into custom RAM locations. */
/* This assumes you have defined a region RAM2 above, and in the Rust
sources added the attribute `#[link_section = ".ram2bss"]` to the data
you want to place there. */
/* Note that the section will not be zero-initialized by the runtime! */
/* SECTIONS {
.ram2bss (NOLOAD) : ALIGN(4) {
*(.ram2bss);
. = ALIGN(4);
} > RAM2
} INSERT AFTER .bss;
*/
@@ -6,8 +6,11 @@ use rtic::app;
#[app(device = embassy_stm32)] #[app(device = embassy_stm32)]
mod app { mod app {
use embassy_time::Timer; use rtic_monotonics::fugit::ExtU32;
use satrs_stm32f3_disco_rtic::{Direction, LedPinSet, Leds}; use rtic_monotonics::Monotonic as _;
use satrs_stm32f3_disco_rtic::{Direction, LedPinSet, Leds};
rtic_monotonics::systick_monotonic!(Mono, 1000);
#[shared] #[shared]
struct Shared {} struct Shared {}
@@ -19,7 +22,7 @@ use satrs_stm32f3_disco_rtic::{Direction, LedPinSet, Leds};
} }
#[init] #[init]
fn init(_cx: init::Context) -> (Shared, Local) { fn init(cx: init::Context) -> (Shared, Local) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
defmt::info!("Starting sat-rs demo application for the STM32F3-Discovery using RTICv2"); defmt::info!("Starting sat-rs demo application for the STM32F3-Discovery using RTICv2");
@@ -36,6 +39,8 @@ use satrs_stm32f3_disco_rtic::{Direction, LedPinSet, Leds};
}; };
let leds = Leds::new(led_pin_set); let leds = Leds::new(led_pin_set);
// Initialize the systick interrupt & obtain the token to prove that we did
Mono::start(cx.core.SYST, 8_000_000);
blinky::spawn().expect("failed to spawn blinky task"); blinky::spawn().expect("failed to spawn blinky task");
( (
Shared {}, Shared {},
@@ -50,7 +55,7 @@ use satrs_stm32f3_disco_rtic::{Direction, LedPinSet, Leds};
async fn blinky(cx: blinky::Context) { async fn blinky(cx: blinky::Context) {
loop { loop {
cx.local.leds.blink_next(cx.local.current_dir); cx.local.leds.blink_next(cx.local.current_dir);
Timer::after_millis(200).await; Mono::delay(200.millis()).await;
} }
} }
} }
@@ -1,9 +1,6 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
use defmt_rtt as _;
use panic_probe as _;
use arbitrary_int::u11; use arbitrary_int::u11;
use core::time::Duration; use core::time::Duration;
use embassy_stm32::gpio::Output; use embassy_stm32::gpio::Output;
@@ -2,11 +2,21 @@
#![no_main] #![no_main]
use arbitrary_int::{u11, u14}; use arbitrary_int::{u11, u14};
use cortex_m_semihosting::debug::{self, EXIT_FAILURE, EXIT_SUCCESS}; use cortex_m_semihosting::debug::{self, EXIT_FAILURE, EXIT_SUCCESS};
use satrs_stm32f3_disco_rtic::{create_tm_packet, tm_size, Request, Response}; use satrs_stm32f3_disco_rtic::{create_tm_packet, tm_size, CcsdsPacketId, Request, Response};
use spacepackets::{CcsdsPacketCreationError, CcsdsPacketIdAndPsc, SpHeader}; use spacepackets::{CcsdsPacketCreationError, SpHeader};
use defmt_rtt as _; // global logger
use panic_probe as _;
use rtic::app; use rtic::app;
#[allow(unused_imports)]
use rtic_monotonics::fugit::{MillisDurationU32, TimerInstantU32};
use rtic_monotonics::systick::prelude::*;
use crate::app::Mono;
const UART_BAUD: u32 = 115200; const UART_BAUD: u32 = 115200;
const DEFAULT_BLINK_FREQ_MS: u32 = 1000; const DEFAULT_BLINK_FREQ_MS: u32 = 1000;
const TX_HANDLER_FREQ_MS: u32 = 20; const TX_HANDLER_FREQ_MS: u32 = 20;
@@ -38,7 +48,7 @@ pub enum TmSendError {
#[derive(Debug, defmt::Format)] #[derive(Debug, defmt::Format)]
pub struct RequestWithTcId { pub struct RequestWithTcId {
pub request: Request, pub request: Request,
pub tc_id: CcsdsPacketIdAndPsc, pub tc_id: CcsdsPacketId,
} }
#[app(device = embassy_stm32)] #[app(device = embassy_stm32)]
@@ -47,19 +57,18 @@ mod app {
use super::*; use super::*;
use arbitrary_int::u14; use arbitrary_int::u14;
use embassy_time::Timer;
use rtic::Mutex; use rtic::Mutex;
use rtic_sync::{ use rtic_sync::{
channel::{Receiver, Sender}, channel::{Receiver, Sender},
make_channel, make_channel,
}; };
use satrs_stm32f3_disco_rtic::{LedPinSet, Request, Response}; use satrs_stm32f3_disco_rtic::{CcsdsPacketId, LedPinSet, Request, Response};
use spacepackets::CcsdsPacketReader; use spacepackets::CcsdsPacketReader;
systick_monotonic!(Mono, 1000);
embassy_stm32::bind_interrupts!(struct Irqs { embassy_stm32::bind_interrupts!(struct Irqs {
USART2 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART2>; USART2 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART2>;
DMA1_CHANNEL6 => embassy_stm32::dma::InterruptHandler<embassy_stm32::peripherals::DMA1_CH6>;
DMA1_CHANNEL7 => embassy_stm32::dma::InterruptHandler<embassy_stm32::peripherals::DMA1_CH7>;
}); });
#[shared] #[shared]
@@ -77,13 +86,15 @@ mod app {
} }
#[init] #[init]
fn init(_cx: init::Context) -> (Shared, Local) { fn init(cx: init::Context) -> (Shared, Local) {
static DMA_BUF: static_cell::ConstStaticCell<[u8; TC_DMA_BUF_LEN]> = static DMA_BUF: static_cell::ConstStaticCell<[u8; TC_DMA_BUF_LEN]> =
static_cell::ConstStaticCell::new([0; TC_DMA_BUF_LEN]); static_cell::ConstStaticCell::new([0; TC_DMA_BUF_LEN]);
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let (req_sender, req_receiver) = make_channel!(RequestWithTcId, 16); let (req_sender, req_receiver) = make_channel!(RequestWithTcId, 16);
// Initialize the systick interrupt & obtain the token to prove that we did
Mono::start(cx.core.SYST, 8_000_000);
defmt::info!("sat-rs demo application for the STM32F3-Discovery with RTICv2"); defmt::info!("sat-rs demo application for the STM32F3-Discovery with RTICv2");
let led_pin_set = LedPinSet { let led_pin_set = LedPinSet {
@@ -101,7 +112,7 @@ mod app {
let mut config = embassy_stm32::usart::Config::default(); let mut config = embassy_stm32::usart::Config::default();
config.baudrate = UART_BAUD; config.baudrate = UART_BAUD;
let uart = embassy_stm32::usart::Uart::new( let uart = embassy_stm32::usart::Uart::new(
p.USART2, p.PA3, p.PA2, p.DMA1_CH7, p.DMA1_CH6, Irqs, config, p.USART2, p.PA3, p.PA2, Irqs, p.DMA1_CH7, p.DMA1_CH6, config,
) )
.unwrap(); .unwrap();
@@ -131,7 +142,10 @@ mod app {
loop { loop {
cx.local.leds.blink_next(cx.local.current_dir); cx.local.leds.blink_next(cx.local.current_dir);
let current_blink_freq = cx.shared.blink_freq.lock(|current| *current); let current_blink_freq = cx.shared.blink_freq.lock(|current| *current);
Timer::after_millis(current_blink_freq.as_millis() as u64).await; Mono::delay(MillisDurationU32::from_ticks(
current_blink_freq.as_millis() as u32,
))
.await;
} }
} }
@@ -155,7 +169,7 @@ mod app {
.unwrap(); .unwrap();
continue; continue;
} }
Timer::after_millis(TX_HANDLER_FREQ_MS as u64).await; Mono::delay(TX_HANDLER_FREQ_MS.millis()).await;
} }
} }
@@ -184,8 +198,9 @@ mod app {
&decoder.dest()[0..packet_size], &decoder.dest()[0..packet_size],
) { ) {
Ok(packet) => { Ok(packet) => {
let tc_packet_id = let packet_id = packet.packet_id();
CcsdsPacketIdAndPsc::new_from_ccsds_packet(&packet); let psc = packet.psc();
let tc_packet_id = CcsdsPacketId { packet_id, psc };
if let Ok(request) = if let Ok(request) =
postcard::from_bytes::<Request>(packet.packet_data()) postcard::from_bytes::<Request>(packet.packet_data())
{ {
@@ -245,7 +260,7 @@ mod app {
fn handle_ping_request( fn handle_ping_request(
cx: &mut req_handler::Context, cx: &mut req_handler::Context,
tc_packet_id: CcsdsPacketIdAndPsc, tc_packet_id: CcsdsPacketId,
) -> Result<(), TmSendError> { ) -> Result<(), TmSendError> {
defmt::info!("Received PUS ping telecommand, sending ping reply"); defmt::info!("Received PUS ping telecommand, sending ping reply");
send_tm(tc_packet_id, Response::CommandDone, *cx.local.seq_count)?; send_tm(tc_packet_id, Response::CommandDone, *cx.local.seq_count)?;
@@ -255,7 +270,7 @@ mod app {
fn handle_change_blink_frequency_request( fn handle_change_blink_frequency_request(
cx: &mut req_handler::Context, cx: &mut req_handler::Context,
tc_packet_id: CcsdsPacketIdAndPsc, tc_packet_id: CcsdsPacketId,
duration: Duration, duration: Duration,
) -> Result<(), TmSendError> { ) -> Result<(), TmSendError> {
defmt::info!( defmt::info!(
@@ -272,14 +287,14 @@ mod app {
} }
fn send_tm( fn send_tm(
tc_packet_id: CcsdsPacketIdAndPsc, tc_packet_id: CcsdsPacketId,
response: Response, response: Response,
current_seq_count: u14, current_seq_count: u14,
) -> Result<(), TmSendError> { ) -> Result<(), TmSendError> {
let sp_header = SpHeader::new_for_unseg_tc(PUS_APID, current_seq_count, 0); let sp_header = SpHeader::new_for_unseg_tc(PUS_APID, current_seq_count, 0);
let tm_header = satrs_stm32f3_disco_rtic::TmHeader { let tm_header = satrs_stm32f3_disco_rtic::TmHeader {
tc_packet_id: Some(tc_packet_id), tc_packet_id: Some(tc_packet_id),
uptime_millis: embassy_time::Instant::now().as_millis() as u32, uptime_millis: Mono::now().duration_since_epoch().to_millis(),
}; };
let mut tm_packet = TmPacket::new(); let mut tm_packet = TmPacket::new();
let tm_size = tm_size(&tm_header, &response); let tm_size = tm_size(&tm_header, &response);
+19 -16
View File
@@ -1,7 +1,7 @@
use anyhow::bail; use anyhow::bail;
use arbitrary_int::u11; use arbitrary_int::u11;
use clap::Parser as _; use clap::Parser as _;
use models::{Apid, MessageType, TcHeader, mgm::request::HkRequest}; use models::{Apid, MessageType, TcHeader, acs::mgm::request::HkRequest};
use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT}; use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT};
use spacepackets::{CcsdsPacketIdAndPsc, SpacePacketHeader}; use spacepackets::{CcsdsPacketIdAndPsc, SpacePacketHeader};
use std::{ use std::{
@@ -136,7 +136,7 @@ fn main() -> anyhow::Result<()> {
let request = models::ccsds::CcsdsTcPacketOwned::new_with_request( let request = models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
TcHeader::new(cmd.target_id(), models::MessageType::Ping), TcHeader::new(cmd.target_id(), models::MessageType::Ping),
models::mgm::request::Request::Ping, models::acs::mgm::request::Request::Ping,
); );
let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header); let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header);
log::info!( log::info!(
@@ -151,8 +151,8 @@ fn main() -> anyhow::Result<()> {
let request = models::ccsds::CcsdsTcPacketOwned::new_with_request( let request = models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
TcHeader::new(target_id, models::MessageType::Hk), TcHeader::new(target_id, models::MessageType::Hk),
models::mgm::request::Request::Hk(HkRequest { models::acs::mgm::request::Request::Hk(HkRequest {
id: models::mgm::request::HkId::Sensor, id: models::acs::mgm::request::HkId::Sensor,
req_type: models::HkRequestType::OneShot, req_type: models::HkRequestType::OneShot,
}), }),
); );
@@ -174,8 +174,8 @@ fn main() -> anyhow::Result<()> {
let request = models::ccsds::CcsdsTcPacketOwned::new_with_request( let request = models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
TcHeader::new(target_id, models::MessageType::Mode), TcHeader::new(target_id, models::MessageType::Mode),
models::mgm::request::Request::Mode( models::acs::mgm::request::Request::Mode(
models::mgm::request::ModeRequest::SetMode(dev_mode), models::acs::mgm::request::ModeRequest::SetMode(dev_mode),
), ),
); );
let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header); let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header);
@@ -193,7 +193,7 @@ fn main() -> anyhow::Result<()> {
let request = models::ccsds::CcsdsTcPacketOwned::new_with_request( let request = models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
TcHeader::new(cmd.target_id(), models::MessageType::Ping), TcHeader::new(cmd.target_id(), models::MessageType::Ping),
models::mgm::request::Request::Ping, models::acs::mgm::request::Request::Ping,
); );
let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header); let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header);
log::info!( log::info!(
@@ -207,21 +207,23 @@ fn main() -> anyhow::Result<()> {
if let Some(mode) = mgm_assembly_args.mode { if let Some(mode) = mgm_assembly_args.mode {
let assembly_mode = match mode { let assembly_mode = match mode {
AssemblyModeSelect::NoModeKeeping => { AssemblyModeSelect::NoModeKeeping => {
models::mgm_assembly::AssemblyMode::NoModeKeeping models::acs::mgm_assembly::Mode::NoModeKeeping
} }
AssemblyModeSelect::Off => { AssemblyModeSelect::Off => {
models::mgm_assembly::AssemblyMode::Device(models::DeviceMode::Off) models::acs::mgm_assembly::Mode::Device(models::DeviceMode::Off)
} }
AssemblyModeSelect::Normal => { AssemblyModeSelect::Normal => {
models::mgm_assembly::AssemblyMode::Device(models::DeviceMode::Normal) models::acs::mgm_assembly::Mode::Device(
models::DeviceMode::Normal,
)
} }
}; };
let request = models::ccsds::CcsdsTcPacketOwned::new_with_request( let request = models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
TcHeader::new(target_id, models::MessageType::Mode), TcHeader::new(target_id, models::MessageType::Mode),
models::mgm_assembly::request::Request::Mode( models::acs::mgm_assembly::request::Request::Mode(
models::mgm_assembly::request::ModeRequest::SetMode(assembly_mode), models::acs::mgm_assembly::request::ModeRequest::SetMode(assembly_mode),
), ),
); );
let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header); let sent_tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&request.sp_header);
@@ -304,8 +306,9 @@ fn handle_raw_tm_packet(data: &[u8]) -> anyhow::Result<()> {
} }
models::ComponentId::AcsSubsystem => todo!(), models::ComponentId::AcsSubsystem => todo!(),
models::ComponentId::AcsMgmAssembly => { models::ComponentId::AcsMgmAssembly => {
let response = let response = postcard::from_bytes::<
postcard::from_bytes::<models::mgm_assembly::response::Response>(remainder); models::acs::mgm_assembly::response::Response,
>(remainder);
log::info!( log::info!(
"Received response from MGM Assembly: {:?}", "Received response from MGM Assembly: {:?}",
response.unwrap() response.unwrap()
@@ -313,12 +316,12 @@ fn handle_raw_tm_packet(data: &[u8]) -> anyhow::Result<()> {
} }
models::ComponentId::AcsMgm0 => { models::ComponentId::AcsMgm0 => {
let response = let response =
postcard::from_bytes::<models::mgm::response::Response>(remainder); postcard::from_bytes::<models::acs::mgm::response::Response>(remainder);
log::info!("Received response from MGM0: {:?}", response.unwrap()); log::info!("Received response from MGM0: {:?}", response.unwrap());
} }
models::ComponentId::AcsMgm1 => { models::ComponentId::AcsMgm1 => {
let response = let response =
postcard::from_bytes::<models::mgm::response::Response>(remainder); postcard::from_bytes::<models::acs::mgm::response::Response>(remainder);
log::info!("Received response from MGM1: {:?}", response.unwrap()); log::info!("Received response from MGM1: {:?}", response.unwrap());
} }
models::ComponentId::EpsSubsystem => todo!(), models::ComponentId::EpsSubsystem => todo!(),
+28
View File
@@ -0,0 +1,28 @@
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Passive,
Safe,
Idle,
}
pub mod request {
use super::Mode;
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ModeRequest {
SetMode(Mode),
ReadMode,
}
}
pub mod response {
use super::Mode;
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ModeReport {
/// Mode of the assembly.
Mode(super::Mode),
/// Children are in wrong mode after commanding.
WrongMode([Option<Mode>; 2]),
}
}
@@ -42,7 +42,7 @@ pub mod request {
} }
#[derive(Default, Debug, Copy, Clone, serde::Serialize, serde::Deserialize)] #[derive(Default, Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub struct MgmData { pub struct SensorData {
pub valid: bool, pub valid: bool,
pub x: f32, pub x: f32,
pub y: f32, pub y: f32,
@@ -50,11 +50,11 @@ pub struct MgmData {
} }
pub mod response { pub mod response {
use crate::{DeviceMode, Message, mgm::MgmData}; use crate::{DeviceMode, Message, acs::mgm::SensorData};
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)] #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)]
pub enum HkResponse { pub enum HkResponse {
MgmData(MgmData), MgmData(SensorData),
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy)] #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy)]
@@ -3,7 +3,7 @@ use core::str::FromStr;
use crate::DeviceMode; use crate::DeviceMode;
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)] #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum AssemblyMode { pub enum Mode {
/// The assembly mode ressembles the modes of the devices it controls. It also tries to keep /// The assembly mode ressembles the modes of the devices it controls. It also tries to keep
/// the children in the correct mode by re-commanding them into the correct mode. /// the children in the correct mode by re-commanding them into the correct mode.
Device(DeviceMode), Device(DeviceMode),
@@ -11,22 +11,22 @@ pub enum AssemblyMode {
NoModeKeeping, NoModeKeeping,
} }
impl FromStr for AssemblyMode { impl FromStr for Mode {
type Err = (); type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() { match s.to_lowercase().as_str() {
"off" => Ok(AssemblyMode::Device(DeviceMode::Off)), "off" => Ok(Mode::Device(DeviceMode::Off)),
"on" => Ok(AssemblyMode::Device(DeviceMode::On)), "on" => Ok(Mode::Device(DeviceMode::On)),
"normal" => Ok(AssemblyMode::Device(DeviceMode::Normal)), "normal" => Ok(Mode::Device(DeviceMode::Normal)),
"no_mode_keeping" => Ok(AssemblyMode::NoModeKeeping), "no_mode_keeping" => Ok(Mode::NoModeKeeping),
_ => Err(()), _ => Err(()),
} }
} }
} }
pub mod request { pub mod request {
use crate::{HkRequestType, Message, mgm_assembly::AssemblyMode}; use crate::{HkRequestType, Message, acs::mgm_assembly::Mode};
#[derive(Debug, PartialEq, Eq, Clone, Copy, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Eq, Clone, Copy, serde::Serialize, serde::Deserialize)]
pub enum HkId { pub enum HkId {
@@ -35,7 +35,7 @@ pub mod request {
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ModeRequest { pub enum ModeRequest {
SetMode(AssemblyMode), SetMode(Mode),
ReadMode, ReadMode,
} }
@@ -77,7 +77,7 @@ pub mod response {
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ModeReport { pub enum ModeReport {
/// Mode of the assembly. /// Mode of the assembly.
Mode(super::AssemblyMode), Mode(super::Mode),
/// Timeout failure setting the children modes. /// Timeout failure setting the children modes.
SetModeTimeout([Option<DeviceMode>; 2]), SetModeTimeout([Option<DeviceMode>; 2]),
/// Children are in wrong mode after commanding. /// Children are in wrong mode after commanding.
+27
View File
@@ -0,0 +1,27 @@
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Off,
Normal,
}
pub mod request {
use super::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ModeRequest {
SetMode(Mode),
ReadMode,
}
}
pub mod response {
use super::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ModeReport {
/// Mode of the assembly.
Mode(super::Mode),
/// Children are in wrong mode after commanding.
WrongMode([Option<Mode>; 2]),
}
}
+5
View File
@@ -0,0 +1,5 @@
pub mod ctrl;
pub mod mgm;
pub mod mgm_assembly;
pub mod mgt;
pub mod subsystem;
+15
View File
@@ -0,0 +1,15 @@
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Off,
Safe,
}
impl Mode {
/// Each subsystem mode has a fallback mode to allow clean transitions.
pub const fn fallback_mode(&self) -> Self {
match self {
Mode::Off => Mode::Safe,
Mode::Safe => Mode::Safe,
}
}
}
+1 -2
View File
@@ -6,10 +6,9 @@ use spacepackets::{
time::cds::{CdsTime, MIN_CDS_FIELD_LEN}, time::cds::{CdsTime, MIN_CDS_FIELD_LEN},
}; };
pub mod acs;
pub mod ccsds; pub mod ccsds;
pub mod control; pub mod control;
pub mod mgm;
pub mod mgm_assembly;
pub mod pcdu; pub mod pcdu;
#[derive( #[derive(
+25 -21
View File
@@ -1,8 +1,8 @@
use models::mgm::MgmData; use models::acs::mgm::SensorData;
use models::mgm::request::ModeRequest; use models::acs::mgm::request::ModeRequest;
use models::mgm::response::ModeResponse; use models::acs::mgm::response::ModeResponse;
use models::pcdu::SwitchId; use models::pcdu::SwitchId;
use models::{ComponentId, DeviceMode, HkRequestType, mgm}; use models::{ComponentId, DeviceMode, HkRequestType, acs::mgm};
use satrs::spacepackets::CcsdsPacketIdAndPsc; use satrs::spacepackets::CcsdsPacketIdAndPsc;
use satrs_example::{HkHelperSingleSet, ModeHelper, TimestampHelper, TmtcQueues}; use satrs_example::{HkHelperSingleSet, ModeHelper, TimestampHelper, TmtcQueues};
use satrs_minisim::acs::MgmRequestLis3Mdl; use satrs_minisim::acs::MgmRequestLis3Mdl;
@@ -153,7 +153,7 @@ pub struct MgmHandlerLis3Mdl {
switch_helper: PowerSwitchHelper, switch_helper: PowerSwitchHelper,
tmtc_queues: TmtcQueues, tmtc_queues: TmtcQueues,
pub spi_com: SpiCommunication, pub spi_com: SpiCommunication,
shared_mgm_set: Arc<Mutex<MgmData>>, shared_mgm_set: Arc<Mutex<SensorData>>,
buffers: BufWrapper, buffers: BufWrapper,
stamp_helper: TimestampHelper, stamp_helper: TimestampHelper,
hk_helper: HkHelperSingleSet, hk_helper: HkHelperSingleSet,
@@ -167,9 +167,9 @@ impl MgmHandlerLis3Mdl {
tmtc_queues: TmtcQueues, tmtc_queues: TmtcQueues,
switch_helper: PowerSwitchHelper, switch_helper: PowerSwitchHelper,
spi_com: SpiCommunication, spi_com: SpiCommunication,
shared_mgm_set: Arc<Mutex<MgmData>>, shared_mgm_set: Arc<Mutex<SensorData>>,
mode_leaf_helper: ModeLeafHelper, mode_leaf_helper: ModeLeafHelper,
mode_timeout: Duration mode_timeout: Duration,
) -> Self { ) -> Self {
Self { Self {
id, id,
@@ -308,7 +308,7 @@ impl MgmHandlerLis3Mdl {
pub fn handle_hk_request( pub fn handle_hk_request(
&mut self, &mut self,
tc_id: Option<CcsdsPacketIdAndPsc>, tc_id: Option<CcsdsPacketIdAndPsc>,
hk_request: &models::mgm::request::HkRequest, hk_request: &models::acs::mgm::request::HkRequest,
) { ) {
match hk_request.req_type { match hk_request.req_type {
HkRequestType::OneShot => { HkRequestType::OneShot => {
@@ -462,8 +462,8 @@ mod tests {
use arbitrary_int::u11; use arbitrary_int::u11;
use models::{ use models::{
Apid, ComponentId, TcHeader, Apid, ComponentId, TcHeader,
acs::mgm::request::HkRequest,
ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned}, ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned},
mgm::request::HkRequest,
pcdu::{SwitchRequest, SwitchState, SwitchStateBinary}, pcdu::{SwitchRequest, SwitchState, SwitchStateBinary},
}; };
use satrs::{request::GenericMessage, spacepackets::SpacePacketHeader}; use satrs::{request::GenericMessage, spacepackets::SpacePacketHeader};
@@ -490,7 +490,7 @@ mod tests {
pub fn create_request_tc( pub fn create_request_tc(
select: MgmSelect, select: MgmSelect,
request: models::mgm::request::Request, request: models::acs::mgm::request::Request,
) -> models::ccsds::CcsdsTcPacketOwned { ) -> models::ccsds::CcsdsTcPacketOwned {
models::ccsds::CcsdsTcPacketOwned::new_with_request( models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
@@ -533,6 +533,7 @@ mod tests {
SpiCommunication::Test(TestSpiInterface::default()), SpiCommunication::Test(TestSpiInterface::default()),
shared_mgm_set, shared_mgm_set,
mode_leaf_helper, mode_leaf_helper,
Duration::from_millis(100),
); );
Self { Self {
assembly_mode_request_tx, assembly_mode_request_tx,
@@ -600,9 +601,10 @@ mod tests {
assert_eq!(tm_packet.tm_header.sender_id, ComponentId::AcsMgm0); assert_eq!(tm_packet.tm_header.sender_id, ComponentId::AcsMgm0);
let response = postcard::from_bytes::<models::mgm::response::Response>(&tm_packet.payload) let response =
.expect("failed to deserialize mode reply"); postcard::from_bytes::<models::acs::mgm::response::Response>(&tm_packet.payload)
matches!(response, models::mgm::response::Response::Ok); .expect("failed to deserialize mode reply");
matches!(response, models::acs::mgm::response::Response::Ok);
// The device should have been polled once. // The device should have been polled once.
assert_eq!(testbench.test_spi_interface().call_count, 1); assert_eq!(testbench.test_spi_interface().call_count, 1);
let mgm_set = *testbench.handler.shared_mgm_set.lock().unwrap(); let mgm_set = *testbench.handler.shared_mgm_set.lock().unwrap();
@@ -688,9 +690,10 @@ mod tests {
assert_eq!(tm_packet.tm_header.sender_id, ComponentId::AcsMgm0); assert_eq!(tm_packet.tm_header.sender_id, ComponentId::AcsMgm0);
let response = postcard::from_bytes::<models::mgm::response::Response>(&tm_packet.payload) let response =
.expect("failed to deserialize mode reply"); postcard::from_bytes::<models::acs::mgm::response::Response>(&tm_packet.payload)
if let models::mgm::response::Response::Hk(mgm::response::HkResponse::MgmData(data)) = .expect("failed to deserialize mode reply");
if let models::acs::mgm::response::Response::Hk(mgm::response::HkResponse::MgmData(data)) =
response response
{ {
assert_eq!(data.valid, false); assert_eq!(data.valid, false);
@@ -739,17 +742,18 @@ mod tests {
assert_eq!(mode_tm.tm_header.sender_id, ComponentId::AcsMgm0); assert_eq!(mode_tm.tm_header.sender_id, ComponentId::AcsMgm0);
let response = postcard::from_bytes::<models::mgm::response::Response>(&mode_tm.payload) let response =
.expect("failed to deserialize mode reply"); postcard::from_bytes::<models::acs::mgm::response::Response>(&mode_tm.payload)
matches!(response, models::mgm::response::Response::Ok); .expect("failed to deserialize mode reply");
matches!(response, models::acs::mgm::response::Response::Ok);
let hk_tm = testbench.tm_rx.try_recv().expect("no hk reply generated"); let hk_tm = testbench.tm_rx.try_recv().expect("no hk reply generated");
assert_eq!(hk_tm.tm_header.sender_id, ComponentId::AcsMgm0); assert_eq!(hk_tm.tm_header.sender_id, ComponentId::AcsMgm0);
let response = postcard::from_bytes::<models::mgm::response::Response>(&hk_tm.payload) let response = postcard::from_bytes::<models::acs::mgm::response::Response>(&hk_tm.payload)
.expect("failed to deserialize mode reply"); .expect("failed to deserialize mode reply");
if let models::mgm::response::Response::Hk(mgm::response::HkResponse::MgmData(data)) = if let models::acs::mgm::response::Response::Hk(mgm::response::HkResponse::MgmData(data)) =
response response
{ {
// Set is now valid. // Set is now valid.
+64 -56
View File
@@ -2,7 +2,7 @@ use std::{sync::mpsc, time::Duration};
use models::{ use models::{
ComponentId, DeviceMode, ComponentId, DeviceMode,
mgm_assembly::{AssemblyMode, request, response}, acs::mgm_assembly::{Mode, request, response},
}; };
use satrs::spacepackets::CcsdsPacketIdAndPsc; use satrs::spacepackets::CcsdsPacketIdAndPsc;
use satrs_example::{ModeHelper, TmtcQueues}; use satrs_example::{ModeHelper, TmtcQueues};
@@ -16,8 +16,8 @@ pub struct ParentQueueHelper {
/// Helper component for communication with a parent component, which is usually as assembly. /// Helper component for communication with a parent component, which is usually as assembly.
pub struct ChildrenQueueHelper { pub struct ChildrenQueueHelper {
pub request_tx_queues: [mpsc::SyncSender<models::mgm::request::ModeRequest>; 2], pub request_tx_queues: [mpsc::SyncSender<models::acs::mgm::request::ModeRequest>; 2],
pub report_rx_queues: [mpsc::Receiver<models::mgm::response::ModeResponse>; 2], pub report_rx_queues: [mpsc::Receiver<models::acs::mgm::response::ModeResponse>; 2],
} }
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
@@ -35,7 +35,7 @@ pub struct MgmInfo {
/// MGM assembly component. /// MGM assembly component.
pub struct Assembly { pub struct Assembly {
mode_helper: ModeHelper<AssemblyMode, TransitionState>, mode_helper: ModeHelper<Mode, TransitionState>,
/// This boolean is used for the distinction between transitions commanded by the parent /// This boolean is used for the distinction between transitions commanded by the parent
/// or by ground, and transitions which were commanded autonomously as part of children /// or by ground, and transitions which were commanded autonomously as part of children
/// mode keeping. /// mode keeping.
@@ -56,7 +56,7 @@ impl Assembly {
mode_timeout: Duration, mode_timeout: Duration,
) -> Self { ) -> Self {
Self { Self {
mode_helper: ModeHelper::new(AssemblyMode::NoModeKeeping, mode_timeout), mode_helper: ModeHelper::new(Mode::NoModeKeeping, mode_timeout),
mode_keeping_transition: false, mode_keeping_transition: false,
tmtc_queues, tmtc_queues,
mgm_modes: [MgmInfo::default(); 2], mgm_modes: [MgmInfo::default(); 2],
@@ -80,14 +80,14 @@ impl Assembly {
match self.tmtc_queues.tc_rx.try_recv() { match self.tmtc_queues.tc_rx.try_recv() {
Ok(packet) => { Ok(packet) => {
let tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&packet.sp_header); let tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&packet.sp_header);
match postcard::from_bytes::<models::mgm_assembly::request::Request>( match postcard::from_bytes::<models::acs::mgm_assembly::request::Request>(
&packet.payload, &packet.payload,
) { ) {
Ok(request) => match request { Ok(request) => match request {
models::mgm_assembly::request::Request::Ping => { models::acs::mgm_assembly::request::Request::Ping => {
self.send_telemetry(Some(tc_id), response::Response::Ok) self.send_telemetry(Some(tc_id), response::Response::Ok)
} }
models::mgm_assembly::request::Request::Mode(request) => { models::acs::mgm_assembly::request::Request::Mode(request) => {
match request { match request {
request::ModeRequest::SetMode(assembly_mode) => { request::ModeRequest::SetMode(assembly_mode) => {
self.start_transition(false, assembly_mode, Some(tc_id)) self.start_transition(false, assembly_mode, Some(tc_id))
@@ -117,7 +117,7 @@ impl Assembly {
pub fn send_telemetry( pub fn send_telemetry(
&self, &self,
tc_id: Option<CcsdsPacketIdAndPsc>, tc_id: Option<CcsdsPacketIdAndPsc>,
response: models::mgm_assembly::response::Response, response: models::acs::mgm_assembly::response::Response,
) { ) {
match pack_ccsds_tm_packet_for_now(Self::ID, tc_id, &response) { match pack_ccsds_tm_packet_for_now(Self::ID, tc_id, &response) {
Ok(packet) => { Ok(packet) => {
@@ -136,11 +136,11 @@ impl Assembly {
match self.parent_queues.request_rx.try_recv() { match self.parent_queues.request_rx.try_recv() {
Ok(request) => match request { Ok(request) => match request {
request::ModeRequest::SetMode(assembly_mode) => match assembly_mode { request::ModeRequest::SetMode(assembly_mode) => match assembly_mode {
AssemblyMode::Device(_device_mode) => { Mode::Device(_device_mode) => {
self.start_transition(false, assembly_mode, None); self.start_transition(false, assembly_mode, None);
} }
AssemblyMode::NoModeKeeping => { Mode::NoModeKeeping => {
self.mode_helper.current = AssemblyMode::NoModeKeeping; self.mode_helper.current = Mode::NoModeKeeping;
} }
}, },
request::ModeRequest::ReadMode => self request::ModeRequest::ReadMode => self
@@ -165,12 +165,12 @@ impl Assembly {
loop { loop {
match rx.try_recv() { match rx.try_recv() {
Ok(report) => match report { Ok(report) => match report {
models::mgm::response::ModeResponse::Mode(device_mode) => { models::acs::mgm::response::ModeResponse::Mode(device_mode) => {
self.mgm_modes[idx].mode = Some(device_mode); self.mgm_modes[idx].mode = Some(device_mode);
self.mgm_modes[idx].reply_received = true; self.mgm_modes[idx].reply_received = true;
mode_report_received = true; mode_report_received = true;
} }
models::mgm::response::ModeResponse::SetModeTimeout => { models::acs::mgm::response::ModeResponse::SetModeTimeout => {
// Ignore, handle this with our own timeout. // Ignore, handle this with our own timeout.
log::warn!("MGM {} mode timeout", idx); log::warn!("MGM {} mode timeout", idx);
} }
@@ -191,7 +191,7 @@ impl Assembly {
// Transition is active, check for completion. // Transition is active, check for completion.
if self.mode_helper.transition_active() if self.mode_helper.transition_active()
&& self.mgm_modes.iter().all(|i| i.reply_received) && self.mgm_modes.iter().all(|i| i.reply_received)
&& let AssemblyMode::Device(device_mode) = self.mode_helper.target.unwrap() && let Mode::Device(device_mode) = self.mode_helper.target.unwrap()
{ {
// If at least one child reached the correct mode, we are done. // If at least one child reached the correct mode, we are done.
if self.mgm_modes.iter().any(|i| i.mode == Some(device_mode)) { if self.mgm_modes.iter().any(|i| i.mode == Some(device_mode)) {
@@ -207,7 +207,7 @@ impl Assembly {
} }
// Mode keeping active: Check children modes. // Mode keeping active: Check children modes.
if let AssemblyMode::Device(device_mode) = self.mode_helper.current if let Mode::Device(device_mode) = self.mode_helper.current
&& self && self
.mgm_modes .mgm_modes
.iter() .iter()
@@ -226,8 +226,8 @@ impl Assembly {
} }
let target = self.mode_helper.target.unwrap(); let target = self.mode_helper.target.unwrap();
let device_mode = match target { let device_mode = match target {
AssemblyMode::Device(device_mode) => device_mode, Mode::Device(device_mode) => device_mode,
AssemblyMode::NoModeKeeping => { Mode::NoModeKeeping => {
self.handle_mode_reached(true); self.handle_mode_reached(true);
return; return;
} }
@@ -275,7 +275,7 @@ impl Assembly {
pub fn command_children(&self, mode: DeviceMode) { pub fn command_children(&self, mode: DeviceMode) {
for tx in &self.children_queues.request_tx_queues { for tx in &self.children_queues.request_tx_queues {
tx.send(models::mgm::request::ModeRequest::SetMode(mode)) tx.send(models::acs::mgm::request::ModeRequest::SetMode(mode))
.unwrap(); .unwrap();
} }
} }
@@ -283,7 +283,7 @@ impl Assembly {
pub fn start_transition( pub fn start_transition(
&mut self, &mut self,
mode_keeping: bool, mode_keeping: bool,
target: AssemblyMode, target: Mode,
tc_id: Option<CcsdsPacketIdAndPsc>, tc_id: Option<CcsdsPacketIdAndPsc>,
) { ) {
self.mode_keeping_transition = mode_keeping; self.mode_keeping_transition = mode_keeping;
@@ -304,7 +304,7 @@ impl Assembly {
} }
#[inline] #[inline]
pub fn mode(&self) -> AssemblyMode { pub fn mode(&self) -> Mode {
self.mode_helper.current self.mode_helper.current
} }
@@ -322,8 +322,8 @@ mod tests {
use arbitrary_int::u11; use arbitrary_int::u11;
use models::{ use models::{
Apid, Message, MessageType, TcHeader, Apid, Message, MessageType, TcHeader,
acs::mgm_assembly,
ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned}, ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned},
mgm_assembly,
}; };
use satrs::spacepackets::SpacePacketHeader; use satrs::spacepackets::SpacePacketHeader;
@@ -332,8 +332,8 @@ mod tests {
pub struct Testbench { pub struct Testbench {
subsystem_req_tx: mpsc::SyncSender<request::ModeRequest>, subsystem_req_tx: mpsc::SyncSender<request::ModeRequest>,
subsystem_report_rx: mpsc::Receiver<response::ModeReport>, subsystem_report_rx: mpsc::Receiver<response::ModeReport>,
mgm_request_rx: [mpsc::Receiver<models::mgm::request::ModeRequest>; 2], mgm_request_rx: [mpsc::Receiver<models::acs::mgm::request::ModeRequest>; 2],
mgm_report_tx: [mpsc::SyncSender<models::mgm::response::ModeResponse>; 2], mgm_report_tx: [mpsc::SyncSender<models::acs::mgm::response::ModeResponse>; 2],
tc_tx: mpsc::SyncSender<CcsdsTcPacketOwned>, tc_tx: mpsc::SyncSender<CcsdsTcPacketOwned>,
tm_rx: mpsc::Receiver<CcsdsTmPacketOwned>, tm_rx: mpsc::Receiver<CcsdsTmPacketOwned>,
assembly: Assembly, assembly: Assembly,
@@ -396,7 +396,7 @@ mod tests {
} }
pub fn create_request_tc( pub fn create_request_tc(
request: models::mgm_assembly::request::Request, request: models::acs::mgm_assembly::request::Request,
) -> models::ccsds::CcsdsTcPacketOwned { ) -> models::ccsds::CcsdsTcPacketOwned {
models::ccsds::CcsdsTcPacketOwned::new_with_request( models::ccsds::CcsdsTcPacketOwned::new_with_request(
SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)), SpacePacketHeader::new_from_apid(u11::new(Apid::Acs as u16)),
@@ -411,7 +411,7 @@ mod tests {
tb.assert_all_queues_empty(); tb.assert_all_queues_empty();
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
tb.assert_all_queues_empty(); tb.assert_all_queues_empty();
assert_eq!(tb.assembly.mode(), AssemblyMode::NoModeKeeping); assert_eq!(tb.assembly.mode(), Mode::NoModeKeeping);
} }
#[test] #[test]
@@ -419,7 +419,7 @@ mod tests {
let mut tb = Testbench::new(); let mut tb = Testbench::new();
tb.tc_tx tb.tc_tx
.send(create_request_tc(mgm_assembly::request::Request::Mode( .send(create_request_tc(mgm_assembly::request::Request::Mode(
request::ModeRequest::SetMode(AssemblyMode::Device(DeviceMode::Normal)), request::ModeRequest::SetMode(Mode::Device(DeviceMode::Normal)),
))) )))
.unwrap(); .unwrap();
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
@@ -429,13 +429,13 @@ mod tests {
let request = rx.try_recv().unwrap(); let request = rx.try_recv().unwrap();
assert_eq!( assert_eq!(
request, request,
models::mgm::request::ModeRequest::SetMode(DeviceMode::Normal) models::acs::mgm::request::ModeRequest::SetMode(DeviceMode::Normal)
); );
} }
// Confirm the mode is set. // Confirm the mode is set.
for tx in tb.mgm_report_tx.iter() { for tx in tb.mgm_report_tx.iter() {
tx.send(models::mgm::response::ModeResponse::Mode( tx.send(models::acs::mgm::response::ModeResponse::Mode(
DeviceMode::Normal, DeviceMode::Normal,
)) ))
.unwrap(); .unwrap();
@@ -443,7 +443,7 @@ mod tests {
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
assert!(!tb.assembly.mode_transition_active()); assert!(!tb.assembly.mode_transition_active());
assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal));
let response = tb.tm_rx.try_recv().unwrap(); let response = tb.tm_rx.try_recv().unwrap();
assert_eq!(response.tm_header.sender_id, Assembly::ID); assert_eq!(response.tm_header.sender_id, Assembly::ID);
@@ -456,7 +456,7 @@ mod tests {
fn test_parent_commanded_transition() { fn test_parent_commanded_transition() {
let mut tb = Testbench::new(); let mut tb = Testbench::new();
tb.subsystem_req_tx tb.subsystem_req_tx
.send(request::ModeRequest::SetMode(AssemblyMode::Device( .send(request::ModeRequest::SetMode(Mode::Device(
DeviceMode::Normal, DeviceMode::Normal,
))) )))
.unwrap(); .unwrap();
@@ -467,13 +467,13 @@ mod tests {
let request = rx.try_recv().unwrap(); let request = rx.try_recv().unwrap();
assert_eq!( assert_eq!(
request, request,
models::mgm::request::ModeRequest::SetMode(DeviceMode::Normal) models::acs::mgm::request::ModeRequest::SetMode(DeviceMode::Normal)
); );
} }
// Confirm the mode is set. // Confirm the mode is set.
for tx in tb.mgm_report_tx.iter() { for tx in tb.mgm_report_tx.iter() {
tx.send(models::mgm::response::ModeResponse::Mode( tx.send(models::acs::mgm::response::ModeResponse::Mode(
DeviceMode::Normal, DeviceMode::Normal,
)) ))
.unwrap(); .unwrap();
@@ -481,12 +481,12 @@ mod tests {
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
assert!(!tb.assembly.mode_transition_active()); assert!(!tb.assembly.mode_transition_active());
assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal));
let report = tb.subsystem_report_rx.try_recv().unwrap(); let report = tb.subsystem_report_rx.try_recv().unwrap();
assert_eq!( assert_eq!(
report, report,
response::ModeReport::Mode(AssemblyMode::Device(DeviceMode::Normal)) response::ModeReport::Mode(Mode::Device(DeviceMode::Normal))
); );
} }
@@ -494,7 +494,7 @@ mod tests {
fn test_one_mgm_is_sufficient() { fn test_one_mgm_is_sufficient() {
let mut tb = Testbench::new(); let mut tb = Testbench::new();
tb.subsystem_req_tx tb.subsystem_req_tx
.send(request::ModeRequest::SetMode(AssemblyMode::Device( .send(request::ModeRequest::SetMode(Mode::Device(
DeviceMode::Normal, DeviceMode::Normal,
))) )))
.unwrap(); .unwrap();
@@ -505,28 +505,30 @@ mod tests {
let request = rx.try_recv().unwrap(); let request = rx.try_recv().unwrap();
assert_eq!( assert_eq!(
request, request,
models::mgm::request::ModeRequest::SetMode(DeviceMode::Normal) models::acs::mgm::request::ModeRequest::SetMode(DeviceMode::Normal)
); );
} }
// One device is sufficient. // One device is sufficient.
tb.mgm_report_tx[0] tb.mgm_report_tx[0]
.send(models::mgm::response::ModeResponse::Mode( .send(models::acs::mgm::response::ModeResponse::Mode(
DeviceMode::Normal, DeviceMode::Normal,
)) ))
.unwrap(); .unwrap();
tb.mgm_report_tx[1] tb.mgm_report_tx[1]
.send(models::mgm::response::ModeResponse::Mode(DeviceMode::Off)) .send(models::acs::mgm::response::ModeResponse::Mode(
DeviceMode::Off,
))
.unwrap(); .unwrap();
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
assert!(!tb.assembly.mode_transition_active()); assert!(!tb.assembly.mode_transition_active());
assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal));
let report = tb.subsystem_report_rx.try_recv().unwrap(); let report = tb.subsystem_report_rx.try_recv().unwrap();
assert_eq!( assert_eq!(
report, report,
response::ModeReport::Mode(AssemblyMode::Device(DeviceMode::Normal)) response::ModeReport::Mode(Mode::Device(DeviceMode::Normal))
); );
} }
@@ -534,7 +536,7 @@ mod tests {
fn test_mode_commanding_fails() { fn test_mode_commanding_fails() {
let mut tb = Testbench::new(); let mut tb = Testbench::new();
tb.subsystem_req_tx tb.subsystem_req_tx
.send(request::ModeRequest::SetMode(AssemblyMode::Device( .send(request::ModeRequest::SetMode(Mode::Device(
DeviceMode::Normal, DeviceMode::Normal,
))) )))
.unwrap(); .unwrap();
@@ -545,19 +547,21 @@ mod tests {
let request = rx.try_recv().unwrap(); let request = rx.try_recv().unwrap();
assert_eq!( assert_eq!(
request, request,
models::mgm::request::ModeRequest::SetMode(DeviceMode::Normal) models::acs::mgm::request::ModeRequest::SetMode(DeviceMode::Normal)
); );
} }
// Confirm the mode is set. // Confirm the mode is set.
for tx in tb.mgm_report_tx.iter() { for tx in tb.mgm_report_tx.iter() {
tx.send(models::mgm::response::ModeResponse::Mode(DeviceMode::Off)) tx.send(models::acs::mgm::response::ModeResponse::Mode(
.unwrap(); DeviceMode::Off,
))
.unwrap();
} }
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
assert!(!tb.assembly.mode_transition_active()); assert!(!tb.assembly.mode_transition_active());
assert_eq!(tb.assembly.mode(), AssemblyMode::NoModeKeeping); assert_eq!(tb.assembly.mode(), Mode::NoModeKeeping);
let report = tb.subsystem_report_rx.try_recv().unwrap(); let report = tb.subsystem_report_rx.try_recv().unwrap();
assert_eq!( assert_eq!(
@@ -570,7 +574,7 @@ mod tests {
fn test_mode_keeping_fails() { fn test_mode_keeping_fails() {
let mut tb = Testbench::new(); let mut tb = Testbench::new();
tb.subsystem_req_tx tb.subsystem_req_tx
.send(request::ModeRequest::SetMode(AssemblyMode::Device( .send(request::ModeRequest::SetMode(Mode::Device(
DeviceMode::Normal, DeviceMode::Normal,
))) )))
.unwrap(); .unwrap();
@@ -581,13 +585,13 @@ mod tests {
let request = rx.try_recv().unwrap(); let request = rx.try_recv().unwrap();
assert_eq!( assert_eq!(
request, request,
models::mgm::request::ModeRequest::SetMode(DeviceMode::Normal) models::acs::mgm::request::ModeRequest::SetMode(DeviceMode::Normal)
); );
} }
// Confirm the mode is set. // Confirm the mode is set.
for tx in tb.mgm_report_tx.iter() { for tx in tb.mgm_report_tx.iter() {
tx.send(models::mgm::response::ModeResponse::Mode( tx.send(models::acs::mgm::response::ModeResponse::Mode(
DeviceMode::Normal, DeviceMode::Normal,
)) ))
.unwrap(); .unwrap();
@@ -595,17 +599,19 @@ mod tests {
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
assert!(!tb.assembly.mode_transition_active()); assert!(!tb.assembly.mode_transition_active());
assert_eq!(tb.assembly.mode(), AssemblyMode::Device(DeviceMode::Normal)); assert_eq!(tb.assembly.mode(), Mode::Device(DeviceMode::Normal));
let report = tb.subsystem_report_rx.try_recv().unwrap(); let report = tb.subsystem_report_rx.try_recv().unwrap();
assert_eq!( assert_eq!(
report, report,
response::ModeReport::Mode(AssemblyMode::Device(DeviceMode::Normal)) response::ModeReport::Mode(Mode::Device(DeviceMode::Normal))
); );
for tx in tb.mgm_report_tx.iter() { for tx in tb.mgm_report_tx.iter() {
tx.send(models::mgm::response::ModeResponse::Mode(DeviceMode::Off)) tx.send(models::acs::mgm::response::ModeResponse::Mode(
.unwrap(); DeviceMode::Off,
))
.unwrap();
} }
// This should start mode keeping. // This should start mode keeping.
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
@@ -615,14 +621,16 @@ mod tests {
let request = rx.try_recv().unwrap(); let request = rx.try_recv().unwrap();
assert_eq!( assert_eq!(
request, request,
models::mgm::request::ModeRequest::SetMode(DeviceMode::Normal) models::acs::mgm::request::ModeRequest::SetMode(DeviceMode::Normal)
); );
} }
// Let the mode keeping fail. // Let the mode keeping fail.
for tx in tb.mgm_report_tx.iter() { for tx in tb.mgm_report_tx.iter() {
tx.send(models::mgm::response::ModeResponse::Mode(DeviceMode::Off)) tx.send(models::acs::mgm::response::ModeResponse::Mode(
.unwrap(); DeviceMode::Off,
))
.unwrap();
} }
tb.assembly.periodic_operation(); tb.assembly.periodic_operation();
let report = tb.subsystem_report_rx.try_recv().unwrap(); let report = tb.subsystem_report_rx.try_recv().unwrap();
+1
View File
@@ -0,0 +1 @@
+1 -2
View File
@@ -1,6 +1,5 @@
pub mod ctrl; pub mod ctrl;
pub mod mgm; pub mod mgm;
pub mod mgm_assembly; pub mod mgm_assembly;
pub mod mgt;
pub mod subsystem; pub mod subsystem;
+116 -1
View File
@@ -1 +1,116 @@
// TODO: Write subsystem use std::sync::mpsc::SyncSender;
use models::ComponentId;
#[derive(Debug)]
pub struct TransitionInfo {
check_mode_reached: bool,
}
#[derive(Debug)]
pub struct ChildModes {
mgm_assembly_mode: models::acs::mgm_assembly::Mode,
mgt_mode: models::acs::mgt::Mode,
controller_mode: models::acs::ctrl::Mode,
}
#[derive(Debug)]
pub struct TransitionCommands {
mgm_assembly_mode: Option<(models::acs::mgm_assembly::Mode, TransitionInfo)>,
mgt_mode: Option<(models::acs::mgt::Mode, TransitionInfo)>,
controller_mode: Option<(models::acs::ctrl::Mode, TransitionInfo)>,
}
const OFF_SEQUENCE: [TransitionCommands; 2] = [
TransitionCommands {
mgm_assembly_mode: None,
mgt_mode: None,
controller_mode: Some((
models::acs::ctrl::Mode::Passive,
TransitionInfo {
check_mode_reached: true,
},
)),
},
TransitionCommands {
mgm_assembly_mode: Some((
models::acs::mgm_assembly::Mode::Device(models::DeviceMode::Off),
TransitionInfo {
check_mode_reached: false,
},
)),
mgt_mode: Some((
models::acs::mgt::Mode::Off,
TransitionInfo {
check_mode_reached: false,
},
)),
controller_mode: None,
},
];
const SAFE_SEQUENCE: [TransitionCommands; 2] = [
TransitionCommands {
mgm_assembly_mode: Some((
models::acs::mgm_assembly::Mode::Device(models::DeviceMode::Normal),
TransitionInfo {
check_mode_reached: false,
},
)),
mgt_mode: Some((
models::acs::mgt::Mode::Normal,
TransitionInfo {
check_mode_reached: false,
},
)),
controller_mode: None,
},
TransitionCommands {
mgm_assembly_mode: None,
mgt_mode: None,
controller_mode: Some((
models::acs::ctrl::Mode::Safe,
TransitionInfo {
check_mode_reached: false,
},
)),
},
];
#[derive(Debug)]
pub struct ModeRequestSenders {
mode_request_ctrl: SyncSender<models::acs::ctrl::request::ModeRequest>,
mode_request_assy: SyncSender<models::acs::mgm_assembly::request::ModeRequest>,
mode_request_mgt: SyncSender<models::acs::mgt::request::ModeRequest>,
}
#[derive(Debug)]
pub struct ModeReportReceivers {
mode_response_ctrl: SyncSender<models::acs::ctrl::response::ModeReport>,
mode_response_assy: SyncSender<models::acs::mgm_assembly::response::ModeReport>,
mode_response_mgt: SyncSender<models::acs::mgt::response::ModeReport>,
}
#[derive(Debug)]
pub struct Subsystem {
current_mode: models::acs::subsystem::Mode,
current_child_modes: Option<ChildModes>,
mode_request_senders: ModeRequestSenders,
mode_report_receivers: ModeReportReceivers,
}
impl Subsystem {
pub const ID: ComponentId = ComponentId::AcsSubsystem;
pub fn new(
mode_request_senders: ModeRequestSenders,
mode_report_receivers: ModeReportReceivers,
) -> Self {
Self {
current_mode: models::acs::subsystem::Mode::Off,
current_child_modes: None,
mode_request_senders,
mode_report_receivers,
}
}
}
+2 -2
View File
@@ -188,7 +188,7 @@ fn main() {
request_rx: mgm_0_mode_request_rx, request_rx: mgm_0_mode_request_rx,
report_tx: mgm_0_mode_report_tx, report_tx: mgm_0_mode_report_tx,
}, },
Duration::from_millis(1000) Duration::from_millis(1000),
); );
let mut mgm_1_handler = mgm::MgmHandlerLis3Mdl::new( let mut mgm_1_handler = mgm::MgmHandlerLis3Mdl::new(
mgm::MgmId::_1, mgm::MgmId::_1,
@@ -203,7 +203,7 @@ fn main() {
request_rx: mgm_1_mode_request_rx, request_rx: mgm_1_mode_request_rx,
report_tx: mgm_1_mode_report_tx, report_tx: mgm_1_mode_report_tx,
}, },
Duration::from_millis(1000) Duration::from_millis(1000),
); );
let mut mgm_assembly = mgm_assembly::Assembly::new( let mut mgm_assembly = mgm_assembly::Assembly::new(
mgm_assembly::ParentQueueHelper { mgm_assembly::ParentQueueHelper {