Compare commits
639 Commits
Author | SHA1 | Date | |
---|---|---|---|
3da8c781b9 | |||
5f08ca5408 | |||
88cb0d3382 | |||
1e52c05150 | |||
17db795475 | |||
4ed7689956 | |||
7ceb81f68d | |||
6fa53e1869 | |||
54328ff357 | |||
c43d9a5a9a | |||
277a6ad33c | |||
b655c03564 | |||
49e15de08a | |||
6ef8c62aca | |||
695a663a15 | |||
94cf42fbeb | |||
fe1e236466 | |||
861ad9e62d | |||
5e4032032f | |||
3a137762f3 | |||
92a0752e18 | |||
6ed2fcd904 | |||
2c17aff124 | |||
3ee9a914cc | |||
7a119bab6e | |||
147c39d539 | |||
dcf01d822b | |||
a660d1d30a | |||
0732218249 | |||
4b0062e3b2 | |||
b2a666d432 | |||
7cc13d2024 | |||
0872fad7dc
|
|||
a87a01d072 | |||
73d7f0a1e5 | |||
c3679f044c | |||
68f84e71ff | |||
f2f33f5049 | |||
3314d07942 | |||
4155aa8776 | |||
86d22affe2 | |||
df4205c71e | |||
e130d45f0b | |||
3dbc01bd8a | |||
51a3a2f5cf | |||
cada6e0440 | |||
07ca95205d | |||
b56f2b4b0e | |||
05738d1e25 | |||
12bc9268f7
|
|||
a05a8ffb50
|
|||
cf875f7883 | |||
4bef1bd567 | |||
885fddd45f | |||
fab4cdd0dc | |||
693e11bcb2 | |||
9196b8b0ed | |||
65815e4646 | |||
57ecfadf43 | |||
71d417710e | |||
a66b503e57 | |||
88f3d92dd8 | |||
26199e7317 | |||
620dc60342 | |||
38305e723f | |||
cb879ea97f | |||
f58f4c302c | |||
fdf3657cf6 | |||
20e920cde2
|
|||
3fdd1feb94
|
|||
a4391c0515
|
|||
1acb7d2679 | |||
ef40391c09 | |||
407901d990
|
|||
7132b0c53f
|
|||
df13fc2e80
|
|||
8adbbf50b2 | |||
962c792679 | |||
c44d8e6437 | |||
4146050807
|
|||
bd2f1bf7f2 | |||
020daf9a77 | |||
e3ae6260ad
|
|||
45b9e88915
|
|||
9cd38a33d4
|
|||
9740435d65 | |||
b2535662e6 | |||
1cf318fca1 | |||
171d4976c3
|
|||
e13fee75d0
|
|||
8e1af9cfba
|
|||
cd6b7d90be
|
|||
3bdbc67e0d
|
|||
fe1cc9444d
|
|||
019d1a7b0d
|
|||
1453b2abdc
|
|||
fe70d2e047 | |||
900cb060e4 | |||
bd7f28152a
|
|||
9ec3eca10a | |||
4212fbef02 | |||
6c1dfafb2e
|
|||
18ba3a711a
|
|||
c1f8512b01
|
|||
c14bbe4a93 | |||
0e171997d7 | |||
e08a2b76b9 | |||
6ef593d8f3
|
|||
08e7a8cf97
|
|||
d90ccd62f8
|
|||
cab20a8c77 | |||
6fdd9da2a0 | |||
410fd1c425 | |||
deb154770d | |||
dcf3b1b1fe | |||
06c5344d8a | |||
26ed774806 | |||
06b381d965 | |||
4bcfb8f5a2 | |||
5ca96b2dd3 | |||
9aec8960b9 | |||
de35764ede | |||
376c359d6e | |||
a110bf32aa | |||
f4c9a4bda2 | |||
7fc934b9df | |||
7dbe69ef49 | |||
72b5567f73 | |||
6a2d5b8161 | |||
7d1b99c3f4 | |||
8bfacbd5ef | |||
8052734028 | |||
b7eb693295 | |||
e96163f2a5 | |||
d4b44962f5 | |||
58dee642a6 | |||
a5f9bb3177 | |||
939eeb09ec | |||
a1fec93b25 | |||
3be495fc30 | |||
73981006a2 | |||
5a60558354 | |||
6915f0e003 | |||
a58f51ee91 | |||
099eb488ae | |||
c64ea7f7e6 | |||
487b6bf690 | |||
bd15d7b0e2 | |||
f8d9925785 | |||
4aca7a91e3 | |||
0fe7b256ec | |||
c6664c5cbf | |||
3750f1ac57 | |||
bfa0a0707c | |||
ffe419e1ab | |||
7b38ee3ecc | |||
f93e299296 | |||
ec8e8533d6 | |||
170cb4d99c | |||
f4523c8396 | |||
23625b2496 | |||
df69515bd4 | |||
0aa617d440 | |||
1f4880ddec | |||
6aa856563e | |||
ebf5609680 | |||
5abcb31e22 | |||
d400a71626 | |||
7811a4cc6b | |||
b135e2f6a1 | |||
c5640c9fca | |||
fe34f69abe | |||
899b19f34f | |||
faeece7210 | |||
ada77ed53b | |||
71eca867ea | |||
a7c6cd017d | |||
335394b863 | |||
de18ebfbe0 | |||
93cf6bab01 | |||
5afe22bc92 | |||
2ff1c0d9d5 | |||
a6787538f2 | |||
db79e34d3b | |||
d22f948af4 | |||
e1aff4c641
|
|||
8d041c6753
|
|||
276501c504
|
|||
65223ad3c7 | |||
075c750e4a | |||
04f5011e0f | |||
832140935f | |||
86bc6c4e0e | |||
31e24e297f | |||
4dacca6df1 | |||
ce9d00a42a | |||
6e4d4cea95 | |||
3641dc3bfa | |||
b899bad0a8 | |||
9e0989915c | |||
758f2b9d7a | |||
46dd662145 | |||
8f4bba6fd1 | |||
a38f5c78ae | |||
dc36513efa | |||
ee0646caf1 | |||
a831ec7bda | |||
efa9c42345 | |||
a0b1ac3d06 | |||
30bb2da570 | |||
c45f267e94 | |||
13fdaf731c | |||
d7a35d9818 | |||
266abad3b3 | |||
042b8fb3c3 | |||
303df55a12 | |||
28beb006b2 | |||
6bfb0d4fb0 | |||
7ac2271eab | |||
631a1aec42 | |||
7eeece6934 | |||
04571bbd7a | |||
32a4aa48d9 | |||
62ae7ff482 | |||
5390e947ca | |||
9ff154cedc | |||
72b5c7d053 | |||
d23082283d | |||
cd514e8125 | |||
fa4a40da6e | |||
a814746c53 | |||
ed74367f01 | |||
3f37c52f67 | |||
a0e305fe1f
|
|||
d28bc3f74d
|
|||
b9afeb9c19
|
|||
7f115303ae
|
|||
e03df2ebca
|
|||
f9e8dc6e60 | |||
0179c04472 | |||
c3b6b0a7ee | |||
90b7f069dc | |||
4ba9ebf58f | |||
468fa01650 | |||
b39e448ab5
|
|||
8ed3bdc95c | |||
04b9ed4504 | |||
ab6a0c3e4d | |||
78972cd173 | |||
c8ed7fe20e | |||
5ce0a60184 | |||
fabc6da562 | |||
17df79b0d6 | |||
178a2183a2 | |||
ae6b5b491b | |||
f099cd7688 | |||
9fde16c912 | |||
770697d5d0 | |||
af77d083fa | |||
9b1ab3eb75 | |||
edf792c4fe
|
|||
a718d182fc
|
|||
714e2d07e5
|
|||
4887dc9e6b
|
|||
3dc096c42b
|
|||
ac73e6d2c3
|
|||
edda42cb61
|
|||
9887359e31
|
|||
1f9c9e2407
|
|||
07d9ab0dd9
|
|||
a3b119fda6
|
|||
86241a0052
|
|||
9715612e46
|
|||
90d289f56e
|
|||
9391949369
|
|||
2b999e7fa7
|
|||
699fc9a861
|
|||
66c9a5eea3
|
|||
af20a36634
|
|||
ba060be0d6
|
|||
a2217b0e64 | |||
f71a363385 | |||
42152ab711 | |||
1820dae3d4
|
|||
c9121c5214 | |||
f079818c42 | |||
29eb0e736f
|
|||
412aaf93bd | |||
0156533385
|
|||
cbf3315e16
|
|||
50d5180076 | |||
92fd1548cb | |||
dbdcf0b0d6 | |||
bacc46a8dc | |||
0fb07fd3d5 | |||
98a858876a | |||
d4fc95ed9f | |||
2e00e10e09 | |||
4a3af32a65 | |||
66ca156ab3 | |||
d67414e829 | |||
0fd18204bf | |||
f225d9a7c1 | |||
9b5fac828b | |||
07dd84ff1e | |||
d5a6feb347 | |||
5728d916ef | |||
e762cc5fb3 | |||
119b1c8eb9 | |||
f72c797f53 | |||
71ef1edb68 | |||
98ef38f3eb | |||
827419ef34 | |||
5b4261104e | |||
ff175170aa | |||
e4431d20c4 | |||
119afe6148 | |||
ff47fafdc2 | |||
0a109e552d | |||
fa13703394 | |||
09ece30304 | |||
c3604085c2 | |||
1274993428 | |||
a7ccfae04e | |||
2c9da6a1e4 | |||
2b36195dac | |||
758ed22b08 | |||
30fba0456b | |||
98e69b9a6a | |||
531f87cd76 | |||
3a0db9c9ad | |||
c8d1ce40ba | |||
32d2ad8f1d | |||
b34767c870 | |||
97567736fb | |||
621a6fd401 | |||
04b6c7006e | |||
8a65aca7b8 | |||
e3dc39a028 | |||
8bb97f5f44 | |||
83a373859d | |||
52acb3373e | |||
ad32eee70a | |||
db3dc80756 | |||
65c59352e9 | |||
722a4208d4 | |||
db63757c0c | |||
5a9da1a99c | |||
a71be232ac | |||
4e428e6353 | |||
6705ede2fc | |||
0ff7e0f97a | |||
e04313b9f3 | |||
1166c66c8c | |||
e78d458f06 | |||
4f6f12217c | |||
ef039c47b8 | |||
d4b7411de1 | |||
2e6a93c479 | |||
f3a651602b | |||
6c00404ca7 | |||
1412dd4fb6 | |||
1602d5d318 | |||
1870bf6405 | |||
51b0d897a1 | |||
670c753a75 | |||
26e48f2f46 | |||
a352f25029 | |||
141438bd24 | |||
f5e20db03f | |||
1cbb7d0af8 | |||
09ffcc8804 | |||
fb062bb4e8 | |||
2f58ca8534 | |||
5747f73dfe | |||
67c0a3b03e | |||
490790bd0c | |||
7dfc7dc8c1 | |||
aa63bd1fa5 | |||
b7383294c9 | |||
e31a95d1c4 | |||
3e9933c7ee | |||
ee3ef042cd | |||
05b0efe851 | |||
8ade378a69 | |||
045d149946 | |||
a75f9553be | |||
f271242d66 | |||
1756b5edcc | |||
9c1fc44c60 | |||
f46a705900 | |||
9183d18acc | |||
befa84a74b | |||
432b400835 | |||
0eb6b7cccb | |||
74ee291983 | |||
a146c34140 | |||
61ced11766 | |||
468fb096c9 | |||
4a2dd19a73 | |||
2658cabc9d | |||
dc83061f80 | |||
00da51b6a2 | |||
f846a18b33 | |||
ab588b4844 | |||
d12dca183d | |||
701ecbd182 | |||
bdd2b23ec3 | |||
d70245b56a | |||
9097a3f3c7 | |||
e05d9d4b2a | |||
07572ab3a0 | |||
304aabc336 | |||
07e8f95a31 | |||
babea226ab | |||
8c24a7310d | |||
8f5982fd72 | |||
611a2c0b45 | |||
61e6b09704 | |||
a9a0266a84 | |||
b7e6315be7 | |||
740275f57a | |||
58dd53def8 | |||
ddbe30f832 | |||
680d496b28 | |||
9c163419b2 | |||
f4fedd20c9 | |||
016fab105e | |||
767a0eda30 | |||
f2c71d962a | |||
7bf880a29f | |||
0185691dba | |||
9997aa5470 | |||
c1ccfe66eb | |||
ae9f43c707 | |||
143002de48 | |||
d439aedee7 | |||
b8d010cd39 | |||
22370e3e1e | |||
b98f91f6c1 | |||
b47bda8ed1 | |||
078a04b317 | |||
d24a983985 | |||
b964b03b2d | |||
f0d55f9e5b | |||
aa54dbbd10 | |||
1a62a13d97 | |||
500b3b6fc6 | |||
fa746f910d | |||
602c635967 | |||
84db92f75e | |||
4de71062af | |||
a4c8319cec | |||
379fd6046e | |||
aa800c4524 | |||
7f1fe3a2d8 | |||
e023220be4 | |||
8cf9dd9136 | |||
62d18826f1 | |||
41f762c6ff | |||
644a768778 | |||
756ea6d90d | |||
2d19d94d09 | |||
09a2ba7843 | |||
716f2b2832 | |||
6934721a42 | |||
fc8a8ce5a9 | |||
5e53795cbe | |||
2f2d1c7c7a | |||
f7be454dae | |||
ca30fed4c3 | |||
54f742bf19 | |||
4bfd675073 | |||
36420a6855 | |||
b0a2b5886f | |||
33d60ccf7f | |||
c8472f222c | |||
e68ac9cc2d | |||
a306b2a0af | |||
f112c28391 | |||
4693407b68 | |||
4e6b3ec9ed | |||
38b9a9b34e | |||
7c67648b8e | |||
9b1d4de9c5 | |||
998f93e3fa | |||
b5e1e0c31b | |||
9a65a9f20b | |||
b2a52b0bfc | |||
46862825ec | |||
dc1e51891e | |||
213dba1e75 | |||
4e686b4ad0 | |||
1e521f0575 | |||
53cccc3c13 | |||
a7c227f8ea | |||
bc6531f7a5 | |||
e17b8d2ec4 | |||
f645b97ba3 | |||
e79e13416e | |||
33773179a7 | |||
c5b26eade4 | |||
28eaf8461a | |||
6f67bd500b | |||
af354bd9fb | |||
aa746276ae | |||
3e3ac9f5be | |||
ae66820b52 | |||
93013d18ff | |||
7f3f99c6aa | |||
600d0c580d | |||
2722e471ef | |||
d8089489c4 | |||
cebe6e1423 | |||
906aedc911 | |||
97df53554e | |||
a81e939e70 | |||
b5f4b6cf7b | |||
f14677ec4e | |||
29dc684455 | |||
3ff8c6a481 | |||
f7bc052070 | |||
9861772c38 | |||
d4080fe5cb | |||
6b976f1046 | |||
673826b131 | |||
ae729337a2 | |||
a09cc86336 | |||
8620bd0283 | |||
ea606ce217 | |||
99305846f8 | |||
dd211cdf54 | |||
2262a15e35 | |||
94431cfdb8 | |||
41ec6dc0f2 | |||
836ce9a6cd | |||
ae80eac9a2 | |||
e063a7148a | |||
2808079444 | |||
3ba81d19a7 | |||
0e6f222ef1 | |||
90ca65f9a9 | |||
f4c156479a | |||
d9e38d97ee | |||
67e94e1ee7 | |||
b20e38a2bc | |||
d71031f2e4 | |||
98d1da428a | |||
df7236cfee | |||
c9cc1d4cfe | |||
128bd7d41a | |||
061cd0468c | |||
2bb0f530fe | |||
b3f5e74609 | |||
ff28b628a4 | |||
5925de94e7 | |||
7c36660000 | |||
ae8f80bb54 | |||
776a53b243 | |||
8ad68aca3a | |||
b1bd7e0215 | |||
d42b6798e0 | |||
fa94c67e99 | |||
4e9a074e82 | |||
b82f19ea50 | |||
271830422a | |||
7869289abc | |||
0a84eab0ef | |||
b816b386cf | |||
8d9755c17f | |||
d552b51c0d | |||
52620f3dda | |||
d7eaceb0fc | |||
e01fe19d53 | |||
af1d0759e1 | |||
af9f346698 | |||
b6ba2f291a | |||
c66799b24f | |||
18be21a310 | |||
abef9da9f9 | |||
4afddad503 | |||
cc39acd436 | |||
2df556c5be | |||
aa43912279 | |||
ece053e5c3 | |||
1c0fbace4d | |||
2fb7ac7b4b | |||
c89e332843 | |||
10f552f56a | |||
310f8f5f3c | |||
584b6e3038 | |||
a81b24b67f | |||
aacd4dc088 | |||
5243f304af | |||
6156cc0b88 | |||
4acf66a020 | |||
2af1735cfd | |||
13844bce65 | |||
d7dc3f34c7 | |||
086dbcc19e | |||
7a53ada4b4 | |||
c5e18957f5 | |||
64b4db98ba | |||
3a236a1a3b | |||
19006e79b1 | |||
44325ee176 | |||
397e23f1da | |||
3d48f4d046 | |||
0d7fe0ff74 | |||
543d147b37 | |||
34dde2640e | |||
205a672680 | |||
57b01a5d2c | |||
4624d5a2a6 | |||
518f9d73f6 | |||
65dd0f313b | |||
39b2a3420c | |||
ce7da9f513 | |||
7a7d0e650f | |||
4ca8c38c98 | |||
96bd188e57 | |||
90db9785ea | |||
506c8a3fa6 | |||
150595b7f7 | |||
07f482a98b | |||
c759e118fa | |||
330e26b2ba | |||
41215c9ae9 | |||
dce6323090 | |||
906413e800 | |||
ad72301ea0 | |||
44d0f1c533 | |||
9d8dfdfd4f | |||
e6813efb88 | |||
8597e04eaf | |||
d6331aab0b | |||
56642a11f7 | |||
f6a0954315 | |||
d00cfc420c |
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -10,9 +10,6 @@
|
|||||||
[submodule "thirdparty/lwgps"]
|
[submodule "thirdparty/lwgps"]
|
||||||
path = thirdparty/lwgps
|
path = thirdparty/lwgps
|
||||||
url = https://github.com/rmspacefish/lwgps.git
|
url = https://github.com/rmspacefish/lwgps.git
|
||||||
[submodule "thirdparty/arcsec_star_tracker"]
|
|
||||||
path = thirdparty/arcsec_star_tracker
|
|
||||||
url = https://egit.irs.uni-stuttgart.de/eive/arcsec_star_tracker.git
|
|
||||||
[submodule "thirdparty/json"]
|
[submodule "thirdparty/json"]
|
||||||
path = thirdparty/json
|
path = thirdparty/json
|
||||||
url = https://github.com/nlohmann/json.git
|
url = https://github.com/nlohmann/json.git
|
||||||
@ -22,3 +19,6 @@
|
|||||||
[submodule "thirdparty/gomspace-sw"]
|
[submodule "thirdparty/gomspace-sw"]
|
||||||
path = thirdparty/gomspace-sw
|
path = thirdparty/gomspace-sw
|
||||||
url = https://egit.irs.uni-stuttgart.de/eive/gomspace-sw.git
|
url = https://egit.irs.uni-stuttgart.de/eive/gomspace-sw.git
|
||||||
|
[submodule "thirdparty/sagittactl"]
|
||||||
|
path = thirdparty/sagittactl
|
||||||
|
url = https://egit.irs.uni-stuttgart.de/eive/sagittactl.git
|
||||||
|
343
CHANGELOG.md
343
CHANGELOG.md
@ -16,6 +16,349 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
# [v4.0.1] 2023-06-23
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- `PusLiveDemux` packet demultiplexing bugfix where the demultiplexing did not work when there was
|
||||||
|
only one destination available.
|
||||||
|
|
||||||
|
# [v4.0.0] 2023-06-22
|
||||||
|
|
||||||
|
- `eive-tmtc` version v5.0.0
|
||||||
|
- `q7s-package` version v3.1.1
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Important bugfixes for PTME. See `q7s-package` CHANGELOG.
|
||||||
|
- TCS fixes: Set temperature values to invalid value for MAX31865 RTD handler, SUS handler
|
||||||
|
and STR handler. Also set dataset to invakid for RTD handler.
|
||||||
|
- Fixed H parameter in SUS converter from 1 mm to 2.5 mm.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Removed PTME busy/ready signals. Those were not used anyway because register reads are used now.
|
||||||
|
- APB bus access busy checking is not done anymore as this is performed by the bus itself now.
|
||||||
|
- Core controller will now announce version and image information event in addition to reboot
|
||||||
|
event in the `inititalize` function.
|
||||||
|
- Core controller will now try to request and announce the firmware version in addition to the
|
||||||
|
OBSW version as well.
|
||||||
|
- Added core controller action to read reboot mechansm information
|
||||||
|
- GNSS reset pin will now only be asserted for 5 ms instead of 100 ms.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Added PL I2C reset pin. It is not used/connected for now but could be used for FDIR procedures to
|
||||||
|
restore the PL I2C.
|
||||||
|
- Core controller now announces firmware version as well when requesting a version info event
|
||||||
|
|
||||||
|
# [v3.3.1] 2023-06-22
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- `PusLiveDemux` packet demultiplexing bugfix where the demultiplexing did not work when there was
|
||||||
|
only one destination available.
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Fixed H parameter in SUS converter from 1 mm to 2.5 mm.
|
||||||
|
|
||||||
|
# [v3.3.0] 2023-06-21
|
||||||
|
|
||||||
|
Like v3.2.0 but without the custom FM changes related to VC0.
|
||||||
|
|
||||||
|
# [v3.2.0] 2023-06-21
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Fix sun vector calculation
|
||||||
|
- SUS total vector was not reset to being a zero vector during eclipse due to a wrong memcpy
|
||||||
|
length.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Reverted all changes related to VC0 handling to avoid FM bug possibly related to FPGA bug.
|
||||||
|
|
||||||
|
# [v3.1.1] 2023-06-14
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- TMP1075 bugfix where negative temperatures could not be measured because of a two's-complement
|
||||||
|
conversion bug.
|
||||||
|
|
||||||
|
# [v3.1.0] 2023-06-14
|
||||||
|
|
||||||
|
- `eive-tmtc` version v4.1.0
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- TCS heater switch enumeration naming was old/wrong and was not updated in sync with the object ID
|
||||||
|
update. This lead to the TCS controller commanding the wrong heaters.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Increase number of allowed parallel HK commands to 16
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Added `CONFIG_SET`, `MAN_HEATER_ON` and `MAN_HEATER_OFF` support for the BPX battery handler
|
||||||
|
|
||||||
|
# [v3.0.0] 2023-06-11
|
||||||
|
|
||||||
|
- `eive-tmtc` version v4.0.0
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Adapt EM configuration to include all GomSpace PCDU devices except the ACU. For the ACU
|
||||||
|
(which broke), a dummy will still be used.
|
||||||
|
- Event Manager queue depth is configurable now.
|
||||||
|
- Do not construct and schedule broken TMP1075 device anymore.
|
||||||
|
- Do not track payload modes in system mode tables.
|
||||||
|
- ACS modes derived from system modes.
|
||||||
|
- The CMake build generator will now search for the cross-compiler binaries in the environmental
|
||||||
|
variable named `CROSS_COMPILE_BIN_PATH` first when setting up the build system. This prevents
|
||||||
|
CMake from selecting wrong cross-compilers if multiple cross-compilers with the same name are used
|
||||||
|
on the same system.
|
||||||
|
- Add ACS board for EM by default now.
|
||||||
|
- Add support for MPSoC HK packet.
|
||||||
|
- Add support for MPSoC Flash Directory Content Report.
|
||||||
|
- Dynamically enable and disable HK packets for MPSoC on `ON` and `OFF` commands.
|
||||||
|
- Add support for MPSoC Flash Directory Content Report.
|
||||||
|
- Larger allowed path and file sizes for STR and PLOC MPSoC modules.
|
||||||
|
- More robust MPSoC flash read and write command data handling.
|
||||||
|
- Increase frequency of payload handlers from 0.8 seconds to 0.5 seconds.
|
||||||
|
- Disable missed deadlines per default. Not useful in orbit, and triggers all the time on the EM
|
||||||
|
build after a number of subsequent runs, without any apparent reason (deadlines are not actually
|
||||||
|
missed, thread usage displayed is nominal)
|
||||||
|
- TM store dumpes will not be cancelled anymore if the transmitter is off. The dump can be cancelled
|
||||||
|
with an OFF command, and the PTME is perfectly capable of dumping without the transmitter being
|
||||||
|
on.
|
||||||
|
- Transmitter state is not taken into account anymore for writing into the PTME. The PTME should
|
||||||
|
be perfectly capable of generating a valid CADU, even when the transmitter is not ON for any
|
||||||
|
reason.
|
||||||
|
- OFF mode is ignores in TM store for determining whether a store will be written. The modes will
|
||||||
|
only be used to cancel a transfer.
|
||||||
|
- Handling of multiple RWs in the ACS Controller is improved and can be changed by parameter
|
||||||
|
commands.
|
||||||
|
- The Directory Listing direct dumper now has a state machine to stagger the directory listing dump.
|
||||||
|
This is required because very large dumps will overload the queue capacities in the framework.
|
||||||
|
- The PUS Service 8 now has larger queue sizes to handle more action replies. The PUS Service 1
|
||||||
|
also has a larger queue size to handle a lot of step replies now.
|
||||||
|
- Moved PDU `vcc` and `vbat` variable from auxiliary dataset to core dataset.
|
||||||
|
- Tweak TCP/IP configuration: Only the TCP server will be included on the EM. For the FM, no
|
||||||
|
TCP/IP servers will be included by default.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Add the remaining system modes.
|
||||||
|
- PLOC MPSoC flash read command working.
|
||||||
|
- BPX battery handler is added for EM by default.
|
||||||
|
- ACU dummy HK sets
|
||||||
|
- IMTQ HK sets
|
||||||
|
- IMTQ dummy now handles power switch
|
||||||
|
- Added some new ACS parameters
|
||||||
|
- Enabled decimation filter for the ADIS GYRs
|
||||||
|
- Enabled second low-pass filter for L3GD20H GYRs
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- CFDP low level protocol bugfix. Requires `fsfw` update and `tmtc` update.
|
||||||
|
- Compile fix if SCEX is compiled for the EM.
|
||||||
|
- Set up Rad Sensor chip select even for EM to avoid SPI bus issues.
|
||||||
|
- Correct ADIS Gyroscope type configuration for the EM, where the 16507 type is used instead of the
|
||||||
|
16505 type.
|
||||||
|
- Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP
|
||||||
|
funnel.
|
||||||
|
- PLOC Supervisor handler now has a power switcher assigned to make PLOC power switching work
|
||||||
|
without an additional PCDU power switch command.
|
||||||
|
- The PLOC Supervisor handler now waits for the replies to the `SET_TIME` command to verify working
|
||||||
|
communication.
|
||||||
|
- The PLOC MPSoC now waits 10 cycles before going to on. These wait cycles are necessary because
|
||||||
|
the MPSoC is not ready to process commands without this additional boot time.
|
||||||
|
- Fixed correction for `GPS Altitude` in case the sensor data is out of the expected bonds.
|
||||||
|
- PLOC MPSoC special communication is now scheduled, which allows flash read and flash write
|
||||||
|
commands to work.
|
||||||
|
- Fixed the MPSoC flash write command.
|
||||||
|
- Added missing ACS parameter.
|
||||||
|
- HK TM store: The HK store dump success event was triggered for cancelled HK dumps.
|
||||||
|
- When a PUS parsing error occured while parsing a TM store file, the dump completion procedure
|
||||||
|
was always executed.
|
||||||
|
- Some smaller logic fixes in the TM store base class
|
||||||
|
- Fixed usage of C `abs` instead of C++ `std::abs`, which results in MTQ commands not being
|
||||||
|
scaled correctly between 1Am² and 0.2Am².
|
||||||
|
- TCS Heater Handler: Always trigger mode event if a heater goes `OFF` or `ON`. This event might
|
||||||
|
soon replace the `HEATER_WENT_ON` and `HEATER_WENT_OFF` events.
|
||||||
|
- Prevent spam of TCS controller heater unavailability event if all heaters are in external control.
|
||||||
|
- TCS heater switch info set contained invalid values because of a faulty `memcpy` in the TCS
|
||||||
|
controller. There is not crash risk but the heater states were invalid.
|
||||||
|
- STR datasets were not set to invalid on shutdown.
|
||||||
|
- Fixed usage of quaternion valid flag, which does not actually represent the validity of the
|
||||||
|
quaternion.
|
||||||
|
- Various fixes for the pointing modes of the `ACS Controller`. All modes should work now as
|
||||||
|
intended.
|
||||||
|
- The variance for the ADIS GYRs now represents the used `-3` version and not the `-1` version
|
||||||
|
- CFDP funnel did not route packets to live channel VC0
|
||||||
|
|
||||||
|
# [v2.0.5] 2023-05-11
|
||||||
|
|
||||||
|
- The dual lane assembly transition failed handler started new transitions towards the current mode
|
||||||
|
instead of the target mode. This means that if the dual lane assembly never reached the initial
|
||||||
|
submode (e.g. mode normal and submode dual side), it will transition back to the current mode,
|
||||||
|
which miht be `MODE_OFF`. Furthermore, this can lead to invalid internal states, so the subsequent
|
||||||
|
recovery handling becomes stuck in the custom recovery sequence when swichting power back on.
|
||||||
|
- The dual lane custom recovery handling was adapted to always perform proper power switch handling
|
||||||
|
irrespective of current or target modes.
|
||||||
|
|
||||||
|
# [v2.0.4] 2023-04-19
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- The dual lane assembly datasets were not marked invalid properly on OFF transitions.
|
||||||
|
|
||||||
|
# [v2.0.3] 2023-04-17
|
||||||
|
|
||||||
|
- eive-tmtc: v3.1.1
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Fixed shadowing within the `SafeCtrl`, which prevented actuator commands to be calculated during
|
||||||
|
eclipse phase.
|
||||||
|
- EM build idle mode fixes for RW dummy.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Add `MGT_OVERHEATING` event and fallback to system SAFE mode if the MGT is overheating for
|
||||||
|
whatever reason.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Low-pass filters can no longer be executed if no actual data is available.
|
||||||
|
|
||||||
|
# [v2.0.2] 2023-04-16
|
||||||
|
|
||||||
|
- Bump patch version to 2.
|
||||||
|
|
||||||
|
# [v2.0.1] 2023-04-16
|
||||||
|
|
||||||
|
- eive-tmtc: v3.1.0
|
||||||
|
|
||||||
|
# [v2.0.0] 2023-04-16
|
||||||
|
|
||||||
|
This is the version which will fly on the satellite for the initial launch phase.
|
||||||
|
|
||||||
|
- q7s-package: v2.5.0
|
||||||
|
- eive-tmtc: v3.0.0
|
||||||
|
- `wire` library is now on version v10.7 as well.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Added `mv`, `cp` and `rm` action helpers for the core controller for common filesystem operations.
|
||||||
|
- Extended directory listing helpers. There is now a directory listing helper which dumps the
|
||||||
|
directory listing as an action data reply immediately. For smaller directory listings, this
|
||||||
|
allows a listing without requiring a separate file downlink (which also has not been implemented
|
||||||
|
yet)
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- The directory listing action commands now allow compressing of either the target output file
|
||||||
|
for the directory listing into file action command, or compression in the helper which dumps
|
||||||
|
the directory listing directly.
|
||||||
|
|
||||||
|
# [v1.45.0] 2023-04-14
|
||||||
|
|
||||||
|
- q7s-package: v2.5.0
|
||||||
|
- eive-tmtc: v3.0.0
|
||||||
|
- STR firmware was updated to v10.7. `wire` library still needs to be updated.
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Small fix for `install-obsw-yocto.sh` script
|
||||||
|
- Bugfix for STR firmware update procedure where the last remaining
|
||||||
|
bytes were not written properly.
|
||||||
|
- Bugfix for STR where an invalid reply was received for special requests
|
||||||
|
like firmware updates.
|
||||||
|
- Bugfix for shell command executors in command controller which lead to a crash.
|
||||||
|
- Important bugfix for STR solution set. Missing STR mode u8 parameter.
|
||||||
|
- Fix for STR image download.
|
||||||
|
- Possible fix for STR image upload.
|
||||||
|
- Fixed regression where the reply result for ACS board and SUS board devices was set to FAILED
|
||||||
|
even when going to OFF mode. In that case, it has to be set to OK so the device handler can
|
||||||
|
complete the OFF transition.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- STR `wire` library updated to v10.3. Submodule renamed to `sagittactl`.
|
||||||
|
- Custom FDIR for TMP1075 sensors. The device handlers reject `NEEDS_RECOVERY` health commands
|
||||||
|
anyway, so it does not really make sense to use the default FDIR.
|
||||||
|
- Reject `NEEDS_RECOVERY` health commands for the heater health devices.
|
||||||
|
- Adapted some queue sizes so that EM startup works without queue errors
|
||||||
|
- Event Manager: 120 -> 160
|
||||||
|
- UDP TMTC Bridge: 50 -> 120
|
||||||
|
- TCP TMTC Bridge: 50 -> 120
|
||||||
|
- Service 5: 120 -> 160, number of events handled in one cycle increased to 80
|
||||||
|
- EM: PCDU dummy is not a device handler anymore, but a custom power switcher object. This avoids
|
||||||
|
some issues where the event manager could not send an event message to the PCDU dummy because
|
||||||
|
the FDIR event queue was too small.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Add a way for the MAX31865 RTD handlers to recognize faulty/broken/off sensor devices.
|
||||||
|
- Add parameter interface for core controller
|
||||||
|
- Allow setting the preferred SD card via the new parameter interface of the core controller
|
||||||
|
with domain ID 0 and unque ID 0.
|
||||||
|
- Added action commands to reset the PDEC. Also added autonomous reset handling for the PDEC,
|
||||||
|
because there is no way so send TCs with a faulty PDEC.
|
||||||
|
- Added `I2C_REBOOT` and `PDEC_REBOOT` events for EIVE system component to ensure ground gets
|
||||||
|
informed.
|
||||||
|
|
||||||
|
## ACS
|
||||||
|
|
||||||
|
- Commanding from ACS Controller is now enabled.
|
||||||
|
- Safe Controller was reverted to FLP Design. This also introduces safe mode strategies.
|
||||||
|
They contain what the controller does and which data it uses. The controller will
|
||||||
|
automatically based on the available data decide on which strategy to use. If a strategy
|
||||||
|
is undesirable (e.g. the MEKF should not be used) this can be handeld via setting parameters.
|
||||||
|
|
||||||
|
# [v1.44.1] 2023-04-12
|
||||||
|
|
||||||
|
- eive-tmtc: v2.22.1
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Bugfixes and improvements for SDC state machine. Internal state was not updated correctly due
|
||||||
|
to a regression, so commanding the SDC state machine externally lead to confusing results.
|
||||||
|
- Heater states array in TCS controller was too small.
|
||||||
|
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
|
||||||
|
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
|
||||||
|
- Add a way for the SUS polling to detect broken or off devices by checking the retrieved
|
||||||
|
temperature for the all-ones value (0x0fff).
|
||||||
|
- Better reply result handling for the ACS board devices.
|
||||||
|
- ADIS1650X initial timeout handling now performed in device handler.
|
||||||
|
- The RW assembly and TCS board assembly now perform proper power switch handling for their
|
||||||
|
recovery handling.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Added additional logic for SDC state machine so that the SD cards are marked unusable when
|
||||||
|
the active SD card is switched or there is a transition from hot redundant to cold redundant mode.
|
||||||
|
This gives other tasks some time to register the SD cards being unusable, and therefore provides
|
||||||
|
a way for them to perform any re-initialization tasks necessary after SD card switches.
|
||||||
|
- TCS controller now only has an OFF mode and an ON mode
|
||||||
|
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
|
||||||
|
the primary control loop) while a TCS board recovery is on-going.
|
||||||
|
- Allow specifying custom OBSW update filename. This allowed keeping a cleaner file structure
|
||||||
|
where each update has a name including the version
|
||||||
|
- The files extracted during an update process are deleted after the update was performed to keep
|
||||||
|
the update directory cleaner.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- TCS controller: SUBMODE_NO_HEATER_CTRL (1) added for ON mode. If this submode is
|
||||||
|
commanded, all heaters will be switched off and then no further heater
|
||||||
|
commanding will be done.
|
||||||
|
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
|
||||||
|
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
|
||||||
|
|
||||||
# [v1.44.0] 2023-04-07
|
# [v1.44.0] 2023-04-07
|
||||||
|
|
||||||
- eive-tmtc: v2.22.0
|
- eive-tmtc: v2.22.0
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(OBSW_VERSION_MAJOR 1)
|
set(OBSW_VERSION_MAJOR 3)
|
||||||
set(OBSW_VERSION_MINOR 44)
|
set(OBSW_VERSION_MINOR 3)
|
||||||
set(OBSW_VERSION_REVISION 0)
|
set(OBSW_VERSION_REVISION 1)
|
||||||
|
|
||||||
# set(CMAKE_VERBOSE TRUE)
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
|
|
||||||
@ -79,12 +79,19 @@ else()
|
|||||||
set(INIT_VAL 1)
|
set(INIT_VAL 1)
|
||||||
set(OBSW_STAR_TRACKER_GROUND_CONFIG 0)
|
set(OBSW_STAR_TRACKER_GROUND_CONFIG 0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(OBSW_ADD_TMTC_TCP_SERVER
|
||||||
|
${OBSW_Q7S_EM}
|
||||||
|
CACHE STRING "Add TCP TMTC Server")
|
||||||
|
set(OBSW_ADD_TMTC_UDP_SERVER
|
||||||
|
0
|
||||||
|
CACHE STRING "Add UDP TMTC Server")
|
||||||
set(OBSW_ADD_MGT
|
set(OBSW_ADD_MGT
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add MGT module")
|
CACHE STRING "Add MGT module")
|
||||||
set(OBSW_ADD_BPX_BATTERY_HANDLER
|
set(OBSW_ADD_BPX_BATTERY_HANDLER
|
||||||
${INIT_VAL}
|
1
|
||||||
CACHE STRING "Add MGT module")
|
CACHE STRING "Add BPX battery module")
|
||||||
set(OBSW_ADD_STAR_TRACKER
|
set(OBSW_ADD_STAR_TRACKER
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add Startracker module")
|
CACHE STRING "Add Startracker module")
|
||||||
@ -94,6 +101,9 @@ set(OBSW_ADD_SUN_SENSORS
|
|||||||
set(OBSW_ADD_SUS_BOARD_ASS
|
set(OBSW_ADD_SUS_BOARD_ASS
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add sun sensor board assembly")
|
CACHE STRING "Add sun sensor board assembly")
|
||||||
|
set(OBSW_ADD_THERMAL_TEMP_INSERTER
|
||||||
|
${OBSW_Q7S_EM}
|
||||||
|
CACHE STRING "Add thermal sensor temperature inserter")
|
||||||
set(OBSW_ADD_ACS_BOARD
|
set(OBSW_ADD_ACS_BOARD
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add ACS board module")
|
CACHE STRING "Add ACS board module")
|
||||||
@ -143,8 +153,11 @@ set(OBSW_ADD_TMP_DEVICES
|
|||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add TMP devices")
|
CACHE STRING "Add TMP devices")
|
||||||
set(OBSW_ADD_GOMSPACE_PCDU
|
set(OBSW_ADD_GOMSPACE_PCDU
|
||||||
${INIT_VAL}
|
1
|
||||||
CACHE STRING "Add GomSpace PCDU modules")
|
CACHE STRING "Add GomSpace PCDU modules")
|
||||||
|
set(OBSW_ADD_GOMSPACE_ACU
|
||||||
|
${INIT_VAL}
|
||||||
|
CACHE STRING "Add GomSpace ACU submodule")
|
||||||
set(OBSW_ADD_RW
|
set(OBSW_ADD_RW
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add RW modules")
|
CACHE STRING "Add RW modules")
|
||||||
@ -220,7 +233,7 @@ set(LIB_EIVE_MISSION_PATH mission)
|
|||||||
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
|
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
|
||||||
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
|
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
|
||||||
set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps)
|
set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps)
|
||||||
set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/arcsec_star_tracker)
|
set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/sagittactl)
|
||||||
set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
|
set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
|
||||||
|
|
||||||
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
||||||
|
18
README.md
18
README.md
@ -99,11 +99,21 @@ When using Windows, run theses steps in MSYS2.
|
|||||||
git submodule update --init
|
git submodule update --init
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version` and that
|
3. Create two system variables to pass the system root path and the cross-compiler path to the
|
||||||
|
build system. You only need to do this once when setting up the build system.
|
||||||
|
Example for Unix:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export CROSS_COMPILE_BIN_PATH=<absolutePathToCrossCompilerBinPath>
|
||||||
|
export ZYNQ_7020_SYSROOT=<absolutePathToSysroot>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Ensure that the cross-compiler is working with
|
||||||
|
`${CROSS_COMPILE_BIN_PATH}/arm-linux-gnueabihf-gcc --version` and that
|
||||||
the sysroot environmental variables have been set like specified in the
|
the sysroot environmental variables have been set like specified in the
|
||||||
[root filesystem chapter](#sysroot).
|
[root filesystem chapter](#sysroot).
|
||||||
|
|
||||||
4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder.
|
5. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder.
|
||||||
Add `-G "MinGW Makefiles` in MinGW64 on Windows.
|
Add `-G "MinGW Makefiles` in MinGW64 on Windows.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@ -112,7 +122,7 @@ When using Windows, run theses steps in MSYS2.
|
|||||||
cmake --build . -j
|
cmake --build . -j
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use provided shell scripts to perform these commands.
|
Please note that you can also use provided shell scripts to perform these commands.
|
||||||
```sh
|
```sh
|
||||||
cp scripts/q7s-env.sh ..
|
cp scripts/q7s-env.sh ..
|
||||||
cp scripts/q7s-env-em.sh ..
|
cp scripts/q7s-env-em.sh ..
|
||||||
@ -144,7 +154,7 @@ When using Windows, run theses steps in MSYS2.
|
|||||||
There are also different values for `-DTGT_BSP` to build for the Raspberry Pi
|
There are also different values for `-DTGT_BSP` to build for the Raspberry Pi
|
||||||
or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`.
|
or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`.
|
||||||
|
|
||||||
5. Build the software with
|
6. Build the software with
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd cmake-build-debug-q7s
|
cd cmake-build-debug-q7s
|
||||||
|
6
automation/Jenkinsfile
vendored
6
automation/Jenkinsfile
vendored
@ -22,7 +22,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR_Q7S) {
|
dir(BUILDDIR_Q7S) {
|
||||||
sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug ..'
|
sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug ..'
|
||||||
sh 'cmake --build . -j6'
|
sh 'cmake --build . -j8'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR_Q7S_EM) {
|
dir(BUILDDIR_Q7S_EM) {
|
||||||
sh 'cmake -DTGT_BSP="arm/q7s" -DEIVE_Q7S_EM=ON -DCMAKE_BUILD_TYPE=Debug ..'
|
sh 'cmake -DTGT_BSP="arm/q7s" -DEIVE_Q7S_EM=ON -DCMAKE_BUILD_TYPE=Debug ..'
|
||||||
sh 'cmake --build . -j6'
|
sh 'cmake --build . -j8'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR_LINUX) {
|
dir(BUILDDIR_LINUX) {
|
||||||
sh 'cmake ..'
|
sh 'cmake ..'
|
||||||
sh 'cmake --build . -j6'
|
sh 'cmake --build . -j8'
|
||||||
sh './eive-unittest'
|
sh './eive-unittest'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "devices/gpioIds.h"
|
#include "devices/gpioIds.h"
|
||||||
#include "fsfw_hal/linux/gpio/Gpio.h"
|
#include "fsfw_hal/linux/gpio/Gpio.h"
|
||||||
#include "linux/payload/PlocMpsocHandler.h"
|
#include "linux/payload/PlocMpsocHandler.h"
|
||||||
#include "linux/payload/PlocMpsocHelper.h"
|
#include "linux/payload/PlocMpsocSpecialComHelper.h"
|
||||||
#include "linux/payload/PlocSupervisorHandler.h"
|
#include "linux/payload/PlocSupervisorHandler.h"
|
||||||
#include "linux/payload/PlocSupvUartMan.h"
|
#include "linux/payload/PlocSupvUartMan.h"
|
||||||
#include "test/gpio/DummyGpioIF.h"
|
#include "test/gpio/DummyGpioIF.h"
|
||||||
@ -62,10 +62,15 @@ void ObjectFactory::produce(void* args) {
|
|||||||
StorageManagerIF* tmStore;
|
StorageManagerIF* tmStore;
|
||||||
StorageManagerIF* ipcStore;
|
StorageManagerIF* ipcStore;
|
||||||
PersistentTmStores persistentStores;
|
PersistentTmStores persistentStores;
|
||||||
|
bool enableHkSets = false;
|
||||||
|
#if OBSW_ENABLE_PERIODIC_HK == 1
|
||||||
|
enableHkSets = true;
|
||||||
|
#endif
|
||||||
auto sdcMan = new DummySdCardManager("/tmp");
|
auto sdcMan = new DummySdCardManager("/tmp");
|
||||||
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore,
|
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore,
|
||||||
&tmStore, persistentStores);
|
&tmStore, persistentStores, 120);
|
||||||
|
|
||||||
|
new TmFunnelHandler(objects::LIVE_TM_TASK, *pusFunnel, *cfdpFunnel);
|
||||||
auto* dummyGpioIF = new DummyGpioIF();
|
auto* dummyGpioIF = new DummyGpioIF();
|
||||||
auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0);
|
auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0);
|
||||||
std::vector<ReturnValue_t> switcherList;
|
std::vector<ReturnValue_t> switcherList;
|
||||||
@ -81,8 +86,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
auto mpsocCookie = new UartCookie(objects::PLOC_MPSOC_HANDLER, mpscoDev, uart::PLOC_MPSOC_BAUD,
|
auto mpsocCookie = new UartCookie(objects::PLOC_MPSOC_HANDLER, mpscoDev, uart::PLOC_MPSOC_BAUD,
|
||||||
mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL);
|
mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL);
|
||||||
mpsocCookie->setNoFixedSizeReply();
|
mpsocCookie->setNoFixedSizeReply();
|
||||||
auto plocMpsocHelper = new PlocMPSoCHelper(objects::PLOC_MPSOC_HELPER);
|
auto plocMpsocHelper = new PlocMpsocSpecialComHelper(objects::PLOC_MPSOC_HELPER);
|
||||||
new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie,
|
new PlocMpsocHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie,
|
||||||
plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, dummyGpioIF),
|
plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, dummyGpioIF),
|
||||||
objects::PLOC_SUPERVISOR_HANDLER);
|
objects::PLOC_SUPERVISOR_HANDLER);
|
||||||
#endif /* OBSW_ADD_PLOC_MPSOC == 1 */
|
#endif /* OBSW_ADD_PLOC_MPSOC == 1 */
|
||||||
@ -100,7 +105,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
dummy::DummyCfg cfg;
|
dummy::DummyCfg cfg;
|
||||||
dummy::createDummies(cfg, *dummySwitcher, dummyGpioIF);
|
dummy::createDummies(cfg, *dummySwitcher, dummyGpioIF, enableHkSets);
|
||||||
|
|
||||||
HeaterHandler* heaterHandler = nullptr;
|
HeaterHandler* heaterHandler = nullptr;
|
||||||
// new ThermalController(objects::THERMAL_CONTROLLER);
|
// new ThermalController(objects::THERMAL_CONTROLLER);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 285 translations.
|
* @brief Auto-generated event translation file. Contains 295 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-04-07 17:42:57
|
* Generated on: 2023-05-17 17:15:34
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
|
|||||||
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||||
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||||
|
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||||
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
|
|||||||
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
||||||
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
||||||
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
||||||
|
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
|
||||||
|
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||||
|
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||||
@ -193,6 +197,10 @@ const char *MPSOC_EXE_INVALID_APID_STRING = "MPSOC_EXE_INVALID_APID";
|
|||||||
const char *MPSOC_HELPER_SEQ_CNT_MISMATCH_STRING = "MPSOC_HELPER_SEQ_CNT_MISMATCH";
|
const char *MPSOC_HELPER_SEQ_CNT_MISMATCH_STRING = "MPSOC_HELPER_SEQ_CNT_MISMATCH";
|
||||||
const char *MPSOC_TM_SIZE_ERROR_STRING = "MPSOC_TM_SIZE_ERROR";
|
const char *MPSOC_TM_SIZE_ERROR_STRING = "MPSOC_TM_SIZE_ERROR";
|
||||||
const char *MPSOC_TM_CRC_MISSMATCH_STRING = "MPSOC_TM_CRC_MISSMATCH";
|
const char *MPSOC_TM_CRC_MISSMATCH_STRING = "MPSOC_TM_CRC_MISSMATCH";
|
||||||
|
const char *MPSOC_FLASH_READ_PACKET_ERROR_STRING = "MPSOC_FLASH_READ_PACKET_ERROR";
|
||||||
|
const char *MPSOC_FLASH_READ_FAILED_STRING = "MPSOC_FLASH_READ_FAILED";
|
||||||
|
const char *MPSOC_FLASH_READ_SUCCESSFUL_STRING = "MPSOC_FLASH_READ_SUCCESSFUL";
|
||||||
|
const char *MPSOC_READ_TIMEOUT_STRING = "MPSOC_READ_TIMEOUT";
|
||||||
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
||||||
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
||||||
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
||||||
@ -268,6 +276,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
|||||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||||
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||||
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||||
|
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
|
||||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||||
@ -275,6 +284,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
|
|||||||
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
||||||
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
||||||
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
||||||
|
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||||
@ -478,8 +488,10 @@ const char *translateEvents(Event event) {
|
|||||||
case (11204):
|
case (11204):
|
||||||
return MEKF_RECOVERY_STRING;
|
return MEKF_RECOVERY_STRING;
|
||||||
case (11205):
|
case (11205):
|
||||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
return MEKF_AUTOMATIC_RESET_STRING;
|
||||||
case (11206):
|
case (11206):
|
||||||
|
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||||
|
case (11207):
|
||||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||||
case (11300):
|
case (11300):
|
||||||
return SWITCH_CMD_SENT_STRING;
|
return SWITCH_CMD_SENT_STRING;
|
||||||
@ -604,9 +616,15 @@ const char *translateEvents(Event event) {
|
|||||||
case (12409):
|
case (12409):
|
||||||
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
||||||
case (12410):
|
case (12410):
|
||||||
return PDEC_RESET_FAILED_STRING;
|
return PDEC_TRYING_RESET_WITH_INIT_STRING;
|
||||||
case (12411):
|
case (12411):
|
||||||
|
return PDEC_TRYING_RESET_NO_INIT_STRING;
|
||||||
|
case (12412):
|
||||||
|
return PDEC_RESET_FAILED_STRING;
|
||||||
|
case (12413):
|
||||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||||
|
case (12414):
|
||||||
|
return PDEC_INIT_FAILED_STRING;
|
||||||
case (12500):
|
case (12500):
|
||||||
return IMAGE_UPLOAD_FAILED_STRING;
|
return IMAGE_UPLOAD_FAILED_STRING;
|
||||||
case (12501):
|
case (12501):
|
||||||
@ -669,6 +687,14 @@ const char *translateEvents(Event event) {
|
|||||||
return MPSOC_TM_SIZE_ERROR_STRING;
|
return MPSOC_TM_SIZE_ERROR_STRING;
|
||||||
case (12613):
|
case (12613):
|
||||||
return MPSOC_TM_CRC_MISSMATCH_STRING;
|
return MPSOC_TM_CRC_MISSMATCH_STRING;
|
||||||
|
case (12614):
|
||||||
|
return MPSOC_FLASH_READ_PACKET_ERROR_STRING;
|
||||||
|
case (12615):
|
||||||
|
return MPSOC_FLASH_READ_FAILED_STRING;
|
||||||
|
case (12616):
|
||||||
|
return MPSOC_FLASH_READ_SUCCESSFUL_STRING;
|
||||||
|
case (12617):
|
||||||
|
return MPSOC_READ_TIMEOUT_STRING;
|
||||||
case (12700):
|
case (12700):
|
||||||
return TRANSITION_BACK_TO_OFF_STRING;
|
return TRANSITION_BACK_TO_OFF_STRING;
|
||||||
case (12701):
|
case (12701):
|
||||||
@ -819,6 +845,8 @@ const char *translateEvents(Event event) {
|
|||||||
return TRYING_I2C_RECOVERY_STRING;
|
return TRYING_I2C_RECOVERY_STRING;
|
||||||
case (14011):
|
case (14011):
|
||||||
return I2C_REBOOT_STRING;
|
return I2C_REBOOT_STRING;
|
||||||
|
case (14012):
|
||||||
|
return PDEC_REBOOT_STRING;
|
||||||
case (14100):
|
case (14100):
|
||||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||||
case (14101):
|
case (14101):
|
||||||
@ -833,6 +861,8 @@ const char *translateEvents(Event event) {
|
|||||||
return PCDU_SYSTEM_OVERHEATING_STRING;
|
return PCDU_SYSTEM_OVERHEATING_STRING;
|
||||||
case (14107):
|
case (14107):
|
||||||
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
||||||
|
case (14108):
|
||||||
|
return MGT_OVERHEATING_STRING;
|
||||||
case (14201):
|
case (14201):
|
||||||
return TX_TIMER_EXPIRED_STRING;
|
return TX_TIMER_EXPIRED_STRING;
|
||||||
case (14202):
|
case (14202):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 171 translations.
|
* Contains 171 translations.
|
||||||
* Generated on: 2023-04-07 17:42:57
|
* Generated on: 2023-05-17 17:15:34
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -59,19 +59,15 @@ void scheduling::initTasks() {
|
|||||||
"DIST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"DIST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
ReturnValue_t result = tmtcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
ReturnValue_t result = tmtcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error << "adding CCSDS distributor failed" << std::endl;
|
sif::error << "Adding CCSDS distributor failed" << std::endl;
|
||||||
}
|
}
|
||||||
result = tmtcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
result = tmtcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error << "adding PUS distributor failed" << std::endl;
|
sif::error << "Adding PUS distributor failed" << std::endl;
|
||||||
}
|
|
||||||
result = tmtcDistributor->addComponent(objects::TM_FUNNEL);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::error << "adding TM funnel failed" << std::endl;
|
|
||||||
}
|
}
|
||||||
result = tmtcDistributor->addComponent(objects::CFDP_DISTRIBUTOR);
|
result = tmtcDistributor->addComponent(objects::CFDP_DISTRIBUTOR);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error << "adding CFDP distributor failed" << std::endl;
|
sif::error << "Adding CFDP distributor failed" << std::endl;
|
||||||
}
|
}
|
||||||
result = tmtcDistributor->addComponent(objects::UDP_TMTC_SERVER);
|
result = tmtcDistributor->addComponent(objects::UDP_TMTC_SERVER);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -95,6 +91,13 @@ void scheduling::initTasks() {
|
|||||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PeriodicTaskIF* liveTmTask = factory->createPeriodicTask(
|
||||||
|
"LIVE_TM", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, nullptr, &RR_SCHEDULING);
|
||||||
|
result = liveTmTask->addComponent(objects::LIVE_TM_TASK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
scheduling::printAddObjectError("LIVE_TM", objects::LIVE_TM_TASK);
|
||||||
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||||
"PUS_HIGH_PRIO", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_HIGH_PRIO", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
@ -149,9 +152,8 @@ void scheduling::initTasks() {
|
|||||||
"THERMAL_CTL_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc);
|
"THERMAL_CTL_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc);
|
||||||
result = thermalTask->addComponent(objects::CORE_CONTROLLER);
|
result = thermalTask->addComponent(objects::CORE_CONTROLLER);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("Core controller dummy", objects::CORE_CONTROLLER);
|
scheduling::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = thermalTask->addComponent(objects::THERMAL_CONTROLLER);
|
result = thermalTask->addComponent(objects::THERMAL_CONTROLLER);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
||||||
@ -218,6 +220,7 @@ void scheduling::initTasks() {
|
|||||||
tmtcDistributor->startTask();
|
tmtcDistributor->startTask();
|
||||||
udpPollingTask->startTask();
|
udpPollingTask->startTask();
|
||||||
tcpPollingTask->startTask();
|
tcpPollingTask->startTask();
|
||||||
|
liveTmTask->startTask();
|
||||||
|
|
||||||
pusHighPrio->startTask();
|
pusHighPrio->startTask();
|
||||||
pusMedPrio->startTask();
|
pusMedPrio->startTask();
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#define OBSW_COMMAND_SAFE_MODE_AT_STARTUP 1
|
#define OBSW_COMMAND_SAFE_MODE_AT_STARTUP 1
|
||||||
|
|
||||||
#define OBSW_ADD_GOMSPACE_PCDU @OBSW_ADD_GOMSPACE_PCDU@
|
#define OBSW_ADD_GOMSPACE_PCDU @OBSW_ADD_GOMSPACE_PCDU@
|
||||||
|
// This define is necessary because the EM setup has the P60 dock module, but no ACU on the P60
|
||||||
|
// module because it broke.
|
||||||
|
#define OBSW_ADD_GOMSPACE_ACU @OBSW_ADD_GOMSPACE_ACU@
|
||||||
#define OBSW_ADD_MGT @OBSW_ADD_MGT@
|
#define OBSW_ADD_MGT @OBSW_ADD_MGT@
|
||||||
#define OBSW_ADD_BPX_BATTERY_HANDLER @OBSW_ADD_BPX_BATTERY_HANDLER@
|
#define OBSW_ADD_BPX_BATTERY_HANDLER @OBSW_ADD_BPX_BATTERY_HANDLER@
|
||||||
#define OBSW_ADD_STAR_TRACKER @OBSW_ADD_STAR_TRACKER@
|
#define OBSW_ADD_STAR_TRACKER @OBSW_ADD_STAR_TRACKER@
|
||||||
@ -43,6 +46,9 @@
|
|||||||
#define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@
|
#define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@
|
||||||
#define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@
|
#define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@
|
||||||
#define OBSW_ADD_CCSDS_IP_CORES @OBSW_ADD_CCSDS_IP_CORES@
|
#define OBSW_ADD_CCSDS_IP_CORES @OBSW_ADD_CCSDS_IP_CORES@
|
||||||
|
// Only relevant for EM for TCS tests.
|
||||||
|
#define OBSW_ADD_THERMAL_TEMP_INSERTER @OBSW_ADD_THERMAL_TEMP_INSERTER@
|
||||||
|
|
||||||
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
||||||
#define OBSW_TM_TO_PTME @OBSW_TM_TO_PTME@
|
#define OBSW_TM_TO_PTME @OBSW_TM_TO_PTME@
|
||||||
// Set to 1 if telecommands are received via the PDEC IP Core
|
// Set to 1 if telecommands are received via the PDEC IP Core
|
||||||
@ -61,12 +67,12 @@
|
|||||||
// because UDP packets are not allowed in the VPN
|
// because UDP packets are not allowed in the VPN
|
||||||
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
|
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
|
||||||
// CCSDS IP Cores.
|
// CCSDS IP Cores.
|
||||||
#define OBSW_ADD_TMTC_TCP_SERVER 1
|
#define OBSW_ADD_TMTC_TCP_SERVER @OBSW_ADD_TMTC_TCP_SERVER@
|
||||||
#define OBSW_ADD_TMTC_UDP_SERVER 1
|
#define OBSW_ADD_TMTC_UDP_SERVER @OBSW_ADD_TMTC_UDP_SERVER@
|
||||||
|
|
||||||
// Can be used to switch device to NORMAL mode immediately
|
// Can be used to switch device to NORMAL mode immediately
|
||||||
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0
|
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0
|
||||||
#define OBSW_PRINT_MISSED_DEADLINES 1
|
#define OBSW_PRINT_MISSED_DEADLINES 0
|
||||||
|
|
||||||
#define OBSW_MPSOC_JTAG_BOOT 0
|
#define OBSW_MPSOC_JTAG_BOOT 0
|
||||||
#define OBSW_STAR_TRACKER_GROUND_CONFIG @OBSW_STAR_TRACKER_GROUND_CONFIG@
|
#define OBSW_STAR_TRACKER_GROUND_CONFIG @OBSW_STAR_TRACKER_GROUND_CONFIG@
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/timemanager/Stopwatch.h"
|
#include "fsfw/timemanager/Stopwatch.h"
|
||||||
#include "fsfw/version.h"
|
#include "fsfw/version.h"
|
||||||
#include "mission/sysDefs.h"
|
|
||||||
#include "watchdog/definitions.h"
|
#include "watchdog/definitions.h"
|
||||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||||
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
||||||
@ -40,7 +39,8 @@ CoreController::CoreController(object_id_t objectId, bool enableHkSet)
|
|||||||
cmdRepliesSizes(128),
|
cmdRepliesSizes(128),
|
||||||
opDivider5(5),
|
opDivider5(5),
|
||||||
opDivider10(10),
|
opDivider10(10),
|
||||||
hkSet(this) {
|
hkSet(this),
|
||||||
|
paramHelper(this) {
|
||||||
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
|
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
|
||||||
try {
|
try {
|
||||||
sdcMan = SdCardManager::instance();
|
sdcMan = SdCardManager::instance();
|
||||||
@ -54,7 +54,6 @@ CoreController::CoreController(object_id_t objectId, bool enableHkSet)
|
|||||||
// Set up state of SD card manager and own initial state.
|
// Set up state of SD card manager and own initial state.
|
||||||
// Stopwatch watch;
|
// Stopwatch watch;
|
||||||
sdcMan->updateSdCardStateFile();
|
sdcMan->updateSdCardStateFile();
|
||||||
sdcMan->updateSdStatePair();
|
|
||||||
SdCardManager::SdStatePair sdStates;
|
SdCardManager::SdStatePair sdStates;
|
||||||
sdcMan->getSdCardsStatus(sdStates);
|
sdcMan->getSdCardsStatus(sdStates);
|
||||||
auto sdCard = sdcMan->getPreferredSdCard();
|
auto sdCard = sdcMan->getPreferredSdCard();
|
||||||
@ -89,6 +88,10 @@ CoreController::CoreController(object_id_t objectId, bool enableHkSet)
|
|||||||
CoreController::~CoreController() {}
|
CoreController::~CoreController() {}
|
||||||
|
|
||||||
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
||||||
|
ReturnValue_t result = paramHelper.handleParameterMessage(message);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
return ExtendedControllerBase::handleCommandMessage(message);
|
return ExtendedControllerBase::handleCommandMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,12 +112,15 @@ void CoreController::performControlOperation() {
|
|||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
performMountedSdCardOperations();
|
performMountedSdCardOperations();
|
||||||
readHkData();
|
readHkData();
|
||||||
|
if (dumpContext.active) {
|
||||||
|
dirListingDumpHandler();
|
||||||
|
}
|
||||||
|
|
||||||
if (shellCmdIsExecuting) {
|
if (shellCmdIsExecuting) {
|
||||||
bool replyReceived = false;
|
bool replyReceived = false;
|
||||||
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
||||||
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
||||||
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD);
|
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD_BLOCKING);
|
||||||
shellCmdIsExecuting = false;
|
shellCmdIsExecuting = false;
|
||||||
cmdReplyBuf.clear();
|
cmdReplyBuf.clear();
|
||||||
while (not cmdRepliesSizes.empty()) {
|
while (not cmdRepliesSizes.empty()) {
|
||||||
@ -155,6 +161,11 @@ ReturnValue_t CoreController::initialize() {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = paramHelper.initialize();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
|
|
||||||
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
||||||
@ -225,6 +236,84 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
case (LIST_DIRECTORY_INTO_FILE): {
|
case (LIST_DIRECTORY_INTO_FILE): {
|
||||||
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
||||||
}
|
}
|
||||||
|
case (LIST_DIRECTORY_DUMP_DIRECTLY): {
|
||||||
|
return actionListDirectoryDumpDirectly(actionId, commandedBy, data, size);
|
||||||
|
}
|
||||||
|
case (CP_HELPER): {
|
||||||
|
CpHelperParser parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::ostringstream oss("cp ", std::ostringstream::ate);
|
||||||
|
if (parser.isRecursiveOptSet()) {
|
||||||
|
oss << "-r ";
|
||||||
|
}
|
||||||
|
auto &sourceTgt = parser.destTgtPair();
|
||||||
|
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
|
||||||
|
sif::info << "CoreController: Performing copy command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (MV_HELPER): {
|
||||||
|
MvHelperParser parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::ostringstream oss("mv ", std::ostringstream::ate);
|
||||||
|
auto &sourceTgt = parser.destTgtPair();
|
||||||
|
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
|
||||||
|
sif::info << "CoreController: Performing move command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RM_HELPER): {
|
||||||
|
RmHelperParser parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::ostringstream oss("rm ", std::ostringstream::ate);
|
||||||
|
if (parser.isRecursiveOptSet() or parser.isForceOptSet()) {
|
||||||
|
oss << "-";
|
||||||
|
}
|
||||||
|
if (parser.isRecursiveOptSet()) {
|
||||||
|
oss << "r";
|
||||||
|
}
|
||||||
|
if (parser.isForceOptSet()) {
|
||||||
|
oss << "f";
|
||||||
|
}
|
||||||
|
size_t removeTargetSize = 0;
|
||||||
|
const char *removeTgt = parser.getRemoveTarget(removeTargetSize);
|
||||||
|
oss << " " << removeTgt;
|
||||||
|
sif::info << "CoreController: Performing remove command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (MKDIR_HELPER): {
|
||||||
|
if (size < 1) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
std::string createdDir = std::string(reinterpret_cast<const char *>(data), size);
|
||||||
|
std::ostringstream oss("mkdir ", std::ostringstream::ate);
|
||||||
|
oss << createdDir;
|
||||||
|
sif::info << "CoreController: Performing directory creation: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
case (SWITCH_REBOOT_FILE_HANDLING): {
|
case (SWITCH_REBOOT_FILE_HANDLING): {
|
||||||
if (size < 1) {
|
if (size < 1) {
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
@ -295,6 +384,41 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
// Completion will be reported by SD card state machine
|
// Completion will be reported by SD card state machine
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
case (SYSTEMCTL_CMD_EXECUTOR): {
|
||||||
|
// Expect one byte systemctl command type and a unit name with at least one byte as minimum.
|
||||||
|
if (size < 2) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
if (data[0] >= core::SystemctlCmd::NUM_CMDS) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
core::SystemctlCmd cmdType = static_cast<core::SystemctlCmd>(data[0]);
|
||||||
|
std::string unitName = std::string(reinterpret_cast<const char *>(data + 1), size - 1);
|
||||||
|
std::ostringstream oss("systemctl ", std::ostringstream::ate);
|
||||||
|
switch (cmdType) {
|
||||||
|
case (core::SystemctlCmd::START): {
|
||||||
|
oss << "start ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (core::SystemctlCmd::STOP): {
|
||||||
|
oss << "stop ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (core::SystemctlCmd::RESTART): {
|
||||||
|
oss << "restart ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oss << unitName;
|
||||||
|
int result = std::system(oss.str().c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
case (SWITCH_IMG_LOCK): {
|
case (SWITCH_IMG_LOCK): {
|
||||||
if (size != 3) {
|
if (size != 3) {
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
@ -325,13 +449,22 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
// Warning: This function will never return, because it reboots the system
|
// Warning: This function will never return, because it reboots the system
|
||||||
return actionReboot(data, size);
|
return actionReboot(data, size);
|
||||||
}
|
}
|
||||||
case (EXECUTE_SHELL_CMD): {
|
case (EXECUTE_SHELL_CMD_BLOCKING): {
|
||||||
std::string cmd = std::string(cmd, size);
|
std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
|
||||||
|
int result = std::system(cmdToExecute.c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
// TODO: Data reply with returnalue maybe?
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (EXECUTE_SHELL_CMD_NON_BLOCKING): {
|
||||||
|
std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
|
||||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
|
||||||
shellCmdIsExecuting) {
|
shellCmdIsExecuting) {
|
||||||
return HasActionsIF::IS_BUSY;
|
return HasActionsIF::IS_BUSY;
|
||||||
}
|
}
|
||||||
cmdExecutor.load(cmd, false, false);
|
cmdExecutor.load(cmdToExecute, false, false);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -368,7 +501,7 @@ ReturnValue_t CoreController::initSdCardBlocking() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
updateSdInfoOther();
|
updateInternalSdInfo();
|
||||||
sif::info << "Cold redundant SD card configuration, preferred SD card: "
|
sif::info << "Cold redundant SD card configuration, preferred SD card: "
|
||||||
<< static_cast<int>(sdInfo.active) << std::endl;
|
<< static_cast<int>(sdInfo.active) << std::endl;
|
||||||
result = sdColdRedundantBlockingInit();
|
result = sdColdRedundantBlockingInit();
|
||||||
@ -404,23 +537,23 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
} else {
|
} else {
|
||||||
// Still update SD state file
|
// Still update SD state file
|
||||||
if (sdInfo.cfgMode == SdCfgMode::PASSIVE) {
|
if (sdInfo.cfgMode == SdCfgMode::PASSIVE) {
|
||||||
sdFsmState = SdStates::UPDATE_INFO;
|
sdFsmState = SdStates::UPDATE_SD_INFO_END;
|
||||||
} else {
|
} else {
|
||||||
sdInfo.cycleCount = 0;
|
sdInfo.cycleCount = 0;
|
||||||
sdInfo.commandExecuted = false;
|
sdInfo.commandPending = false;
|
||||||
sdFsmState = SdStates::GET_INFO;
|
sdFsmState = SdStates::UPDATE_SD_INFO_START;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This lambda checks the non-blocking operation and assigns the new state on success.
|
// This lambda checks the non-blocking operation of the SD card manager and assigns the new
|
||||||
// It returns true for an operation success and false otherwise
|
// state on success. It returns true for an operation success and false otherwise
|
||||||
auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
auto nonBlockingSdcOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
||||||
std::string opPrintout) {
|
std::string opPrintout) {
|
||||||
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
||||||
if (status == SdCardManager::OpStatus::SUCCESS) {
|
if (status == SdCardManager::OpStatus::SUCCESS) {
|
||||||
sdFsmState = newStateOnSuccess;
|
sdFsmState = newStateOnSuccess;
|
||||||
sdInfo.commandExecuted = false;
|
sdInfo.commandPending = false;
|
||||||
sdInfo.cycleCount = 0;
|
sdInfo.cycleCount = 0;
|
||||||
return true;
|
return true;
|
||||||
} else if (sdInfo.cycleCount > 4) {
|
} else if (sdInfo.cycleCount > 4) {
|
||||||
@ -431,26 +564,29 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (sdFsmState == SdStates::GET_INFO) {
|
if (sdFsmState == SdStates::UPDATE_SD_INFO_START) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
// Create updated status file
|
// Create updated status file
|
||||||
result = sdcMan->updateSdCardStateFile();
|
result = sdcMan->updateSdCardStateFile();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
|
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
sdFsmState = SdStates::SET_STATE_SELF;
|
|
||||||
sdInfo.commandExecuted = false;
|
|
||||||
sdInfo.cycleCount = 0;
|
|
||||||
} else {
|
|
||||||
nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sdFsmState == SdStates::SET_STATE_SELF) {
|
|
||||||
if (not sdInfo.commandExecuted) {
|
|
||||||
result = sdcMan->getSdCardsStatus(sdInfo.currentState);
|
result = sdcMan->getSdCardsStatus(sdInfo.currentState);
|
||||||
updateSdInfoOther();
|
updateInternalSdInfo();
|
||||||
|
auto currentlyActiveSdc = sdcMan->getActiveSdCard();
|
||||||
|
// Used/active SD card switches, so mark SD card unusable so other tasks have some time
|
||||||
|
// registering the unavailable SD card.
|
||||||
|
if (not currentlyActiveSdc.has_value() or
|
||||||
|
((currentlyActiveSdc.value() == sd::SdCard::SLOT_0) and
|
||||||
|
(sdInfo.active == sd::SdCard::SLOT_1)) or
|
||||||
|
((currentlyActiveSdc.value() == sd::SdCard::SLOT_1) and
|
||||||
|
(sdInfo.active == sd::SdCard::SLOT_0))) {
|
||||||
|
sdInfo.lockSdCardUsage = true;
|
||||||
|
}
|
||||||
|
if (sdInfo.lockSdCardUsage) {
|
||||||
|
sdcMan->markUnusable();
|
||||||
|
}
|
||||||
if (sdInfo.active != sd::SdCard::SLOT_0 and sdInfo.active != sd::SdCard::SLOT_1) {
|
if (sdInfo.active != sd::SdCard::SLOT_0 and sdInfo.active != sd::SdCard::SLOT_1) {
|
||||||
sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl;
|
sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl;
|
||||||
sdInfo.active = sd::SdCard::SLOT_0;
|
sdInfo.active = sd::SdCard::SLOT_0;
|
||||||
@ -462,7 +598,11 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
sif::info << "Cold redundant SD card configuration, target SD card: "
|
sif::info << "Cold redundant SD card configuration, target SD card: "
|
||||||
<< static_cast<int>(sdInfo.active) << std::endl;
|
<< static_cast<int>(sdInfo.active) << std::endl;
|
||||||
}
|
}
|
||||||
|
SdStates tgtState = SdStates::IDLE;
|
||||||
|
bool skipCycles = sdInfo.lockSdCardUsage;
|
||||||
|
// Need to do different things depending on state of SD card which will be active.
|
||||||
if (sdInfo.activeState == sd::SdState::MOUNTED) {
|
if (sdInfo.activeState == sd::SdState::MOUNTED) {
|
||||||
|
// Already mounted, so we can perform handling of the other side.
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
std::string mountString;
|
std::string mountString;
|
||||||
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
||||||
@ -475,27 +615,57 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
#endif
|
#endif
|
||||||
sdcMan->setActiveSdCard(sdInfo.active);
|
sdcMan->setActiveSdCard(sdInfo.active);
|
||||||
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
||||||
sdFsmState = SdStates::DETERMINE_OTHER;
|
tgtState = SdStates::DETERMINE_OTHER;
|
||||||
} else if (sdInfo.activeState == sd::SdState::OFF) {
|
} else if (sdInfo.activeState == sd::SdState::OFF) {
|
||||||
|
// It's okay to do the delay after swichting active SD on, no one can use it anyway..
|
||||||
sdCardSetup(sdInfo.active, sd::SdState::ON, sdInfo.activeChar, false);
|
sdCardSetup(sdInfo.active, sd::SdState::ON, sdInfo.activeChar, false);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
|
// Do not skip cycles here, would mess up the state machine. We skip the cycles after
|
||||||
|
// the SD card was switched on.
|
||||||
|
skipCycles = false;
|
||||||
|
// Remain on the current state.
|
||||||
|
tgtState = sdFsmState;
|
||||||
} else if (sdInfo.activeState == sd::SdState::ON) {
|
} else if (sdInfo.activeState == sd::SdState::ON) {
|
||||||
sdFsmState = SdStates::MOUNT_SELF;
|
// We can do the delay before mounting where applicable.
|
||||||
|
tgtState = SdStates::MOUNT_SELF;
|
||||||
|
}
|
||||||
|
if (skipCycles) {
|
||||||
|
sdFsmState = SdStates::SKIP_TWO_CYCLES_IF_SD_LOCKED;
|
||||||
|
fsmStateAfterDelay = tgtState;
|
||||||
|
sdInfo.skippedCyclesCount = 0;
|
||||||
|
} else {
|
||||||
|
sdFsmState = tgtState;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
||||||
sdInfo.activeState = sd::SdState::ON;
|
sdInfo.activeState = sd::SdState::ON;
|
||||||
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
||||||
|
// Skip the two cycles now.
|
||||||
|
if (sdInfo.lockSdCardUsage) {
|
||||||
|
sdFsmState = SdStates::SKIP_TWO_CYCLES_IF_SD_LOCKED;
|
||||||
|
fsmStateAfterDelay = SdStates::MOUNT_SELF;
|
||||||
|
sdInfo.skippedCyclesCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sdFsmState == SdStates::SKIP_TWO_CYCLES_IF_SD_LOCKED) {
|
||||||
|
sdInfo.skippedCyclesCount++;
|
||||||
|
// Count to three because this branch will run in the same FSM cycle.
|
||||||
|
if (sdInfo.skippedCyclesCount == 3) {
|
||||||
|
sdFsmState = fsmStateAfterDelay;
|
||||||
|
fsmStateAfterDelay = SdStates::IDLE;
|
||||||
|
sdInfo.skippedCyclesCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sdFsmState == SdStates::MOUNT_SELF) {
|
if (sdFsmState == SdStates::MOUNT_SELF) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
if (nonBlockingSdcOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
||||||
sdcMan->setActiveSdCard(sdInfo.active);
|
sdcMan->setActiveSdCard(sdInfo.active);
|
||||||
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
||||||
sdInfo.activeState = sd::SdState::MOUNTED;
|
sdInfo.activeState = sd::SdState::MOUNTED;
|
||||||
@ -532,23 +702,33 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
if (sdFsmState == SdStates::SET_STATE_OTHER) {
|
if (sdFsmState == SdStates::SET_STATE_OTHER) {
|
||||||
// Set state of other SD card to ON or OFF, depending on redundancy mode
|
// Set state of other SD card to ON or OFF, depending on redundancy mode
|
||||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false);
|
result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
if (nonBlockingSdcOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
||||||
"Switching off other SD card")) {
|
"Switching off other SD card")) {
|
||||||
|
sdInfo.otherState = sd::SdState::OFF;
|
||||||
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
||||||
|
} else {
|
||||||
|
// Continue.. avoid being stuck here..
|
||||||
|
sdFsmState = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE;
|
||||||
sdInfo.otherState = sd::SdState::OFF;
|
sdInfo.otherState = sd::SdState::OFF;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false);
|
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
||||||
"Switching on other SD card")) {
|
"Switching on other SD card")) {
|
||||||
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
|
} else {
|
||||||
|
// Contnue.. avoid being stuck here.
|
||||||
|
sdFsmState = SdStates::MOUNT_UNMOUNT_OTHER;
|
||||||
sdInfo.otherState = sd::SdState::ON;
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
}
|
}
|
||||||
@ -559,21 +739,25 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
if (sdFsmState == SdStates::MOUNT_UNMOUNT_OTHER) {
|
if (sdFsmState == SdStates::MOUNT_UNMOUNT_OTHER) {
|
||||||
// Mount or unmount other SD card, depending on redundancy mode
|
// Mount or unmount other SD card, depending on redundancy mode
|
||||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
if (nonBlockingSdcOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
||||||
sdInfo.otherState = sd::SdState::ON;
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
|
} else {
|
||||||
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
|
sdFsmState = SdStates::SET_STATE_OTHER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) {
|
if (nonBlockingSdcOpChecking(SdStates::UPDATE_SD_INFO_END, 4, "Mounting other SD card")) {
|
||||||
sdInfo.otherState = sd::SdState::MOUNTED;
|
sdInfo.otherState = sd::SdState::MOUNTED;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
||||||
}
|
}
|
||||||
@ -582,14 +766,17 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
|
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
|
||||||
sdFsmState = SdStates::UPDATE_INFO;
|
sdFsmState = SdStates::UPDATE_SD_INFO_END;
|
||||||
} else if (sdFsmState == SdStates::UPDATE_INFO) {
|
} else if (sdFsmState == SdStates::UPDATE_SD_INFO_END) {
|
||||||
// Update status file
|
// Update status file
|
||||||
result = sdcMan->updateSdCardStateFile();
|
result = sdcMan->updateSdCardStateFile();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl;
|
sif::warning << "CoreController: Updating SD card state file failed" << std::endl;
|
||||||
}
|
}
|
||||||
sdInfo.commandExecuted = false;
|
updateInternalSdInfo();
|
||||||
|
// Mark usable again in any case.
|
||||||
|
sdcMan->markUsable();
|
||||||
|
sdInfo.commandPending = false;
|
||||||
sdFsmState = SdStates::IDLE;
|
sdFsmState = SdStates::IDLE;
|
||||||
sdInfo.cycleCount = 0;
|
sdInfo.cycleCount = 0;
|
||||||
sdcMan->setBlocking(false);
|
sdcMan->setBlocking(false);
|
||||||
@ -599,8 +786,16 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
actionHelper.finish(true, sdCommandingInfo.commander, sdCommandingInfo.actionId,
|
actionHelper.finish(true, sdCommandingInfo.commander, sdCommandingInfo.actionId,
|
||||||
returnvalue::OK);
|
returnvalue::OK);
|
||||||
}
|
}
|
||||||
|
const char *modeStr = "UNKNOWN";
|
||||||
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
|
modeStr = "COLD REDUNDANT";
|
||||||
|
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||||
|
modeStr = "HOT REDUNDANT";
|
||||||
|
}
|
||||||
|
sif::info << "SD card update into " << modeStr
|
||||||
|
<< " mode finished. Active SD: " << sdInfo.activeChar << std::endl;
|
||||||
if (not sdInfo.initFinished) {
|
if (not sdInfo.initFinished) {
|
||||||
updateSdInfoOther();
|
updateInternalSdInfo();
|
||||||
sdInfo.initFinished = true;
|
sdInfo.initFinished = true;
|
||||||
sif::info << "SD card initialization finished" << std::endl;
|
sif::info << "SD card initialization finished" << std::endl;
|
||||||
}
|
}
|
||||||
@ -797,59 +992,152 @@ ReturnValue_t CoreController::initVersionFile() {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy,
|
MessageQueueId_t commandedBy,
|
||||||
const uint8_t *data, size_t size) {
|
const uint8_t *data, size_t size) {
|
||||||
// TODO: Packet definition for clean deserialization
|
core::ListDirectoryCmdBase parser(data, size);
|
||||||
// 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
|
ReturnValue_t result = parser.parse();
|
||||||
// null termination, at least 7 bytes for minimum target file name /tmp/a with
|
if (result != returnvalue::OK) {
|
||||||
// null termination.
|
return result;
|
||||||
if (size < 14) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
|
||||||
}
|
}
|
||||||
// We could also make -l optional, but I can't think of a reason why to not use -l..
|
|
||||||
|
|
||||||
// This flag specifies to run ls with -a
|
std::ostringstream oss("ls -l", std::ostringstream::ate);
|
||||||
bool aFlag = data[0];
|
if (parser.aFlagSet()) {
|
||||||
data += 1;
|
|
||||||
// This flag specifies to run ls with -R
|
|
||||||
bool RFlag = data[1];
|
|
||||||
data += 1;
|
|
||||||
|
|
||||||
size_t remainingSize = size - 2;
|
|
||||||
// One larger for null termination, which prevents undefined behaviour if the sent
|
|
||||||
// strings are not 0 terminated properly
|
|
||||||
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
|
|
||||||
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
|
|
||||||
const char *currentCharPtr = reinterpret_cast<const char *>(repoAndTargetFileBuffer.data());
|
|
||||||
// Full target file name
|
|
||||||
std::string repoName(currentCharPtr);
|
|
||||||
size_t repoLength = repoName.length();
|
|
||||||
// The other string needs to be at least one letter plus NULL termination to be valid at all
|
|
||||||
// The first string also needs to be NULL terminated, but the termination is not included
|
|
||||||
// in the string length, so this is subtracted from the remaining size as well
|
|
||||||
if (repoLength > remainingSize - 3) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
|
||||||
}
|
|
||||||
// The file length will not include the NULL termination, so we skip it
|
|
||||||
currentCharPtr += repoLength + 1;
|
|
||||||
std::string targetFileName(currentCharPtr);
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "ls -l";
|
|
||||||
if (aFlag) {
|
|
||||||
oss << "a";
|
oss << "a";
|
||||||
}
|
}
|
||||||
if (RFlag) {
|
if (parser.rFlagSet()) {
|
||||||
oss << "R";
|
oss << "R";
|
||||||
}
|
}
|
||||||
|
|
||||||
oss << " " << repoName << " > " << targetFileName;
|
size_t repoNameLen = 0;
|
||||||
int result = std::system(oss.str().c_str());
|
const char *repoName = parser.getRepoName(repoNameLen);
|
||||||
if (result != 0) {
|
|
||||||
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
oss << " " << repoName << " > " << LIST_DIR_DUMP_WORK_FILE;
|
||||||
actionHelper.finish(false, commandedBy, actionId);
|
sif::info << "Executing " << oss.str() << " for direct dump";
|
||||||
|
if (parser.compressionOptionSet()) {
|
||||||
|
sif::info << " with compression";
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
sif::info << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
if (parser.compressionOptionSet()) {
|
||||||
|
std::string compressedName = LIST_DIR_DUMP_WORK_FILE + std::string(".gz");
|
||||||
|
oss.str("");
|
||||||
|
oss << "gzip " << LIST_DIR_DUMP_WORK_FILE;
|
||||||
|
ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
oss.str("");
|
||||||
|
// Overwrite the work file with the compressed archive.
|
||||||
|
oss << "mv " << compressedName << " " << LIST_DIR_DUMP_WORK_FILE;
|
||||||
|
ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirListingBuf[8] = parser.compressionOptionSet();
|
||||||
|
// First four bytes reserved for segment index. One byte for compression option information
|
||||||
|
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
|
||||||
|
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
|
||||||
|
if (ifile.bad()) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
std::error_code e;
|
||||||
|
dumpContext.totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
dumpContext.segmentIdx = 0;
|
||||||
|
dumpContext.dumpedBytes = 0;
|
||||||
|
size_t nextDumpLen = 0;
|
||||||
|
size_t dummy = 0;
|
||||||
|
dumpContext.maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
|
||||||
|
dumpContext.listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
|
||||||
|
uint32_t chunks = dumpContext.totalFileSize / dumpContext.maxDumpLen;
|
||||||
|
if (dumpContext.totalFileSize % dumpContext.maxDumpLen != 0) {
|
||||||
|
chunks++;
|
||||||
|
}
|
||||||
|
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
|
||||||
|
dirListingBuf.size() - sizeof(uint32_t),
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
while (dumpContext.dumpedBytes < dumpContext.totalFileSize) {
|
||||||
|
ifile.seekg(dumpContext.dumpedBytes, std::ios::beg);
|
||||||
|
nextDumpLen = dumpContext.maxDumpLen;
|
||||||
|
if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) {
|
||||||
|
nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes;
|
||||||
|
}
|
||||||
|
SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy,
|
||||||
|
dirListingBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||||
|
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + dumpContext.listingDataOffset),
|
||||||
|
nextDumpLen);
|
||||||
|
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
|
||||||
|
dumpContext.listingDataOffset + nextDumpLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
dumpContext.segmentIdx++;
|
||||||
|
dumpContext.dumpedBytes += nextDumpLen;
|
||||||
|
// Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles.
|
||||||
|
if (dumpContext.segmentIdx == 10) {
|
||||||
|
dumpContext.active = true;
|
||||||
|
dumpContext.firstDump = true;
|
||||||
|
dumpContext.commander = commandedBy;
|
||||||
|
dumpContext.actionId = actionId;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t *data, size_t size) {
|
||||||
|
core::ListDirectoryIntoFile parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream oss("ls -l", std::ostringstream::ate);
|
||||||
|
if (parser.aFlagSet()) {
|
||||||
|
oss << "a";
|
||||||
|
}
|
||||||
|
if (parser.rFlagSet()) {
|
||||||
|
oss << "R";
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t repoNameLen = 0;
|
||||||
|
const char *repoName = parser.getRepoName(repoNameLen);
|
||||||
|
size_t targetFileNameLen = 0;
|
||||||
|
const char *targetFileName = parser.getTargetName(targetFileNameLen);
|
||||||
|
oss << " " << repoName << " > " << targetFileName;
|
||||||
|
sif::info << "Executing list directory request, command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compression will add a .gz ending. I don't have any issue with this, it makes it explicit
|
||||||
|
// that this is a compressed file.
|
||||||
|
if (parser.compressionOptionSet()) {
|
||||||
|
oss.str("");
|
||||||
|
oss << "gzip " << targetFileName;
|
||||||
|
sif::info << "Compressing directory listing: " << oss.str() << std::endl;
|
||||||
|
ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initBootCopyFile() {
|
ReturnValue_t CoreController::initBootCopyFile() {
|
||||||
@ -977,7 +1265,7 @@ ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy co
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::updateSdInfoOther() {
|
void CoreController::updateInternalSdInfo() {
|
||||||
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
||||||
sdInfo.activeChar = "0";
|
sdInfo.activeChar = "0";
|
||||||
sdInfo.otherChar = "1";
|
sdInfo.otherChar = "1";
|
||||||
@ -1237,7 +1525,7 @@ void CoreController::performMountedSdCardOperations() {
|
|||||||
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
|
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
|
||||||
if (not performOneShotSdCardOpsSwitch) {
|
if (not performOneShotSdCardOpsSwitch) {
|
||||||
std::ostringstream path;
|
std::ostringstream path;
|
||||||
path << mntPoint << "/" << CONF_FOLDER;
|
path << mntPoint << "/" << core::CONF_FOLDER;
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not std::filesystem::exists(path.str()), e) {
|
if (not std::filesystem::exists(path.str()), e) {
|
||||||
bool created = std::filesystem::create_directory(path.str(), e);
|
bool created = std::filesystem::create_directory(path.str(), e);
|
||||||
@ -1923,11 +2211,20 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
|||||||
} else if (sourceDir == SwUpdateSources::TMP_DIR) {
|
} else if (sourceDir == SwUpdateSources::TMP_DIR) {
|
||||||
prefixPath = path("/tmp");
|
prefixPath = path("/tmp");
|
||||||
}
|
}
|
||||||
path archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME);
|
path archivePath;
|
||||||
|
// It is optionally possible to supply the source file path
|
||||||
|
if (size > 2) {
|
||||||
|
archivePath = prefixPath / std::string(reinterpret_cast<const char *>(data + 2), size - 2);
|
||||||
|
} else {
|
||||||
|
archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME);
|
||||||
|
}
|
||||||
|
sif::info << "Updating with archive path " << archivePath << std::endl;
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not exists(archivePath, e)) {
|
if (not exists(archivePath, e)) {
|
||||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
// TODO: Decompressing without limiting memory usage with xz is actually a bit risky..
|
||||||
|
// But has not been an issue so far.
|
||||||
ostringstream cmd("tar -xJf", ios::app);
|
ostringstream cmd("tar -xJf", ios::app);
|
||||||
cmd << " " << archivePath << " -C " << prefixPath;
|
cmd << " " << archivePath << " -C " << prefixPath;
|
||||||
int result = system(cmd.str().c_str());
|
int result = system(cmd.str().c_str());
|
||||||
@ -2010,6 +2307,10 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
|||||||
cmd.str("");
|
cmd.str("");
|
||||||
cmd.clear();
|
cmd.clear();
|
||||||
|
|
||||||
|
// Remove the extracted files to keep directories clean.
|
||||||
|
std::filesystem::remove(strippedImagePath, e);
|
||||||
|
std::filesystem::remove(obswVersionFilePath, e);
|
||||||
|
|
||||||
// TODO: This takes a long time and will block the core controller.. Maybe use command executor?
|
// TODO: This takes a long time and will block the core controller.. Maybe use command executor?
|
||||||
// For now dont care..
|
// For now dont care..
|
||||||
cmd << "writeprotect " << std::to_string(data[0]) << " " << std::to_string(data[1]) << " 1";
|
cmd << "writeprotect " << std::to_string(data[0]) << " " << std::to_string(data[1]) << " 1";
|
||||||
@ -2030,6 +2331,11 @@ bool CoreController::startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mo
|
|||||||
}
|
}
|
||||||
sdFsmState = SdStates::START;
|
sdFsmState = SdStates::START;
|
||||||
sdInfo.active = targetActiveSd;
|
sdInfo.active = targetActiveSd;
|
||||||
|
// If we are going from 2 SD cards to one, lock SD card usage in any case because 1 SD card is
|
||||||
|
// going off.
|
||||||
|
if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT and mode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
|
sdInfo.lockSdCardUsage = true;
|
||||||
|
}
|
||||||
sdInfo.cfgMode = mode;
|
sdInfo.cfgMode = mode;
|
||||||
sdCommandingInfo.actionId = actionId;
|
sdCommandingInfo.actionId = actionId;
|
||||||
sdCommandingInfo.commander = commander;
|
sdCommandingInfo.commander = commander;
|
||||||
@ -2047,7 +2353,86 @@ void CoreController::announceBootCounts() {
|
|||||||
totalBootCount & 0xffffffff);
|
totalBootCount & 0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t CoreController::getCommandQueue() const {
|
||||||
|
return ExtendedControllerBase::getCommandQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::dirListingDumpHandler() {
|
||||||
|
if (dumpContext.firstDump) {
|
||||||
|
dumpContext.firstDump = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t nextDumpLen = 0;
|
||||||
|
size_t dummy = 0;
|
||||||
|
ReturnValue_t result;
|
||||||
|
std::error_code e;
|
||||||
|
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
|
||||||
|
if (ifile.bad()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (dumpContext.dumpedBytes < dumpContext.totalFileSize) {
|
||||||
|
ifile.seekg(dumpContext.dumpedBytes, std::ios::beg);
|
||||||
|
nextDumpLen = dumpContext.maxDumpLen;
|
||||||
|
if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) {
|
||||||
|
nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes;
|
||||||
|
}
|
||||||
|
SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy,
|
||||||
|
dirListingBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||||
|
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + dumpContext.listingDataOffset),
|
||||||
|
nextDumpLen);
|
||||||
|
result =
|
||||||
|
actionHelper.reportData(dumpContext.commander, dumpContext.actionId, dirListingBuf.data(),
|
||||||
|
dumpContext.listingDataOffset + nextDumpLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
dumpContext.active = false;
|
||||||
|
actionHelper.finish(false, dumpContext.commander, dumpContext.actionId, result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dumpContext.segmentIdx++;
|
||||||
|
dumpContext.dumpedBytes += nextDumpLen;
|
||||||
|
// Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles.
|
||||||
|
if (dumpContext.segmentIdx == 10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dumpContext.dumpedBytes >= dumpContext.totalFileSize) {
|
||||||
|
actionHelper.finish(true, dumpContext.commander, dumpContext.actionId, result);
|
||||||
|
dumpContext.active = false;
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CoreController::isNumber(const std::string &s) {
|
bool CoreController::isNumber(const std::string &s) {
|
||||||
return !s.empty() && std::find_if(s.begin(), s.end(),
|
return !s.empty() && std::find_if(s.begin(), s.end(),
|
||||||
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||||
|
ParameterWrapper *parameterWrapper,
|
||||||
|
const ParameterWrapper *newValues,
|
||||||
|
uint16_t startAtIndex) {
|
||||||
|
if (domainId != 0) {
|
||||||
|
return HasParametersIF::INVALID_DOMAIN_ID;
|
||||||
|
}
|
||||||
|
if (uniqueIdentifier >= ParamId::NUM_IDS) {
|
||||||
|
return HasParametersIF::INVALID_IDENTIFIER_ID;
|
||||||
|
}
|
||||||
|
uint8_t newPrefSd;
|
||||||
|
ReturnValue_t result = newValues->getElement(&newPrefSd);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Only SD card 0 (0) and 1 (1) are allowed values.
|
||||||
|
if (newPrefSd > 1) {
|
||||||
|
return HasParametersIF::INVALID_VALUE;
|
||||||
|
}
|
||||||
|
result = sdcMan->setPreferredSdCard(static_cast<sd::SdCard>(newPrefSd));
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
parameterWrapper->set(prefSdRaw);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <fsfw/container/DynamicFIFO.h>
|
#include <fsfw/container/DynamicFIFO.h>
|
||||||
#include <fsfw/container/SimpleRingBuffer.h>
|
#include <fsfw/container/SimpleRingBuffer.h>
|
||||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||||
|
#include <fsfw/parameters/ParameterHelper.h>
|
||||||
|
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||||
#include <libxiphos.h>
|
#include <libxiphos.h>
|
||||||
#include <mission/acs/archive/GPSDefinitions.h>
|
#include <mission/acs/archive/GPSDefinitions.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
@ -16,17 +18,11 @@
|
|||||||
#include "bsp_q7s/fs/SdCardManager.h"
|
#include "bsp_q7s/fs/SdCardManager.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||||
|
#include "mission/sysDefs.h"
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
class SdCardManager;
|
class SdCardManager;
|
||||||
|
|
||||||
namespace xsc {
|
|
||||||
|
|
||||||
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
|
||||||
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
|
||||||
|
|
||||||
} // namespace xsc
|
|
||||||
|
|
||||||
struct RebootFile {
|
struct RebootFile {
|
||||||
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
||||||
|
|
||||||
@ -48,8 +44,10 @@ struct RebootFile {
|
|||||||
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
|
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CoreController : public ExtendedControllerBase {
|
class CoreController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||||
public:
|
public:
|
||||||
|
enum ParamId : uint8_t { PREF_SD = 0, NUM_IDS };
|
||||||
|
|
||||||
static xsc::Chip CURRENT_CHIP;
|
static xsc::Chip CURRENT_CHIP;
|
||||||
static xsc::Copy CURRENT_COPY;
|
static xsc::Copy CURRENT_COPY;
|
||||||
|
|
||||||
@ -57,23 +55,18 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
|
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
|
||||||
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
|
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
|
||||||
|
|
||||||
static constexpr char CONF_FOLDER[] = "conf";
|
|
||||||
|
|
||||||
static constexpr char VERSION_FILE_NAME[] = "version.txt";
|
|
||||||
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
|
|
||||||
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
|
|
||||||
|
|
||||||
const std::string VERSION_FILE =
|
const std::string VERSION_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::VERSION_FILE_NAME);
|
||||||
const std::string REBOOT_FILE =
|
const std::string REBOOT_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_FILE_NAME);
|
||||||
const std::string BACKUP_TIME_FILE =
|
const std::string BACKUP_TIME_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
|
||||||
|
|
||||||
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
|
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
|
||||||
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
||||||
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
|
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
|
||||||
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
|
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
|
||||||
|
static constexpr char LIST_DIR_DUMP_WORK_FILE[] = "/tmp/dir_listing.tmp";
|
||||||
|
|
||||||
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
|
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
|
||||||
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
|
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
|
||||||
@ -129,8 +122,8 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
enum class SdStates {
|
enum class SdStates {
|
||||||
NONE,
|
NONE,
|
||||||
START,
|
START,
|
||||||
GET_INFO,
|
UPDATE_SD_INFO_START,
|
||||||
SET_STATE_SELF,
|
SKIP_TWO_CYCLES_IF_SD_LOCKED,
|
||||||
MOUNT_SELF,
|
MOUNT_SELF,
|
||||||
// Determine operations for other SD card, depending on redundancy configuration
|
// Determine operations for other SD card, depending on redundancy configuration
|
||||||
DETERMINE_OTHER,
|
DETERMINE_OTHER,
|
||||||
@ -140,7 +133,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
// Skip period because the shell command used to generate the info file sometimes is
|
// Skip period because the shell command used to generate the info file sometimes is
|
||||||
// missing the last performed operation if executed too early
|
// missing the last performed operation if executed too early
|
||||||
SKIP_CYCLE_BEFORE_INFO_UPDATE,
|
SKIP_CYCLE_BEFORE_INFO_UPDATE,
|
||||||
UPDATE_INFO,
|
UPDATE_SD_INFO_END,
|
||||||
// SD initialization done
|
// SD initialization done
|
||||||
IDLE
|
IDLE
|
||||||
};
|
};
|
||||||
@ -152,23 +145,30 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
SdCardManager* sdcMan = nullptr;
|
SdCardManager* sdcMan = nullptr;
|
||||||
MessageQueueIF* eventQueue = nullptr;
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
|
|
||||||
|
uint8_t prefSdRaw = sd::SdCard::SLOT_0;
|
||||||
SdStates sdFsmState = SdStates::START;
|
SdStates sdFsmState = SdStates::START;
|
||||||
|
SdStates fsmStateAfterDelay = SdStates::IDLE;
|
||||||
enum SdCfgMode { PASSIVE, COLD_REDUNDANT, HOT_REDUNDANT };
|
enum SdCfgMode { PASSIVE, COLD_REDUNDANT, HOT_REDUNDANT };
|
||||||
|
|
||||||
struct SdFsmParams {
|
struct SdFsmParams {
|
||||||
SdCfgMode cfgMode = SdCfgMode::COLD_REDUNDANT;
|
SdCfgMode cfgMode = SdCfgMode::COLD_REDUNDANT;
|
||||||
sd::SdCard active = sd::SdCard::NONE;
|
sd::SdCard active = sd::SdCard::NONE;
|
||||||
sd::SdCard other = sd::SdCard::NONE;
|
sd::SdCard other = sd::SdCard::NONE;
|
||||||
sd::SdState activeState = sd::SdState::OFF;
|
|
||||||
sd::SdState otherState = sd::SdState::OFF;
|
|
||||||
std::string activeChar = "0";
|
std::string activeChar = "0";
|
||||||
std::string otherChar = "1";
|
std::string otherChar = "1";
|
||||||
|
sd::SdState activeState = sd::SdState::OFF;
|
||||||
|
sd::SdState otherState = sd::SdState::OFF;
|
||||||
std::pair<bool, bool> mountSwitch = {true, true};
|
std::pair<bool, bool> mountSwitch = {true, true};
|
||||||
// Used to track whether a command was executed
|
// This flag denotes that the SD card usage is locked. This is relevant if SD cards go off
|
||||||
bool commandExecuted = true;
|
// to leave appliation using the SD cards some time to detect the SD card is not usable anymore.
|
||||||
|
// This is relevant if the active SD card is being switched. The SD card will also be locked
|
||||||
|
// when going from hot-redundant mode to cold-redundant mode.
|
||||||
|
bool lockSdCardUsage = false;
|
||||||
|
bool commandPending = true;
|
||||||
bool initFinished = false;
|
bool initFinished = false;
|
||||||
SdCardManager::SdStatePair currentState;
|
SdCardManager::SdStatePair currentState;
|
||||||
uint16_t cycleCount = 0;
|
uint16_t cycleCount = 0;
|
||||||
|
uint16_t skippedCyclesCount = 0;
|
||||||
} sdInfo;
|
} sdInfo;
|
||||||
|
|
||||||
struct SdCommanding {
|
struct SdCommanding {
|
||||||
@ -177,6 +177,20 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
DeviceCommandId_t actionId;
|
DeviceCommandId_t actionId;
|
||||||
} sdCommandingInfo;
|
} sdCommandingInfo;
|
||||||
|
|
||||||
|
struct DirListingDumpContext {
|
||||||
|
bool active;
|
||||||
|
bool firstDump;
|
||||||
|
size_t dumpedBytes;
|
||||||
|
size_t totalFileSize;
|
||||||
|
size_t listingDataOffset;
|
||||||
|
size_t maxDumpLen;
|
||||||
|
uint32_t segmentIdx;
|
||||||
|
MessageQueueId_t commander = MessageQueueIF::NO_QUEUE;
|
||||||
|
DeviceCommandId_t actionId;
|
||||||
|
};
|
||||||
|
std::array<uint8_t, 1024> dirListingBuf{};
|
||||||
|
DirListingDumpContext dumpContext{};
|
||||||
|
|
||||||
RebootFile rebootFile = {};
|
RebootFile rebootFile = {};
|
||||||
|
|
||||||
CommandExecutor cmdExecutor;
|
CommandExecutor cmdExecutor;
|
||||||
@ -210,10 +224,16 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
core::HkSet hkSet;
|
core::HkSet hkSet;
|
||||||
|
|
||||||
|
ParameterHelper paramHelper;
|
||||||
|
|
||||||
#if OBSW_SD_CARD_MUST_BE_ON == 1
|
#if OBSW_SD_CARD_MUST_BE_ON == 1
|
||||||
bool remountAttemptFlag = true;
|
bool remountAttemptFlag = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
|
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||||
|
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||||
|
uint16_t startAtIndex) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
|
|
||||||
@ -232,7 +252,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
void initPrint();
|
void initPrint();
|
||||||
|
|
||||||
ReturnValue_t sdStateMachine();
|
ReturnValue_t sdStateMachine();
|
||||||
void updateSdInfoOther();
|
void updateInternalSdInfo();
|
||||||
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
||||||
bool printOutput = true);
|
bool printOutput = true);
|
||||||
ReturnValue_t executeSwUpdate(SwUpdateSources sourceDir, const uint8_t* data, size_t size);
|
ReturnValue_t executeSwUpdate(SwUpdateSources sourceDir, const uint8_t* data, size_t size);
|
||||||
@ -245,6 +265,12 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size);
|
const uint8_t* data, size_t size);
|
||||||
|
ReturnValue_t actionListDirectoryDumpDirectly(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size);
|
||||||
|
|
||||||
|
ReturnValue_t actionListDirectoryCommonCommandCreator(const uint8_t* data, size_t size,
|
||||||
|
std::ostringstream& oss);
|
||||||
|
|
||||||
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
|
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
|
||||||
ReturnValue_t actionReboot(const uint8_t* data, size_t size);
|
ReturnValue_t actionReboot(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
@ -262,6 +288,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
void rewriteRebootFile(RebootFile file);
|
void rewriteRebootFile(RebootFile file);
|
||||||
void announceBootCounts();
|
void announceBootCounts();
|
||||||
void readHkData();
|
void readHkData();
|
||||||
|
void dirListingDumpHandler();
|
||||||
bool isNumber(const std::string& s);
|
bool isNumber(const std::string& s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#include <linux/com/SyrlinksComHandler.h>
|
#include <linux/com/SyrlinksComHandler.h>
|
||||||
#include <linux/payload/PlocMemoryDumper.h>
|
#include <linux/payload/PlocMemoryDumper.h>
|
||||||
#include <linux/payload/PlocMpsocHandler.h>
|
#include <linux/payload/PlocMpsocHandler.h>
|
||||||
#include <linux/payload/PlocMpsocHelper.h>
|
#include <linux/payload/PlocMpsocSpecialComHelper.h>
|
||||||
#include <linux/payload/PlocSupervisorHandler.h>
|
#include <linux/payload/PlocSupervisorHandler.h>
|
||||||
#include <linux/payload/ScexUartReader.h>
|
#include <linux/payload/ScexUartReader.h>
|
||||||
#include <linux/payload/plocMpscoDefs.h>
|
#include <linux/payload/plocMpsocHelpers.h>
|
||||||
#include <linux/power/CspComIF.h>
|
#include <linux/power/CspComIF.h>
|
||||||
#include <mission/acs/GyrL3gCustomHandler.h>
|
#include <mission/acs/GyrL3gCustomHandler.h>
|
||||||
#include <mission/acs/MgmLis3CustomHandler.h>
|
#include <mission/acs/MgmLis3CustomHandler.h>
|
||||||
@ -27,8 +27,9 @@
|
|||||||
#include <mission/system/acs/ImtqAssembly.h>
|
#include <mission/system/acs/ImtqAssembly.h>
|
||||||
#include <mission/system/acs/StrAssembly.h>
|
#include <mission/system/acs/StrAssembly.h>
|
||||||
#include <mission/system/acs/StrFdir.h>
|
#include <mission/system/acs/StrFdir.h>
|
||||||
|
#include <mission/system/com/SyrlinksAssembly.h>
|
||||||
#include <mission/system/objects/CamSwitcher.h>
|
#include <mission/system/objects/CamSwitcher.h>
|
||||||
#include <mission/system/objects/SyrlinksAssembly.h>
|
#include <mission/system/tcs/TmpDevFdir.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||||
@ -62,17 +63,15 @@
|
|||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
#include "mission/system/com/SyrlinksFdir.h"
|
#include "mission/system/com/SyrlinksFdir.h"
|
||||||
#include "mission/system/com/comModeTree.h"
|
#include "mission/system/com/comModeTree.h"
|
||||||
#include "mission/system/fdir/RtdFdir.h"
|
|
||||||
#include "mission/system/objects/TcsBoardAssembly.h"
|
|
||||||
#include "mission/system/power/GomspacePowerFdir.h"
|
#include "mission/system/power/GomspacePowerFdir.h"
|
||||||
|
#include "mission/system/tcs/RtdFdir.h"
|
||||||
|
#include "mission/system/tcs/TcsBoardAssembly.h"
|
||||||
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/system/tree/payloadModeTree.h"
|
#include "mission/system/tree/payloadModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
|
||||||
#include "mission/tmtc/tmFilters.h"
|
#include "mission/tmtc/tmFilters.h"
|
||||||
#include "mission/utility/GlobalConfigHandler.h"
|
#include "mission/utility/GlobalConfigHandler.h"
|
||||||
#include "tmtc/pusIds.h"
|
#include "tmtc/pusIds.h"
|
||||||
|
|
||||||
using gpio::Direction;
|
|
||||||
using gpio::Levels;
|
|
||||||
#if OBSW_TEST_LIBGPIOD == 1
|
#if OBSW_TEST_LIBGPIOD == 1
|
||||||
#include "linux/boardtest/LibgpiodTest.h"
|
#include "linux/boardtest/LibgpiodTest.h"
|
||||||
#endif
|
#endif
|
||||||
@ -123,6 +122,9 @@ using gpio::Levels;
|
|||||||
#include "mission/system/acs/AcsBoardAssembly.h"
|
#include "mission/system/acs/AcsBoardAssembly.h"
|
||||||
#include "mission/tmtc/TmFunnelHandler.h"
|
#include "mission/tmtc/TmFunnelHandler.h"
|
||||||
|
|
||||||
|
using gpio::Direction;
|
||||||
|
using gpio::Levels;
|
||||||
|
|
||||||
ResetArgs RESET_ARGS_GNSS;
|
ResetArgs RESET_ARGS_GNSS;
|
||||||
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
||||||
std::atomic_bool PTME_LOCKED = false;
|
std::atomic_bool PTME_LOCKED = false;
|
||||||
@ -164,6 +166,7 @@ void ObjectFactory::createTmpComponents() {
|
|||||||
new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE));
|
new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE));
|
||||||
auto* tmpDevHandler =
|
auto* tmpDevHandler =
|
||||||
new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]);
|
new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]);
|
||||||
|
tmpDevHandler->setCustomFdir(new TmpDevFdir(tmpDevIds[idx].first));
|
||||||
tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||||
// TODO: Remove this after TCS subsystem was added
|
// TODO: Remove this after TCS subsystem was added
|
||||||
// These devices are connected to the 3V3 stack and should be powered permanently. Therefore,
|
// These devices are connected to the 3V3 stack and should be powered permanently. Therefore,
|
||||||
@ -186,7 +189,6 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF,
|
|||||||
*i2cComIF = new I2cComIF(objects::I2C_COM_IF);
|
*i2cComIF = new I2cComIF(objects::I2C_COM_IF);
|
||||||
*uartComIF = new SerialComIF(objects::UART_COM_IF);
|
*uartComIF = new SerialComIF(objects::UART_COM_IF);
|
||||||
*spiMainComIF = new SpiComIF(objects::SPI_MAIN_COM_IF, q7s::SPI_DEFAULT_DEV, **gpioComIF);
|
*spiMainComIF = new SpiComIF(objects::SPI_MAIN_COM_IF, q7s::SPI_DEFAULT_DEV, **gpioComIF);
|
||||||
//*spiRWComIF = new SpiComIF(objects::SPI_RW_COM_IF, q7s::SPI_RW_DEV, **gpioComIF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher,
|
void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher,
|
||||||
@ -194,7 +196,6 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
|
|||||||
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_SIZE, addresses::P60DOCK, 500);
|
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_SIZE, addresses::P60DOCK, 500);
|
||||||
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU1, 500);
|
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU1, 500);
|
||||||
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU2, 500);
|
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU2, 500);
|
||||||
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_SIZE, addresses::ACU, 500);
|
|
||||||
|
|
||||||
auto p60Fdir = new GomspacePowerFdir(objects::P60DOCK_HANDLER);
|
auto p60Fdir = new GomspacePowerFdir(objects::P60DOCK_HANDLER);
|
||||||
P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF,
|
P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF,
|
||||||
@ -208,9 +209,12 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
|
|||||||
Pdu2Handler* pdu2handler = new Pdu2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF,
|
Pdu2Handler* pdu2handler = new Pdu2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF,
|
||||||
pdu2CspCookie, pdu2Fdir, enableHkSets);
|
pdu2CspCookie, pdu2Fdir, enableHkSets);
|
||||||
|
|
||||||
|
#if OBSW_ADD_GOMSPACE_ACU == 1
|
||||||
|
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_SIZE, addresses::ACU, 500);
|
||||||
auto acuFdir = new GomspacePowerFdir(objects::ACU_HANDLER);
|
auto acuFdir = new GomspacePowerFdir(objects::ACU_HANDLER);
|
||||||
ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie,
|
ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie,
|
||||||
acuFdir, enableHkSets);
|
acuFdir, enableHkSets);
|
||||||
|
#endif
|
||||||
auto pcduHandler = new PcduHandler(objects::PCDU_HANDLER, 50);
|
auto pcduHandler = new PcduHandler(objects::PCDU_HANDLER, 50);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,7 +224,9 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
|
|||||||
p60dockhandler->setModeNormal();
|
p60dockhandler->setModeNormal();
|
||||||
pdu1handler->setModeNormal();
|
pdu1handler->setModeNormal();
|
||||||
pdu2handler->setModeNormal();
|
pdu2handler->setModeNormal();
|
||||||
|
#if OBSW_ADD_GOMSPACE_ACU == 1
|
||||||
acuhandler->setModeNormal();
|
acuhandler->setModeNormal();
|
||||||
|
#endif
|
||||||
if (pwrSwitcher != nullptr) {
|
if (pwrSwitcher != nullptr) {
|
||||||
*pwrSwitcher = pcduHandler;
|
*pwrSwitcher = pcduHandler;
|
||||||
}
|
}
|
||||||
@ -234,20 +240,7 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
|
|||||||
|
|
||||||
ReturnValue_t ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF,
|
ReturnValue_t ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF,
|
||||||
Stack5VHandler& stackHandler) {
|
Stack5VHandler& stackHandler) {
|
||||||
using namespace gpio;
|
createRadSensorChipSelect(gpioComIF);
|
||||||
if (gpioComIF == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
GpioCookie* gpioCookieRadSensor = new GpioCookie;
|
|
||||||
std::stringstream consumer;
|
|
||||||
consumer << "0x" << std::hex << objects::RAD_SENSOR;
|
|
||||||
GpiodRegularByLineName* gpio = new GpiodRegularByLineName(
|
|
||||||
q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), Direction::OUT, Levels::HIGH);
|
|
||||||
gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio);
|
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_RADFET, consumer.str(), Direction::OUT,
|
|
||||||
Levels::LOW);
|
|
||||||
gpioCookieRadSensor->addGpio(gpioIds::ENABLE_RADFET, gpio);
|
|
||||||
gpioChecker(gpioComIF->addGpios(gpioCookieRadSensor), "RAD sensor");
|
|
||||||
|
|
||||||
SpiCookie* spiCookieRadSensor =
|
SpiCookie* spiCookieRadSensor =
|
||||||
new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, RAD_SENSOR::READ_SIZE,
|
new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, RAD_SENSOR::READ_SIZE,
|
||||||
@ -361,7 +354,7 @@ void ObjectFactory::createAcsBoardGpios(GpioCookie& cookie) {
|
|||||||
|
|
||||||
void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF,
|
void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF,
|
||||||
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher,
|
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher,
|
||||||
bool enableHkSets) {
|
bool enableHkSets, adis1650x::Type adisType) {
|
||||||
using namespace gpio;
|
using namespace gpio;
|
||||||
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
||||||
createAcsBoardGpios(*gpioCookieAcsBoard);
|
createAcsBoardGpios(*gpioCookieAcsBoard);
|
||||||
@ -447,9 +440,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
|
|||||||
new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, adis1650x::MAXIMUM_REPLY_SIZE,
|
new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, adis1650x::MAXIMUM_REPLY_SIZE,
|
||||||
spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED);
|
spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED);
|
||||||
spiCookie->setMutexParams(MutexIF::TimeoutType::WAITING, spi::ACS_BOARD_CS_TIMEOUT);
|
spiCookie->setMutexParams(MutexIF::TimeoutType::WAITING, spi::ACS_BOARD_CS_TIMEOUT);
|
||||||
auto adisHandler =
|
auto adisHandler = new GyrAdis1650XHandler(objects::GYRO_0_ADIS_HANDLER,
|
||||||
new GyrAdis1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::ACS_BOARD_POLLING_TASK,
|
objects::ACS_BOARD_POLLING_TASK, spiCookie, adisType);
|
||||||
spiCookie, adis1650x::Type::ADIS16505);
|
|
||||||
fdir = new AcsBoardFdir(objects::GYRO_0_ADIS_HANDLER);
|
fdir = new AcsBoardFdir(objects::GYRO_0_ADIS_HANDLER);
|
||||||
adisHandler->setCustomFdir(fdir);
|
adisHandler->setCustomFdir(fdir);
|
||||||
assemblyChildren[4] = adisHandler;
|
assemblyChildren[4] = adisHandler;
|
||||||
@ -482,9 +474,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
|
|||||||
new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, adis1650x::MAXIMUM_REPLY_SIZE,
|
new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, adis1650x::MAXIMUM_REPLY_SIZE,
|
||||||
spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED);
|
spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED);
|
||||||
spiCookie->setMutexParams(MutexIF::TimeoutType::WAITING, spi::ACS_BOARD_CS_TIMEOUT);
|
spiCookie->setMutexParams(MutexIF::TimeoutType::WAITING, spi::ACS_BOARD_CS_TIMEOUT);
|
||||||
adisHandler =
|
adisHandler = new GyrAdis1650XHandler(objects::GYRO_2_ADIS_HANDLER,
|
||||||
new GyrAdis1650XHandler(objects::GYRO_2_ADIS_HANDLER, objects::ACS_BOARD_POLLING_TASK,
|
objects::ACS_BOARD_POLLING_TASK, spiCookie, adisType);
|
||||||
spiCookie, adis1650x::Type::ADIS16505);
|
|
||||||
fdir = new AcsBoardFdir(objects::GYRO_2_ADIS_HANDLER);
|
fdir = new AcsBoardFdir(objects::GYRO_2_ADIS_HANDLER);
|
||||||
adisHandler->setCustomFdir(fdir);
|
adisHandler->setCustomFdir(fdir);
|
||||||
assemblyChildren[6] = adisHandler;
|
assemblyChildren[6] = adisHandler;
|
||||||
@ -632,8 +623,8 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
|
|||||||
new SerialCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV,
|
new SerialCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV,
|
||||||
serial::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL);
|
serial::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL);
|
||||||
mpsocCookie->setNoFixedSizeReply();
|
mpsocCookie->setNoFixedSizeReply();
|
||||||
auto plocMpsocHelper = new PlocMPSoCHelper(objects::PLOC_MPSOC_HELPER);
|
auto plocMpsocHelper = new PlocMpsocSpecialComHelper(objects::PLOC_MPSOC_HELPER);
|
||||||
auto* mpsocHandler = new PlocMPSoCHandler(
|
auto* mpsocHandler = new PlocMpsocHandler(
|
||||||
objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie, plocMpsocHelper,
|
objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie, plocMpsocHelper,
|
||||||
Gpio(gpioIds::ENABLE_MPSOC_UART, gpioComIF), objects::PLOC_SUPERVISOR_HANDLER);
|
Gpio(gpioIds::ENABLE_MPSOC_UART, gpioComIF), objects::PLOC_SUPERVISOR_HANDLER);
|
||||||
mpsocHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
mpsocHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||||
@ -653,6 +644,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
|
|||||||
auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
|
auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
|
||||||
Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
|
Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
|
||||||
power::PDU1_CH6_PLOC_12V, *supvHelper);
|
power::PDU1_CH6_PLOC_12V, *supvHelper);
|
||||||
|
supvHandler->setPowerSwitcher(&pwrSwitch);
|
||||||
supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
||||||
static_cast<void>(consumer);
|
static_cast<void>(consumer);
|
||||||
@ -813,7 +805,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
|||||||
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
|
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
|
||||||
auto* hkStore = new PersistentSingleTmStoreTask(
|
auto* hkStore = new PersistentSingleTmStoreTask(
|
||||||
objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc,
|
objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc,
|
||||||
persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance(),
|
persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_CANCELLED, *SdCardManager::instance(),
|
||||||
PTME_LOCKED);
|
PTME_LOCKED);
|
||||||
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
|
|
||||||
@ -1016,3 +1008,20 @@ void ObjectFactory::testAcsBrdAss(AcsBoardAssembly* acsAss) {
|
|||||||
sif::warning << "Sending mode command failed" << std::endl;
|
sif::warning << "Sending mode command failed" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectFactory::createRadSensorChipSelect(LinuxLibgpioIF* gpioIF) {
|
||||||
|
using namespace gpio;
|
||||||
|
if (gpioIF == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GpioCookie* gpioCookieRadSensor = new GpioCookie;
|
||||||
|
std::stringstream consumer;
|
||||||
|
consumer << "0x" << std::hex << objects::RAD_SENSOR;
|
||||||
|
GpiodRegularByLineName* gpio = new GpiodRegularByLineName(
|
||||||
|
q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), Direction::OUT, Levels::HIGH);
|
||||||
|
gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio);
|
||||||
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_RADFET, consumer.str(), Direction::OUT,
|
||||||
|
Levels::LOW);
|
||||||
|
gpioCookieRadSensor->addGpio(gpioIds::ENABLE_RADFET, gpio);
|
||||||
|
gpioChecker(gpioIF->addGpios(gpioCookieRadSensor), "RAD sensor");
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <fsfw/returnvalues/returnvalue.h>
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
|
#include <mission/acs/gyroAdisHelpers.h>
|
||||||
#include <mission/com/CcsdsIpCoreHandler.h>
|
#include <mission/com/CcsdsIpCoreHandler.h>
|
||||||
#include <mission/com/PersistentLogTmStoreTask.h>
|
#include <mission/com/PersistentLogTmStoreTask.h>
|
||||||
#include <mission/genericFactory.h>
|
#include <mission/genericFactory.h>
|
||||||
@ -58,10 +59,12 @@ void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher
|
|||||||
void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF,
|
void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF,
|
||||||
PowerSwitchIF* pwrSwitcher, Stack5VHandler& stackHandler);
|
PowerSwitchIF* pwrSwitcher, Stack5VHandler& stackHandler);
|
||||||
void createTmpComponents();
|
void createTmpComponents();
|
||||||
|
void createRadSensorChipSelect(LinuxLibgpioIF* gpioIF);
|
||||||
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler);
|
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler);
|
||||||
void createAcsBoardGpios(GpioCookie& cookie);
|
void createAcsBoardGpios(GpioCookie& cookie);
|
||||||
void createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF,
|
void createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF,
|
||||||
PowerSwitchIF& pwrSwitcher, bool enableHkSets);
|
PowerSwitchIF& pwrSwitcher, bool enableHkSets,
|
||||||
|
adis1650x::Type adisType);
|
||||||
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable,
|
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable,
|
||||||
HeaterHandler*& heaterHandler);
|
HeaterHandler*& heaterHandler);
|
||||||
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets);
|
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets);
|
||||||
|
@ -302,6 +302,9 @@ void scheduling::initTasks() {
|
|||||||
|
|
||||||
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
||||||
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
||||||
|
#if OBSW_ADD_THERMAL_TEMP_INSERTER == 1
|
||||||
|
tcsSystemTask->addComponent(objects::THERMAL_TEMP_INSERTER);
|
||||||
|
#endif
|
||||||
scheduling::scheduleRtdSensors(tcsSystemTask);
|
scheduling::scheduleRtdSensors(tcsSystemTask);
|
||||||
result = tcsSystemTask->addComponent(objects::TCS_SUBSYSTEM);
|
result = tcsSystemTask->addComponent(objects::TCS_SUBSYSTEM);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -317,12 +320,10 @@ void scheduling::initTasks() {
|
|||||||
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_HEATERS == 1
|
|
||||||
result = tcsSystemTask->addComponent(objects::HEATER_HANDLER);
|
result = tcsSystemTask->addComponent(objects::HEATER_HANDLER);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
|
scheduling::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if OBSW_ADD_SYRLINKS == 1
|
#if OBSW_ADD_SYRLINKS == 1
|
||||||
PeriodicTaskIF* syrlinksCom = factory->createPeriodicTask(
|
PeriodicTaskIF* syrlinksCom = factory->createPeriodicTask(
|
||||||
@ -344,7 +345,6 @@ void scheduling::initTasks() {
|
|||||||
}
|
}
|
||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
|
|
||||||
// TODO: Use regular scheduler for this task
|
|
||||||
#if OBSW_ADD_PLOC_MPSOC == 1
|
#if OBSW_ADD_PLOC_MPSOC == 1
|
||||||
PeriodicTaskIF* mpsocHelperTask = factory->createPeriodicTask(
|
PeriodicTaskIF* mpsocHelperTask = factory->createPeriodicTask(
|
||||||
"PLOC_MPSOC_HELPER", 0, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"PLOC_MPSOC_HELPER", 0, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
@ -365,7 +365,7 @@ void scheduling::initTasks() {
|
|||||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR */
|
#endif /* OBSW_ADD_PLOC_SUPERVISOR */
|
||||||
|
|
||||||
PeriodicTaskIF* plTask = factory->createPeriodicTask(
|
PeriodicTaskIF* plTask = factory->createPeriodicTask(
|
||||||
"PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc, &RR_SCHEDULING);
|
"PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
||||||
plTask->addComponent(objects::CAM_SWITCHER);
|
plTask->addComponent(objects::CAM_SWITCHER);
|
||||||
scheduling::addMpsocSupvHandlers(plTask);
|
scheduling::addMpsocSupvHandlers(plTask);
|
||||||
scheduling::scheduleScexDev(plTask);
|
scheduling::scheduleScexDev(plTask);
|
||||||
@ -471,6 +471,9 @@ void scheduling::initTasks() {
|
|||||||
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
||||||
supvHelperTask->startTask();
|
supvHelperTask->startTask();
|
||||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
||||||
|
#if OBSW_ADD_PLOC_MPSOC == 1
|
||||||
|
mpsocHelperTask->startTask();
|
||||||
|
#endif
|
||||||
plTask->startTask();
|
plTask->startTask();
|
||||||
|
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
@ -36,7 +36,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
PersistentTmStores stores;
|
PersistentTmStores stores;
|
||||||
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
||||||
*SdCardManager::instance(), &ipcStore, &tmStore, stores);
|
*SdCardManager::instance(), &ipcStore, &tmStore, stores,
|
||||||
|
200);
|
||||||
|
|
||||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||||
SerialComIF* uartComIF = nullptr;
|
SerialComIF* uartComIF = nullptr;
|
||||||
@ -51,11 +52,20 @@ void ObjectFactory::produce(void* args) {
|
|||||||
// level components.
|
// level components.
|
||||||
dummy::DummyCfg dummyCfg;
|
dummy::DummyCfg dummyCfg;
|
||||||
dummyCfg.addCoreCtrlCfg = false;
|
dummyCfg.addCoreCtrlCfg = false;
|
||||||
|
dummyCfg.addCamSwitcherDummy = false;
|
||||||
#if OBSW_ADD_SYRLINKS == 1
|
#if OBSW_ADD_SYRLINKS == 1
|
||||||
dummyCfg.addSyrlinksDummies = false;
|
dummyCfg.addSyrlinksDummies = false;
|
||||||
#endif
|
#endif
|
||||||
|
#if OBSW_ADD_PLOC_SUPERVISOR == 1 || OBSW_ADD_PLOC_MPSOC == 1
|
||||||
|
dummyCfg.addPlocDummies = false;
|
||||||
|
#endif
|
||||||
#if OBSW_ADD_GOMSPACE_PCDU == 1
|
#if OBSW_ADD_GOMSPACE_PCDU == 1
|
||||||
dummyCfg.addPowerDummies = false;
|
dummyCfg.addPowerDummies = false;
|
||||||
|
// The ACU broke.
|
||||||
|
dummyCfg.addOnlyAcuDummy = true;
|
||||||
|
#endif
|
||||||
|
#if OBSW_ADD_BPX_BATTERY_HANDLER == 1
|
||||||
|
dummyCfg.addBpxBattDummy = false;
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_ACS_BOARD == 1
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
dummyCfg.addAcsBoardDummies = false;
|
dummyCfg.addAcsBoardDummies = false;
|
||||||
@ -63,13 +73,13 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
PowerSwitchIF* pwrSwitcher = nullptr;
|
PowerSwitchIF* pwrSwitcher = nullptr;
|
||||||
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
||||||
auto* comCookieDummy = new ComCookieDummy();
|
pwrSwitcher = new PcduHandlerDummy(objects::PCDU_HANDLER);
|
||||||
pwrSwitcher = new PcduHandlerDummy(objects::PCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
|
||||||
#else
|
#else
|
||||||
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
||||||
#endif
|
#endif
|
||||||
|
satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher);
|
||||||
|
|
||||||
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF);
|
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF, enableHkSets);
|
||||||
|
|
||||||
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||||
|
|
||||||
@ -89,7 +99,10 @@ void ObjectFactory::produce(void* args) {
|
|||||||
// createRadSensorComponent(gpioComIF);
|
// createRadSensorComponent(gpioComIF);
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_BOARD == 1
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher);
|
// Still initialize chip select to avoid SPI bus issues.
|
||||||
|
createRadSensorChipSelect(gpioComIF);
|
||||||
|
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true,
|
||||||
|
adis1650x::Type::ADIS16507);
|
||||||
#else
|
#else
|
||||||
// Still add all GPIOs for EM.
|
// Still add all GPIOs for EM.
|
||||||
GpioCookie* acsBoardGpios = new GpioCookie();
|
GpioCookie* acsBoardGpios = new GpioCookie();
|
||||||
@ -117,6 +130,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
createStrComponents(pwrSwitcher);
|
createStrComponents(pwrSwitcher);
|
||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
|
|
||||||
|
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
||||||
|
|
||||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||||
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
||||||
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
|
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
|
||||||
@ -125,6 +140,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_TM_TO_PTME == 1
|
#if OBSW_TM_TO_PTME == 1
|
||||||
if (ccsdsArgs.liveDestination != nullptr) {
|
if (ccsdsArgs.liveDestination != nullptr) {
|
||||||
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
|
cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||||
@ -134,7 +150,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
#if OBSW_ADD_SCEX_DEVICE == 1
|
#if OBSW_ADD_SCEX_DEVICE == 1
|
||||||
createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), false,
|
createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), false,
|
||||||
pcdu::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V);
|
power::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V);
|
||||||
#endif
|
#endif
|
||||||
createAcsController(true, enableHkSets);
|
createAcsController(true, enableHkSets);
|
||||||
HeaterHandler* heaterHandler;
|
HeaterHandler* heaterHandler;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
|
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
|
||||||
|
#include <devices/gpioIds.h>
|
||||||
#include <fsfw/storagemanager/LocalPool.h>
|
#include <fsfw/storagemanager/LocalPool.h>
|
||||||
#include <fsfw/storagemanager/PoolManager.h>
|
#include <fsfw/storagemanager/PoolManager.h>
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
@ -32,7 +33,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
PersistentTmStores stores;
|
PersistentTmStores stores;
|
||||||
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
||||||
*SdCardManager::instance(), &ipcStore, &tmStore, stores);
|
*SdCardManager::instance(), &ipcStore, &tmStore, stores,
|
||||||
|
200);
|
||||||
|
|
||||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||||
SerialComIF* uartComIF = nullptr;
|
SerialComIF* uartComIF = nullptr;
|
||||||
@ -58,7 +60,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_BOARD == 1
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true);
|
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true,
|
||||||
|
adis1650x::Type::ADIS16505);
|
||||||
#endif
|
#endif
|
||||||
HeaterHandler* heaterHandler;
|
HeaterHandler* heaterHandler;
|
||||||
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
|
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
|
||||||
@ -94,6 +97,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_TM_TO_PTME == 1
|
#if OBSW_TM_TO_PTME == 1
|
||||||
if (ccsdsArgs.liveDestination != nullptr) {
|
if (ccsdsArgs.liveDestination != nullptr) {
|
||||||
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
|
cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||||
|
@ -309,32 +309,6 @@ void SdCardManager::resetState() {
|
|||||||
currentOp = Operations::IDLE;
|
currentOp = Operations::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::updateSdStatePair() {
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
std::error_code e;
|
|
||||||
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
|
||||||
return STATUS_FILE_NEXISTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now the file should exist in any case. Still check whether it exists.
|
|
||||||
fstream sdStatus(SD_STATE_FILE);
|
|
||||||
if (not sdStatus.good()) {
|
|
||||||
return STATUS_FILE_NEXISTS;
|
|
||||||
}
|
|
||||||
string line;
|
|
||||||
uint8_t idx = 0;
|
|
||||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
|
||||||
// Process status file line by line
|
|
||||||
while (std::getline(sdStatus, line)) {
|
|
||||||
processSdStatusLine(line, idx, currentSd);
|
|
||||||
}
|
|
||||||
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
|
||||||
sdCardActive = false;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
istringstream iss(line);
|
istringstream iss(line);
|
||||||
@ -407,6 +381,7 @@ ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||||
|
using namespace std;
|
||||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||||
return CommandExecutor::COMMAND_PENDING;
|
return CommandExecutor::COMMAND_PENDING;
|
||||||
}
|
}
|
||||||
@ -414,10 +389,31 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
|||||||
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
||||||
cmdExecutor.load(updateCmd, true, printCmdOutput);
|
cmdExecutor.load(updateCmd, true, printCmdOutput);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if (blocking and result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
std::error_code e;
|
||||||
|
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
||||||
|
return STATUS_FILE_NEXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now the file should exist in any case. Still check whether it exists.
|
||||||
|
fstream sdStatus(SD_STATE_FILE);
|
||||||
|
if (not sdStatus.good()) {
|
||||||
|
return STATUS_FILE_NEXISTS;
|
||||||
|
}
|
||||||
|
string line;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||||
|
// Process status file line by line
|
||||||
|
while (std::getline(sdStatus, line)) {
|
||||||
|
processSdStatusLine(line, idx, currentSd);
|
||||||
|
}
|
||||||
|
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
||||||
|
sdCardActive = false;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SdCardManager::getCurrentMountPrefix() const {
|
const char* SdCardManager::getCurrentMountPrefix() const {
|
||||||
@ -585,3 +581,8 @@ void SdCardManager::markUnusable() {
|
|||||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||||
markedUnusable = true;
|
markedUnusable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdCardManager::markUsable() {
|
||||||
|
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||||
|
markedUnusable = false;
|
||||||
|
}
|
||||||
|
@ -117,16 +117,6 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
|||||||
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
||||||
SdStatePair* statusPair = nullptr);
|
SdStatePair* statusPair = nullptr);
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the state file or creates one if it does not exist. You need to call this
|
|
||||||
* function before calling #sdCardActive
|
|
||||||
* @return
|
|
||||||
* - returnvalue::OK if the state file was updated successfully
|
|
||||||
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
|
||||||
* - returnvalue::FAILED: blocking command failed
|
|
||||||
*/
|
|
||||||
ReturnValue_t updateSdCardStateFile();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the state of the SD cards. If the state file does not exist, this function will
|
* Get the state of the SD cards. If the state file does not exist, this function will
|
||||||
* take care of updating it. If it does not, the function will use the state file to get
|
* take care of updating it. If it does not, the function will use the state file to get
|
||||||
@ -215,6 +205,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
|||||||
ReturnValue_t performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError);
|
ReturnValue_t performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError);
|
||||||
|
|
||||||
void markUnusable();
|
void markUnusable();
|
||||||
|
void markUsable();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CommandExecutor cmdExecutor;
|
CommandExecutor cmdExecutor;
|
||||||
@ -234,7 +225,15 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
|||||||
|
|
||||||
SdCardManager();
|
SdCardManager();
|
||||||
|
|
||||||
ReturnValue_t updateSdStatePair();
|
/**
|
||||||
|
* Update the state file or creates one if it does not exist. You need to call this
|
||||||
|
* function before calling #sdCardActive
|
||||||
|
* @return
|
||||||
|
* - returnvalue::OK if the state file was updated successfully
|
||||||
|
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
||||||
|
* - returnvalue::FAILED: blocking command failed
|
||||||
|
*/
|
||||||
|
ReturnValue_t updateSdCardStateFile();
|
||||||
|
|
||||||
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy")
|
|||||||
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
|
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
|
||||||
|
|
||||||
# At the very least, cross compile gcc and g++ have to be set!
|
# At the very least, cross compile gcc and g++ have to be set!
|
||||||
find_program (CMAKE_C_COMPILER ${CROSS_COMPILE_CC} REQUIRED)
|
find_program (CMAKE_C_COMPILER ${CROSS_COMPILE_CC} HINTS $ENV{CROSS_COMPILE_BIN_PATH} REQUIRED)
|
||||||
find_program (CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX} REQUIRED)
|
find_program (CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX} HINTS $ENV{CROSS_COMPILE_BIN_PATH} REQUIRED)
|
||||||
# Useful utilities, not strictly necessary
|
# Useful utilities, not strictly necessary
|
||||||
find_program(CMAKE_SIZE ${CROSS_COMPILE_SIZE})
|
find_program(CMAKE_SIZE ${CROSS_COMPILE_SIZE})
|
||||||
find_program(CMAKE_OBJCOPY ${CROSS_COMPILE_OBJCOPY})
|
find_program(CMAKE_OBJCOPY ${CROSS_COMPILE_OBJCOPY})
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#ifndef FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
|
|
||||||
#define FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace heater {
|
|
||||||
enum Switchers : uint8_t {
|
|
||||||
HEATER_0_OBC_BRD,
|
|
||||||
HEATER_1_PLOC_PROC_BRD,
|
|
||||||
HEATER_2_ACS_BRD,
|
|
||||||
HEATER_3_PCDU_PDU,
|
|
||||||
HEATER_4_CAMERA,
|
|
||||||
HEATER_5_STR,
|
|
||||||
HEATER_6_DRO,
|
|
||||||
HEATER_7_S_BAND,
|
|
||||||
NUMBER_OF_SWITCHES
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_ */
|
|
@ -34,8 +34,8 @@ static constexpr uint32_t STR_IMG_HELPER_QUEUE_SIZE = 50;
|
|||||||
static constexpr uint8_t LIVE_TM = 0;
|
static constexpr uint8_t LIVE_TM = 0;
|
||||||
|
|
||||||
/* Limits for filename and path checks */
|
/* Limits for filename and path checks */
|
||||||
static constexpr uint32_t MAX_PATH_SIZE = 100;
|
static constexpr uint32_t MAX_PATH_SIZE = 200;
|
||||||
static constexpr uint32_t MAX_FILENAME_SIZE = 50;
|
static constexpr uint32_t MAX_FILENAME_SIZE = 100;
|
||||||
|
|
||||||
static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120;
|
static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120;
|
||||||
// Burn time for autonomous deployment
|
// Burn time for autonomous deployment
|
||||||
@ -58,7 +58,9 @@ static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300;
|
|||||||
|
|
||||||
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
|
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
|
||||||
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80;
|
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80;
|
||||||
|
static constexpr uint32_t VERIFICATION_SERVICE_QUEUE_DEPTH = 120;
|
||||||
static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60;
|
static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60;
|
||||||
|
static constexpr uint32_t ACTION_SERVICE_QUEUE_DEPTH = 60;
|
||||||
|
|
||||||
static constexpr uint32_t MAX_STORED_CMDS_UDP = 150;
|
static constexpr uint32_t MAX_STORED_CMDS_UDP = 150;
|
||||||
static constexpr uint32_t MAX_STORED_CMDS_TCP = 180;
|
static constexpr uint32_t MAX_STORED_CMDS_TCP = 180;
|
||||||
|
@ -37,9 +37,6 @@ enum commonClassIds : uint8_t {
|
|||||||
SUPV_RETURN_VALUES_IF, // SPVRTVIF
|
SUPV_RETURN_VALUES_IF, // SPVRTVIF
|
||||||
ACS_CTRL, // ACSCTRL
|
ACS_CTRL, // ACSCTRL
|
||||||
ACS_MEKF, // ACSMEKF
|
ACS_MEKF, // ACSMEKF
|
||||||
ACS_SAFE, // ACSSAF
|
|
||||||
ACS_PTG, // ACSPTG
|
|
||||||
ACS_DETUMBLE, // ACSDTB
|
|
||||||
SD_CARD_MANAGER, // SDMA
|
SD_CARD_MANAGER, // SDMA
|
||||||
LOCAL_PARAM_HANDLER, // LPH
|
LOCAL_PARAM_HANDLER, // LPH
|
||||||
PERSISTENT_TM_STORE, // PTM
|
PERSISTENT_TM_STORE, // PTM
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
|
|
||||||
AcuDummy::AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
|
AcuDummy::AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets)
|
||||||
: DeviceHandlerBase(objectId, comif, comCookie) {}
|
: DeviceHandlerBase(objectId, comif, comCookie),
|
||||||
|
coreHk(this),
|
||||||
|
auxHk(this),
|
||||||
|
enableHkSets(enableHkSets) {}
|
||||||
|
|
||||||
AcuDummy::~AcuDummy() {}
|
AcuDummy::~AcuDummy() {}
|
||||||
|
|
||||||
@ -37,7 +40,49 @@ uint32_t AcuDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
|
|||||||
|
|
||||||
ReturnValue_t AcuDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t AcuDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
LocalDataPoolManager &poolManager) {
|
||||||
|
using namespace ACU;
|
||||||
|
localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNELS, new PoolEntry<int16_t>(6));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNELS, new PoolEntry<uint16_t>(6));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_VCC, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_VBAT, new PoolEntry<uint16_t>({0}));
|
||||||
|
|
||||||
localDataPoolMap.emplace(ACU::pool::ACU_TEMPERATURES,
|
localDataPoolMap.emplace(ACU::pool::ACU_TEMPERATURES,
|
||||||
new PoolEntry<float>({10.0, 10.0, 10.0}, true));
|
new PoolEntry<float>({10.0, 10.0, 10.0}, true));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_MPPT_MODE, new PoolEntry<uint8_t>({0}));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_VBOOST_IN_CHANNELS, new PoolEntry<uint16_t>(6));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_POWER_IN_CHANNELS, new PoolEntry<uint16_t>(6));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_DAC_ENABLES, new PoolEntry<uint8_t>(3));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_DAC_RAW_CHANNELS, new PoolEntry<uint16_t>(6));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_BOOTCNT, new PoolEntry<uint32_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_UPTIME, new PoolEntry<uint32_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_RESET_CAUSE, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_MPPT_TIME, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_MPPT_PERIOD, new PoolEntry<uint16_t>({0}));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_DEVICES, new PoolEntry<uint8_t>(8));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_DEVICES_STATUS, new PoolEntry<uint8_t>(8));
|
||||||
|
|
||||||
|
localDataPoolMap.emplace(pool::ACU_WDT_CNT_GND, new PoolEntry<uint32_t>({0}));
|
||||||
|
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
|
||||||
|
|
||||||
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
|
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||||
|
poolManager.subscribeForRegularPeriodicPacket(
|
||||||
|
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalPoolDataSetBase *AcuDummy::getDataSetHandle(sid_t sid) {
|
||||||
|
if (sid == coreHk.getSid()) {
|
||||||
|
return &coreHk;
|
||||||
|
} else if (sid == auxHk.getSid()) {
|
||||||
|
return &auxHk;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define DUMMIES_ACUDUMMY_H_
|
#define DUMMIES_ACUDUMMY_H_
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
|
#include <mission/power/gsDefs.h>
|
||||||
|
|
||||||
class AcuDummy : public DeviceHandlerBase {
|
class AcuDummy : public DeviceHandlerBase {
|
||||||
public:
|
public:
|
||||||
@ -11,10 +12,14 @@ class AcuDummy : public DeviceHandlerBase {
|
|||||||
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
||||||
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
||||||
|
|
||||||
AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
|
AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets);
|
||||||
virtual ~AcuDummy();
|
virtual ~AcuDummy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ACU::CoreHk coreHk;
|
||||||
|
ACU::AuxHk auxHk;
|
||||||
|
bool enableHkSets;
|
||||||
|
|
||||||
void doStartUp() override;
|
void doStartUp() override;
|
||||||
void doShutDown() override;
|
void doShutDown() override;
|
||||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
||||||
@ -28,6 +33,7 @@ class AcuDummy : public DeviceHandlerBase {
|
|||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
LocalDataPoolManager &poolManager) override;
|
||||||
|
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DUMMIES_ACUDUMMY_H_ */
|
#endif /* DUMMIES_ACUDUMMY_H_ */
|
||||||
|
@ -2,8 +2,13 @@
|
|||||||
|
|
||||||
#include <mission/acs/imtqHelpers.h>
|
#include <mission/acs/imtqHelpers.h>
|
||||||
|
|
||||||
ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
|
ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie,
|
||||||
: DeviceHandlerBase(objectId, comif, comCookie) {}
|
power::Switch_t pwrSwitcher, bool enableHkSets)
|
||||||
|
: DeviceHandlerBase(objectId, comif, comCookie),
|
||||||
|
setNoTorque(this),
|
||||||
|
setWithTorque(this),
|
||||||
|
enableHkSets(enableHkSets),
|
||||||
|
switcher(pwrSwitcher) {}
|
||||||
|
|
||||||
ImtqDummy::~ImtqDummy() = default;
|
ImtqDummy::~ImtqDummy() = default;
|
||||||
|
|
||||||
@ -11,6 +16,15 @@ void ImtqDummy::doStartUp() { setMode(MODE_NORMAL); }
|
|||||||
|
|
||||||
void ImtqDummy::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
void ImtqDummy::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
||||||
|
|
||||||
|
ReturnValue_t ImtqDummy::getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) {
|
||||||
|
if (switcher != power::NO_SWITCH) {
|
||||||
|
*numberOfSwitches = 1;
|
||||||
|
*switches = &switcher;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
return DeviceHandlerBase::NO_SWITCH;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t ImtqDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; }
|
ReturnValue_t ImtqDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; }
|
||||||
|
|
||||||
ReturnValue_t ImtqDummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
ReturnValue_t ImtqDummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||||
@ -43,5 +57,39 @@ ReturnValue_t ImtqDummy::initializeLocalDataPool(localpool::DataPool &localDataP
|
|||||||
localDataPoolMap.emplace(imtq::ACTUATION_CAL_STATUS, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(imtq::ACTUATION_CAL_STATUS, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(imtq::MTM_RAW, new PoolEntry<float>({0.12, 0.76, -0.45}, true));
|
localDataPoolMap.emplace(imtq::MTM_RAW, new PoolEntry<float>({0.12, 0.76, -0.45}, true));
|
||||||
localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry<uint8_t>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::DIPOLES_ID, new PoolEntry<int16_t>({0, 0, 0}));
|
||||||
|
localDataPoolMap.emplace(imtq::CURRENT_TORQUE_DURATION, new PoolEntry<uint16_t>({0}));
|
||||||
|
|
||||||
|
// ENG HK No Torque
|
||||||
|
localDataPoolMap.emplace(imtq::DIGITAL_VOLTAGE_MV, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::ANALOG_VOLTAGE_MV, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::DIGITAL_CURRENT, new PoolEntry<float>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::ANALOG_CURRENT, new PoolEntry<float>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::COIL_CURRENTS, &coilCurrentsMilliampsNoTorque);
|
||||||
|
localDataPoolMap.emplace(imtq::COIL_TEMPERATURES, &coilTempsNoTorque);
|
||||||
|
localDataPoolMap.emplace(imtq::MCU_TEMPERATURE, new PoolEntry<int16_t>({0}));
|
||||||
|
|
||||||
|
// ENG HK With Torque
|
||||||
|
localDataPoolMap.emplace(imtq::DIGITAL_VOLTAGE_MV_WT, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::ANALOG_VOLTAGE_MV_WT, new PoolEntry<uint16_t>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::DIGITAL_CURRENT_WT, new PoolEntry<float>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::ANALOG_CURRENT_WT, new PoolEntry<float>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::COIL_CURRENTS_WT, &coilCurrentsMilliampsWithTorque);
|
||||||
|
localDataPoolMap.emplace(imtq::COIL_TEMPERATURES_WT, &coilTempsWithTorque);
|
||||||
|
localDataPoolMap.emplace(imtq::MCU_TEMPERATURE_WT, new PoolEntry<int16_t>({0}));
|
||||||
|
|
||||||
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
|
subdp::DiagnosticsHkPeriodicParams(setNoTorque.getSid(), enableHkSets, 30.0));
|
||||||
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
|
subdp::DiagnosticsHkPeriodicParams(setWithTorque.getSid(), enableHkSets, 30.0));
|
||||||
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
|
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalPoolDataSetBase *ImtqDummy::getDataSetHandle(sid_t sid) {
|
||||||
|
if (sid == setNoTorque.getSid()) {
|
||||||
|
return &setNoTorque;
|
||||||
|
} else if (sid == setWithTorque.getSid()) {
|
||||||
|
return &setWithTorque;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
|
|
||||||
|
#include "mission/acs/imtqHelpers.h"
|
||||||
|
|
||||||
class ImtqDummy : public DeviceHandlerBase {
|
class ImtqDummy : public DeviceHandlerBase {
|
||||||
public:
|
public:
|
||||||
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
|
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
|
||||||
@ -11,10 +13,35 @@ class ImtqDummy : public DeviceHandlerBase {
|
|||||||
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
||||||
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
||||||
|
|
||||||
ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
|
ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie,
|
||||||
|
power::Switch_t pwrSwitcher, bool enableHkSets);
|
||||||
~ImtqDummy() override;
|
~ImtqDummy() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override;
|
||||||
|
imtq::HkDatasetNoTorque setNoTorque;
|
||||||
|
imtq::HkDatasetWithTorque setWithTorque;
|
||||||
|
bool enableHkSets;
|
||||||
|
|
||||||
|
PoolEntry<uint8_t> statusMode = PoolEntry<uint8_t>({0});
|
||||||
|
PoolEntry<uint8_t> statusError = PoolEntry<uint8_t>({0});
|
||||||
|
PoolEntry<uint8_t> statusConfig = PoolEntry<uint8_t>({0});
|
||||||
|
PoolEntry<uint32_t> statusUptime = PoolEntry<uint32_t>({0});
|
||||||
|
|
||||||
|
PoolEntry<int32_t> mgmCalEntry = PoolEntry<int32_t>(3);
|
||||||
|
PoolEntry<int16_t> dipolesPoolEntry = PoolEntry<int16_t>({0, 0, 0}, false);
|
||||||
|
PoolEntry<uint16_t> torqueDurationEntry = PoolEntry<uint16_t>({0}, false);
|
||||||
|
PoolEntry<float> coilCurrentsMilliampsNoTorque = PoolEntry<float>(3);
|
||||||
|
PoolEntry<float> coilCurrentsMilliampsWithTorque = PoolEntry<float>(3);
|
||||||
|
PoolEntry<int16_t> coilTempsNoTorque = PoolEntry<int16_t>(3);
|
||||||
|
PoolEntry<int16_t> coilTempsWithTorque = PoolEntry<int16_t>(3);
|
||||||
|
PoolEntry<float> mtmRawNoTorque = PoolEntry<float>(3);
|
||||||
|
PoolEntry<uint8_t> actStatusNoTorque = PoolEntry<uint8_t>(1);
|
||||||
|
PoolEntry<float> mtmRawWithTorque = PoolEntry<float>(3);
|
||||||
|
PoolEntry<uint8_t> actStatusWithTorque = PoolEntry<uint8_t>(1);
|
||||||
|
|
||||||
|
power::Switch_t switcher = power::NO_SWITCH;
|
||||||
|
|
||||||
void doStartUp() override;
|
void doStartUp() override;
|
||||||
void doShutDown() override;
|
void doShutDown() override;
|
||||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
||||||
@ -28,6 +55,7 @@ class ImtqDummy : public DeviceHandlerBase {
|
|||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
LocalDataPoolManager &poolManager) override;
|
||||||
|
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DUMMIES_IMTQDUMMY_H_ */
|
#endif /* DUMMIES_IMTQDUMMY_H_ */
|
||||||
|
@ -1,49 +1,20 @@
|
|||||||
#include "PcduHandlerDummy.h"
|
#include "PcduHandlerDummy.h"
|
||||||
|
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
|
|
||||||
#include "mission/power/defs.h"
|
#include "mission/power/defs.h"
|
||||||
|
|
||||||
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
|
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId)
|
||||||
: DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) {
|
: SystemObject(objectId), manager(this, nullptr), dummySwitcher(objectId, 18, 18, false) {
|
||||||
switcherLock = MutexFactory::instance()->createMutex();
|
switcherLock = MutexFactory::instance()->createMutex();
|
||||||
|
queue = QueueFactory::instance()->createMessageQueue(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
PcduHandlerDummy::~PcduHandlerDummy() {}
|
PcduHandlerDummy::~PcduHandlerDummy() {}
|
||||||
|
|
||||||
void PcduHandlerDummy::doStartUp() { setMode(MODE_NORMAL); }
|
ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
|
LocalDataPoolManager& poolManager) {
|
||||||
void PcduHandlerDummy::doShutDown() { setMode(MODE_OFF); }
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
|
||||||
return NOTHING_TO_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
|
||||||
return NOTHING_TO_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
|
||||||
const uint8_t *commandData,
|
|
||||||
size_t commandDataLen) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::scanForReply(const uint8_t *start, size_t len,
|
|
||||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PcduHandlerDummy::fillCommandAndReplyMap() {}
|
|
||||||
|
|
||||||
uint32_t PcduHandlerDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
|
||||||
LocalDataPoolManager &poolManager) {
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +47,8 @@ ReturnValue_t PcduHandlerDummy::getFuseState(uint8_t fuseNr) const {
|
|||||||
|
|
||||||
uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }
|
uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }
|
||||||
|
|
||||||
void PcduHandlerDummy::performOperationHook() {
|
ReturnValue_t PcduHandlerDummy::performOperation(uint8_t opCode) {
|
||||||
|
// TODO: Handle HK messages in queue.
|
||||||
SwitcherBoolArray switcherChangeCopy{};
|
SwitcherBoolArray switcherChangeCopy{};
|
||||||
{
|
{
|
||||||
MutexGuard mg(switcherLock);
|
MutexGuard mg(switcherLock);
|
||||||
@ -93,4 +65,18 @@ void PcduHandlerDummy::performOperationHook() {
|
|||||||
switchChangeArray[idx] = false;
|
switchChangeArray[idx] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_id_t PcduHandlerDummy::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
|
MessageQueueId_t PcduHandlerDummy::getCommandQueue() const { return queue->getId(); }
|
||||||
|
|
||||||
|
dur_millis_t PcduHandlerDummy::getPeriodicOperationFrequency() const {
|
||||||
|
// TODO: dummy value. Retrieve from intiitalize after task creation..
|
||||||
|
return 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDataPoolManager* PcduHandlerDummy::getHkManagerHandle() { return &manager; }
|
||||||
|
|
||||||
|
LocalPoolDataSetBase* PcduHandlerDummy::getDataSetHandle(sid_t sid) { return nullptr; }
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <fsfw/power/DummyPowerSwitcher.h>
|
#include <fsfw/power/DummyPowerSwitcher.h>
|
||||||
|
|
||||||
class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
|
class PcduHandlerDummy : public PowerSwitchIF,
|
||||||
|
public HasLocalDataPoolIF,
|
||||||
|
public SystemObject,
|
||||||
|
public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
|
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
|
||||||
static const DeviceCommandId_t PERIODIC_REPLY = 2;
|
static const DeviceCommandId_t PERIODIC_REPLY = 2;
|
||||||
@ -11,33 +14,49 @@ class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
|
|||||||
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
||||||
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
||||||
|
|
||||||
PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
|
PcduHandlerDummy(object_id_t objectId);
|
||||||
virtual ~PcduHandlerDummy();
|
virtual ~PcduHandlerDummy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MutexIF *switcherLock;
|
MessageQueueIF* queue;
|
||||||
|
LocalDataPoolManager manager;
|
||||||
|
MutexIF* switcherLock;
|
||||||
DummyPowerSwitcher dummySwitcher;
|
DummyPowerSwitcher dummySwitcher;
|
||||||
using SwitcherBoolArray = std::array<bool, 18>;
|
using SwitcherBoolArray = std::array<bool, 18>;
|
||||||
|
|
||||||
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
SwitcherBoolArray switchChangeArray{};
|
SwitcherBoolArray switchChangeArray{};
|
||||||
void performOperationHook() override;
|
|
||||||
void doStartUp() override;
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
void doShutDown() override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
|
||||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
|
|
||||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
|
||||||
size_t commandDataLen) override;
|
|
||||||
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId,
|
|
||||||
size_t *foundLen) override;
|
|
||||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
|
||||||
void fillCommandAndReplyMap() override;
|
|
||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
|
||||||
LocalDataPoolManager &poolManager) override;
|
|
||||||
|
|
||||||
ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
|
ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
|
||||||
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
||||||
ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
|
ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
|
||||||
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
||||||
uint32_t getSwitchDelayMs(void) const override;
|
uint32_t getSwitchDelayMs(void) const override;
|
||||||
|
|
||||||
|
object_id_t getObjectId() const override;
|
||||||
|
|
||||||
|
/** Command queue for housekeeping messages. */
|
||||||
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
|
dur_millis_t getPeriodicOperationFrequency() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every class implementing this interface should have a local data pool manager. This
|
||||||
|
* function will return a reference to the manager.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used by the pool manager to get a valid dataset
|
||||||
|
* from a SID. This function is protected to prevent users from
|
||||||
|
* using raw data set pointers which could not be thread-safe. Users
|
||||||
|
* should use the #ProvidesDataPoolSubscriptionIF.
|
||||||
|
* @param sid Corresponding structure ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
};
|
};
|
||||||
|
@ -37,6 +37,9 @@ uint32_t RwDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
|
|||||||
|
|
||||||
ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
LocalDataPoolManager &poolManager) {
|
||||||
|
localDataPoolMap.emplace(rws::RW_SPEED, &rwSpeed);
|
||||||
|
localDataPoolMap.emplace(rws::RAMP_TIME, &rampTime);
|
||||||
|
|
||||||
localDataPoolMap.emplace(rws::TEMPERATURE_C, new PoolEntry<int32_t>({0}));
|
localDataPoolMap.emplace(rws::TEMPERATURE_C, new PoolEntry<int32_t>({0}));
|
||||||
|
|
||||||
localDataPoolMap.emplace(rws::CURR_SPEED, new PoolEntry<int32_t>({0}));
|
localDataPoolMap.emplace(rws::CURR_SPEED, new PoolEntry<int32_t>({0}));
|
||||||
|
@ -15,6 +15,9 @@ class RwDummy : public DeviceHandlerBase {
|
|||||||
virtual ~RwDummy();
|
virtual ~RwDummy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PoolEntry<int32_t> rwSpeed = PoolEntry<int32_t>({0});
|
||||||
|
PoolEntry<uint16_t> rampTime = PoolEntry<uint16_t>({10});
|
||||||
|
|
||||||
void doStartUp() override;
|
void doStartUp() override;
|
||||||
void doShutDown() override;
|
void doShutDown() override;
|
||||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
||||||
|
@ -64,6 +64,7 @@ ReturnValue_t StarTrackerDummy::initializeLocalDataPool(localpool::DataPool &loc
|
|||||||
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
||||||
|
localDataPoolMap.emplace(startracker::STR_MODE, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "TemperatureSensorInserter.h"
|
#include "TemperatureSensorInserter.h"
|
||||||
|
|
||||||
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
#include <objects/systemObjectList.h>
|
#include <objects/systemObjectList.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -14,10 +15,7 @@ TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId,
|
|||||||
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
|
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
|
||||||
|
|
||||||
ReturnValue_t TemperatureSensorInserter::initialize() {
|
ReturnValue_t TemperatureSensorInserter::initialize() {
|
||||||
if (performTest) {
|
testCase = TestCase::NONE;
|
||||||
if (testCase == TestCase::COOL_SYRLINKS) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,35 +31,82 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
|
|||||||
tempsWereInitialized = true;
|
tempsWereInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycles == 10) {
|
switch (testCase) {
|
||||||
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
|
case (TestCase::NONE): {
|
||||||
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(-100, true);
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_SYRLINKS): {
|
||||||
|
// TODO: How do I insert this?
|
||||||
|
// Does not work on EM, where a real syrlinks device is connected.
|
||||||
|
if (cycles == 15) {
|
||||||
|
lp_var_t<float> tempSyrlinksBasebandBoard =
|
||||||
|
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
|
||||||
|
PoolReadGuard pg(&tempSyrlinksBasebandBoard);
|
||||||
|
tempSyrlinksBasebandBoard.value = -50;
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
lp_var_t<float> tempSyrlinksBasebandBoard =
|
||||||
|
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
|
||||||
|
PoolReadGuard pg(&tempSyrlinksBasebandBoard);
|
||||||
|
tempSyrlinksBasebandBoard.value = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_HPA): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold HPA temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-60, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting HPA temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_MGT): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold MGT temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_15_IC18_IMTQ]->setTemperature(-60, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting MGT temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_15_IC18_IMTQ]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_STR):
|
||||||
|
case (TestCase::COLD_STR_CONSECUTIVE): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold STR temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting STR temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
if (testCase == TestCase::COLD_STR_CONSECUTIVE) {
|
||||||
|
if (cycles == 45) {
|
||||||
|
sif::debug << "Setting cold STR temperature again" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
if (cycles == 60) {
|
||||||
|
sif::debug << "Setting STR temperature back to normal again" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_CAMERA): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold CAM temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting CAM temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycles == 35) {
|
|
||||||
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(0, true);
|
|
||||||
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(0, true);
|
|
||||||
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-100, true);
|
|
||||||
}
|
|
||||||
if (cycles == 60) {
|
|
||||||
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
|
|
||||||
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
ReturnValue_t result = max31865PlocHeatspreaderSet.read();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "Failed to read temperature from MAX31865 dataset" << std::endl;
|
|
||||||
}
|
|
||||||
max31865PlocHeatspreaderSet.rtdValue = value - 5;
|
|
||||||
max31865PlocHeatspreaderSet.temperatureCelcius = value;
|
|
||||||
if ((iteration % 100) < 20) {
|
|
||||||
max31865PlocHeatspreaderSet.setValidity(false, true);
|
|
||||||
} else {
|
|
||||||
max31865PlocHeatspreaderSet.setValidity(true, true);
|
|
||||||
}
|
|
||||||
max31865PlocHeatspreaderSet.commit();
|
|
||||||
*/
|
|
||||||
cycles++;
|
cycles++;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||||
|
#include <mission/com/syrlinksDefs.h>
|
||||||
#include <mission/tcs/Max31865Definitions.h>
|
#include <mission/tcs/Max31865Definitions.h>
|
||||||
|
|
||||||
#include "Max31865Dummy.h"
|
#include "Max31865Dummy.h"
|
||||||
@ -22,11 +23,19 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
|
|||||||
private:
|
private:
|
||||||
Max31865DummyMap max31865DummyMap;
|
Max31865DummyMap max31865DummyMap;
|
||||||
Tmp1075DummyMap tmp1075DummyMap;
|
Tmp1075DummyMap tmp1075DummyMap;
|
||||||
enum TestCase { NONE = 0, COOL_SYRLINKS = 1 };
|
|
||||||
|
enum TestCase {
|
||||||
|
NONE = 0,
|
||||||
|
COLD_SYRLINKS = 1,
|
||||||
|
COLD_HPA = 2,
|
||||||
|
COLD_MGT = 3,
|
||||||
|
COLD_STR = 4,
|
||||||
|
COLD_STR_CONSECUTIVE = 5,
|
||||||
|
COLD_CAMERA = 6,
|
||||||
|
};
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
uint32_t cycles = 0;
|
uint32_t cycles = 0;
|
||||||
bool tempsWereInitialized = false;
|
bool tempsWereInitialized = false;
|
||||||
bool performTest = false;
|
|
||||||
TestCase testCase = TestCase::NONE;
|
TestCase testCase = TestCase::NONE;
|
||||||
|
|
||||||
// void noise();
|
// void noise();
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include <mission/system/acs/ImtqAssembly.h>
|
#include <mission/system/acs/ImtqAssembly.h>
|
||||||
#include <mission/system/acs/StrAssembly.h>
|
#include <mission/system/acs/StrAssembly.h>
|
||||||
#include <mission/system/objects/CamSwitcher.h>
|
#include <mission/system/objects/CamSwitcher.h>
|
||||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
#include <mission/system/tcs/TcsBoardAssembly.h>
|
||||||
|
|
||||||
#include "TemperatureSensorInserter.h"
|
#include "TemperatureSensorInserter.h"
|
||||||
#include "dummies/Max31865Dummy.h"
|
#include "dummies/Max31865Dummy.h"
|
||||||
@ -38,13 +38,17 @@
|
|||||||
#include "mission/genericFactory.h"
|
#include "mission/genericFactory.h"
|
||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
#include "mission/system/com/comModeTree.h"
|
#include "mission/system/com/comModeTree.h"
|
||||||
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/system/tree/payloadModeTree.h"
|
#include "mission/system/tree/payloadModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
#include "mission/tcs/defs.h"
|
||||||
|
|
||||||
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {
|
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF,
|
||||||
|
bool enableHkSets) {
|
||||||
new ComIFDummy(objects::DUMMY_COM_IF);
|
new ComIFDummy(objects::DUMMY_COM_IF);
|
||||||
auto* comCookieDummy = new ComCookieDummy();
|
auto* comCookieDummy = new ComCookieDummy();
|
||||||
new BpxDummy(objects::BPX_BATT_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
if (cfg.addBpxBattDummy) {
|
||||||
|
new BpxDummy(objects::BPX_BATT_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
|
}
|
||||||
if (cfg.addCoreCtrlCfg) {
|
if (cfg.addCoreCtrlCfg) {
|
||||||
new CoreControllerDummy(objects::CORE_CONTROLLER);
|
new CoreControllerDummy(objects::CORE_CONTROLLER);
|
||||||
}
|
}
|
||||||
@ -71,11 +75,15 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
|||||||
}
|
}
|
||||||
auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY);
|
auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY);
|
||||||
imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||||
auto* imtqDummy = new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
auto* imtqDummy = new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy,
|
||||||
|
power::Switches::PDU1_CH3_MGT_5V, enableHkSets);
|
||||||
imtqDummy->enableThermalModule(ThermalStateCfg());
|
imtqDummy->enableThermalModule(ThermalStateCfg());
|
||||||
|
imtqDummy->setPowerSwitcher(&pwrSwitcher);
|
||||||
imtqDummy->connectModeTreeParent(*imtqAssy);
|
imtqDummy->connectModeTreeParent(*imtqAssy);
|
||||||
if (cfg.addPowerDummies) {
|
if (cfg.addOnlyAcuDummy) {
|
||||||
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets);
|
||||||
|
} else if (cfg.addPowerDummies) {
|
||||||
|
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets);
|
||||||
new PduDummy(objects::PDU1_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
new PduDummy(objects::PDU1_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
new PduDummy(objects::PDU2_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
new PduDummy(objects::PDU2_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
new P60DockDummy(objects::P60DOCK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
new P60DockDummy(objects::P60DOCK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
@ -193,16 +201,19 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
|||||||
tmpSensorDummies.emplace(
|
tmpSensorDummies.emplace(
|
||||||
objects::TMP1075_HANDLER_PLPCDU_0,
|
objects::TMP1075_HANDLER_PLPCDU_0,
|
||||||
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy));
|
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy));
|
||||||
tmpSensorDummies.emplace(
|
// damaged.
|
||||||
objects::TMP1075_HANDLER_PLPCDU_1,
|
// tmpSensorDummies.emplace(
|
||||||
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF, comCookieDummy));
|
// objects::TMP1075_HANDLER_PLPCDU_1,
|
||||||
|
// new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF,
|
||||||
|
// comCookieDummy));
|
||||||
tmpSensorDummies.emplace(
|
tmpSensorDummies.emplace(
|
||||||
objects::TMP1075_HANDLER_IF_BOARD,
|
objects::TMP1075_HANDLER_IF_BOARD,
|
||||||
new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy));
|
new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy));
|
||||||
|
|
||||||
new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies,
|
new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies,
|
||||||
tmpSensorDummies);
|
tmpSensorDummies);
|
||||||
TcsBoardAssembly* tcsBoardAssy = ObjectFactory::createTcsBoardAssy(pwrSwitcher);
|
TcsBoardAssembly* tcsBoardAssy =
|
||||||
|
ObjectFactory::createTcsBoardAssy(pwrSwitcher, tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||||
for (auto& rtd : rtdSensorDummies) {
|
for (auto& rtd : rtdSensorDummies) {
|
||||||
rtd.second->connectModeTreeParent(*tcsBoardAssy);
|
rtd.second->connectModeTreeParent(*tcsBoardAssy);
|
||||||
}
|
}
|
||||||
@ -210,9 +221,11 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
|||||||
tmp.second->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
tmp.second->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto* camSwitcher =
|
if (cfg.addCamSwitcherDummy) {
|
||||||
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, power::Switches::PDU2_CH8_PAYLOAD_CAMERA);
|
auto* camSwitcher = new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher,
|
||||||
camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
power::Switches::PDU2_CH8_PAYLOAD_CAMERA);
|
||||||
|
camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||||
|
}
|
||||||
auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy);
|
auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||||
auto* plPcduDummy =
|
auto* plPcduDummy =
|
||||||
|
@ -6,17 +6,22 @@ class GpioIF;
|
|||||||
|
|
||||||
namespace dummy {
|
namespace dummy {
|
||||||
|
|
||||||
|
// Default values targeted towards EM.
|
||||||
struct DummyCfg {
|
struct DummyCfg {
|
||||||
bool addCoreCtrlCfg = true;
|
bool addCoreCtrlCfg = true;
|
||||||
|
// Special variant because the ACU broke. Overrides addPowerDummies, only ACU dummy will be added.
|
||||||
|
bool addOnlyAcuDummy = false;
|
||||||
bool addPowerDummies = true;
|
bool addPowerDummies = true;
|
||||||
|
bool addBpxBattDummy = true;
|
||||||
bool addSyrlinksDummies = true;
|
bool addSyrlinksDummies = true;
|
||||||
bool addAcsBoardDummies = true;
|
bool addAcsBoardDummies = true;
|
||||||
bool addSusDummies = true;
|
bool addSusDummies = true;
|
||||||
bool addTempSensorDummies = true;
|
bool addTempSensorDummies = true;
|
||||||
bool addRtdComIFDummy = true;
|
bool addRtdComIFDummy = true;
|
||||||
bool addPlocDummies = true;
|
bool addPlocDummies = true;
|
||||||
|
bool addCamSwitcherDummy = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF);
|
void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF, bool enableHkSets);
|
||||||
|
|
||||||
} // namespace dummy
|
} // namespace dummy
|
||||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 285d327b97...0f76cdb3ba
@ -86,13 +86,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acs/defs.h
|
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
|
||||||
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acs/defs.h
|
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
|
||||||
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acs/defs.h
|
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
|
||||||
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acs/defs.h
|
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
|
||||||
11204;0x2bc4;MEKF_RECOVERY;INFO;No description;mission/acs/defs.h
|
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
|
||||||
11205;0x2bc5;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acs/defs.h
|
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||||
11206;0x2bc6;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acs/defs.h
|
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
|
||||||
|
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
|
||||||
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
||||||
@ -145,17 +146,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
||||||
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
||||||
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
||||||
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h
|
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h
|
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h
|
||||||
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h
|
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h
|
||||||
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h
|
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h
|
||||||
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h
|
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h
|
||||||
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h
|
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h
|
||||||
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h
|
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h
|
||||||
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h
|
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h
|
||||||
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h
|
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h
|
12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h
|
||||||
12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h
|
12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h
|
||||||
|
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
|
||||||
|
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
|
||||||
|
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
|
||||||
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
||||||
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
|
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
|
||||||
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
||||||
@ -173,20 +177,24 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12515;0x30e3;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/acs/StrComHandler.h
|
12515;0x30e3;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/acs/StrComHandler.h
|
||||||
12516;0x30e4;STR_HELPER_SENDING_PACKET_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
12516;0x30e4;STR_HELPER_SENDING_PACKET_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
||||||
12517;0x30e5;STR_HELPER_REQUESTING_MSG_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
12517;0x30e5;STR_HELPER_REQUESTING_MSG_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
||||||
12600;0x3138;MPSOC_FLASH_WRITE_FAILED;LOW;Flash write fails;linux/payload/PlocMpsocHelper.h
|
12600;0x3138;MPSOC_FLASH_WRITE_FAILED;LOW;Flash write fails;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12601;0x3139;MPSOC_FLASH_WRITE_SUCCESSFUL;LOW;Flash write successful;linux/payload/PlocMpsocHelper.h
|
12601;0x3139;MPSOC_FLASH_WRITE_SUCCESSFUL;INFO;Flash write successful;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12602;0x313a;MPSOC_SENDING_COMMAND_FAILED;LOW;No description;linux/payload/PlocMpsocHelper.h
|
12602;0x313a;MPSOC_SENDING_COMMAND_FAILED;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12603;0x313b;MPSOC_HELPER_REQUESTING_REPLY_FAILED;LOW;Request receive message of communication interface failed P1: Return value returned by the communication interface requestReceiveMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12603;0x313b;MPSOC_HELPER_REQUESTING_REPLY_FAILED;LOW;Request receive message of communication interface failed P1: Return value returned by the communication interface requestReceiveMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12604;0x313c;MPSOC_HELPER_READING_REPLY_FAILED;LOW;Reading receive message of communication interface failed P1: Return value returned by the communication interface readingReceivedMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12604;0x313c;MPSOC_HELPER_READING_REPLY_FAILED;LOW;Reading receive message of communication interface failed P1: Return value returned by the communication interface readingReceivedMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12605;0x313d;MPSOC_MISSING_ACK;LOW;Did not receive acknowledgment report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12605;0x313d;MPSOC_MISSING_ACK;LOW;Did not receive acknowledgment report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12606;0x313e;MPSOC_MISSING_EXE;LOW;Did not receive execution report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12606;0x313e;MPSOC_MISSING_EXE;LOW;Did not receive execution report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12607;0x313f;MPSOC_ACK_FAILURE_REPORT;LOW;Received acknowledgment failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12607;0x313f;MPSOC_ACK_FAILURE_REPORT;LOW;Received acknowledgment failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12608;0x3140;MPSOC_EXE_FAILURE_REPORT;LOW;Received execution failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12608;0x3140;MPSOC_EXE_FAILURE_REPORT;LOW;Received execution failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12609;0x3141;MPSOC_ACK_INVALID_APID;LOW;Expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12609;0x3141;MPSOC_ACK_INVALID_APID;LOW;Expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12610;0x3142;MPSOC_EXE_INVALID_APID;LOW;Expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12610;0x3142;MPSOC_EXE_INVALID_APID;LOW;Expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12611;0x3143;MPSOC_HELPER_SEQ_CNT_MISMATCH;LOW;Received sequence count does not match expected sequence count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHelper.h
|
12611;0x3143;MPSOC_HELPER_SEQ_CNT_MISMATCH;LOW;Received sequence count does not match expected sequence count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12612;0x3144;MPSOC_TM_SIZE_ERROR;LOW;No description;linux/payload/PlocMpsocHelper.h
|
12612;0x3144;MPSOC_TM_SIZE_ERROR;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12613;0x3145;MPSOC_TM_CRC_MISSMATCH;LOW;No description;linux/payload/PlocMpsocHelper.h
|
12613;0x3145;MPSOC_TM_CRC_MISSMATCH;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12614;0x3146;MPSOC_FLASH_READ_PACKET_ERROR;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12615;0x3147;MPSOC_FLASH_READ_FAILED;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12616;0x3148;MPSOC_FLASH_READ_SUCCESSFUL;INFO;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12617;0x3149;MPSOC_READ_TIMEOUT;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12700;0x319c;TRANSITION_BACK_TO_OFF;MEDIUM;Could not transition properly and went back to ALL OFF;mission/payload/PayloadPcduHandler.h
|
12700;0x319c;TRANSITION_BACK_TO_OFF;MEDIUM;Could not transition properly and went back to ALL OFF;mission/payload/PayloadPcduHandler.h
|
||||||
12701;0x319d;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
12701;0x319d;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
||||||
12702;0x319e;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
12702;0x319e;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
||||||
@ -208,7 +216,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
||||||
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
||||||
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
||||||
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h
|
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
|
||||||
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
||||||
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
||||||
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
||||||
@ -260,8 +268,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
||||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
||||||
14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
||||||
14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
||||||
|
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
|
||||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
@ -269,6 +278,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
|
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
||||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
||||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||||
|
|
@ -500,7 +500,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
|
0x6900;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
|
||||||
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
@ -509,9 +509,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
|
0x6d00;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
|
0x6d01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
|
0x6e00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||||
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
|
||||||
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
|
||||||
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
|
||||||
|
|
@ -86,13 +86,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acs/defs.h
|
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
|
||||||
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acs/defs.h
|
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
|
||||||
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acs/defs.h
|
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
|
||||||
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acs/defs.h
|
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
|
||||||
11204;0x2bc4;MEKF_RECOVERY;INFO;No description;mission/acs/defs.h
|
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
|
||||||
11205;0x2bc5;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acs/defs.h
|
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||||
11206;0x2bc6;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acs/defs.h
|
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
|
||||||
|
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
|
||||||
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
||||||
@ -145,17 +146,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
||||||
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
||||||
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
||||||
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h
|
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h
|
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h
|
||||||
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h
|
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h
|
||||||
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h
|
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h
|
||||||
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h
|
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h
|
||||||
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h
|
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h
|
||||||
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h
|
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h
|
||||||
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h
|
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h
|
||||||
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h
|
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h
|
12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h
|
||||||
12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h
|
12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h
|
||||||
|
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
|
||||||
|
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
|
||||||
|
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
|
||||||
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
||||||
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
|
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
|
||||||
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
||||||
@ -173,20 +177,24 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12515;0x30e3;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/acs/StrComHandler.h
|
12515;0x30e3;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/acs/StrComHandler.h
|
||||||
12516;0x30e4;STR_HELPER_SENDING_PACKET_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
12516;0x30e4;STR_HELPER_SENDING_PACKET_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
||||||
12517;0x30e5;STR_HELPER_REQUESTING_MSG_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
12517;0x30e5;STR_HELPER_REQUESTING_MSG_FAILED;LOW;No description;linux/acs/StrComHandler.h
|
||||||
12600;0x3138;MPSOC_FLASH_WRITE_FAILED;LOW;Flash write fails;linux/payload/PlocMpsocHelper.h
|
12600;0x3138;MPSOC_FLASH_WRITE_FAILED;LOW;Flash write fails;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12601;0x3139;MPSOC_FLASH_WRITE_SUCCESSFUL;LOW;Flash write successful;linux/payload/PlocMpsocHelper.h
|
12601;0x3139;MPSOC_FLASH_WRITE_SUCCESSFUL;INFO;Flash write successful;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12602;0x313a;MPSOC_SENDING_COMMAND_FAILED;LOW;No description;linux/payload/PlocMpsocHelper.h
|
12602;0x313a;MPSOC_SENDING_COMMAND_FAILED;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12603;0x313b;MPSOC_HELPER_REQUESTING_REPLY_FAILED;LOW;Request receive message of communication interface failed P1: Return value returned by the communication interface requestReceiveMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12603;0x313b;MPSOC_HELPER_REQUESTING_REPLY_FAILED;LOW;Request receive message of communication interface failed P1: Return value returned by the communication interface requestReceiveMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12604;0x313c;MPSOC_HELPER_READING_REPLY_FAILED;LOW;Reading receive message of communication interface failed P1: Return value returned by the communication interface readingReceivedMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12604;0x313c;MPSOC_HELPER_READING_REPLY_FAILED;LOW;Reading receive message of communication interface failed P1: Return value returned by the communication interface readingReceivedMessage function P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12605;0x313d;MPSOC_MISSING_ACK;LOW;Did not receive acknowledgment report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12605;0x313d;MPSOC_MISSING_ACK;LOW;Did not receive acknowledgment report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12606;0x313e;MPSOC_MISSING_EXE;LOW;Did not receive execution report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocHelper.h
|
12606;0x313e;MPSOC_MISSING_EXE;LOW;Did not receive execution report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12607;0x313f;MPSOC_ACK_FAILURE_REPORT;LOW;Received acknowledgment failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12607;0x313f;MPSOC_ACK_FAILURE_REPORT;LOW;Received acknowledgment failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12608;0x3140;MPSOC_EXE_FAILURE_REPORT;LOW;Received execution failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12608;0x3140;MPSOC_EXE_FAILURE_REPORT;LOW;Received execution failure report P1: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12609;0x3141;MPSOC_ACK_INVALID_APID;LOW;Expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12609;0x3141;MPSOC_ACK_INVALID_APID;LOW;Expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12610;0x3142;MPSOC_EXE_INVALID_APID;LOW;Expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocHelper.h
|
12610;0x3142;MPSOC_EXE_INVALID_APID;LOW;Expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of MPSoC;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12611;0x3143;MPSOC_HELPER_SEQ_CNT_MISMATCH;LOW;Received sequence count does not match expected sequence count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHelper.h
|
12611;0x3143;MPSOC_HELPER_SEQ_CNT_MISMATCH;LOW;Received sequence count does not match expected sequence count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12612;0x3144;MPSOC_TM_SIZE_ERROR;LOW;No description;linux/payload/PlocMpsocHelper.h
|
12612;0x3144;MPSOC_TM_SIZE_ERROR;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12613;0x3145;MPSOC_TM_CRC_MISSMATCH;LOW;No description;linux/payload/PlocMpsocHelper.h
|
12613;0x3145;MPSOC_TM_CRC_MISSMATCH;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12614;0x3146;MPSOC_FLASH_READ_PACKET_ERROR;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12615;0x3147;MPSOC_FLASH_READ_FAILED;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12616;0x3148;MPSOC_FLASH_READ_SUCCESSFUL;INFO;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
12617;0x3149;MPSOC_READ_TIMEOUT;LOW;No description;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
12700;0x319c;TRANSITION_BACK_TO_OFF;MEDIUM;Could not transition properly and went back to ALL OFF;mission/payload/PayloadPcduHandler.h
|
12700;0x319c;TRANSITION_BACK_TO_OFF;MEDIUM;Could not transition properly and went back to ALL OFF;mission/payload/PayloadPcduHandler.h
|
||||||
12701;0x319d;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
12701;0x319d;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
||||||
12702;0x319e;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
12702;0x319e;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/payload/PayloadPcduHandler.h
|
||||||
@ -208,7 +216,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
||||||
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
||||||
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
||||||
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h
|
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
|
||||||
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
||||||
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
||||||
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
||||||
@ -260,8 +268,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
||||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
||||||
14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
||||||
14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
||||||
|
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
|
||||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
@ -269,6 +278,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
|
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
||||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
||||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||||
|
|
@ -478,8 +478,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x53b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;182;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
|
0x53b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;182;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
|
||||||
0x53b7;STRH_StartrackerNotRunningFirmware;Star tracker must be in firmware mode to run this command;183;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
|
0x53b7;STRH_StartrackerNotRunningFirmware;Star tracker must be in firmware mode to run this command;183;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
|
||||||
0x53b8;STRH_StartrackerNotRunningBootloader;Star tracker must be in bootloader mode to run this command;184;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
|
0x53b8;STRH_StartrackerNotRunningBootloader;Star tracker must be in bootloader mode to run this command;184;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
|
||||||
0x54e0;DWLPWRON_InvalidMode;Received command has invalid JESD mode (valid modes are 0 - 5);224;DWLPWRON_CMD;linux/payload/plocMpscoDefs.h
|
0x54e0;DWLPWRON_InvalidMode;Received command has invalid JESD mode (valid modes are 0 - 5);224;DWLPWRON_CMD;linux/payload/plocMpsocHelpers.h
|
||||||
0x54e1;DWLPWRON_InvalidLaneRate;Received command has invalid lane rate (valid lane rate are 0 - 9);225;DWLPWRON_CMD;linux/payload/plocMpscoDefs.h
|
0x54e1;DWLPWRON_InvalidLaneRate;Received command has invalid lane rate (valid lane rate are 0 - 9);225;DWLPWRON_CMD;linux/payload/plocMpsocHelpers.h
|
||||||
0x5700;PLSPVhLP_RequestDone;No description;0;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
|
0x5700;PLSPVhLP_RequestDone;No description;0;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
|
||||||
0x5701;PLSPVhLP_NoPacketFound;No description;1;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
|
0x5701;PLSPVhLP_NoPacketFound;No description;1;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
|
||||||
0x5702;PLSPVhLP_DecodeBufTooSmall;No description;2;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
|
0x5702;PLSPVhLP_DecodeBufTooSmall;No description;2;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
|
||||||
@ -517,21 +517,21 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
|
0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
|
||||||
0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
||||||
0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
||||||
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/com/CcsdsIpCoreHandler.h
|
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/com/CcsdsIpCoreHandler.h
|
||||||
0x61a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;160;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
0x61a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;160;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
||||||
0x61a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);161;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
0x61a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);161;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
||||||
@ -543,7 +543,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
||||||
0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
||||||
0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
||||||
0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h
|
0x65a0;PLMPHLP_FileWriteError;File error occured for file transfers from OBC to the MPSoC.;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
|
0x65a1;PLMPHLP_FileReadError;File error occured for file transfers from MPSoC to OBC.;161;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocSpecialComHelper.h
|
||||||
0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
@ -583,7 +584,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x68b5;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);181;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
0x68b5;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);181;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||||
0x68c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
0x68c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||||
0x68c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
0x68c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||||
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
|
0x6900;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
|
||||||
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
@ -592,21 +593,18 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
|
0x6b00;SDMA_OpOngoing;No description;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
|
0x6b01;SDMA_AlreadyOn;No description;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
|
0x6b02;SDMA_AlreadyMounted;No description;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e00;SDMA_OpOngoing;No description;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b03;SDMA_AlreadyOff;No description;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e01;SDMA_AlreadyOn;No description;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0a;SDMA_StatusFileNexists;No description;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e02;SDMA_AlreadyMounted;No description;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0b;SDMA_StatusFileFormatInvalid;No description;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e03;SDMA_AlreadyOff;No description;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0c;SDMA_MountError;No description;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0a;SDMA_StatusFileNexists;No description;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0d;SDMA_UnmountError;No description;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0b;SDMA_StatusFileFormatInvalid;No description;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0c;SDMA_MountError;No description;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0d;SDMA_UnmountError;No description;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6c00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
|
||||||
0x6e0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6d00;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6e0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6d01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6f00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
|
0x6e00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||||
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
0x7000;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
||||||
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
|
||||||
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
|
||||||
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 285 translations.
|
* @brief Auto-generated event translation file. Contains 295 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-04-07 17:42:57
|
* Generated on: 2023-05-17 17:15:34
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
|
|||||||
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||||
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||||
|
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||||
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
|
|||||||
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
||||||
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
||||||
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
||||||
|
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
|
||||||
|
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||||
|
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||||
@ -193,6 +197,10 @@ const char *MPSOC_EXE_INVALID_APID_STRING = "MPSOC_EXE_INVALID_APID";
|
|||||||
const char *MPSOC_HELPER_SEQ_CNT_MISMATCH_STRING = "MPSOC_HELPER_SEQ_CNT_MISMATCH";
|
const char *MPSOC_HELPER_SEQ_CNT_MISMATCH_STRING = "MPSOC_HELPER_SEQ_CNT_MISMATCH";
|
||||||
const char *MPSOC_TM_SIZE_ERROR_STRING = "MPSOC_TM_SIZE_ERROR";
|
const char *MPSOC_TM_SIZE_ERROR_STRING = "MPSOC_TM_SIZE_ERROR";
|
||||||
const char *MPSOC_TM_CRC_MISSMATCH_STRING = "MPSOC_TM_CRC_MISSMATCH";
|
const char *MPSOC_TM_CRC_MISSMATCH_STRING = "MPSOC_TM_CRC_MISSMATCH";
|
||||||
|
const char *MPSOC_FLASH_READ_PACKET_ERROR_STRING = "MPSOC_FLASH_READ_PACKET_ERROR";
|
||||||
|
const char *MPSOC_FLASH_READ_FAILED_STRING = "MPSOC_FLASH_READ_FAILED";
|
||||||
|
const char *MPSOC_FLASH_READ_SUCCESSFUL_STRING = "MPSOC_FLASH_READ_SUCCESSFUL";
|
||||||
|
const char *MPSOC_READ_TIMEOUT_STRING = "MPSOC_READ_TIMEOUT";
|
||||||
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
||||||
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
||||||
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
||||||
@ -268,6 +276,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
|||||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||||
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||||
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||||
|
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
|
||||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||||
@ -275,6 +284,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
|
|||||||
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
||||||
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
||||||
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
||||||
|
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||||
@ -478,8 +488,10 @@ const char *translateEvents(Event event) {
|
|||||||
case (11204):
|
case (11204):
|
||||||
return MEKF_RECOVERY_STRING;
|
return MEKF_RECOVERY_STRING;
|
||||||
case (11205):
|
case (11205):
|
||||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
return MEKF_AUTOMATIC_RESET_STRING;
|
||||||
case (11206):
|
case (11206):
|
||||||
|
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||||
|
case (11207):
|
||||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||||
case (11300):
|
case (11300):
|
||||||
return SWITCH_CMD_SENT_STRING;
|
return SWITCH_CMD_SENT_STRING;
|
||||||
@ -604,9 +616,15 @@ const char *translateEvents(Event event) {
|
|||||||
case (12409):
|
case (12409):
|
||||||
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
||||||
case (12410):
|
case (12410):
|
||||||
return PDEC_RESET_FAILED_STRING;
|
return PDEC_TRYING_RESET_WITH_INIT_STRING;
|
||||||
case (12411):
|
case (12411):
|
||||||
|
return PDEC_TRYING_RESET_NO_INIT_STRING;
|
||||||
|
case (12412):
|
||||||
|
return PDEC_RESET_FAILED_STRING;
|
||||||
|
case (12413):
|
||||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||||
|
case (12414):
|
||||||
|
return PDEC_INIT_FAILED_STRING;
|
||||||
case (12500):
|
case (12500):
|
||||||
return IMAGE_UPLOAD_FAILED_STRING;
|
return IMAGE_UPLOAD_FAILED_STRING;
|
||||||
case (12501):
|
case (12501):
|
||||||
@ -669,6 +687,14 @@ const char *translateEvents(Event event) {
|
|||||||
return MPSOC_TM_SIZE_ERROR_STRING;
|
return MPSOC_TM_SIZE_ERROR_STRING;
|
||||||
case (12613):
|
case (12613):
|
||||||
return MPSOC_TM_CRC_MISSMATCH_STRING;
|
return MPSOC_TM_CRC_MISSMATCH_STRING;
|
||||||
|
case (12614):
|
||||||
|
return MPSOC_FLASH_READ_PACKET_ERROR_STRING;
|
||||||
|
case (12615):
|
||||||
|
return MPSOC_FLASH_READ_FAILED_STRING;
|
||||||
|
case (12616):
|
||||||
|
return MPSOC_FLASH_READ_SUCCESSFUL_STRING;
|
||||||
|
case (12617):
|
||||||
|
return MPSOC_READ_TIMEOUT_STRING;
|
||||||
case (12700):
|
case (12700):
|
||||||
return TRANSITION_BACK_TO_OFF_STRING;
|
return TRANSITION_BACK_TO_OFF_STRING;
|
||||||
case (12701):
|
case (12701):
|
||||||
@ -819,6 +845,8 @@ const char *translateEvents(Event event) {
|
|||||||
return TRYING_I2C_RECOVERY_STRING;
|
return TRYING_I2C_RECOVERY_STRING;
|
||||||
case (14011):
|
case (14011):
|
||||||
return I2C_REBOOT_STRING;
|
return I2C_REBOOT_STRING;
|
||||||
|
case (14012):
|
||||||
|
return PDEC_REBOOT_STRING;
|
||||||
case (14100):
|
case (14100):
|
||||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||||
case (14101):
|
case (14101):
|
||||||
@ -833,6 +861,8 @@ const char *translateEvents(Event event) {
|
|||||||
return PCDU_SYSTEM_OVERHEATING_STRING;
|
return PCDU_SYSTEM_OVERHEATING_STRING;
|
||||||
case (14107):
|
case (14107):
|
||||||
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
||||||
|
case (14108):
|
||||||
|
return MGT_OVERHEATING_STRING;
|
||||||
case (14201):
|
case (14201):
|
||||||
return TX_TIMER_EXPIRED_STRING;
|
return TX_TIMER_EXPIRED_STRING;
|
||||||
case (14202):
|
case (14202):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 175 translations.
|
* Contains 175 translations.
|
||||||
* Generated on: 2023-04-07 17:42:57
|
* Generated on: 2023-05-17 17:15:34
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
#include <mission/payload/ScexDeviceHandler.h>
|
#include <mission/payload/ScexDeviceHandler.h>
|
||||||
#include <mission/system/acs/SusAssembly.h>
|
#include <mission/system/acs/SusAssembly.h>
|
||||||
#include <mission/system/acs/SusFdir.h>
|
#include <mission/system/acs/SusFdir.h>
|
||||||
#include <mission/system/fdir/RtdFdir.h>
|
#include <mission/system/tcs/RtdFdir.h>
|
||||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
#include <mission/system/tcs/TcsBoardAssembly.h>
|
||||||
#include <mission/tcs/Max31865EiveHandler.h>
|
#include <mission/tcs/Max31865EiveHandler.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
@ -27,8 +27,9 @@
|
|||||||
#include "devices/gpioIds.h"
|
#include "devices/gpioIds.h"
|
||||||
#include "eive/definitions.h"
|
#include "eive/definitions.h"
|
||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/system/tree/payloadModeTree.h"
|
#include "mission/system/tree/payloadModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
#include "mission/tcs/defs.h"
|
||||||
|
|
||||||
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
|
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
|
||||||
PowerSwitchIF& pwrSwitcher, std::string spiDev,
|
PowerSwitchIF& pwrSwitcher, std::string spiDev,
|
||||||
@ -278,7 +279,8 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
|||||||
std::array<Max31865EiveHandler*, NUM_RTDS> rtds = {};
|
std::array<Max31865EiveHandler*, NUM_RTDS> rtds = {};
|
||||||
RtdFdir* rtdFdir = nullptr;
|
RtdFdir* rtdFdir = nullptr;
|
||||||
|
|
||||||
TcsBoardAssembly* tcsBoardAss = ObjectFactory::createTcsBoardAssy(*pwrSwitcher);
|
TcsBoardAssembly* tcsBoardAss =
|
||||||
|
ObjectFactory::createTcsBoardAssy(*pwrSwitcher, tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||||
|
|
||||||
// Create special low level reader communication interface
|
// Create special low level reader communication interface
|
||||||
new Max31865RtdPolling(objects::SPI_RTD_COM_IF, comIF, gpioComIF);
|
new Max31865RtdPolling(objects::SPI_RTD_COM_IF, comIF, gpioComIF);
|
||||||
|
@ -113,7 +113,9 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != adis.mode) {
|
if (req->mode != adis.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
adis.type = req->type;
|
adis.type = req->type;
|
||||||
adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
adis.decRate = req->cfg.decRateReg;
|
||||||
|
// The initial countdown is handled by the device handler now.
|
||||||
|
// adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
||||||
if (adis.type == adis1650x::Type::ADIS16507) {
|
if (adis.type == adis1650x::Type::ADIS16507) {
|
||||||
adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
|
adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
|
||||||
} else if (adis.type == adis1650x::Type::ADIS16505) {
|
} else if (adis.type == adis1650x::Type::ADIS16505) {
|
||||||
@ -121,11 +123,13 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
} else {
|
} else {
|
||||||
sif::warning << "AcsBoardPolling: Unknown ADIS type" << std::endl;
|
sif::warning << "AcsBoardPolling: Unknown ADIS type" << std::endl;
|
||||||
}
|
}
|
||||||
|
adis.replyResult = returnvalue::FAILED;
|
||||||
adis.performStartup = true;
|
adis.performStartup = true;
|
||||||
} else if (req->mode == acs::SimpleSensorMode::OFF) {
|
} else if (req->mode == acs::SimpleSensorMode::OFF) {
|
||||||
adis.performStartup = false;
|
adis.performStartup = false;
|
||||||
adis.ownReply.cfgWasSet = false;
|
adis.ownReply.cfgWasSet = false;
|
||||||
adis.ownReply.dataWasSet = false;
|
adis.ownReply.dataWasSet = false;
|
||||||
|
adis.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
adis.mode = req->mode;
|
adis.mode = req->mode;
|
||||||
}
|
}
|
||||||
@ -142,8 +146,10 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
std::memcpy(gyro.sensorCfg, req->ctrlRegs, 5);
|
std::memcpy(gyro.sensorCfg, req->ctrlRegs, 5);
|
||||||
gyro.performStartup = true;
|
gyro.performStartup = true;
|
||||||
|
gyro.replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
gyro.ownReply.cfgWasSet = false;
|
gyro.ownReply.cfgWasSet = false;
|
||||||
|
gyro.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
gyro.mode = req->mode;
|
gyro.mode = req->mode;
|
||||||
}
|
}
|
||||||
@ -159,8 +165,10 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != mgm.mode) {
|
if (req->mode != mgm.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
mgm.performStartup = true;
|
mgm.performStartup = true;
|
||||||
|
mgm.replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
mgm.ownReply.dataWasSet = false;
|
mgm.ownReply.dataWasSet = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
mgm.ownReply.temperatureWasSet = false;
|
mgm.ownReply.temperatureWasSet = false;
|
||||||
}
|
}
|
||||||
mgm.mode = req->mode;
|
mgm.mode = req->mode;
|
||||||
@ -177,8 +185,10 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != mgm.mode) {
|
if (req->mode != mgm.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
mgm.performStartup = true;
|
mgm.performStartup = true;
|
||||||
|
mgm.replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
mgm.ownReply.dataWasRead = false;
|
mgm.ownReply.dataWasRead = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
mgm.mode = req->mode;
|
mgm.mode = req->mode;
|
||||||
}
|
}
|
||||||
@ -309,18 +319,18 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
std::memcpy(cmdBuf.data() + 1, l3g.sensorCfg, 5);
|
std::memcpy(cmdBuf.data() + 1, l3g.sensorCfg, 5);
|
||||||
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
l3g.replyResult = returnvalue::OK;
|
l3g.replyResult = result;
|
||||||
}
|
}
|
||||||
// Ignore useless reply and red config
|
// Ignore useless reply and red config
|
||||||
cmdBuf[0] = l3gd20h::CTRL_REG_1 | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
cmdBuf[0] = l3gd20h::CTRL_REG_1 | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
||||||
std::memset(cmdBuf.data() + 1, 0, 5);
|
std::memset(cmdBuf.data() + 1, 0, 5);
|
||||||
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
l3g.replyResult = returnvalue::OK;
|
l3g.replyResult = result;
|
||||||
}
|
}
|
||||||
result = spiComIF.readReceivedMessage(l3g.cookie, &rawReply, &dummy);
|
result = spiComIF.readReceivedMessage(l3g.cookie, &rawReply, &dummy);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
l3g.replyResult = returnvalue::OK;
|
l3g.replyResult = result;
|
||||||
}
|
}
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
// Cross check configuration as verification that communication is working
|
// Cross check configuration as verification that communication is working
|
||||||
@ -331,6 +341,7 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
l3g.replyResult = returnvalue::OK;
|
||||||
l3g.performStartup = false;
|
l3g.performStartup = false;
|
||||||
l3g.ownReply.cfgWasSet = true;
|
l3g.ownReply.cfgWasSet = true;
|
||||||
l3g.ownReply.sensitivity = l3gd20h::ctrlReg4ToSensitivity(l3g.sensorCfg[3]);
|
l3g.ownReply.sensitivity = l3gd20h::ctrlReg4ToSensitivity(l3g.sensorCfg[3]);
|
||||||
@ -357,6 +368,7 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
l3g.replyResult = returnvalue::OK;
|
||||||
l3g.ownReply.statusReg = rawReply[l3gd20h::STATUS_IDX];
|
l3g.ownReply.statusReg = rawReply[l3gd20h::STATUS_IDX];
|
||||||
l3g.ownReply.angVelocities[0] = (rawReply[l3gd20h::OUT_X_H] << 8) | rawReply[l3gd20h::OUT_X_L];
|
l3g.ownReply.angVelocities[0] = (rawReply[l3gd20h::OUT_X_H] << 8) | rawReply[l3gd20h::OUT_X_L];
|
||||||
l3g.ownReply.angVelocities[1] = (rawReply[l3gd20h::OUT_Y_H] << 8) | rawReply[l3gd20h::OUT_Y_L];
|
l3g.ownReply.angVelocities[1] = (rawReply[l3gd20h::OUT_Y_H] << 8) | rawReply[l3gd20h::OUT_Y_L];
|
||||||
@ -365,6 +377,80 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t AcsBoardPolling::writeAdisReg(SpiCookie& cookie) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
int retval = 0;
|
||||||
|
// Prepare transfer
|
||||||
|
int fileDescriptor = 0;
|
||||||
|
std::string device = spiComIF.getSpiDev();
|
||||||
|
UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||||
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
|
return spi::OPENING_FILE_FAILED;
|
||||||
|
}
|
||||||
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
|
uint32_t spiSpeed = 0;
|
||||||
|
cookie.getSpiParameters(spiMode, spiSpeed, nullptr);
|
||||||
|
spiComIF.setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||||
|
cookie.assignWriteBuffer(cmdBuf.data());
|
||||||
|
cookie.setTransferSize(2);
|
||||||
|
|
||||||
|
gpioId_t gpioId = cookie.getChipSelectPin();
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t timeoutMs = 0;
|
||||||
|
MutexIF* mutex = spiComIF.getCsMutex();
|
||||||
|
cookie.getMutexParams(timeoutType, timeoutMs);
|
||||||
|
if (mutex == nullptr) {
|
||||||
|
sif::warning << "GyroADIS16507Handler::spiSendCallback: "
|
||||||
|
"Mutex or GPIO interface invalid"
|
||||||
|
<< std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = 0;
|
||||||
|
spi_ioc_transfer* transferStruct = cookie.getTransferStructHandle();
|
||||||
|
uint64_t origTx = transferStruct->tx_buf;
|
||||||
|
uint64_t origRx = transferStruct->rx_buf;
|
||||||
|
for (idx = 0; idx < 4; idx += 2) {
|
||||||
|
result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "AcsBoardPolling: Failed to lock mutex" << std::endl;
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Pull SPI CS low. For now, no support for active high given
|
||||||
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
gpioIF.pullLow(gpioId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute transfer
|
||||||
|
// Initiate a full duplex SPI transfer.
|
||||||
|
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie.getTransferStructHandle());
|
||||||
|
if (retval < 0) {
|
||||||
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
|
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
|
}
|
||||||
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
|
comIf->performSpiWiretapping(cookie);
|
||||||
|
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
|
||||||
|
|
||||||
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
gpioIF.pullHigh(gpioId);
|
||||||
|
}
|
||||||
|
mutex->unlockMutex();
|
||||||
|
|
||||||
|
transferStruct->tx_buf += 2;
|
||||||
|
transferStruct->rx_buf += 2;
|
||||||
|
if (idx < 4) {
|
||||||
|
usleep(adis1650x::STALL_TIME_MICROSECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transferStruct->tx_buf = origTx;
|
||||||
|
transferStruct->rx_buf = origRx;
|
||||||
|
cookie.setTransferSize(0);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen) {
|
ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
@ -443,21 +529,21 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
|||||||
void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||||
bool cdHasTimedOut = false;
|
|
||||||
bool mustPerformStartup = false;
|
bool mustPerformStartup = false;
|
||||||
|
uint16_t decRate = 0;
|
||||||
{
|
{
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
mode = gyro.mode;
|
mode = gyro.mode;
|
||||||
cdHasTimedOut = gyro.countdown.hasTimedOut();
|
decRate = gyro.decRate;
|
||||||
mustPerformStartup = gyro.performStartup;
|
mustPerformStartup = gyro.performStartup;
|
||||||
}
|
}
|
||||||
if (mode == acs::SimpleSensorMode::OFF) {
|
if (mode == acs::SimpleSensorMode::OFF) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (not cdHasTimedOut) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mustPerformStartup) {
|
if (mustPerformStartup) {
|
||||||
|
adis1650x::prepareWriteRegCommand(adis1650x::DEC_RATE_REG, decRate, cmdBuf.data(),
|
||||||
|
cmdBuf.size());
|
||||||
|
writeAdisReg(*gyro.cookie);
|
||||||
uint8_t regList[6];
|
uint8_t regList[6];
|
||||||
// Read configuration
|
// Read configuration
|
||||||
regList[0] = adis1650x::DIAG_STAT_REG;
|
regList[0] = adis1650x::DIAG_STAT_REG;
|
||||||
@ -485,16 +571,23 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
|||||||
gyro.replyResult = returnvalue::FAILED;
|
gyro.replyResult = returnvalue::FAILED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
uint16_t decRateReadBack = (rawReply[10] << 8) | rawReply[11];
|
||||||
|
if (decRateReadBack != decRate) {
|
||||||
|
sif::warning << "AcsPollingTask: DEC rate configuration failed. Read " << decRateReadBack
|
||||||
|
<< ", expected " << decRate << std::endl;
|
||||||
|
gyro.replyResult = returnvalue::FAILED;
|
||||||
|
}
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
gyro.ownReply.cfgWasSet = true;
|
gyro.ownReply.cfgWasSet = true;
|
||||||
gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3];
|
gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3];
|
||||||
gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5];
|
gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5];
|
||||||
gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7];
|
gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7];
|
||||||
gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9];
|
gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9];
|
||||||
gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11];
|
gyro.ownReply.cfg.decRateReg = decRateReadBack;
|
||||||
gyro.ownReply.cfg.prodId = prodId;
|
gyro.ownReply.cfg.prodId = prodId;
|
||||||
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
||||||
gyro.performStartup = false;
|
gyro.performStartup = false;
|
||||||
|
gyro.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
// Read regular registers
|
// Read regular registers
|
||||||
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
|
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
|
||||||
@ -533,6 +626,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
|
gyro.replyResult = returnvalue::OK;
|
||||||
gyro.ownReply.dataWasSet = true;
|
gyro.ownReply.dataWasSet = true;
|
||||||
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3];
|
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3];
|
||||||
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5];
|
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5];
|
||||||
@ -590,6 +684,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
|||||||
}
|
}
|
||||||
// Done here. We can always read back config and data during periodic handling
|
// Done here. We can always read back config and data during periodic handling
|
||||||
mgm.performStartup = false;
|
mgm.performStartup = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
cmdBuf[0] = mgmLis3::readCommand(mgmLis3::CTRL_REG1, true);
|
cmdBuf[0] = mgmLis3::readCommand(mgmLis3::CTRL_REG1, true);
|
||||||
std::memset(cmdBuf.data() + 1, 0, mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS);
|
std::memset(cmdBuf.data() + 1, 0, mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS);
|
||||||
@ -607,7 +702,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
|||||||
// Verify communication by re-checking config
|
// Verify communication by re-checking config
|
||||||
if (rawReply[1] != mgm.cfg[0] or rawReply[2] != mgm.cfg[1] or rawReply[3] != mgm.cfg[2] or
|
if (rawReply[1] != mgm.cfg[0] or rawReply[2] != mgm.cfg[1] or rawReply[3] != mgm.cfg[2] or
|
||||||
rawReply[4] != mgm.cfg[3] or rawReply[5] != mgm.cfg[4]) {
|
rawReply[4] != mgm.cfg[3] or rawReply[5] != mgm.cfg[4]) {
|
||||||
mgm.replyResult = result;
|
mgm.replyResult = returnvalue::FAILED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -634,6 +729,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
mgm.ownReply.temperatureWasSet = true;
|
mgm.ownReply.temperatureWasSet = true;
|
||||||
mgm.ownReply.temperatureRaw = (rawReply[2] << 8) | rawReply[1];
|
mgm.ownReply.temperatureRaw = (rawReply[2] << 8) | rawReply[1];
|
||||||
}
|
}
|
||||||
@ -704,6 +800,7 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mgm.performStartup = false;
|
mgm.performStartup = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
// Regular read operation
|
// Regular read operation
|
||||||
cmdBuf[0] = mgmRm3100::MEASUREMENT_REG_START | mgmRm3100::READ_MASK;
|
cmdBuf[0] = mgmRm3100::MEASUREMENT_REG_START | mgmRm3100::READ_MASK;
|
||||||
@ -725,6 +822,7 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
|||||||
mgm.ownReply.scaleFactors[idx] = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
mgm.ownReply.scaleFactors[idx] = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
||||||
}
|
}
|
||||||
mgm.ownReply.dataWasRead = true;
|
mgm.ownReply.dataWasRead = true;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
// Bitshift trickery to account for 24 bit signed value.
|
// Bitshift trickery to account for 24 bit signed value.
|
||||||
mgm.ownReply.mgmValuesRaw[0] =
|
mgm.ownReply.mgmValuesRaw[0] =
|
||||||
((rawReply[1] << 24) | (rawReply[2] << 16) | (rawReply[3] << 8)) >> 8;
|
((rawReply[1] << 24) | (rawReply[2] << 16) | (rawReply[3] << 8)) >> 8;
|
||||||
|
@ -37,6 +37,7 @@ class AcsBoardPolling : public SystemObject,
|
|||||||
|
|
||||||
struct GyroAdis : public DevBase {
|
struct GyroAdis : public DevBase {
|
||||||
adis1650x::Type type;
|
adis1650x::Type type;
|
||||||
|
uint16_t decRate;
|
||||||
Countdown countdown;
|
Countdown countdown;
|
||||||
acs::Adis1650XReply ownReply;
|
acs::Adis1650XReply ownReply;
|
||||||
acs::Adis1650XReply readerReply;
|
acs::Adis1650XReply readerReply;
|
||||||
@ -84,6 +85,8 @@ class AcsBoardPolling : public SystemObject,
|
|||||||
void gyroAdisHandler(GyroAdis& gyro);
|
void gyroAdisHandler(GyroAdis& gyro);
|
||||||
void mgmLis3Handler(MgmLis3& mgm);
|
void mgmLis3Handler(MgmLis3& mgm);
|
||||||
void mgmRm3100Handler(MgmRm3100& mgm);
|
void mgmRm3100Handler(MgmRm3100& mgm);
|
||||||
|
// This fumction configures the register as specified on p.21 of the datasheet.
|
||||||
|
ReturnValue_t writeAdisReg(SpiCookie& cookie);
|
||||||
// Special readout: 16us stall time between small 2 byte transfers.
|
// Special readout: 16us stall time between small 2 byte transfers.
|
||||||
ReturnValue_t readAdisCfg(SpiCookie& spiCookie, size_t transferLen);
|
ReturnValue_t readAdisCfg(SpiCookie& spiCookie, size_t transferLen);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
target_sources(
|
target_sources(${OBSW_NAME} PUBLIC AcsBoardPolling.cpp ImtqPollingTask.cpp
|
||||||
${OBSW_NAME} PUBLIC AcsBoardPolling.cpp ImtqPollingTask.cpp RwPollingTask.cpp
|
RwPollingTask.cpp SusPolling.cpp)
|
||||||
SusPolling.cpp StrComHandler.cpp)
|
|
||||||
|
# Dependency on proprietary library
|
||||||
|
if(TGT_BSP MATCHES "arm/q7s")
|
||||||
|
target_sources(${OBSW_NAME} PUBLIC StrComHandler.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
||||||
target_sources(${OBSW_NAME} PRIVATE GpsHyperionLinuxController.cpp)
|
target_sources(${OBSW_NAME} PRIVATE GpsHyperionLinuxController.cpp)
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include "mission/utility/ProgressPrinter.h"
|
#include "mission/utility/ProgressPrinter.h"
|
||||||
#include "mission/utility/Timestamp.h"
|
#include "mission/utility/Timestamp.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <sagitta/client/actionreq.h>
|
||||||
|
}
|
||||||
|
|
||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
|
|
||||||
StrComHandler::StrComHandler(object_id_t objectId) : SystemObject(objectId) {
|
StrComHandler::StrComHandler(object_id_t objectId) : SystemObject(objectId) {
|
||||||
@ -89,7 +93,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InternalState::FIRMWARE_UPDATE: {
|
case InternalState::FIRMWARE_UPDATE: {
|
||||||
replyTimeout.setTimeout(200);
|
replyTimeout.setTimeout(2000);
|
||||||
resetReplyHandlingState();
|
resetReplyHandlingState();
|
||||||
result = performFirmwareUpdate();
|
result = performFirmwareUpdate();
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
@ -125,6 +129,7 @@ ReturnValue_t StrComHandler::startImageUpload(std::string fullname) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::UPLOAD_IMAGE;
|
state = InternalState::UPLOAD_IMAGE;
|
||||||
}
|
}
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -151,6 +156,7 @@ ReturnValue_t StrComHandler::startImageDownload(std::string path) {
|
|||||||
downloadImage.path = path;
|
downloadImage.path = path;
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::DOWNLOAD_IMAGE;
|
state = InternalState::DOWNLOAD_IMAGE;
|
||||||
}
|
}
|
||||||
terminate = false;
|
terminate = false;
|
||||||
@ -187,6 +193,7 @@ ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) {
|
|||||||
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST);
|
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST);
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::FIRMWARE_UPDATE;
|
state = InternalState::FIRMWARE_UPDATE;
|
||||||
}
|
}
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -216,6 +223,7 @@ ReturnValue_t StrComHandler::startFlashRead(std::string path, uint8_t startRegio
|
|||||||
flashRead.size = length;
|
flashRead.size = length;
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::FLASH_READ;
|
state = InternalState::FLASH_READ;
|
||||||
}
|
}
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -301,6 +309,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
uint32_t imageSize = 0;
|
uint32_t imageSize = 0;
|
||||||
struct UploadActionRequest uploadReq;
|
struct UploadActionRequest uploadReq;
|
||||||
uploadReq.position = 0;
|
uploadReq.position = 0;
|
||||||
|
size_t writtenBytes = 0;
|
||||||
#ifdef XIPHOS_Q7S
|
#ifdef XIPHOS_Q7S
|
||||||
if (not sdcMan->getActiveSdCard()) {
|
if (not sdcMan->getActiveSdCard()) {
|
||||||
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
||||||
@ -323,7 +332,9 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
ProgressPrinter progressPrinter("Image upload", imageSize);
|
ProgressPrinter progressPrinter("Image upload", imageSize);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
while ((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) {
|
size_t fullChunks = imageSize / SIZE_IMAGE_PART;
|
||||||
|
size_t remainder = imageSize % SIZE_IMAGE_PART;
|
||||||
|
for (size_t idx = 0; idx < fullChunks; idx++) {
|
||||||
if (terminate) {
|
if (terminate) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -342,6 +353,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
uploadReq.position++;
|
uploadReq.position++;
|
||||||
|
writtenBytes += SIZE_IMAGE_PART;
|
||||||
|
|
||||||
// This does a bit of delaying roughly every second
|
// This does a bit of delaying roughly every second
|
||||||
if (uploadReq.position % 50 == 0) {
|
if (uploadReq.position % 50 == 0) {
|
||||||
@ -349,20 +361,20 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
TaskFactory::delayTask(2);
|
TaskFactory::delayTask(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
|
if (remainder > 0) {
|
||||||
uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART;
|
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
|
||||||
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
|
file.seekg(fullChunks * SIZE_IMAGE_PART, file.beg);
|
||||||
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
|
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
|
||||||
file.close();
|
file.close();
|
||||||
uploadReq.position++;
|
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
|
||||||
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
|
result = sendAndRead(size, uploadReq.position);
|
||||||
result = sendAndRead(size, uploadReq.position);
|
if (result != returnvalue::OK) {
|
||||||
if (result != returnvalue::OK) {
|
return returnvalue::FAILED;
|
||||||
return returnvalue::FAILED;
|
}
|
||||||
}
|
result = checkActionReply(replyLen);
|
||||||
result = checkActionReply(replyLen);
|
if (result != returnvalue::OK) {
|
||||||
if (result != returnvalue::OK) {
|
return result;
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
||||||
@ -390,7 +402,8 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
#endif
|
#endif
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
uint32_t bytesWritten = 0;
|
uint32_t bytesWrittenInRegion = 0;
|
||||||
|
size_t totalBytesWritten = 0;
|
||||||
uint32_t fileSize = 0;
|
uint32_t fileSize = 0;
|
||||||
|
|
||||||
struct WriteActionRequest req;
|
struct WriteActionRequest req;
|
||||||
@ -412,20 +425,18 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
ProgressPrinter progressPrinter("Flash write", fileSize);
|
ProgressPrinter progressPrinter("Flash write", fileSize);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
uint32_t fileChunks = fileSize / CHUNK_SIZE;
|
uint32_t fileChunks = fileSize / CHUNK_SIZE;
|
||||||
bytesWritten = 0;
|
bytesWrittenInRegion = 0;
|
||||||
req.region = flashWrite.firstRegion;
|
req.region = flashWrite.firstRegion;
|
||||||
req.length = CHUNK_SIZE;
|
req.length = CHUNK_SIZE;
|
||||||
for (uint32_t idx = 0; idx < fileChunks; idx++) {
|
|
||||||
if (terminate) {
|
auto writeNextSegment = [&](uint32_t chunkIdx) {
|
||||||
return returnvalue::OK;
|
file.seekg(chunkIdx * CHUNK_SIZE, file.beg);
|
||||||
}
|
|
||||||
file.seekg(idx * CHUNK_SIZE, file.beg);
|
|
||||||
file.read(reinterpret_cast<char*>(req.data), CHUNK_SIZE);
|
file.read(reinterpret_cast<char*>(req.data), CHUNK_SIZE);
|
||||||
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
if (bytesWrittenInRegion + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
||||||
req.region++;
|
req.region++;
|
||||||
bytesWritten = 0;
|
bytesWrittenInRegion = 0;
|
||||||
}
|
}
|
||||||
req.address = bytesWritten;
|
req.address = bytesWrittenInRegion;
|
||||||
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
||||||
result = sendAndRead(size, req.address);
|
result = sendAndRead(size, req.address);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -435,34 +446,49 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
bytesWritten += CHUNK_SIZE;
|
totalBytesWritten += CHUNK_SIZE;
|
||||||
|
bytesWrittenInRegion += CHUNK_SIZE;
|
||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
progressPrinter.print(idx * CHUNK_SIZE);
|
progressPrinter.print(chunkIdx * CHUNK_SIZE);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t idx = 0; idx < fileChunks; idx++) {
|
||||||
|
if (terminate) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
result = writeNextSegment(idx);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (idx % 50 == 0) {
|
if (idx % 50 == 0) {
|
||||||
// Some grace time for other tasks
|
// Some grace time for other tasks
|
||||||
TaskFactory::delayTask(2);
|
TaskFactory::delayTask(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t remainingBytes = fileSize - fileChunks * CHUNK_SIZE;
|
uint32_t remainingBytes = fileSize - fileChunks * CHUNK_SIZE;
|
||||||
file.seekg((fileChunks - 1) * CHUNK_SIZE, file.beg);
|
if (remainingBytes > 0) {
|
||||||
file.read(reinterpret_cast<char*>(req.data), remainingBytes);
|
file.seekg(fileChunks * CHUNK_SIZE, file.beg);
|
||||||
file.close();
|
file.read(reinterpret_cast<char*>(req.data), remainingBytes);
|
||||||
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
file.close();
|
||||||
req.region++;
|
if (bytesWrittenInRegion + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
||||||
bytesWritten = 0;
|
req.region++;
|
||||||
}
|
bytesWrittenInRegion = 0;
|
||||||
req.address = bytesWritten;
|
}
|
||||||
req.length = remainingBytes;
|
req.address = bytesWrittenInRegion;
|
||||||
bytesWritten += remainingBytes;
|
req.length = remainingBytes;
|
||||||
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
totalBytesWritten += CHUNK_SIZE;
|
||||||
result = sendAndRead(size, req.address);
|
bytesWrittenInRegion += remainingBytes;
|
||||||
if (result != returnvalue::OK) {
|
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
||||||
return result;
|
result = sendAndRead(size, req.address);
|
||||||
}
|
if (result != returnvalue::OK) {
|
||||||
result = checkActionReply(replyLen);
|
return result;
|
||||||
if (result != returnvalue::OK) {
|
}
|
||||||
return result;
|
result = checkActionReply(replyLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
progressPrinter.print(fileSize);
|
progressPrinter.print(fileSize);
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#include "bsp_q7s/fs/SdCardManager.h"
|
#include "bsp_q7s/fs/SdCardManager.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "arcsec/client/generated/actionreq.h"
|
|
||||||
#include "arcsec/common/generated/tmtcstructs.h"
|
|
||||||
#include "fsfw/devicehandlers/CookieIF.h"
|
#include "fsfw/devicehandlers/CookieIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/osal/linux/BinarySemaphore.h"
|
#include "fsfw/osal/linux/BinarySemaphore.h"
|
||||||
@ -174,7 +172,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
|
|||||||
static const uint32_t FLASH_REGION_SIZE = 0x20000;
|
static const uint32_t FLASH_REGION_SIZE = 0x20000;
|
||||||
|
|
||||||
struct ImageDownload {
|
struct ImageDownload {
|
||||||
static const uint32_t LAST_POSITION = 4095;
|
static const uint32_t LAST_POSITION = 4096;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t MAX_POLLS = 10000;
|
static const uint32_t MAX_POLLS = 10000;
|
||||||
|
@ -69,9 +69,12 @@ ReturnValue_t SusPolling::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|||||||
if (susDevs[susIdx].mode != susReq->mode) {
|
if (susDevs[susIdx].mode != susReq->mode) {
|
||||||
if (susReq->mode == acs::SimpleSensorMode::NORMAL) {
|
if (susReq->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
susDevs[susIdx].performStartup = true;
|
susDevs[susIdx].performStartup = true;
|
||||||
|
susDevs[susIdx].replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
susDevs[susIdx].ownReply.cfgWasSet = false;
|
susDevs[susIdx].ownReply.cfgWasSet = false;
|
||||||
susDevs[susIdx].ownReply.dataWasSet = false;
|
susDevs[susIdx].ownReply.dataWasSet = false;
|
||||||
|
// We are off now, but DHB wants a proper reply.
|
||||||
|
susDevs[susIdx].replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
susDevs[susIdx].mode = susReq->mode;
|
susDevs[susIdx].mode = susReq->mode;
|
||||||
}
|
}
|
||||||
@ -95,11 +98,14 @@ ReturnValue_t SusPolling::readReceivedMessage(CookieIF* cookie, uint8_t** buffer
|
|||||||
if (susIdx < 0) {
|
if (susIdx < 0) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (susDevs[susIdx].replyResult != returnvalue::OK) {
|
||||||
|
return susDevs[susIdx].replyResult;
|
||||||
|
}
|
||||||
MutexGuard mg(ipcLock);
|
MutexGuard mg(ipcLock);
|
||||||
std::memcpy(&susDevs[susIdx].readerReply, &susDevs[susIdx].ownReply, sizeof(acs::SusReply));
|
std::memcpy(&susDevs[susIdx].readerReply, &susDevs[susIdx].ownReply, sizeof(acs::SusReply));
|
||||||
*buffer = reinterpret_cast<uint8_t*>(&susDevs[susIdx].readerReply);
|
*buffer = reinterpret_cast<uint8_t*>(&susDevs[susIdx].readerReply);
|
||||||
*size = sizeof(acs::SusReply);
|
*size = sizeof(acs::SusReply);
|
||||||
return OK;
|
return susDevs[susIdx].replyResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SusPolling::handleSusPolling() {
|
ReturnValue_t SusPolling::handleSusPolling() {
|
||||||
@ -164,11 +170,18 @@ ReturnValue_t SusPolling::handleSusPolling() {
|
|||||||
}
|
}
|
||||||
MutexGuard mg(ipcLock);
|
MutexGuard mg(ipcLock);
|
||||||
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
|
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
|
||||||
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
|
// Reply is all ones. Sensor is probably off or faulty when
|
||||||
susDevs[idx].ownReply.channelsRaw[chIdx] =
|
// it should not be.
|
||||||
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
|
if (susDevs[idx].ownReply.tempRaw == 0x0fff) {
|
||||||
|
susDevs[idx].replyResult = returnvalue::FAILED;
|
||||||
|
} else {
|
||||||
|
susDevs[idx].replyResult = returnvalue::OK;
|
||||||
|
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
|
||||||
|
susDevs[idx].ownReply.channelsRaw[chIdx] =
|
||||||
|
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
|
||||||
|
}
|
||||||
|
susDevs[idx].ownReply.dataWasSet = true;
|
||||||
}
|
}
|
||||||
susDevs[idx].ownReply.dataWasSet = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 285 translations.
|
* @brief Auto-generated event translation file. Contains 295 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-04-07 17:42:57
|
* Generated on: 2023-05-17 17:15:34
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
|
|||||||
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||||
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||||
|
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||||
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
|
|||||||
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
||||||
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
||||||
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
||||||
|
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
|
||||||
|
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||||
|
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||||
@ -193,6 +197,10 @@ const char *MPSOC_EXE_INVALID_APID_STRING = "MPSOC_EXE_INVALID_APID";
|
|||||||
const char *MPSOC_HELPER_SEQ_CNT_MISMATCH_STRING = "MPSOC_HELPER_SEQ_CNT_MISMATCH";
|
const char *MPSOC_HELPER_SEQ_CNT_MISMATCH_STRING = "MPSOC_HELPER_SEQ_CNT_MISMATCH";
|
||||||
const char *MPSOC_TM_SIZE_ERROR_STRING = "MPSOC_TM_SIZE_ERROR";
|
const char *MPSOC_TM_SIZE_ERROR_STRING = "MPSOC_TM_SIZE_ERROR";
|
||||||
const char *MPSOC_TM_CRC_MISSMATCH_STRING = "MPSOC_TM_CRC_MISSMATCH";
|
const char *MPSOC_TM_CRC_MISSMATCH_STRING = "MPSOC_TM_CRC_MISSMATCH";
|
||||||
|
const char *MPSOC_FLASH_READ_PACKET_ERROR_STRING = "MPSOC_FLASH_READ_PACKET_ERROR";
|
||||||
|
const char *MPSOC_FLASH_READ_FAILED_STRING = "MPSOC_FLASH_READ_FAILED";
|
||||||
|
const char *MPSOC_FLASH_READ_SUCCESSFUL_STRING = "MPSOC_FLASH_READ_SUCCESSFUL";
|
||||||
|
const char *MPSOC_READ_TIMEOUT_STRING = "MPSOC_READ_TIMEOUT";
|
||||||
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
||||||
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
||||||
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
||||||
@ -268,6 +276,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
|||||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||||
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||||
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||||
|
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
|
||||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||||
@ -275,6 +284,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
|
|||||||
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
||||||
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
||||||
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
||||||
|
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||||
@ -478,8 +488,10 @@ const char *translateEvents(Event event) {
|
|||||||
case (11204):
|
case (11204):
|
||||||
return MEKF_RECOVERY_STRING;
|
return MEKF_RECOVERY_STRING;
|
||||||
case (11205):
|
case (11205):
|
||||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
return MEKF_AUTOMATIC_RESET_STRING;
|
||||||
case (11206):
|
case (11206):
|
||||||
|
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||||
|
case (11207):
|
||||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||||
case (11300):
|
case (11300):
|
||||||
return SWITCH_CMD_SENT_STRING;
|
return SWITCH_CMD_SENT_STRING;
|
||||||
@ -604,9 +616,15 @@ const char *translateEvents(Event event) {
|
|||||||
case (12409):
|
case (12409):
|
||||||
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
||||||
case (12410):
|
case (12410):
|
||||||
return PDEC_RESET_FAILED_STRING;
|
return PDEC_TRYING_RESET_WITH_INIT_STRING;
|
||||||
case (12411):
|
case (12411):
|
||||||
|
return PDEC_TRYING_RESET_NO_INIT_STRING;
|
||||||
|
case (12412):
|
||||||
|
return PDEC_RESET_FAILED_STRING;
|
||||||
|
case (12413):
|
||||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||||
|
case (12414):
|
||||||
|
return PDEC_INIT_FAILED_STRING;
|
||||||
case (12500):
|
case (12500):
|
||||||
return IMAGE_UPLOAD_FAILED_STRING;
|
return IMAGE_UPLOAD_FAILED_STRING;
|
||||||
case (12501):
|
case (12501):
|
||||||
@ -669,6 +687,14 @@ const char *translateEvents(Event event) {
|
|||||||
return MPSOC_TM_SIZE_ERROR_STRING;
|
return MPSOC_TM_SIZE_ERROR_STRING;
|
||||||
case (12613):
|
case (12613):
|
||||||
return MPSOC_TM_CRC_MISSMATCH_STRING;
|
return MPSOC_TM_CRC_MISSMATCH_STRING;
|
||||||
|
case (12614):
|
||||||
|
return MPSOC_FLASH_READ_PACKET_ERROR_STRING;
|
||||||
|
case (12615):
|
||||||
|
return MPSOC_FLASH_READ_FAILED_STRING;
|
||||||
|
case (12616):
|
||||||
|
return MPSOC_FLASH_READ_SUCCESSFUL_STRING;
|
||||||
|
case (12617):
|
||||||
|
return MPSOC_READ_TIMEOUT_STRING;
|
||||||
case (12700):
|
case (12700):
|
||||||
return TRANSITION_BACK_TO_OFF_STRING;
|
return TRANSITION_BACK_TO_OFF_STRING;
|
||||||
case (12701):
|
case (12701):
|
||||||
@ -819,6 +845,8 @@ const char *translateEvents(Event event) {
|
|||||||
return TRYING_I2C_RECOVERY_STRING;
|
return TRYING_I2C_RECOVERY_STRING;
|
||||||
case (14011):
|
case (14011):
|
||||||
return I2C_REBOOT_STRING;
|
return I2C_REBOOT_STRING;
|
||||||
|
case (14012):
|
||||||
|
return PDEC_REBOOT_STRING;
|
||||||
case (14100):
|
case (14100):
|
||||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||||
case (14101):
|
case (14101):
|
||||||
@ -833,6 +861,8 @@ const char *translateEvents(Event event) {
|
|||||||
return PCDU_SYSTEM_OVERHEATING_STRING;
|
return PCDU_SYSTEM_OVERHEATING_STRING;
|
||||||
case (14107):
|
case (14107):
|
||||||
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
||||||
|
case (14108):
|
||||||
|
return MGT_OVERHEATING_STRING;
|
||||||
case (14201):
|
case (14201):
|
||||||
return TX_TIMER_EXPIRED_STRING;
|
return TX_TIMER_EXPIRED_STRING;
|
||||||
case (14202):
|
case (14202):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 175 translations.
|
* Contains 175 translations.
|
||||||
* Generated on: 2023-04-07 17:42:57
|
* Generated on: 2023-05-17 17:15:34
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
#include "fsfw_hal/linux/uio/UioMapper.h"
|
#include "fsfw_hal/linux/uio/UioMapper.h"
|
||||||
|
#include "linux/ipcore/PdecConfig.h"
|
||||||
#include "pdec.h"
|
#include "pdec.h"
|
||||||
|
|
||||||
using namespace pdec;
|
using namespace pdec;
|
||||||
@ -103,21 +104,10 @@ ReturnValue_t PdecHandler::firstLoop() {
|
|||||||
|
|
||||||
result = releasePdec();
|
result = releasePdec();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This configuration must be done while the PDEC is not held in reset.
|
|
||||||
if (OP_MODE == Modes::IRQ) {
|
|
||||||
// Configure interrupt mask register to enable interrupts
|
|
||||||
*(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
|
|
||||||
}
|
|
||||||
result = resetFarStatFlag();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
// Requires reconfiguration and reinitialization of PDEC
|
|
||||||
triggerEvent(INVALID_FAR);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
|
||||||
|
return postResetOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
||||||
@ -141,10 +131,11 @@ ReturnValue_t PdecHandler::polledOperation() {
|
|||||||
if (newTcReceived()) {
|
if (newTcReceived()) {
|
||||||
handleNewTc();
|
handleNewTc();
|
||||||
}
|
}
|
||||||
checkLocks();
|
doPeriodicWork();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::PDEC_RESET: {
|
case State::PDEC_RESET: {
|
||||||
|
triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT);
|
||||||
ReturnValue_t result = pdecToReset();
|
ReturnValue_t result = pdecToReset();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
triggerEvent(PDEC_RESET_FAILED);
|
triggerEvent(PDEC_RESET_FAILED);
|
||||||
@ -165,8 +156,8 @@ ReturnValue_t PdecHandler::polledOperation() {
|
|||||||
// See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information.
|
// See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information.
|
||||||
ReturnValue_t PdecHandler::irqOperation() {
|
ReturnValue_t PdecHandler::irqOperation() {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
int fd = -1;
|
// int fd = -1;
|
||||||
// Used to unmask IRQ
|
// Used to unmask IRQ
|
||||||
uint32_t info = 1;
|
uint32_t info = 1;
|
||||||
|
|
||||||
interruptWindowCd.resetTimer();
|
interruptWindowCd.resetTimer();
|
||||||
@ -182,22 +173,29 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case State::INIT: {
|
case State::INIT: {
|
||||||
result = handleInitState();
|
result = handleInitState();
|
||||||
if (result == returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
openIrqFile(&fd);
|
break;
|
||||||
|
}
|
||||||
|
openIrqFile();
|
||||||
|
if (ptmeResetWithReinitializationPending) {
|
||||||
|
actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION);
|
||||||
|
ptmeResetWithReinitializationPending = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::PDEC_RESET: {
|
case State::PDEC_RESET: {
|
||||||
|
triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT);
|
||||||
result = pdecToReset();
|
result = pdecToReset();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
triggerEvent(PDEC_RESET_FAILED);
|
triggerEvent(PDEC_RESET_FAILED);
|
||||||
}
|
}
|
||||||
|
usleep(20);
|
||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::RUNNING: {
|
case State::RUNNING: {
|
||||||
checkLocks();
|
doPeriodicWork();
|
||||||
checkAndHandleIrqs(fd, info);
|
checkAndHandleIrqs(info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::WAIT_FOR_RECOVERY:
|
case State::WAIT_FOR_RECOVERY:
|
||||||
@ -219,27 +217,28 @@ ReturnValue_t PdecHandler::handleInitState() {
|
|||||||
ReturnValue_t result = firstLoop();
|
ReturnValue_t result = firstLoop();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
if (result == LocalParameterHandler::SD_NOT_READY) {
|
if (result == LocalParameterHandler::SD_NOT_READY) {
|
||||||
TaskFactory::delayTask(400);
|
|
||||||
if (initTries == MAX_INIT_TRIES) {
|
if (initTries == MAX_INIT_TRIES) {
|
||||||
sif::error << "PdecHandler::handleInitState: SD card never "
|
sif::error << "PdecHandler::handleInitState: SD card never becomes ready" << std::endl;
|
||||||
"becomes ready"
|
initFailedHandler(result);
|
||||||
<< std::endl;
|
return result;
|
||||||
state = State::WAIT_FOR_RECOVERY;
|
|
||||||
} else {
|
|
||||||
state = State::INIT;
|
|
||||||
}
|
}
|
||||||
|
state = State::INIT;
|
||||||
|
initTries++;
|
||||||
|
TaskFactory::delayTask(400);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
state = State::WAIT_FOR_RECOVERY;
|
sif::error << "PDEC: Init failed with reason 0x" << std::hex << std::setw(4) << result
|
||||||
|
<< std::endl;
|
||||||
|
initFailedHandler(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
state = State::RUNNING;
|
state = State::RUNNING;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdecHandler::openIrqFile(int* fd) {
|
void PdecHandler::openIrqFile() {
|
||||||
*fd = open(uioNames.irq, O_RDWR);
|
irqFd = open(uioNames.irq, O_RDWR);
|
||||||
if (*fd < 0) {
|
if (irqFd < 0) {
|
||||||
sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed"
|
sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
triggerEvent(OPEN_IRQ_FILE_FAILED);
|
triggerEvent(OPEN_IRQ_FILE_FAILED);
|
||||||
@ -247,16 +246,16 @@ void PdecHandler::openIrqFile(int* fd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
|
ReturnValue_t PdecHandler::checkAndHandleIrqs(uint32_t& info) {
|
||||||
ssize_t nb = write(fd, &info, sizeof(info));
|
ssize_t nb = write(irqFd, &info, sizeof(info));
|
||||||
if (nb != static_cast<ssize_t>(sizeof(info))) {
|
if (nb != static_cast<ssize_t>(sizeof(info))) {
|
||||||
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
|
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
|
||||||
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
|
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
|
||||||
close(fd);
|
close(irqFd);
|
||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
|
struct pollfd fds = {.fd = irqFd, .events = POLLIN, .revents = 0};
|
||||||
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
|
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
// No TCs for timeout period
|
// No TCs for timeout period
|
||||||
@ -264,7 +263,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
|
|||||||
resetIrqLimiters();
|
resetIrqLimiters();
|
||||||
} else if (ret >= 1) {
|
} else if (ret >= 1) {
|
||||||
// Interrupt handling.
|
// Interrupt handling.
|
||||||
nb = read(fd, &info, sizeof(info));
|
nb = read(irqFd, &info, sizeof(info));
|
||||||
interruptCounter++;
|
interruptCounter++;
|
||||||
if (nb == static_cast<ssize_t>(sizeof(info))) {
|
if (nb == static_cast<ssize_t>(sizeof(info))) {
|
||||||
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
|
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
|
||||||
@ -303,7 +302,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
|
|||||||
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
|
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
|
||||||
<< strerror(errno) << std::endl;
|
<< strerror(errno) << std::endl;
|
||||||
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
|
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
|
||||||
close(fd);
|
close(irqFd);
|
||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
@ -335,6 +334,7 @@ MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->get
|
|||||||
|
|
||||||
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
|
using namespace pdec;
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case PRINT_CLCW:
|
case PRINT_CLCW:
|
||||||
printClcw();
|
printClcw();
|
||||||
@ -342,6 +342,16 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c
|
|||||||
case PRINT_PDEC_MON:
|
case PRINT_PDEC_MON:
|
||||||
printPdecMon();
|
printPdecMon();
|
||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
|
case RESET_PDEC_NO_REINIITALIZATION: {
|
||||||
|
pdecResetNoInit();
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case RESET_PDEC_WITH_REINIITALIZATION: {
|
||||||
|
initializeReset();
|
||||||
|
ptmeResetWithReinitializationPending = true;
|
||||||
|
this->commandedBy = commandedBy;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return COMMAND_NOT_IMPLEMENTED;
|
return COMMAND_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
@ -370,7 +380,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
// PDEC needs reset to apply this parameter change
|
// PDEC needs reset to apply this parameter change
|
||||||
state = State::PDEC_RESET;
|
initializeReset();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) {
|
} else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) {
|
||||||
uint8_t newVal = 0;
|
uint8_t newVal = 0;
|
||||||
@ -392,7 +402,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
// PDEC needs reset to apply this parameter change
|
// PDEC needs reset to apply this parameter change
|
||||||
state = State::PDEC_RESET;
|
initializeReset();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -425,8 +435,7 @@ ReturnValue_t PdecHandler::releasePdec() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::pdecToReset() {
|
ReturnValue_t PdecHandler::pdecToReset() {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = gpioComIF->pullLow(pdecReset);
|
||||||
result = gpioComIF->pullLow(pdecReset);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error << "PdecHandler::pdecToReset: Failed to pull PDEC reset line"
|
sif::error << "PdecHandler::pdecToReset: Failed to pull PDEC reset line"
|
||||||
" to low"
|
" to low"
|
||||||
@ -449,22 +458,13 @@ bool PdecHandler::newTcReceived() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdecHandler::checkLocks() {
|
void PdecHandler::doPeriodicWork() {
|
||||||
uint32_t clcw = getClcw();
|
// scuffed test code
|
||||||
if (not(clcw & NO_RF_MASK) && not carrierLock) {
|
// if(testCntr < 30) {
|
||||||
triggerEvent(CARRIER_LOCK);
|
// triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
|
||||||
carrierLock = true;
|
// testCntr++;
|
||||||
} else if ((clcw & NO_RF_MASK) && carrierLock) {
|
// }
|
||||||
carrierLock = false;
|
checkLocks();
|
||||||
triggerEvent(LOST_CARRIER_LOCK_PDEC);
|
|
||||||
}
|
|
||||||
if (not(clcw & NO_BITLOCK_MASK) && not bitLock) {
|
|
||||||
triggerEvent(BIT_LOCK_PDEC);
|
|
||||||
bitLock = true;
|
|
||||||
} else if ((clcw & NO_BITLOCK_MASK) && bitLock) {
|
|
||||||
bitLock = false;
|
|
||||||
triggerEvent(LOST_BIT_LOCK_PDEC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
||||||
@ -748,6 +748,68 @@ void PdecHandler::resetIrqLimiters() {
|
|||||||
interruptCounter = 0;
|
interruptCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdecHandler::checkLocks() {
|
||||||
|
uint32_t clcw = getClcw();
|
||||||
|
if (not(clcw & NO_RF_MASK) && not carrierLock) {
|
||||||
|
triggerEvent(CARRIER_LOCK);
|
||||||
|
carrierLock = true;
|
||||||
|
} else if ((clcw & NO_RF_MASK) && carrierLock) {
|
||||||
|
carrierLock = false;
|
||||||
|
triggerEvent(LOST_CARRIER_LOCK_PDEC);
|
||||||
|
}
|
||||||
|
if (not(clcw & NO_BITLOCK_MASK) && not bitLock) {
|
||||||
|
triggerEvent(BIT_LOCK_PDEC);
|
||||||
|
bitLock = true;
|
||||||
|
} else if ((clcw & NO_BITLOCK_MASK) && bitLock) {
|
||||||
|
bitLock = false;
|
||||||
|
triggerEvent(LOST_BIT_LOCK_PDEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdecHandler::initFailedHandler(ReturnValue_t reason) {
|
||||||
|
triggerEvent(pdec::PDEC_INIT_FAILED, reason, 0);
|
||||||
|
if (ptmeResetWithReinitializationPending) {
|
||||||
|
actionHelper.finish(false, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION, reason);
|
||||||
|
ptmeResetWithReinitializationPending = false;
|
||||||
|
}
|
||||||
|
state = State::WAIT_FOR_RECOVERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdecHandler::pdecResetNoInit() {
|
||||||
|
triggerEvent(pdec::PDEC_TRYING_RESET_NO_INIT);
|
||||||
|
pdecToReset();
|
||||||
|
usleep(20);
|
||||||
|
releasePdec();
|
||||||
|
ReturnValue_t result = postResetOperation();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// What can we really do here? Event was already triggered if this is due to the FAR flag
|
||||||
|
// not being reset.
|
||||||
|
sif::error << "PdecHandler::pdecResetNoInit: Post reset operation failed unexpectedly"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PdecHandler::postResetOperation() {
|
||||||
|
// This configuration must be done while the PDEC is not held in reset.
|
||||||
|
if (OP_MODE == Modes::IRQ) {
|
||||||
|
// Configure interrupt mask register to enable interrupts
|
||||||
|
*(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
|
||||||
|
}
|
||||||
|
ReturnValue_t result = resetFarStatFlag();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Requires reconfiguration and reinitialization of PDEC
|
||||||
|
triggerEvent(INVALID_FAR);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdecHandler::initializeReset() {
|
||||||
|
if (irqFd != 0) {
|
||||||
|
close(irqFd);
|
||||||
|
}
|
||||||
|
state = State::PDEC_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
std::string PdecHandler::getMonStatusString(uint32_t status) {
|
std::string PdecHandler::getMonStatusString(uint32_t status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case TC_CHANNEL_INACTIVE:
|
case TC_CHANNEL_INACTIVE:
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <fsfw/timemanager/Countdown.h>
|
#include <fsfw/timemanager/Countdown.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "PdecConfig.h"
|
#include "PdecConfig.h"
|
||||||
#include "eive/definitions.h"
|
#include "eive/definitions.h"
|
||||||
@ -79,73 +81,11 @@ class PdecHandler : public SystemObject,
|
|||||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||||
uint16_t startAtIndex) override;
|
uint16_t startAtIndex) override;
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
|
||||||
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
|
||||||
//! P2: When frame declared illegal this parameter this parameter gives information about the
|
|
||||||
//! reason (IReason field of the PDEC_FAR register)
|
|
||||||
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
|
||||||
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Carrier lock detected
|
|
||||||
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
|
||||||
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Lost carrier lock
|
|
||||||
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Lost bit lock
|
|
||||||
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs
|
|
||||||
static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM);
|
|
||||||
static constexpr Event POLL_SYSCALL_ERROR_PDEC =
|
|
||||||
event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM);
|
|
||||||
static constexpr Event WRITE_SYSCALL_ERROR_PDEC =
|
|
||||||
event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low
|
|
||||||
static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file
|
|
||||||
static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
|
||||||
|
|
||||||
static constexpr Modes OP_MODE = Modes::IRQ;
|
static constexpr Modes OP_MODE = Modes::IRQ;
|
||||||
|
|
||||||
static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0);
|
|
||||||
static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1);
|
|
||||||
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
|
|
||||||
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
|
|
||||||
static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3);
|
|
||||||
static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4);
|
|
||||||
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
|
||||||
|
|
||||||
static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6);
|
|
||||||
//! Error in version number and reserved A and B fields
|
|
||||||
static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7);
|
|
||||||
//! Illegal combination of bypass and control command flag
|
|
||||||
static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8);
|
|
||||||
//! Spacecraft identifier did not match
|
|
||||||
static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9);
|
|
||||||
//! VC identifier bits 0 to 4 did not match
|
|
||||||
static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA);
|
|
||||||
//! VC identifier bit 5 did not match
|
|
||||||
static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB);
|
|
||||||
//! N(S) of BC or BD frame not set to all zeros
|
|
||||||
static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC);
|
|
||||||
//! Invalid BC control command
|
|
||||||
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
|
||||||
|
|
||||||
static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE;
|
static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE;
|
||||||
|
|
||||||
// Action IDs
|
|
||||||
static const ActionId_t PRINT_CLCW = 0;
|
|
||||||
// Print PDEC monitor register
|
|
||||||
static const ActionId_t PRINT_PDEC_MON = 1;
|
|
||||||
|
|
||||||
#ifdef TE0720_1CFA
|
#ifdef TE0720_1CFA
|
||||||
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
||||||
static const int RAM_MAP_SIZE = 0x4000;
|
static const int RAM_MAP_SIZE = 0x4000;
|
||||||
@ -185,17 +125,6 @@ class PdecHandler : public SystemObject,
|
|||||||
|
|
||||||
static constexpr uint32_t MAX_ALLOWED_IRQS_PER_WINDOW = 800;
|
static constexpr uint32_t MAX_ALLOWED_IRQS_PER_WINDOW = 800;
|
||||||
|
|
||||||
enum class FrameAna_t : uint8_t {
|
|
||||||
ABANDONED_CLTU,
|
|
||||||
FRAME_DIRTY,
|
|
||||||
FRAME_ILLEGAL,
|
|
||||||
FRAME_ILLEGAL_MULTI_REASON,
|
|
||||||
AD_DISCARDED_LOCKOUT,
|
|
||||||
AD_DISCARDED_WAIT,
|
|
||||||
AD_DISCARDED_NS_VR,
|
|
||||||
FRAME_ACCEPTED
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class IReason_t : uint8_t {
|
enum class IReason_t : uint8_t {
|
||||||
NO_REPORT,
|
NO_REPORT,
|
||||||
ERROR_VERSION_NUMBER,
|
ERROR_VERSION_NUMBER,
|
||||||
@ -213,6 +142,7 @@ class PdecHandler : public SystemObject,
|
|||||||
|
|
||||||
Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS);
|
Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS);
|
||||||
object_id_t tcDestinationId;
|
object_id_t tcDestinationId;
|
||||||
|
int irqFd = 0;
|
||||||
|
|
||||||
AcceptsTelecommandsIF* tcDestination = nullptr;
|
AcceptsTelecommandsIF* tcDestination = nullptr;
|
||||||
|
|
||||||
@ -258,6 +188,9 @@ class PdecHandler : public SystemObject,
|
|||||||
bool carrierLock = false;
|
bool carrierLock = false;
|
||||||
bool bitLock = false;
|
bool bitLock = false;
|
||||||
|
|
||||||
|
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
|
||||||
|
bool ptmeResetWithReinitializationPending = false;
|
||||||
|
|
||||||
UioNames uioNames;
|
UioNames uioNames;
|
||||||
|
|
||||||
ParameterHelper paramHelper;
|
ParameterHelper paramHelper;
|
||||||
@ -266,6 +199,9 @@ class PdecHandler : public SystemObject,
|
|||||||
|
|
||||||
uint32_t initTries = 0;
|
uint32_t initTries = 0;
|
||||||
|
|
||||||
|
// scuffed test counter.
|
||||||
|
uint8_t testCntr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs initialization stuff which must be performed in first
|
* @brief Performs initialization stuff which must be performed in first
|
||||||
* loop of running task
|
* loop of running task
|
||||||
@ -282,8 +218,8 @@ class PdecHandler : public SystemObject,
|
|||||||
ReturnValue_t polledOperation();
|
ReturnValue_t polledOperation();
|
||||||
ReturnValue_t irqOperation();
|
ReturnValue_t irqOperation();
|
||||||
ReturnValue_t handleInitState();
|
ReturnValue_t handleInitState();
|
||||||
void openIrqFile(int* fd);
|
void openIrqFile();
|
||||||
ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info);
|
ReturnValue_t checkAndHandleIrqs(uint32_t& info);
|
||||||
|
|
||||||
uint32_t readFar();
|
uint32_t readFar();
|
||||||
|
|
||||||
@ -325,6 +261,8 @@ class PdecHandler : public SystemObject,
|
|||||||
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
|
void doPeriodicWork();
|
||||||
|
|
||||||
void checkLocks();
|
void checkLocks();
|
||||||
|
|
||||||
void resetIrqLimiters();
|
void resetIrqLimiters();
|
||||||
@ -400,6 +338,13 @@ class PdecHandler : public SystemObject,
|
|||||||
*/
|
*/
|
||||||
void printPdecMon();
|
void printPdecMon();
|
||||||
|
|
||||||
|
void pdecResetNoInit();
|
||||||
|
|
||||||
|
ReturnValue_t postResetOperation();
|
||||||
|
void initializeReset();
|
||||||
|
|
||||||
|
void initFailedHandler(ReturnValue_t reason);
|
||||||
|
|
||||||
std::string getMonStatusString(uint32_t status);
|
std::string getMonStatusString(uint32_t status);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,95 @@
|
|||||||
#ifndef LINUX_OBC_PDEC_H_
|
#ifndef LINUX_OBC_PDEC_H_
|
||||||
#define LINUX_OBC_PDEC_H_
|
#define LINUX_OBC_PDEC_H_
|
||||||
|
|
||||||
|
#include <eive/resultClassIds.h>
|
||||||
|
#include <fsfw/action/ActionMessage.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace pdec {
|
namespace pdec {
|
||||||
|
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
||||||
|
static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0);
|
||||||
|
static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1);
|
||||||
|
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3);
|
||||||
|
static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4);
|
||||||
|
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||||
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
||||||
|
|
||||||
|
static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6);
|
||||||
|
//! Error in version number and reserved A and B fields
|
||||||
|
static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7);
|
||||||
|
//! Illegal combination of bypass and control command flag
|
||||||
|
static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8);
|
||||||
|
//! Spacecraft identifier did not match
|
||||||
|
static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9);
|
||||||
|
//! VC identifier bits 0 to 4 did not match
|
||||||
|
static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA);
|
||||||
|
//! VC identifier bit 5 did not match
|
||||||
|
static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB);
|
||||||
|
//! N(S) of BC or BD frame not set to all zeros
|
||||||
|
static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC);
|
||||||
|
//! Invalid BC control command
|
||||||
|
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
||||||
|
|
||||||
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
||||||
|
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
||||||
|
//! P2: When frame declared illegal this parameter this parameter gives information about the
|
||||||
|
//! reason (IReason field of the PDEC_FAR register)
|
||||||
|
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
||||||
|
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Carrier lock detected
|
||||||
|
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
||||||
|
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Lost carrier lock
|
||||||
|
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Lost bit lock
|
||||||
|
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs
|
||||||
|
static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM);
|
||||||
|
static constexpr Event POLL_SYSCALL_ERROR_PDEC =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM);
|
||||||
|
static constexpr Event WRITE_SYSCALL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Trying a PDEC reset with complete re-initialization
|
||||||
|
static constexpr Event PDEC_TRYING_RESET_WITH_INIT =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Trying a PDEC reset without re-initialization.
|
||||||
|
static constexpr Event PDEC_TRYING_RESET_NO_INIT =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low
|
||||||
|
static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file
|
||||||
|
static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 13, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent
|
||||||
|
//! confiuration never becoming available, for example due to SD card issues.
|
||||||
|
static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 14, severity::HIGH);
|
||||||
|
|
||||||
|
// Action IDs
|
||||||
|
static constexpr ActionId_t PRINT_CLCW = 0;
|
||||||
|
// Print PDEC monitor register
|
||||||
|
static constexpr ActionId_t PRINT_PDEC_MON = 1;
|
||||||
|
static constexpr ActionId_t RESET_PDEC_NO_REINIITALIZATION = 2;
|
||||||
|
static constexpr ActionId_t RESET_PDEC_WITH_REINIITALIZATION = 3;
|
||||||
|
|
||||||
|
enum class FrameAna_t : uint8_t {
|
||||||
|
ABANDONED_CLTU,
|
||||||
|
FRAME_DIRTY,
|
||||||
|
FRAME_ILLEGAL,
|
||||||
|
FRAME_ILLEGAL_MULTI_REASON,
|
||||||
|
AD_DISCARDED_LOCKOUT,
|
||||||
|
AD_DISCARDED_WAIT,
|
||||||
|
AD_DISCARDED_NS_VR,
|
||||||
|
FRAME_ACCEPTED
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t STAT_POSITION = 31;
|
static const uint8_t STAT_POSITION = 31;
|
||||||
static const uint8_t FRAME_ANA_POSITION = 28;
|
static const uint8_t FRAME_ANA_POSITION = 28;
|
||||||
static const uint8_t IREASON_POSITION = 25;
|
static const uint8_t IREASON_POSITION = 25;
|
||||||
|
@ -2,7 +2,8 @@ target_sources(
|
|||||||
${OBSW_NAME}
|
${OBSW_NAME}
|
||||||
PUBLIC PlocMemoryDumper.cpp
|
PUBLIC PlocMemoryDumper.cpp
|
||||||
PlocMpsocHandler.cpp
|
PlocMpsocHandler.cpp
|
||||||
PlocMpsocHelper.cpp
|
PlocMpsocSpecialComHelper.cpp
|
||||||
|
plocMpsocHelpers.cpp
|
||||||
PlocSupervisorHandler.cpp
|
PlocSupervisorHandler.cpp
|
||||||
PlocSupvUartMan.cpp
|
PlocSupvUartMan.cpp
|
||||||
ScexDleParser.cpp
|
ScexDleParser.cpp
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,9 @@
|
|||||||
#ifndef BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_
|
#ifndef BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_
|
||||||
#define BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_
|
#define BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_
|
||||||
|
|
||||||
#include <linux/payload/PlocMpsocHelper.h>
|
#include <linux/payload/PlocMpsocSpecialComHelper.h>
|
||||||
#include <linux/payload/mpsocRetvals.h>
|
#include <linux/payload/mpsocRetvals.h>
|
||||||
#include <linux/payload/plocMpscoDefs.h>
|
#include <linux/payload/plocMpsocHelpers.h>
|
||||||
#include <linux/payload/plocSupvDefs.h>
|
#include <linux/payload/plocSupvDefs.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -28,9 +28,10 @@
|
|||||||
* @note The sequence count in the space packets must be incremented with each received and sent
|
* @note The sequence count in the space packets must be incremented with each received and sent
|
||||||
* packet otherwise the MPSoC will reply with an acknowledgment failure report.
|
* packet otherwise the MPSoC will reply with an acknowledgment failure report.
|
||||||
*
|
*
|
||||||
* @author J. Meier
|
* NOTE: This is not an example for a good device handler, DO NOT USE THIS AS A REFERENCE HANDLER.
|
||||||
|
* @author J. Meier, R. Mueller
|
||||||
*/
|
*/
|
||||||
class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
@ -43,10 +44,10 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
* module in the programmable logic
|
* module in the programmable logic
|
||||||
* @param supervisorHandler Object ID of the supervisor handler
|
* @param supervisorHandler Object ID of the supervisor handler
|
||||||
*/
|
*/
|
||||||
PlocMPSoCHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF* comCookie,
|
PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF* comCookie,
|
||||||
PlocMPSoCHelper* plocMPSoCHelper, Gpio uartIsolatorSwitch,
|
PlocMpsocSpecialComHelper* plocMPSoCHelper, Gpio uartIsolatorSwitch,
|
||||||
object_id_t supervisorHandler);
|
object_id_t supervisorHandler);
|
||||||
virtual ~PlocMPSoCHandler();
|
virtual ~PlocMpsocHandler();
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) override;
|
const uint8_t* data, size_t size) override;
|
||||||
@ -77,7 +78,9 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
||||||
DeviceCommandId_t alternateReplyID = 0) override;
|
DeviceCommandId_t alternateReplyID = 0) override;
|
||||||
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||||
virtual ReturnValue_t doSendReadHook() override;
|
ReturnValue_t doSendReadHook() override;
|
||||||
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
|
bool dontCheckQueue() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER;
|
||||||
@ -103,7 +106,8 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
|
|
||||||
static const uint16_t APID_MASK = 0x7FF;
|
static const uint16_t APID_MASK = 0x7FF;
|
||||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||||
static const uint8_t STATUS_OFFSET = 10;
|
|
||||||
|
mpsoc::HkReport hkReport;
|
||||||
|
|
||||||
MessageQueueIF* eventQueue = nullptr;
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
MessageQueueIF* commandActionHelperQueue = nullptr;
|
MessageQueueIF* commandActionHelperQueue = nullptr;
|
||||||
@ -114,6 +118,41 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
SpacePacketCreator creator;
|
SpacePacketCreator creator;
|
||||||
ploc::SpTcParams spParams = ploc::SpTcParams(creator);
|
ploc::SpTcParams spParams = ploc::SpTcParams(creator);
|
||||||
|
|
||||||
|
PoolEntry<uint32_t> peStatus = PoolEntry<uint32_t>();
|
||||||
|
PoolEntry<uint8_t> peMode = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peDownlinkPwrOn = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peDownlinkReplyActive = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peDownlinkJesdSyncStatus = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peDownlinkDacStatus = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peCameraStatus = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peCameraSdiStatus = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<float> peCameraFpgaTemp = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peCameraSocTemp = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonTemp = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVccInt = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVccAux = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVccBram = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVccPaux = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVccPint = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVccPdro = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonMb12V = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonMb3V3 = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonMb1V8 = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc12V = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc5V = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc3V3 = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc3V3VA = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc2V5DDR = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc1V2DDR = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc0V9 = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonVcc0V6VTT = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonSafeCotsCur = PoolEntry<float>();
|
||||||
|
PoolEntry<float> peSysmonNvm4XoCur = PoolEntry<float>();
|
||||||
|
PoolEntry<uint16_t> peSemUncorrectableErrs = PoolEntry<uint16_t>();
|
||||||
|
PoolEntry<uint16_t> peSemCorrectableErrs = PoolEntry<uint16_t>();
|
||||||
|
PoolEntry<uint8_t> peSemStatus = PoolEntry<uint8_t>();
|
||||||
|
PoolEntry<uint8_t> peRebootMpsocRequired = PoolEntry<uint8_t>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This variable is used to store the id of the next reply to receive. This is necessary
|
* This variable is used to store the id of the next reply to receive. This is necessary
|
||||||
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
||||||
@ -123,13 +162,14 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
|
|
||||||
SerialComIF* uartComIf = nullptr;
|
SerialComIF* uartComIf = nullptr;
|
||||||
|
|
||||||
PlocMPSoCHelper* plocMPSoCHelper = nullptr;
|
PlocMpsocSpecialComHelper* specialComHelper = nullptr;
|
||||||
Gpio uartIsolatorSwitch;
|
Gpio uartIsolatorSwitch;
|
||||||
object_id_t supervisorHandler = 0;
|
object_id_t supervisorHandler = 0;
|
||||||
CommandActionHelper commandActionHelper;
|
CommandActionHelper commandActionHelper;
|
||||||
|
|
||||||
// Used to block incoming commands when MPSoC helper class is currently executing a command
|
// Used to block incoming commands when MPSoC helper class is currently executing a command
|
||||||
bool plocMPSoCHelperExecuting = false;
|
bool specialComHelperExecuting = false;
|
||||||
|
bool commandIsPending = false;
|
||||||
|
|
||||||
struct TmMemReadReport {
|
struct TmMemReadReport {
|
||||||
static const uint8_t FIX_SIZE = 14;
|
static const uint8_t FIX_SIZE = 14;
|
||||||
@ -137,20 +177,18 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TmMemReadReport tmMemReadReport;
|
TmMemReadReport tmMemReadReport;
|
||||||
|
Countdown cmdCountdown = Countdown(10000);
|
||||||
struct TmCamCmdRpt {
|
|
||||||
size_t rememberSpacePacketSize = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
TmCamCmdRpt tmCamCmdRpt;
|
|
||||||
|
|
||||||
struct TelemetryBuffer {
|
struct TelemetryBuffer {
|
||||||
uint16_t length = 0;
|
uint16_t length = 0;
|
||||||
uint8_t buffer[mpsoc::SP_MAX_SIZE];
|
uint8_t buffer[mpsoc::SP_MAX_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
size_t foundPacketLen = 0;
|
||||||
TelemetryBuffer tmBuffer;
|
TelemetryBuffer tmBuffer;
|
||||||
|
uint32_t waitCycles = 0;
|
||||||
|
|
||||||
|
enum class StartupState { IDLE, HW_INIT, WAIT_CYCLES, DONE } startupState = StartupState::IDLE;
|
||||||
enum class PowerState { OFF, BOOTING, SHUTDOWN, ON };
|
enum class PowerState { OFF, BOOTING, SHUTDOWN, ON };
|
||||||
|
|
||||||
PowerState powerState = PowerState::OFF;
|
PowerState powerState = PowerState::OFF;
|
||||||
@ -167,6 +205,8 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
ReturnValue_t prepareTcReplayStop();
|
ReturnValue_t prepareTcReplayStop();
|
||||||
ReturnValue_t prepareTcDownlinkPwrOn(const uint8_t* commandData, size_t commandDataLen);
|
ReturnValue_t prepareTcDownlinkPwrOn(const uint8_t* commandData, size_t commandDataLen);
|
||||||
ReturnValue_t prepareTcDownlinkPwrOff();
|
ReturnValue_t prepareTcDownlinkPwrOff();
|
||||||
|
ReturnValue_t prepareTcGetHkReport();
|
||||||
|
ReturnValue_t prepareTcGetDirContent(const uint8_t* commandData, size_t commandDataLen);
|
||||||
ReturnValue_t prepareTcReplayWriteSequence(const uint8_t* commandData, size_t commandDataLen);
|
ReturnValue_t prepareTcReplayWriteSequence(const uint8_t* commandData, size_t commandDataLen);
|
||||||
ReturnValue_t prepareTcCamCmdSend(const uint8_t* commandData, size_t commandDataLen);
|
ReturnValue_t prepareTcCamCmdSend(const uint8_t* commandData, size_t commandDataLen);
|
||||||
ReturnValue_t prepareTcModeIdle();
|
ReturnValue_t prepareTcModeIdle();
|
||||||
@ -174,7 +214,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
ReturnValue_t prepareTcSimplexSendFile(const uint8_t* commandData, size_t commandDataLen);
|
ReturnValue_t prepareTcSimplexSendFile(const uint8_t* commandData, size_t commandDataLen);
|
||||||
ReturnValue_t prepareTcDownlinkDataModulate(const uint8_t* commandData, size_t commandDataLen);
|
ReturnValue_t prepareTcDownlinkDataModulate(const uint8_t* commandData, size_t commandDataLen);
|
||||||
ReturnValue_t prepareTcModeSnapshot();
|
ReturnValue_t prepareTcModeSnapshot();
|
||||||
void finishTcPrep(size_t packetLen);
|
ReturnValue_t finishTcPrep(mpsoc::TcBase& tcBase);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function checks the crc of the received PLOC reply.
|
* @brief This function checks the crc of the received PLOC reply.
|
||||||
@ -213,6 +253,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t handleMemoryReadReport(const uint8_t* data);
|
ReturnValue_t handleMemoryReadReport(const uint8_t* data);
|
||||||
|
|
||||||
|
ReturnValue_t handleGetHkReport(const uint8_t* data);
|
||||||
ReturnValue_t handleCamCmdRpt(const uint8_t* data);
|
ReturnValue_t handleCamCmdRpt(const uint8_t* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,7 +272,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
* @param dataSize Size of telemetry in bytes.
|
* @param dataSize Size of telemetry in bytes.
|
||||||
* @param replyId Id of the reply. This will be added to the ActionMessage.
|
* @param replyId Id of the reply. This will be added to the ActionMessage.
|
||||||
*/
|
*/
|
||||||
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
|
void handleDeviceTm(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief In case an acknowledgment failure reply has been received this function disables
|
* @brief In case an acknowledgment failure reply has been received this function disables
|
||||||
@ -255,15 +296,11 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
|||||||
*/
|
*/
|
||||||
void disableExeReportReply();
|
void disableExeReportReply();
|
||||||
|
|
||||||
void printStatus(const uint8_t* data);
|
|
||||||
|
|
||||||
ReturnValue_t prepareTcModeReplay();
|
ReturnValue_t prepareTcModeReplay();
|
||||||
|
|
||||||
uint16_t getStatus(const uint8_t* data);
|
void cmdDoneHandler(bool success, ReturnValue_t result);
|
||||||
|
|
||||||
void handleActionCommandFailure(ActionId_t actionId);
|
void handleActionCommandFailure(ActionId_t actionId);
|
||||||
|
|
||||||
std::string getStatusString(uint16_t status);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ */
|
#endif /* BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ */
|
||||||
|
@ -1,355 +0,0 @@
|
|||||||
#include <linux/payload/PlocMpsocHelper.h>
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#ifdef XIPHOS_Q7S
|
|
||||||
#include "bsp_q7s/fs/FilesystemHelper.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mission/utility/Timestamp.h"
|
|
||||||
|
|
||||||
using namespace ploc;
|
|
||||||
|
|
||||||
PlocMPSoCHelper::PlocMPSoCHelper(object_id_t objectId) : SystemObject(objectId) {
|
|
||||||
spParams.buf = commandBuffer;
|
|
||||||
spParams.maxSize = sizeof(commandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlocMPSoCHelper::~PlocMPSoCHelper() {}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::initialize() {
|
|
||||||
#ifdef XIPHOS_Q7S
|
|
||||||
sdcMan = SdCardManager::instance();
|
|
||||||
if (sdcMan == nullptr) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::initialize: Invalid SD Card Manager" << std::endl;
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::performOperation(uint8_t operationCode) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
semaphore.acquire();
|
|
||||||
while (true) {
|
|
||||||
#if OBSW_THREAD_TRACING == 1
|
|
||||||
trace::threadTrace(opCounter, "PLOC MPSOC Helper");
|
|
||||||
#endif
|
|
||||||
switch (internalState) {
|
|
||||||
case InternalState::IDLE: {
|
|
||||||
semaphore.acquire();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case InternalState::FLASH_WRITE: {
|
|
||||||
result = performFlashWrite();
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL);
|
|
||||||
} else {
|
|
||||||
triggerEvent(MPSOC_FLASH_WRITE_FAILED);
|
|
||||||
}
|
|
||||||
internalState = InternalState::IDLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
sif::debug << "PlocMPSoCHelper::performOperation: Invalid state" << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::setComIF(DeviceCommunicationIF* communicationInterface_) {
|
|
||||||
uartComIF = dynamic_cast<SerialComIF*>(communicationInterface_);
|
|
||||||
if (uartComIF == nullptr) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl;
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMPSoCHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
|
|
||||||
|
|
||||||
void PlocMPSoCHelper::setSequenceCount(SourceSequenceCounter* sequenceCount_) {
|
|
||||||
sequenceCount = sequenceCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::startFlashWrite(std::string obcFile, std::string mpsocFile) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
#ifdef XIPHOS_Q7S
|
|
||||||
result = FilesystemHelper::checkPath(obcFile);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = FilesystemHelper::fileExists(mpsocFile);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef TE0720_1CFA
|
|
||||||
if (not std::filesystem::exists(obcFile)) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::startFlashWrite: File " << obcFile << "does not exist"
|
|
||||||
<< std::endl;
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
flashWrite.obcFile = obcFile;
|
|
||||||
flashWrite.mpsocFile = mpsocFile;
|
|
||||||
internalState = InternalState::FLASH_WRITE;
|
|
||||||
result = resetHelper();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::resetHelper() {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
semaphore.release();
|
|
||||||
spParams.buf = commandBuffer;
|
|
||||||
terminate = false;
|
|
||||||
result = uartComIF->flushUartRxBuffer(comCookie);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMPSoCHelper::stopProcess() { terminate = true; }
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::performFlashWrite() {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
result = flashfopen();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
uint8_t tempData[mpsoc::MAX_DATA_SIZE];
|
|
||||||
std::ifstream file(flashWrite.obcFile, std::ifstream::binary);
|
|
||||||
// Set position of next character to end of file input stream
|
|
||||||
file.seekg(0, file.end);
|
|
||||||
// tellg returns position of character in input stream
|
|
||||||
size_t remainingSize = file.tellg();
|
|
||||||
size_t dataLength = 0;
|
|
||||||
size_t bytesRead = 0;
|
|
||||||
while (remainingSize > 0) {
|
|
||||||
if (terminate) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
if (remainingSize > mpsoc::MAX_DATA_SIZE) {
|
|
||||||
dataLength = mpsoc::MAX_DATA_SIZE;
|
|
||||||
} else {
|
|
||||||
dataLength = remainingSize;
|
|
||||||
}
|
|
||||||
if (file.is_open()) {
|
|
||||||
file.seekg(bytesRead, file.beg);
|
|
||||||
file.read(reinterpret_cast<char*>(tempData), dataLength);
|
|
||||||
bytesRead += dataLength;
|
|
||||||
remainingSize -= dataLength;
|
|
||||||
} else {
|
|
||||||
return FILE_CLOSED_ACCIDENTALLY;
|
|
||||||
}
|
|
||||||
(*sequenceCount)++;
|
|
||||||
mpsoc::TcFlashWrite tc(spParams, *sequenceCount);
|
|
||||||
result = tc.buildPacket(tempData, dataLength);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = handlePacketTransmission(tc);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = flashfclose();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::flashfopen() {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
spParams.buf = commandBuffer;
|
|
||||||
(*sequenceCount)++;
|
|
||||||
mpsoc::FlashFopen flashFopen(spParams, *sequenceCount);
|
|
||||||
result = flashFopen.createPacket(flashWrite.mpsocFile, mpsoc::FlashFopen::APPEND);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = handlePacketTransmission(flashFopen);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::flashfclose() {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
spParams.buf = commandBuffer;
|
|
||||||
(*sequenceCount)++;
|
|
||||||
mpsoc::FlashFclose flashFclose(spParams, *sequenceCount);
|
|
||||||
result = flashFclose.createPacket(flashWrite.mpsocFile);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = handlePacketTransmission(flashFclose);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::handlePacketTransmission(ploc::SpTcBase& tc) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
result = sendCommand(tc);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = handleAck();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = handleExe();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::sendCommand(ploc::SpTcBase& tc) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
result = uartComIF->sendMessage(comCookie, tc.getFullPacket(), tc.getFullPacketLen());
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl;
|
|
||||||
triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::handleAck() {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
result = handleTmReception(mpsoc::SIZE_ACK_REPORT);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
SpTmReader tmPacket(tmBuf.data(), tmBuf.size());
|
|
||||||
result = checkReceivedTm(tmPacket);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
uint16_t apid = tmPacket.getApid();
|
|
||||||
if (apid != mpsoc::apid::ACK_SUCCESS) {
|
|
||||||
handleAckApidFailure(apid);
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMPSoCHelper::handleAckApidFailure(uint16_t apid) {
|
|
||||||
if (apid == mpsoc::apid::ACK_FAILURE) {
|
|
||||||
triggerEvent(MPSOC_ACK_FAILURE_REPORT, static_cast<uint32_t>(internalState));
|
|
||||||
sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Received acknowledgement failure "
|
|
||||||
<< "report" << std::endl;
|
|
||||||
} else {
|
|
||||||
triggerEvent(MPSOC_ACK_INVALID_APID, apid, static_cast<uint32_t>(internalState));
|
|
||||||
sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected acknowledgement report "
|
|
||||||
<< "but received space packet with apid " << std::hex << apid << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::handleExe() {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
|
|
||||||
result = handleTmReception(mpsoc::SIZE_EXE_REPORT);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
ploc::SpTmReader tmPacket(tmBuf.data(), tmBuf.size());
|
|
||||||
result = checkReceivedTm(tmPacket);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
uint16_t apid = tmPacket.getApid();
|
|
||||||
if (apid != mpsoc::apid::EXE_SUCCESS) {
|
|
||||||
handleExeApidFailure(apid);
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMPSoCHelper::handleExeApidFailure(uint16_t apid) {
|
|
||||||
if (apid == mpsoc::apid::EXE_FAILURE) {
|
|
||||||
triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState));
|
|
||||||
sif::warning << "PlocMPSoCHelper::handleExeApidFailure: Received execution failure "
|
|
||||||
<< "report" << std::endl;
|
|
||||||
} else {
|
|
||||||
triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState));
|
|
||||||
sif::warning << "PlocMPSoCHelper::handleExeApidFailure: Expected execution report "
|
|
||||||
<< "but received space packet with apid " << std::hex << apid << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::handleTmReception(size_t remainingBytes) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
size_t readBytes = 0;
|
|
||||||
size_t currentBytes = 0;
|
|
||||||
for (int retries = 0; retries < RETRIES; retries++) {
|
|
||||||
result = receive(tmBuf.data() + readBytes, ¤tBytes, remainingBytes);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
readBytes += currentBytes;
|
|
||||||
remainingBytes = remainingBytes - currentBytes;
|
|
||||||
if (remainingBytes == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (remainingBytes != 0) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::handleTmReception: Failed to receive reply" << std::endl;
|
|
||||||
triggerEvent(MPSOC_MISSING_EXE, remainingBytes, static_cast<uint32_t>(internalState));
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::checkReceivedTm(SpTmReader& reader) {
|
|
||||||
ReturnValue_t result = reader.checkSize();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::error << "PlocMPSoCHelper::handleTmReception: Size check on received TM failed"
|
|
||||||
<< std::endl;
|
|
||||||
triggerEvent(MPSOC_TM_SIZE_ERROR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
reader.checkCrc();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::handleTmReception: CRC check failed" << std::endl;
|
|
||||||
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
(*sequenceCount)++;
|
|
||||||
uint16_t recvSeqCnt = reader.getSequenceCount();
|
|
||||||
if (recvSeqCnt != *sequenceCount) {
|
|
||||||
triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt);
|
|
||||||
*sequenceCount = recvSeqCnt;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMPSoCHelper::receive(uint8_t* data, size_t* readBytes, size_t requestBytes) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
uint8_t* buffer = nullptr;
|
|
||||||
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl;
|
|
||||||
triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result,
|
|
||||||
static_cast<uint32_t>(static_cast<uint32_t>(internalState)));
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl;
|
|
||||||
triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(internalState));
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
if (*readBytes > 0) {
|
|
||||||
std::memcpy(data, buffer, *readBytes);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
544
linux/payload/PlocMpsocSpecialComHelper.cpp
Normal file
544
linux/payload/PlocMpsocSpecialComHelper.cpp
Normal file
@ -0,0 +1,544 @@
|
|||||||
|
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <linux/payload/PlocMpsocSpecialComHelper.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#ifdef XIPHOS_Q7S
|
||||||
|
#include "bsp_q7s/fs/FilesystemHelper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mission/utility/Timestamp.h"
|
||||||
|
|
||||||
|
using namespace ploc;
|
||||||
|
|
||||||
|
PlocMpsocSpecialComHelper::PlocMpsocSpecialComHelper(object_id_t objectId)
|
||||||
|
: SystemObject(objectId) {
|
||||||
|
spParams.buf = commandBuffer;
|
||||||
|
spParams.maxSize = sizeof(commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
PlocMpsocSpecialComHelper::~PlocMpsocSpecialComHelper() {}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::initialize() {
|
||||||
|
#ifdef XIPHOS_Q7S
|
||||||
|
sdcMan = SdCardManager::instance();
|
||||||
|
if (sdcMan == nullptr) {
|
||||||
|
sif::warning << "PlocMPSoCHelper::initialize: Invalid SD Card Manager" << std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::performOperation(uint8_t operationCode) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
semaphore.acquire();
|
||||||
|
while (true) {
|
||||||
|
#if OBSW_THREAD_TRACING == 1
|
||||||
|
trace::threadTrace(opCounter, "PLOC MPSOC Helper");
|
||||||
|
#endif
|
||||||
|
switch (internalState) {
|
||||||
|
case InternalState::IDLE: {
|
||||||
|
semaphore.acquire();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case InternalState::FLASH_WRITE: {
|
||||||
|
result = performFlashWrite();
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL, sequenceCount->get());
|
||||||
|
} else {
|
||||||
|
triggerEvent(MPSOC_FLASH_WRITE_FAILED, sequenceCount->get());
|
||||||
|
}
|
||||||
|
internalState = InternalState::IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case InternalState::FLASH_READ: {
|
||||||
|
result = performFlashRead();
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
triggerEvent(MPSOC_FLASH_READ_SUCCESSFUL, sequenceCount->get());
|
||||||
|
} else {
|
||||||
|
triggerEvent(MPSOC_FLASH_READ_FAILED, sequenceCount->get());
|
||||||
|
}
|
||||||
|
internalState = InternalState::IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sif::debug << "PlocMPSoCHelper::performOperation: Invalid state" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::setComIF(DeviceCommunicationIF* communicationInterface_) {
|
||||||
|
uartComIF = dynamic_cast<SerialComIF*>(communicationInterface_);
|
||||||
|
if (uartComIF == nullptr) {
|
||||||
|
sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocMpsocSpecialComHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
|
||||||
|
|
||||||
|
void PlocMpsocSpecialComHelper::setSequenceCount(SourceSequenceCounter* sequenceCount_) {
|
||||||
|
sequenceCount = sequenceCount_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::startFlashWrite(std::string obcFile,
|
||||||
|
std::string mpsocFile) {
|
||||||
|
if (internalState != InternalState::IDLE) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
ReturnValue_t result = startFlashReadOrWriteBase(std::move(obcFile), std::move(mpsocFile));
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
internalState = InternalState::FLASH_WRITE;
|
||||||
|
return semaphore.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::startFlashRead(std::string obcFile, std::string mpsocFile,
|
||||||
|
size_t readFileSize) {
|
||||||
|
if (internalState != InternalState::IDLE) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
ReturnValue_t result = startFlashReadOrWriteBase(std::move(obcFile), std::move(mpsocFile));
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
flashReadAndWrite.totalReadSize = readFileSize;
|
||||||
|
internalState = InternalState::FLASH_READ;
|
||||||
|
return semaphore.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocMpsocSpecialComHelper::resetHelper() {
|
||||||
|
spParams.buf = commandBuffer;
|
||||||
|
terminate = false;
|
||||||
|
uartComIF->flushUartRxBuffer(comCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocMpsocSpecialComHelper::stopProcess() { terminate = true; }
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::performFlashWrite() {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
std::ifstream file(flashReadAndWrite.obcFile, std::ifstream::binary);
|
||||||
|
if (file.bad()) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
result = flashfopen(mpsoc::FileAccessModes::WRITE | mpsoc::FileAccessModes::OPEN_ALWAYS);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Set position of next character to end of file input stream
|
||||||
|
file.seekg(0, file.end);
|
||||||
|
// tellg returns position of character in input stream
|
||||||
|
size_t remainingSize = file.tellg();
|
||||||
|
size_t dataLength = 0;
|
||||||
|
size_t bytesRead = 0;
|
||||||
|
while (remainingSize > 0) {
|
||||||
|
if (terminate) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
// The minus 4 is necessary for unknown reasons. Maybe some bug in the ILH software?
|
||||||
|
if (remainingSize > mpsoc::MAX_FLASH_WRITE_DATA_SIZE - 4) {
|
||||||
|
dataLength = mpsoc::MAX_FLASH_WRITE_DATA_SIZE - 4;
|
||||||
|
} else {
|
||||||
|
dataLength = remainingSize;
|
||||||
|
}
|
||||||
|
if (file.bad() or not file.is_open()) {
|
||||||
|
return FILE_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
file.seekg(bytesRead, file.beg);
|
||||||
|
file.read(reinterpret_cast<char*>(fileBuf.data()), dataLength);
|
||||||
|
bytesRead += dataLength;
|
||||||
|
remainingSize -= dataLength;
|
||||||
|
mpsoc::TcFlashWrite tc(spParams, *sequenceCount);
|
||||||
|
result = tc.setPayload(fileBuf.data(), dataLength);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = tc.finishPacket();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
(*sequenceCount)++;
|
||||||
|
result = handlePacketTransmissionNoReply(tc);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = flashfclose();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::performFlashRead() {
|
||||||
|
std::error_code e;
|
||||||
|
std::ofstream ofile(flashReadAndWrite.obcFile, std::ios::trunc | std::ios::binary);
|
||||||
|
if (ofile.bad()) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
ReturnValue_t result = flashfopen(mpsoc::FileAccessModes::READ);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
std::filesystem::remove(flashReadAndWrite.obcFile, e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
size_t readSoFar = 0;
|
||||||
|
size_t nextReadSize = mpsoc::MAX_FLASH_READ_DATA_SIZE;
|
||||||
|
while (readSoFar < flashReadAndWrite.totalReadSize) {
|
||||||
|
if (terminate) {
|
||||||
|
std::filesystem::remove(flashReadAndWrite.obcFile, e);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
nextReadSize = mpsoc::MAX_FLASH_READ_DATA_SIZE;
|
||||||
|
if (flashReadAndWrite.totalReadSize - readSoFar < mpsoc::MAX_FLASH_READ_DATA_SIZE) {
|
||||||
|
nextReadSize = flashReadAndWrite.totalReadSize - readSoFar;
|
||||||
|
}
|
||||||
|
if (ofile.bad() or not ofile.is_open()) {
|
||||||
|
std::filesystem::remove(flashReadAndWrite.obcFile, e);
|
||||||
|
return FILE_READ_ERROR;
|
||||||
|
}
|
||||||
|
mpsoc::TcFlashRead flashReadRequest(spParams, *sequenceCount);
|
||||||
|
result = flashReadRequest.setPayload(nextReadSize);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
std::filesystem::remove(flashReadAndWrite.obcFile, e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = flashReadRequest.finishPacket();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
std::filesystem::remove(flashReadAndWrite.obcFile, e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
(*sequenceCount)++;
|
||||||
|
result = handlePacketTransmissionFlashRead(flashReadRequest, ofile, nextReadSize);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
std::filesystem::remove(flashReadAndWrite.obcFile, e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
readSoFar += nextReadSize;
|
||||||
|
}
|
||||||
|
result = flashfclose();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::flashfopen(uint8_t mode) {
|
||||||
|
spParams.buf = commandBuffer;
|
||||||
|
mpsoc::FlashFopen flashFopen(spParams, *sequenceCount);
|
||||||
|
ReturnValue_t result = flashFopen.setPayload(flashReadAndWrite.mpsocFile, mode);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = flashFopen.finishPacket();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
(*sequenceCount)++;
|
||||||
|
result = handlePacketTransmissionNoReply(flashFopen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::flashfclose() {
|
||||||
|
spParams.buf = commandBuffer;
|
||||||
|
mpsoc::FlashFclose flashFclose(spParams, *sequenceCount);
|
||||||
|
ReturnValue_t result = flashFclose.finishPacket();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
(*sequenceCount)++;
|
||||||
|
result = handlePacketTransmissionNoReply(flashFclose);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::handlePacketTransmissionFlashRead(mpsoc::TcFlashRead& tc,
|
||||||
|
std::ofstream& ofile,
|
||||||
|
size_t expectedReadLen) {
|
||||||
|
ReturnValue_t result = sendCommand(tc);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = handleAck();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = handleTmReception();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have the nominal case where the flash read report appears first, or the case where we
|
||||||
|
// get an EXE failure immediately.
|
||||||
|
if (spReader.getApid() == mpsoc::apid::TM_FLASH_READ_REPORT) {
|
||||||
|
result = handleFlashReadReply(ofile, expectedReadLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return handleExe();
|
||||||
|
} else if (spReader.getApid() == mpsoc::apid::EXE_FAILURE) {
|
||||||
|
handleExeFailure();
|
||||||
|
} else {
|
||||||
|
triggerEvent(MPSOC_EXE_INVALID_APID, spReader.getApid(), static_cast<uint32_t>(internalState));
|
||||||
|
sif::warning << "PLOC MPSoC: Expected execution report "
|
||||||
|
<< "but received space packet with apid " << std::hex << spReader.getApid()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::handlePacketTransmissionNoReply(ploc::SpTcBase& tc) {
|
||||||
|
ReturnValue_t result = sendCommand(tc);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = handleAck();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return handleExe();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::sendCommand(ploc::SpTcBase& tc) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
result = uartComIF->sendMessage(comCookie, tc.getFullPacket(), tc.getFullPacketLen());
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl;
|
||||||
|
triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::handleAck() {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
result = handleTmReception();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = checkReceivedTm();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
uint16_t apid = spReader.getApid();
|
||||||
|
if (apid != mpsoc::apid::ACK_SUCCESS) {
|
||||||
|
handleAckApidFailure(spReader);
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocMpsocSpecialComHelper::handleAckApidFailure(const ploc::SpTmReader& reader) {
|
||||||
|
uint16_t apid = reader.getApid();
|
||||||
|
if (apid == mpsoc::apid::ACK_FAILURE) {
|
||||||
|
uint16_t status = mpsoc::getStatusFromRawData(reader.getFullData());
|
||||||
|
sif::warning << "PLOC MPSoC ACK Failure: " << mpsoc::getStatusString(status) << std::endl;
|
||||||
|
triggerEvent(MPSOC_ACK_FAILURE_REPORT, static_cast<uint32_t>(internalState), status);
|
||||||
|
} else {
|
||||||
|
triggerEvent(MPSOC_ACK_INVALID_APID, apid, static_cast<uint32_t>(internalState));
|
||||||
|
sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected acknowledgement report "
|
||||||
|
<< "but received space packet with apid " << std::hex << apid << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::handleExe() {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
|
||||||
|
result = handleTmReception();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = checkReceivedTm();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
uint16_t apid = spReader.getApid();
|
||||||
|
if (apid == mpsoc::apid::EXE_FAILURE) {
|
||||||
|
handleExeFailure();
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
} else if (apid != mpsoc::apid::EXE_SUCCESS) {
|
||||||
|
triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState));
|
||||||
|
sif::warning << "PLOC MPSoC: Expected execution report "
|
||||||
|
<< "but received space packet with apid " << std::hex << apid << std::endl;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocMpsocSpecialComHelper::handleExeFailure() {
|
||||||
|
uint16_t status = mpsoc::getStatusFromRawData(spReader.getFullData());
|
||||||
|
sif::warning << "PLOC MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl;
|
||||||
|
triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState));
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::handleTmReception() {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
tmCountdown.resetTimer();
|
||||||
|
size_t readBytes = 0;
|
||||||
|
size_t currentBytes = 0;
|
||||||
|
uint32_t usleepDelay = 5;
|
||||||
|
size_t fullPacketLen = 0;
|
||||||
|
while (true) {
|
||||||
|
if (tmCountdown.hasTimedOut()) {
|
||||||
|
triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs());
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
result = receive(tmBuf.data() + readBytes, 6, ¤tBytes);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
spReader.setReadOnlyData(tmBuf.data(), tmBuf.size());
|
||||||
|
fullPacketLen = spReader.getFullPacketLen();
|
||||||
|
readBytes += currentBytes;
|
||||||
|
if (readBytes == 6) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(usleepDelay);
|
||||||
|
if (usleepDelay < 200000) {
|
||||||
|
usleepDelay *= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
if (tmCountdown.hasTimedOut()) {
|
||||||
|
triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs());
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
result = receive(tmBuf.data() + readBytes, fullPacketLen - readBytes, ¤tBytes);
|
||||||
|
readBytes += currentBytes;
|
||||||
|
if (fullPacketLen == readBytes) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(usleepDelay);
|
||||||
|
if (usleepDelay < 200000) {
|
||||||
|
usleepDelay *= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// arrayprinter::print(tmBuf.data(), readBytes);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::handleFlashReadReply(std::ofstream& ofile,
|
||||||
|
size_t expectedReadLen) {
|
||||||
|
ReturnValue_t result = checkReceivedTm();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
uint16_t apid = spReader.getApid();
|
||||||
|
if (apid != mpsoc::apid::TM_FLASH_READ_REPORT) {
|
||||||
|
triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_APID_ERROR);
|
||||||
|
sif::warning << "PLOC MPSoC Flash Read: Unexpected APID" << std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const uint8_t* packetData = spReader.getPacketData();
|
||||||
|
size_t deserDummy = spReader.getPacketDataLen() - mpsoc::CRC_SIZE;
|
||||||
|
uint32_t receivedReadLen = 0;
|
||||||
|
// I think this is buggy, weird stuff in the short name field.
|
||||||
|
// std::string receivedShortName = std::string(reinterpret_cast<const char*>(packetData), 12);
|
||||||
|
// if (receivedShortName != flashReadAndWrite.mpsocFile.substr(0, 11)) {
|
||||||
|
// sif::warning << "PLOC MPSoC Flash Read: Missmatch between request file name and "
|
||||||
|
// "received file name"
|
||||||
|
// << std::endl;
|
||||||
|
// triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_FILENAME_ERROR);
|
||||||
|
// return returnvalue::FAILED;
|
||||||
|
// }
|
||||||
|
packetData += 12;
|
||||||
|
result = SerializeAdapter::deSerialize(&receivedReadLen, &packetData, &deserDummy,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (receivedReadLen != expectedReadLen) {
|
||||||
|
sif::warning << "PLOC MPSoC Flash Read: Missmatch between request read length and "
|
||||||
|
"received read length"
|
||||||
|
<< std::endl;
|
||||||
|
triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_READLEN_ERROR);
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
ofile.write(reinterpret_cast<const char*>(packetData), receivedReadLen);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::fileCheck(std::string obcFile) {
|
||||||
|
#ifdef XIPHOS_Q7S
|
||||||
|
ReturnValue_t result = FilesystemHelper::checkPath(obcFile);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#elif defined(TE0720_1CFA)
|
||||||
|
if (not std::filesystem::exists(obcFile)) {
|
||||||
|
sif::warning << "PlocMPSoCHelper::startFlashWrite: File " << obcFile << "does not exist"
|
||||||
|
<< std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::startFlashReadOrWriteBase(std::string obcFile,
|
||||||
|
std::string mpsocFile) {
|
||||||
|
ReturnValue_t result = fileCheck(obcFile);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
flashReadAndWrite.obcFile = std::move(obcFile);
|
||||||
|
flashReadAndWrite.mpsocFile = std::move(mpsocFile);
|
||||||
|
resetHelper();
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::checkReceivedTm() {
|
||||||
|
ReturnValue_t result = spReader.checkSize();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::error << "PLOC MPSoC: Size check on received TM failed" << std::endl;
|
||||||
|
triggerEvent(MPSOC_TM_SIZE_ERROR);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
spReader.checkCrc();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::warning << "PLOC MPSoC: CRC check failed" << std::endl;
|
||||||
|
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
uint16_t recvSeqCnt = spReader.getSequenceCount();
|
||||||
|
if (recvSeqCnt != *sequenceCount) {
|
||||||
|
triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt);
|
||||||
|
*sequenceCount = recvSeqCnt;
|
||||||
|
}
|
||||||
|
// This sequence count ping pong does not make any sense but it is how the MPSoC expects it.
|
||||||
|
(*sequenceCount)++;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocMpsocSpecialComHelper::receive(uint8_t* data, size_t requestBytes,
|
||||||
|
size_t* readBytes) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
uint8_t* buffer = nullptr;
|
||||||
|
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl;
|
||||||
|
triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result,
|
||||||
|
static_cast<uint32_t>(static_cast<uint32_t>(internalState)));
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl;
|
||||||
|
triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(internalState));
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
if (*readBytes > 0) {
|
||||||
|
std::memcpy(data, buffer, *readBytes);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
#ifndef BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_
|
#ifndef BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_
|
||||||
#define BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_
|
#define BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_
|
||||||
|
|
||||||
#include <linux/payload/plocMpscoDefs.h>
|
#include <linux/payload/plocMpsocHelpers.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
#include "fsfw/devicehandlers/CookieIF.h"
|
#include "fsfw/devicehandlers/CookieIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/osal/linux/BinarySemaphore.h"
|
#include "fsfw/osal/linux/BinarySemaphore.h"
|
||||||
@ -22,14 +23,14 @@
|
|||||||
* MPSoC and OBC.
|
* MPSoC and OBC.
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PlocMPSoCHelper : public SystemObject, public ExecutableObjectIF {
|
class PlocMpsocSpecialComHelper : public SystemObject, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HELPER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HELPER;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Flash write fails
|
//! [EXPORT] : [COMMENT] Flash write fails
|
||||||
static const Event MPSOC_FLASH_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
|
static const Event MPSOC_FLASH_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] Flash write successful
|
//! [EXPORT] : [COMMENT] Flash write successful
|
||||||
static const Event MPSOC_FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(1, severity::LOW);
|
static const Event MPSOC_FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(1, severity::INFO);
|
||||||
//! [EXPORT] : [COMMENT] Communication interface returned failure when trying to send the command
|
//! [EXPORT] : [COMMENT] Communication interface returned failure when trying to send the command
|
||||||
//! to the MPSoC
|
//! to the MPSoC
|
||||||
//! P1: Return value returned by the communication interface sendMessage function
|
//! P1: Return value returned by the communication interface sendMessage function
|
||||||
@ -71,9 +72,19 @@ class PlocMPSoCHelper : public SystemObject, public ExecutableObjectIF {
|
|||||||
static const Event MPSOC_HELPER_SEQ_CNT_MISMATCH = MAKE_EVENT(11, severity::LOW);
|
static const Event MPSOC_HELPER_SEQ_CNT_MISMATCH = MAKE_EVENT(11, severity::LOW);
|
||||||
static const Event MPSOC_TM_SIZE_ERROR = MAKE_EVENT(12, severity::LOW);
|
static const Event MPSOC_TM_SIZE_ERROR = MAKE_EVENT(12, severity::LOW);
|
||||||
static const Event MPSOC_TM_CRC_MISSMATCH = MAKE_EVENT(13, severity::LOW);
|
static const Event MPSOC_TM_CRC_MISSMATCH = MAKE_EVENT(13, severity::LOW);
|
||||||
|
static const Event MPSOC_FLASH_READ_PACKET_ERROR = MAKE_EVENT(14, severity::LOW);
|
||||||
|
static const Event MPSOC_FLASH_READ_FAILED = MAKE_EVENT(15, severity::LOW);
|
||||||
|
static const Event MPSOC_FLASH_READ_SUCCESSFUL = MAKE_EVENT(16, severity::INFO);
|
||||||
|
static const Event MPSOC_READ_TIMEOUT = MAKE_EVENT(17, severity::LOW);
|
||||||
|
|
||||||
PlocMPSoCHelper(object_id_t objectId);
|
enum FlashReadErrorType : uint32_t {
|
||||||
virtual ~PlocMPSoCHelper();
|
FLASH_READ_APID_ERROR = 0,
|
||||||
|
FLASH_READ_FILENAME_ERROR = 1,
|
||||||
|
FLASH_READ_READLEN_ERROR = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
PlocMpsocSpecialComHelper(object_id_t objectId);
|
||||||
|
virtual ~PlocMpsocSpecialComHelper();
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
@ -90,6 +101,14 @@ class PlocMPSoCHelper : public SystemObject, public ExecutableObjectIF {
|
|||||||
* @return returnvalue::OK if successful, otherwise error return value
|
* @return returnvalue::OK if successful, otherwise error return value
|
||||||
*/
|
*/
|
||||||
ReturnValue_t startFlashWrite(std::string obcFile, std::string mpsocFile);
|
ReturnValue_t startFlashWrite(std::string obcFile, std::string mpsocFile);
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param obcFile Full target file name on OBC
|
||||||
|
* @param mpsocFile The file on the MPSoC which should be copied ot the OBC
|
||||||
|
* @param readFileSize The size of the file on the MPSoC.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t startFlashRead(std::string obcFile, std::string mpsocFile, size_t readFileSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Can be used to interrupt a running data transfer.
|
* @brief Can be used to interrupt a running data transfer.
|
||||||
@ -104,20 +123,25 @@ class PlocMPSoCHelper : public SystemObject, public ExecutableObjectIF {
|
|||||||
private:
|
private:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER;
|
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] File accidentally close
|
//! [EXPORT] : [COMMENT] File error occured for file transfers from OBC to the MPSoC.
|
||||||
static const ReturnValue_t FILE_CLOSED_ACCIDENTALLY = MAKE_RETURN_CODE(0xA0);
|
static const ReturnValue_t FILE_WRITE_ERROR = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] File error occured for file transfers from MPSoC to OBC.
|
||||||
|
static const ReturnValue_t FILE_READ_ERROR = MAKE_RETURN_CODE(0xA1);
|
||||||
|
|
||||||
// Maximum number of times the communication interface retries polling data from the reply
|
// Maximum number of times the communication interface retries polling data from the reply
|
||||||
// buffer
|
// buffer
|
||||||
static const int RETRIES = 10000;
|
static const int RETRIES = 10000;
|
||||||
|
|
||||||
struct FlashWrite {
|
struct FlashInfo {
|
||||||
std::string obcFile;
|
std::string obcFile;
|
||||||
std::string mpsocFile;
|
std::string mpsocFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlashWrite flashWrite;
|
struct FlashRead : public FlashInfo {
|
||||||
|
size_t totalReadSize = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FlashRead flashReadAndWrite;
|
||||||
#if OBSW_THREAD_TRACING == 1
|
#if OBSW_THREAD_TRACING == 1
|
||||||
uint32_t opCounter = 0;
|
uint32_t opCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -134,7 +158,10 @@ class PlocMPSoCHelper : public SystemObject, public ExecutableObjectIF {
|
|||||||
SpacePacketCreator creator;
|
SpacePacketCreator creator;
|
||||||
ploc::SpTcParams spParams = ploc::SpTcParams(creator);
|
ploc::SpTcParams spParams = ploc::SpTcParams(creator);
|
||||||
|
|
||||||
std::array<uint8_t, mpsoc::MAX_REPLY_SIZE> tmBuf;
|
Countdown tmCountdown = Countdown(5000);
|
||||||
|
|
||||||
|
std::array<uint8_t, mpsoc::SP_MAX_DATA_SIZE> fileBuf{};
|
||||||
|
std::array<uint8_t, mpsoc::MAX_REPLY_SIZE> tmBuf{};
|
||||||
|
|
||||||
bool terminate = false;
|
bool terminate = false;
|
||||||
|
|
||||||
@ -147,20 +174,27 @@ class PlocMPSoCHelper : public SystemObject, public ExecutableObjectIF {
|
|||||||
CookieIF* comCookie = nullptr;
|
CookieIF* comCookie = nullptr;
|
||||||
// Sequence count, must be set by Ploc MPSoC Handler
|
// Sequence count, must be set by Ploc MPSoC Handler
|
||||||
SourceSequenceCounter* sequenceCount = nullptr;
|
SourceSequenceCounter* sequenceCount = nullptr;
|
||||||
|
ploc::SpTmReader spReader;
|
||||||
|
|
||||||
ReturnValue_t resetHelper();
|
void resetHelper();
|
||||||
ReturnValue_t performFlashWrite();
|
ReturnValue_t performFlashWrite();
|
||||||
ReturnValue_t flashfopen();
|
ReturnValue_t performFlashRead();
|
||||||
|
ReturnValue_t flashfopen(uint8_t accessMode);
|
||||||
ReturnValue_t flashfclose();
|
ReturnValue_t flashfclose();
|
||||||
ReturnValue_t handlePacketTransmission(ploc::SpTcBase& tc);
|
ReturnValue_t handlePacketTransmissionNoReply(ploc::SpTcBase& tc);
|
||||||
|
ReturnValue_t handlePacketTransmissionFlashRead(mpsoc::TcFlashRead& tc, std::ofstream& ofile,
|
||||||
|
size_t expectedReadLen);
|
||||||
|
ReturnValue_t handleFlashReadReply(std::ofstream& ofile, size_t expectedReadLen);
|
||||||
ReturnValue_t sendCommand(ploc::SpTcBase& tc);
|
ReturnValue_t sendCommand(ploc::SpTcBase& tc);
|
||||||
ReturnValue_t receive(uint8_t* data, size_t* readBytes, size_t requestBytes);
|
ReturnValue_t receive(uint8_t* data, size_t requestBytes, size_t* readBytes);
|
||||||
ReturnValue_t handleAck();
|
ReturnValue_t handleAck();
|
||||||
ReturnValue_t handleExe();
|
ReturnValue_t handleExe();
|
||||||
void handleAckApidFailure(uint16_t apid);
|
ReturnValue_t startFlashReadOrWriteBase(std::string obcFile, std::string mpsocFile);
|
||||||
void handleExeApidFailure(uint16_t apid);
|
ReturnValue_t fileCheck(std::string obcFile);
|
||||||
ReturnValue_t handleTmReception(size_t remainingBytes);
|
void handleAckApidFailure(const ploc::SpTmReader& reader);
|
||||||
ReturnValue_t checkReceivedTm(ploc::SpTmReader& reader);
|
void handleExeFailure();
|
||||||
|
ReturnValue_t handleTmReception();
|
||||||
|
ReturnValue_t checkReceivedTm();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ */
|
#endif /* BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ */
|
@ -151,7 +151,7 @@ void PlocSupervisorHandler::doStartUp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (startupState == StartupState::SET_TIME_EXECUTING) {
|
if (startupState == StartupState::TIME_WAS_SET) {
|
||||||
startupState = StartupState::ON;
|
startupState = StartupState::ON;
|
||||||
}
|
}
|
||||||
if (startupState == StartupState::ON) {
|
if (startupState == StartupState::ON) {
|
||||||
@ -176,7 +176,7 @@ ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t*
|
|||||||
ReturnValue_t PlocSupervisorHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t PlocSupervisorHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||||
if (startupState == StartupState::SET_TIME) {
|
if (startupState == StartupState::SET_TIME) {
|
||||||
*id = supv::SET_TIME_REF;
|
*id = supv::SET_TIME_REF;
|
||||||
startupState = StartupState::SET_TIME_EXECUTING;
|
startupState = StartupState::WAIT_FOR_TIME_REPLY;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
return NOTHING_TO_SEND;
|
return NOTHING_TO_SEND;
|
||||||
@ -1909,6 +1909,10 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionRepor
|
|||||||
case supv::SET_TIME_REF: {
|
case supv::SET_TIME_REF: {
|
||||||
// We could only allow proper bootup when the time was set successfully, but
|
// We could only allow proper bootup when the time was set successfully, but
|
||||||
// this makes debugging difficult.
|
// this makes debugging difficult.
|
||||||
|
|
||||||
|
if (startupState == StartupState::WAIT_FOR_TIME_REPLY) {
|
||||||
|
startupState = StartupState::TIME_WAS_SET;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -99,7 +99,14 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
|||||||
static const uint32_t MRAM_DUMP_TIMEOUT = 60000;
|
static const uint32_t MRAM_DUMP_TIMEOUT = 60000;
|
||||||
// 4 s
|
// 4 s
|
||||||
static const uint32_t BOOT_TIMEOUT = 4000;
|
static const uint32_t BOOT_TIMEOUT = 4000;
|
||||||
enum class StartupState : uint8_t { OFF, BOOTING, SET_TIME, SET_TIME_EXECUTING, ON };
|
enum class StartupState : uint8_t {
|
||||||
|
OFF,
|
||||||
|
BOOTING,
|
||||||
|
SET_TIME,
|
||||||
|
WAIT_FOR_TIME_REPLY,
|
||||||
|
TIME_WAS_SET,
|
||||||
|
ON
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr bool SET_TIME_DURING_BOOT = true;
|
static constexpr bool SET_TIME_DURING_BOOT = true;
|
||||||
|
|
||||||
|
95
linux/payload/plocMpsocHelpers.cpp
Normal file
95
linux/payload/plocMpsocHelpers.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include "plocMpsocHelpers.h"
|
||||||
|
|
||||||
|
uint16_t mpsoc::getStatusFromRawData(const uint8_t* data) {
|
||||||
|
return (*(data + STATUS_OFFSET) << 8) | *(data + STATUS_OFFSET + 1);
|
||||||
|
}
|
||||||
|
std::string mpsoc::getStatusString(uint16_t status) {
|
||||||
|
switch (status) {
|
||||||
|
case (mpsoc::status_code::UNKNOWN_APID): {
|
||||||
|
return "Unknown APID";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::INCORRECT_LENGTH): {
|
||||||
|
return "Incorrect length";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::INCORRECT_CRC): {
|
||||||
|
return "Incorrect crc";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::INCORRECT_PKT_SEQ_CNT): {
|
||||||
|
return "Incorrect packet sequence count";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::TC_NOT_ALLOWED_IN_MODE): {
|
||||||
|
return "TC not allowed in this mode";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::TC_EXEUTION_DISABLED): {
|
||||||
|
return "TC execution disabled";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_MOUNT_FAILED): {
|
||||||
|
return "Flash mount failed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_FILE_ALREADY_OPEN): {
|
||||||
|
return "Flash file already open";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_FILE_ALREADY_CLOSED): {
|
||||||
|
return "Flash file already closed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_FILE_OPEN_FAILED): {
|
||||||
|
return "Flash file open failed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_FILE_NOT_OPEN): {
|
||||||
|
return "Flash file not open";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_UNMOUNT_FAILED): {
|
||||||
|
return "Flash unmount failed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::HEAP_ALLOCATION_FAILED): {
|
||||||
|
return "Heap allocation failed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::INVALID_PARAMETER): {
|
||||||
|
return "Invalid parameter";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::NOT_INITIALIZED): {
|
||||||
|
return "Not initialized";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::REBOOT_IMMINENT): {
|
||||||
|
return "Reboot imminent";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::CORRUPT_DATA): {
|
||||||
|
return "Corrupt data";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_CORRECTABLE_MISMATCH): {
|
||||||
|
return "Flash correctable mismatch";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::FLASH_UNCORRECTABLE_MISMATCH): {
|
||||||
|
return "Flash uncorrectable mismatch";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (mpsoc::status_code::DEFAULT_ERROR_CODE): {
|
||||||
|
return "Default error code";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "0x" << std::hex << status;
|
||||||
|
return ss.str().c_str();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
|
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
|
||||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
|
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
|
||||||
|
|
||||||
|
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||||
#include <linux/payload/mpsocRetvals.h>
|
#include <linux/payload/mpsocRetvals.h>
|
||||||
#include <mission/payload/plocSpBase.h>
|
#include <mission/payload/plocSpBase.h>
|
||||||
@ -12,6 +13,61 @@
|
|||||||
|
|
||||||
namespace mpsoc {
|
namespace mpsoc {
|
||||||
|
|
||||||
|
enum FileAccessModes : uint8_t {
|
||||||
|
// Opens a file, fails if the file does not exist.
|
||||||
|
OPEN_EXISTING = 0x00,
|
||||||
|
READ = 0x01,
|
||||||
|
WRITE = 0x02,
|
||||||
|
// Creates a new file, fails if it already exists.
|
||||||
|
CREATE_NEW = 0x04,
|
||||||
|
// Creates a new file, existing file is truncated and overwritten.
|
||||||
|
CREATE_ALWAYS = 0x08,
|
||||||
|
// Opens the file if it is existing. If not, a new file is created.
|
||||||
|
OPEN_ALWAYS = 0x10,
|
||||||
|
OPEN_APPEND = 0x30
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr uint32_t HK_SET_ID = 0;
|
||||||
|
|
||||||
|
namespace poolid {
|
||||||
|
enum {
|
||||||
|
STATUS = 0,
|
||||||
|
MODE = 1,
|
||||||
|
DOWNLINK_PWR_ON = 2,
|
||||||
|
DOWNLINK_REPLY_ACTIIVE = 3,
|
||||||
|
DOWNLINK_JESD_SYNC_STATUS = 4,
|
||||||
|
DOWNLINK_DAC_STATUS = 5,
|
||||||
|
CAM_STATUS = 6,
|
||||||
|
CAM_SDI_STATUS = 7,
|
||||||
|
CAM_FPGA_TEMP = 8,
|
||||||
|
CAM_SOC_TEMP = 9,
|
||||||
|
SYSMON_TEMP = 10,
|
||||||
|
SYSMON_VCCINT = 11,
|
||||||
|
SYSMON_VCCAUX = 12,
|
||||||
|
SYSMON_VCCBRAM = 13,
|
||||||
|
SYSMON_VCCPAUX = 14,
|
||||||
|
SYSMON_VCCPINT = 15,
|
||||||
|
SYSMON_VCCPDRO = 16,
|
||||||
|
SYSMON_MB12V = 17,
|
||||||
|
SYSMON_MB3V3 = 18,
|
||||||
|
SYSMON_MB1V8 = 19,
|
||||||
|
SYSMON_VCC12V = 20,
|
||||||
|
SYSMON_VCC5V = 21,
|
||||||
|
SYSMON_VCC3V3 = 22,
|
||||||
|
SYSMON_VCC3V3VA = 23,
|
||||||
|
SYSMON_VCC2V5DDR = 24,
|
||||||
|
SYSMON_VCC1V2DDR = 25,
|
||||||
|
SYSMON_VCC0V9 = 26,
|
||||||
|
SYSMON_VCC0V6VTT = 27,
|
||||||
|
SYSMON_SAFE_COTS_CUR = 28,
|
||||||
|
SYSMON_NVM4_XO_CUR = 29,
|
||||||
|
SEM_UNCORRECTABLE_ERRS = 30,
|
||||||
|
SEM_CORRECTABLE_ERRS = 31,
|
||||||
|
SEM_STATUS = 32,
|
||||||
|
REBOOT_MPSOC_REQUIRED = 33,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static const DeviceCommandId_t NONE = 0;
|
static const DeviceCommandId_t NONE = 0;
|
||||||
static const DeviceCommandId_t TC_MEM_WRITE = 1;
|
static const DeviceCommandId_t TC_MEM_WRITE = 1;
|
||||||
static const DeviceCommandId_t TC_MEM_READ = 2;
|
static const DeviceCommandId_t TC_MEM_READ = 2;
|
||||||
@ -20,7 +76,7 @@ static const DeviceCommandId_t EXE_REPORT = 5;
|
|||||||
static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 6;
|
static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 6;
|
||||||
static const DeviceCommandId_t TC_FLASHFOPEN = 7;
|
static const DeviceCommandId_t TC_FLASHFOPEN = 7;
|
||||||
static const DeviceCommandId_t TC_FLASHFCLOSE = 8;
|
static const DeviceCommandId_t TC_FLASHFCLOSE = 8;
|
||||||
static const DeviceCommandId_t TC_FLASHWRITE = 9;
|
static const DeviceCommandId_t TC_FLASH_WRITE_FULL_FILE = 9;
|
||||||
static const DeviceCommandId_t TC_FLASHDELETE = 10;
|
static const DeviceCommandId_t TC_FLASHDELETE = 10;
|
||||||
static const DeviceCommandId_t TC_REPLAY_START = 11;
|
static const DeviceCommandId_t TC_REPLAY_START = 11;
|
||||||
static const DeviceCommandId_t TC_REPLAY_STOP = 12;
|
static const DeviceCommandId_t TC_REPLAY_STOP = 12;
|
||||||
@ -37,6 +93,11 @@ static const DeviceCommandId_t TC_CAM_TAKE_PIC = 22;
|
|||||||
static const DeviceCommandId_t TC_SIMPLEX_SEND_FILE = 23;
|
static const DeviceCommandId_t TC_SIMPLEX_SEND_FILE = 23;
|
||||||
static const DeviceCommandId_t TC_DOWNLINK_DATA_MODULATE = 24;
|
static const DeviceCommandId_t TC_DOWNLINK_DATA_MODULATE = 24;
|
||||||
static const DeviceCommandId_t TC_MODE_SNAPSHOT = 25;
|
static const DeviceCommandId_t TC_MODE_SNAPSHOT = 25;
|
||||||
|
static const DeviceCommandId_t TC_GET_HK_REPORT = 26;
|
||||||
|
static const DeviceCommandId_t TM_GET_HK_REPORT = 27;
|
||||||
|
static const DeviceCommandId_t TC_FLASH_GET_DIRECTORY_CONTENT = 28;
|
||||||
|
static const DeviceCommandId_t TM_FLASH_DIRECTORY_CONTENT = 29;
|
||||||
|
static constexpr DeviceCommandId_t TC_FLASH_READ_FULL_FILE = 30;
|
||||||
|
|
||||||
// Will reset the sequence count of the OBSW
|
// Will reset the sequence count of the OBSW
|
||||||
static const DeviceCommandId_t OBSW_RESET_SEQ_COUNT = 50;
|
static const DeviceCommandId_t OBSW_RESET_SEQ_COUNT = 50;
|
||||||
@ -45,6 +106,7 @@ static const uint16_t SIZE_ACK_REPORT = 14;
|
|||||||
static const uint16_t SIZE_EXE_REPORT = 14;
|
static const uint16_t SIZE_EXE_REPORT = 14;
|
||||||
static const uint16_t SIZE_TM_MEM_READ_REPORT = 18;
|
static const uint16_t SIZE_TM_MEM_READ_REPORT = 18;
|
||||||
static const uint16_t SIZE_TM_CAM_CMD_RPT = 18;
|
static const uint16_t SIZE_TM_CAM_CMD_RPT = 18;
|
||||||
|
static constexpr size_t SIZE_TM_HK_REPORT = 369;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpacePacket apids of PLOC telecommands and telemetry.
|
* SpacePacket apids of PLOC telecommands and telemetry.
|
||||||
@ -57,23 +119,32 @@ static const uint16_t TC_DOWNLINK_PWR_ON = 0x113;
|
|||||||
static const uint16_t TC_MEM_WRITE = 0x114;
|
static const uint16_t TC_MEM_WRITE = 0x114;
|
||||||
static const uint16_t TC_MEM_READ = 0x115;
|
static const uint16_t TC_MEM_READ = 0x115;
|
||||||
static const uint16_t TC_CAM_TAKE_PIC = 0x116;
|
static const uint16_t TC_CAM_TAKE_PIC = 0x116;
|
||||||
static const uint16_t TC_FLASHWRITE = 0x117;
|
static constexpr uint16_t TC_FLASHWRITE = 0x117;
|
||||||
|
static constexpr uint16_t TC_FLASHREAD = 0x118;
|
||||||
static const uint16_t TC_FLASHFOPEN = 0x119;
|
static const uint16_t TC_FLASHFOPEN = 0x119;
|
||||||
static const uint16_t TC_FLASHFCLOSE = 0x11A;
|
static const uint16_t TC_FLASHFCLOSE = 0x11A;
|
||||||
|
static constexpr uint16_t TC_FLASH_GET_DIRECTORY_CONTENT = 0x11B;
|
||||||
static const uint16_t TC_FLASHDELETE = 0x11C;
|
static const uint16_t TC_FLASHDELETE = 0x11C;
|
||||||
|
static constexpr uint16_t TC_FLASH_CREATE_DIR = 0x11D;
|
||||||
static const uint16_t TC_MODE_IDLE = 0x11E;
|
static const uint16_t TC_MODE_IDLE = 0x11E;
|
||||||
static const uint16_t TC_MODE_REPLAY = 0x11F;
|
static const uint16_t TC_MODE_REPLAY = 0x11F;
|
||||||
static const uint16_t TC_MODE_SNAPSHOT = 0x120;
|
static const uint16_t TC_MODE_SNAPSHOT = 0x120;
|
||||||
static const uint16_t TC_DOWNLINK_DATA_MODULATE = 0x121;
|
static const uint16_t TC_DOWNLINK_DATA_MODULATE = 0x121;
|
||||||
|
static constexpr uint16_t TC_HK_GET_REPORT = 0x123;
|
||||||
static const uint16_t TC_DOWNLINK_PWR_OFF = 0x124;
|
static const uint16_t TC_DOWNLINK_PWR_OFF = 0x124;
|
||||||
static const uint16_t TC_CAM_CMD_SEND = 0x12C;
|
static const uint16_t TC_CAM_CMD_SEND = 0x12C;
|
||||||
|
static constexpr uint16_t TC_FLASH_COPY_FILE = 0x12E;
|
||||||
static const uint16_t TC_SIMPLEX_SEND_FILE = 0x130;
|
static const uint16_t TC_SIMPLEX_SEND_FILE = 0x130;
|
||||||
static const uint16_t TM_MEMORY_READ_REPORT = 0x404;
|
|
||||||
static const uint16_t ACK_SUCCESS = 0x400;
|
static const uint16_t ACK_SUCCESS = 0x400;
|
||||||
static const uint16_t ACK_FAILURE = 0x401;
|
static const uint16_t ACK_FAILURE = 0x401;
|
||||||
static const uint16_t EXE_SUCCESS = 0x402;
|
static const uint16_t EXE_SUCCESS = 0x402;
|
||||||
static const uint16_t EXE_FAILURE = 0x403;
|
static const uint16_t EXE_FAILURE = 0x403;
|
||||||
|
static const uint16_t TM_MEMORY_READ_REPORT = 0x404;
|
||||||
|
static const uint16_t TM_FLASH_READ_REPORT = 0x405;
|
||||||
|
static constexpr uint16_t TM_FLASH_DIRECTORY_CONTENT = 0x406;
|
||||||
static const uint16_t TM_CAM_CMD_RPT = 0x407;
|
static const uint16_t TM_CAM_CMD_RPT = 0x407;
|
||||||
|
static constexpr uint16_t TM_HK_GET_REPORT = 0x408;
|
||||||
} // namespace apid
|
} // namespace apid
|
||||||
|
|
||||||
/** Offset from first byte in space packet to first byte of data field */
|
/** Offset from first byte in space packet to first byte of data field */
|
||||||
@ -83,6 +154,8 @@ static const char NULL_TERMINATOR = '\0';
|
|||||||
static const uint8_t MIN_SPACE_PACKET_LENGTH = 7;
|
static const uint8_t MIN_SPACE_PACKET_LENGTH = 7;
|
||||||
static const uint8_t SPACE_PACKET_HEADER_SIZE = 6;
|
static const uint8_t SPACE_PACKET_HEADER_SIZE = 6;
|
||||||
|
|
||||||
|
static const uint8_t STATUS_OFFSET = 10;
|
||||||
|
|
||||||
static constexpr size_t CRC_SIZE = 2;
|
static constexpr size_t CRC_SIZE = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,9 +179,15 @@ static const uint16_t LENGTH_TC_MEM_READ = 8;
|
|||||||
* at sheet README
|
* at sheet README
|
||||||
*/
|
*/
|
||||||
static constexpr size_t SP_MAX_SIZE = 1024;
|
static constexpr size_t SP_MAX_SIZE = 1024;
|
||||||
static const size_t MAX_REPLY_SIZE = SP_MAX_SIZE * 3;
|
static constexpr size_t MAX_REPLY_SIZE = SP_MAX_SIZE * 3;
|
||||||
static const size_t MAX_COMMAND_SIZE = SP_MAX_SIZE;
|
static constexpr size_t MAX_COMMAND_SIZE = SP_MAX_SIZE;
|
||||||
static const size_t MAX_DATA_SIZE = 1016;
|
// 1016 bytes.
|
||||||
|
static constexpr size_t SP_MAX_DATA_SIZE = SP_MAX_SIZE - ccsds::HEADER_LEN - CRC_SIZE;
|
||||||
|
static constexpr size_t FLASH_READ_MIN_OVERHEAD = 16;
|
||||||
|
// 1000 bytes.
|
||||||
|
static const size_t MAX_FLASH_READ_DATA_SIZE = SP_MAX_DATA_SIZE - FLASH_READ_MIN_OVERHEAD;
|
||||||
|
// 1012 bytes, 4 bytes for the write length.
|
||||||
|
static constexpr size_t MAX_FLASH_WRITE_DATA_SIZE = SP_MAX_DATA_SIZE - sizeof(uint32_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The replay write sequence command has a maximum delay for the execution report which amounts to
|
* The replay write sequence command has a maximum delay for the execution report which amounts to
|
||||||
@ -131,7 +210,7 @@ static const uint16_t TC_EXEUTION_DISABLED = 0x5E2;
|
|||||||
static const uint16_t FLASH_MOUNT_FAILED = 0x5E3;
|
static const uint16_t FLASH_MOUNT_FAILED = 0x5E3;
|
||||||
static const uint16_t FLASH_FILE_ALREADY_CLOSED = 0x5E4;
|
static const uint16_t FLASH_FILE_ALREADY_CLOSED = 0x5E4;
|
||||||
static const uint16_t FLASH_FILE_OPEN_FAILED = 0x5E5;
|
static const uint16_t FLASH_FILE_OPEN_FAILED = 0x5E5;
|
||||||
static const uint16_t FLASH_FILE_ALREDY_OPEN = 0x5E6;
|
static const uint16_t FLASH_FILE_ALREADY_OPEN = 0x5E6;
|
||||||
static const uint16_t FLASH_FILE_NOT_OPEN = 0x5E7;
|
static const uint16_t FLASH_FILE_NOT_OPEN = 0x5E7;
|
||||||
static const uint16_t FLASH_UNMOUNT_FAILED = 0x5E8;
|
static const uint16_t FLASH_UNMOUNT_FAILED = 0x5E8;
|
||||||
static const uint16_t HEAP_ALLOCATION_FAILED = 0x5E9;
|
static const uint16_t HEAP_ALLOCATION_FAILED = 0x5E9;
|
||||||
@ -156,7 +235,7 @@ class TcBase : public ploc::SpTcBase, public MPSoCReturnValuesIF {
|
|||||||
virtual ~TcBase() = default;
|
virtual ~TcBase() = default;
|
||||||
|
|
||||||
// Initial length field of space packet. Will always be updated when packet is created.
|
// Initial length field of space packet. Will always be updated when packet is created.
|
||||||
static const uint16_t INIT_LENGTH = 2;
|
static const uint16_t INIT_LENGTH = CRC_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
@ -166,47 +245,23 @@ class TcBase : public ploc::SpTcBase, public MPSoCReturnValuesIF {
|
|||||||
*/
|
*/
|
||||||
TcBase(ploc::SpTcParams params, uint16_t apid, uint16_t sequenceCount)
|
TcBase(ploc::SpTcParams params, uint16_t apid, uint16_t sequenceCount)
|
||||||
: ploc::SpTcBase(params, apid, 0, sequenceCount) {
|
: ploc::SpTcBase(params, apid, 0, sequenceCount) {
|
||||||
|
payloadStart = spParams.buf + ccsds::HEADER_LEN;
|
||||||
spParams.setFullPayloadLen(INIT_LENGTH);
|
spParams.setFullPayloadLen(INIT_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t buildPacket() { return buildPacket(nullptr, 0); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function to initialize the space packet
|
* @brief Function to finsh and write the space packet. It is expected that the user has
|
||||||
*
|
* set the payload fields in the child class*
|
||||||
* @param commandData Pointer to command specific data
|
|
||||||
* @param commandDataLen Length of command data
|
|
||||||
*
|
|
||||||
* @return returnvalue::OK if packet creation was successful, otherwise error return value
|
* @return returnvalue::OK if packet creation was successful, otherwise error return value
|
||||||
*/
|
*/
|
||||||
ReturnValue_t buildPacket(const uint8_t* commandData, size_t commandDataLen) {
|
ReturnValue_t finishPacket() {
|
||||||
payloadStart = spParams.buf + ccsds::HEADER_LEN;
|
|
||||||
ReturnValue_t res;
|
|
||||||
if (commandData != nullptr and commandDataLen > 0) {
|
|
||||||
res = initPacket(commandData, commandDataLen);
|
|
||||||
if (res != returnvalue::OK) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSpFields();
|
updateSpFields();
|
||||||
res = checkSizeAndSerializeHeader();
|
ReturnValue_t res = checkSizeAndSerializeHeader();
|
||||||
if (res != returnvalue::OK) {
|
if (res != returnvalue::OK) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
return calcAndSetCrc();
|
return calcAndSetCrc();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* @brief Must be overwritten by the child class to define the command specific parameters
|
|
||||||
*
|
|
||||||
* @param commandData Pointer to received command data
|
|
||||||
* @param commandDataLen Length of received command data
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,8 +279,7 @@ class TcMemRead : public TcBase {
|
|||||||
|
|
||||||
uint16_t getMemLen() const { return memLen; }
|
uint16_t getMemLen() const { return memLen; }
|
||||||
|
|
||||||
protected:
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
result = lengthCheck(commandDataLen);
|
result = lengthCheck(commandDataLen);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -271,8 +325,7 @@ class TcMemWrite : public TcBase {
|
|||||||
TcMemWrite(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcMemWrite(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_MEM_WRITE, sequenceCount) {}
|
: TcBase(params, apid::TC_MEM_WRITE, sequenceCount) {}
|
||||||
|
|
||||||
protected:
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
result = lengthCheck(commandDataLen);
|
result = lengthCheck(commandDataLen);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -314,72 +367,58 @@ class TcMemWrite : public TcBase {
|
|||||||
/**
|
/**
|
||||||
* @brief Class to help creation of flash fopen command.
|
* @brief Class to help creation of flash fopen command.
|
||||||
*/
|
*/
|
||||||
class FlashFopen : public ploc::SpTcBase {
|
class FlashFopen : public TcBase {
|
||||||
public:
|
public:
|
||||||
FlashFopen(ploc::SpTcParams params, uint16_t sequenceCount)
|
FlashFopen(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: ploc::SpTcBase(params, apid::TC_FLASHFOPEN, sequenceCount) {}
|
: TcBase(params, apid::TC_FLASHFOPEN, sequenceCount) {}
|
||||||
|
|
||||||
static const char APPEND = 'a';
|
ReturnValue_t setPayload(std::string filename, uint8_t mode) {
|
||||||
static const char WRITE = 'w';
|
accessMode = mode;
|
||||||
static const char READ = 'r';
|
|
||||||
|
|
||||||
ReturnValue_t createPacket(std::string filename, char accessMode_) {
|
|
||||||
accessMode = accessMode_;
|
|
||||||
size_t nameSize = filename.size();
|
size_t nameSize = filename.size();
|
||||||
spParams.setFullPayloadLen(nameSize + sizeof(NULL_TERMINATOR) + sizeof(accessMode) + CRC_SIZE);
|
spParams.setFullPayloadLen(256 + sizeof(uint8_t) + CRC_SIZE);
|
||||||
ReturnValue_t result = checkPayloadLen();
|
ReturnValue_t result = checkPayloadLen();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::memcpy(payloadStart, filename.c_str(), nameSize);
|
std::memcpy(payloadStart, filename.c_str(), nameSize);
|
||||||
*(spParams.buf + nameSize) = NULL_TERMINATOR;
|
// payloadStart[nameSize] = NULL_TERMINATOR;
|
||||||
std::memcpy(payloadStart + nameSize + sizeof(NULL_TERMINATOR), &accessMode, sizeof(accessMode));
|
std::memset(payloadStart + nameSize, 0, 256 - nameSize);
|
||||||
updateSpFields();
|
// payloadStart[255] = NULL_TERMINATOR;
|
||||||
return calcAndSetCrc();
|
payloadStart[256] = accessMode;
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char accessMode = APPEND;
|
uint8_t accessMode = FileAccessModes::OPEN_EXISTING;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to help creation of flash fclose command.
|
* @brief Class to help creation of flash fclose command.
|
||||||
*/
|
*/
|
||||||
class FlashFclose : public ploc::SpTcBase {
|
class FlashFclose : public TcBase {
|
||||||
public:
|
public:
|
||||||
FlashFclose(ploc::SpTcParams params, uint16_t sequenceCount)
|
FlashFclose(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: ploc::SpTcBase(params, apid::TC_FLASHFCLOSE, sequenceCount) {}
|
: TcBase(params, apid::TC_FLASHFCLOSE, sequenceCount) {
|
||||||
|
spParams.setFullPayloadLen(CRC_SIZE);
|
||||||
ReturnValue_t createPacket(std::string filename) {
|
|
||||||
size_t nameSize = filename.size();
|
|
||||||
spParams.setFullPayloadLen(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE);
|
|
||||||
ReturnValue_t result = checkPayloadLen();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::memcpy(payloadStart, filename.c_str(), nameSize);
|
|
||||||
*(payloadStart + nameSize) = NULL_TERMINATOR;
|
|
||||||
return calcAndSetCrc();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to build flash write space packet.
|
* @brief Class to build flash write space packet.
|
||||||
*/
|
*/
|
||||||
class TcFlashWrite : public ploc::SpTcBase {
|
class TcFlashWrite : public TcBase {
|
||||||
public:
|
public:
|
||||||
TcFlashWrite(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcFlashWrite(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: ploc::SpTcBase(params, apid::TC_FLASHWRITE, sequenceCount) {}
|
: TcBase(params, apid::TC_FLASHWRITE, sequenceCount) {}
|
||||||
|
|
||||||
ReturnValue_t buildPacket(const uint8_t* writeData, uint32_t writeLen_) {
|
ReturnValue_t setPayload(const uint8_t* writeData, uint32_t writeLen_) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
writeLen = writeLen_;
|
writeLen = writeLen_;
|
||||||
if (writeLen > MAX_DATA_SIZE) {
|
if (writeLen > MAX_FLASH_WRITE_DATA_SIZE) {
|
||||||
sif::debug << "FlashWrite::createPacket: Command data too big" << std::endl;
|
sif::error << "TcFlashWrite: Command data too big" << std::endl;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
spParams.setFullPayloadLen(static_cast<uint16_t>(writeLen) + 4 + CRC_SIZE);
|
spParams.setFullPayloadLen(sizeof(uint32_t) + static_cast<uint16_t>(writeLen) + CRC_SIZE);
|
||||||
result = checkPayloadLen();
|
ReturnValue_t result = checkPayloadLen();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -389,11 +428,11 @@ class TcFlashWrite : public ploc::SpTcBase {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::memcpy(payloadStart + sizeof(writeLen), writeData, writeLen);
|
std::memcpy(payloadStart + sizeof(uint32_t), writeData, writeLen);
|
||||||
updateSpFields();
|
updateSpFields();
|
||||||
auto res = checkSizeAndSerializeHeader();
|
result = checkSizeAndSerializeHeader();
|
||||||
if (res != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return res;
|
return result;
|
||||||
}
|
}
|
||||||
return calcAndSetCrc();
|
return calcAndSetCrc();
|
||||||
}
|
}
|
||||||
@ -402,15 +441,52 @@ class TcFlashWrite : public ploc::SpTcBase {
|
|||||||
uint32_t writeLen = 0;
|
uint32_t writeLen = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TcFlashRead : public TcBase {
|
||||||
|
public:
|
||||||
|
TcFlashRead(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
|
: TcBase(params, apid::TC_FLASHREAD, sequenceCount) {}
|
||||||
|
|
||||||
|
ReturnValue_t setPayload(uint32_t readLen) {
|
||||||
|
if (readLen > MAX_FLASH_READ_DATA_SIZE) {
|
||||||
|
sif::error << "TcFlashRead: Read length " << readLen << " too large" << std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
spParams.setFullPayloadLen(sizeof(uint32_t) + CRC_SIZE);
|
||||||
|
ReturnValue_t result = checkPayloadLen();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
size_t serializedSize = ccsds::HEADER_LEN;
|
||||||
|
result = SerializeAdapter::serialize(&readLen, payloadStart, &serializedSize, spParams.maxSize,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
updateSpFields();
|
||||||
|
result = checkSizeAndSerializeHeader();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = calcAndSetCrc();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
readSize = readLen;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t readSize = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to help creation of flash delete command.
|
* @brief Class to help creation of flash delete command.
|
||||||
*/
|
*/
|
||||||
class TcFlashDelete : public ploc::SpTcBase {
|
class TcFlashDelete : public TcBase {
|
||||||
public:
|
public:
|
||||||
TcFlashDelete(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcFlashDelete(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: ploc::SpTcBase(params, apid::TC_FLASHDELETE, sequenceCount) {}
|
: TcBase(params, apid::TC_FLASHDELETE, sequenceCount) {}
|
||||||
|
|
||||||
ReturnValue_t buildPacket(std::string filename) {
|
ReturnValue_t setPayload(std::string filename) {
|
||||||
size_t nameSize = filename.size();
|
size_t nameSize = filename.size();
|
||||||
spParams.setFullPayloadLen(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE);
|
spParams.setFullPayloadLen(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE);
|
||||||
auto res = checkPayloadLen();
|
auto res = checkPayloadLen();
|
||||||
@ -449,8 +525,7 @@ class TcReplayStart : public TcBase {
|
|||||||
TcReplayStart(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcReplayStart(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_REPLAY_START, sequenceCount) {}
|
: TcBase(params, apid::TC_REPLAY_START, sequenceCount) {}
|
||||||
|
|
||||||
protected:
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
spParams.setFullPayloadLen(commandDataLen + CRC_SIZE);
|
spParams.setFullPayloadLen(commandDataLen + CRC_SIZE);
|
||||||
result = lengthCheck(commandDataLen);
|
result = lengthCheck(commandDataLen);
|
||||||
@ -498,8 +573,7 @@ class TcDownlinkPwrOn : public TcBase {
|
|||||||
TcDownlinkPwrOn(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcDownlinkPwrOn(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_DOWNLINK_PWR_ON, sequenceCount) {}
|
: TcBase(params, apid::TC_DOWNLINK_PWR_ON, sequenceCount) {}
|
||||||
|
|
||||||
protected:
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
result = lengthCheck(commandDataLen);
|
result = lengthCheck(commandDataLen);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -561,6 +635,30 @@ class TcDownlinkPwrOn : public TcBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TcGetHkReport : public TcBase {
|
||||||
|
public:
|
||||||
|
TcGetHkReport(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
|
: TcBase(params, apid::TC_HK_GET_REPORT, sequenceCount) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TcGetDirContent : public TcBase {
|
||||||
|
public:
|
||||||
|
TcGetDirContent(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
|
: TcBase(params, apid::TC_FLASH_GET_DIRECTORY_CONTENT, sequenceCount) {}
|
||||||
|
|
||||||
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
// Yeah it needs to be 256.. even if the path is shorter.
|
||||||
|
spParams.setFullPayloadLen(256 + CRC_SIZE);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::memcpy(payloadStart, commandData, commandDataLen);
|
||||||
|
payloadStart[255] = '\0';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to build replay stop space packet.
|
* @brief Class to build replay stop space packet.
|
||||||
*/
|
*/
|
||||||
@ -581,8 +679,7 @@ class TcReplayWriteSeq : public TcBase {
|
|||||||
TcReplayWriteSeq(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcReplayWriteSeq(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_REPLAY_WRITE_SEQUENCE, sequenceCount) {}
|
: TcBase(params, apid::TC_REPLAY_WRITE_SEQUENCE, sequenceCount) {}
|
||||||
|
|
||||||
protected:
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
spParams.setFullPayloadLen(commandDataLen + sizeof(NULL_TERMINATOR) + CRC_SIZE);
|
spParams.setFullPayloadLen(commandDataLen + sizeof(NULL_TERMINATOR) + CRC_SIZE);
|
||||||
result = lengthCheck(commandDataLen);
|
result = lengthCheck(commandDataLen);
|
||||||
@ -611,36 +708,69 @@ class TcReplayWriteSeq : public TcBase {
|
|||||||
/**
|
/**
|
||||||
* @brief Helps to extract the fields of the flash write command from the PUS packet.
|
* @brief Helps to extract the fields of the flash write command from the PUS packet.
|
||||||
*/
|
*/
|
||||||
class FlashWritePusCmd : public MPSoCReturnValuesIF {
|
class FlashBasePusCmd : public MPSoCReturnValuesIF {
|
||||||
public:
|
public:
|
||||||
FlashWritePusCmd(){};
|
FlashBasePusCmd() = default;
|
||||||
|
virtual ~FlashBasePusCmd() = default;
|
||||||
|
|
||||||
ReturnValue_t extractFields(const uint8_t* commandData, size_t commandDataLen) {
|
virtual ReturnValue_t extractFields(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
if (commandDataLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE + MAX_FILENAME_SIZE)) {
|
if (commandDataLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE + MAX_FILENAME_SIZE)) {
|
||||||
return INVALID_LENGTH;
|
return INVALID_LENGTH;
|
||||||
}
|
}
|
||||||
obcFile = std::string(reinterpret_cast<const char*>(commandData));
|
size_t fileLen = strnlen(reinterpret_cast<const char*>(commandData), commandDataLen);
|
||||||
if (obcFile.size() > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE)) {
|
if (fileLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE)) {
|
||||||
return FILENAME_TOO_LONG;
|
return FILENAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
mpsocFile = std::string(
|
obcFile = std::string(reinterpret_cast<const char*>(commandData), fileLen);
|
||||||
reinterpret_cast<const char*>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR));
|
fileLen =
|
||||||
if (mpsocFile.size() > MAX_FILENAME_SIZE) {
|
strnlen(reinterpret_cast<const char*>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR),
|
||||||
|
commandDataLen - obcFile.size() - 1);
|
||||||
|
if (fileLen > MAX_FILENAME_SIZE) {
|
||||||
return MPSOC_FILENAME_TOO_LONG;
|
return MPSOC_FILENAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
|
mpsocFile = std::string(
|
||||||
|
reinterpret_cast<const char*>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR),
|
||||||
|
fileLen);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getObcFile() { return obcFile; }
|
const std::string& getObcFile() const { return obcFile; }
|
||||||
|
|
||||||
std::string getMPSoCFile() { return mpsocFile; }
|
const std::string& getMPSoCFile() const { return mpsocFile; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t getParsedSize() const {
|
||||||
|
return getObcFile().size() + getMPSoCFile().size() + 2 * SIZE_NULL_TERMINATOR;
|
||||||
|
}
|
||||||
|
static const size_t SIZE_NULL_TERMINATOR = 1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const size_t SIZE_NULL_TERMINATOR = 1;
|
std::string obcFile;
|
||||||
std::string obcFile = "";
|
std::string mpsocFile;
|
||||||
std::string mpsocFile = "";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FlashReadPusCmd : public FlashBasePusCmd {
|
||||||
|
public:
|
||||||
|
FlashReadPusCmd(){};
|
||||||
|
|
||||||
|
ReturnValue_t extractFields(const uint8_t* commandData, size_t commandDataLen) override {
|
||||||
|
ReturnValue_t result = FlashBasePusCmd::extractFields(commandData, commandDataLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (commandDataLen < (getParsedSize() + 4)) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
size_t deserDummy = 4;
|
||||||
|
return SerializeAdapter::deSerialize(&readSize, commandData + getParsedSize(), &deserDummy,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getReadSize() const { return readSize; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t readSize = 0;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* @brief Class to build replay stop space packet.
|
* @brief Class to build replay stop space packet.
|
||||||
*/
|
*/
|
||||||
@ -676,7 +806,7 @@ class TcCamTakePic : public TcBase {
|
|||||||
TcCamTakePic(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcCamTakePic(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_CAM_TAKE_PIC, sequenceCount) {}
|
: TcBase(params, apid::TC_CAM_TAKE_PIC, sequenceCount) {}
|
||||||
|
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
if (commandDataLen > MAX_DATA_LENGTH) {
|
if (commandDataLen > MAX_DATA_LENGTH) {
|
||||||
return INVALID_LENGTH;
|
return INVALID_LENGTH;
|
||||||
}
|
}
|
||||||
@ -705,7 +835,7 @@ class TcSimplexSendFile : public TcBase {
|
|||||||
TcSimplexSendFile(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcSimplexSendFile(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_SIMPLEX_SEND_FILE, sequenceCount) {}
|
: TcBase(params, apid::TC_SIMPLEX_SEND_FILE, sequenceCount) {}
|
||||||
|
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
if (commandDataLen > MAX_DATA_LENGTH) {
|
if (commandDataLen > MAX_DATA_LENGTH) {
|
||||||
return INVALID_LENGTH;
|
return INVALID_LENGTH;
|
||||||
}
|
}
|
||||||
@ -730,7 +860,7 @@ class TcDownlinkDataModulate : public TcBase {
|
|||||||
TcDownlinkDataModulate(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcDownlinkDataModulate(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_DOWNLINK_DATA_MODULATE, sequenceCount) {}
|
: TcBase(params, apid::TC_DOWNLINK_DATA_MODULATE, sequenceCount) {}
|
||||||
|
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
if (commandDataLen > MAX_DATA_LENGTH) {
|
if (commandDataLen > MAX_DATA_LENGTH) {
|
||||||
return INVALID_LENGTH;
|
return INVALID_LENGTH;
|
||||||
}
|
}
|
||||||
@ -748,8 +878,7 @@ class TcCamcmdSend : public TcBase {
|
|||||||
TcCamcmdSend(ploc::SpTcParams params, uint16_t sequenceCount)
|
TcCamcmdSend(ploc::SpTcParams params, uint16_t sequenceCount)
|
||||||
: TcBase(params, apid::TC_CAM_CMD_SEND, sequenceCount) {}
|
: TcBase(params, apid::TC_CAM_CMD_SEND, sequenceCount) {}
|
||||||
|
|
||||||
protected:
|
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
|
||||||
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) override {
|
|
||||||
if (commandDataLen > MAX_DATA_LENGTH) {
|
if (commandDataLen > MAX_DATA_LENGTH) {
|
||||||
return INVALID_LENGTH;
|
return INVALID_LENGTH;
|
||||||
}
|
}
|
||||||
@ -774,6 +903,69 @@ class TcCamcmdSend : public TcBase {
|
|||||||
static const uint8_t CARRIAGE_RETURN = 0xD;
|
static const uint8_t CARRIAGE_RETURN = 0xD;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HkReport : public StaticLocalDataSet<36> {
|
||||||
|
public:
|
||||||
|
HkReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, HK_SET_ID) {}
|
||||||
|
|
||||||
|
HkReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, HK_SET_ID)) {}
|
||||||
|
|
||||||
|
lp_var_t<uint32_t> status = lp_var_t<uint32_t>(sid.objectId, mpsoc::poolid::STATUS, this);
|
||||||
|
lp_var_t<uint8_t> mode = lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::MODE, this);
|
||||||
|
lp_var_t<uint8_t> downlinkPwrOn =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::DOWNLINK_PWR_ON, this);
|
||||||
|
lp_var_t<uint8_t> downlinkReplyActive =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::DOWNLINK_REPLY_ACTIIVE, this);
|
||||||
|
lp_var_t<uint8_t> downlinkJesdSyncStatus =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::DOWNLINK_JESD_SYNC_STATUS, this);
|
||||||
|
lp_var_t<uint8_t> downlinkDacStatus =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::DOWNLINK_DAC_STATUS, this);
|
||||||
|
lp_var_t<uint8_t> camStatus = lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::CAM_STATUS, this);
|
||||||
|
lp_var_t<uint8_t> camSdiStatus =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::CAM_SDI_STATUS, this);
|
||||||
|
lp_var_t<float> camFpgaTemp = lp_var_t<float>(sid.objectId, mpsoc::poolid::CAM_FPGA_TEMP, this);
|
||||||
|
lp_var_t<float> camSocTemp = lp_var_t<float>(sid.objectId, mpsoc::poolid::CAM_SOC_TEMP, this);
|
||||||
|
lp_var_t<float> sysmonTemp = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_TEMP, this);
|
||||||
|
lp_var_t<float> sysmonVccInt = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCCINT, this);
|
||||||
|
lp_var_t<float> sysmonVccAux = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCCAUX, this);
|
||||||
|
lp_var_t<float> sysmonVccBram =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCCBRAM, this);
|
||||||
|
lp_var_t<float> sysmonVccPaux =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCCPAUX, this);
|
||||||
|
lp_var_t<float> sysmonVccPint =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCCPINT, this);
|
||||||
|
lp_var_t<float> sysmonVccPdro =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCCPDRO, this);
|
||||||
|
lp_var_t<float> sysmonMb12V = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_MB12V, this);
|
||||||
|
lp_var_t<float> sysmonMb3V3 = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_MB3V3, this);
|
||||||
|
lp_var_t<float> sysmonMb1V8 = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_MB1V8, this);
|
||||||
|
lp_var_t<float> sysmonVcc12V = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC12V, this);
|
||||||
|
lp_var_t<float> sysmonVcc5V = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC5V, this);
|
||||||
|
lp_var_t<float> sysmonVcc3V3 = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC3V3, this);
|
||||||
|
lp_var_t<float> sysmonVcc3V3VA =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC3V3VA, this);
|
||||||
|
lp_var_t<float> sysmonVcc2V5DDR =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC2V5DDR, this);
|
||||||
|
lp_var_t<float> sysmonVcc1V2DDR =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC1V2DDR, this);
|
||||||
|
lp_var_t<float> sysmonVcc0V9 = lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC0V9, this);
|
||||||
|
lp_var_t<float> sysmonVcc0V6VTT =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_VCC0V6VTT, this);
|
||||||
|
lp_var_t<float> sysmonSafeCotsCur =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_SAFE_COTS_CUR, this);
|
||||||
|
lp_var_t<float> sysmonNvm4XoCur =
|
||||||
|
lp_var_t<float>(sid.objectId, mpsoc::poolid::SYSMON_NVM4_XO_CUR, this);
|
||||||
|
lp_var_t<uint16_t> semUncorrectableErrs =
|
||||||
|
lp_var_t<uint16_t>(sid.objectId, mpsoc::poolid::SEM_UNCORRECTABLE_ERRS, this);
|
||||||
|
lp_var_t<uint16_t> semCorrectableErrs =
|
||||||
|
lp_var_t<uint16_t>(sid.objectId, mpsoc::poolid::SEM_CORRECTABLE_ERRS, this);
|
||||||
|
lp_var_t<uint8_t> semStatus = lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::SEM_STATUS, this);
|
||||||
|
lp_var_t<uint8_t> rebootMpsocRequired =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, mpsoc::poolid::REBOOT_MPSOC_REQUIRED, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t getStatusFromRawData(const uint8_t* data);
|
||||||
|
std::string getStatusString(uint16_t status);
|
||||||
|
|
||||||
} // namespace mpsoc
|
} // namespace mpsoc
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */
|
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */
|
@ -15,7 +15,7 @@ GyrAdis1650XHandler::GyrAdis1650XHandler(object_id_t objectId, object_id_t devic
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GyrAdis1650XHandler::doStartUp() {
|
void GyrAdis1650XHandler::doStartUp() {
|
||||||
if (internalState != InternalState::STARTUP) {
|
if (internalState == InternalState::NONE) {
|
||||||
internalState = InternalState::STARTUP;
|
internalState = InternalState::STARTUP;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
}
|
}
|
||||||
@ -24,19 +24,21 @@ void GyrAdis1650XHandler::doStartUp() {
|
|||||||
if (not commandExecuted) {
|
if (not commandExecuted) {
|
||||||
warningSwitch = true;
|
warningSwitch = true;
|
||||||
breakCountdown.setTimeout(adis1650x::START_UP_TIME);
|
breakCountdown.setTimeout(adis1650x::START_UP_TIME);
|
||||||
|
updatePeriodicReply(true, adis1650x::REPLY);
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
if (breakCountdown.hasTimedOut()) {
|
}
|
||||||
updatePeriodicReply(true, adis1650x::REPLY);
|
if (internalState == InternalState::STARTUP_DONE) {
|
||||||
setMode(MODE_ON);
|
setMode(MODE_ON);
|
||||||
internalState = InternalState::NONE;
|
commandExecuted = false;
|
||||||
}
|
internalState = InternalState::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GyrAdis1650XHandler::doShutDown() {
|
void GyrAdis1650XHandler::doShutDown() {
|
||||||
if (internalState != InternalState::SHUTDOWN) {
|
if (internalState != InternalState::SHUTDOWN) {
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
|
PoolReadGuard pg(&primaryDataset);
|
||||||
primaryDataset.setValidity(false, true);
|
primaryDataset.setValidity(false, true);
|
||||||
internalState = InternalState::SHUTDOWN;
|
internalState = InternalState::SHUTDOWN;
|
||||||
}
|
}
|
||||||
@ -56,7 +58,11 @@ ReturnValue_t GyrAdis1650XHandler::buildNormalDeviceCommand(DeviceCommandId_t *i
|
|||||||
ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||||
switch (internalState) {
|
switch (internalState) {
|
||||||
case (InternalState::STARTUP): {
|
case (InternalState::STARTUP): {
|
||||||
|
if (breakCountdown.isBusy()) {
|
||||||
|
return NOTHING_TO_SEND;
|
||||||
|
}
|
||||||
*id = adis1650x::REQUEST;
|
*id = adis1650x::REQUEST;
|
||||||
|
adisRequest.cfg.decRateReg = adis1650x::DEC_RATE;
|
||||||
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
||||||
}
|
}
|
||||||
case (InternalState::SHUTDOWN): {
|
case (InternalState::SHUTDOWN): {
|
||||||
@ -87,6 +93,9 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
|
|||||||
getMode() == _MODE_POWER_DOWN) {
|
getMode() == _MODE_POWER_DOWN) {
|
||||||
return IGNORE_FULL_PACKET;
|
return IGNORE_FULL_PACKET;
|
||||||
}
|
}
|
||||||
|
if (internalState == InternalState::STARTUP) {
|
||||||
|
internalState = InternalState::STARTUP_DONE;
|
||||||
|
}
|
||||||
*foundLen = remainingSize;
|
*foundLen = remainingSize;
|
||||||
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
@ -48,7 +48,7 @@ class GyrAdis1650XHandler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
bool warningSwitch = true;
|
bool warningSwitch = true;
|
||||||
|
|
||||||
enum class InternalState { NONE, STARTUP, SHUTDOWN };
|
enum class InternalState { NONE, STARTUP, STARTUP_DONE, SHUTDOWN };
|
||||||
|
|
||||||
InternalState internalState = InternalState::STARTUP;
|
InternalState internalState = InternalState::STARTUP;
|
||||||
bool commandExecuted = false;
|
bool commandExecuted = false;
|
||||||
|
@ -33,6 +33,7 @@ void GyrL3gCustomHandler::doStartUp() {
|
|||||||
void GyrL3gCustomHandler::doShutDown() {
|
void GyrL3gCustomHandler::doShutDown() {
|
||||||
if (internalState != InternalState::SHUTDOWN) {
|
if (internalState != InternalState::SHUTDOWN) {
|
||||||
internalState = InternalState::SHUTDOWN;
|
internalState = InternalState::SHUTDOWN;
|
||||||
|
PoolReadGuard pg(&dataset);
|
||||||
dataset.setValidity(false, true);
|
dataset.setValidity(false, true);
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ void MgmLis3CustomHandler::doStartUp() {
|
|||||||
|
|
||||||
void MgmLis3CustomHandler::doShutDown() {
|
void MgmLis3CustomHandler::doShutDown() {
|
||||||
if (internalState != InternalState::SHUTDOWN) {
|
if (internalState != InternalState::SHUTDOWN) {
|
||||||
|
PoolReadGuard pg(&dataset);
|
||||||
dataset.setValidity(false, true);
|
dataset.setValidity(false, true);
|
||||||
internalState = InternalState::SHUTDOWN;
|
internalState = InternalState::SHUTDOWN;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
|
@ -33,6 +33,7 @@ void MgmRm3100CustomHandler::doStartUp() {
|
|||||||
void MgmRm3100CustomHandler::doShutDown() {
|
void MgmRm3100CustomHandler::doShutDown() {
|
||||||
if (internalState != InternalState::SHUTDOWN) {
|
if (internalState != InternalState::SHUTDOWN) {
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
|
PoolReadGuard pg(&primaryDataset);
|
||||||
primaryDataset.setValidity(false, true);
|
primaryDataset.setValidity(false, true);
|
||||||
internalState = InternalState::SHUTDOWN;
|
internalState = InternalState::SHUTDOWN;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ void SusHandler::doStartUp() {
|
|||||||
|
|
||||||
void SusHandler::doShutDown() {
|
void SusHandler::doShutDown() {
|
||||||
if (internalState != InternalState::SHUTDOWN) {
|
if (internalState != InternalState::SHUTDOWN) {
|
||||||
|
PoolReadGuard pg(&dataset);
|
||||||
dataset.setValidity(false, true);
|
dataset.setValidity(false, true);
|
||||||
internalState = InternalState::SHUTDOWN;
|
internalState = InternalState::SHUTDOWN;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
|
@ -8,11 +8,6 @@
|
|||||||
|
|
||||||
namespace acs {
|
namespace acs {
|
||||||
|
|
||||||
struct Adis1650XRequest {
|
|
||||||
SimpleSensorMode mode;
|
|
||||||
adis1650x::Type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Adis1650XConfig {
|
struct Adis1650XConfig {
|
||||||
uint16_t diagStat;
|
uint16_t diagStat;
|
||||||
uint16_t filterSetting;
|
uint16_t filterSetting;
|
||||||
@ -22,6 +17,12 @@ struct Adis1650XConfig {
|
|||||||
uint16_t prodId;
|
uint16_t prodId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Adis1650XRequest {
|
||||||
|
SimpleSensorMode mode;
|
||||||
|
adis1650x::Type type;
|
||||||
|
Adis1650XConfig cfg;
|
||||||
|
};
|
||||||
|
|
||||||
struct Adis1650XData {
|
struct Adis1650XData {
|
||||||
double sensitivity = 0.0;
|
double sensitivity = 0.0;
|
||||||
// Angular velocities in all axes (X, Y and Z)
|
// Angular velocities in all axes (X, Y and Z)
|
||||||
|
@ -3,41 +3,59 @@
|
|||||||
|
|
||||||
#include <eive/eventSubsystemIds.h>
|
#include <eive/eventSubsystemIds.h>
|
||||||
#include <fsfw/modes/HasModesIF.h>
|
#include <fsfw/modes/HasModesIF.h>
|
||||||
|
#include <mission/sysDefs.h>
|
||||||
|
|
||||||
namespace acs {
|
namespace acs {
|
||||||
|
|
||||||
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
|
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
|
||||||
|
|
||||||
// These modes are the submodes of the ACS controller and the modes of the ACS subsystem.
|
// These modes are the modes of the ACS controller and of the ACS subsystem.
|
||||||
enum AcsMode : Mode_t {
|
enum AcsMode : Mode_t {
|
||||||
OFF = HasModesIF::MODE_OFF,
|
OFF = HasModesIF::MODE_OFF,
|
||||||
SAFE = 10,
|
SAFE = satsystem::Mode::SAFE,
|
||||||
PTG_IDLE = 11,
|
PTG_IDLE = satsystem::Mode::PTG_IDLE,
|
||||||
PTG_NADIR = 12,
|
PTG_NADIR = satsystem::Mode::PTG_NADIR,
|
||||||
PTG_TARGET = 13,
|
PTG_TARGET = satsystem::Mode::PTG_TARGET,
|
||||||
PTG_TARGET_GS = 14,
|
PTG_TARGET_GS = satsystem::Mode::PTG_TARGET_GS,
|
||||||
PTG_INERTIAL = 15,
|
PTG_INERTIAL = satsystem::Mode::PTG_INERTIAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
|
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
|
||||||
|
|
||||||
// static constexpr uint8_t ACS_SYSTEM_DETUMBLE_SUBMODE = 1;
|
enum SafeModeStrategy : uint8_t {
|
||||||
|
SAFECTRL_OFF = 0,
|
||||||
|
SAFECTRL_NO_MAG_FIELD_FOR_CONTROL = 1,
|
||||||
|
SAFECTRL_NO_SENSORS_FOR_CONTROL = 2,
|
||||||
|
SAFECTRL_ACTIVE_MEKF = 10,
|
||||||
|
SAFECTRL_WITHOUT_MEKF = 11,
|
||||||
|
SAFECTRL_ECLIPSE_DAMPING = 12,
|
||||||
|
SAFECTRL_ECLIPSE_IDELING = 13,
|
||||||
|
SAFECTRL_DETUMBLE_FULL = 20,
|
||||||
|
SAFECTRL_DETUMBLE_DETERIORATED = 21,
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
||||||
//!< The limits for the rotation in safe mode were violated.
|
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
|
||||||
static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
|
static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
|
||||||
//!< The system has recovered from a safe rate rotation violation.
|
//! [EXPORT] : [COMMENT] The system has recovered from a safe rate rotation violation.
|
||||||
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
|
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
|
||||||
//!< Multiple RWs are invalid, not commandable and therefore higher ACS modes cannot be maintained.
|
//! [EXPORT] : [COMMENT] Multiple RWs are invalid, uncommandable and therefore higher ACS modes
|
||||||
|
//! cannot be maintained.
|
||||||
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
|
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
|
||||||
//!< MEKF was not able to compute a solution.
|
//! [EXPORT] : [COMMENT] MEKF was not able to compute a solution.
|
||||||
|
//! P1: MEKF state on exit
|
||||||
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
|
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
|
||||||
//!< MEKF is able to compute a solution again.
|
//! [EXPORT] : [COMMENT] MEKF is able to compute a solution again.
|
||||||
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
|
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
|
||||||
//!< MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.
|
//! [EXPORT] : [COMMENT] MEKF performed an automatic reset after detection of nonfinite values.
|
||||||
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(5, severity::HIGH);
|
static constexpr Event MEKF_AUTOMATIC_RESET = MAKE_EVENT(5, severity::INFO);
|
||||||
//!< The ACS safe mode controller was not able to compute a solution and has failed.
|
//! [EXPORT] : [COMMENT] MEKF was not able to compute a solution during any pointing ACS mode for a
|
||||||
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(6, severity::HIGH);
|
//! prolonged time.
|
||||||
|
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(6, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] The ACS safe mode controller was not able to compute a solution and has
|
||||||
|
//! failed.
|
||||||
|
//! P1: Missing information about magnetic field, P2: Missing information about rotational rate
|
||||||
|
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH);
|
||||||
|
|
||||||
extern const char* getModeStr(AcsMode mode);
|
extern const char* getModeStr(AcsMode mode);
|
||||||
|
|
||||||
|
@ -52,3 +52,14 @@ double adis1650x::rangMdlToSensitivity(uint16_t rangMdl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adis1650x::prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* outBuf,
|
||||||
|
size_t maxLen) {
|
||||||
|
if (maxLen < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outBuf[0] = regStart | adis1650x::WRITE_MASK;
|
||||||
|
outBuf[1] = val & 0xff;
|
||||||
|
outBuf[2] = (regStart + 1) | adis1650x::WRITE_MASK;
|
||||||
|
outBuf[3] = (val >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
@ -16,6 +16,8 @@ enum class BurstModes {
|
|||||||
};
|
};
|
||||||
|
|
||||||
size_t prepareReadCommand(const uint8_t* regList, size_t len, uint8_t* outBuf, size_t maxLen);
|
size_t prepareReadCommand(const uint8_t* regList, size_t len, uint8_t* outBuf, size_t maxLen);
|
||||||
|
void prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* outBuf, size_t maxLen);
|
||||||
|
|
||||||
BurstModes burstModeFromMscCtrl(uint16_t mscCtrl);
|
BurstModes burstModeFromMscCtrl(uint16_t mscCtrl);
|
||||||
double rangMdlToSensitivity(uint16_t rangMdl);
|
double rangMdlToSensitivity(uint16_t rangMdl);
|
||||||
|
|
||||||
@ -92,6 +94,9 @@ static constexpr size_t SENSOR_READOUT_SIZE = 20 + 2;
|
|||||||
static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA;
|
static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA;
|
||||||
static constexpr uint32_t ADIS_CFG_DATASET_ID = READ_OUT_CONFIG;
|
static constexpr uint32_t ADIS_CFG_DATASET_ID = READ_OUT_CONFIG;
|
||||||
|
|
||||||
|
static constexpr uint16_t FILT_CTRL = 0x0000;
|
||||||
|
static constexpr uint16_t DEC_RATE = 0x00C7;
|
||||||
|
|
||||||
enum GlobCmds : uint8_t {
|
enum GlobCmds : uint8_t {
|
||||||
FACTORY_CALIBRATION = 0b0000'0010,
|
FACTORY_CALIBRATION = 0b0000'0010,
|
||||||
SENSOR_SELF_TEST = 0b0000'0100,
|
SENSOR_SELF_TEST = 0b0000'0100,
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
#include <mission/acs/str/ArcsecDatalinkLayer.h>
|
#include "ArcsecDatalinkLayer.h"
|
||||||
|
|
||||||
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) { slipInit(); }
|
extern "C" {
|
||||||
|
#include <wire/common/SLIP.h>
|
||||||
|
#include <wire/common/misc.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) {}
|
||||||
|
|
||||||
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
|
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
|
||||||
|
|
||||||
@ -11,38 +16,50 @@ ReturnValue_t ArcsecDatalinkLayer::checkRingBufForFrame(const uint8_t** decodedF
|
|||||||
return DEC_IN_PROGRESS;
|
return DEC_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
|
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
|
||||||
|
|
||||||
|
bool startFound = false;
|
||||||
|
size_t startIdx = 0;
|
||||||
for (size_t idx = 0; idx < currentLen; idx++) {
|
for (size_t idx = 0; idx < currentLen; idx++) {
|
||||||
enum arc_dec_result decResult =
|
if (rxAnalysisBuffer[idx] != SLIP_START_AND_END) {
|
||||||
arc_transport_decode_body(rxAnalysisBuffer[idx], &slipInfo, decodedRxFrame, &rxFrameSize);
|
continue;
|
||||||
switch (decResult) {
|
}
|
||||||
case ARC_DEC_INPROGRESS: {
|
if (not startFound) {
|
||||||
break;
|
startFound = true;
|
||||||
}
|
startIdx = idx;
|
||||||
case ARC_DEC_ERROR_FRAME_SHORT: {
|
continue;
|
||||||
decodeRingBuf.deleteData(idx);
|
}
|
||||||
return REPLY_TOO_SHORT;
|
// Now we can try decoding the whole frame.
|
||||||
}
|
size_t encodedDataSize = 0;
|
||||||
case ARC_DEC_ERROR_CHECKSUM:
|
slip_error_t slipError =
|
||||||
decodeRingBuf.deleteData(idx);
|
slip_decode_frame(decodedRxFrame, &rxFrameSize, rxAnalysisBuffer + startIdx,
|
||||||
return CRC_FAILURE;
|
idx - startIdx + 1, &encodedDataSize, ARC_DEF_SAGITTA_SLIP_ID);
|
||||||
case ARC_DEC_ASYNC:
|
decodeRingBuf.deleteData(idx + 1);
|
||||||
case ARC_DEC_SYNC: {
|
switch (slipError) {
|
||||||
// Reset length of SLIP struct for next frame
|
case (SLIP_OK): {
|
||||||
slipInfo.length = 0;
|
|
||||||
if (decodedFrame != nullptr) {
|
if (decodedFrame != nullptr) {
|
||||||
*decodedFrame = decodedRxFrame;
|
*decodedFrame = decodedRxFrame;
|
||||||
}
|
}
|
||||||
frameLen = rxFrameSize;
|
frameLen = rxFrameSize;
|
||||||
decodeRingBuf.deleteData(idx);
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
default:
|
case (SLIP_BAD_CRC): {
|
||||||
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
|
return CRC_FAILURE;
|
||||||
break;
|
}
|
||||||
|
case (SLIP_OVERFLOW): {
|
||||||
|
return SLIP_OVERFLOW_RETVAL;
|
||||||
|
}
|
||||||
|
// Should not happen, we searched for start and end marker..
|
||||||
|
case (SLIP_NO_END): {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
case (SLIP_ID_MISMATCH): {
|
||||||
|
return SLIP_ID_MISSMATCH_RETVAL;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decodeRingBuf.deleteData(currentLen);
|
|
||||||
return DEC_IN_PROGRESS;
|
return DEC_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,18 +72,11 @@ ReturnValue_t ArcsecDatalinkLayer::feedData(const uint8_t* rawData, size_t rawDa
|
|||||||
return decodeRingBuf.writeData(rawData, rawDataLen);
|
return decodeRingBuf.writeData(rawData, rawDataLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::reset() {
|
void ArcsecDatalinkLayer::reset() { decodeRingBuf.clear(); }
|
||||||
slipInit();
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::slipInit() {
|
|
||||||
slip_decode_init(rxBufferArc, sizeof(rxBufferArc), &slipInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
|
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
|
||||||
size_t& size) {
|
size_t& size) {
|
||||||
arc_transport_encode_body(data, length, txEncoded, &size);
|
slip_encode_frame(data, length, txEncoded, &size, ARC_DEF_SAGITTA_SLIP_ID);
|
||||||
if (txFrame != nullptr) {
|
if (txFrame != nullptr) {
|
||||||
*txFrame = txEncoded;
|
*txFrame = txEncoded;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include <mission/acs/str/strHelpers.h>
|
#include <mission/acs/str/strHelpers.h>
|
||||||
|
|
||||||
#include "arcsec/common/misc.h"
|
|
||||||
#include "eive/resultClassIds.h"
|
#include "eive/resultClassIds.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <wire/common/SLIP.h>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
||||||
*/
|
*/
|
||||||
@ -22,6 +25,8 @@ class ArcsecDatalinkLayer {
|
|||||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
||||||
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
||||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t SLIP_OVERFLOW_RETVAL = MAKE_RETURN_CODE(0xA3);
|
||||||
|
static const ReturnValue_t SLIP_ID_MISSMATCH_RETVAL = MAKE_RETURN_CODE(0xA4);
|
||||||
|
|
||||||
static const uint8_t STATUS_OK = 0;
|
static const uint8_t STATUS_OK = 0;
|
||||||
|
|
||||||
@ -74,7 +79,7 @@ class ArcsecDatalinkLayer {
|
|||||||
// Decoded frame will be copied to this buffer
|
// Decoded frame will be copied to this buffer
|
||||||
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
|
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
|
||||||
// Size of decoded frame
|
// Size of decoded frame
|
||||||
uint32_t rxFrameSize = 0;
|
size_t rxFrameSize = 0;
|
||||||
|
|
||||||
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
||||||
// reply
|
// reply
|
||||||
@ -82,7 +87,7 @@ class ArcsecDatalinkLayer {
|
|||||||
// Size of encoded frame
|
// Size of encoded frame
|
||||||
uint32_t txFrameSize = 0;
|
uint32_t txFrameSize = 0;
|
||||||
|
|
||||||
slip_decode_state slipInfo;
|
// slip_decode_state slipInfo;
|
||||||
|
|
||||||
void slipInit();
|
void slipInit();
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include "arcsecJsonKeys.h"
|
#include "arcsecJsonKeys.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <wire/common/genericstructs.h>
|
||||||
|
}
|
||||||
|
|
||||||
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
||||||
|
|
||||||
ReturnValue_t ArcsecJsonParamBase::create(uint8_t* buffer) {
|
ReturnValue_t ArcsecJsonParamBase::create(uint8_t* buffer) {
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "arcsec/common/generated/tmtcstructs.h"
|
|
||||||
#include "arcsec/common/genericstructs.h"
|
|
||||||
#include "eive/resultClassIds.h"
|
#include "eive/resultClassIds.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
#include <arcsec/client/generated/actionreq.h>
|
|
||||||
#include <arcsec/client/generated/parameter.h>
|
|
||||||
#include <arcsec/client/generated/telemetry.h>
|
|
||||||
#include <fsfw/ipc/QueueFactory.h>
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
#include <mission/acs/str/StarTrackerHandler.h>
|
#include <mission/acs/str/StarTrackerHandler.h>
|
||||||
#include <mission/acs/str/strHelpers.h>
|
#include <mission/acs/str/strHelpers.h>
|
||||||
#include <mission/acs/str/strJsonCommands.h>
|
#include <mission/acs/str/strJsonCommands.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <sagitta/client/actionreq.h>
|
||||||
|
#include <sagitta/client/client_tm_structs.h>
|
||||||
|
#include <sagitta/client/parameter.h>
|
||||||
|
#include <sagitta/client/telemetry.h>
|
||||||
|
#include <wire/common/genericstructs.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "arcsec/common/misc.h"
|
#include "eive/definitions.h"
|
||||||
|
|
||||||
std::atomic_bool JCFG_DONE(false);
|
std::atomic_bool JCFG_DONE(false);
|
||||||
|
|
||||||
@ -95,6 +100,19 @@ void StarTrackerHandler::doShutDown() {
|
|||||||
startupState = StartupState::IDLE;
|
startupState = StartupState::IDLE;
|
||||||
bootState = FwBootState::NONE;
|
bootState = FwBootState::NONE;
|
||||||
solutionSet.setReportingEnabled(false);
|
solutionSet.setReportingEnabled(false);
|
||||||
|
{
|
||||||
|
PoolReadGuard pg(&solutionSet);
|
||||||
|
solutionSet.caliQw.value = 0.0;
|
||||||
|
solutionSet.caliQx.value = 0.0;
|
||||||
|
solutionSet.caliQy.value = 0.0;
|
||||||
|
solutionSet.caliQz.value = 0.0;
|
||||||
|
solutionSet.isTrustWorthy.value = 0;
|
||||||
|
solutionSet.setValidity(false, true);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
PoolReadGuard pg(&temperatureSet);
|
||||||
|
temperatureSet.setValidity(false, true);
|
||||||
|
}
|
||||||
reinitNextSetParam = false;
|
reinitNextSetParam = false;
|
||||||
setMode(_MODE_POWER_DOWN);
|
setMode(_MODE_POWER_DOWN);
|
||||||
}
|
}
|
||||||
@ -148,7 +166,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
case (startracker::SET_JSON_FILE_NAME): {
|
case (startracker::SET_JSON_FILE_NAME): {
|
||||||
if (size > MAX_PATH_SIZE) {
|
if (size > config::MAX_PATH_SIZE) {
|
||||||
return FILE_PATH_TOO_LONG;
|
return FILE_PATH_TOO_LONG;
|
||||||
}
|
}
|
||||||
paramJsonFile = std::string(reinterpret_cast<const char*>(data), size);
|
paramJsonFile = std::string(reinterpret_cast<const char*>(data), size);
|
||||||
@ -185,7 +203,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (size > MAX_PATH_SIZE + MAX_FILE_NAME) {
|
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
|
||||||
return FILE_PATH_TOO_LONG;
|
return FILE_PATH_TOO_LONG;
|
||||||
}
|
}
|
||||||
result = strHelper->startImageUpload(std::string(reinterpret_cast<const char*>(data), size));
|
result = strHelper->startImageUpload(std::string(reinterpret_cast<const char*>(data), size));
|
||||||
@ -200,7 +218,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (size > MAX_PATH_SIZE) {
|
if (size > config::MAX_PATH_SIZE) {
|
||||||
return FILE_PATH_TOO_LONG;
|
return FILE_PATH_TOO_LONG;
|
||||||
}
|
}
|
||||||
result =
|
result =
|
||||||
@ -224,14 +242,14 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
case (startracker::CHANGE_IMAGE_DOWNLOAD_FILE): {
|
case (startracker::CHANGE_IMAGE_DOWNLOAD_FILE): {
|
||||||
if (size > MAX_FILE_NAME) {
|
if (size > config::MAX_FILENAME_SIZE) {
|
||||||
return FILENAME_TOO_LONG;
|
return FILENAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
strHelper->setDownloadImageName(std::string(reinterpret_cast<const char*>(data), size));
|
strHelper->setDownloadImageName(std::string(reinterpret_cast<const char*>(data), size));
|
||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
case (startracker::SET_FLASH_READ_FILENAME): {
|
case (startracker::SET_FLASH_READ_FILENAME): {
|
||||||
if (size > MAX_FILE_NAME) {
|
if (size > config::MAX_FILENAME_SIZE) {
|
||||||
return FILENAME_TOO_LONG;
|
return FILENAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
strHelper->setFlashReadFilename(std::string(reinterpret_cast<const char*>(data), size));
|
strHelper->setFlashReadFilename(std::string(reinterpret_cast<const char*>(data), size));
|
||||||
@ -242,7 +260,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (size > MAX_PATH_SIZE + MAX_FILE_NAME) {
|
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
|
||||||
return FILE_PATH_TOO_LONG;
|
return FILE_PATH_TOO_LONG;
|
||||||
}
|
}
|
||||||
result =
|
result =
|
||||||
@ -880,7 +898,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case (startracker::REQ_TIME): {
|
case (startracker::REQ_TIME): {
|
||||||
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE);
|
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE, "REQ_TIME");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::PING_REQUEST): {
|
case (startracker::PING_REQUEST): {
|
||||||
@ -895,7 +913,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_VERSION): {
|
case (startracker::REQ_VERSION): {
|
||||||
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE);
|
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE, "REQ_VERSION");
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -906,23 +924,23 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_INTERFACE): {
|
case (startracker::REQ_INTERFACE): {
|
||||||
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE);
|
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE, "REQ_INTERFACE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_POWER): {
|
case (startracker::REQ_POWER): {
|
||||||
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE);
|
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE, "REQ_POWER");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_SOLUTION): {
|
case (startracker::REQ_SOLUTION): {
|
||||||
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE);
|
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE, "REQ_SOLUTION");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_TEMPERATURE): {
|
case (startracker::REQ_TEMPERATURE): {
|
||||||
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE);
|
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE, "REQ_TEMP");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_HISTOGRAM): {
|
case (startracker::REQ_HISTOGRAM): {
|
||||||
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE);
|
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE, "REQ_HISTO");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::SUBSCRIPTION):
|
case (startracker::SUBSCRIPTION):
|
||||||
@ -1084,6 +1102,7 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
|
|||||||
localDataPoolMap.emplace(startracker::LISA_QZ, new PoolEntry<float>({0}));
|
localDataPoolMap.emplace(startracker::LISA_QZ, new PoolEntry<float>({0}));
|
||||||
localDataPoolMap.emplace(startracker::LISA_PERC_CLOSE, new PoolEntry<float>({0}));
|
localDataPoolMap.emplace(startracker::LISA_PERC_CLOSE, new PoolEntry<float>({0}));
|
||||||
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
||||||
|
localDataPoolMap.emplace(startracker::STR_MODE, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
||||||
@ -1563,7 +1582,7 @@ ReturnValue_t StarTrackerHandler::executeFlashReadCommand(const uint8_t* command
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (commandDataLen - sizeof(startRegion) - sizeof(length) > MAX_PATH_SIZE) {
|
if (commandDataLen - sizeof(startRegion) - sizeof(length) > config::MAX_PATH_SIZE) {
|
||||||
sif::warning << "StarTrackerHandler::executeFlashReadCommand: Received command with invalid"
|
sif::warning << "StarTrackerHandler::executeFlashReadCommand: Received command with invalid"
|
||||||
<< " path and filename" << std::endl;
|
<< " path and filename" << std::endl;
|
||||||
return FILE_PATH_TOO_LONG;
|
return FILE_PATH_TOO_LONG;
|
||||||
@ -1703,7 +1722,7 @@ ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData
|
|||||||
bool reinitSet) {
|
bool reinitSet) {
|
||||||
// Stopwatch watch;
|
// Stopwatch watch;
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
if (commandDataLen > MAX_PATH_SIZE) {
|
if (commandDataLen > config::MAX_PATH_SIZE) {
|
||||||
return FILE_PATH_TOO_LONG;
|
return FILE_PATH_TOO_LONG;
|
||||||
}
|
}
|
||||||
if (reinitSet) {
|
if (reinitSet) {
|
||||||
@ -1971,7 +1990,7 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||||
size_t size) {
|
size_t size, const char* context) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
uint8_t status = startracker::getStatusField(rawFrame);
|
uint8_t status = startracker::getStatusField(rawFrame);
|
||||||
if (status != startracker::STATUS_OK) {
|
if (status != startracker::STATUS_OK) {
|
||||||
@ -1987,7 +2006,8 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
|
|||||||
dataset.setValidityBufferGeneration(false);
|
dataset.setValidityBufferGeneration(false);
|
||||||
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
|
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed" << std::endl;
|
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
dataset.setValidityBufferGeneration(true);
|
dataset.setValidityBufferGeneration(true);
|
||||||
dataset.setValidity(true, true);
|
dataset.setValidity(true, true);
|
||||||
|
@ -10,12 +10,15 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "arcsec/common/SLIP.h"
|
|
||||||
#include "devices/powerSwitcherList.h"
|
#include "devices/powerSwitcherList.h"
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/timemanager/Countdown.h"
|
#include "fsfw/timemanager/Countdown.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <wire/common/SLIP.h>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the device handler for the star tracker from arcsec.
|
* @brief This is the device handler for the star tracker from arcsec.
|
||||||
*
|
*
|
||||||
@ -141,9 +144,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
|||||||
//! [EXPORT] : [COMMENT] Failed to boot star tracker into bootloader mode
|
//! [EXPORT] : [COMMENT] Failed to boot star tracker into bootloader mode
|
||||||
static const Event BOOTING_BOOTLOADER_FAILED_EVENT = MAKE_EVENT(2, severity::LOW);
|
static const Event BOOTING_BOOTLOADER_FAILED_EVENT = MAKE_EVENT(2, severity::LOW);
|
||||||
|
|
||||||
static const size_t MAX_PATH_SIZE = 50;
|
|
||||||
static const size_t MAX_FILE_NAME = 30;
|
|
||||||
|
|
||||||
static const uint8_t STATUS_OFFSET = 2;
|
static const uint8_t STATUS_OFFSET = 2;
|
||||||
static const uint8_t PARAMS_OFFSET = 2;
|
static const uint8_t PARAMS_OFFSET = 2;
|
||||||
static const uint8_t TICKS_OFFSET = 3;
|
static const uint8_t TICKS_OFFSET = 3;
|
||||||
@ -478,7 +478,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
|||||||
*
|
*
|
||||||
* @return returnvalue::OK if successful, otherwise error return value
|
* @return returnvalue::OK if successful, otherwise error return value
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size);
|
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size,
|
||||||
|
const char* context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if star tracker is in valid mode for executing the received command.
|
* @brief Checks if star tracker is in valid mode for executing the received command.
|
||||||
|
@ -9,7 +9,7 @@ static const char PROPERTIES[] = "properties";
|
|||||||
static const char NAME[] = "name";
|
static const char NAME[] = "name";
|
||||||
static const char VALUE[] = "value";
|
static const char VALUE[] = "value";
|
||||||
|
|
||||||
static const char LIMITS[] = "limits";
|
static const char LIMITS[] = "Limits";
|
||||||
static const char ACTION[] = "action";
|
static const char ACTION[] = "action";
|
||||||
static const char FPGA18CURRENT[] = "FPGA18Current";
|
static const char FPGA18CURRENT[] = "FPGA18Current";
|
||||||
static const char FPGA25CURRENT[] = "FPGA25Current";
|
static const char FPGA25CURRENT[] = "FPGA25Current";
|
||||||
@ -22,20 +22,20 @@ static const char CMOSVRESCURRENT[] = "CMOSVResCurrent";
|
|||||||
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
||||||
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
||||||
|
|
||||||
static const char MOUNTING[] = "mounting";
|
static const char MOUNTING[] = "Mounting";
|
||||||
static const char qw[] = "qw";
|
static const char qw[] = "qw";
|
||||||
static const char qx[] = "qx";
|
static const char qx[] = "qx";
|
||||||
static const char qy[] = "qy";
|
static const char qy[] = "qy";
|
||||||
static const char qz[] = "qz";
|
static const char qz[] = "qz";
|
||||||
|
|
||||||
static const char IMAGE_PROCESSOR[] = "imageprocessor";
|
static const char IMAGE_PROCESSOR[] = "ImageProcessor";
|
||||||
static const char IMAGE_PROCESSOR_MODE[] = "mode";
|
static const char IMAGE_PROCESSOR_MODE[] = "mode";
|
||||||
static const char STORE[] = "store";
|
static const char STORE[] = "store";
|
||||||
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
|
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
|
||||||
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
|
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
|
||||||
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
|
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
|
||||||
|
|
||||||
static const char CAMERA[] = "camera";
|
static const char CAMERA[] = "Camera";
|
||||||
static const char MODE[] = "mode";
|
static const char MODE[] = "mode";
|
||||||
static const char FOCALLENGTH[] = "focallength";
|
static const char FOCALLENGTH[] = "focallength";
|
||||||
static const char EXPOSURE[] = "exposure";
|
static const char EXPOSURE[] = "exposure";
|
||||||
@ -77,7 +77,7 @@ static const char ENABLE_HISTOGRAM[] = "enableHistogram";
|
|||||||
static const char ENABLE_CONTRAST[] = "enableContrast";
|
static const char ENABLE_CONTRAST[] = "enableContrast";
|
||||||
static const char BIN_MODE[] = "binMode";
|
static const char BIN_MODE[] = "binMode";
|
||||||
|
|
||||||
static const char CENTROIDING[] = "centroiding";
|
static const char CENTROIDING[] = "Centroiding";
|
||||||
static const char ENABLE_FILTER[] = "enableFilter";
|
static const char ENABLE_FILTER[] = "enableFilter";
|
||||||
static const char MAX_QUALITY[] = "maxquality";
|
static const char MAX_QUALITY[] = "maxquality";
|
||||||
static const char DARK_THRESHOLD[] = "darkthreshold";
|
static const char DARK_THRESHOLD[] = "darkthreshold";
|
||||||
@ -92,7 +92,7 @@ static const char TRANSMATRIX_01[] = "transmatrix01";
|
|||||||
static const char TRANSMATRIX_10[] = "transmatrix10";
|
static const char TRANSMATRIX_10[] = "transmatrix10";
|
||||||
static const char TRANSMATRIX_11[] = "transmatrix11";
|
static const char TRANSMATRIX_11[] = "transmatrix11";
|
||||||
|
|
||||||
static const char LISA[] = "lisa";
|
static const char LISA[] = "LISA";
|
||||||
static const char LISA_MODE[] = "mode";
|
static const char LISA_MODE[] = "mode";
|
||||||
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
|
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
|
||||||
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
|
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
|
||||||
@ -108,29 +108,29 @@ static const char MAX_COMBINATIONS[] = "max_combinations";
|
|||||||
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
||||||
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
||||||
|
|
||||||
static const char MATCHING[] = "matching";
|
static const char MATCHING[] = "Matching";
|
||||||
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
||||||
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
||||||
|
|
||||||
static const char VALIDATION[] = "validation";
|
static const char VALIDATION[] = "Validation";
|
||||||
static const char STABLE_COUNT[] = "stable_count";
|
static const char STABLE_COUNT[] = "stable_count";
|
||||||
static const char MAX_DIFFERENCE[] = "max_difference";
|
static const char MAX_DIFFERENCE[] = "max_difference";
|
||||||
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
||||||
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
||||||
|
|
||||||
static const char TRACKING[] = "tracking";
|
static const char TRACKING[] = "Tracking";
|
||||||
static const char THIN_LIMIT[] = "thinLimit";
|
static const char THIN_LIMIT[] = "thinLimit";
|
||||||
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
||||||
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
||||||
static const char TRACKER_CHOICE[] = "trackerChoice";
|
static const char TRACKER_CHOICE[] = "trackerChoice";
|
||||||
|
|
||||||
static const char ALGO[] = "algo";
|
static const char ALGO[] = "Algo";
|
||||||
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
|
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
|
||||||
static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
|
static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
|
||||||
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
|
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
|
||||||
static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
|
static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
|
||||||
|
|
||||||
static const char LOGLEVEL[] = "loglevel";
|
static const char LOGLEVEL[] = "LogLevel";
|
||||||
static const char LOGLEVEL1[] = "loglevel1";
|
static const char LOGLEVEL1[] = "loglevel1";
|
||||||
static const char LOGLEVEL2[] = "loglevel2";
|
static const char LOGLEVEL2[] = "loglevel2";
|
||||||
static const char LOGLEVEL3[] = "loglevel3";
|
static const char LOGLEVEL3[] = "loglevel3";
|
||||||
@ -148,7 +148,7 @@ static const char LOGLEVEL14[] = "loglevel14";
|
|||||||
static const char LOGLEVEL15[] = "loglevel15";
|
static const char LOGLEVEL15[] = "loglevel15";
|
||||||
static const char LOGLEVEL16[] = "loglevel16";
|
static const char LOGLEVEL16[] = "loglevel16";
|
||||||
|
|
||||||
static const char SUBSCRIPTION[] = "subscription";
|
static const char SUBSCRIPTION[] = "Subscription";
|
||||||
static const char TELEMETRY_1[] = "telemetry1";
|
static const char TELEMETRY_1[] = "telemetry1";
|
||||||
static const char TELEMETRY_2[] = "telemetry2";
|
static const char TELEMETRY_2[] = "telemetry2";
|
||||||
static const char TELEMETRY_3[] = "telemetry3";
|
static const char TELEMETRY_3[] = "telemetry3";
|
||||||
@ -166,13 +166,13 @@ static const char TELEMETRY_14[] = "telemetry14";
|
|||||||
static const char TELEMETRY_15[] = "telemetry15";
|
static const char TELEMETRY_15[] = "telemetry15";
|
||||||
static const char TELEMETRY_16[] = "telemetry16";
|
static const char TELEMETRY_16[] = "telemetry16";
|
||||||
|
|
||||||
static const char LOG_SUBSCRIPTION[] = "logsubscription";
|
static const char LOG_SUBSCRIPTION[] = "LogSubscription";
|
||||||
static const char LEVEL1[] = "level1";
|
static const char LEVEL1[] = "level1";
|
||||||
static const char MODULE1[] = "module1";
|
static const char MODULE1[] = "module1";
|
||||||
static const char LEVEL2[] = "level2";
|
static const char LEVEL2[] = "level2";
|
||||||
static const char MODULE2[] = "module2";
|
static const char MODULE2[] = "module2";
|
||||||
|
|
||||||
static const char DEBUG_CAMERA[] = "debugcamera";
|
static const char DEBUG_CAMERA[] = "DebugCamera";
|
||||||
static const char TIMING[] = "timing";
|
static const char TIMING[] = "timing";
|
||||||
static const char TEST[] = "test";
|
static const char TEST[] = "test";
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ enum PoolIds : lp_id_t {
|
|||||||
LISA_QZ,
|
LISA_QZ,
|
||||||
LISA_PERC_CLOSE,
|
LISA_PERC_CLOSE,
|
||||||
LISA_NR_CLOSE,
|
LISA_NR_CLOSE,
|
||||||
|
STR_MODE,
|
||||||
TRUST_WORTHY,
|
TRUST_WORTHY,
|
||||||
STABLE_COUNT,
|
STABLE_COUNT,
|
||||||
SOLUTION_STRATEGY,
|
SOLUTION_STRATEGY,
|
||||||
@ -358,7 +359,7 @@ static const uint8_t VERSION_SET_ENTRIES = 5;
|
|||||||
static const uint8_t INTERFACE_SET_ENTRIES = 4;
|
static const uint8_t INTERFACE_SET_ENTRIES = 4;
|
||||||
static const uint8_t POWER_SET_ENTRIES = 18;
|
static const uint8_t POWER_SET_ENTRIES = 18;
|
||||||
static const uint8_t TIME_SET_ENTRIES = 4;
|
static const uint8_t TIME_SET_ENTRIES = 4;
|
||||||
static const uint8_t SOLUTION_SET_ENTRIES = 23;
|
static const uint8_t SOLUTION_SET_ENTRIES = 25;
|
||||||
static const uint8_t HISTOGRAM_SET_ENTRIES = 38;
|
static const uint8_t HISTOGRAM_SET_ENTRIES = 38;
|
||||||
static const uint8_t CHECKSUM_SET_ENTRIES = 1;
|
static const uint8_t CHECKSUM_SET_ENTRIES = 1;
|
||||||
static const uint8_t CAMERA_SET_ENTRIES = 24;
|
static const uint8_t CAMERA_SET_ENTRIES = 24;
|
||||||
@ -640,7 +641,7 @@ class TimeSet : public StaticLocalDataSet<TIME_SET_ENTRIES> {
|
|||||||
*/
|
*/
|
||||||
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
||||||
public:
|
public:
|
||||||
static const size_t SIZE = 78;
|
static const size_t SIZE = 79;
|
||||||
|
|
||||||
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
|
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
|
||||||
|
|
||||||
@ -682,6 +683,7 @@ class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
|||||||
lp_var_t<float>(sid.objectId, PoolIds::LISA_PERC_CLOSE, this);
|
lp_var_t<float>(sid.objectId, PoolIds::LISA_PERC_CLOSE, this);
|
||||||
// Number of close stars in LISA solution
|
// Number of close stars in LISA solution
|
||||||
lp_var_t<uint8_t> lisaNrClose = lp_var_t<uint8_t>(sid.objectId, PoolIds::LISA_NR_CLOSE, this);
|
lp_var_t<uint8_t> lisaNrClose = lp_var_t<uint8_t>(sid.objectId, PoolIds::LISA_NR_CLOSE, this);
|
||||||
|
lp_var_t<uint8_t> strMode = lp_var_t<uint8_t>(sid.objectId, PoolIds::STR_MODE, this);
|
||||||
// Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0)
|
// Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0)
|
||||||
lp_var_t<uint8_t> isTrustWorthy = lp_var_t<uint8_t>(sid.objectId, PoolIds::TRUST_WORTHY, this);
|
lp_var_t<uint8_t> isTrustWorthy = lp_var_t<uint8_t>(sid.objectId, PoolIds::TRUST_WORTHY, this);
|
||||||
// Number of times the validation criteria was met
|
// Number of times the validation criteria was met
|
||||||
|
@ -1 +1 @@
|
|||||||
|
target_sources(${LIB_EIVE_MISSION} PRIVATE CfdpHandler.cpp)
|
||||||
|
135
mission/cfdp/CfdpHandler.cpp
Normal file
135
mission/cfdp/CfdpHandler.cpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#include "CfdpHandler.h"
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/pdu/AckPduReader.h"
|
||||||
|
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
||||||
|
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||||
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
|
using namespace returnvalue;
|
||||||
|
using namespace cfdp;
|
||||||
|
|
||||||
|
CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg)
|
||||||
|
: SystemObject(fsfwParams.objectId),
|
||||||
|
msgQueue(fsfwParams.msgQueue),
|
||||||
|
destHandler(
|
||||||
|
DestHandlerParams(LocalEntityCfg(cfdpCfg.id, cfdpCfg.indicCfg, cfdpCfg.faultHandler),
|
||||||
|
cfdpCfg.userHandler, cfdpCfg.remoteCfgProvider, cfdpCfg.packetInfoList,
|
||||||
|
cfdpCfg.lostSegmentsList),
|
||||||
|
FsfwParams(fsfwParams.packetDest, nullptr, this, fsfwParams.tcStore,
|
||||||
|
fsfwParams.tmStore)) {
|
||||||
|
destHandler.setMsgQueue(msgQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; }
|
||||||
|
|
||||||
|
[[nodiscard]] uint32_t CfdpHandler::getIdentifier() const {
|
||||||
|
return destHandler.getDestHandlerParams().cfg.localId.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] MessageQueueId_t CfdpHandler::getRequestQueue() const { return msgQueue.getId(); }
|
||||||
|
|
||||||
|
ReturnValue_t CfdpHandler::initialize() {
|
||||||
|
ReturnValue_t result = destHandler.initialize();
|
||||||
|
if (result != OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
tcStore = destHandler.getTcStore();
|
||||||
|
tmStore = destHandler.getTmStore();
|
||||||
|
|
||||||
|
return SystemObject::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CfdpHandler::performOperation(uint8_t operationCode) {
|
||||||
|
// TODO: Receive TC packets and route them to source and dest handler, depending on which is
|
||||||
|
// correct or more appropriate
|
||||||
|
ReturnValue_t status;
|
||||||
|
ReturnValue_t result = OK;
|
||||||
|
TmTcMessage tmtcMsg;
|
||||||
|
for (status = msgQueue.receiveMessage(&tmtcMsg); status == returnvalue::OK;
|
||||||
|
status = msgQueue.receiveMessage(&tmtcMsg)) {
|
||||||
|
result = handleCfdpPacket(tmtcMsg);
|
||||||
|
if (result != OK) {
|
||||||
|
status = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto& fsmRes = destHandler.performStateMachine();
|
||||||
|
// TODO: Error handling?
|
||||||
|
while (fsmRes.callStatus == CallStatus::CALL_AGAIN) {
|
||||||
|
destHandler.performStateMachine();
|
||||||
|
// TODO: Error handling?
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) {
|
||||||
|
auto accessorPair = tcStore->getData(msg.getStorageId());
|
||||||
|
if (accessorPair.first != OK) {
|
||||||
|
return accessorPair.first;
|
||||||
|
}
|
||||||
|
PduHeaderReader reader(accessorPair.second.data(), accessorPair.second.size());
|
||||||
|
ReturnValue_t result = reader.parseData();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return INVALID_PDU_FORMAT;
|
||||||
|
}
|
||||||
|
// The CFDP distributor should have taken care of ensuring the destination ID is correct
|
||||||
|
PduType type = reader.getPduType();
|
||||||
|
// Only the destination handler can process these PDUs
|
||||||
|
if (type == PduType::FILE_DATA) {
|
||||||
|
// Disable auto-deletion of packet
|
||||||
|
accessorPair.second.release();
|
||||||
|
PacketInfo info(type, msg.getStorageId());
|
||||||
|
result = destHandler.passPacket(info);
|
||||||
|
} else {
|
||||||
|
// Route depending on PDU type and directive type if applicable. It retrieves directive type
|
||||||
|
// from the raw stream for better performance (with sanity and directive code check).
|
||||||
|
// The routing is based on section 4.5 of the CFDP standard which specifies the PDU forwarding
|
||||||
|
// procedure.
|
||||||
|
|
||||||
|
// PDU header only. Invalid supplied data. A directive packet should have a valid data field
|
||||||
|
// with at least one byte being the directive code
|
||||||
|
const uint8_t* pduDataField = reader.getPduDataField();
|
||||||
|
if (pduDataField == nullptr) {
|
||||||
|
return INVALID_PDU_FORMAT;
|
||||||
|
}
|
||||||
|
if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) {
|
||||||
|
sif::error << "CfdpHandler: Invalid PDU directive field " << pduDataField[0] << std::endl;
|
||||||
|
return INVALID_DIRECTIVE_FIELD;
|
||||||
|
}
|
||||||
|
auto directive = static_cast<FileDirective>(pduDataField[0]);
|
||||||
|
|
||||||
|
auto passToDestHandler = [&]() {
|
||||||
|
accessorPair.second.release();
|
||||||
|
PacketInfo info(type, msg.getStorageId(), directive);
|
||||||
|
result = destHandler.passPacket(info);
|
||||||
|
};
|
||||||
|
auto passToSourceHandler = [&]() {
|
||||||
|
|
||||||
|
};
|
||||||
|
if (directive == FileDirective::METADATA or directive == FileDirective::EOF_DIRECTIVE or
|
||||||
|
directive == FileDirective::PROMPT) {
|
||||||
|
// Section b) of 4.5.3: These PDUs should always be targeted towards the file receiver a.k.a.
|
||||||
|
// the destination handler
|
||||||
|
passToDestHandler();
|
||||||
|
} else if (directive == FileDirective::FINISH or directive == FileDirective::NAK or
|
||||||
|
directive == FileDirective::KEEP_ALIVE) {
|
||||||
|
// Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a.
|
||||||
|
// the source handler
|
||||||
|
passToSourceHandler();
|
||||||
|
} else if (directive == FileDirective::ACK) {
|
||||||
|
// Section a): Recipient depends of the type of PDU that is being acknowledged. We can simply
|
||||||
|
// extract the PDU type from the raw stream. If it is an EOF PDU, this packet is passed to
|
||||||
|
// the source handler, for a Finished PDU, it is passed to the destination handler.
|
||||||
|
FileDirective ackedDirective;
|
||||||
|
if (not AckPduReader::checkAckedDirectiveField(pduDataField[1], ackedDirective)) {
|
||||||
|
return INVALID_ACK_DIRECTIVE_FIELDS;
|
||||||
|
}
|
||||||
|
if (ackedDirective == FileDirective::EOF_DIRECTIVE) {
|
||||||
|
passToSourceHandler();
|
||||||
|
} else if (ackedDirective == FileDirective::FINISH) {
|
||||||
|
passToDestHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
71
mission/cfdp/CfdpHandler.h
Normal file
71
mission/cfdp/CfdpHandler.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
||||||
|
#define FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/handler/DestHandler.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
|
struct FsfwHandlerParams {
|
||||||
|
FsfwHandlerParams(object_id_t objectId, HasFileSystemIF& vfs, AcceptsTelemetryIF& packetDest,
|
||||||
|
StorageManagerIF& tcStore, StorageManagerIF& tmStore, MessageQueueIF& msgQueue)
|
||||||
|
: objectId(objectId),
|
||||||
|
vfs(vfs),
|
||||||
|
packetDest(packetDest),
|
||||||
|
tcStore(tcStore),
|
||||||
|
tmStore(tmStore),
|
||||||
|
msgQueue(msgQueue) {}
|
||||||
|
object_id_t objectId{};
|
||||||
|
HasFileSystemIF& vfs;
|
||||||
|
AcceptsTelemetryIF& packetDest;
|
||||||
|
StorageManagerIF& tcStore;
|
||||||
|
StorageManagerIF& tmStore;
|
||||||
|
MessageQueueIF& msgQueue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CfdpHandlerCfg {
|
||||||
|
CfdpHandlerCfg(cfdp::EntityId localId, cfdp::IndicationCfg indicationCfg,
|
||||||
|
cfdp::UserBase& userHandler, cfdp::FaultHandlerBase& userFaultHandler,
|
||||||
|
cfdp::PacketInfoListBase& packetInfo, cfdp::LostSegmentsListBase& lostSegmentsList,
|
||||||
|
cfdp::RemoteConfigTableIF& remoteCfgProvider)
|
||||||
|
: id(std::move(localId)),
|
||||||
|
indicCfg(indicationCfg),
|
||||||
|
packetInfoList(packetInfo),
|
||||||
|
lostSegmentsList(lostSegmentsList),
|
||||||
|
remoteCfgProvider(remoteCfgProvider),
|
||||||
|
userHandler(userHandler),
|
||||||
|
faultHandler(userFaultHandler) {}
|
||||||
|
|
||||||
|
cfdp::EntityId id;
|
||||||
|
cfdp::IndicationCfg indicCfg;
|
||||||
|
cfdp::PacketInfoListBase& packetInfoList;
|
||||||
|
cfdp::LostSegmentsListBase& lostSegmentsList;
|
||||||
|
cfdp::RemoteConfigTableIF& remoteCfgProvider;
|
||||||
|
cfdp::UserBase& userHandler;
|
||||||
|
cfdp::FaultHandlerBase& faultHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
|
||||||
|
public:
|
||||||
|
explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg);
|
||||||
|
|
||||||
|
[[nodiscard]] const char* getName() const override;
|
||||||
|
[[nodiscard]] uint32_t getIdentifier() const override;
|
||||||
|
[[nodiscard]] MessageQueueId_t getRequestQueue() const override;
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageQueueIF& msgQueue;
|
||||||
|
cfdp::DestHandler destHandler;
|
||||||
|
StorageManagerIF* tcStore = nullptr;
|
||||||
|
StorageManagerIF* tmStore = nullptr;
|
||||||
|
|
||||||
|
ReturnValue_t handleCfdpPacket(TmTcMessage& msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
@ -94,13 +94,6 @@ void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, boo
|
|||||||
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
|
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
|
||||||
DumpContext& dumpContext, bool& dumpPerformed) {
|
DumpContext& dumpContext, bool& dumpPerformed) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
// The PTME might have been reset an transmitter state change, so there is no point in continuing
|
|
||||||
// the dump.
|
|
||||||
// TODO: Will be solved in a cleaner way, this is kind of a hack.
|
|
||||||
if (not channel.isTxOn()) {
|
|
||||||
cancelDump(dumpContext, store, false);
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
// It is assumed that the PTME will only be locked for a short period (e.g. to change datarate).
|
// It is assumed that the PTME will only be locked for a short period (e.g. to change datarate).
|
||||||
if (not channel.isBusy() and not ptmeLocked) {
|
if (not channel.isBusy() and not ptmeLocked) {
|
||||||
performDump(store, dumpContext, dumpPerformed);
|
performDump(store, dumpContext, dumpPerformed);
|
||||||
@ -138,25 +131,22 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
|
|||||||
dumpContext.ptmeBusyCounter = 0;
|
dumpContext.ptmeBusyCounter = 0;
|
||||||
tmSinkBusyCd.resetTimer();
|
tmSinkBusyCd.resetTimer();
|
||||||
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
||||||
if (result != returnvalue::OK) {
|
if (fileHasSwapped and result == PersistentTmStore::DUMP_DONE) {
|
||||||
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
|
||||||
} else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) {
|
|
||||||
// This can happen if a file is corrupted and the next file swap completes the dump.
|
// This can happen if a file is corrupted and the next file swap completes the dump.
|
||||||
dumpDoneHandler();
|
dumpDoneHandler();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
|
} else if (result != returnvalue::OK) {
|
||||||
|
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
dumpedLen = tmReader.getFullPacketLen();
|
dumpedLen = tmReader.getFullPacketLen();
|
||||||
// Only write to VC if mode is on, but always confirm the dump.
|
result = channel.write(tmReader.getFullData(), dumpedLen);
|
||||||
// If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written
|
if (result == DirectTmSinkIF::IS_BUSY) {
|
||||||
// (e.g. to confirm a reset or the transmitter is off anyway).
|
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
|
||||||
if (mode == MODE_ON) {
|
} else if (result != returnvalue::OK) {
|
||||||
result = channel.write(tmReader.getFullData(), dumpedLen);
|
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;
|
||||||
if (result == DirectTmSinkIF::IS_BUSY) {
|
|
||||||
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
|
|
||||||
} else if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = store.confirmDump(tmReader, fileHasSwapped);
|
result = store.confirmDump(tmReader, fileHasSwapped);
|
||||||
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
|
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
|
||||||
dumpPerformed = true;
|
dumpPerformed = true;
|
||||||
|
@ -11,23 +11,14 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
|
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
|
||||||
if (txOn) {
|
return ptme.writeToVc(vcId, data, size);
|
||||||
return ptme.writeToVc(vcId, data, size);
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
||||||
|
|
||||||
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
||||||
|
|
||||||
bool VirtualChannel::isBusy() const {
|
bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); }
|
||||||
// Data is discarded, so channel is not busy.
|
|
||||||
if (not txOn) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ptme.isBusy(vcId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
|
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
|
||||||
|
|
||||||
|
@ -151,57 +151,70 @@ void AcsController::performSafe() {
|
|||||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||||
if (not mekfInvalidFlag) {
|
if (not mekfInvalidFlag) {
|
||||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||||
mekfInvalidFlag = true;
|
mekfInvalidFlag = true;
|
||||||
}
|
}
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||||
|
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||||
navigation.resetMekf(&mekfData);
|
navigation.resetMekf(&mekfData);
|
||||||
mekfLost = true;
|
mekfLost = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mekfInvalidFlag) {
|
||||||
|
triggerEvent(acs::MEKF_RECOVERY);
|
||||||
mekfInvalidFlag = false;
|
mekfInvalidFlag = false;
|
||||||
}
|
}
|
||||||
// get desired satellite rate and sun direction to align
|
|
||||||
double satRateSafe[3] = {0, 0, 0}, sunTargetDir[3] = {0, 0, 0};
|
// get desired satellite rate, sun direction to align to and inertia
|
||||||
guidance.getTargetParamsSafe(sunTargetDir, satRateSafe);
|
double sunTargetDir[3] = {0, 0, 0};
|
||||||
// if MEKF is working
|
guidance.getTargetParamsSafe(sunTargetDir);
|
||||||
|
|
||||||
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
|
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_RUNNING) {
|
acs::SafeModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
|
||||||
result = safeCtrl.safeMekf(now, mekfData.quatMekf.value, mekfData.quatMekf.isValid(),
|
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
|
||||||
mgmDataProcessed.magIgrfModel.value,
|
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
|
||||||
mgmDataProcessed.magIgrfModel.isValid(),
|
acsParameters.safeModeControllerParameters.useMekf,
|
||||||
susDataProcessed.sunIjkModel.value, susDataProcessed.isValid(),
|
acsParameters.safeModeControllerParameters.dampingDuringEclipse);
|
||||||
mekfData.satRotRateMekf.value, mekfData.satRotRateMekf.isValid(),
|
switch (safeCtrlStrat) {
|
||||||
sunTargetDir, satRateSafe, &errAng, magMomMtq);
|
case (acs::SafeModeStrategy::SAFECTRL_ACTIVE_MEKF):
|
||||||
} else {
|
safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value, mekfData.satRotRateMekf.value,
|
||||||
result = safeCtrl.safeNoMekf(
|
susDataProcessed.sunIjkModel.value, mekfData.quatMekf.value, sunTargetDir,
|
||||||
now, susDataProcessed.susVecTot.value, susDataProcessed.susVecTot.isValid(),
|
magMomMtq, errAng);
|
||||||
susDataProcessed.susVecTotDerivative.value, susDataProcessed.susVecTotDerivative.isValid(),
|
|
||||||
mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
|
|
||||||
mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTotDerivative.isValid(),
|
|
||||||
sunTargetDir, satRateSafe, &errAng, magMomMtq);
|
|
||||||
}
|
|
||||||
if (result == returnvalue::FAILED) {
|
|
||||||
if (not safeCtrlFailureFlag) {
|
|
||||||
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE);
|
|
||||||
safeCtrlFailureFlag = true;
|
|
||||||
}
|
|
||||||
safeCtrlFailureCounter++;
|
|
||||||
if (safeCtrlFailureCounter > 150) {
|
|
||||||
safeCtrlFailureFlag = false;
|
safeCtrlFailureFlag = false;
|
||||||
safeCtrlFailureCounter = 0;
|
safeCtrlFailureCounter = 0;
|
||||||
}
|
break;
|
||||||
} else {
|
case (acs::SafeModeStrategy::SAFECTRL_WITHOUT_MEKF):
|
||||||
safeCtrlFailureFlag = false;
|
safeCtrl.safeNonMekf(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
|
||||||
safeCtrlFailureCounter = 0;
|
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING):
|
||||||
|
safeCtrl.safeRateDamping(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
|
||||||
|
sunTargetDir, magMomMtq, errAng);
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING):
|
||||||
|
errAng = NAN;
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(1, 0);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(0, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::error << "AcsController: Invalid safe mode strategy for performSafe" << std::endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs);
|
||||||
acsParameters.magnetorquerParameter.dipolMax);
|
|
||||||
|
|
||||||
// detumble check and switch
|
// detumble check and switch
|
||||||
if (mekfData.satRotRateMekf.isValid() &&
|
if (mekfData.satRotRateMekf.isValid() && acsParameters.safeModeControllerParameters.useMekf &&
|
||||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
|
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
|
||||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||||
detumbleCounter++;
|
detumbleCounter++;
|
||||||
@ -219,10 +232,10 @@ void AcsController::performSafe() {
|
|||||||
startTransition(mode, acs::SafeSubmode::DETUMBLE);
|
startTransition(mode, acs::SafeSubmode::DETUMBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCtrlValData(errAng);
|
updateCtrlValData(errAng, safeCtrlStrat);
|
||||||
updateActuatorCmdData(cmdDipolMtqs);
|
updateActuatorCmdData(cmdDipoleMtqs);
|
||||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2],
|
||||||
// acsParameters.magnetorquerParameter.torqueDuration);
|
acsParameters.magnetorquerParameter.torqueDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcsController::performDetumble() {
|
void AcsController::performDetumble() {
|
||||||
@ -236,23 +249,45 @@ void AcsController::performDetumble() {
|
|||||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||||
if (not mekfInvalidFlag) {
|
if (not mekfInvalidFlag) {
|
||||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||||
mekfInvalidFlag = true;
|
mekfInvalidFlag = true;
|
||||||
}
|
}
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||||
|
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||||
navigation.resetMekf(&mekfData);
|
navigation.resetMekf(&mekfData);
|
||||||
|
mekfLost = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mekfInvalidFlag) {
|
||||||
|
triggerEvent(acs::MEKF_RECOVERY);
|
||||||
mekfInvalidFlag = false;
|
mekfInvalidFlag = false;
|
||||||
}
|
}
|
||||||
|
acs::SafeModeStrategy safeCtrlStrat = detumble.detumbleStrategy(
|
||||||
|
mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(),
|
||||||
|
mgmDataProcessed.mgmVecTotDerivative.isValid(),
|
||||||
|
acsParameters.detumbleParameter.useFullDetumbleLaw);
|
||||||
double magMomMtq[3] = {0, 0, 0};
|
double magMomMtq[3] = {0, 0, 0};
|
||||||
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value,
|
switch (safeCtrlStrat) {
|
||||||
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTot.value,
|
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL):
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq,
|
detumble.bDotLawFull(gyrDataProcessed.gyrVecTot.value, mgmDataProcessed.mgmVecTot.value,
|
||||||
acsParameters.detumbleParameter.gainD);
|
magMomMtq, acsParameters.detumbleParameter.gainFull);
|
||||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
break;
|
||||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED):
|
||||||
acsParameters.magnetorquerParameter.dipolMax);
|
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTot.value,
|
||||||
|
magMomMtq, acsParameters.detumbleParameter.gainBdot);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(1, 0);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(0, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::error << "AcsController: Invalid safe mode strategy for performDetumble" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||||
|
acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs);
|
||||||
|
|
||||||
if (mekfData.satRotRateMekf.isValid() &&
|
if (mekfData.satRotRateMekf.isValid() &&
|
||||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
|
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
|
||||||
@ -273,10 +308,9 @@ void AcsController::performDetumble() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disableCtrlValData();
|
disableCtrlValData();
|
||||||
updateActuatorCmdData(cmdDipolMtqs);
|
updateActuatorCmdData(cmdDipoleMtqs);
|
||||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2],
|
||||||
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
|
acsParameters.magnetorquerParameter.torqueDuration);
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcsController::performPointingCtrl() {
|
void AcsController::performPointingCtrl() {
|
||||||
@ -291,21 +325,22 @@ void AcsController::performPointingCtrl() {
|
|||||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||||
mekfInvalidCounter++;
|
mekfInvalidCounter++;
|
||||||
if (not mekfInvalidFlag) {
|
if (not mekfInvalidFlag) {
|
||||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||||
mekfInvalidFlag = true;
|
mekfInvalidFlag = true;
|
||||||
}
|
}
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||||
|
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||||
navigation.resetMekf(&mekfData);
|
navigation.resetMekf(&mekfData);
|
||||||
|
mekfLost = true;
|
||||||
}
|
}
|
||||||
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
|
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
|
||||||
// Trigger this so STR FDIR can set the device faulty.
|
// Trigger this so STR FDIR can set the device faulty.
|
||||||
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
|
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
|
||||||
mekfInvalidCounter = 0;
|
mekfInvalidCounter = 0;
|
||||||
}
|
}
|
||||||
// commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration,
|
commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
|
||||||
// cmdSpeedRws[0],
|
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
||||||
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
acsParameters.rwHandlingParameters.rampTime);
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (mekfInvalidFlag) {
|
if (mekfInvalidFlag) {
|
||||||
@ -318,8 +353,10 @@ void AcsController::performPointingCtrl() {
|
|||||||
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
|
result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
|
||||||
if (result == returnvalue::FAILED) {
|
if (result == returnvalue::FAILED) {
|
||||||
if (multipleRwUnavailableCounter == 5) {
|
if (multipleRwUnavailableCounter >=
|
||||||
|
acsParameters.rwHandlingParameters.multipleRwInvalidTimeout) {
|
||||||
triggerEvent(acs::MULTIPLE_RW_INVALID);
|
triggerEvent(acs::MULTIPLE_RW_INVALID);
|
||||||
|
multipleRwUnavailableCounter = 0;
|
||||||
}
|
}
|
||||||
multipleRwUnavailableCounter++;
|
multipleRwUnavailableCounter++;
|
||||||
return;
|
return;
|
||||||
@ -333,24 +370,26 @@ void AcsController::performPointingCtrl() {
|
|||||||
// Variables required for setting actuators
|
// Variables required for setting actuators
|
||||||
double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0}, torqueRws[4] = {0, 0, 0, 0},
|
double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0}, torqueRws[4] = {0, 0, 0, 0},
|
||||||
mgtDpDes[3] = {0, 0, 0};
|
mgtDpDes[3] = {0, 0, 0};
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case acs::PTG_IDLE:
|
case acs::PTG_IDLE:
|
||||||
guidance.targetQuatPtgSun(susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
|
guidance.targetQuatPtgSun(now, susDataProcessed.sunIjkModel.value, targetQuat,
|
||||||
|
targetSatRotRate);
|
||||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||||
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
||||||
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
|
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
|
||||||
*rwPseudoInv, torquePtgRws);
|
*rwPseudoInv, torquePtgRws);
|
||||||
ptgCtrl.ptgNullspace(
|
ptgCtrl.ptgNullspace(&acsParameters.idleModeControllerParameters,
|
||||||
&acsParameters.idleModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
|
||||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
rwTrqNs);
|
||||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||||
ptgCtrl.ptgDesaturation(
|
ptgCtrl.ptgDesaturation(
|
||||||
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||||
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||||
enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction;
|
enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -364,17 +403,17 @@ void AcsController::performPointingCtrl() {
|
|||||||
errorSatRotRate, errorAngle);
|
errorSatRotRate, errorAngle);
|
||||||
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
|
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
|
||||||
*rwPseudoInv, torquePtgRws);
|
*rwPseudoInv, torquePtgRws);
|
||||||
ptgCtrl.ptgNullspace(
|
ptgCtrl.ptgNullspace(&acsParameters.targetModeControllerParameters,
|
||||||
&acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
|
||||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
rwTrqNs);
|
||||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||||
ptgCtrl.ptgDesaturation(
|
ptgCtrl.ptgDesaturation(
|
||||||
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||||
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||||
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
|
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -385,17 +424,17 @@ void AcsController::performPointingCtrl() {
|
|||||||
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
||||||
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
|
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
|
||||||
*rwPseudoInv, torquePtgRws);
|
*rwPseudoInv, torquePtgRws);
|
||||||
ptgCtrl.ptgNullspace(
|
ptgCtrl.ptgNullspace(&acsParameters.gsTargetModeControllerParameters,
|
||||||
&acsParameters.gsTargetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
|
||||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
rwTrqNs);
|
||||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||||
ptgCtrl.ptgDesaturation(
|
ptgCtrl.ptgDesaturation(
|
||||||
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||||
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||||
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
|
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -409,66 +448,76 @@ void AcsController::performPointingCtrl() {
|
|||||||
errorSatRotRate, errorAngle);
|
errorSatRotRate, errorAngle);
|
||||||
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate,
|
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate,
|
||||||
*rwPseudoInv, torquePtgRws);
|
*rwPseudoInv, torquePtgRws);
|
||||||
ptgCtrl.ptgNullspace(
|
ptgCtrl.ptgNullspace(&acsParameters.nadirModeControllerParameters,
|
||||||
&acsParameters.nadirModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
|
||||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
rwTrqNs);
|
||||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||||
ptgCtrl.ptgDesaturation(
|
ptgCtrl.ptgDesaturation(
|
||||||
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||||
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||||
enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction;
|
enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case acs::PTG_INERTIAL:
|
case acs::PTG_INERTIAL:
|
||||||
std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat,
|
std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat,
|
||||||
4 * sizeof(double));
|
sizeof(targetQuat));
|
||||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||||
targetSatRotRate, acsParameters.inertialModeControllerParameters.quatRef,
|
targetSatRotRate, acsParameters.inertialModeControllerParameters.quatRef,
|
||||||
acsParameters.inertialModeControllerParameters.refRotRate, errorQuat,
|
acsParameters.inertialModeControllerParameters.refRotRate, errorQuat,
|
||||||
errorSatRotRate, errorAngle);
|
errorSatRotRate, errorAngle);
|
||||||
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate,
|
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate,
|
||||||
*rwPseudoInv, torquePtgRws);
|
*rwPseudoInv, torquePtgRws);
|
||||||
ptgCtrl.ptgNullspace(
|
ptgCtrl.ptgNullspace(&acsParameters.inertialModeControllerParameters,
|
||||||
&acsParameters.inertialModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
|
||||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
rwTrqNs);
|
||||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||||
ptgCtrl.ptgDesaturation(
|
ptgCtrl.ptgDesaturation(
|
||||||
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||||
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||||
enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction;
|
enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sif::error << "AcsController: Invalid mode for performPointingCtrl";
|
sif::error << "AcsController: Invalid mode for performPointingCtrl" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
actuatorCmd.cmdSpeedToRws(
|
actuatorCmd.cmdSpeedToRws(
|
||||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, torqueRws,
|
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
|
||||||
cmdSpeedRws, acsParameters.onBoardParams.sampleTime,
|
acsParameters.onBoardParams.sampleTime, acsParameters.rwHandlingParameters.inertiaWheel,
|
||||||
acsParameters.rwHandlingParameters.maxRwSpeed,
|
acsParameters.rwHandlingParameters.maxRwSpeed, torqueRws, cmdSpeedRws);
|
||||||
acsParameters.rwHandlingParameters.inertiaWheel);
|
|
||||||
if (enableAntiStiction) {
|
if (enableAntiStiction) {
|
||||||
ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws);
|
ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws);
|
||||||
}
|
}
|
||||||
actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs,
|
actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
acsParameters.magnetorquerParameter.dipoleMax, mgtDpDes, cmdDipoleMtqs);
|
||||||
acsParameters.magnetorquerParameter.dipolMax);
|
|
||||||
|
|
||||||
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
|
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
|
||||||
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs);
|
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipoleMtqs);
|
||||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2],
|
||||||
// acsParameters.magnetorquesParameter.torqueDuration, cmdSpeedRws[0],
|
acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
|
||||||
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
acsParameters.rwHandlingParameters.rampTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AcsController::safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure) {
|
||||||
|
if (not safeCtrlFailureFlag) {
|
||||||
|
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE, mgmFailure, sensorFailure);
|
||||||
|
safeCtrlFailureFlag = true;
|
||||||
|
}
|
||||||
|
safeCtrlFailureCounter++;
|
||||||
|
if (safeCtrlFailureCounter > 150) {
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
@ -529,17 +578,19 @@ void AcsController::updateActuatorCmdData(const double *rwTargetTorque,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcsController::updateCtrlValData(double errAng) {
|
void AcsController::updateCtrlValData(double errAng, uint8_t safeModeStrat) {
|
||||||
PoolReadGuard pg(&ctrlValData);
|
PoolReadGuard pg(&ctrlValData);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
ctrlValData.tgtQuat.setValid(false);
|
ctrlValData.tgtQuat.setValid(false);
|
||||||
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
ctrlValData.errQuat.setValid(false);
|
ctrlValData.errQuat.setValid(false);
|
||||||
ctrlValData.errAng.value = errAng;
|
ctrlValData.errAng.value = errAng;
|
||||||
ctrlValData.errAng.setValid(true);
|
ctrlValData.errAng.setValid(true);
|
||||||
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
|
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
|
||||||
ctrlValData.tgtRotRate.setValid(false);
|
ctrlValData.tgtRotRate.setValid(false);
|
||||||
|
ctrlValData.safeStrat.value = safeModeStrat;
|
||||||
|
ctrlValData.safeStrat.setValid(true);
|
||||||
ctrlValData.setValidity(true, false);
|
ctrlValData.setValidity(true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,6 +603,7 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
|
|||||||
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
|
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
|
||||||
ctrlValData.errAng.value = errAng;
|
ctrlValData.errAng.value = errAng;
|
||||||
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
|
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
|
||||||
|
ctrlValData.safeStrat.value = acs::SafeModeStrategy::SAFECTRL_OFF;
|
||||||
ctrlValData.setValidity(true, true);
|
ctrlValData.setValidity(true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,10 +611,10 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
|
|||||||
void AcsController::disableCtrlValData() {
|
void AcsController::disableCtrlValData() {
|
||||||
PoolReadGuard pg(&ctrlValData);
|
PoolReadGuard pg(&ctrlValData);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
ctrlValData.errAng.value = 0;
|
ctrlValData.errAng.value = 0;
|
||||||
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
|
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
|
||||||
ctrlValData.setValidity(false, true);
|
ctrlValData.setValidity(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -644,6 +696,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
|||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
||||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
|
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
|
||||||
// Ctrl Values
|
// Ctrl Values
|
||||||
|
localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
|
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
|
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
|
||||||
|
@ -12,18 +12,17 @@
|
|||||||
#include <mission/acs/imtqHelpers.h>
|
#include <mission/acs/imtqHelpers.h>
|
||||||
#include <mission/acs/rwHelpers.h>
|
#include <mission/acs/rwHelpers.h>
|
||||||
#include <mission/acs/susMax1227Helpers.h>
|
#include <mission/acs/susMax1227Helpers.h>
|
||||||
|
#include <mission/controller/acs/ActuatorCmd.h>
|
||||||
|
#include <mission/controller/acs/Guidance.h>
|
||||||
|
#include <mission/controller/acs/MultiplicativeKalmanFilter.h>
|
||||||
|
#include <mission/controller/acs/Navigation.h>
|
||||||
|
#include <mission/controller/acs/SensorProcessing.h>
|
||||||
|
#include <mission/controller/acs/control/Detumble.h>
|
||||||
|
#include <mission/controller/acs/control/PtgCtrl.h>
|
||||||
|
#include <mission/controller/acs/control/SafeCtrl.h>
|
||||||
|
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
|
|
||||||
#include "acs/ActuatorCmd.h"
|
|
||||||
#include "acs/Guidance.h"
|
|
||||||
#include "acs/MultiplicativeKalmanFilter.h"
|
|
||||||
#include "acs/Navigation.h"
|
|
||||||
#include "acs/SensorProcessing.h"
|
|
||||||
#include "acs/control/Detumble.h"
|
|
||||||
#include "acs/control/PtgCtrl.h"
|
|
||||||
#include "acs/control/SafeCtrl.h"
|
|
||||||
#include "controllerdefinitions/AcsCtrlDefinitions.h"
|
|
||||||
|
|
||||||
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||||
public:
|
public:
|
||||||
static constexpr dur_millis_t INIT_DELAY = 500;
|
static constexpr dur_millis_t INIT_DELAY = 500;
|
||||||
@ -41,9 +40,9 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
void performPointingCtrl();
|
void performPointingCtrl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr double UNIT_QUAT[4] = {0, 0, 0, 1};
|
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
|
||||||
static constexpr double ZERO_VEC[3] = {0, 0, 0};
|
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
|
||||||
static constexpr double RW_OFF_TORQUE[4] = {0.0, 0.0, 0.0, 0.0};
|
static constexpr double RW_OFF_TORQUE[4] = {0, 0, 0, 0};
|
||||||
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
|
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
bool enableHkSets = false;
|
bool enableHkSets = false;
|
||||||
@ -70,7 +69,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
bool mekfLost = false;
|
bool mekfLost = false;
|
||||||
|
|
||||||
int32_t cmdSpeedRws[4] = {0, 0, 0, 0};
|
int32_t cmdSpeedRws[4] = {0, 0, 0, 0};
|
||||||
int16_t cmdDipolMtqs[3] = {0, 0, 0};
|
int16_t cmdDipoleMtqs[3] = {0, 0, 0};
|
||||||
|
|
||||||
#if OBSW_THREAD_TRACING == 1
|
#if OBSW_THREAD_TRACING == 1
|
||||||
uint32_t opCounter = 0;
|
uint32_t opCounter = 0;
|
||||||
@ -85,6 +84,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
|
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
|
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
|
||||||
|
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
|
||||||
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
|
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
@ -105,6 +105,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
void modeChanged(Mode_t mode, Submode_t submode);
|
void modeChanged(Mode_t mode, Submode_t submode);
|
||||||
void announceMode(bool recursive);
|
void announceMode(bool recursive);
|
||||||
|
|
||||||
|
void safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure);
|
||||||
|
|
||||||
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
uint16_t dipoleTorqueDuration);
|
uint16_t dipoleTorqueDuration);
|
||||||
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
@ -113,7 +115,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
void updateActuatorCmdData(const int16_t* mtqTargetDipole);
|
void updateActuatorCmdData(const int16_t* mtqTargetDipole);
|
||||||
void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed,
|
void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed,
|
||||||
const int16_t* mtqTargetDipole);
|
const int16_t* mtqTargetDipole);
|
||||||
void updateCtrlValData(double errAng);
|
void updateCtrlValData(double errAng, uint8_t safeModeStrat);
|
||||||
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
|
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
|
||||||
const double* tgtRotRate);
|
const double* tgtRotRate);
|
||||||
void disableCtrlValData();
|
void disableCtrlValData();
|
||||||
@ -212,6 +214,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
|
|
||||||
// Ctrl Values
|
// Ctrl Values
|
||||||
acsctrl::CtrlValData ctrlValData;
|
acsctrl::CtrlValData ctrlValData;
|
||||||
|
PoolEntry<uint8_t> safeStrat = PoolEntry<uint8_t>();
|
||||||
PoolEntry<double> tgtQuat = PoolEntry<double>(4);
|
PoolEntry<double> tgtQuat = PoolEntry<double>(4);
|
||||||
PoolEntry<double> errQuat = PoolEntry<double>(4);
|
PoolEntry<double> errQuat = PoolEntry<double>(4);
|
||||||
PoolEntry<double> errAng = PoolEntry<double>();
|
PoolEntry<double> errAng = PoolEntry<double>();
|
||||||
|
@ -20,8 +20,11 @@
|
|||||||
#define LOWER_SYRLINKS_UPPER_LIMITS 0
|
#define LOWER_SYRLINKS_UPPER_LIMITS 0
|
||||||
#define LOWER_EBAND_UPPER_LIMITS 0
|
#define LOWER_EBAND_UPPER_LIMITS 0
|
||||||
#define LOWER_PLOC_UPPER_LIMITS 0
|
#define LOWER_PLOC_UPPER_LIMITS 0
|
||||||
|
#define LOWER_MGT_UPPER_LIMITS 0
|
||||||
|
#define LOWER_RW_UPPER_LIMITS 0
|
||||||
|
|
||||||
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater)
|
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||||
|
const std::atomic_bool& tcsBoardShortUnavailable)
|
||||||
: ExtendedControllerBase(objectId),
|
: ExtendedControllerBase(objectId),
|
||||||
heaterHandler(heater),
|
heaterHandler(heater),
|
||||||
sensorTemperatures(this),
|
sensorTemperatures(this),
|
||||||
@ -66,7 +69,8 @@ ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater
|
|||||||
susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB),
|
susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB),
|
||||||
susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF),
|
susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF),
|
||||||
susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF),
|
susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF),
|
||||||
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) {
|
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB),
|
||||||
|
tcsBrdShortlyUnavailable(tcsBoardShortUnavailable) {
|
||||||
resetSensorsArray();
|
resetSensorsArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +113,7 @@ void ThermalController::performControlOperation() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycles == 50) {
|
if (cycles == 40) {
|
||||||
bool changedLimits = false;
|
bool changedLimits = false;
|
||||||
#if LOWER_SYRLINKS_UPPER_LIMITS == 1
|
#if LOWER_SYRLINKS_UPPER_LIMITS == 1
|
||||||
changedLimits = true;
|
changedLimits = true;
|
||||||
@ -128,16 +132,30 @@ void ThermalController::performControlOperation() {
|
|||||||
hpaLimits.cutOffLimit = 0;
|
hpaLimits.cutOffLimit = 0;
|
||||||
hpaLimits.opUpperLimit = 0;
|
hpaLimits.opUpperLimit = 0;
|
||||||
hpaLimits.nopUpperLimit = 0;
|
hpaLimits.nopUpperLimit = 0;
|
||||||
|
#endif
|
||||||
|
#if LOWER_MGT_UPPER_LIMITS == 1
|
||||||
|
changedLimits = true;
|
||||||
|
mgtLimits.cutOffLimit = 0;
|
||||||
|
mgtLimits.opUpperLimit = 0;
|
||||||
|
mgtLimits.nopUpperLimit = 0;
|
||||||
|
#endif
|
||||||
|
#if LOWER_RW_UPPER_LIMITS == 1
|
||||||
|
changedLimits = true;
|
||||||
|
rwLimits.cutOffLimit = 0;
|
||||||
|
rwLimits.opUpperLimit = 0;
|
||||||
|
rwLimits.nopUpperLimit = 0;
|
||||||
#endif
|
#endif
|
||||||
if (changedLimits) {
|
if (changedLimits) {
|
||||||
sif::debug << "ThermalController: changing limits" << std::endl; // TODO: rausschmeissen
|
sif::debug << "ThermalController: changing limits" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (not tcsBrdShortlyUnavailable) {
|
||||||
PoolReadGuard pg(&sensorTemperatures);
|
{
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
PoolReadGuard pg(&sensorTemperatures);
|
||||||
copySensors();
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
|
copySensors();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -157,7 +175,7 @@ void ThermalController::performControlOperation() {
|
|||||||
heaterHandler.getAllSwitchStates(heaterSwitchStateArray);
|
heaterHandler.getAllSwitchStates(heaterSwitchStateArray);
|
||||||
{
|
{
|
||||||
PoolReadGuard pg(&heaterInfo);
|
PoolReadGuard pg(&heaterInfo);
|
||||||
std::memcpy(heaterInfo.heaterSwitchState.value, heaterStates.data(), 8);
|
std::memcpy(heaterInfo.heaterSwitchState.value, heaterSwitchStateArray.data(), 8);
|
||||||
{
|
{
|
||||||
PoolReadGuard pg2(¤tVecPdu2);
|
PoolReadGuard pg2(¤tVecPdu2);
|
||||||
if (pg.getReadResult() == returnvalue::OK and pg2.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK and pg2.getReadResult() == returnvalue::OK) {
|
||||||
@ -166,26 +184,31 @@ void ThermalController::performControlOperation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transitionToOff) {
|
cycles++;
|
||||||
for (const auto& switchState : heaterSwitchStateArray) {
|
if (transitionWhenHeatersOff) {
|
||||||
if (switchState != HeaterHandler::SwitchState::OFF) {
|
bool allSwitchersOff = true;
|
||||||
transitionToOffCycles++;
|
for (size_t idx = 0; idx < heaterSwitchStateArray.size(); idx++) {
|
||||||
// if heater still ON after 10 cycles, switch OFF again
|
if (heaterSwitchStateArray[idx] != HeaterHandler::SwitchState::OFF) {
|
||||||
if (transitionToOffCycles == 10) {
|
allSwitchersOff = false;
|
||||||
for (uint8_t i = 0; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
|
// if heater still ON after 3 cycles, switch OFF again
|
||||||
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
|
if (transitionWhenHeatersOffCycles == 3) {
|
||||||
HeaterHandler::SwitchState::OFF);
|
heaterHandler.switchHeater(static_cast<heater::Switch>(idx),
|
||||||
}
|
HeaterHandler::SwitchState::OFF);
|
||||||
triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE);
|
triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setMode(MODE_OFF);
|
|
||||||
}
|
}
|
||||||
} else if (mode != MODE_OFF) {
|
if (allSwitchersOff or transitionWhenHeatersOffCycles == 6) {
|
||||||
|
// Finish the transition
|
||||||
|
transitionWhenHeatersOff = false;
|
||||||
|
resetThermalStates();
|
||||||
|
setMode(targetMode, targetSubmode);
|
||||||
|
} else {
|
||||||
|
transitionWhenHeatersOffCycles++;
|
||||||
|
}
|
||||||
|
} else if (mode != MODE_OFF and not tcsBrdShortlyUnavailable) {
|
||||||
performThermalModuleCtrl(heaterSwitchStateArray);
|
performThermalModuleCtrl(heaterSwitchStateArray);
|
||||||
}
|
}
|
||||||
cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
@ -288,12 +311,18 @@ LocalPoolDataSetBase* ThermalController::getDataSetHandle(sid_t sid) {
|
|||||||
|
|
||||||
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t* msToReachTheMode) {
|
uint32_t* msToReachTheMode) {
|
||||||
|
if ((mode != MODE_OFF) and (mode != MODE_ON)) {
|
||||||
|
return INVALID_MODE;
|
||||||
|
}
|
||||||
|
if (mode == MODE_ON) {
|
||||||
|
if (submode != SUBMODE_NONE and submode != SUBMODE_NO_HEATER_CTRL) {
|
||||||
|
return HasModesIF::INVALID_SUBMODE;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
if (submode != SUBMODE_NONE) {
|
if (submode != SUBMODE_NONE) {
|
||||||
return INVALID_SUBMODE;
|
return INVALID_SUBMODE;
|
||||||
}
|
}
|
||||||
if ((mode != MODE_OFF) && (mode != MODE_ON) && (mode != MODE_NORMAL)) {
|
|
||||||
return INVALID_MODE;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -972,8 +1001,8 @@ void ThermalController::copyDevices() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::ctrlAcsBoard() {
|
void ThermalController::ctrlAcsBoard() {
|
||||||
heater::Switchers switchNr = heater::HEATER_2_ACS_BRD;
|
heater::Switch switchNr = heater::HEATER_2_ACS_BRD;
|
||||||
heater::Switchers redSwitchNr = heater::HEATER_0_OBC_BRD;
|
heater::Switch redSwitchNr = heater::HEATER_3_OBC_BRD;
|
||||||
|
|
||||||
// A side
|
// A side
|
||||||
thermalComponent = ACS_BOARD;
|
thermalComponent = ACS_BOARD;
|
||||||
@ -1019,7 +1048,9 @@ void ThermalController::ctrlAcsBoard() {
|
|||||||
} else {
|
} else {
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
if (heaterHandler.getSwitchState(switchNr)) {
|
if (heaterHandler.getSwitchState(switchNr)) {
|
||||||
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
|
if (submode != SUBMODE_NO_HEATER_CTRL) {
|
||||||
|
heaterSwitchHelper(switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1036,9 +1067,14 @@ void ThermalController::ctrlMgt() {
|
|||||||
sensors[2].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.plpcduHeatspreader.value;
|
sensors[2].second = sensorTemperatures.plpcduHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits);
|
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, mgtLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
// TODO: trigger special event
|
if (componentAboveUpperLimit and not mgtTooHotFlag) {
|
||||||
|
triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32());
|
||||||
|
mgtTooHotFlag = true;
|
||||||
|
} else if (not componentAboveUpperLimit) {
|
||||||
|
mgtTooHotFlag = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::ctrlRw() {
|
void ThermalController::ctrlRw() {
|
||||||
@ -1170,7 +1206,7 @@ void ThermalController::ctrlIfBoard() {
|
|||||||
sensors[2].first = deviceTemperatures.mgm2SideB.isValid();
|
sensors[2].first = deviceTemperatures.mgm2SideB.isValid();
|
||||||
sensors[2].second = deviceTemperatures.mgm2SideB.value;
|
sensors[2].second = deviceTemperatures.mgm2SideB.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, ifBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, ifBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
// TODO: special event overheating + could go back to safe mode
|
// TODO: special event overheating + could go back to safe mode
|
||||||
}
|
}
|
||||||
@ -1184,7 +1220,7 @@ void ThermalController::ctrlTcsBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
// TODO: special event overheating + could go back to safe mode
|
// TODO: special event overheating + could go back to safe mode
|
||||||
}
|
}
|
||||||
@ -1198,7 +1234,7 @@ void ThermalController::ctrlObc() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits);
|
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
||||||
@ -1217,13 +1253,13 @@ void ThermalController::ctrlObcIfBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
||||||
obcTooHotFlag = true;
|
obcTooHotFlag = true;
|
||||||
} else if (not componentAboveUpperLimit) {
|
} else if (not componentAboveUpperLimit) {
|
||||||
obcTooHotFlag = false; // TODO: !!
|
obcTooHotFlag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,7 +1288,7 @@ void ThermalController::ctrlPcduP60Board() {
|
|||||||
sensors[1].first = deviceTemperatures.temp2P60dock.isValid();
|
sensors[1].first = deviceTemperatures.temp2P60dock.isValid();
|
||||||
sensors[1].second = deviceTemperatures.temp2P60dock.value;
|
sensors[1].second = deviceTemperatures.temp2P60dock.value;
|
||||||
numSensors = 2;
|
numSensors = 2;
|
||||||
HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits);
|
HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
||||||
@ -1264,8 +1300,8 @@ void ThermalController::ctrlPcduP60Board() {
|
|||||||
|
|
||||||
void ThermalController::ctrlPcduAcu() {
|
void ThermalController::ctrlPcduAcu() {
|
||||||
thermalComponent = PCDUACU;
|
thermalComponent = PCDUACU;
|
||||||
heater::Switchers switchNr = heater::HEATER_3_PCDU_PDU;
|
heater::Switch switchNr = heater::HEATER_1_PCDU_PDU;
|
||||||
heater::Switchers redSwitchNr = heater::HEATER_2_ACS_BRD;
|
heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD;
|
||||||
|
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
bool sensorTempAvailable = true;
|
bool sensorTempAvailable = true;
|
||||||
@ -1304,7 +1340,7 @@ void ThermalController::ctrlPcduPdu() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits);
|
HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
||||||
@ -1325,7 +1361,7 @@ void ThermalController::ctrlPlPcduBoard() {
|
|||||||
sensors[3].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
sensors[3].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
||||||
sensors[3].second = sensorTemperatures.plpcduHeatspreader.value;
|
sensors[3].second = sensorTemperatures.plpcduHeatspreader.value;
|
||||||
numSensors = 4;
|
numSensors = 4;
|
||||||
HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
||||||
}
|
}
|
||||||
@ -1339,7 +1375,7 @@ void ThermalController::ctrlPlocMissionBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD,
|
HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD,
|
||||||
plocMissionBoardLimits);
|
plocMissionBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
||||||
@ -1354,7 +1390,7 @@ void ThermalController::ctrlPlocProcessingBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD,
|
HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD,
|
||||||
plocProcessingBoardLimits);
|
plocProcessingBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
||||||
@ -1369,7 +1405,7 @@ void ThermalController::ctrlDac() {
|
|||||||
sensors[2].first = sensorTemperatures.plocHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.plocHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.plocHeatspreader.value;
|
sensors[2].second = sensorTemperatures.plocHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, dacLimits);
|
HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, dacLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
||||||
}
|
}
|
||||||
@ -1553,13 +1589,16 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate
|
|||||||
void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
|
void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
|
||||||
if (selectAndReadSensorTemp(htrCtx)) {
|
if (selectAndReadSensorTemp(htrCtx)) {
|
||||||
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
||||||
|
// Core loop for a thermal component, after sensors and heaters were selected.
|
||||||
checkLimitsAndCtrlHeater(htrCtx);
|
checkLimitsAndCtrlHeater(htrCtx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: muss der Heater dann wirklich abgeschalten werden?
|
// No sensors available, so switch the heater off. We can not perform control tasks if we
|
||||||
|
// are blind..
|
||||||
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
||||||
if (heaterHandler.getSwitchState(htrCtx.switchNr)) {
|
if (heaterCtrlAllowed() and
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
|
(heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON)) {
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1589,16 +1628,21 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) {
|
bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr) {
|
||||||
bool heaterAvailable = true;
|
bool heaterAvailable = true;
|
||||||
|
|
||||||
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
|
HasHealthIF::HealthState mainHealth = heaterHandler.getHealth(switchNr);
|
||||||
if (heaterHandler.getHealth(redSwitchNr) == HasHealthIF::HEALTHY) {
|
HasHealthIF::HealthState redHealth = heaterHandler.getHealth(redSwitchNr);
|
||||||
|
if (mainHealth != HasHealthIF::HEALTHY) {
|
||||||
|
if (redHealth == HasHealthIF::HEALTHY) {
|
||||||
switchNr = redSwitchNr;
|
switchNr = redSwitchNr;
|
||||||
redSwitchNrInUse = true;
|
redSwitchNrInUse = true;
|
||||||
} else {
|
} else {
|
||||||
heaterAvailable = false;
|
heaterAvailable = false;
|
||||||
triggerEvent(tcsCtrl::NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr);
|
// Special case: Ground might command/do something with the heaters, so prevent spam.
|
||||||
|
if (not(mainHealth == EXTERNAL_CONTROL and redHealth == EXTERNAL_CONTROL)) {
|
||||||
|
triggerEvent(tcsCtrl::NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redSwitchNrInUse = false;
|
redSwitchNrInUse = false;
|
||||||
@ -1607,15 +1651,18 @@ bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switch
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, const char* whatLimit) {
|
void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, const char* whatLimit) {
|
||||||
|
if (not heaterCtrlAllowed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
|
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
|
||||||
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
|
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
|
||||||
<< whatLimit << ", switching off heater" << std::endl;
|
<< whatLimit << ", switching off heater" << std::endl;
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
heaterStates[htrCtx.switchNr].switchTransition = true;
|
||||||
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
||||||
}
|
}
|
||||||
if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) {
|
if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) {
|
||||||
heaterHandler.switchHeater(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF);
|
heaterSwitchHelper(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
|
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
|
||||||
heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF;
|
heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF;
|
||||||
}
|
}
|
||||||
@ -1630,43 +1677,44 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
|
|||||||
if (heaterStates[htrCtx.switchNr].switchTransition) {
|
if (heaterStates[htrCtx.switchNr].switchTransition) {
|
||||||
htrCtx.doHeaterHandling = false;
|
htrCtx.doHeaterHandling = false;
|
||||||
heaterCtrlCheckUpperLimits(htrCtx);
|
heaterCtrlCheckUpperLimits(htrCtx);
|
||||||
} else {
|
return;
|
||||||
// Heater off
|
}
|
||||||
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
|
|
||||||
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
|
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
|
||||||
if (sensorTemp < htrCtx.tempLimit.opLowerLimit) {
|
// Heater off
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::ON);
|
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
|
||||||
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
|
if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) {
|
||||||
<< static_cast<int>(thermalComponent) << " ON" << std::endl;
|
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " ON" << std::endl;
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, thermalComponent);
|
||||||
|
heaterStates[htrCtx.switchNr].switchTransition = true;
|
||||||
|
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
|
||||||
|
} else {
|
||||||
|
// Even if heater control is now allowed, we can update the state.
|
||||||
|
thermalStates[thermalComponent].heating = false;
|
||||||
|
}
|
||||||
|
heaterCtrlCheckUpperLimits(htrCtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Heater on
|
||||||
|
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
|
||||||
|
if (thermalStates[thermalComponent].heating) {
|
||||||
|
// We are already in a heating cycle, so need to check whether heating task is complete.
|
||||||
|
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET and heaterCtrlAllowed()) {
|
||||||
|
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " OFF" << std::endl;
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
heaterStates[htrCtx.switchNr].switchTransition = true;
|
||||||
thermalStates[thermalComponent].heating = true;
|
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
||||||
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
|
|
||||||
} else {
|
|
||||||
thermalStates[thermalComponent].heating = false;
|
|
||||||
}
|
}
|
||||||
heaterCtrlCheckUpperLimits(htrCtx);
|
return;
|
||||||
// Heater on
|
}
|
||||||
} else if (heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON) {
|
// This can happen if heater is used as alternative heater (no regular heating cycle), so we
|
||||||
if (thermalStates[thermalComponent].heating) {
|
// should still check the upper limits.
|
||||||
// We are already in a heating cycle, so need to check whether heating task is complete.
|
bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx);
|
||||||
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET) {
|
if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) {
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
|
componentAboveCutOffLimit = true;
|
||||||
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
|
if (not tooHighHandlerAlreadyCalled) {
|
||||||
<< static_cast<int>(thermalComponent) << " OFF" << std::endl;
|
heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit");
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
|
||||||
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
|
||||||
thermalStates[thermalComponent].heating = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This can happen if heater is used as alternative heater (no regular heating cycle), so we
|
|
||||||
// should still check the upper limits.
|
|
||||||
bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx);
|
|
||||||
if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) {
|
|
||||||
componentAboveCutOffLimit = true;
|
|
||||||
if (not tooHighHandlerAlreadyCalled) {
|
|
||||||
heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1698,8 +1746,8 @@ void ThermalController::resetSensorsArray() {
|
|||||||
}
|
}
|
||||||
thermalComponent = NONE;
|
thermalComponent = NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates) {
|
void ThermalController::heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates) {
|
||||||
// TODO: Test
|
|
||||||
for (unsigned i = 0; i < 7; i++) {
|
for (unsigned i = 0; i < 7; i++) {
|
||||||
if (heaterStates[i].switchTransition) {
|
if (heaterStates[i].switchTransition) {
|
||||||
if (currentHeaterStates[i] == heaterStates[i].target) {
|
if (currentHeaterStates[i] == heaterStates[i].target) {
|
||||||
@ -1723,11 +1771,12 @@ uint32_t ThermalController::tempFloatToU32() const {
|
|||||||
return tempRaw;
|
return tempRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::setMode(Mode_t mode) {
|
void ThermalController::setMode(Mode_t mode, Submode_t submode) {
|
||||||
if (mode == MODE_OFF) {
|
if (mode == MODE_OFF) {
|
||||||
transitionToOff = false;
|
transitionWhenHeatersOff = false;
|
||||||
}
|
}
|
||||||
this->mode = mode;
|
this->mode = mode;
|
||||||
|
this->submode = submode;
|
||||||
modeHelper.modeChanged(mode, submode);
|
modeHelper.modeChanged(mode, submode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
}
|
}
|
||||||
@ -1742,6 +1791,43 @@ bool ThermalController::tooHotHandler(object_id_t object, bool& oneShotFlag) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO_HEATER_CTRL; }
|
||||||
|
|
||||||
|
void ThermalController::resetThermalStates() {
|
||||||
|
for (auto& thermalState : thermalStates) {
|
||||||
|
thermalState.heating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
|
||||||
|
HeaterHandler::SwitchState state,
|
||||||
|
unsigned componentIdx) {
|
||||||
|
timeval currentTime;
|
||||||
|
Clock::getClockMonotonic(¤tTime);
|
||||||
|
if (state == HeaterHandler::SwitchState::ON) {
|
||||||
|
heaterHandler.switchHeater(switchNr, state);
|
||||||
|
thermalStates[componentIdx].heating = true;
|
||||||
|
thermalStates[componentIdx].heaterStartTime = currentTime.tv_sec;
|
||||||
|
} else {
|
||||||
|
heaterHandler.switchHeater(switchNr, state);
|
||||||
|
thermalStates[componentIdx].heating = false;
|
||||||
|
thermalStates[componentIdx].heaterEndTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThermalController::heaterSwitchHelperAllOff() {
|
||||||
|
timeval currentTime;
|
||||||
|
Clock::getClockMonotonic(¤tTime);
|
||||||
|
size_t idx = 0;
|
||||||
|
for (; idx < heater::Switch::NUMBER_OF_SWITCHES; idx++) {
|
||||||
|
heaterHandler.switchHeater(static_cast<heater::Switch>(idx), HeaterHandler::SwitchState::OFF);
|
||||||
|
}
|
||||||
|
for (idx = 0; idx < thermalStates.size(); idx++) {
|
||||||
|
thermalStates[idx].heating = false;
|
||||||
|
thermalStates[idx].heaterEndTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
|
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
|
||||||
// Clear the one shot flag is the component is in acceptable temperature range.
|
// Clear the one shot flag is the component is in acceptable temperature range.
|
||||||
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
|
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
|
||||||
@ -1751,14 +1837,15 @@ void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object,
|
|||||||
|
|
||||||
void ThermalController::startTransition(Mode_t mode_, Submode_t submode_) {
|
void ThermalController::startTransition(Mode_t mode_, Submode_t submode_) {
|
||||||
triggerEvent(CHANGING_MODE, mode_, submode_);
|
triggerEvent(CHANGING_MODE, mode_, submode_);
|
||||||
if (mode_ == MODE_OFF) {
|
// For MODE_OFF and the no heater control submode, we command all switches to off before
|
||||||
for (uint8_t i = 0; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
|
// completing the transition. This ensures a consistent state when commanding these modes.
|
||||||
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
|
if ((mode_ == MODE_OFF) or ((mode_ == MODE_ON) and (submode_ == SUBMODE_NO_HEATER_CTRL))) {
|
||||||
HeaterHandler::SwitchState::OFF);
|
heaterSwitchHelperAllOff();
|
||||||
}
|
transitionWhenHeatersOff = true;
|
||||||
transitionToOff = true;
|
targetMode = mode_;
|
||||||
transitionToOffCycles = 0;
|
targetSubmode = submode_;
|
||||||
|
transitionWhenHeatersOffCycles = 0;
|
||||||
} else {
|
} else {
|
||||||
setMode(mode_);
|
setMode(mode_, submode_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <mission/tcs/Tmp1075Definitions.h>
|
#include <mission/tcs/Tmp1075Definitions.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,8 +48,13 @@ struct TempLimits {
|
|||||||
|
|
||||||
struct ThermalState {
|
struct ThermalState {
|
||||||
uint8_t errorCounter;
|
uint8_t errorCounter;
|
||||||
bool heating;
|
// Is heating on for that thermal module?
|
||||||
uint32_t heaterStartTime;
|
bool heating = false;
|
||||||
|
heater::Switch heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
|
||||||
|
// Heater start time and end times as UNIX seconds. Please note that these times will be updated
|
||||||
|
// when a switch command is sent, with no guarantess that the heater actually went on.
|
||||||
|
uint32_t heaterStartTime = 0;
|
||||||
|
uint32_t heaterEndTime = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HeaterState {
|
struct HeaterState {
|
||||||
@ -89,25 +95,28 @@ enum ThermalComponents : uint8_t {
|
|||||||
|
|
||||||
class ThermalController : public ExtendedControllerBase {
|
class ThermalController : public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
|
||||||
|
|
||||||
static const uint16_t INVALID_TEMPERATURE = 999;
|
static const uint16_t INVALID_TEMPERATURE = 999;
|
||||||
static const uint8_t NUMBER_OF_SENSORS = 16;
|
static const uint8_t NUMBER_OF_SENSORS = 16;
|
||||||
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
|
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
|
||||||
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
|
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
|
||||||
|
|
||||||
ThermalController(object_id_t objectId, HeaterHandler& heater);
|
ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||||
|
const std::atomic_bool& tcsBoardShortUnavailable);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct HeaterContext {
|
struct HeaterContext {
|
||||||
public:
|
public:
|
||||||
HeaterContext(heater::Switchers switchNr, heater::Switchers redundantSwitchNr,
|
HeaterContext(heater::Switch switchNr, heater::Switch redundantSwitchNr,
|
||||||
const TempLimits& tempLimit)
|
const TempLimits& tempLimit)
|
||||||
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
|
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
|
||||||
bool doHeaterHandling = true;
|
bool doHeaterHandling = true;
|
||||||
heater::Switchers switchNr;
|
heater::Switch switchNr;
|
||||||
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
|
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
|
||||||
heater::Switchers redSwitchNr;
|
heater::Switch redSwitchNr;
|
||||||
const TempLimits& tempLimit;
|
const TempLimits& tempLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,6 +190,10 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
susMax1227::SusDataset susSet10;
|
susMax1227::SusDataset susSet10;
|
||||||
susMax1227::SusDataset susSet11;
|
susMax1227::SusDataset susSet11;
|
||||||
|
|
||||||
|
// If the TCS board in unavailable, for example due to a recovery, skip
|
||||||
|
// some TCS controller tasks to avoid unnecessary events.
|
||||||
|
const std::atomic_bool& tcsBrdShortlyUnavailable = false;
|
||||||
|
|
||||||
lp_var_t<float> tempQ7s = lp_var_t<float>(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE);
|
lp_var_t<float> tempQ7s = lp_var_t<float>(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE);
|
||||||
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_1);
|
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_1);
|
||||||
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_2);
|
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_2);
|
||||||
@ -254,14 +267,17 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
bool pcduSystemTooHotFlag = false;
|
bool pcduSystemTooHotFlag = false;
|
||||||
bool syrlinksTooHotFlag = false;
|
bool syrlinksTooHotFlag = false;
|
||||||
bool obcTooHotFlag = false;
|
bool obcTooHotFlag = false;
|
||||||
|
bool mgtTooHotFlag = false;
|
||||||
bool strTooHotFlag = false;
|
bool strTooHotFlag = false;
|
||||||
bool rwTooHotFlag = false;
|
bool rwTooHotFlag = false;
|
||||||
|
|
||||||
bool transitionToOff = false;
|
bool transitionWhenHeatersOff = false;
|
||||||
uint32_t transitionToOffCycles = 0;
|
uint32_t transitionWhenHeatersOffCycles = 0;
|
||||||
|
Mode_t targetMode = MODE_OFF;
|
||||||
|
Submode_t targetSubmode = SUBMODE_NONE;
|
||||||
uint32_t cycles = 0;
|
uint32_t cycles = 0;
|
||||||
std::array<ThermalState, 30> thermalStates{};
|
std::array<ThermalState, ThermalComponents::NUM_ENTRIES> thermalStates{};
|
||||||
std::array<HeaterState, 7> heaterStates{};
|
std::array<HeaterState, heater::NUMBER_OF_SWITCHES> heaterStates{};
|
||||||
|
|
||||||
// Initial delay to make sure all pool variables have been initialized their owners.
|
// Initial delay to make sure all pool variables have been initialized their owners.
|
||||||
// Also, wait for system initialization to complete.
|
// Also, wait for system initialization to complete.
|
||||||
@ -286,6 +302,9 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
|
|
||||||
|
bool heaterCtrlAllowed() const;
|
||||||
|
void resetThermalStates();
|
||||||
|
|
||||||
void resetSensorsArray();
|
void resetSensorsArray();
|
||||||
void copySensors();
|
void copySensors();
|
||||||
void copySus();
|
void copySus();
|
||||||
@ -296,9 +315,13 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
|
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
|
||||||
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
|
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
|
||||||
|
|
||||||
bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr);
|
bool chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr);
|
||||||
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
|
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
|
||||||
|
|
||||||
|
void heaterSwitchHelperAllOff();
|
||||||
|
void heaterSwitchHelper(heater::Switch switchNr, HeaterHandler::SwitchState state,
|
||||||
|
unsigned componentIdx);
|
||||||
|
|
||||||
void ctrlAcsBoard();
|
void ctrlAcsBoard();
|
||||||
void ctrlMgt();
|
void ctrlMgt();
|
||||||
void ctrlRw();
|
void ctrlRw();
|
||||||
@ -323,7 +346,7 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
void ctrlMpa();
|
void ctrlMpa();
|
||||||
void ctrlScexBoard();
|
void ctrlScexBoard();
|
||||||
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
||||||
void setMode(Mode_t mode);
|
void setMode(Mode_t mode, Submode_t submode);
|
||||||
uint32_t tempFloatToU32() const;
|
uint32_t tempFloatToU32() const;
|
||||||
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
|
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
|
||||||
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);
|
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);
|
||||||
|
@ -33,18 +33,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x2: // InertiaEIVE
|
case 0x2: // InertiaEIVE
|
||||||
switch (parameterId) {
|
switch (parameterId) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrix);
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x1:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x2:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
|
||||||
break;
|
break;
|
||||||
case 0x4:
|
case 0x3:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -107,6 +104,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x11:
|
case 0x11:
|
||||||
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
|
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
|
||||||
break;
|
break;
|
||||||
|
case 0x12:
|
||||||
|
parameterWrapper->set(mgmHandlingParameters.mgmDerivativeFilterWeight);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -221,6 +221,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x23:
|
case 0x23:
|
||||||
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta);
|
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta);
|
||||||
break;
|
break;
|
||||||
|
case 0x24:
|
||||||
|
parameterWrapper->set(susHandlingParameters.susBrightnessThreshold);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -260,6 +263,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0xA:
|
case 0xA:
|
||||||
parameterWrapper->set(gyrHandlingParameters.preferAdis);
|
parameterWrapper->set(gyrHandlingParameters.preferAdis);
|
||||||
break;
|
break;
|
||||||
|
case 0xB:
|
||||||
|
parameterWrapper->set(gyrHandlingParameters.gyrFilterWeight);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -287,6 +293,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(rwHandlingParameters.rampTime);
|
parameterWrapper->set(rwHandlingParameters.rampTime);
|
||||||
break;
|
break;
|
||||||
|
case 0x7:
|
||||||
|
parameterWrapper->set(rwHandlingParameters.multipleRwInvalidTimeout);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -312,7 +321,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->setMatrix(rwMatrices.without4);
|
parameterWrapper->setMatrix(rwMatrices.without4);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->setVector(rwMatrices.nullspace);
|
parameterWrapper->setVector(rwMatrices.nullspaceVector);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
@ -321,28 +330,34 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case (0x8): // SafeModeControllerParameters
|
case (0x8): // SafeModeControllerParameters
|
||||||
switch (parameterId) {
|
switch (parameterId) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_rate_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_orthoMekf);
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_align_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_alignMekf);
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_rate_no_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_parallelMekf);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_align_no_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_orthoNonMekf);
|
||||||
break;
|
break;
|
||||||
case 0x4:
|
case 0x4:
|
||||||
parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin);
|
parameterWrapper->set(safeModeControllerParameters.k_alignNonMekf);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
|
parameterWrapper->set(safeModeControllerParameters.k_parallelNonMekf);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
|
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->setVector(safeModeControllerParameters.satRateRef);
|
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
|
||||||
|
break;
|
||||||
|
case 0x8:
|
||||||
|
parameterWrapper->set(safeModeControllerParameters.useMekf);
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
|
parameterWrapper->set(safeModeControllerParameters.dampingDuringEclipse);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
@ -366,18 +381,20 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(idleModeControllerParameters.gainNullspace);
|
parameterWrapper->set(idleModeControllerParameters.gainNullspace);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(idleModeControllerParameters.desatMomentumRef);
|
parameterWrapper->set(idleModeControllerParameters.nullspaceSpeed);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(idleModeControllerParameters.deSatGainFactor);
|
parameterWrapper->setVector(idleModeControllerParameters.desatMomentumRef);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->set(idleModeControllerParameters.desatOn);
|
parameterWrapper->set(idleModeControllerParameters.deSatGainFactor);
|
||||||
break;
|
break;
|
||||||
case 0x8:
|
case 0x8:
|
||||||
|
parameterWrapper->set(idleModeControllerParameters.desatOn);
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
|
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -400,48 +417,51 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
|
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(targetModeControllerParameters.desatMomentumRef);
|
parameterWrapper->set(targetModeControllerParameters.nullspaceSpeed);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
|
parameterWrapper->setVector(targetModeControllerParameters.desatMomentumRef);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->set(targetModeControllerParameters.desatOn);
|
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
|
||||||
break;
|
break;
|
||||||
case 0x8:
|
case 0x8:
|
||||||
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
|
parameterWrapper->set(targetModeControllerParameters.desatOn);
|
||||||
break;
|
break;
|
||||||
case 0x9:
|
case 0x9:
|
||||||
parameterWrapper->setVector(targetModeControllerParameters.refDirection);
|
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
|
||||||
break;
|
break;
|
||||||
case 0xA:
|
case 0xA:
|
||||||
parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
|
parameterWrapper->setVector(targetModeControllerParameters.refDirection);
|
||||||
break;
|
break;
|
||||||
case 0xB:
|
case 0xB:
|
||||||
parameterWrapper->setVector(targetModeControllerParameters.quatRef);
|
parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
|
||||||
break;
|
break;
|
||||||
case 0xC:
|
case 0xC:
|
||||||
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
|
parameterWrapper->setVector(targetModeControllerParameters.quatRef);
|
||||||
break;
|
break;
|
||||||
case 0xD:
|
case 0xD:
|
||||||
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
|
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
|
||||||
break;
|
break;
|
||||||
case 0xE:
|
case 0xE:
|
||||||
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
|
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
|
||||||
break;
|
break;
|
||||||
case 0xF:
|
case 0xF:
|
||||||
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
|
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
parameterWrapper->set(targetModeControllerParameters.avoidBlindStr);
|
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
|
||||||
break;
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
parameterWrapper->set(targetModeControllerParameters.blindAvoidStart);
|
parameterWrapper->set(targetModeControllerParameters.avoidBlindStr);
|
||||||
break;
|
break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
parameterWrapper->set(targetModeControllerParameters.blindAvoidStop);
|
parameterWrapper->set(targetModeControllerParameters.blindAvoidStart);
|
||||||
break;
|
break;
|
||||||
case 0x13:
|
case 0x13:
|
||||||
|
parameterWrapper->set(targetModeControllerParameters.blindAvoidStop);
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
parameterWrapper->set(targetModeControllerParameters.blindRotRate);
|
parameterWrapper->set(targetModeControllerParameters.blindRotRate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -466,30 +486,33 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(gsTargetModeControllerParameters.gainNullspace);
|
parameterWrapper->set(gsTargetModeControllerParameters.gainNullspace);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(gsTargetModeControllerParameters.desatMomentumRef);
|
parameterWrapper->set(gsTargetModeControllerParameters.nullspaceSpeed);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.deSatGainFactor);
|
parameterWrapper->setVector(gsTargetModeControllerParameters.desatMomentumRef);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.desatOn);
|
parameterWrapper->set(gsTargetModeControllerParameters.deSatGainFactor);
|
||||||
break;
|
break;
|
||||||
case 0x8:
|
case 0x8:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
|
parameterWrapper->set(gsTargetModeControllerParameters.desatOn);
|
||||||
break;
|
break;
|
||||||
case 0x9:
|
case 0x9:
|
||||||
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
|
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
|
||||||
break;
|
break;
|
||||||
case 0xA:
|
case 0xA:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
|
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
|
||||||
break;
|
break;
|
||||||
case 0xB:
|
case 0xB:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
|
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
|
||||||
break;
|
break;
|
||||||
case 0xC:
|
case 0xC:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
|
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
|
||||||
break;
|
break;
|
||||||
case 0xD:
|
case 0xD:
|
||||||
|
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
|
||||||
|
break;
|
||||||
|
case 0xE:
|
||||||
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
|
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -514,24 +537,30 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(nadirModeControllerParameters.gainNullspace);
|
parameterWrapper->set(nadirModeControllerParameters.gainNullspace);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(nadirModeControllerParameters.desatMomentumRef);
|
parameterWrapper->set(nadirModeControllerParameters.nullspaceSpeed);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor);
|
parameterWrapper->setVector(nadirModeControllerParameters.desatMomentumRef);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->set(nadirModeControllerParameters.desatOn);
|
parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor);
|
||||||
break;
|
break;
|
||||||
case 0x8:
|
case 0x8:
|
||||||
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
|
parameterWrapper->set(nadirModeControllerParameters.desatOn);
|
||||||
break;
|
break;
|
||||||
case 0x9:
|
case 0x9:
|
||||||
parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
|
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
|
||||||
break;
|
break;
|
||||||
case 0xA:
|
case 0xA:
|
||||||
|
parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
|
||||||
|
break;
|
||||||
|
case 0xB:
|
||||||
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
|
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
|
||||||
break;
|
break;
|
||||||
case 0xC:
|
case 0xC:
|
||||||
|
parameterWrapper->setVector(nadirModeControllerParameters.refRotRate);
|
||||||
|
break;
|
||||||
|
case 0xD:
|
||||||
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
|
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -556,21 +585,24 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(inertialModeControllerParameters.gainNullspace);
|
parameterWrapper->set(inertialModeControllerParameters.gainNullspace);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(inertialModeControllerParameters.desatMomentumRef);
|
parameterWrapper->set(inertialModeControllerParameters.nullspaceSpeed);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor);
|
parameterWrapper->setVector(inertialModeControllerParameters.desatMomentumRef);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->set(inertialModeControllerParameters.desatOn);
|
parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor);
|
||||||
break;
|
break;
|
||||||
case 0x8:
|
case 0x8:
|
||||||
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
|
parameterWrapper->set(inertialModeControllerParameters.desatOn);
|
||||||
break;
|
break;
|
||||||
case 0x9:
|
case 0x9:
|
||||||
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
|
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
|
||||||
break;
|
break;
|
||||||
case 0xA:
|
case 0xA:
|
||||||
|
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
|
||||||
|
break;
|
||||||
|
case 0xB:
|
||||||
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
|
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
|
||||||
break;
|
break;
|
||||||
case 0xC:
|
case 0xC:
|
||||||
@ -682,7 +714,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->setMatrix(magnetorquerParameter.inverseAlignment);
|
parameterWrapper->setMatrix(magnetorquerParameter.inverseAlignment);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->set(magnetorquerParameter.dipolMax);
|
parameterWrapper->set(magnetorquerParameter.dipoleMax);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->set(magnetorquerParameter.torqueDuration);
|
parameterWrapper->set(magnetorquerParameter.torqueDuration);
|
||||||
@ -703,7 +735,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(detumbleParameter.omegaDetumbleEnd);
|
parameterWrapper->set(detumbleParameter.omegaDetumbleEnd);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
parameterWrapper->set(detumbleParameter.gainD);
|
parameterWrapper->set(detumbleParameter.gainBdot);
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
parameterWrapper->set(detumbleParameter.gainFull);
|
||||||
|
break;
|
||||||
|
case 0x5:
|
||||||
|
parameterWrapper->set(detumbleParameter.useFullDetumbleLaw);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
|
@ -22,22 +22,27 @@ class AcsParameters : public HasParametersIF {
|
|||||||
} onBoardParams;
|
} onBoardParams;
|
||||||
|
|
||||||
struct InertiaEIVE {
|
struct InertiaEIVE {
|
||||||
double inertiaMatrix[3][3] = {{0.1539829, -0.0001821456, -0.0050135},
|
/* Possible inertia matrices
|
||||||
{-0.0001821456, 0.1701302, 0.0004748963},
|
* 2023-04-14
|
||||||
{-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021
|
* all matrices derived from the CAD model with CAD mass of 8.72 kg
|
||||||
// Possible inertia matrices
|
* all matrices are scaled by final measured mass of 8.756 kg
|
||||||
double inertiaMatrixDeployed[3][3] = {{0.1539829, -0.0001821456, -0.0050135},
|
* all matrices are in [kg m^2]
|
||||||
{-0.0001821456, 0.1701302, 0.0004748963},
|
*/
|
||||||
{-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021
|
double inertiaMatrixDeployed[3][3] = {
|
||||||
double inertiaMatrixUndeployed[3][3] = {{0.122485, -0.0001798426, -0.005008},
|
{0.128333461640235, -0.000151805020803, -0.004178414952517},
|
||||||
{-0.0001798426, 0.162240, 0.000475596},
|
{-0.000151805020803, 0.141791062870050, 0.000395791231451},
|
||||||
{-0.005008, 0.000475596, 0.060136}}; // 19.11.2021
|
{-0.004178414952517, 0.000395791231451, 0.069793610830099}};
|
||||||
double inertiaMatrixPanel1[3][3] = {{0.13823347, -0.0001836122, -0.00501207},
|
double inertiaMatrixUndeployed[3][3] = {
|
||||||
{-0.0001836122, 0.16619787, 0.0083537},
|
{0.102082611845982, -0.000149885620646, -0.004174050971653},
|
||||||
{-0.00501207, 0.0083537, 0.07192588}}; // 19.11.2021
|
{-0.000149885620646, 0.135214836333048, 0.000396374487363},
|
||||||
double inertiaMatrixPanel3[3][3] = {{0.13823487, -0.000178376, -0.005009767},
|
{-0.004174050971653, 0.000396374487363, 0.050118987572848}};
|
||||||
{-0.000178376, 0.166172, -0.007403},
|
double inertiaMatrixPanel1[3][3] = {{0.115207454653725, -0.000153027308288, -0.004177193002842},
|
||||||
{-0.005009767, -0.007403, 0.07195314}};
|
{-0.000153027308288, 0.138513727361148, 0.006962185987503},
|
||||||
|
{-0.004177193002842, 0.006962185987503, 0.059944939352491}};
|
||||||
|
double inertiaMatrixPanel3[3][3] = {
|
||||||
|
{0.115208618832493, -0.000148663333161, -0.004175272921328},
|
||||||
|
{-0.000148663333161, 0.138492171841952, -0.006170020268690},
|
||||||
|
{-0.004175272921328, -0.006170020268690, 0.059967659050454}};
|
||||||
} inertiaEIVE;
|
} inertiaEIVE;
|
||||||
|
|
||||||
struct MgmHandlingParameters {
|
struct MgmHandlingParameters {
|
||||||
@ -72,6 +77,7 @@ class AcsParameters : public HasParametersIF {
|
|||||||
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
|
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
|
||||||
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
|
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
|
||||||
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
|
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
|
||||||
|
float mgmDerivativeFilterWeight = 0.5;
|
||||||
} mgmHandlingParameters;
|
} mgmHandlingParameters;
|
||||||
|
|
||||||
struct SusHandlingParameters {
|
struct SusHandlingParameters {
|
||||||
@ -760,6 +766,7 @@ class AcsParameters : public HasParametersIF {
|
|||||||
{116.975421945286, -5.53022680362263, -5.61081660666997, 0.109754904982136,
|
{116.975421945286, -5.53022680362263, -5.61081660666997, 0.109754904982136,
|
||||||
0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513,
|
0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513,
|
||||||
-0.000889232196185857, -0.00168429567131815}};
|
-0.000889232196185857, -0.00168429567131815}};
|
||||||
|
float susBrightnessThreshold = 0.7;
|
||||||
} susHandlingParameters;
|
} susHandlingParameters;
|
||||||
|
|
||||||
struct GyrHandlingParameters {
|
struct GyrHandlingParameters {
|
||||||
@ -775,11 +782,12 @@ class AcsParameters : public HasParametersIF {
|
|||||||
|
|
||||||
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
|
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
|
||||||
* assumed to be equal for the same class of sensors */
|
* assumed to be equal for the same class of sensors */
|
||||||
float gyr02variance[3] = {pow(3.0e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
float gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||||
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||||
pow(4.3e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
||||||
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
||||||
uint8_t preferAdis = true;
|
uint8_t preferAdis = false;
|
||||||
|
float gyrFilterWeight = 0.6;
|
||||||
} gyrHandlingParameters;
|
} gyrHandlingParameters;
|
||||||
|
|
||||||
struct RwHandlingParameters {
|
struct RwHandlingParameters {
|
||||||
@ -791,6 +799,8 @@ class AcsParameters : public HasParametersIF {
|
|||||||
double stictionTorque = 0.0006;
|
double stictionTorque = 0.0006;
|
||||||
|
|
||||||
uint16_t rampTime = 10;
|
uint16_t rampTime = 10;
|
||||||
|
|
||||||
|
uint32_t multipleRwInvalidTimeout = 25;
|
||||||
} rwHandlingParameters;
|
} rwHandlingParameters;
|
||||||
|
|
||||||
struct RwMatrices {
|
struct RwMatrices {
|
||||||
@ -807,22 +817,23 @@ class AcsParameters : public HasParametersIF {
|
|||||||
{1.0864, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, 0.5432, 1.2797}};
|
{1.0864, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, 0.5432, 1.2797}};
|
||||||
double without4[4][3] = {
|
double without4[4][3] = {
|
||||||
{0.5432, 0.5432, 1.2797}, {0, -1.0864, 0}, {-0.5432, 0.5432, 1.2797}, {0, 0, 0}};
|
{0.5432, 0.5432, 1.2797}, {0, -1.0864, 0}, {-0.5432, 0.5432, 1.2797}, {0, 0, 0}};
|
||||||
double nullspace[4] = {-0.5000, 0.5000, -0.5000, 0.5000};
|
double nullspaceVector[4] = {-1, 1, -1, 1};
|
||||||
} rwMatrices;
|
} rwMatrices;
|
||||||
|
|
||||||
struct SafeModeControllerParameters {
|
struct SafeModeControllerParameters {
|
||||||
double k_rate_mekf = 0.00059437;
|
double k_orthoMekf = 4.4e-3;
|
||||||
double k_align_mekf = 0.000056875;
|
double k_alignMekf = 4.0e-5;
|
||||||
|
double k_parallelMekf = 3.75e-4;
|
||||||
|
|
||||||
double k_rate_no_mekf = 0.00059437;
|
double k_orthoNonMekf = 4.4e-3;
|
||||||
double k_align_no_mekf = 0.000056875;
|
double k_alignNonMekf = 4.0e-5;
|
||||||
|
double k_parallelNonMekf = 3.75e-4;
|
||||||
double sunMagAngleMin = 5 * M_PI / 180;
|
|
||||||
|
|
||||||
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
|
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
|
||||||
double sunTargetDir[3] = {0, 0, 1};
|
double sunTargetDir[3] = {0, 0, 1};
|
||||||
|
|
||||||
double satRateRef[3] = {0, 0, 0};
|
uint8_t useMekf = false;
|
||||||
|
uint8_t dampingDuringEclipse = true;
|
||||||
} safeModeControllerParameters;
|
} safeModeControllerParameters;
|
||||||
|
|
||||||
struct PointingLawParameters {
|
struct PointingLawParameters {
|
||||||
@ -830,7 +841,9 @@ class AcsParameters : public HasParametersIF {
|
|||||||
double om = 0.3;
|
double om = 0.3;
|
||||||
double omMax = 1 * M_PI / 180;
|
double omMax = 1 * M_PI / 180;
|
||||||
double qiMin = 0.1;
|
double qiMin = 0.1;
|
||||||
|
|
||||||
double gainNullspace = 0.01;
|
double gainNullspace = 0.01;
|
||||||
|
double nullspaceSpeed = 32500; // 0.1 RPM
|
||||||
|
|
||||||
double desatMomentumRef[3] = {0, 0, 0};
|
double desatMomentumRef[3] = {0, 0, 0};
|
||||||
double deSatGainFactor = 1000;
|
double deSatGainFactor = 1000;
|
||||||
@ -923,7 +936,7 @@ class AcsParameters : public HasParametersIF {
|
|||||||
double mtq2orientationMatrix[3][3] = {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}};
|
double mtq2orientationMatrix[3][3] = {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}};
|
||||||
double alignmentMatrixMtq[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}};
|
double alignmentMatrixMtq[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}};
|
||||||
double inverseAlignment[3][3] = {{0, -1, 0}, {0, 0, 1}, {-1, 0, 0}};
|
double inverseAlignment[3][3] = {{0, -1, 0}, {0, 0, 1}, {-1, 0, 0}};
|
||||||
double dipolMax = 0.2; // [Am^2]
|
double dipoleMax = 0.2; // [Am^2]
|
||||||
|
|
||||||
uint16_t torqueDuration = 300; // [ms]
|
uint16_t torqueDuration = 300; // [ms]
|
||||||
} magnetorquerParameter;
|
} magnetorquerParameter;
|
||||||
@ -931,8 +944,10 @@ class AcsParameters : public HasParametersIF {
|
|||||||
struct DetumbleParameter {
|
struct DetumbleParameter {
|
||||||
uint8_t detumblecounter = 75; // 30 s
|
uint8_t detumblecounter = 75; // 30 s
|
||||||
double omegaDetumbleStart = 2 * M_PI / 180;
|
double omegaDetumbleStart = 2 * M_PI / 180;
|
||||||
double omegaDetumbleEnd = 0.4 * M_PI / 180;
|
double omegaDetumbleEnd = 1 * M_PI / 180;
|
||||||
double gainD = pow(10.0, -3.3);
|
double gainBdot = pow(10.0, -3.3);
|
||||||
|
double gainFull = pow(10.0, -2.3);
|
||||||
|
uint8_t useFullDetumbleLaw = false;
|
||||||
} detumbleParameter;
|
} detumbleParameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "util/CholeskyDecomposition.h"
|
|
||||||
#include "util/MathOperations.h"
|
|
||||||
|
|
||||||
ActuatorCmd::ActuatorCmd() {}
|
ActuatorCmd::ActuatorCmd() {}
|
||||||
|
|
||||||
ActuatorCmd::~ActuatorCmd() {}
|
ActuatorCmd::~ActuatorCmd() {}
|
||||||
@ -25,24 +20,30 @@ void ActuatorCmd::scalingTorqueRws(double *rwTrq, double maxTorque) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActuatorCmd::cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2,
|
void ActuatorCmd::cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1,
|
||||||
int32_t speedRw3, const double *rwTorque, int32_t *rwCmdSpeed,
|
const int32_t speedRw2, const int32_t speedRw3,
|
||||||
double sampleTime, int32_t maxRwSpeed, double inertiaWheel) {
|
const double sampleTime, const double inertiaWheel,
|
||||||
using namespace Math;
|
const int32_t maxRwSpeed, const double *rwTorque,
|
||||||
|
int32_t *rwCmdSpeed) {
|
||||||
// Calculating the commanded speed in RPM for every reaction wheel
|
// group RW speed values (in 0.1 [RPM]) in vector
|
||||||
int32_t speedRws[4] = {speedRw0, speedRw1, speedRw2, speedRw3};
|
int32_t speedRws[4] = {speedRw0, speedRw1, speedRw2, speedRw3};
|
||||||
|
|
||||||
|
// calculate required RW speed as sum of current RW speed and RW speed delta
|
||||||
|
// delta w_rw = delta t / I_RW * torque_RW [rad/s]
|
||||||
double deltaSpeed[4] = {0, 0, 0, 0};
|
double deltaSpeed[4] = {0, 0, 0, 0};
|
||||||
double radToRpm = 60 / (2 * PI); // factor for conversion to RPM
|
const double factor = sampleTime / inertiaWheel * RAD_PER_SEC_TO_RPM * 10;
|
||||||
// W_RW = Torque_RW / I_RW * delta t [rad/s]
|
|
||||||
double factor = sampleTime / inertiaWheel * radToRpm;
|
|
||||||
int32_t deltaSpeedInt[4] = {0, 0, 0, 0};
|
|
||||||
VectorOperations<double>::mulScalar(rwTorque, factor, deltaSpeed, 4);
|
VectorOperations<double>::mulScalar(rwTorque, factor, deltaSpeed, 4);
|
||||||
|
|
||||||
|
// convert double to int32
|
||||||
|
int32_t deltaSpeedInt[4] = {0, 0, 0, 0};
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
deltaSpeedInt[i] = std::round(deltaSpeed[i]);
|
deltaSpeedInt[i] = std::round(deltaSpeed[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sum of current RW speed and RW speed delta
|
||||||
VectorOperations<int32_t>::add(speedRws, deltaSpeedInt, rwCmdSpeed, 4);
|
VectorOperations<int32_t>::add(speedRws, deltaSpeedInt, rwCmdSpeed, 4);
|
||||||
VectorOperations<int32_t>::mulScalar(rwCmdSpeed, 10, rwCmdSpeed, 4);
|
|
||||||
|
// crop values which would exceed the maximum possible RPM
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
if (rwCmdSpeed[i] > maxRwSpeed) {
|
if (rwCmdSpeed[i] > maxRwSpeed) {
|
||||||
rwCmdSpeed[i] = maxRwSpeed;
|
rwCmdSpeed[i] = maxRwSpeed;
|
||||||
@ -52,24 +53,25 @@ void ActuatorCmd::cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t spee
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator,
|
void ActuatorCmd::cmdDipoleMtq(const double *inverseAlignment, const double maxDipole,
|
||||||
const double *inverseAlignment, double maxDipol) {
|
const double *dipoleMoment, int16_t *dipoleMomentActuator) {
|
||||||
// Convert to actuator frame
|
// convert to actuator frame
|
||||||
double dipolMomentActuatorDouble[3] = {0, 0, 0};
|
double dipoleMomentActuatorDouble[3] = {0, 0, 0};
|
||||||
MatrixOperations<double>::multiply(inverseAlignment, dipolMoment, dipolMomentActuatorDouble, 3, 3,
|
MatrixOperations<double>::multiply(inverseAlignment, dipoleMoment, dipoleMomentActuatorDouble, 3,
|
||||||
1);
|
3, 1);
|
||||||
// Scaling along largest element if dipol exceeds maximum
|
// scaling along largest element if dipole exceeds maximum
|
||||||
uint8_t maxIdx = 0;
|
uint8_t maxIdx = 0;
|
||||||
VectorOperations<double>::maxAbsValue(dipolMomentActuatorDouble, 3, &maxIdx);
|
VectorOperations<double>::maxAbsValue(dipoleMomentActuatorDouble, 3, &maxIdx);
|
||||||
double maxAbsValue = abs(dipolMomentActuatorDouble[maxIdx]);
|
double maxAbsValue = std::abs(dipoleMomentActuatorDouble[maxIdx]);
|
||||||
if (maxAbsValue > maxDipol) {
|
if (maxAbsValue > maxDipole) {
|
||||||
double scalingFactor = maxDipol / maxAbsValue;
|
double scalingFactor = maxDipole / maxAbsValue;
|
||||||
VectorOperations<double>::mulScalar(dipolMomentActuatorDouble, scalingFactor,
|
VectorOperations<double>::mulScalar(dipoleMomentActuatorDouble, scalingFactor,
|
||||||
dipolMomentActuatorDouble, 3);
|
dipoleMomentActuatorDouble, 3);
|
||||||
}
|
}
|
||||||
// scale dipole from 1 Am^2 to 1e^-4 Am^2
|
// scale dipole from 1 Am^2 to 1e^-4 Am^2
|
||||||
VectorOperations<double>::mulScalar(dipolMomentActuatorDouble, 1e4, dipolMomentActuatorDouble, 3);
|
VectorOperations<double>::mulScalar(dipoleMomentActuatorDouble, 1e4, dipoleMomentActuatorDouble,
|
||||||
|
3);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
dipolMomentActuator[i] = std::round(dipolMomentActuatorDouble[i]);
|
dipoleMomentActuator[i] = std::round(dipoleMomentActuatorDouble[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#ifndef ACTUATORCMD_H_
|
#ifndef ACTUATORCMD_H_
|
||||||
#define ACTUATORCMD_H_
|
#define ACTUATORCMD_H_
|
||||||
|
|
||||||
#include "MultiplicativeKalmanFilter.h"
|
#include <cmath>
|
||||||
#include "SensorProcessing.h"
|
|
||||||
#include "SensorValues.h"
|
|
||||||
|
|
||||||
class ActuatorCmd {
|
class ActuatorCmd {
|
||||||
public:
|
public:
|
||||||
@ -19,29 +17,30 @@ class ActuatorCmd {
|
|||||||
void scalingTorqueRws(double *rwTrq, double maxTorque);
|
void scalingTorqueRws(double *rwTrq, double maxTorque);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief: cmdSpeedToRws() will set the maximum possible torque for the reaction
|
* @brief: cmdSpeedToRws() Calculates the RPM for the reaction wheel configuration,
|
||||||
* wheels, also will calculate the needed revolutions per minute for the RWs, which will be given
|
* given the required torque calculated by the controller. Will also scale down the RPM of the
|
||||||
* as Input to the RWs
|
* wheels if they exceed the maximum possible RPM
|
||||||
* @param: rwTrqIn given torque from pointing controller
|
* @param: rwTrq given torque from pointing controller
|
||||||
* rwTrqNS Nullspace torque
|
|
||||||
* rwCmdSpeed output revolutions per minute for every
|
* rwCmdSpeed output revolutions per minute for every
|
||||||
* reaction wheel
|
* reaction wheel
|
||||||
*/
|
*/
|
||||||
void cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2, int32_t speedRw3,
|
void cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2,
|
||||||
const double *rwTorque, int32_t *rwCmdSpeed, double sampleTime,
|
const int32_t speedRw3, const double sampleTime, const double inertiaWheel,
|
||||||
int32_t maxRwSpeed, double inertiaWheel);
|
const int32_t maxRwSpeed, const double *rwTorque, int32_t *rwCmdSpeed);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief: cmdDipolMtq() gives the commanded dipol moment for the magnetorques
|
* @brief: cmdDipoleMtq() gives the commanded dipole moment for the
|
||||||
|
* magnetorquer
|
||||||
*
|
*
|
||||||
* @param: dipolMoment given dipol moment in spacecraft frame
|
* @param: dipoleMoment given dipole moment in spacecraft frame
|
||||||
* dipolMomentActuator resulting dipol moment in actuator reference frame
|
* dipoleMomentActuator resulting dipole moment in actuator reference frame
|
||||||
*/
|
*/
|
||||||
void cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator,
|
void cmdDipoleMtq(const double *inverseAlignment, const double maxDipole,
|
||||||
const double *inverseAlignment, double maxDipol);
|
const double *dipoleMoment, int16_t *dipoleMomentActuator);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
|
static constexpr double RAD_PER_SEC_TO_RPM = 60 / (2 * M_PI);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ACTUATORCMD_H_ */
|
#endif /* ACTUATORCMD_H_ */
|
||||||
|
@ -266,7 +266,8 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
|
|||||||
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guidance::targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double refSatRate[3]) {
|
void Guidance::targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4],
|
||||||
|
double targetSatRotRate[3]) {
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// Calculation of target quaternion to sun
|
// Calculation of target quaternion to sun
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
@ -296,9 +297,8 @@ void Guidance::targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Calculation of reference rotation rate
|
// Calculation of reference rotation rate
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
refSatRate[0] = 0;
|
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
|
||||||
refSatRate[1] = 0;
|
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||||
refSatRate[2] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
|
void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
|
||||||
@ -412,7 +412,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], doubl
|
|||||||
|
|
||||||
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
||||||
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
|
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
|
||||||
double errorQuat[4], double errorSatRotRate[3], double errorAngle) {
|
double errorQuat[4], double errorSatRotRate[3], double &errorAngle) {
|
||||||
// First calculate error quaternion between current and target orientation
|
// First calculate error quaternion between current and target orientation
|
||||||
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat);
|
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat);
|
||||||
// Last calculate add rotation from reference quaternion
|
// Last calculate add rotation from reference quaternion
|
||||||
@ -424,26 +424,17 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do
|
|||||||
// Calculate error angle
|
// Calculate error angle
|
||||||
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
|
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
|
||||||
|
|
||||||
// Only give back error satellite rotational rate if orientation has already been aquired
|
// Calculate error satellite rotational rate
|
||||||
if (errorAngle < 2. / 180. * M_PI) {
|
// First combine the target and reference satellite rotational rates
|
||||||
// First combine the target and reference satellite rotational rates
|
double combinedRefSatRotRate[3] = {0, 0, 0};
|
||||||
double combinedRefSatRotRate[3] = {0, 0, 0};
|
VectorOperations<double>::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3);
|
||||||
VectorOperations<double>::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3);
|
// Then subtract the combined required satellite rotational rates from the actual rate
|
||||||
// Then substract the combined required satellite rotational rates from the actual rate
|
VectorOperations<double>::subtract(currentSatRotRate, combinedRefSatRotRate, errorSatRotRate, 3);
|
||||||
VectorOperations<double>::subtract(currentSatRotRate, combinedRefSatRotRate, errorSatRotRate,
|
|
||||||
3);
|
|
||||||
} else {
|
|
||||||
// If orientation has not been aquired yet set satellite rotational rate to zero
|
|
||||||
errorSatRotRate = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// target flag in matlab, importance, does look like it only gives feedback if pointing control is
|
|
||||||
// under 150 arcsec ??
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
||||||
double targetSatRotRate[3], double errorQuat[4],
|
double targetSatRotRate[3], double errorQuat[4],
|
||||||
double errorSatRotRate[3], double errorAngle) {
|
double errorSatRotRate[3], double &errorAngle) {
|
||||||
// First calculate error quaternion between current and target orientation
|
// First calculate error quaternion between current and target orientation
|
||||||
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat);
|
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat);
|
||||||
// Keep scalar part of quaternion positive
|
// Keep scalar part of quaternion positive
|
||||||
@ -453,17 +444,8 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do
|
|||||||
// Calculate error angle
|
// Calculate error angle
|
||||||
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
|
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
|
||||||
|
|
||||||
// Only give back error satellite rotational rate if orientation has already been aquired
|
// Calculate error satellite rotational rate
|
||||||
if (errorAngle < 2. / 180. * M_PI) {
|
VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3);
|
||||||
// Then substract the combined required satellite rotational rates from the actual rate
|
|
||||||
VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3);
|
|
||||||
} else {
|
|
||||||
// If orientation has not been aquired yet set satellite rotational rate to zero
|
|
||||||
errorSatRotRate = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// target flag in matlab, importance, does look like it only gives feedback if pointing control is
|
|
||||||
// under 150 arcsec ??
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
|
void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
|
||||||
@ -471,20 +453,25 @@ void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double qua
|
|||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// Calculation of target rotation rate
|
// Calculation of target rotation rate
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
double timeElapsed = now.tv_sec + now.tv_usec * pow(10, -6) -
|
double timeElapsed = now.tv_sec + now.tv_usec * 1e-6 -
|
||||||
(timeSavedQuaternion.tv_sec +
|
(timeSavedQuaternion.tv_sec + timeSavedQuaternion.tv_usec * 1e-6);
|
||||||
timeSavedQuaternion.tv_usec * pow((double)timeSavedQuaternion.tv_usec, -6));
|
if (VectorOperations<double>::norm(savedQuaternion, 4) == 0) {
|
||||||
|
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion));
|
||||||
|
}
|
||||||
if (timeElapsed < timeElapsedMax) {
|
if (timeElapsed < timeElapsedMax) {
|
||||||
|
double q[4] = {0, 0, 0, 0}, qS[4] = {0, 0, 0, 0};
|
||||||
|
QuaternionOperations::inverse(quatInertialTarget, q);
|
||||||
|
QuaternionOperations::inverse(savedQuaternion, qS);
|
||||||
double qDiff[4] = {0, 0, 0, 0};
|
double qDiff[4] = {0, 0, 0, 0};
|
||||||
VectorOperations<double>::subtract(quatInertialTarget, savedQuaternion, qDiff, 4);
|
VectorOperations<double>::subtract(q, qS, qDiff, 4);
|
||||||
VectorOperations<double>::mulScalar(qDiff, 1 / timeElapsed, qDiff, 4);
|
VectorOperations<double>::mulScalar(qDiff, 1 / timeElapsed, qDiff, 4);
|
||||||
|
|
||||||
double tgtQuatVec[3] = {quatInertialTarget[0], quatInertialTarget[1], quatInertialTarget[2]},
|
double tgtQuatVec[3] = {q[0], q[1], q[2]};
|
||||||
qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]};
|
double qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]};
|
||||||
double sum1[3] = {0, 0, 0}, sum2[3] = {0, 0, 0}, sum3[3] = {0, 0, 0}, sum[3] = {0, 0, 0};
|
double sum1[3] = {0, 0, 0}, sum2[3] = {0, 0, 0}, sum3[3] = {0, 0, 0}, sum[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::cross(quatInertialTarget, qDiff, sum1);
|
VectorOperations<double>::cross(tgtQuatVec, qDiffVec, sum1);
|
||||||
VectorOperations<double>::mulScalar(tgtQuatVec, qDiff[3], sum2, 3);
|
VectorOperations<double>::mulScalar(tgtQuatVec, qDiff[3], sum2, 3);
|
||||||
VectorOperations<double>::mulScalar(qDiffVec, quatInertialTarget[3], sum3, 3);
|
VectorOperations<double>::mulScalar(qDiffVec, q[3], sum3, 3);
|
||||||
VectorOperations<double>::add(sum1, sum2, sum, 3);
|
VectorOperations<double>::add(sum1, sum2, sum, 3);
|
||||||
VectorOperations<double>::subtract(sum, sum3, sum, 3);
|
VectorOperations<double>::subtract(sum, sum3, sum, 3);
|
||||||
double omegaRefNew[3] = {0, 0, 0};
|
double omegaRefNew[3] = {0, 0, 0};
|
||||||
@ -531,15 +518,11 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
|
|||||||
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double));
|
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else {
|
} else {
|
||||||
// @note: This one takes the normal pseudoInverse of all four raction wheels valid.
|
|
||||||
// Does not make sense, but is implemented that way in MATLAB ?!
|
|
||||||
// Thought: It does not really play a role, because in case there are more then one
|
|
||||||
// reaction wheel invalid the pointing control is destined to fail.
|
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) {
|
void Guidance::getTargetParamsSafe(double sunTargetSafe[3]) {
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
|
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
|
||||||
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
||||||
@ -549,8 +532,6 @@ void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3
|
|||||||
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
|
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
|
||||||
3 * sizeof(double));
|
3 * sizeof(double));
|
||||||
}
|
}
|
||||||
std::memcpy(satRateSafe, acsParameters->safeModeControllerParameters.satRateRef,
|
|
||||||
3 * sizeof(double));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
|
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
|
||||||
|
@ -12,10 +12,10 @@ class Guidance {
|
|||||||
Guidance(AcsParameters *acsParameters_);
|
Guidance(AcsParameters *acsParameters_);
|
||||||
virtual ~Guidance();
|
virtual ~Guidance();
|
||||||
|
|
||||||
void getTargetParamsSafe(double sunTargetSafe[3], double satRateRef[3]);
|
void getTargetParamsSafe(double sunTargetSafe[3]);
|
||||||
ReturnValue_t solarArrayDeploymentComplete();
|
ReturnValue_t solarArrayDeploymentComplete();
|
||||||
|
|
||||||
// Function to get the target quaternion and refence rotation rate from gps position and
|
// Function to get the target quaternion and reference rotation rate from gps position and
|
||||||
// position of the ground station
|
// position of the ground station
|
||||||
void targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3], double sunDirI[3],
|
void targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3], double sunDirI[3],
|
||||||
double refDirB[3], double quatBI[4], double targetQuat[4],
|
double refDirB[3], double quatBI[4], double targetQuat[4],
|
||||||
@ -25,9 +25,10 @@ class Guidance {
|
|||||||
void targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3], double quatIX[4],
|
void targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3], double quatIX[4],
|
||||||
double targetSatRotRate[3]);
|
double targetSatRotRate[3]);
|
||||||
|
|
||||||
// Function to get the target quaternion and refence rotation rate for sun pointing after ground
|
// Function to get the target quaternion and reference rotation rate for sun pointing after ground
|
||||||
// station
|
// station
|
||||||
void targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double refSatRate[3]);
|
void targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4],
|
||||||
|
double targetSatRotRate[3]);
|
||||||
|
|
||||||
// Function to get the target quaternion and refence rotation rate from gps position for Nadir
|
// Function to get the target quaternion and refence rotation rate from gps position for Nadir
|
||||||
// pointing
|
// pointing
|
||||||
@ -37,15 +38,15 @@ class Guidance {
|
|||||||
double targetQuat[4], double refSatRate[3]);
|
double targetQuat[4], double refSatRate[3]);
|
||||||
|
|
||||||
// @note: Calculates the error quaternion between the current orientation and the target
|
// @note: Calculates the error quaternion between the current orientation and the target
|
||||||
// quaternion, considering a reference quaternion. Additionally the difference between the actual
|
// quaternion, considering a reference quaternion. Additionally the difference between the actual
|
||||||
// and a desired satellite rotational rate is calculated, again considering a reference rotational
|
// and a desired satellite rotational rate is calculated, again considering a reference rotational
|
||||||
// rate. Lastly gives back the error angle of the error quaternion.
|
// rate. Lastly gives back the error angle of the error quaternion.
|
||||||
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
||||||
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
|
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
|
||||||
double errorQuat[4], double errorSatRotRate[3], double errorAngle);
|
double errorQuat[4], double errorSatRotRate[3], double &errorAngle);
|
||||||
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
||||||
double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3],
|
double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3],
|
||||||
double errorAngle);
|
double &errorAngle);
|
||||||
|
|
||||||
void targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
|
void targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
|
||||||
double *targetSatRotRate);
|
double *targetSatRotRate);
|
||||||
|
@ -1105,11 +1105,9 @@ void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mek
|
|||||||
{
|
{
|
||||||
PoolReadGuard pg(mekfData);
|
PoolReadGuard pg(mekfData);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
|
std::memcpy(mekfData->quatMekf.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
double zeroVec[3] = {0.0, 0.0, 0.0};
|
|
||||||
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
|
|
||||||
mekfData->quatMekf.setValid(false);
|
mekfData->quatMekf.setValid(false);
|
||||||
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
|
std::memcpy(mekfData->satRotRateMekf.value, ZERO_VEC3, 3 * sizeof(double));
|
||||||
mekfData->satRotRateMekf.setValid(false);
|
mekfData->satRotRateMekf.setValid(false);
|
||||||
mekfData->mekfStatus = mekfStatus;
|
mekfData->mekfStatus = mekfStatus;
|
||||||
mekfData->setValidity(true, false);
|
mekfData->setValidity(true, false);
|
||||||
|
@ -80,6 +80,9 @@ class MultiplicativeKalmanFilter {
|
|||||||
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 9);
|
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 9);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
|
||||||
|
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
/*Parameters*/
|
/*Parameters*/
|
||||||
double quaternion_STR_SB[4];
|
double quaternion_STR_SB[4];
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user