Compare commits

...

266 Commits

Author SHA1 Message Date
d8ec121131 Merge pull request 'preparing v1.43.2' (#575) from prep_v1.43.2 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #575
2023-04-05 18:21:11 +02:00
3e54bc9c3f preparing v1.43.2
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 17:29:09 +02:00
4ca45f348c Merge pull request 'Bug' (#574) from bugfix_syrlinks into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #574
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-05 17:15:17 +02:00
34a0288987 Merge branch 'develop' into bugfix_syrlinks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-05 17:13:20 +02:00
f031c46cb5 ACS Board assy
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-05 17:10:50 +02:00
dbf627cc12 Merge pull request 'Assembly and FDIR updates' (#572) from bugfix_syrlinks into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #572
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-05 17:02:50 +02:00
b06db0a0fc Merge branch 'bugfix_syrlinks' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into bugfix_syrlinks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-05 16:58:40 +02:00
0a68b50ad7 copy and paste fix 2023-04-05 16:58:32 +02:00
b11ed219a2 Merge branch 'develop' into bugfix_syrlinks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:47:53 +02:00
67082a6559 Merge pull request 'No more RW commands during Safe Mode' (#573) from acs-safe-no-rw-cmd into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #573
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-04-05 16:47:19 +02:00
36d5f8fd31 changelog, updates
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:41:49 +02:00
cdba7985ea Merge branch 'develop' into acs-safe-no-rw-cmd
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:26:31 +02:00
38b7593900 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:23:29 +02:00
78cc0fc52d set commanded speed to 0 during off transition 2023-04-05 16:21:38 +02:00
4ed112d019 safe mode controller no longer commands RWs 2023-04-05 16:21:10 +02:00
7549a24f6f same adaption for IMTQ 2023-04-05 16:19:53 +02:00
d53fdf9078 Merge branch 'develop' into bugfix_syrlinks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:09:19 +02:00
67988dad64 Merge pull request 'str assembly mode checks' (#571) from syrlinks_assy_mode_checks into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #571
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-05 16:08:16 +02:00
56c5838d15 str assembly include mode off
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-05 16:06:59 +02:00
2950876ce4 syrlinks ASSY
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:05:05 +02:00
a875bf55b8 Merge branch 'develop' into syrlinks_assy_mode_checks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 15:31:12 +02:00
a28ba4ec66 Merge pull request 'SUS Assembly bug' (#569) from bugfix_sus_assy into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #569
2023-04-05 15:30:12 +02:00
c65b402361 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 15:29:44 +02:00
f5e47c6114 some more mode checks 2023-04-05 15:29:03 +02:00
600921e3a0 some code fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 15:11:37 +02:00
3c38410643 some more tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 15:08:07 +02:00
2e0a685507 overwrite health corrections
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 15:06:41 +02:00
0ade2ae0ee str assembly mode checks
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-05 15:05:32 +02:00
b050047d9a special handling for sus groups
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 14:50:33 +02:00
65c231e92d that was a lot of printouts 2023-04-05 14:46:45 +02:00
5e93282662 seems to work now, but the whole printout crap needs to be removed
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 14:41:34 +02:00
0cabe3a9ea Merge remote-tracking branch 'origin/develop' into bugfix_sus_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 10:29:38 +02:00
845548ed25 maybe that fixes the issues 2023-04-05 10:27:19 +02:00
858c6c301e Merge pull request 'whoops' (#570) from fix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #570
2023-04-05 09:55:20 +02:00
9825a8583f whoops
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 09:45:42 +02:00
babc4f80a8 Merge pull request 'update HK frequencies' (#568) from update_hk_frequencies into develop
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Reviewed-on: #568
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-05 09:21:35 +02:00
3299260653 fix GPS HK enabling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-04 20:59:25 +02:00
a0e531445a Merge remote-tracking branch 'origin/develop' into update_hk_frequencies
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 20:55:50 +02:00
5e854668b5 Merge pull request 'prep next patch release' (#567) from prep_v1.43.1 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #567
2023-04-04 20:45:15 +02:00
52c69f05e6 prep next patch release
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 20:39:13 +02:00
5dd2638241 Merge pull request 'Tweaks Syrlinks HK' (#565) from tweak_syrlinks_hk into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #565
2023-04-04 20:37:53 +02:00
c835b31e7f minor fix
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-04 20:36:52 +02:00
57b41701ce hopefully those were the last fixes
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-04 20:34:28 +02:00
69bbe4ea39 update HK frequencies
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 19:18:53 +02:00
f2a2c73984 Merge remote-tracking branch 'origin/develop' into tweak_syrlinks_hk
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 18:53:14 +02:00
85cf95d6bb Merge pull request 'Feature: Set health overrides' (#563) from feature_set_health_overrides into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #563
2023-04-04 18:52:06 +02:00
08d83c158a Merge pull request 'wrong logic' (#566) from bugfix_gps_fdir into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #566
2023-04-04 18:51:50 +02:00
b0e65867ee wrong logic
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 18:51:09 +02:00
106cb1ab35 Merge branch 'develop' into feature_set_health_overrides
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 18:39:54 +02:00
a06d90daad remove duplicate code
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 18:29:07 +02:00
3cc48a4cea annoying
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 18:21:30 +02:00
04178b8831 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 18:04:09 +02:00
28882cc359 Merge pull request 'fancy GPS fdir' (#562) from fancy_gps_fdir into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #562
2023-04-04 18:02:54 +02:00
c9bd922711 Merge remote-tracking branch 'origin/develop' into tweak_syrlinks_hk
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 18:02:29 +02:00
94c736d143 Merge branch 'develop' into fancy_gps_fdir
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 18:00:36 +02:00
c4516f53b8 another include fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-04 17:57:07 +02:00
f39981deca include fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-04 17:55:57 +02:00
fd8317acd7 Merge remote-tracking branch 'origin/develop' into feature_set_health_overrides
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-04 17:54:43 +02:00
7df3308717 Merge pull request 'TCS Sanity Range' (#564) from tcs_sanity_range_check into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #564
2023-04-04 17:53:44 +02:00
a76074acf5 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 17:53:38 +02:00
697dcab345 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 17:52:03 +02:00
104a8cab33 seems to work now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-04 17:49:01 +02:00
8d4b980c32 this should fix some bugs 2023-04-04 16:46:07 +02:00
677457bbe7 syrlinks HK tweaks
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-04 15:59:45 +02:00
908927ed9f some fixes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 15:09:51 +02:00
4a287344f4 add sanity range check
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-04 15:02:56 +02:00
ae0413f7f6 clean up code structure a bit
Some checks failed
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-04 14:52:22 +02:00
01081cbb29 set health overrides
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-04 14:45:09 +02:00
1d82977ca2 clean up
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-04 14:29:05 +02:00
bc7bdfe1fe Merge pull request 'inititalize loop indexes' (#561) from tcs_bugfix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #561
2023-04-04 14:26:00 +02:00
38a0c14940 inititalize loop indexes
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-04 14:24:57 +02:00
3941770378 fancy GPS fdir
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-04 14:20:27 +02:00
e10359077c finally works
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-04 14:01:13 +02:00
8d1db69e0d annoying 2023-04-04 13:48:50 +02:00
8a2137d5d3 another test 2023-04-04 13:46:21 +02:00
e47ba65550 another test 2023-04-04 13:45:12 +02:00
143fb44037 try something 2023-04-04 13:41:55 +02:00
18994f5e65 Merge pull request 'prep v1.43.0' (#560) from prep_v1.43.0 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #560
2023-04-04 13:33:06 +02:00
39a3b4aa6f prep v1.43.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 13:32:41 +02:00
2b18ab1504 Merge pull request 'Bugfixes ans tweaks for STR' (#559) from bugfixes_tweaks_str into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #559
2023-04-04 11:22:49 +02:00
83e0627548 Merge remote-tracking branch 'origin/develop' into bugfixes_tweaks_str
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 11:22:07 +02:00
152a3c20cf bump submodules
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 11:20:03 +02:00
9e8880c2c5 Merge remote-tracking branch 'origin/develop' into bugfixes_tweaks_str 2023-04-04 11:19:34 +02:00
ed8623259e Merge pull request 'Feature: 3V3 stack power switching' (#556) from feature_3v3_stack_switching into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #556
2023-04-04 11:18:57 +02:00
69a3cb20be Merge remote-tracking branch 'origin/develop' into feature_3v3_stack_switching
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-04 11:18:45 +02:00
01b98ca091 Merge pull request 'tweaks' (#558) from single_store_tweak_fsfw into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #558
2023-04-04 11:15:49 +02:00
0cd246182d bump fsfw
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-04 01:52:34 +02:00
9270165bf8 fix STR bugs and improve code
- Reset reply size after returning a reply
- Reset data link layer and flush RX for regular commands and before
  performing special commands to ensure consistent start state
- Clean up DHB a bit
- Set STR dev to OFF in assembly when it is faulty.
2023-04-04 01:35:05 +02:00
9aedc36e4d tweaks
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
- Bump fsfw: O_SYNC flag on UioMapper
- Reduce delay for single TM store task to 2 ms
2023-04-03 21:57:48 +02:00
f5588e9c62 Merge remote-tracking branch 'origin/develop' into feature_3v3_stack_switching
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 19:58:35 +02:00
afbab6d3f2 Merge pull request 'Bugfix for GPS health devices' (#555) from bugfix_gps_health_dev_connect_parent into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #555
2023-04-03 19:57:50 +02:00
6d0bd88cd9 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-03 19:57:16 +02:00
23af9685d6 bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-03 19:15:14 +02:00
a26d71f745 i hate this crap
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-03 19:04:21 +02:00
8404ce237b something is wrong now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-03 18:54:47 +02:00
1610bdecf9 connect parent
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-03 18:02:45 +02:00
53c88f85d5 changelog update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 16:58:48 +02:00
ac514d9c19 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-03 16:57:12 +02:00
e6f0695e1e bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-03 16:55:37 +02:00
6b37d292c6 add 3v3 stack switching
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-03 16:25:32 +02:00
e3677f89fe Merge pull request 'IMTQ: Lower Integration Time' (#552) from imtq_lower_integration_time into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #552
2023-04-03 15:43:30 +02:00
5267bfcd82 Merge remote-tracking branch 'origin/develop' into imtq_lower_integration_time
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-03 15:34:51 +02:00
99eae0df51 update changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-03 15:31:46 +02:00
73e2508025 Merge pull request 'remove double lock' (#554) from bugfix_axi_ptme_lock into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #554
2023-04-03 15:30:36 +02:00
1b2dd12e61 remove double lock
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-03 15:29:18 +02:00
8585114041 missing state check
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-03 15:27:06 +02:00
c4f62842ab Merge remote-tracking branch 'origin/develop' into imtq_lower_integration_time
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 15:21:00 +02:00
800ab7e87f Merge pull request 'disable some printouts' (#553) from tweaks_tcs into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #553
2023-04-03 15:20:32 +02:00
11d9871c0a disable some printouts
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2023-04-03 15:20:11 +02:00
958abadd65 somethings buggy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 15:16:53 +02:00
fba856a9a9 Merge branch 'develop' into imtq_lower_integration_time
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 15:13:00 +02:00
bc582abcb3 Merge pull request 'Thermal Controller Update' (#399) from thermal_controller into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #399
2023-04-03 15:12:48 +02:00
ba7a2c3ece Merge branch 'develop' into thermal_controller
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-03 15:12:30 +02:00
a8a0299b46 some adaptions, heater to off seems to work
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 14:38:00 +02:00
f4b47a24c0 adaptions for EM build
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 14:22:58 +02:00
e9c5bfe324 event spam has stopped
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 14:09:54 +02:00
5dcafa1de0 lower integration time
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-03 10:12:19 +02:00
7522eac9eb done 2023-04-02 23:43:41 +02:00
847e3bb51d prep imtq startup handling 2023-04-02 20:12:24 +02:00
020dfa8278 Merge pull request 'add compatible firmware' (#551) from ptme_poll_threshold_register into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #551
2023-04-02 15:52:29 +02:00
389b77a092 Merge branch 'develop' into ptme_poll_threshold_register
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-02 15:52:17 +02:00
a31f8c934a add compatible firmware
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-04-02 15:51:55 +02:00
685a4caace Merge pull request 'add SW IF for manipulating poll threshold' (#550) from ptme_poll_threshold_register into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #550
2023-04-02 15:35:39 +02:00
9360dad028 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-02 15:34:52 +02:00
8eac0b5ebd changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-02 15:33:49 +02:00
703eaaa9aa poll threshold param cmd handling
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-02 15:32:04 +02:00
cab55c79dc add SW IF for manipulating poll threshold
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-02 14:22:52 +02:00
62952b89b1 Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-01 16:00:15 +02:00
b205fb5269 bump changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-01 15:55:37 +02:00
959f37f25a changelog format fix 2023-04-01 15:55:23 +02:00
789b0ff7ae Merge pull request 'prep v1.42.0' (#549) from prep_v1.42.0 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #549
2023-04-01 15:40:45 +02:00
601318d7eb prep v1.42.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-01 15:33:02 +02:00
87d622c82c Merge pull request 'STR tweaks parameter update' (#544) from str_tweaks_param_update into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #544
2023-04-01 15:23:43 +02:00
fc43627abb Merge branch 'develop' into str_tweaks_param_update 2023-04-01 15:23:33 +02:00
0878f3882a Merge pull request 'reduced HK rollover' (#547) from tweak_reduced_hk_rollover into develop
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
Reviewed-on: #547
2023-04-01 15:23:03 +02:00
6a8ddf96b8 Merge branch 'develop' into tweak_reduced_hk_rollover 2023-04-01 15:22:54 +02:00
6a2f569fc3 Merge pull request 'Double GomSpace polling frequency' (#548) from tweak_poll_gs_devs_more_often into develop
Reviewed-on: #548
2023-04-01 15:22:40 +02:00
d2f11b1860 Merge branch 'develop' into str_tweaks_param_update
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-01 15:20:52 +02:00
cf8dc9ed7d reduced HK rollover
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-01 15:07:47 +02:00
f65cf23391 dobule GS polling frequency
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-01 15:07:04 +02:00
b4c6965d9e poll GS devices more often 2023-04-01 15:06:21 +02:00
78d39a3760 Merge pull request 'filename fixes scex' (#546) from scex_filename_fixes into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #546
2023-04-01 15:05:04 +02:00
b58fc90879 important correction
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-01 14:40:34 +02:00
2386944ed8 removed unused code
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-01 14:32:41 +02:00
409631fb0a filename fixes scex
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-01 14:23:11 +02:00
13b8f9b1ec Merge remote-tracking branch 'origin/develop' into str_tweaks_param_update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-01 13:43:59 +02:00
d0f641abe0 Merge pull request 'Possible Bugfix for Duallane Swichting' (#545) from possible_bugfix_duallane_power_switching into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #545
2023-04-01 13:43:36 +02:00
9b5fc8995c changelog 2023-04-01 13:43:24 +02:00
23a4b08709 seems to work, improve dummy PCDU handler
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 23:41:30 +02:00
d1775a52aa Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 19:18:05 +02:00
ff6ad60eed changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 19:16:57 +02:00
95d220c304 docs
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 19:15:54 +02:00
65989261b0 that should fix the issue
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 19:14:42 +02:00
e365e03c2a possible bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 19:00:37 +02:00
da36160f6e returncode check
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 18:52:35 +02:00
3f8603967c param update STR
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-03-31 18:51:16 +02:00
013692cc41 Merge pull request 'PAPB multi-byte write support' (#543) from papb_multi_byte_write_support into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #543
2023-03-31 18:37:13 +02:00
2f9de8c36e some tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 17:41:01 +02:00
fcf3437410 some more tweaks 2023-03-31 17:39:13 +02:00
f51656a813 add back volatile keyword
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-31 17:36:49 +02:00
bb7a616283 some minor tweaks
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-31 17:35:53 +02:00
028f94a2f7 Merge remote-tracking branch 'origin/develop' into papb_multi_byte_write_support
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-31 17:34:35 +02:00
62ba7a1f80 Merge remote-tracking branch 'origin/develop' into papb_multi_byte_write_support
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 17:29:10 +02:00
9d42bb87d9 Merge pull request 'PTME rework reset handling' (#542) from ptme_rework_reset_handling into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #542
2023-03-31 17:26:52 +02:00
6c8eeeab31 init result
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 17:12:11 +02:00
f16d92c1b1 some more lock handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 17:05:01 +02:00
55a22c840c PTME_LOCK atomic boolean and related handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 16:51:30 +02:00
caa7c20adf tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 15:12:05 +02:00
6ee3fe2eef changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 13:22:07 +02:00
76ea3f7979 compile fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-31 13:21:38 +02:00
3871c8b8de change layering
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-31 13:17:15 +02:00
e0f94039b4 found some bugs
Some checks failed
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-31 12:47:55 +02:00
a1380a6e3a syrlinks bugfix
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-03-31 12:11:55 +02:00
795486ae6c trying to find out whats wrong 2023-03-31 12:11:31 +02:00
4b1221ab99 modes for VC/stores 2023-03-31 01:14:59 +02:00
f6f4db525c read reg instead of polling GPIO 2023-03-30 23:52:37 +02:00
a6e24485e2 Merge pull request 'done' (#541) from refactor_fix_duallane_fdirs into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #541
2023-03-30 17:23:14 +02:00
74a38dc76b re-run generators
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-30 17:22:28 +02:00
5f6f85a778 done
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-03-30 17:16:59 +02:00
6426142039 Merge pull request 'minor tweak for device handler' (#540) from scex_minor_tweak into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #540
2023-03-30 13:41:54 +02:00
1541376701 minor tweak for device handler
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-30 13:41:14 +02:00
27370fcd44 multi byte write support but does not work..
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-03-30 13:36:44 +02:00
770fee0097 some minor tweaks 2023-03-29 17:38:38 +02:00
5903b3ef60 Merge pull request 'SCEX update' (#538) from tweaks_scex_filenames into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #538
2023-03-29 17:37:06 +02:00
0bf4527e94 Merge branch 'develop' into tweaks_scex_filenames
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-29 13:39:46 +02:00
f695115102 Merge pull request 'move STR assy' (#539) from move_str_assy into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #539
2023-03-29 12:42:55 +02:00
a72805d137 move STR assy
Some checks are pending
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-29 11:44:13 +02:00
b7c17fdf0f scex update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-29 11:41:42 +02:00
def7eca2f2 cleaning up a bit
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-28 19:38:02 +02:00
520b41c53b transition basic mode handling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-28 17:21:43 +02:00
28d7dcf177 Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-28 16:37:09 +02:00
36d7852c1d changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-28 16:35:49 +02:00
5c97020087 small change
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-28 15:11:21 +02:00
861bee8083 Merge branch 'develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-26 16:58:30 +02:00
3e7901f060 Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-26 16:52:39 +02:00
0301c18af2 resolve some merge conflicts
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-24 21:20:27 +01:00
f71972609c Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-24 21:15:29 +01:00
9c8fc84053 Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-21 23:44:25 +01:00
2153294e6f EM build working now
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-21 15:17:31 +01:00
0fdc79df5e Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-21 14:55:55 +01:00
0e5a3a2f6c update changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-21 14:46:07 +01:00
b81618344e update eive system FDIR
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-21 14:38:10 +01:00
d85ddcdbff Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-21 14:18:57 +01:00
092e9fa508 bump deps 2023-03-21 14:18:32 +01:00
ba9cf5d79d small changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-18 18:03:59 +01:00
4871479ed5 fixes for q7s build
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-18 11:17:24 +01:00
eb46841237 update thermal controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-17 17:40:11 +01:00
d44142ac26 Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-17 17:36:51 +01:00
f7be8ea63c use supervisor fdir
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
controls the power switch
2023-03-16 19:10:05 +01:00
3c6eb265c7 PLOC SUPV dummy has switch now
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-16 18:52:32 +01:00
b1d2f73b01 move Switches enum
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-16 18:47:51 +01:00
eda1f7e212 syrlinks event works
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-16 18:28:51 +01:00
56a4378a63 that should be transition safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-16 18:05:23 +01:00
a16671762d Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-16 17:48:17 +01:00
350ed59033 handle syrlinks overheating in COM SS
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 17:13:25 +01:00
096253a9a3 Merge branch 'feature_scheduling_tweaks' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 16:25:13 +01:00
11e5866f31 added some defines
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 16:24:46 +01:00
9b8092fb09 this seems to work
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 16:24:01 +01:00
f546df50a1 Merge branch 'feature_boot_sequence_eive_sys' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 16:21:14 +01:00
8201a4140a works better now
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 16:19:37 +01:00
364342855d maybe force a mode command?
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 15:52:20 +01:00
c688a51838 Merge remote-tracking branch 'origin/feature_boot_sequence_eive_sys' into thermal_controller 2023-03-15 15:52:14 +01:00
715a69db89 this should cover upper bound checking when heater is off
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 15:43:20 +01:00
dc44af5b29 copy and paste error
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 15:20:47 +01:00
27f29eda40 small error
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 15:16:12 +01:00
50a62b9243 sth broke..
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 15:13:53 +01:00
da7c450e06 most temps should be valid now
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 15:00:06 +01:00
a92fa31cb5 better variable names, tweaks for less init events
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 14:56:26 +01:00
d273621419 some tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 14:36:18 +01:00
64ec76bfb7 Merge branch 'develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-15 14:14:56 +01:00
69525b6fd1 bump fsfw
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-15 14:10:53 +01:00
c1d8eda2c7 Merge remote-tracking branch 'origin/develop' into thermal_controller 2023-03-15 14:10:36 +01:00
8b11302028 unittest works again
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-14 20:35:49 +01:00
c1b4a1c164 Merge branch 'thermal_controller' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-14 20:04:03 +01:00
58212d7081 Merge remote-tracking branch 'origin/develop' into thermal_controller 2023-03-14 20:04:00 +01:00
a6e6ee053d Merge branch 'develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-14 20:03:29 +01:00
e82777479b Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-14 18:50:28 +01:00
a51a680396 Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-14 15:34:25 +01:00
d3bf70243b Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-14 14:25:35 +01:00
4392598a67 Merge remote-tracking branch 'origin/develop' into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-14 14:16:59 +01:00
26a9dce0a0 basic implementation for passive cooling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-13 17:36:41 +01:00
9d1d62aee0 bump fsfw
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-13 16:02:24 +01:00
bf2d97bd60 continue thermal controller overheating
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-13 15:59:19 +01:00
721a01409e Merge branch 'thermal_controller' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into thermal_controller
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-13 13:28:02 +01:00
a0d6552781 . 2023-03-13 13:27:36 +01:00
c709b2a526 Merge branch 'develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-13 13:01:31 +01:00
5793d73ff6 printouts
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-13 12:53:40 +01:00
c63b13fc40 overheating
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 16:53:48 +01:00
224a3af6f8 Merge remote-tracking branch 'origin/develop' into thermal_controller 2023-03-09 16:09:01 +01:00
131c508cae position heaterTransitionControl()
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 09:37:10 +01:00
7a62624687 changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 15:56:05 +01:00
337717d271 Merge branch 'thermal_controller' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 14:35:04 +01:00
9c77703ada Merge branch 'develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-05 16:19:59 +01:00
718d067b40 small 2023-03-05 13:27:42 +01:00
37b540fd48 switch
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
Transition
2023-03-05 13:05:32 +01:00
88db78fed9 Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-28 19:17:45 +01:00
5f3bd5c754 Merge branch 'thermal_controller' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 13:46:14 +01:00
63275df3f0 formal changes 2023-02-24 13:39:23 +01:00
d6f537da5f Merge remote-tracking branch 'origin/develop' into thermal_controller
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 15:58:10 +01:00
9a7779cffb struct heaterStates and more
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 21:46:56 +01:00
0fa1bab94d comments
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-22 19:14:35 +01:00
29179bde0c merge conflicts
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-22 18:01:54 +01:00
b9a6425078 dummy change
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-22 17:50:03 +01:00
e13636167f limit for error events thermalcontroller + dummy beta
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-22 17:30:30 +01:00
9b849d10e9 small changes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 17:49:55 +01:00
77b7433caf enum ThermalComponents
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-10 12:18:16 +01:00
150 changed files with 3202 additions and 1660 deletions

1
.idea/cmake.xml generated
View File

@ -2,7 +2,6 @@
<project version="4">
<component name="CMakeSharedSettings">
<configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" NO_GENERATOR="true" />
<configuration PROFILE_NAME="Debug Q7S" ENABLED="true" CONFIG_NAME="Debug" TOOLCHAIN_NAME="Q7S" GENERATION_OPTIONS="-DTGT_BSP=&quot;arm/q7s&quot;" NO_GENERATOR="true">
<ADDITIONAL_GENERATION_ENVIRONMENT>
<envs>

View File

@ -16,10 +16,109 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v1.43.2] 2023-04-05
## Changed
- Adapted HK data rates to new table for LEOP SAFE mode.
- GPS controller HK is now generated periodically as well.
- Better mode combination checks for assembly components. This includes:
- IMTQ assembly
- Syrlinks assembly
- Dual Lane Assembly
- RWs are no longer commanded by the ACS Controller during safe mode. Instead the RW speed command
is set to 0 as part or the `doShutDown` of the RW handler.
## Fixed
- Dual lane assemblies: Fix handling when health states are overwritten. Also add better handling
when some devices are permanent faulty and some are only faulty. In that case, only the faulty
devices will be restored.
- ACS dual lane assembly: Gyro 3 helper mode was assigned to the Gyro 2 mode.
# [v1.43.1] 2023-04-04
## Fixed
- Generic HK handling: Bug where HKs were generated a lot more often than required. This is the case
if a device handler `PERFORM_OPERATION` step is performed more than once per PST cycle.
- Syrlinks now goes to `_MODE_TO_ON` when finishing the `doStartUp` transition.
## Changed
- Doubled GS PST interval instead of scheduling everything twice.
- Syrlinks now only has one `PERFORM_OPERATION` step, but still has two communication steps.
- PCDU components only allow setting `NEEDS_RECOVERY`, `HEALTHY` and `EXTERNAL_CONTROL` health
states now. TMP sensor components only allow `HEALTHY` , `EXTERNAL_CONTROL`, `FAULTY` and
`PERMANENT_FAULTY`.
- TCS controller now does a sanity check on the temperature values: Values below -80 C or above
160 C are ignored.
# [v1.43.0] 2023-04-04
- q7s-package: v2.4.0
- eive-tmtc: v2.21.0
## Added
- Version of thermal controller which performs basic control tasks.
- PCDU handler can now command switch of the 3V3 stack (switch ID 19)
- Set STR dev to OFF in assembly when it is faulty.
- STR: Reset data link layer and flush RX for regular commands and before performing special
commands to ensure consistent start state
## Fixed
- PTME was not reset after configuration changes.
- GPS health devices: ACS board assembly not reacts to health changes.
- STR COM helper: Reset reply size after returning a reply
## Changed
- Poll threshold configuration of the PTME IP core is now configurable via a parameter command
and is set to 0b010 (4 polls) instead of 0b001 (1 poll) per default.
- EIVE system fallback and COM system fallback: Perform general subsystem handling first, then
event reception, and finally any new transition handling.
- IMTQ MGM integration time lowered to 6 ms. This relaxes scheduling requirements a bit.
- PCDU handler switcher HK set now has additional 3V3 switcher state HK.
# [v1.42.0] 2023-04-01
- eive-tmtc: v2.20.1
- q7s-package: v2.3.0
## Changed
- SCEX filename updates. Also use T as the file ID / date separator between date and time.
- COM TM store and dump handling: Introduce modes for all 4 TM VC/store tasks. The OFF mode can be
used to disable ongoing dumps or to prevent writes to the PTME VC. This allows cleaner reset
handling of the PTME. All 4 VC/store tasks were attached to the COM mode tree and are commanded
as part of the COM sequence as well to ensure consistent state with the CCSDS IP core handler.
- Added `PTME_LOCKED` boolean lock which is used to lock the PTME so it is not used by the VC tasks
anymore. This lock will be controlled by the CCSDS IP core handler and is locked when the PTME
needs to be reset. Examples for this are datarate changes.
- Simulate real PCDU in PCDU dummy by remembering commandes switch change and triggering appropriate
events. Switch feedback is still immediate.
- GomSpace devices are polled with a doubled frequency. This speeds up power switch commanding.
## Fixed
- Bugfix for side lane transitions of the dual lane assemblies, which only worked when the
assembly was directly commanded.
- Syrlinks Handler: Bugfix so transition command is only sent once.
- SCEX file name bug: Create file name time stamp with `strftime` similarly to how it's done
for the persistent TM store.
## Added
- Added GPS0 and GPS1 health device which are used by the ACS board assembly when deciding whether
to change to the other side or to go to dual side directly. Setting the health devices to faulty
should also trigger a side switch or a switch to dual mode.
# [v1.41.0] 2023-03-28
eive-tmtc: v2.20.0
q7s-package: v2.2.0
- eive-tmtc: v2.20.0
- q7s-package: v2.2.0
## Fixed

View File

@ -10,8 +10,8 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 1)
set(OBSW_VERSION_MINOR 41)
set(OBSW_VERSION_REVISION 0)
set(OBSW_VERSION_MINOR 43)
set(OBSW_VERSION_REVISION 2)
# set(CMAKE_VERBOSE TRUE)
@ -113,7 +113,7 @@ set(OBSW_ADD_TCS_CTRL
1
CACHE STRING "Add TCS controllers")
set(OBSW_ADD_HEATERS
${INIT_VAL}
1
CACHE STRING "Add TCS heaters")
set(OBSW_ADD_PLOC_SUPERVISOR
${INIT_VAL}
@ -486,7 +486,8 @@ endif()
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_FSFW_NAME}
${LIB_OS_NAME})
target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_FSFW_NAME} ${LIB_JSON_NAME})
target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_EIVE_MISSION}
${LIB_FSFW_NAME} ${LIB_JSON_NAME})
target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_EIVE_MISSION} ${LIB_DUMMIES})

View File

@ -11,6 +11,7 @@
#include "../mission/utility/DummySdCardManager.h"
#include "OBSWConfig.h"
#include "fsfw/platform.h"
#include "fsfw/power/PowerSwitchIF.h"
#include "fsfw_tests/integration/task/TestTask.h"
#if OBSW_ADD_TMTC_UDP_SERVER == 1
@ -29,7 +30,7 @@
#include <dummies/AcuDummy.h>
#include <dummies/CoreControllerDummy.h>
#include "dummies/helpers.h"
#include "dummies/helperFactory.h"
#ifdef PLATFORM_UNIX
#include <fsfw_hal/linux/serial/SerialComIF.h>
@ -67,6 +68,12 @@ void ObjectFactory::produce(void* args) {
auto* dummyGpioIF = new DummyGpioIF();
auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0);
std::vector<ReturnValue_t> switcherList;
auto initVal = PowerSwitchIF::SWITCH_OFF;
for (unsigned i = 0; i < 18; i++) {
switcherList.emplace_back(initVal);
}
dummySwitcher->setInitialSwitcherList(switcherList);
#ifdef PLATFORM_UNIX
new SerialComIF(objects::UART_COM_IF);
#if OBSW_ADD_PLOC_MPSOC == 1

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 283 translations.
* @brief Auto-generated event translation file. Contains 284 translations.
* @details
* Generated on: 2023-03-28 22:20:01
* Generated on: 2023-04-04 13:59:07
*/
#include "translateEvents.h"
@ -209,11 +209,11 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE";
const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED";
const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY";
const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900";
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901";
const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING =
"SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
@ -270,10 +270,10 @@ const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
const char *PLOC_OVERHEATING_STRING = "PLOC_OVERHEATING";
const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *HPA_OVERHEATING_STRING = "HPA_OVERHEATING";
const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_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 *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
@ -700,6 +700,8 @@ const char *translateEvents(Event event) {
return POWER_STATE_MACHINE_TIMEOUT_STRING;
case (12803):
return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING;
case (12804):
return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING;
case (12900):
return TRANSITION_OTHER_SIDE_FAILED_12900_STRING;
case (12901):
@ -820,14 +822,14 @@ const char *translateEvents(Event event) {
return NO_HEALTHY_HEATER_AVAILABLE_STRING;
case (14102):
return SYRLINKS_OVERHEATING_STRING;
case (14103):
return PLOC_OVERHEATING_STRING;
case (14104):
return OBC_OVERHEATING_STRING;
case (14105):
return HPA_OVERHEATING_STRING;
return CAMERA_OVERHEATING_STRING;
case (14106):
return PLPCDU_OVERHEATING_STRING;
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 169 translations.
* Generated on: 2023-03-28 22:20:01
* Contains 171 translations.
* Generated on: 2023-04-04 13:59:07
*/
#include "translateObjects.h"
@ -38,6 +38,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV";
const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV";
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
@ -242,6 +244,10 @@ const char *translateObject(object_id_t object) {
return STAR_TRACKER_STRING;
case 0x44130045:
return GPS_CONTROLLER_STRING;
case 0x44130046:
return GPS_0_HEALTH_DEV_STRING;
case 0x44130047:
return GPS_1_HEALTH_DEV_STRING;
case 0x44140013:
return IMTQ_POLLING_STRING;
case 0x44140014:

View File

@ -156,6 +156,10 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
}
result = thermalTask->addComponent(objects::HEATER_HANDLER);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
}
FixedTimeslotTaskIF* pstTask = factory->createFixedTimeslotTask(
"DUMMY_PST", 75, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc);
@ -193,7 +197,8 @@ void scheduling::initTasks() {
#endif /* OBSW_ADD_TEST_CODE == 1 */
PeriodicTaskIF* dummyTask = factory->createPeriodicTask(
"DUMMY_TASK", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc);
"DUMMY_TASK", 35, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
dummyTask->addComponent(objects::THERMAL_TEMP_INSERTER);
scheduling::scheduleTmpTempSensors(dummyTask);
scheduling::scheduleRtdSensors(dummyTask);
dummyTask->addComponent(objects::SUS_0_N_LOC_XFYFZM_PT_XF);

View File

@ -138,7 +138,7 @@ ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &local
localDataPoolMap.emplace(core::TEMPERATURE, &tempPoolEntry);
localDataPoolMap.emplace(core::PS_VOLTAGE, &psVoltageEntry);
localDataPoolMap.emplace(core::PL_VOLTAGE, &plVoltageEntry);
poolManager.subscribeForRegularPeriodicPacket({hkSet.getSid(), enableHkSet, 12.0});
poolManager.subscribeForRegularPeriodicPacket({hkSet.getSid(), enableHkSet, 60.0});
return returnvalue::OK;
}

View File

@ -1,5 +1,6 @@
#include "ObjectFactory.h"
#include <fsfw/devicehandlers/HealthDevice.h>
#include <fsfw/subsystem/Subsystem.h>
#include <linux/acs/AcsBoardPolling.h>
#include <linux/acs/GpsHyperionLinuxController.h>
@ -19,15 +20,15 @@
#include <mission/acs/MgmRm3100CustomHandler.h>
#include <mission/acs/str/StarTrackerHandler.h>
#include <mission/acs/str/strHelpers.h>
#include <mission/com/LiveTmTask.h>
#include <mission/com/PersistentLogTmStoreTask.h>
#include <mission/com/PersistentSingleTmStoreTask.h>
#include <mission/power/CspCookie.h>
#include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/fdir/StrFdir.h>
#include <mission/system/acs/StrAssembly.h>
#include <mission/system/acs/StrFdir.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/StrAssembly.h>
#include <mission/system/objects/SyrlinksAssembly.h>
#include <mission/tmtc/LiveTmTask.h>
#include <mission/tmtc/PersistentLogTmStoreTask.h>
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
#include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h"
@ -61,9 +62,9 @@
#include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/SyrlinksFdir.h"
#include "mission/system/com/comModeTree.h"
#include "mission/system/fdir/GomspacePowerFdir.h"
#include "mission/system/fdir/RtdFdir.h"
#include "mission/system/objects/TcsBoardAssembly.h"
#include "mission/system/power/GomspacePowerFdir.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tmtc/tmFilters.h"
@ -80,6 +81,7 @@ using gpio::Levels;
#include <mission/acs/ImtqHandler.h>
#include <mission/acs/rwHelpers.h>
#include <mission/com/SyrlinksHandler.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/payload/PayloadPcduHandler.h>
#include <mission/payload/RadiationSensorHandler.h>
#include <mission/payload/payloadPcduDefinitions.h>
@ -95,7 +97,6 @@ using gpio::Levels;
#include <mission/tcs/Max31865Definitions.h>
#include <mission/tcs/Max31865PT1000Handler.h>
#include <mission/tcs/Tmp1075Handler.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include <sstream>
@ -124,6 +125,7 @@ using gpio::Levels;
ResetArgs RESET_ARGS_GNSS;
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
std::atomic_bool PTME_LOCKED = false;
std::atomic_uint16_t I2C_FATAL_ERRORS = 0;
void Factory::setStaticFrameworkObjectIds() {
@ -358,7 +360,8 @@ void ObjectFactory::createAcsBoardGpios(GpioCookie& cookie) {
}
void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF,
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher) {
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher,
bool enableHkSets) {
using namespace gpio;
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
createAcsBoardGpios(*gpioCookieAcsBoard);
@ -512,8 +515,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
#endif
RESET_ARGS_GNSS.gpioComIF = gpioComIF;
RESET_ARGS_GNSS.waitPeriodMs = 100;
auto gpsCtrl =
new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
auto gpsCtrl = new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT,
enableHkSets, debugGps);
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
@ -588,7 +591,7 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc
}
new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, gpioIF, pwrSwitcher,
pcdu::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V,
power::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V,
gpioIds::DEPLSA1, gpioIds::DEPLSA2, *SdCardManager::instance());
}
@ -604,7 +607,7 @@ void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) {
auto syrlinksFdir = new SyrlinksFdir(objects::SYRLINKS_HANDLER);
auto syrlinksHandler =
new SyrlinksHandler(objects::SYRLINKS_HANDLER, objects::SYRLINKS_COM_HANDLER,
syrlinksUartCookie, pcdu::PDU1_CH1_SYRLINKS_12V, syrlinksFdir);
syrlinksUartCookie, power::PDU1_CH1_SYRLINKS_12V, syrlinksFdir);
syrlinksHandler->setPowerSwitcher(pwrSwitcher);
syrlinksHandler->connectModeTreeParent(*syrlinksAssy);
#if OBSW_DEBUG_SYRLINKS == 1
@ -616,7 +619,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
using namespace gpio;
std::stringstream consumer;
auto* camSwitcher =
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitch, pcdu::PDU2_CH8_PAYLOAD_CAMERA);
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitch, power::PDU2_CH8_PAYLOAD_CAMERA);
camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
#if OBSW_ADD_PLOC_MPSOC == 1
consumer << "0x" << std::hex << objects::PLOC_MPSOC_HANDLER;
@ -649,7 +652,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
auto supvHelper = new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
pcdu::PDU1_CH6_PLOC_12V, *supvHelper);
power::PDU1_CH6_PLOC_12V, *supvHelper);
supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
static_cast<void>(consumer);
@ -726,7 +729,7 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF,
rws[idx] = rwHandler;
}
createRwAssy(*pwrSwitcher, pcdu::Switches::PDU2_CH2_RW_5V, rws, rwIds);
createRwAssy(*pwrSwitcher, power::Switches::PDU2_CH2_RW_5V, rws, rwIds);
#endif /* OBSW_ADD_RW == 1 */
}
@ -751,10 +754,8 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3");
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
// Initialise to low and then pull high to do a PTME reset, which puts the PTME in reset
// state. It will be put out of reset in the CCSDS handler initialize function.
gpio = new GpiodRegularByLineName(q7s::gpioNames::PTME_RESETN, "PTME RESETN",
gpio::Direction::OUT, gpio::Levels::LOW);
gpio::Direction::OUT, gpio::Levels::HIGH);
gpioCookiePtmeIp->addGpio(gpioIds::PTME_RESETN, gpio);
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
@ -788,34 +789,42 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
*args.ipCoreHandler =
new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig,
LINK_STATE, &args.gpioComIF, gpios);
LINK_STATE, &args.gpioComIF, gpios, PTME_LOCKED);
// This VC will receive all live TM
auto* vcWithQueue =
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
LINK_STATE, args.tmStore, 500);
args.liveDestination = vcWithQueue;
new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue);
auto* liveTask = new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel,
*vcWithQueue, PTME_LOCKED);
liveTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
// Set up log store.
auto* vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme,
LINK_STATE);
LogStores logStores(args.stores);
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
*SdCardManager::instance());
auto* logStore =
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
*SdCardManager::instance(), PTME_LOCKED);
logStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
new PersistentSingleTmStoreTask(objects::HK_STORE_AND_TM_TASK, args.ipcStore,
*args.stores.hkStore, *vc, persTmStore::DUMP_HK_STORE_DONE,
persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance());
auto* hkStore = new PersistentSingleTmStoreTask(
objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc,
persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance(),
PTME_LOCKED);
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
LINK_STATE);
// Core task which handles the CFDP store and takes care of dumping it as TM using a VC directly
new PersistentSingleTmStoreTask(objects::CFDP_STORE_AND_TM_TASK, args.ipcStore,
*args.stores.cfdpStore, *vc, persTmStore::DUMP_CFDP_STORE_DONE,
persTmStore::DUMP_CFDP_CANCELLED, *SdCardManager::instance());
auto* cfdpTask = new PersistentSingleTmStoreTask(
objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, *args.stores.cfdpStore, *vc,
persTmStore::DUMP_CFDP_STORE_DONE, persTmStore::DUMP_CFDP_CANCELLED,
*SdCardManager::instance(), PTME_LOCKED);
cfdpTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
if (result != returnvalue::OK) {
@ -958,7 +967,7 @@ void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) {
auto strFdir = new StrFdir(objects::STAR_TRACKER);
auto starTracker =
new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie,
paramJsonFile, strComIF, pcdu::PDU1_CH2_STAR_TRACKER_5V);
paramJsonFile, strComIF, power::PDU1_CH2_STAR_TRACKER_5V);
starTracker->setPowerSwitcher(pwrSwitcher);
starTracker->connectModeTreeParent(*strAssy);
starTracker->setCustomFdir(strFdir);
@ -971,7 +980,7 @@ void ObjectFactory::createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enable
new ImtqPollingTask(objects::IMTQ_POLLING, I2C_FATAL_ERRORS);
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, imtq::MAX_REPLY_SIZE, q7s::I2C_PL_EIVE);
auto imtqHandler = new ImtqHandler(objects::IMTQ_HANDLER, objects::IMTQ_POLLING, imtqI2cCookie,
pcdu::Switches::PDU1_CH3_MGT_5V, enableHkSets);
power::Switches::PDU1_CH3_MGT_5V, enableHkSets);
imtqHandler->enableThermalModule(ThermalStateCfg());
imtqHandler->setPowerSwitcher(pwrSwitcher);
imtqHandler->connectModeTreeParent(*imtqAssy);

View File

@ -4,11 +4,11 @@
#include <fsfw/returnvalues/returnvalue.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
#include <mission/com/CcsdsIpCoreHandler.h>
#include <mission/com/PersistentLogTmStoreTask.h>
#include <mission/genericFactory.h>
#include <mission/system/objects/Stack5VHandler.h>
#include <mission/tcs/HeaterHandler.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PersistentLogTmStoreTask.h>
#include <mission/tmtc/PusTmFunnel.h>
#include <atomic>
@ -24,6 +24,7 @@ class AcsBoardAssembly;
class GpioIF;
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
extern std::atomic_bool PTME_LOCKED;
namespace ObjectFactory {
@ -61,7 +62,7 @@ void createTmpComponents();
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler);
void createAcsBoardGpios(GpioCookie& cookie);
void createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF,
PowerSwitchIF& pwrSwitcher);
PowerSwitchIF& pwrSwitcher, bool enableHkSets);
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable,
HeaterHandler*& heaterHandler);
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets);

View File

@ -291,6 +291,14 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY);
}
result = acsSysTask->addComponent(objects::GPS_0_HEALTH_DEV);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("GPS_0_HEALTH_DEV", objects::GPS_0_HEALTH_DEV);
}
result = acsSysTask->addComponent(objects::GPS_1_HEALTH_DEV);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("GPS_1_HEALTH_DEV", objects::GPS_1_HEALTH_DEV);
}
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
@ -530,7 +538,7 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction
FixedTimeslotTaskIF* gomSpacePstTask =
factory.createFixedTimeslotTask("GS_PST_TASK", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4,
0.5, missedDeadlineFunc, &RR_SCHEDULING);
0.25, missedDeadlineFunc, &RR_SCHEDULING);
result = pst::pstGompaceCan(gomSpacePstTask);
if (result != returnvalue::OK) {
if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {

View File

@ -13,7 +13,7 @@
#include "bsp_q7s/core/ObjectFactory.h"
#include "busConf.h"
#include "devConf.h"
#include "dummies/helpers.h"
#include "dummies/helperFactory.h"
#include "eive/objects.h"
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
#include "linux/ObjectFactory.h"
@ -137,8 +137,8 @@ void ObjectFactory::produce(void* args) {
pcdu::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V);
#endif
createAcsController(true, enableHkSets);
HeaterHandler* heaterHandler = nullptr;
ObjectFactory::createGenericHeaterComponents(*gpioComIF, *pwrSwitcher, heaterHandler);
HeaterHandler* heaterHandler;
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
createThermalController(*heaterHandler);
satsystem::init();
}

View File

@ -55,7 +55,7 @@ void ObjectFactory::produce(void* args) {
#endif
#if OBSW_ADD_ACS_BOARD == 1
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher);
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true);
#endif
HeaterHandler* heaterHandler;
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
@ -97,7 +97,7 @@ void ObjectFactory::produce(void* args) {
#if OBSW_ADD_SCEX_DEVICE == 1
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
/* Test Task */
#if OBSW_ADD_TEST_CODE == 1

View File

@ -15,6 +15,9 @@ static constexpr char OBSW_VERSION_FILE_NAME[] = "obsw_version.txt";
static constexpr char OBSW_PATH[] = "/usr/bin/eive-obsw";
static constexpr char OBSW_VERSION_FILE_PATH[] = "/usr/share/eive-obsw/obsw_version.txt";
// ISO8601 timestamp.
static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ";
static constexpr uint16_t EIVE_PUS_APID = 0x65;
static constexpr uint16_t EIVE_CFDP_APID = 0x66;
static constexpr uint16_t EIVE_LOCAL_CFDP_ENTITY_ID = EIVE_CFDP_APID;

View File

@ -43,6 +43,8 @@ enum commonObjects : uint32_t {
RW4 = 0x44120350,
STAR_TRACKER = 0x44130001,
GPS_CONTROLLER = 0x44130045,
GPS_0_HEALTH_DEV = 0x44130046,
GPS_1_HEALTH_DEV = 0x44130047,
IMTQ_POLLING = 0x44140013,
IMTQ_HANDLER = 0x44140014,

View File

@ -26,6 +26,6 @@ target_sources(
CoreControllerDummy.cpp
PlocMpsocDummy.cpp
PlocSupervisorDummy.cpp
helpers.cpp
helperFactory.cpp
MgmRm3100Dummy.cpp
Tmp1075Dummy.cpp)

View File

@ -46,7 +46,7 @@ ReturnValue_t GyroAdisDummy::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(adis1650x::ACCELERATION_X, new PoolEntry<double>({0.0}));
localDataPoolMap.emplace(adis1650x::ACCELERATION_Y, new PoolEntry<double>({0.0}));
localDataPoolMap.emplace(adis1650x::ACCELERATION_Z, new PoolEntry<double>({0.0}));
localDataPoolMap.emplace(adis1650x::TEMPERATURE, new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(adis1650x::TEMPERATURE, new PoolEntry<float>({10.0}, true));
return returnvalue::OK;
}

View File

@ -1,5 +1,7 @@
#include "Max31865Dummy.h"
#include "fsfw/datapool/PoolReadGuard.h"
using namespace returnvalue;
Max31865Dummy::Max31865Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
@ -28,15 +30,20 @@ ReturnValue_t Max31865Dummy::initializeLocalDataPool(localpool::DataPool &localD
LocalDataPoolManager &poolManager) {
using namespace MAX31865;
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::RTD_VALUE), new PoolEntry<float>({0}));
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::TEMPERATURE_C), new PoolEntry<float>({0}));
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::TEMPERATURE_C),
new PoolEntry<float>({10.0}, true));
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::LAST_FAULT_BYTE),
new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::FAULT_BYTE), new PoolEntry<uint8_t>({0}));
return OK;
}
void Max31865Dummy::setTemperature(float temperature) {
set.temperatureCelcius.value = temperature;
void Max31865Dummy::setTemperature(float temperature, bool valid) {
PoolReadGuard pg(&set);
if (pg.getReadResult() == returnvalue::OK) {
set.temperatureCelcius.value = temperature;
set.setValidity(valid, true);
}
}
LocalPoolDataSetBase *Max31865Dummy::getDataSetHandle(sid_t sid) { return &set; }

View File

@ -10,7 +10,7 @@ class Max31865Dummy : public DeviceHandlerBase {
Max31865Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
Max31865Dummy(object_id_t objectId, CookieIF *comCookie);
void setTemperature(float temperature);
void setTemperature(float temperature, bool setValid);
private:
MAX31865::PrimarySet set;

View File

@ -40,7 +40,7 @@ uint32_t MgmLIS3MDLDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
ReturnValue_t MgmLIS3MDLDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(mgmLis3::TEMPERATURE_CELCIUS, new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(mgmLis3::TEMPERATURE_CELCIUS, new PoolEntry<float>({10.0}, true));
localDataPoolMap.emplace(mgmLis3::FIELD_STRENGTHS,
new PoolEntry<float>({1.02, 0.56, -0.78}, true));
return returnvalue::OK;

View File

@ -2,6 +2,8 @@
#include <mission/power/gsDefs.h>
#include "fsfw/datapool/PoolReadGuard.h"
P60DockDummy::P60DockDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie) {}

View File

@ -3,6 +3,8 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "mission/power/gsDefs.h"
class P60DockDummy : public DeviceHandlerBase {
public:
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
@ -15,6 +17,8 @@ class P60DockDummy : public DeviceHandlerBase {
virtual ~P60DockDummy();
protected:
lp_var_t<float> temp1 = lp_var_t<float>(this, P60Dock::pool::P60DOCK_TEMPERATURE_1);
lp_var_t<float> temp2 = lp_var_t<float>(this, P60Dock::pool::P60DOCK_TEMPERATURE_2);
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;

View File

@ -2,8 +2,12 @@
#include <mission/power/gsDefs.h>
#include "mission/power/defs.h"
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) {}
: DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) {
switcherLock = MutexFactory::instance()->createMutex();
}
PcduHandlerDummy::~PcduHandlerDummy() {}
@ -44,6 +48,17 @@ ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool &loc
}
ReturnValue_t PcduHandlerDummy::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) {
if (onOff == SWITCH_ON) {
triggerEvent(power::SWITCH_CMD_SENT, true, switchNr);
} else {
triggerEvent(power::SWITCH_CMD_SENT, false, switchNr);
}
{
MutexGuard mg(switcherLock);
// To simulate a real PCDU, remember the switch change to trigger a SWITCH_HAS_CHANGED event
// at a later stage.
switchChangeArray[switchNr] = true;
}
return dummySwitcher.sendSwitchCommand(switchNr, onOff);
}
@ -60,3 +75,22 @@ ReturnValue_t PcduHandlerDummy::getFuseState(uint8_t fuseNr) const {
}
uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }
void PcduHandlerDummy::performOperationHook() {
SwitcherBoolArray switcherChangeCopy{};
{
MutexGuard mg(switcherLock);
std::memcpy(switcherChangeCopy.data(), switchChangeArray.data(), switchChangeArray.size());
}
for (uint8_t idx = 0; idx < switcherChangeCopy.size(); idx++) {
if (switcherChangeCopy[idx]) {
if (dummySwitcher.getSwitchState(idx) == PowerSwitchIF::SWITCH_ON) {
triggerEvent(power::SWITCH_HAS_CHANGED, true, idx);
} else {
triggerEvent(power::SWITCH_HAS_CHANGED, false, idx);
}
MutexGuard mg(switcherLock);
switchChangeArray[idx] = false;
}
}
}

View File

@ -15,8 +15,12 @@ class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
virtual ~PcduHandlerDummy();
protected:
MutexIF *switcherLock;
DummyPowerSwitcher dummySwitcher;
using SwitcherBoolArray = std::array<bool, 18>;
SwitcherBoolArray switchChangeArray{};
void performOperationHook() override;
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;

View File

@ -2,6 +2,8 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "mission/power/defs.h"
class PlocMpsocDummy : public DeviceHandlerBase {
public:
static const DeviceCommandId_t SIMPLE_COMMAND = 1;

View File

@ -1,8 +1,10 @@
#include "PlocSupervisorDummy.h"
PlocSupervisorDummy::PlocSupervisorDummy(object_id_t objectId, object_id_t comif,
CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie) {}
CookieIF *comCookie, PowerSwitchIF &pwrSwitcher)
: DeviceHandlerBase(objectId, comif, comCookie) {
setPowerSwitcher(&pwrSwitcher);
}
PlocSupervisorDummy::~PlocSupervisorDummy() {}
@ -42,3 +44,10 @@ ReturnValue_t PlocSupervisorDummy::initializeLocalDataPool(localpool::DataPool &
LocalDataPoolManager &poolManager) {
return returnvalue::OK;
}
ReturnValue_t PlocSupervisorDummy::getSwitches(const uint8_t **switches,
uint8_t *numberOfSwitches) {
*numberOfSwitches = 1;
*switches = reinterpret_cast<const uint8_t *>(&switchId);
return returnvalue::OK;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/power/defs.h>
class PlocSupervisorDummy : public DeviceHandlerBase {
public:
@ -10,10 +11,13 @@ class PlocSupervisorDummy : public DeviceHandlerBase {
static const uint8_t SIMPLE_COMMAND_DATA = 1;
static const uint8_t PERIODIC_REPLY_DATA = 2;
PlocSupervisorDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
PlocSupervisorDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie,
PowerSwitchIF &pwrSwitcher);
virtual ~PlocSupervisorDummy();
protected:
const power::Switches switchId = power::Switches::PDU1_CH6_PLOC_12V;
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
@ -27,4 +31,5 @@ class PlocSupervisorDummy : public DeviceHandlerBase {
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override;
};

View File

@ -40,7 +40,7 @@ uint32_t StarTrackerDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo)
ReturnValue_t StarTrackerDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(startracker::MCU_TEMPERATURE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(startracker::MCU_TEMPERATURE, new PoolEntry<float>({10.0}, true));
localDataPoolMap.emplace(startracker::TICKS_SOLUTION_SET, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(startracker::TIME_SOLUTION_SET, new PoolEntry<uint64_t>({0}));

View File

@ -40,7 +40,7 @@ uint32_t SyrlinksDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { r
ReturnValue_t SyrlinksDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(syrlinks::TEMP_BASEBAND_BOARD, new PoolEntry<float>({0}));
localDataPoolMap.emplace(syrlinks::TEMP_POWER_AMPLIFIER, new PoolEntry<float>({0}));
localDataPoolMap.emplace(syrlinks::TEMP_BASEBAND_BOARD, new PoolEntry<float>({10}, true));
localDataPoolMap.emplace(syrlinks::TEMP_POWER_AMPLIFIER, new PoolEntry<float>({10}, true));
return returnvalue::OK;
}

View File

@ -9,7 +9,7 @@
TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId,
Max31865DummyMap tempSensorDummies_,
Tmp1075DummyMap tempTmpSensorDummies_)
: SystemObject(objects::THERMAL_TEMP_INSERTER),
: SystemObject(objectId),
max31865DummyMap(std::move(tempSensorDummies_)),
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
@ -22,6 +22,32 @@ ReturnValue_t TemperatureSensorInserter::initialize() {
}
ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
// TODO: deviceSensors
if (not tempsWereInitialized) {
for (auto& rtdDummy : max31865DummyMap) {
rtdDummy.second->setTemperature(10, true);
}
for (auto& tmpDummy : tmp1075DummyMap) {
tmpDummy.second->setTemperature(10, true);
}
tempsWereInitialized = true;
}
if (cycles == 10) {
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(-100, 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) {
@ -36,5 +62,7 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
}
max31865PlocHeatspreaderSet.commit();
*/
cycles++;
return returnvalue::OK;
}
ReturnValue_t TemperatureSensorInserter::initializeAfterTaskCreation() { return returnvalue::OK; }

View File

@ -14,6 +14,7 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
Tmp1075DummyMap tempTmpSensorDummies_);
ReturnValue_t initialize() override;
ReturnValue_t initializeAfterTaskCreation() override;
protected:
ReturnValue_t performOperation(uint8_t opCode) override;
@ -23,6 +24,8 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
Tmp1075DummyMap tmp1075DummyMap;
enum TestCase { NONE = 0, COOL_SYRLINKS = 1 };
int iteration = 0;
uint32_t cycles = 0;
bool tempsWereInitialized = false;
bool performTest = false;
TestCase testCase = TestCase::NONE;

View File

@ -1,5 +1,6 @@
#include "Tmp1075Dummy.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include <mission/tcs/Tmp1075Definitions.h>
using namespace returnvalue;
@ -26,11 +27,16 @@ ReturnValue_t Tmp1075Dummy::scanForReply(const uint8_t *start, size_t len,
ReturnValue_t Tmp1075Dummy::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
return 0;
}
void Tmp1075Dummy::setTemperature(float temperature, bool valid) {
PoolReadGuard pg(&set);
set.temperatureCelcius.value = temperature;
set.setValidity(valid, true);
}
void Tmp1075Dummy::fillCommandAndReplyMap() {}
uint32_t Tmp1075Dummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 1000; }
ReturnValue_t Tmp1075Dummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(TMP1075::TEMPERATURE_C_TMP1075, new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(TMP1075::TEMPERATURE_C_TMP1075, new PoolEntry<float>({10.0}, true));
return OK;
}
LocalPoolDataSetBase *Tmp1075Dummy::getDataSetHandle(sid_t sid) { return &set; }

View File

@ -8,6 +8,7 @@
class Tmp1075Dummy : public DeviceHandlerBase {
public:
Tmp1075Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
void setTemperature(float temperature, bool setValid);
private:
TMP1075::Tmp1075Dataset set;

View File

@ -1,4 +1,4 @@
#include "helpers.h"
#include "helperFactory.h"
#include <dummies/AcuDummy.h>
#include <dummies/BpxDummy.h>
@ -24,11 +24,12 @@
#include <dummies/StarTrackerDummy.h>
#include <dummies/SusDummy.h>
#include <dummies/SyrlinksDummy.h>
#include <fsfw/devicehandlers/HealthDevice.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <mission/power/gsDefs.h>
#include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/StrAssembly.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include "TemperatureSensorInserter.h"
@ -56,7 +57,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
rws[1] = new RwDummy(objects::RW2, objects::DUMMY_COM_IF, comCookieDummy);
rws[2] = new RwDummy(objects::RW3, objects::DUMMY_COM_IF, comCookieDummy);
rws[3] = new RwDummy(objects::RW4, objects::DUMMY_COM_IF, comCookieDummy);
ObjectFactory::createRwAssy(pwrSwitcher, pcdu::Switches::PDU2_CH2_RW_5V, rws, rwIds);
ObjectFactory::createRwAssy(pwrSwitcher, power::Switches::PDU2_CH2_RW_5V, rws, rwIds);
new SaDeplDummy(objects::SOLAR_ARRAY_DEPL_HANDLER);
auto* strAssy = new StrAssembly(objects::STR_ASSY);
strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
@ -210,7 +211,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
}
}
auto* camSwitcher =
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, pcdu::Switches::PDU2_CH8_PAYLOAD_CAMERA);
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, power::Switches::PDU2_CH8_PAYLOAD_CAMERA);
camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy);
scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
@ -221,8 +222,8 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
auto* plocMpsocDummy =
new PlocMpsocDummy(objects::PLOC_MPSOC_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
plocMpsocDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
auto* plocSupervisorDummy = new PlocSupervisorDummy(objects::PLOC_SUPERVISOR_HANDLER,
objects::DUMMY_COM_IF, comCookieDummy);
auto* plocSupervisorDummy = new PlocSupervisorDummy(
objects::PLOC_SUPERVISOR_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, pwrSwitcher);
plocSupervisorDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
}
}

2
fsfw

Submodule fsfw updated: 4f632e2c68...6650c293da

View File

@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h
12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h
12803;0x3203;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/AcsBoardAssembly.h
12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h
12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;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
@ -260,13 +261,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.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.;bsp_q7s/core/CoreController.h
14010;0x36ba;I2C_UNAVAILABLE_REBOOT;MEDIUM;No description;bsp_q7s/core/CoreController.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14103;0x3717;PLOC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14104;0x3718;OBC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14105;0x3719;HPA_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.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
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14104;0x3718;OBC_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
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;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
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

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
203 12801 0x3201 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/AcsBoardAssembly.h
204 12802 0x3202 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/AcsBoardAssembly.h
205 12803 0x3203 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/AcsBoardAssembly.h
206 12804 0x3204 DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY MEDIUM This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode. mission/system/acs/AcsBoardAssembly.h
207 12900 0x3264 TRANSITION_OTHER_SIDE_FAILED HIGH No description mission/system/acs/SusAssembly.h
208 12901 0x3265 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/SusAssembly.h
209 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
261 14007 0x36b7 REBOOT_COUNTER INFO Total reboot counter, which is the sum of the boot count of all individual images. bsp_q7s/core/CoreController.h
262 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. bsp_q7s/core/CoreController.h
263 14010 0x36ba I2C_UNAVAILABLE_REBOOT MEDIUM No description bsp_q7s/core/CoreController.h
264 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
265 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
266 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
267 14103 14104 0x3717 0x3718 PLOC_OVERHEATING OBC_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
268 14104 14105 0x3718 0x3719 OBC_OVERHEATING CAMERA_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
269 14105 14106 0x3719 0x371a HPA_OVERHEATING PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
270 14106 14107 0x371a 0x371b PLPCDU_OVERHEATING HEATER_NOT_OFF_FOR_OFF_MODE HIGH MEDIUM No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
271 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
272 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
273 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

View File

@ -30,6 +30,8 @@
0x44120350;RW4
0x44130001;STAR_TRACKER
0x44130045;GPS_CONTROLLER
0x44130046;GPS_0_HEALTH_DEV
0x44130047;GPS_1_HEALTH_DEV
0x44140013;IMTQ_POLLING
0x44140014;IMTQ_HANDLER
0x442000A1;PCDU_HANDLER

1 0x42694269 TEST_TASK
30 0x44120350 RW4
31 0x44130001 STAR_TRACKER
32 0x44130045 GPS_CONTROLLER
33 0x44130046 GPS_0_HEALTH_DEV
34 0x44130047 GPS_1_HEALTH_DEV
35 0x44140013 IMTQ_POLLING
36 0x44140014 IMTQ_HANDLER
37 0x442000A1 PCDU_HANDLER

View File

@ -440,7 +440,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5106;IMTQ_InternalProcessingError;No description;6;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5107;IMTQ_RejectedWithoutReason;No description;7;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5108;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x51a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;167;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5109;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x510a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x52b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h
0x52b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h
0x52b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
440 0x5106 IMTQ_InternalProcessingError No description 6 IMTQ_HANDLER mission/acs/imtqHelpers.h
441 0x5107 IMTQ_RejectedWithoutReason No description 7 IMTQ_HANDLER mission/acs/imtqHelpers.h
442 0x5108 IMTQ_CmdErrUnknown No description 8 IMTQ_HANDLER mission/acs/imtqHelpers.h
443 0x51a7 0x5109 IMTQ_UnexpectedSelfTestReply IMTQ_StartupCfgError The status reply to a self test command was received but no self test command has been sent. This should normally never happen. No description 167 9 IMTQ_HANDLER mission/acs/imtqHelpers.h
444 0x510a IMTQ_UnexpectedSelfTestReply The status reply to a self test command was received but no self test command has been sent. This should normally never happen. 10 IMTQ_HANDLER mission/acs/imtqHelpers.h
445 0x52b0 RWHA_SpiWriteFailure No description 176 RW_HANDLER mission/acs/rwHelpers.h
446 0x52b1 RWHA_SpiReadFailure Used by the spi send function to tell a failing read call 177 RW_HANDLER mission/acs/rwHelpers.h
447 0x52b2 RWHA_MissingStartSign Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E 178 RW_HANDLER mission/acs/rwHelpers.h

View File

@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h
12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h
12803;0x3203;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/AcsBoardAssembly.h
12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h
12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;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
@ -260,13 +261,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.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.;bsp_q7s/core/CoreController.h
14010;0x36ba;I2C_UNAVAILABLE_REBOOT;MEDIUM;No description;bsp_q7s/core/CoreController.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14103;0x3717;PLOC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14104;0x3718;OBC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14105;0x3719;HPA_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.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
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14104;0x3718;OBC_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
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;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
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

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
203 12801 0x3201 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/AcsBoardAssembly.h
204 12802 0x3202 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/AcsBoardAssembly.h
205 12803 0x3203 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/AcsBoardAssembly.h
206 12804 0x3204 DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY MEDIUM This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode. mission/system/acs/AcsBoardAssembly.h
207 12900 0x3264 TRANSITION_OTHER_SIDE_FAILED HIGH No description mission/system/acs/SusAssembly.h
208 12901 0x3265 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/SusAssembly.h
209 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
261 14007 0x36b7 REBOOT_COUNTER INFO Total reboot counter, which is the sum of the boot count of all individual images. bsp_q7s/core/CoreController.h
262 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. bsp_q7s/core/CoreController.h
263 14010 0x36ba I2C_UNAVAILABLE_REBOOT MEDIUM No description bsp_q7s/core/CoreController.h
264 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
265 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
266 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
267 14103 14104 0x3717 0x3718 PLOC_OVERHEATING OBC_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
268 14104 14105 0x3718 0x3719 OBC_OVERHEATING CAMERA_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
269 14105 14106 0x3719 0x371a HPA_OVERHEATING PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
270 14106 14107 0x371a 0x371b PLPCDU_OVERHEATING HEATER_NOT_OFF_FOR_OFF_MODE HIGH MEDIUM No description mission/controller/ThermalController.h mission/controller/tcsDefs.h
271 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
272 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
273 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

View File

@ -29,6 +29,8 @@
0x44120350;RW4
0x44130001;STAR_TRACKER
0x44130045;GPS_CONTROLLER
0x44130046;GPS_0_HEALTH_DEV
0x44130047;GPS_1_HEALTH_DEV
0x44140013;IMTQ_POLLING
0x44140014;IMTQ_HANDLER
0x442000A1;PCDU_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
29 0x44120350 RW4
30 0x44130001 STAR_TRACKER
31 0x44130045 GPS_CONTROLLER
32 0x44130046 GPS_0_HEALTH_DEV
33 0x44130047 GPS_1_HEALTH_DEV
34 0x44140013 IMTQ_POLLING
35 0x44140014 IMTQ_HANDLER
36 0x442000A1 PCDU_HANDLER

View File

@ -440,7 +440,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5106;IMTQ_InternalProcessingError;No description;6;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5107;IMTQ_RejectedWithoutReason;No description;7;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5108;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x51a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;167;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5109;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x510a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x52b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h
0x52b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h
0x52b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
440 0x5106 IMTQ_InternalProcessingError No description 6 IMTQ_HANDLER mission/acs/imtqHelpers.h
441 0x5107 IMTQ_RejectedWithoutReason No description 7 IMTQ_HANDLER mission/acs/imtqHelpers.h
442 0x5108 IMTQ_CmdErrUnknown No description 8 IMTQ_HANDLER mission/acs/imtqHelpers.h
443 0x51a7 0x5109 IMTQ_UnexpectedSelfTestReply IMTQ_StartupCfgError The status reply to a self test command was received but no self test command has been sent. This should normally never happen. No description 167 9 IMTQ_HANDLER mission/acs/imtqHelpers.h
444 0x510a IMTQ_UnexpectedSelfTestReply The status reply to a self test command was received but no self test command has been sent. This should normally never happen. 10 IMTQ_HANDLER mission/acs/imtqHelpers.h
445 0x52b0 RWHA_SpiWriteFailure No description 176 RW_HANDLER mission/acs/rwHelpers.h
446 0x52b1 RWHA_SpiReadFailure Used by the spi send function to tell a failing read call 177 RW_HANDLER mission/acs/rwHelpers.h
447 0x52b2 RWHA_MissingStartSign Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E 178 RW_HANDLER mission/acs/rwHelpers.h

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 283 translations.
* @brief Auto-generated event translation file. Contains 284 translations.
* @details
* Generated on: 2023-03-28 22:20:01
* Generated on: 2023-04-04 13:59:07
*/
#include "translateEvents.h"
@ -209,6 +209,7 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE";
const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED";
const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY";
const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900";
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901";
const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902";
@ -269,10 +270,10 @@ const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
const char *PLOC_OVERHEATING_STRING = "PLOC_OVERHEATING";
const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *HPA_OVERHEATING_STRING = "HPA_OVERHEATING";
const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_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 *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
@ -699,6 +700,8 @@ const char *translateEvents(Event event) {
return POWER_STATE_MACHINE_TIMEOUT_STRING;
case (12803):
return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING;
case (12804):
return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING;
case (12900):
return TRANSITION_OTHER_SIDE_FAILED_12900_STRING;
case (12901):
@ -819,14 +822,14 @@ const char *translateEvents(Event event) {
return NO_HEALTHY_HEATER_AVAILABLE_STRING;
case (14102):
return SYRLINKS_OVERHEATING_STRING;
case (14103):
return PLOC_OVERHEATING_STRING;
case (14104):
return OBC_OVERHEATING_STRING;
case (14105):
return HPA_OVERHEATING_STRING;
return CAMERA_OVERHEATING_STRING;
case (14106):
return PLPCDU_OVERHEATING_STRING;
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 173 translations.
* Generated on: 2023-03-28 22:20:01
* Contains 175 translations.
* Generated on: 2023-04-04 13:59:07
*/
#include "translateObjects.h"
@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV";
const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV";
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) {
return STAR_TRACKER_STRING;
case 0x44130045:
return GPS_CONTROLLER_STRING;
case 0x44130046:
return GPS_0_HEALTH_DEV_STRING;
case 0x44130047:
return GPS_1_HEALTH_DEV_STRING;
case 0x44140013:
return IMTQ_POLLING_STRING;
case 0x44140014:

View File

@ -18,8 +18,11 @@
#include <ctime>
GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
bool debugHyperionGps)
: ExtendedControllerBase(objectId), gpsSet(this), debugHyperionGps(debugHyperionGps) {}
bool enableHkSets, bool debugHyperionGps)
: ExtendedControllerBase(objectId),
gpsSet(this),
enableHkSets(enableHkSets),
debugHyperionGps(debugHyperionGps) {}
GpsHyperionLinuxController::~GpsHyperionLinuxController() {
gps_stream(&gps, WATCH_DISABLE, nullptr);
@ -86,7 +89,7 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), false, 30.0});
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0});
return returnvalue::OK;
}
@ -99,6 +102,7 @@ void GpsHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t
ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) {
handleQueue();
poolManager.performHkOperation();
while (true) {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "GPS CTRL");

View File

@ -29,7 +29,7 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
enum ReadModes { SHM = 0, SOCKET = 1 };
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool enableHkSets,
bool debugHyperionGps = false);
virtual ~GpsHyperionLinuxController();
@ -58,6 +58,7 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
private:
GpsPrimaryDataset gpsSet;
gps_data_t gps = {};
bool enableHkSets = false;
const char* currentClientBuf = nullptr;
ReadModes readMode = ReadModes::SOCKET;
Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000);

View File

@ -27,7 +27,7 @@ ReturnValue_t ImtqPollingTask::performOperation(uint8_t operationCode) {
comStatus = returnvalue::OK;
// Stopwatch watch;
switch (currentRequest) {
switch (currentRequest.requestType) {
case imtq::RequestType::MEASURE_NO_ACTUATION: {
// Measured to take 24 ms for debug and release builds.
// Stopwatch watch;
@ -51,6 +51,30 @@ void ImtqPollingTask::handleMeasureStep() {
uint8_t* replyPtr;
ImtqRepliesDefault replies(replyBuf.data());
// If some startup handling is added later, set configured after it was done once.
if (performStartup) {
// Set integration time for the MGM.
cmdBuf[0] = imtq::CC::SET_PARAM;
size_t dummy = 0;
SerializeAdapter::serialize(&imtq::param::INTEGRATION_TIME_SELECT, cmdBuf.data() + 1, &dummy,
cmdBuf.size(), SerializeIF::Endianness::LITTLE);
cmdBuf[3] = currentRequest.integrationTimeSel;
cmdLen = 4;
ReturnValue_t result = performI2cFullRequest(replyBuf.data(), 5);
if (result != returnvalue::OK) {
comStatus = imtq::STARTUP_CFG_ERROR;
}
if (replyBuf[0] != imtq::CC::SET_PARAM) {
sif::error << "ImtqPollingTask: First byte of reply not equal to sent CC" << std::endl;
comStatus = imtq::STARTUP_CFG_ERROR;
}
if (replyBuf[4] != currentRequest.integrationTimeSel) {
sif::error << "ImtqPollingTask: Integration time configuration failed" << std::endl;
comStatus = imtq::STARTUP_CFG_ERROR;
}
currentIntegrationTimeMs =
imtq::integrationTimeFromSelectValue(currentRequest.integrationTimeSel);
performStartup = false;
}
replies.setConfigured();
// Can be used later to verify correct timing (e.g. all data has been read)
@ -73,7 +97,7 @@ void ImtqPollingTask::handleMeasureStep() {
return;
}
if (specialRequest != imtq::SpecialRequest::NONE) {
if (currentRequest.specialRequest != imtq::SpecialRequest::NONE) {
auto executeSelfTest = [&](imtq::selfTest::Axis axis) {
cmdBuf[0] = imtq::CC::SELF_TEST_CMD;
cmdBuf[1] = axis;
@ -81,7 +105,7 @@ void ImtqPollingTask::handleMeasureStep() {
};
// If a self-test is already ongoing, ignore the request.
if (replies.getSystemState()[2] != static_cast<uint8_t>(imtq::mode::SELF_TEST)) {
switch (specialRequest) {
switch (currentRequest.specialRequest) {
case (imtq::SpecialRequest::DO_SELF_TEST_POS_X): {
executeSelfTest(imtq::selfTest::Axis::X_POSITIVE);
break;
@ -234,18 +258,21 @@ ReturnValue_t ImtqPollingTask::initializeInterface(CookieIF* cookie) {
ReturnValue_t ImtqPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
size_t sendLen) {
const auto* imtqReq = reinterpret_cast<const imtq::Request*>(sendData);
if (sendLen != sizeof(imtq::Request)) {
return returnvalue::FAILED;
}
{
MutexGuard mg(ipcLock);
if (imtqReq->request == imtq::RequestType::ACTUATE) {
std::memcpy(dipoles, imtqReq->dipoles, sizeof(dipoles));
torqueDuration = imtqReq->torqueDuration;
}
currentRequest = imtqReq->request;
specialRequest = imtqReq->specialRequest;
if (state != InternalState::IDLE) {
return returnvalue::FAILED;
}
state = InternalState::IS_BUSY;
if (currentRequest.mode != imtqReq->mode) {
if (imtqReq->mode == acs::SimpleSensorMode::NORMAL) {
performStartup = true;
}
}
std::memcpy(&currentRequest, imtqReq, sendLen);
}
semaphore->release();
@ -345,10 +372,10 @@ void ImtqPollingTask::buildDipoleCommand() {
uint8_t* serPtr = cmdBuf.data() + 1;
size_t serLen = 0;
for (uint8_t idx = 0; idx < 3; idx++) {
SerializeAdapter::serialize(&dipoles[idx], &serPtr, &serLen, cmdBuf.size(),
SerializeAdapter::serialize(&currentRequest.dipoles[idx], &serPtr, &serLen, cmdBuf.size(),
SerializeIF::Endianness::LITTLE);
}
SerializeAdapter::serialize(&torqueDuration, &serPtr, &serLen, cmdBuf.size(),
SerializeAdapter::serialize(&currentRequest.torqueDuration, &serPtr, &serLen, cmdBuf.size(),
SerializeIF::Endianness::LITTLE);
// sif::debug << "Dipole X: " << dipoles[0] << std::endl;
// sif::debug << "Torqeu Dur: " << torqueDuration << std::endl;
@ -357,22 +384,28 @@ void ImtqPollingTask::buildDipoleCommand() {
ReturnValue_t ImtqPollingTask::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
size_t* size) {
imtq::RequestType currentRequest;
imtq::Request currentRequest;
{
MutexGuard mg(ipcLock);
currentRequest = this->currentRequest;
std::memcpy(&currentRequest, &this->currentRequest, sizeof(currentRequest));
}
size_t replyLen = 0;
MutexGuard mg(bufLock);
if (currentRequest == imtq::RequestType::MEASURE_NO_ACTUATION) {
replyLen = getExchangeBufLen(specialRequest);
memcpy(exchangeBuf.data(), replyBuf.data(), replyLen);
} else if (currentRequest == imtq::RequestType::ACTUATE) {
replyLen = ImtqRepliesWithTorque::BASE_LEN;
memcpy(exchangeBuf.data(), replyBufActuation.data(), replyLen);
} else {
*size = 0;
{
MutexGuard mg(bufLock);
if (currentRequest.requestType == imtq::RequestType::MEASURE_NO_ACTUATION) {
replyLen = getExchangeBufLen(currentRequest.specialRequest);
memcpy(exchangeBuf.data(), replyBuf.data(), replyLen);
} else if (currentRequest.requestType == imtq::RequestType::ACTUATE) {
replyLen = ImtqRepliesWithTorque::BASE_LEN;
memcpy(exchangeBuf.data(), replyBufActuation.data(), replyLen);
} else {
*size = 0;
}
}
{
MutexGuard mg(ipcLock);
this->currentRequest.requestType = imtq::RequestType::DO_NOTHING;
}
*buffer = exchangeBuf.data();
*size = replyLen;
@ -417,6 +450,7 @@ void ImtqPollingTask::clearReadFlagsWithTorque(ImtqRepliesWithTorque& replies) {
ReturnValue_t ImtqPollingTask::performI2cFullRequest(uint8_t* reply, size_t replyLen) {
int fd = 0;
if (cmdLen == 0 or reply == nullptr) {
sif::error << "ImtqPollingTask: Command lenght is zero or reply PTR is invalid" << std::endl;
return returnvalue::FAILED;
}

View File

@ -3,6 +3,7 @@
#include <fsfw/tasks/SemaphoreIF.h>
#include <fsfw_hal/linux/i2c/I2cCookie.h>
#include <mission/acs/acsBoardPolling.h>
#include <atomic>
@ -24,7 +25,6 @@ class ImtqPollingTask : public SystemObject,
static constexpr ReturnValue_t NO_REPLY_AVAILABLE = returnvalue::makeCode(2, 0);
enum class InternalState { IDLE, IS_BUSY } state = InternalState::IDLE;
imtq::RequestType currentRequest = imtq::RequestType::MEASURE_NO_ACTUATION;
SemaphoreIF* semaphore;
ReturnValue_t comStatus = returnvalue::OK;
@ -38,10 +38,9 @@ class ImtqPollingTask : public SystemObject,
// Required in addition to integration time, otherwise old data might be read.
static constexpr uint32_t MGM_READ_BUFFER_TIME_MS = 6;
bool ignoreNextActuateRequest = false;
bool performStartup = false;
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
int16_t dipoles[3] = {};
uint16_t torqueDuration = 0;
imtq::Request currentRequest{};
std::array<uint8_t, 32> cmdBuf;
std::array<uint8_t, 524> replyBuf;

View File

@ -42,7 +42,6 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
while (true) {
lock->lockMutex();
state = InternalState::SLEEPING;
datalinkLayer.reset();
lock->unlockMutex();
semaphore.acquire();
switch (state) {
@ -58,6 +57,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
}
case InternalState::UPLOAD_IMAGE: {
replyTimeout.setTimeout(200);
resetReplyHandlingState();
result = performImageUpload();
if (result == returnvalue::OK) {
triggerEvent(IMAGE_UPLOAD_SUCCESSFUL);
@ -68,6 +68,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
}
case InternalState::DOWNLOAD_IMAGE: {
replyTimeout.setTimeout(200);
resetReplyHandlingState();
result = performImageDownload();
if (result == returnvalue::OK) {
triggerEvent(IMAGE_DOWNLOAD_SUCCESSFUL);
@ -78,6 +79,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
}
case InternalState::FLASH_READ: {
replyTimeout.setTimeout(200);
resetReplyHandlingState();
result = performFlashRead();
if (result == returnvalue::OK) {
triggerEvent(FLASH_READ_SUCCESSFUL);
@ -88,6 +90,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
}
case InternalState::FIRMWARE_UPDATE: {
replyTimeout.setTimeout(200);
resetReplyHandlingState();
result = performFirmwareUpdate();
if (result == returnvalue::OK) {
triggerEvent(FIRMWARE_UPDATE_SUCCESSFUL);
@ -645,7 +648,8 @@ ReturnValue_t StrComHandler::sendMessage(CookieIF* cookie, const uint8_t* sendDa
return BUSY;
}
}
serial::flushRxBuf(serialPort);
// Ensure consistent state.
resetReplyHandlingState();
const uint8_t* txFrame;
size_t frameLen;
@ -697,6 +701,7 @@ ReturnValue_t StrComHandler::readReceivedMessage(CookieIF* cookie, uint8_t** buf
*buffer = const_cast<uint8_t*>(replyPtr);
*size = replyLen;
}
replyLen = 0;
return replyResult;
}
@ -781,3 +786,8 @@ ReturnValue_t StrComHandler::readOneReply(uint32_t failParameter) {
}
}
}
void StrComHandler::resetReplyHandlingState() {
serial::flushRxBuf(serialPort);
datalinkLayer.reset();
}

View File

@ -374,6 +374,8 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
* @return
*/
ReturnValue_t readOneReply(uint32_t failParameter);
void resetReplyHandlingState();
};
#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 283 translations.
* @brief Auto-generated event translation file. Contains 284 translations.
* @details
* Generated on: 2023-03-28 22:20:01
* Generated on: 2023-04-04 13:59:07
*/
#include "translateEvents.h"
@ -209,11 +209,11 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE";
const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED";
const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY";
const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900";
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901";
const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING =
"SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
@ -270,10 +270,10 @@ const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
const char *PLOC_OVERHEATING_STRING = "PLOC_OVERHEATING";
const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *HPA_OVERHEATING_STRING = "HPA_OVERHEATING";
const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_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 *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
@ -700,6 +700,8 @@ const char *translateEvents(Event event) {
return POWER_STATE_MACHINE_TIMEOUT_STRING;
case (12803):
return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING;
case (12804):
return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING;
case (12900):
return TRANSITION_OTHER_SIDE_FAILED_12900_STRING;
case (12901):
@ -820,14 +822,14 @@ const char *translateEvents(Event event) {
return NO_HEALTHY_HEATER_AVAILABLE_STRING;
case (14102):
return SYRLINKS_OVERHEATING_STRING;
case (14103):
return PLOC_OVERHEATING_STRING;
case (14104):
return OBC_OVERHEATING_STRING;
case (14105):
return HPA_OVERHEATING_STRING;
return CAMERA_OVERHEATING_STRING;
case (14106):
return PLPCDU_OVERHEATING_STRING;
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 173 translations.
* Generated on: 2023-03-28 22:20:01
* Contains 175 translations.
* Generated on: 2023-04-04 13:59:07
*/
#include "translateObjects.h"
@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV";
const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV";
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) {
return STAR_TRACKER_STRING;
case 0x44130045:
return GPS_CONTROLLER_STRING;
case 0x44130046:
return GPS_0_HEALTH_DEV_STRING;
case 0x44130047:
return GPS_1_HEALTH_DEV_STRING;
case 0x44140013:
return IMTQ_POLLING_STRING;
case 0x44140014:

View File

@ -1,5 +1,7 @@
#include "AxiPtmeConfig.h"
#include <fsfw/ipc/MutexGuard.h>
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw_hal/linux/uio/UioMapper.h"
@ -39,97 +41,59 @@ ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) {
return returnvalue::OK;
}
ReturnValue_t AxiPtmeConfig::enableTxclockManipulator() {
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
void AxiPtmeConfig::enableTxclockManipulator() {
writeBit(COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR);
}
ReturnValue_t AxiPtmeConfig::disableTxclockManipulator() {
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, false, BitPos::EN_TX_CLK_MANIPULATOR);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
void AxiPtmeConfig::disableTxclockManipulator() {
writeBit(COMMON_CONFIG_REG, false, BitPos::EN_TX_CLK_MANIPULATOR);
}
ReturnValue_t AxiPtmeConfig::enableTxclockInversion() {
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, true, BitPos::INVERT_CLOCK);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
void AxiPtmeConfig::enableTxclockInversion() {
writeBit(COMMON_CONFIG_REG, true, BitPos::INVERT_CLOCK);
}
ReturnValue_t AxiPtmeConfig::disableTxclockInversion() {
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, false, BitPos::INVERT_CLOCK);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
void AxiPtmeConfig::disableTxclockInversion() {
writeBit(COMMON_CONFIG_REG, false, BitPos::INVERT_CLOCK);
}
ReturnValue_t AxiPtmeConfig::enableBatPriorityBit() {
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, true, BitPos::EN_BAT_PRIORITY);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
void AxiPtmeConfig::enableBatPriorityBit() {
writeBit(COMMON_CONFIG_REG, true, BitPos::EN_BAT_PRIORITY);
}
ReturnValue_t AxiPtmeConfig::disableBatPriorityBit() {
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, false, BitPos::EN_BAT_PRIORITY);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
void AxiPtmeConfig::disableBatPriorityBit() {
writeBit(COMMON_CONFIG_REG, false, BitPos::EN_BAT_PRIORITY);
}
ReturnValue_t AxiPtmeConfig::writeReg(uint32_t regOffset, uint32_t writeVal) {
ReturnValue_t result = returnvalue::OK;
result = mutex->lockMutex(timeoutType, mutexTimeout);
if (result != returnvalue::OK) {
sif::warning << "AxiPtmeConfig::readReg: Failed to lock mutex" << std::endl;
return returnvalue::FAILED;
}
void AxiPtmeConfig::writeReg(uint32_t regOffset, uint32_t writeVal) {
MutexGuard mg(mutex, timeoutType, mutexTimeout);
*(baseAddress + regOffset / ADRESS_DIVIDER) = writeVal;
result = mutex->unlockMutex();
if (result != returnvalue::OK) {
sif::warning << "AxiPtmeConfig::readReg: Failed to unlock mutex" << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t AxiPtmeConfig::readReg(uint32_t regOffset, uint32_t* readVal) {
ReturnValue_t result = returnvalue::OK;
result = mutex->lockMutex(timeoutType, mutexTimeout);
if (result != returnvalue::OK) {
sif::warning << "AxiPtmeConfig::readReg: Failed to lock mutex" << std::endl;
return returnvalue::FAILED;
}
*readVal = *(baseAddress + regOffset / ADRESS_DIVIDER);
result = mutex->unlockMutex();
if (result != returnvalue::OK) {
sif::warning << "AxiPtmeConfig::readReg: Failed to unlock mutex" << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
uint32_t AxiPtmeConfig::readReg(uint32_t regOffset) {
MutexGuard mg(mutex, timeoutType, mutexTimeout);
return *(baseAddress + regOffset / ADRESS_DIVIDER);
}
ReturnValue_t AxiPtmeConfig::writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos) {
uint32_t readVal = 0;
ReturnValue_t result = readReg(regOffset, &readVal);
if (result != returnvalue::OK) {
return result;
}
void AxiPtmeConfig::writePollThreshold(AxiPtmeConfig::IdlePollThreshold pollThreshold) {
uint32_t regVal = readCommonCfgReg();
// Clear bits first
regVal &= ~(0b111 << 3);
regVal |= (static_cast<uint8_t>(pollThreshold) << 3);
writeCommonCfgReg(regVal);
}
AxiPtmeConfig::IdlePollThreshold AxiPtmeConfig::readPollThreshold() {
uint32_t regVal = readCommonCfgReg();
return static_cast<AxiPtmeConfig::IdlePollThreshold>((regVal >> 3) & 0b111);
}
void AxiPtmeConfig::writeCommonCfgReg(uint32_t value) { writeReg(COMMON_CONFIG_REG, value); }
uint32_t AxiPtmeConfig::readCommonCfgReg() { return readReg(COMMON_CONFIG_REG); }
void AxiPtmeConfig::writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos) {
uint32_t readVal = readReg(regOffset);
uint32_t writeVal =
(readVal & ~(1 << static_cast<uint32_t>(bitPos))) | bitVal << static_cast<uint32_t>(bitPos);
result = writeReg(regOffset, writeVal);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
writeReg(regOffset, writeVal);
}

View File

@ -14,6 +14,16 @@
*/
class AxiPtmeConfig : public SystemObject {
public:
enum IdlePollThreshold : uint8_t {
ALWAYS = 0b000,
POLL_1 = 0b001,
POLL_4 = 0b010,
POLL_16 = 0b011,
POLL_64 = 0b100,
POLL_256 = 0b101,
POLL_1024 = 0b110,
NEVER = 0b111
};
/**
* @brief Constructor
* @param axiUio Device file of UIO belonging to the AXI configuration interface.
@ -40,8 +50,8 @@ class AxiPtmeConfig : public SystemObject {
* Default: Enables TX clock manipulator
*
*/
ReturnValue_t enableTxclockManipulator();
ReturnValue_t disableTxclockManipulator();
void enableTxclockManipulator();
void disableTxclockManipulator();
/**
* @brief The next to functions control whether data will be updated on the rising or falling edge
@ -51,11 +61,14 @@ class AxiPtmeConfig : public SystemObject {
* Disable clock inversion. Data updated on rising edge.
* Default: Inversion is disabled
*/
ReturnValue_t enableTxclockInversion();
ReturnValue_t disableTxclockInversion();
void enableTxclockInversion();
void disableTxclockInversion();
ReturnValue_t enableBatPriorityBit();
ReturnValue_t disableBatPriorityBit();
void enableBatPriorityBit();
void disableBatPriorityBit();
void writePollThreshold(IdlePollThreshold pollThreshold);
IdlePollThreshold readPollThreshold();
private:
// Address of register storing the bitrate configuration parameter
@ -80,7 +93,7 @@ class AxiPtmeConfig : public SystemObject {
*
* @param writeVal Value to write
*/
ReturnValue_t writeReg(uint32_t regOffset, uint32_t writeVal);
void writeReg(uint32_t regOffset, uint32_t writeVal);
/**
* @brief Reads value from configuration register
@ -88,7 +101,10 @@ class AxiPtmeConfig : public SystemObject {
* @param regOffset Offset of register from base address to read from
* Qparam readVal Pointer to variable where read value will be written to
*/
ReturnValue_t readReg(uint32_t regOffset, uint32_t* readVal);
uint32_t readReg(uint32_t regOffset);
uint32_t readCommonCfgReg();
void writeCommonCfgReg(uint32_t value);
/**
* @brief Sets one bit in a register
@ -99,7 +115,7 @@ class AxiPtmeConfig : public SystemObject {
*
* @return returnvalue::OK if successful, otherwise returnvalue::FAILED
*/
ReturnValue_t writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos);
void writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos);
};
#endif /* LINUX_OBC_AXIPTMECONFIG_H_ */

View File

@ -2,6 +2,7 @@
#include <linux/ipcore/PapbVcInterface.h>
#include <unistd.h>
#include <cstring>
#include <ctime>
#include "fsfw/serviceinterface/ServiceInterface.h"
@ -18,29 +19,63 @@ PapbVcInterface::~PapbVcInterface() {}
ReturnValue_t PapbVcInterface::initialize() {
UioMapper uioMapper(uioFile, mapNum);
uint32_t* baseReg;
ReturnValue_t result = uioMapper.getMappedAdress(&baseReg, UioMapper::Permissions::WRITE_ONLY);
ReturnValue_t result = uioMapper.getMappedAdress(const_cast<uint32_t**>(&vcBaseReg),
UioMapper::Permissions::WRITE_ONLY);
if (result != returnvalue::OK) {
return result;
}
vcBaseReg = baseReg;
return returnvalue::OK;
}
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
if (pollPapbBusySignal(0) == returnvalue::OK) {
startPacketTransfer();
// There are no packets smaller than 4, this is considered a configuration error.
if (size < 4) {
return returnvalue::FAILED;
}
if (pollInterfaceReadiness(0, true) == returnvalue::OK) {
startPacketTransfer(ByteWidthCfg::ONE);
} else {
return DirectTmSinkIF::IS_BUSY;
}
// TODO: This should work but does not.. :(
// size_t idx = 0;
// while (idx < size) {
//
// nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
// if ((size - idx) < 4) {
// *vcBaseReg = CONFIG_DATA_INPUT | (size - idx - 1);
// usleep(1);
// }
// if (pollPapbBusySignal(2) == returnvalue::OK) {
// // vcBaseReg + DATA_REG_OFFSET + 3 = static_cast<uint8_t>(data + idx);
// // vcBaseReg + DATA_REG_OFFSET + 2 = static_cast<uint8_t>(data + idx + 1);
// // vcBaseReg + DATA_REG_OFFSET + 1 = static_cast<uint8_t>(data + idx + 2);
// // vcBaseReg + DATA_REG_OFFSET = static_cast<uint8_t>(data + idx + 3);
//
// // std::memcpy((vcBaseReg + DATA_REG_OFFSET), data + idx , nextWriteSize);
// *(vcBaseReg + DATA_REG_OFFSET) = *reinterpret_cast<const uint32_t*>(data + idx);
// //uint8_t* byteReg = reinterpret_cast<uint8_t*>(vcBaseReg + DATA_REG_OFFSET);
//
// //byteReg[0] = data[idx];
// //byteReg[1] = data[idx];
// } else {
// abortPacketTransfer();
// return returnvalue::FAILED;
// }
// // TODO: Change this after the bugfix. Right now, the PAPB ignores the content of the byte
// // width configuration.5
// // It's okay to increment by a larger amount for the last segment here, loop will be over
// // in any case.
// idx += 4;
// }
for (size_t idx = 0; idx < size; idx++) {
// This delay is super-important, DO NOT REMOVE!
// Polling the GPIO too often can mess up the scheduler.
// Polling the GPIO or the config register too often messes up the scheduler.
// TODO: Maybe this should not be done like this. It would be better if there was a custom
// FPGA module which can accept packets and then takes care of dumping that packet into
// the PTME. DMA would be an ideal solution for this.
nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
if (pollPapbBusySignal(2) == returnvalue::OK) {
if (pollInterfaceReadiness(2, false) == returnvalue::OK) {
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
} else {
abortPacketTransfer();
@ -48,7 +83,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
}
}
nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
if (pollPapbBusySignal(2) == returnvalue::OK) {
if (pollInterfaceReadiness(2, false) == returnvalue::OK) {
completePacketTransfer();
} else {
abortPacketTransfer();
@ -57,27 +92,29 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
return returnvalue::OK;
}
void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
*vcBaseReg = CONFIG_DATA_INPUT | initWidth;
}
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const {
gpio::Levels papbBusyState = gpio::Levels::LOW;
ReturnValue_t result;
ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries,
bool checkReadyState) const {
uint32_t busyIdx = 0;
nextDelay.tv_nsec = 0;
nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS;
while (true) {
/** Check if PAPB interface is ready to receive data */
result = gpioComIF->readGpio(papbBusyId, papbBusyState);
if (result != returnvalue::OK) {
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
<< std::endl;
return returnvalue::FAILED;
}
if (papbBusyState == gpio::Levels::HIGH) {
// Check if PAPB interface is ready to receive data. Use the configuration register for this.
// Bit 5, see PTME ptme_001_01-0-7-r2 Table 31.
uint32_t reg = *vcBaseReg;
bool busy = (reg >> 5) & 0b1;
bool ready = (reg >> 6) & 0b1;
if (not busy) {
return returnvalue::OK;
}
if (checkReadyState and not ready) {
return PAPB_BUSY;
}
busyIdx++;
if (busyIdx >= maxPollRetries) {
@ -87,9 +124,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const
// Ignore signal handling here for now.
nanosleep(&nextDelay, &remDelay);
// Adaptive delay.
if (nextDelay.tv_nsec == 0) {
nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS;
} else if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) {
if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) {
nextDelay.tv_nsec *= 2;
}
}
@ -116,7 +151,7 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
return;
}
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0) == PAPB_BUSY; }
bool PapbVcInterface::isBusy() const { return pollInterfaceReadiness(0, true) == PAPB_BUSY; }
void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); }

View File

@ -5,6 +5,8 @@
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <linux/ipcore/VirtualChannelIF.h>
#include <atomic>
#include "OBSWConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
@ -50,13 +52,14 @@ class PapbVcInterface : public VirtualChannelIF {
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
enum ByteWidthCfg : uint32_t { ONE = 0b00, TWO = 0b01, THREE = 0b10, FOUR = 0b11 };
/**
* Configuration bits:
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
* bit[2]: Set this bit to 1 to abort a transferred packet
* bit[3]: Signals to VcInterface the start of a new telemetry packet
*/
static constexpr uint32_t CONFIG_START = 0b00001000;
static constexpr uint32_t CONFIG_DATA_INPUT = 0b00001000;
/**
* Abort a transferred packet.
@ -76,7 +79,7 @@ class PapbVcInterface : public VirtualChannelIF {
*/
static const int DATA_REG_OFFSET = 256;
static constexpr long int FIRST_NON_NULL_DELAY_NS = 10;
static constexpr long int FIRST_DELAY_PAPB_POLLING_NS = 10;
static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40;
LinuxLibgpioIF* gpioComIF = nullptr;
@ -89,7 +92,7 @@ class PapbVcInterface : public VirtualChannelIF {
std::string uioFile;
int mapNum = 0;
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 5};
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10};
mutable struct timespec remDelay;
volatile uint32_t* vcBaseReg = nullptr;
@ -100,7 +103,7 @@ class PapbVcInterface : public VirtualChannelIF {
* @brief This function sends the config byte to the virtual channel of the PTME IP Core
* to initiate a packet transfer.
*/
void startPacketTransfer();
void startPacketTransfer(ByteWidthCfg initWidth);
void abortPacketTransfer();
@ -117,7 +120,7 @@ class PapbVcInterface : public VirtualChannelIF {
*
* @return returnvalue::OK when ready to receive data else PAPB_BUSY.
*/
inline ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries) const;
inline ReturnValue_t pollInterfaceReadiness(uint32_t maxPollRetries, bool checkReadyState) const;
/**
* @brief This function can be used for debugging to check whether there are packets in

View File

@ -26,33 +26,30 @@ ReturnValue_t PtmeConfig::setRate(uint32_t bitRate) {
return axiPtmeConfig->writeCaduRateReg(static_cast<uint8_t>(rateVal));
}
ReturnValue_t PtmeConfig::invertTxClock(bool invert) {
ReturnValue_t result = returnvalue::OK;
void PtmeConfig::invertTxClock(bool invert) {
if (invert) {
result = axiPtmeConfig->enableTxclockInversion();
axiPtmeConfig->enableTxclockInversion();
} else {
result = axiPtmeConfig->disableTxclockInversion();
axiPtmeConfig->disableTxclockInversion();
}
if (result != returnvalue::OK) {
return CLK_INVERSION_FAILED;
}
return result;
}
ReturnValue_t PtmeConfig::configTxManipulator(bool enable) {
ReturnValue_t result = returnvalue::OK;
void PtmeConfig::configTxManipulator(bool enable) {
if (enable) {
result = axiPtmeConfig->enableTxclockManipulator();
axiPtmeConfig->enableTxclockManipulator();
} else {
result = axiPtmeConfig->disableTxclockManipulator();
axiPtmeConfig->disableTxclockManipulator();
}
return result;
}
ReturnValue_t PtmeConfig::enableBatPriorityBit(bool enable) {
void PtmeConfig::enableBatPriorityBit(bool enable) {
if (enable) {
return axiPtmeConfig->enableBatPriorityBit();
axiPtmeConfig->enableBatPriorityBit();
} else {
return axiPtmeConfig->disableBatPriorityBit();
axiPtmeConfig->disableBatPriorityBit();
}
}
void PtmeConfig::setPollThreshold(AxiPtmeConfig::IdlePollThreshold pollThreshold) {
axiPtmeConfig->writePollThreshold(pollThreshold);
}

View File

@ -43,7 +43,7 @@ class PtmeConfig : public SystemObject {
*
* @return REUTRN_OK if successful, otherwise error return value
*/
ReturnValue_t invertTxClock(bool invert);
void invertTxClock(bool invert);
/**
* @brief Controls the tx clock manipulator of the PTME wrapper component
@ -53,7 +53,7 @@ class PtmeConfig : public SystemObject {
*
* @return REUTRN_OK if successful, otherwise error return value
*/
ReturnValue_t configTxManipulator(bool enable);
void configTxManipulator(bool enable);
/**
* Enable the bat priority bit in the PTME wrapper component.
@ -62,7 +62,9 @@ class PtmeConfig : public SystemObject {
* @param enable
* @return
*/
ReturnValue_t enableBatPriorityBit(bool enable);
void enableBatPriorityBit(bool enable);
void setPollThreshold(AxiPtmeConfig::IdlePollThreshold pollThreshold);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::RATE_SETTER;

View File

@ -17,7 +17,7 @@ static constexpr bool DEBUG_MODE = true;
SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_,
GpioIF& gpioInterface,
PowerSwitchIF& mainLineSwitcher_,
pcdu::Switches mainLineSwitch_,
power::Switches mainLineSwitch_,
gpioId_t deplSA1, gpioId_t deplSA2,
SdCardMountedIF& sdcMountedIF)
: SystemObject(setObjectId_),

View File

@ -107,7 +107,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
* @param burnTimeMs Time duration the power will be applied to the burn wires.
*/
SolarArrayDeploymentHandler(object_id_t setObjectId, GpioIF& gpio,
PowerSwitchIF& mainLineSwitcher, pcdu::Switches mainLineSwitch,
PowerSwitchIF& mainLineSwitcher, power::Switches mainLineSwitch,
gpioId_t deplSA1, gpioId_t deplSA2, SdCardMountedIF& sdcMountedIF);
virtual ~SolarArrayDeploymentHandler();

View File

@ -87,12 +87,11 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
*foundLen = remainingSize;
if (remainingSize != sizeof(acs::Adis1650XReply)) {
*foundLen = remainingSize;
return returnvalue::FAILED;
}
*foundId = adis1650x::REPLY;
*foundLen = remainingSize;
if (internalState == InternalState::SHUTDOWN) {
commandExecuted = true;
}

View File

@ -99,12 +99,11 @@ ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
*foundLen = len;
if (len != sizeof(acs::GyroL3gReply)) {
*foundLen = len;
return returnvalue::FAILED;
}
*foundId = l3gd20h::REPLY;
*foundLen = len;
*foundId = adis1650x::REPLY;
if (internalState == InternalState::SHUTDOWN) {
commandExecuted = true;
}

View File

@ -151,19 +151,25 @@ void ImtqHandler::doStartUp() {
}
void ImtqHandler::doShutDown() {
updatePeriodicReply(false, imtq::cmdIds::REPLY_NO_TORQUE);
updatePeriodicReply(false, imtq::cmdIds::REPLY_WITH_TORQUE);
specialRequestActive = false;
firstReplyCycle = true;
internalState = InternalState::NONE;
commandExecuted = false;
statusSet.setValidity(false, true);
rawMtmNoTorque.setValidity(false, true);
rawMtmWithTorque.setValidity(false, true);
hkDatasetNoTorque.setValidity(false, true);
hkDatasetWithTorque.setValidity(false, true);
calMtmMeasurementSet.setValidity(false, true);
setMode(_MODE_POWER_DOWN);
if (internalState != InternalState::SHUTDOWN) {
commandExecuted = false;
internalState = InternalState::SHUTDOWN;
}
if (internalState == InternalState::SHUTDOWN and commandExecuted) {
updatePeriodicReply(false, imtq::cmdIds::REPLY_NO_TORQUE);
updatePeriodicReply(false, imtq::cmdIds::REPLY_WITH_TORQUE);
specialRequestActive = false;
firstReplyCycle = true;
internalState = InternalState::NONE;
commandExecuted = false;
statusSet.setValidity(false, true);
rawMtmNoTorque.setValidity(false, true);
rawMtmWithTorque.setValidity(false, true);
hkDatasetNoTorque.setValidity(false, true);
hkDatasetWithTorque.setValidity(false, true);
calMtmMeasurementSet.setValidity(false, true);
setMode(_MODE_POWER_DOWN);
}
}
ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
@ -178,7 +184,7 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
}
default: {
*id = imtq::cmdIds::REQUEST;
request.request = imtq::RequestType::DO_NOTHING;
request.requestType = imtq::RequestType::DO_NOTHING;
request.specialRequest = imtq::SpecialRequest::NONE;
expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
rawPacket = reinterpret_cast<uint8_t*>(&request);
@ -190,7 +196,7 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
}
ReturnValue_t ImtqHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
if (internalState == InternalState::STARTUP) {
if (internalState == InternalState::STARTUP or internalState == InternalState::SHUTDOWN) {
*id = imtq::cmdIds::REQUEST;
return buildCommandFromCommand(*id, nullptr, 0);
}
@ -201,7 +207,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
const uint8_t* commandData,
size_t commandDataLen) {
auto genericSpecialRequest = [&](imtq::SpecialRequest specialRequest) {
request.request = imtq::RequestType::MEASURE_NO_ACTUATION;
request.requestType = imtq::RequestType::MEASURE_NO_ACTUATION;
request.specialRequest = specialRequest;
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
specialRequestActive = true;
@ -238,9 +244,16 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
return returnvalue::OK;
}
case (imtq::cmdIds::REQUEST): {
request.request = imtq::RequestType::MEASURE_NO_ACTUATION;
request.requestType = imtq::RequestType::MEASURE_NO_ACTUATION;
request.specialRequest = imtq::SpecialRequest::NONE;
// 6 ms integration time instead of 10 ms.
request.integrationTimeSel = 2;
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
if (internalState == InternalState::SHUTDOWN) {
request.mode = acs::SimpleSensorMode::OFF;
} else {
request.mode = acs::SimpleSensorMode::NORMAL;
}
rawPacket = reinterpret_cast<uint8_t*>(&request);
rawPacketLen = sizeof(imtq::Request);
return returnvalue::OK;
@ -267,7 +280,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
}
expectedReply = imtq::cmdIds::REPLY_WITH_TORQUE;
request.request = imtq::RequestType::ACTUATE;
request.requestType = imtq::RequestType::ACTUATE;
request.specialRequest = imtq::SpecialRequest::NONE;
std::memcpy(request.dipoles, dipoleSet.dipoles.value, sizeof(request.dipoles));
request.torqueDuration = dipoleSet.currentTorqueDurationMs.value;
@ -309,6 +322,9 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
if (internalState == InternalState::SHUTDOWN) {
commandExecuted = true;
}
if (remainingSize > 0) {
*foundLen = remainingSize;
*foundId = expectedReply;
@ -779,9 +795,9 @@ ReturnValue_t ImtqHandler::initializeLocalDataPool(localpool::DataPool& localDat
localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0}));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 12.0));
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 30.0));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 12.0));
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 30.0));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0));
poolManager.subscribeForDiagPeriodicPacket(

View File

@ -55,6 +55,10 @@ void RwHandler::doShutDown() {
PoolReadGuard pg(&tmDataset);
tmDataset.setValidity(false, true);
}
{
PoolReadGuard pg(&rwSpeedActuationSet);
rwSpeedActuationSet.setRwSpeed(0, 10);
}
// The power switch is handled by the assembly, so we can go off here directly.
setMode(MODE_OFF);
}

View File

@ -1,13 +1,13 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_ACSPOLLING_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_ACSPOLLING_H_
#include <mission/acs/defs.h>
#include "fsfw/thermal/tcsDefinitions.h"
#include "gyroAdisHelpers.h"
namespace acs {
enum SimpleSensorMode { NORMAL = 0, OFF = 1 };
struct Adis1650XRequest {
SimpleSensorMode mode;
adis1650x::Type type;

View File

@ -6,6 +6,8 @@
namespace acs {
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
// These modes are the submodes of the ACS controller and the modes of the ACS subsystem.
enum AcsMode : Mode_t {
OFF = HasModesIF::MODE_OFF,

View File

@ -1,5 +1,26 @@
#include "imtqHelpers.h"
uint16_t imtq::integrationTimeFromSelectValue(uint8_t value) {
switch (value) {
case (0):
return 2;
case (1):
return 3;
case (2):
return 6;
case (3):
return 10;
case (4):
return 20;
case (5):
return 40;
case (6):
return 80;
default:
return 10;
}
}
size_t imtq::getReplySize(CC::CC cc, size_t* optSecondSize) {
switch (cc) {
// Software reset is a bit special and can also cause a I2C NAK because

View File

@ -5,6 +5,7 @@
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <mission/acs/defs.h>
class ImtqHandler;
@ -13,6 +14,8 @@ class ImtqHandler;
namespace imtq {
uint16_t integrationTimeFromSelectValue(uint8_t value);
enum class RequestType : uint8_t { MEASURE_NO_ACTUATION, ACTUATE, DO_NOTHING };
enum class SpecialRequest : uint8_t {
@ -27,7 +30,8 @@ enum class SpecialRequest : uint8_t {
};
struct Request {
imtq::RequestType request = imtq::RequestType::MEASURE_NO_ACTUATION;
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
imtq::RequestType requestType = imtq::RequestType::MEASURE_NO_ACTUATION;
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
uint8_t integrationTimeSel = 3;
int16_t dipoles[3]{};
@ -57,9 +61,10 @@ static const ReturnValue_t CC_UNAVAILABLE = MAKE_RETURN_CODE(5);
static const ReturnValue_t INTERNAL_PROCESSING_ERROR = MAKE_RETURN_CODE(6);
static const ReturnValue_t REJECTED_WITHOUT_REASON = MAKE_RETURN_CODE(7);
static const ReturnValue_t CMD_ERR_UNKNOWN = MAKE_RETURN_CODE(8);
static constexpr ReturnValue_t STARTUP_CFG_ERROR = MAKE_RETURN_CODE(9);
//! [EXPORT] : [COMMENT] The status reply to a self test command was received but no self test
//! command has been sent. This should normally never happen.
static const ReturnValue_t UNEXPECTED_SELF_TEST_REPLY = MAKE_RETURN_CODE(0xA7);
static const ReturnValue_t UNEXPECTED_SELF_TEST_REPLY = MAKE_RETURN_CODE(10);
namespace cmdIds {
@ -162,6 +167,13 @@ enum CC : uint8_t {
} // namespace CC
namespace param {
static constexpr uint16_t SEL_MTM = 0x2002;
static constexpr uint16_t INTEGRATION_TIME_SELECT = 0x2003;
} // namespace param
size_t getReplySize(CC::CC cc, size_t* optSecondSize = nullptr);
namespace mode {

View File

@ -56,6 +56,49 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
StarTrackerHandler::~StarTrackerHandler() {}
void StarTrackerHandler::doStartUp() {
switch (startupState) {
case StartupState::IDLE:
startupState = StartupState::CHECK_PROGRAM;
return;
case StartupState::BOOT_BOOTLOADER:
// This step is required in case the star tracker is already in firmware mode to harmonize
// the device handler's submode to the star tracker's mode
return;
case StartupState::DONE:
if (jcfgCountdown.isBusy()) {
startupState = StartupState::WAIT_JCFG;
return;
}
startupState = StartupState::IDLE;
break;
case StartupState::WAIT_JCFG: {
if (jcfgCountdown.hasTimedOut()) {
startupState = StartupState::IDLE;
break;
}
return;
}
default:
return;
}
solutionSet.setReportingEnabled(true);
startupState = StartupState::DONE;
internalState = InternalState::IDLE;
setMode(_MODE_TO_ON);
}
void StarTrackerHandler::doShutDown() {
// If the star tracker is shutdown also stop all running processes in the image loader task
strHelper->stopProcess();
internalState = InternalState::IDLE;
startupState = StartupState::IDLE;
bootState = FwBootState::NONE;
solutionSet.setReportingEnabled(false);
reinitNextSetParam = false;
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t StarTrackerHandler::initialize() {
ReturnValue_t result = returnvalue::OK;
result = DeviceHandlerBase::initialize();
@ -213,6 +256,8 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
default:
break;
}
// In case the JSON has changed, reinitiate the next parameter set to update.
reinitNextSetParam = true;
return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size);
}
@ -232,49 +277,7 @@ void StarTrackerHandler::performOperationHook() {
}
}
Submode_t StarTrackerHandler::getInitialSubmode() { return SUBMODE_BOOTLOADER; }
void StarTrackerHandler::doStartUp() {
switch (startupState) {
case StartupState::IDLE:
startupState = StartupState::CHECK_PROGRAM;
return;
case StartupState::BOOT_BOOTLOADER:
// This step is required in case the star tracker is already in firmware mode to harmonize
// the device handler's submode to the star tracker's mode
return;
case StartupState::DONE:
if (jcfgCountdown.isBusy()) {
startupState = StartupState::WAIT_JCFG;
return;
}
startupState = StartupState::IDLE;
break;
case StartupState::WAIT_JCFG: {
if (jcfgCountdown.hasTimedOut()) {
startupState = StartupState::IDLE;
break;
}
return;
}
default:
return;
}
solutionSet.setReportingEnabled(true);
startupState = StartupState::DONE;
internalState = InternalState::IDLE;
setMode(_MODE_TO_ON);
}
void StarTrackerHandler::doShutDown() {
// If the star tracker is shutdown also stop all running processes in the image loader task
strHelper->stopProcess();
internalState = InternalState::IDLE;
startupState = StartupState::IDLE;
bootState = FwBootState::NONE;
solutionSet.setReportingEnabled(false);
setMode(_MODE_POWER_DOWN);
}
Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; }
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
if (strHelperHandlingSpecialRequest) {
@ -313,6 +316,8 @@ ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t
if (bootCountdown.isBusy()) {
return NOTHING_TO_SEND;
}
// Was already done.
reinitNextSetParam = false;
bootState = FwBootState::REQ_VERSION;
}
switch (bootState) {
@ -461,7 +466,8 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
return returnvalue::OK;
}
case (startracker::SUBSCRIPTION): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.subscription);
result =
prepareParamCommand(commandData, commandDataLen, jcfgs.subscription, reinitNextSetParam);
return returnvalue::OK;
}
case (startracker::REQ_SOLUTION): {
@ -477,55 +483,60 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
return returnvalue::OK;
}
case (startracker::LIMITS): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits, reinitNextSetParam);
return result;
}
case (startracker::MOUNTING): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting, reinitNextSetParam);
return result;
}
case (startracker::IMAGE_PROCESSOR): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor,
reinitNextSetParam);
return result;
}
case (startracker::CAMERA): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera, reinitNextSetParam);
return result;
}
case (startracker::CENTROIDING): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding);
result =
prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding, reinitNextSetParam);
return result;
}
case (startracker::LISA): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa, reinitNextSetParam);
return result;
}
case (startracker::MATCHING): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching, reinitNextSetParam);
return result;
}
case (startracker::VALIDATION): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.validation);
result =
prepareParamCommand(commandData, commandDataLen, jcfgs.validation, reinitNextSetParam);
return result;
}
case (startracker::ALGO): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo, reinitNextSetParam);
return result;
}
case (startracker::TRACKING): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking, reinitNextSetParam);
return result;
}
case (startracker::LOGLEVEL): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel, reinitNextSetParam);
return result;
}
case (startracker::LOGSUBSCRIPTION): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription,
reinitNextSetParam);
return result;
}
case (startracker::DEBUG_CAMERA): {
result = prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera);
result =
prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera, reinitNextSetParam);
return result;
}
case (startracker::CHECKSUM): {
@ -694,7 +705,7 @@ ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t
return INVALID_SUBMODE;
}
case MODE_ON:
if (submode == SUBMODE_BOOTLOADER || submode == SUBMODE_FIRMWARE) {
if (submode == startracker::SUBMODE_BOOTLOADER || submode == startracker::SUBMODE_FIRMWARE) {
return returnvalue::OK;
} else {
return INVALID_SUBMODE;
@ -725,6 +736,7 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
}
void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
using namespace startracker;
uint8_t dhbSubmode = getSubmode();
// We hide that the transition to submode firmware actually goes through the submode bootloader.
// This is because the startracker always starts in bootloader mode but we want to allow direct
@ -751,6 +763,7 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
}
void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom) {
using namespace startracker;
if (subModeFrom == SUBMODE_FIRMWARE) {
setMode(MODE_NORMAL);
} else if (subModeFrom == SUBMODE_BOOTLOADER) {
@ -776,7 +789,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
if (toMode == MODE_NORMAL) {
setMode(toMode, 0);
} else {
setMode(toMode, SUBMODE_FIRMWARE);
setMode(toMode, startracker::SUBMODE_FIRMWARE);
}
sif::info << "STR: Firmware boot success" << std::endl;
internalState = InternalState::IDLE;
@ -820,7 +833,6 @@ void StarTrackerHandler::bootBootloader() {
ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
ReturnValue_t result = returnvalue::OK;
size_t bytesLeft = 0;
if (remainingSize == 0) {
*foundLen = remainingSize;
@ -834,24 +846,24 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t* start, size_t rema
switch (startracker::getReplyFrameType(start)) {
case TMTC_ACTIONREPLY: {
*foundLen = remainingSize - bytesLeft;
result = scanForActionReply(startracker::getId(start), foundId);
*foundLen = remainingSize;
return scanForActionReply(startracker::getId(start), foundId);
break;
}
case TMTC_SETPARAMREPLY: {
*foundLen = remainingSize - bytesLeft;
result = scanForSetParameterReply(startracker::getId(start), foundId);
*foundLen = remainingSize;
return scanForSetParameterReply(startracker::getId(start), foundId);
break;
}
case TMTC_PARAMREPLY: {
*foundLen = remainingSize - bytesLeft;
result = scanForGetParameterReply(startracker::getId(start), foundId);
*foundLen = remainingSize;
return scanForGetParameterReply(startracker::getId(start), foundId);
break;
}
case TMTC_TELEMETRYREPLYA:
case TMTC_TELEMETRYREPLY: {
*foundLen = remainingSize - bytesLeft;
result = scanForTmReply(startracker::getId(start), foundId);
*foundLen = remainingSize;
return scanForTmReply(startracker::getId(start), foundId);
break;
}
default: {
@ -859,9 +871,6 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t* start, size_t rema
result = returnvalue::FAILED;
}
}
remainingSize = bytesLeft;
return result;
}
@ -1690,12 +1699,19 @@ void StarTrackerHandler::prepareHistogramRequest() {
ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData,
size_t commandDataLen,
ArcsecJsonParamBase& paramSet) {
ArcsecJsonParamBase& paramSet,
bool reinitSet) {
// Stopwatch watch;
ReturnValue_t result = returnvalue::OK;
if (commandDataLen > MAX_PATH_SIZE) {
return FILE_PATH_TOO_LONG;
}
if (reinitSet) {
result = paramSet.init(paramJsonFile);
if (result != returnvalue::OK) {
return result;
}
}
result = paramSet.create(commandBuffer);
if (result != returnvalue::OK) {

View File

@ -54,9 +54,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
Submode_t getInitialSubmode() override;
static const Submode_t SUBMODE_BOOTLOADER = 1;
static const Submode_t SUBMODE_FIRMWARE = 2;
protected:
void doStartUp() override;
void doShutDown() override;
@ -287,6 +284,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
InternalState internalState = InternalState::IDLE;
bool reinitNextSetParam = false;
bool strHelperHandlingSpecialRequest = false;
const power::Switch_t powerSwitch = power::NO_SWITCH;
@ -409,7 +408,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
* @return returnvalue::OK if successful, otherwise error return Value
*/
ReturnValue_t prepareParamCommand(const uint8_t* commandData, size_t commandDataLen,
ArcsecJsonParamBase& paramSet);
ArcsecJsonParamBase& paramSet, bool reinitSet);
/**
* @brief The following function will fill the command buffer with the command to request

View File

@ -11,6 +11,9 @@
namespace startracker {
static const Submode_t SUBMODE_BOOTLOADER = 1;
static const Submode_t SUBMODE_FIRMWARE = 2;
/**
* @brief Returns the frame type field of a decoded frame.
*/

View File

@ -1,2 +1,11 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE SyrlinksHandler.cpp
CcsdsIpCoreHandler.cpp)
target_sources(
${LIB_EIVE_MISSION}
PRIVATE SyrlinksHandler.cpp
CcsdsIpCoreHandler.cpp
LiveTmTask.cpp
PersistentLogTmStoreTask.cpp
TmStoreTaskBase.cpp
VirtualChannel.cpp
VirtualChannelWithQueue.cpp
PersistentSingleTmStoreTask.cpp
LiveTmTask.cpp)

View File

@ -15,9 +15,11 @@
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination,
PtmeConfig& ptmeConfig, std::atomic_bool& linkState,
GpioIF* gpioIF, PtmeGpios gpioIds)
GpioIF* gpioIF, PtmeGpios gpioIds,
std::atomic_bool& ptmeLocked)
: SystemObject(objectId),
linkState(linkState),
ptmeLocked(ptmeLocked),
tcDestination(tcDestination),
parameterHelper(this),
actionHelper(this, nullptr),
@ -29,12 +31,14 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDesti
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
eventQueue =
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
ptmeLocked = true;
}
CcsdsIpCoreHandler::~CcsdsIpCoreHandler() = default;
ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) {
readCommandQueue();
performPtmeUpdateWhenApplicable();
return returnvalue::OK;
}
@ -71,11 +75,11 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
}
// This also pulls the PTME out of reset state.
if (batPriorityParam == 0) {
disablePrioritySelectMode();
} else {
enablePrioritySelectMode();
}
updateBatPriorityFromParam();
ptmeConfig.setPollThreshold(
static_cast<AxiPtmeConfig::IdlePollThreshold>(params.pollThresholdParam));
resetPtme();
ptmeLocked = false;
#if OBSW_SYRLINKS_SIMULATED == 1
// Update data on rising edge
@ -117,7 +121,10 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues,
uint16_t startAtIndex) {
if ((domainId == 0) and (uniqueIdentifier == ParamId::BAT_PRIORITY)) {
if (domainId != 0) {
return HasParametersIF::INVALID_DOMAIN_ID;
}
if (uniqueIdentifier == ParamId::BAT_PRIORITY) {
uint8_t newVal = 0;
ReturnValue_t result = newValues->getElement(&newVal);
if (result != returnvalue::OK) {
@ -126,11 +133,33 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
if (newVal > 1) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(batPriorityParam);
if (mode == MODE_ON) {
updateBatPriorityOnTxOff = true;
} else if (mode == MODE_OFF) {
updateBatPriorityFromParam();
parameterWrapper->set(params.batPriorityParam);
if (newVal != params.batPriorityParam) {
// This ensures that the BAT priority is updated at some point when an update of the PTME is
// allowed
updateContext.updateBatPrio = true;
// If we are off, we can do the update after X cycles. Otherwise, wait until the transmitter
// goes off.
if (mode == MODE_OFF) {
initPtmeUpdateAfterXCycles();
}
}
return returnvalue::OK;
} else if (uniqueIdentifier == ParamId::POLL_THRESHOLD) {
uint8_t newVal = 0;
ReturnValue_t result = newValues->getElement(&newVal);
if (result != returnvalue::OK) {
return result;
}
if (newVal > static_cast<uint8_t>(AxiPtmeConfig::NEVER)) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(newVal);
if (newVal != params.pollThresholdParam) {
updateContext.updatePollThreshold = true;
if (mode == MODE_OFF) {
initPtmeUpdateAfterXCycles();
}
}
return returnvalue::OK;
}
@ -148,50 +177,33 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
const uint8_t* data, size_t size) {
ReturnValue_t result = returnvalue::OK;
switch (actionId) {
case SET_LOW_RATE: {
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW);
result = ptmeConfig.setRate(RATE_100KBPS);
break;
}
case SET_HIGH_RATE: {
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH);
result = ptmeConfig.setRate(RATE_500KBPS);
break;
}
case ARBITRARY_RATE: {
uint32_t bitrate = 0;
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
result = ptmeConfig.setRate(bitrate);
result = SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
ptmeConfig.setRate(bitrate);
updateContext.updateClockRate = true;
if (mode == MODE_OFF) {
initPtmeUpdateAfterXCycles();
}
break;
}
case EN_TRANSMITTER: {
enableTransmit();
if (mode == HasModesIF::MODE_OFF) {
mode = HasModesIF::MODE_ON;
}
return EXECUTION_FINISHED;
}
case DISABLE_TRANSMITTER: {
disableTransmit();
if (mode == HasModesIF::MODE_ON) {
mode = HasModesIF::MODE_OFF;
}
return EXECUTION_FINISHED;
}
case ENABLE_TX_CLK_MANIPULATOR: {
result = ptmeConfig.configTxManipulator(true);
ptmeConfig.configTxManipulator(true);
break;
}
case DISABLE_TX_CLK_MANIPULATOR: {
result = ptmeConfig.configTxManipulator(false);
ptmeConfig.configTxManipulator(false);
break;
}
case UPDATE_ON_RISING_EDGE: {
result = ptmeConfig.invertTxClock(false);
ptmeConfig.invertTxClock(false);
break;
}
case UPDATE_ON_FALLING_EDGE: {
result = ptmeConfig.invertTxClock(true);
ptmeConfig.invertTxClock(true);
break;
}
default:
@ -206,12 +218,8 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
void CcsdsIpCoreHandler::enableTransmit() {
// Reset PTME on each transmit enable.
updateBatPriorityFromParam();
#ifndef TE0720_1CFA
gpioIF->pullHigh(ptmeGpios.enableTxClock);
gpioIF->pullHigh(ptmeGpios.enableTxData);
#endif
linkState = LINK_UP;
}
@ -236,34 +244,23 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod
}
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
auto rateSet = [&](uint32_t rate) {
ReturnValue_t result = ptmeConfig.setRate(rate);
if (result == returnvalue::OK) {
this->mode = HasModesIF::MODE_ON;
}
};
triggerEvent(CHANGING_MODE, mode, submode);
if (mode == HasModesIF::MODE_ON) {
enableTransmit();
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
com::Datarate currentDatarate = com::getCurrentDatarate();
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
rateSet(RATE_100KBPS);
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
rateSet(RATE_500KBPS);
}
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
rateSet(RATE_500KBPS);
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
rateSet(RATE_100KBPS);
if (this->submode != submode) {
initPtmeUpdateAfterXCycles();
updateContext.enableTransmitAfterPtmeUpdate = true;
updateContext.updateClockRate = true;
this->submode = submode;
this->mode = mode;
updateContext.setModeAfterUpdate = true;
return;
}
// No rate change, so enable transmitter right away.
enableTransmit();
} else if (mode == HasModesIF::MODE_OFF) {
disableTransmit();
this->mode = HasModesIF::MODE_OFF;
}
this->submode = submode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
setMode(mode, submode);
}
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
@ -274,9 +271,9 @@ void CcsdsIpCoreHandler::disableTransmit() {
gpioIF->pullLow(ptmeGpios.enableTxData);
#endif
linkState = LINK_DOWN;
if (updateBatPriorityOnTxOff) {
updateBatPriorityFromParam();
updateBatPriorityOnTxOff = false;
// Some parameters need update and transmitter is off now.
if (updateContext.updateBatPrio or updateContext.updateClockRate) {
initPtmeUpdateAfterXCycles();
}
}
@ -294,26 +291,95 @@ ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; }
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }
void CcsdsIpCoreHandler::enablePrioritySelectMode() {
ptmeConfig.enableBatPriorityBit(true);
// Reset the PTME
gpioIF->pullLow(ptmeGpios.ptmeResetn);
usleep(10);
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
}
void CcsdsIpCoreHandler::enablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(true); }
void CcsdsIpCoreHandler::disablePrioritySelectMode() {
ptmeConfig.enableBatPriorityBit(false);
// Reset the PTME
gpioIF->pullLow(ptmeGpios.ptmeResetn);
usleep(10);
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
}
void CcsdsIpCoreHandler::disablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(false); }
void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
if (batPriorityParam == 0) {
if (params.batPriorityParam == 0) {
disablePrioritySelectMode();
} else {
enablePrioritySelectMode();
}
}
void CcsdsIpCoreHandler::setMode(Mode_t mode, Submode_t submode) {
this->submode = submode;
this->mode = mode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
void CcsdsIpCoreHandler::performPtmeUpdateWhenApplicable() {
if (not updateContext.performPtmeUpdateAfterXCycles) {
return;
}
if (updateContext.ptmeUpdateCycleCount >= 2) {
bool doResetPtme = false;
if (updateContext.updateBatPrio) {
updateBatPriorityFromParam();
updateContext.updateBatPrio = false;
doResetPtme = true;
}
if (updateContext.updatePollThreshold) {
ptmeConfig.setPollThreshold(
static_cast<AxiPtmeConfig::IdlePollThreshold>(params.pollThresholdParam));
updateContext.updatePollThreshold = false;
doResetPtme = true;
}
ReturnValue_t result = returnvalue::OK;
if (updateContext.updateClockRate) {
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
com::Datarate currentDatarate = com::getCurrentDatarate();
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
result = ptmeConfig.setRate(RATE_100KBPS);
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
result = ptmeConfig.setRate(RATE_500KBPS);
}
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
result = ptmeConfig.setRate(RATE_500KBPS);
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
result = ptmeConfig.setRate(RATE_100KBPS);
}
if (result != returnvalue::OK) {
sif::error << "CcsdsIpCoreHandler: Setting datarate failed" << std::endl;
}
updateContext.updateClockRate = false;
doResetPtme = true;
}
finishPtmeUpdateAfterXCycles(doResetPtme);
return;
}
updateContext.ptmeUpdateCycleCount++;
}
void CcsdsIpCoreHandler::resetPtme() {
gpioIF->pullLow(ptmeGpios.ptmeResetn);
usleep(10);
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
}
void CcsdsIpCoreHandler::initPtmeUpdateAfterXCycles() {
if (not updateContext.performPtmeUpdateAfterXCycles) {
updateContext.performPtmeUpdateAfterXCycles = true;
updateContext.ptmeUpdateCycleCount = 0;
ptmeLocked = true;
}
}
void CcsdsIpCoreHandler::finishPtmeUpdateAfterXCycles(bool doResetPtme) {
if (doResetPtme) {
resetPtme();
}
ptmeLocked = false;
updateContext.performPtmeUpdateAfterXCycles = false;
updateContext.ptmeUpdateCycleCount = 0;
if (updateContext.enableTransmitAfterPtmeUpdate) {
enableTransmit();
updateContext.enableTransmitAfterPtmeUpdate = false;
}
if (updateContext.setModeAfterUpdate) {
setMode(mode, submode);
updateContext.setModeAfterUpdate = false;
}
}

View File

@ -2,7 +2,7 @@
#define CCSDSHANDLER_H_
#include <fsfw/modes/HasModesIF.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <cstdint>
#include <unordered_map>
@ -60,7 +60,7 @@ class CcsdsIpCoreHandler : public SystemObject,
public ReceivesParameterMessagesIF,
public HasActionsIF {
public:
enum ParamId : uint8_t { BAT_PRIORITY = 0 };
enum ParamId : uint8_t { BAT_PRIORITY = 0, POLL_THRESHOLD = 1 };
static const bool LINK_UP = true;
static const bool LINK_DOWN = false;
@ -79,7 +79,8 @@ class CcsdsIpCoreHandler : public SystemObject,
* @param enTxData GPIO ID of RS485 tx data enable
*/
CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig,
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds);
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds,
std::atomic_bool& ptmeLocked);
~CcsdsIpCoreHandler();
@ -137,9 +138,8 @@ class CcsdsIpCoreHandler : public SystemObject,
//! [EXPORT] : [COMMENT] Received action message with unknown action id
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
// using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannelWithQueue*>;
// VirtualChannelMap virtualChannelMap;
std::atomic_bool& linkState;
std::atomic_bool& ptmeLocked;
object_id_t tcDestination;
@ -156,9 +156,22 @@ class CcsdsIpCoreHandler : public SystemObject,
PtmeConfig& ptmeConfig;
PtmeGpios ptmeGpios;
// BAT priority bit on by default to enable priority selection mode for the PTME.
uint8_t batPriorityParam = 0;
bool updateBatPriorityOnTxOff = false;
struct Parameters {
// BAT priority bit on by default to enable priority selection mode for the PTME.
uint8_t batPriorityParam = 0;
uint8_t pollThresholdParam = static_cast<uint8_t>(AxiPtmeConfig::IdlePollThreshold::POLL_4);
} params;
struct UpdateContext {
bool updateBatPrio = false;
bool updateClockRate = false;
bool updatePollThreshold = false;
bool enableTransmitAfterPtmeUpdate = false;
uint8_t ptmeUpdateCycleCount = 0;
bool performPtmeUpdateAfterXCycles = false;
bool setModeAfterUpdate = false;
} updateContext{};
GpioIF* gpioIF = nullptr;
@ -180,6 +193,8 @@ class CcsdsIpCoreHandler : public SystemObject,
*/
void disableTransmit();
void performPtmeUpdateWhenApplicable();
/**
* The following set of functions configure the mode of the PTME bandwith allocation table (BAT)
* module. This consists of the following 2 steps:
@ -189,6 +204,11 @@ class CcsdsIpCoreHandler : public SystemObject,
void enablePrioritySelectMode();
void disablePrioritySelectMode();
void updateBatPriorityFromParam();
void setMode(Mode_t mode, Submode_t submode);
void resetPtme();
void initPtmeUpdateAfterXCycles();
void finishPtmeUpdateAfterXCycles(bool doResetPtme);
};
#endif /* CCSDSHANDLER_H_ */

107
mission/com/LiveTmTask.cpp Normal file
View File

@ -0,0 +1,107 @@
#include "LiveTmTask.h"
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/subsystem/helper.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked)
: SystemObject(objectId),
modeHelper(this),
pusFunnel(pusFunnel),
cfdpFunnel(cfdpFunnel),
channel(channel),
ptmeLocked(ptmeLocked) {
requestQueue = QueueFactory::instance()->createMessageQueue();
}
ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
readCommandQueue();
while (true) {
bool performWriteOp = true;
if (mode == MODE_OFF or ptmeLocked) {
performWriteOp = false;
}
// The funnel tasks are scheduled here directly as well.
ReturnValue_t result = channel.handleNextTm(performWriteOp);
if (result == DirectTmSinkIF::IS_BUSY) {
sif::error << "Lost live TM, PAPB busy" << std::endl;
}
if (result == MessageQueueIF::EMPTY) {
if (tmFunnelCd.hasTimedOut()) {
pusFunnel.performOperation(0);
cfdpFunnel.performOperation(0);
tmFunnelCd.resetTimer();
}
// Read command queue during idle times.
readCommandQueue();
// 40 ms IDLE delay. Might tweak this in the future.
TaskFactory::delayTask(40);
} else {
packetCounter++;
}
}
}
MessageQueueId_t LiveTmTask::getCommandQueue() const { return requestQueue->getId(); }
void LiveTmTask::getMode(Mode_t* mode, Submode_t* submode) {
if (mode != nullptr) {
*mode = this->mode;
}
if (submode != nullptr) {
*submode = SUBMODE_NONE;
}
}
ReturnValue_t LiveTmTask::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if (mode == MODE_ON or mode == MODE_OFF) {
return returnvalue::OK;
}
return returnvalue::FAILED;
}
void LiveTmTask::startTransition(Mode_t mode, Submode_t submode) {
this->mode = mode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
void LiveTmTask::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); }
object_id_t LiveTmTask::getObjectId() const { return SystemObject::getObjectId(); }
const HasHealthIF* LiveTmTask::getOptHealthIF() const { return nullptr; }
const HasModesIF& LiveTmTask::getModeIF() const { return *this; }
ReturnValue_t LiveTmTask::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
}
void LiveTmTask::readCommandQueue(void) {
CommandMessage commandMessage;
ReturnValue_t result = returnvalue::FAILED;
result = requestQueue->receiveMessage(&commandMessage);
if (result == returnvalue::OK) {
result = modeHelper.handleModeCommand(&commandMessage);
if (result == returnvalue::OK) {
return;
}
CommandMessage reply;
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
requestQueue->reply(&reply);
return;
}
}
ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; }
ReturnValue_t LiveTmTask::initialize() {
modeHelper.initialize();
return returnvalue::OK;
}

57
mission/com/LiveTmTask.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef MISSION_TMTC_LIVETMTASK_H_
#define MISSION_TMTC_LIVETMTASK_H_
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/subsystem/ModeTreeChildIF.h>
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PusTmFunnel.h>
class LiveTmTask : public SystemObject,
public HasModesIF,
public ExecutableObjectIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF {
public:
LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked);
ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override;
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
private:
MessageQueueIF* requestQueue;
ModeHelper modeHelper;
Mode_t mode = HasModesIF::MODE_OFF;
Countdown tmFunnelCd = Countdown(100);
PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel;
VirtualChannelWithQueue& channel;
uint32_t packetCounter = 0;
const std::atomic_bool& ptmeLocked;
void readCommandQueue(void);
MessageQueueId_t getCommandQueue() const override;
void getMode(Mode_t* mode, Submode_t* submode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
void startTransition(Mode_t mode, Submode_t submode) override;
void announceMode(bool recursive) override;
object_id_t getObjectId() const override;
const HasHealthIF* getOptHealthIF() const override;
const HasModesIF& getModeIF() const override;
ModeTreeChildIF& getModeTreeChildIF() override;
};
#endif /* MISSION_TMTC_LIVETMTASK_H_ */

View File

@ -5,8 +5,9 @@
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
LogStores stores, VirtualChannel& channel,
SdCardMountedIF& sdcMan)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
stores(stores),
okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED),
notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED),
@ -27,6 +28,8 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
}
};
while (true) {
readCommandQueue();
if (not cyclicStoreCheck()) {
continue;
}
@ -40,6 +43,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
TaskFactory::delayTask(100);
} else if (vcBusyDuringDump) {
// TODO: Might not be necessary
sif::debug << "VC busy, delaying" << std::endl;
TaskFactory::delayTask(10);
}
}
@ -54,3 +58,17 @@ bool PersistentLogTmStoreTask::initStoresIfPossible() {
}
return false;
}
void PersistentLogTmStoreTask::startTransition(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
bool channelIsOn = channel.isTxOn();
cancelDump(okStoreContext, stores.okStore, channelIsOn);
cancelDump(notOkStoreContext, stores.notOkStore, channelIsOn);
cancelDump(miscStoreContext, stores.miscStore, channelIsOn);
this->mode = MODE_OFF;
} else if (mode == MODE_ON) {
this->mode = MODE_ON;
}
modeHelper.modeChanged(mode, submode);
announceMode(false);
}

View File

@ -5,11 +5,11 @@
#include <fsfw/storagemanager/StorageManagerIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <mission/com/TmStoreTaskBase.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/genericFactory.h>
#include <mission/tmtc/PersistentTmStore.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/TmStoreTaskBase.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
struct LogStores {
LogStores(PersistentTmStores& stores)
@ -22,7 +22,8 @@ struct LogStores {
class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
public:
PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore,
VirtualChannel& channel, SdCardMountedIF& sdcMan);
VirtualChannel& channel, SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked);
ReturnValue_t performOperation(uint8_t opCode) override;
@ -36,6 +37,7 @@ class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObject
bool someFileWasSwapped = false;
bool initStoresIfPossible() override;
void startTransition(Mode_t mode, Submode_t submode) override;
};
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */

View File

@ -1,17 +1,21 @@
#include "PersistentSingleTmStoreTask.h"
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
#include <unistd.h>
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
storeWithQueue(tmStore),
dumpContext(eventIfDumpDone, eventIfCancelled) {}
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
while (true) {
readCommandQueue();
// Delay done by the check
if (not cyclicStoreCheck()) {
continue;
@ -20,8 +24,12 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
if (not busy) {
TaskFactory::delayTask(100);
} else if (dumpContext.vcBusyDuringDump) {
sif::debug << "VC busy, delaying" << std::endl;
// TODO: Might not be necessary
TaskFactory::delayTask(10);
} else {
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
TaskFactory::delayTask(2);
}
}
}
@ -33,3 +41,14 @@ bool PersistentSingleTmStoreTask::initStoresIfPossible() {
}
return false;
}
void PersistentSingleTmStoreTask::startTransition(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
cancelDump(dumpContext, storeWithQueue, channel.isTxOn());
this->mode = MODE_OFF;
} else if (mode == MODE_ON) {
this->mode = MODE_ON;
}
modeHelper.modeChanged(mode, submode);
announceMode(false);
}

View File

@ -3,16 +3,16 @@
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <mission/com/TmStoreTaskBase.h>
#include <mission/com/VirtualChannel.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/TmStoreTaskBase.h>
#include <mission/tmtc/VirtualChannel.h>
class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
public:
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel,
Event eventIfDumpDone, Event eventIfCancelled,
SdCardMountedIF& sdcMan);
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
ReturnValue_t performOperation(uint8_t opCode) override;
@ -23,6 +23,8 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj
Countdown graceDelayDuringDumping = Countdown(100);
bool initStoresIfPossible() override;
void startTransition(Mode_t mode, Submode_t submode) override;
};
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */

View File

@ -27,8 +27,9 @@ void SyrlinksHandler::doStartUp() {
if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) {
if (commandExecuted) {
// Go to normal mode immediately and disable transmitter on startup.
setMode(_MODE_TO_NORMAL);
setMode(_MODE_TO_ON);
internalState = InternalState::IDLE;
transState = TransitionState::IDLE;
commandExecuted = false;
}
}
@ -36,14 +37,16 @@ void SyrlinksHandler::doStartUp() {
void SyrlinksHandler::doShutDown() {
// In any case, always disable TX first.
if (internalState != InternalState::SET_TX_STANDBY) {
internalState = InternalState::SET_TX_STANDBY;
if (internalState != InternalState::TX_TRANSITION) {
internalState = InternalState::TX_TRANSITION;
transState = TransitionState::SET_TX_STANDBY;
commandExecuted = false;
}
if (internalState == InternalState::SET_TX_STANDBY) {
if (internalState == InternalState::TX_TRANSITION) {
if (commandExecuted) {
temperatureSet.setValidity(false, true);
internalState = InternalState::OFF;
transState = TransitionState::IDLE;
commandExecuted = false;
setMode(_MODE_POWER_DOWN);
}
@ -97,33 +100,47 @@ ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
}
ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
if (transState == TransitionState::CMD_PENDING or transState == TransitionState::DONE) {
return NOTHING_TO_SEND;
}
switch (internalState) {
case InternalState::ENABLE_TEMPERATURE_PROTECTION: {
*id = syrlinks::WRITE_LCL_CONFIG;
transState = TransitionState::CMD_PENDING;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SET_TX_MODULATION: {
*id = syrlinks::SET_TX_MODE_MODULATION;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SELECT_MODULATION_BPSK: {
*id = syrlinks::SET_WAVEFORM_BPSK;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SELECT_MODULATION_0QPSK: {
*id = syrlinks::SET_WAVEFORM_0QPSK;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SET_TX_CW: {
*id = syrlinks::SET_TX_MODE_CW;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SET_TX_STANDBY: {
*id = syrlinks::SET_TX_MODE_STANDBY;
return buildCommandFromCommand(*id, nullptr, 0);
}
default:
case InternalState::TX_TRANSITION: {
switch (transState) {
case TransitionState::SET_TX_MODULATION: {
*id = syrlinks::SET_TX_MODE_MODULATION;
return buildCommandFromCommand(*id, nullptr, 0);
}
case TransitionState::SELECT_MODULATION_BPSK: {
*id = syrlinks::SET_WAVEFORM_BPSK;
return buildCommandFromCommand(*id, nullptr, 0);
}
case TransitionState::SELECT_MODULATION_0QPSK: {
*id = syrlinks::SET_WAVEFORM_0QPSK;
return buildCommandFromCommand(*id, nullptr, 0);
}
case TransitionState::SET_TX_CW: {
*id = syrlinks::SET_TX_MODE_CW;
return buildCommandFromCommand(*id, nullptr, 0);
}
case TransitionState::SET_TX_STANDBY: {
*id = syrlinks::SET_TX_MODE_STANDBY;
return buildCommandFromCommand(*id, nullptr, 0);
}
default: {
return NOTHING_TO_SEND;
}
}
transState = TransitionState::CMD_PENDING;
break;
}
default: {
break;
}
}
return NOTHING_TO_SEND;
}
@ -442,7 +459,6 @@ ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
}
return returnvalue::OK;
}
@ -620,8 +636,6 @@ void SyrlinksHandler::parseAgcHighByte(const uint8_t* packet) {
agcValueHighByte = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
}
void SyrlinksHandler::setNormalDatapoolEntriesInvalid() {}
uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; }
ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -650,11 +664,11 @@ ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& loca
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(rxDataset.getSid(), enableHkSets, 60.0));
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 20.0));
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 120.0));
return returnvalue::OK;
}
void SyrlinksHandler::setModeNormal() { setMode(MODE_NORMAL); }
void SyrlinksHandler::setModeNormal() { setMode(_MODE_TO_NORMAL); }
float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; }
@ -673,15 +687,37 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
break;
}
case (syrlinks::SET_WAVEFORM_BPSK):
case (syrlinks::SET_WAVEFORM_0QPSK):
case (syrlinks::SET_TX_MODE_STANDBY):
case (syrlinks::SET_TX_MODE_MODULATION):
case (syrlinks::SET_TX_MODE_CW): {
case (syrlinks::SET_WAVEFORM_0QPSK): {
if (result == returnvalue::OK and isTransitionalMode()) {
transState = TransitionState::SET_TX_MODULATION;
commandExecuted = true;
}
break;
}
case (syrlinks::SET_TX_MODE_STANDBY): {
if (result == returnvalue::OK and isTransitionalMode()) {
transState = TransitionState::DONE;
commandExecuted = true;
}
break;
}
case (syrlinks::SET_TX_MODE_MODULATION): {
if (result == returnvalue::OK and isTransitionalMode()) {
transState = TransitionState::DONE;
commandExecuted = true;
}
break;
}
case (syrlinks::SET_TX_MODE_CW): {
if (result == returnvalue::OK and isTransitionalMode()) {
commandExecuted = true;
transState = TransitionState::DONE;
}
break;
}
default: {
sif::error << "Syrlinks: Unexpected ACK reply" << std::endl;
}
}
switch (rememberCommandId) {
case (syrlinks::SET_TX_MODE_STANDBY): {
@ -699,7 +735,7 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
if (submode >= com::Submode::NUM_SUBMODES) {
if (submode >= com::Submode::NUM_SUBMODES or submode < com::Submode::RX_ONLY) {
return HasModesIF::INVALID_SUBMODE;
}
return returnvalue::OK;
@ -726,68 +762,54 @@ void SyrlinksHandler::setDebugMode(bool enable) { this->debugMode = enable; }
void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
Mode_t tgtMode = getBaseMode(getMode());
auto commandDone = [&]() {
setMode(tgtMode);
auto doneHandler = [&]() {
internalState = InternalState::IDLE;
transState = TransitionState::IDLE;
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
};
auto txOnHandler = [&](InternalState selMod) {
if (internalState == InternalState::IDLE) {
commandExecuted = false;
internalState = selMod;
}
// Select modulation first (BPSK or 0QPSK).
if (internalState == selMod) {
if (commandExecuted) {
internalState = InternalState::SET_TX_MODULATION;
commandExecuted = false;
}
}
// Now go into modulation mode.
if (internalState == InternalState::SET_TX_MODULATION) {
if (commandExecuted) {
commandDone();
return true;
}
}
return false;
};
if (transState == TransitionState::DONE) {
return doneHandler();
}
auto txStandbyHandler = [&]() {
if (internalState == InternalState::IDLE) {
internalState = InternalState::SET_TX_STANDBY;
commandExecuted = false;
}
if (internalState == InternalState::SET_TX_STANDBY) {
if (commandExecuted) {
commandDone();
return;
}
}
txDataset.setReportingEnabled(false);
poolManager.changeCollectionInterval(temperatureSet.getSid(), 60.0);
transState = TransitionState::SET_TX_STANDBY;
internalState = InternalState::TX_TRANSITION;
};
auto txOnHandler = [&](TransitionState tgtTransitionState) {
txDataset.setReportingEnabled(true);
poolManager.changeCollectionInterval(txDataset.getSid(), 10.0);
poolManager.changeCollectionInterval(temperatureSet.getSid(), 5.0);
transState = tgtTransitionState;
internalState = InternalState::TX_TRANSITION;
};
if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) {
// If submode has not changed, no special transition handling necessary.
if (getSubmode() == subModeFrom) {
return doneHandler();
}
// Transition is on-going, wait for it to finish.
if (transState != TransitionState::IDLE) {
return;
}
// Transition start logic.
switch (getSubmode()) {
case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): {
auto currentDatarate = com::getCurrentDatarate();
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
return;
}
txOnHandler(TransitionState::SELECT_MODULATION_BPSK);
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
return;
}
txOnHandler(TransitionState::SELECT_MODULATION_0QPSK);
}
break;
}
case (com::Submode::RX_AND_TX_LOW_DATARATE): {
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
return;
}
txOnHandler(TransitionState::SELECT_MODULATION_BPSK);
break;
}
case (com::Submode::RX_AND_TX_HIGH_DATARATE): {
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
return;
}
txOnHandler(TransitionState::SELECT_MODULATION_0QPSK);
break;
}
case (com::Submode::RX_ONLY): {
@ -795,21 +817,17 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
return;
}
case (com::Submode::RX_AND_TX_CW): {
if (internalState == InternalState::IDLE) {
internalState = InternalState::SET_TX_STANDBY;
commandExecuted = false;
}
if (commandExecuted) {
commandDone();
return;
}
txOnHandler(TransitionState::SET_TX_CW);
break;
}
default: {
commandDone();
sif::error << "SyrlinksHandler: Unexpected submode " << getSubmode() << std::endl;
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
}
}
} else if (tgtMode == HasModesIF::MODE_OFF) {
txStandbyHandler();
} else {
return doneHandler();
}
}

View File

@ -46,7 +46,6 @@ class SyrlinksHandler : public DeviceHandlerBase {
size_t* foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
void setNormalDatapoolEntriesInvalid() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
@ -118,15 +117,20 @@ class SyrlinksHandler : public DeviceHandlerBase {
enum class InternalState {
OFF,
ENABLE_TEMPERATURE_PROTECTION,
TX_TRANSITION,
IDLE
} internalState = InternalState::OFF;
enum class TransitionState {
IDLE,
SELECT_MODULATION_BPSK,
SELECT_MODULATION_0QPSK,
SET_TX_MODULATION,
SET_TX_CW,
SET_TX_STANDBY,
IDLE
};
InternalState internalState = InternalState::OFF;
CMD_PENDING,
DONE
} transState = TransitionState::IDLE;
/**
* This object is used to store the id of the next command to execute. This controls the

View File

@ -0,0 +1,228 @@
#include "TmStoreTaskBase.h"
#include <fsfw/ipc/CommandMessageIF.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/subsystem/helper.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <fsfw/tmstorage/TmStoreMessage.h>
#include "mission/persistentTmStoreDefs.h"
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
VirtualChannel& channel, SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked)
: SystemObject(objectId),
modeHelper(this),
ipcStore(ipcStore),
tmReader(&timeReader),
channel(channel),
sdcMan(sdcMan),
ptmeLocked(ptmeLocked) {
requestQueue = QueueFactory::instance()->createMessageQueue(10);
}
bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext) {
ReturnValue_t result;
bool tmToStoreReceived = false;
bool tcRequestReceived = false;
bool dumpPerformed = false;
fileHasSwapped = false;
dumpContext.packetWasDumped = false;
dumpContext.vcBusyDuringDump = false;
// Store TM persistently
result = store.handleNextTm();
if (result == returnvalue::OK) {
tmToStoreReceived = true;
}
// Dump TMs
if (store.getState() == PersistentTmStore::State::DUMPING) {
if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) {
return result;
}
} else {
Command_t execCmd;
// Handle TC requests, for example deletion or retrieval requests.
result = store.handleCommandQueue(ipcStore, execCmd);
if (result == returnvalue::OK) {
if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
cancelDumpCd.resetTimer();
tmSinkBusyCd.resetTimer();
dumpContext.reset();
}
tcRequestReceived = true;
}
}
if (tcRequestReceived or tmToStoreReceived or dumpPerformed) {
return true;
}
return false;
}
bool TmStoreTaskBase::cyclicStoreCheck() {
if (not storesInitialized) {
storesInitialized = initStoresIfPossible();
if (not storesInitialized) {
TaskFactory::delayTask(400);
return false;
}
} else if (sdCardCheckCd.hasTimedOut()) {
if (not sdcMan.isSdCardUsable(std::nullopt)) {
// Might be due to imminent shutdown or SD card switch.
storesInitialized = false;
TaskFactory::delayTask(100);
return false;
}
sdCardCheckCd.resetTimer();
}
return true;
}
void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) {
ctx.reset();
if (store.getState() == PersistentTmStore::State::DUMPING) {
triggerEvent(ctx.eventIfCancelled, ctx.numberOfDumpedPackets, ctx.dumpedBytes);
}
store.cancelDump();
if (isTxOn) {
channel.cancelTransfer();
}
}
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext, bool& dumpPerformed) {
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).
if (not channel.isBusy() and not ptmeLocked) {
performDump(store, dumpContext, dumpPerformed);
} else {
// The PTME might be at full load, so it might sense to delay for a bit to let it do
// its work until some more bandwidth is available. Set a flag here so the upper layer can
// do ths.
dumpContext.vcBusyDuringDump = true;
dumpContext.ptmeBusyCounter++;
if (dumpContext.ptmeBusyCounter == 100) {
// If this happens, something is probably wrong.
sif::warning << "PTME busy for longer period. Cancelling dump" << std::endl;
cancelDump(dumpContext, store, channel.isTxOn());
}
}
if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) {
cancelDump(dumpContext, store, channel.isTxOn());
}
return result;
}
ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext, bool& dumpPerformed) {
size_t dumpedLen = 0;
auto dumpDoneHandler = [&]() {
uint32_t startTime;
uint32_t endTime;
store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime);
triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets,
dumpContext.dumpedBytes);
dumpContext.reset();
};
// Dump the next packet into the PTME.
dumpContext.ptmeBusyCounter = 0;
tmSinkBusyCd.resetTimer();
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
if (result != returnvalue::OK) {
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.
dumpDoneHandler();
return returnvalue::OK;
}
dumpedLen = tmReader.getFullPacketLen();
// Only write to VC if mode is on, but always confirm the dump.
// If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written
// (e.g. to confirm a reset or the transmitter is off anyway).
if (mode == MODE_ON) {
result = channel.write(tmReader.getFullData(), dumpedLen);
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);
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
dumpPerformed = true;
if (dumpedLen > 0) {
dumpContext.dumpedBytes += dumpedLen;
dumpContext.numberOfDumpedPackets += 1;
dumpContext.packetWasDumped = true;
}
}
if (result == PersistentTmStore::DUMP_DONE) {
dumpDoneHandler();
}
return returnvalue::OK;
}
ReturnValue_t TmStoreTaskBase::initialize() {
modeHelper.initialize();
return returnvalue::OK;
}
void TmStoreTaskBase::getMode(Mode_t* mode, Submode_t* submode) {
if (mode != nullptr) {
*mode = this->mode;
}
if (submode != nullptr) {
*submode = SUBMODE_NONE;
}
}
ReturnValue_t TmStoreTaskBase::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if (mode == MODE_ON or mode == MODE_OFF) {
return returnvalue::OK;
}
return returnvalue::FAILED;
}
MessageQueueId_t TmStoreTaskBase::getCommandQueue() const { return requestQueue->getId(); }
void TmStoreTaskBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); }
object_id_t TmStoreTaskBase::getObjectId() const { return SystemObject::getObjectId(); }
const HasHealthIF* TmStoreTaskBase::getOptHealthIF() const { return nullptr; }
const HasModesIF& TmStoreTaskBase::getModeIF() const { return *this; }
ReturnValue_t TmStoreTaskBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
}
ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; }
void TmStoreTaskBase::readCommandQueue(void) {
CommandMessage commandMessage;
ReturnValue_t result = returnvalue::FAILED;
result = requestQueue->receiveMessage(&commandMessage);
if (result == returnvalue::OK) {
result = modeHelper.handleModeCommand(&commandMessage);
if (result == returnvalue::OK) {
return;
}
CommandMessage reply;
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
requestQueue->reply(&reply);
return;
}
}

View File

@ -1,15 +1,22 @@
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
#define MISSION_TMTC_TMSTORETASKBASE_H_
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/subsystem/ModeTreeChildIF.h>
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
#include <fsfw/timemanager/CdsShortTimeStamper.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/com/VirtualChannel.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/VirtualChannel.h>
/**
* Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping
* the TM store into the virtual channel directly.
*/
class TmStoreTaskBase : public SystemObject {
class TmStoreTaskBase : public SystemObject,
public HasModesIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF {
public:
struct DumpContext {
DumpContext(Event eventIfDone, Event eventIfCancelled)
@ -33,19 +40,35 @@ class TmStoreTaskBase : public SystemObject {
};
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
SdCardMountedIF& sdcMan);
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
ReturnValue_t initialize() override;
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
protected:
ModeHelper modeHelper;
MessageQueueIF* requestQueue;
StorageManagerIF& ipcStore;
PusTmReader tmReader;
CdsShortTimeStamper timeReader;
VirtualChannel& channel;
SdCardMountedIF& sdcMan;
const std::atomic_bool& ptmeLocked;
Mode_t mode = HasModesIF::MODE_OFF;
Countdown sdCardCheckCd = Countdown(800);
// 20 minutes are allowed as maximum dump time.
Countdown cancelDumpCd = Countdown(60 * 20 * 1000);
// If the TM sink is busy for 1 minute for whatever reason, cancel the dump.
Countdown tmSinkBusyCd = Countdown(60 * 1000);
VirtualChannel& channel;
bool storesInitialized = false;
bool fileHasSwapped = false;
SdCardMountedIF& sdcMan;
void readCommandQueue(void);
virtual bool initStoresIfPossible() = 0;
virtual void startTransition(Mode_t mode, Submode_t submode) = 0;
void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn);
/**
@ -58,6 +81,8 @@ class TmStoreTaskBase : public SystemObject {
ReturnValue_t handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext,
bool& dumpPerformed);
ReturnValue_t performDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext,
bool& dumpPerformed);
/**
* Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to
@ -65,7 +90,17 @@ class TmStoreTaskBase : public SystemObject {
*/
bool cyclicStoreCheck();
virtual bool initStoresIfPossible() = 0;
MessageQueueId_t getCommandQueue() const override;
void getMode(Mode_t* mode, Submode_t* submode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
void announceMode(bool recursive) override;
object_id_t getObjectId() const override;
const HasHealthIF* getOptHealthIF() const override;
const HasModesIF& getModeIF() const override;
ModeTreeChildIF& getModeTreeChildIF() override;
};
#endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */

View File

@ -1,4 +1,4 @@
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include "VirtualChannelWithQueue.h"
#include "OBSWConfig.h"
#include "fsfw/ipc/QueueFactory.h"
@ -19,7 +19,7 @@ VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t v
const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); }
ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
TmTcMessage message;
ReturnValue_t result = tmQueue->receiveMessage(&message);
if (result == MessageQueueIF::EMPTY) {
@ -36,7 +36,9 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
return result;
}
result = write(data, size);
if (performWriteOp) {
result = write(data, size);
}
// Try delete in any case, ignore failures (which should not happen), it is more important to
// propagate write errors.
tmStore.deleteData(storeId);

View File

@ -4,7 +4,7 @@
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <linux/ipcore/PtmeIF.h>
#include <mission/tmtc/VirtualChannel.h>
#include <mission/com/VirtualChannel.h>
#include <atomic>
@ -34,7 +34,7 @@ class VirtualChannelWithQueue : public VirtualChannel, public AcceptsTelemetryIF
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
[[nodiscard]] const char* getName() const override;
ReturnValue_t sendNextTm();
ReturnValue_t handleNextTm(bool performWriteOp);
private:
MessageQueueIF* tmQueue = nullptr;

View File

@ -3,6 +3,8 @@
#include <fsfw/ipc/MutexFactory.h>
#include <fsfw/ipc/MutexGuard.h>
#include <atomic>
com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK;
MutexIF* DATARATE_LOCK = nullptr;

View File

@ -221,9 +221,8 @@ void AcsController::performSafe() {
updateCtrlValData(errAng);
updateActuatorCmdData(cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
// acsParameters.rwHandlingParameters.rampTime);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquerParameter.torqueDuration);
}
void AcsController::performDetumble() {
@ -472,6 +471,18 @@ void AcsController::performPointingCtrl() {
// acsParameters.rwHandlingParameters.rampTime);
}
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
uint16_t dipoleTorqueDuration) {
{
PoolReadGuard pg(&dipoleSet);
MutexGuard mg(torquer::lazyLock(), torquer::LOCK_TYPE, torquer::LOCK_TIMEOUT,
torquer::LOCK_CTX);
torquer::NEW_ACTUATION_FLAG = true;
dipoleSet.setDipoles(xDipole, yDipole, zDipole, dipoleTorqueDuration);
}
return returnvalue::OK;
}
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
uint16_t dipoleTorqueDuration, int32_t rw1Speed,
int32_t rw2Speed, int32_t rw3Speed, int32_t rw4Speed,
@ -565,7 +576,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 5.0});
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 10.0});
// MGM Processed
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc);
@ -575,7 +586,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer);
localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf);
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 12.0});
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 10.0});
// SUS Raw
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw);
@ -589,7 +600,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw);
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 5.0});
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 10.0});
// SUS Processed
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc);
@ -606,43 +617,43 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer);
localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk);
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 12.0});
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 10.0});
// GYR Raw
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw);
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 5.0});
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 10.0});
// GYR Processed
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot);
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 12.0});
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 10.0});
// GPS Processed
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 12.0});
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
// MEKF
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 12.0});
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
// Ctrl Values
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 12.0});
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 10.0});
// Actuator CMD
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed);
localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole);
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 12.0});
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 10.0});
return returnvalue::OK;
}

View File

@ -105,6 +105,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void modeChanged(Mode_t mode, Submode_t submode);
void announceMode(bool recursive);
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
uint16_t dipoleTorqueDuration);
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed,
int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime);

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
#include <mission/acs/str/strHelpers.h>
#include <mission/acs/susMax1227Helpers.h>
#include <mission/com/syrlinksDefs.h>
#include <mission/controller/controllerdefinitions/ThermalControllerDefinitions.h>
#include <mission/controller/tcsDefs.h>
#include <mission/payload/payloadPcduDefinitions.h>
#include <mission/power/bpxBattDefs.h>
#include <mission/power/gsDefs.h>
@ -45,17 +45,73 @@ struct TempLimits {
float nopUpperLimit;
};
struct ThermalState {
uint8_t errorCounter;
bool heating;
uint32_t heaterStartTime;
};
struct HeaterState {
bool switchTransition;
HeaterHandler::SwitchState target;
uint8_t heaterSwitchControlCycles;
};
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
enum ThermalComponents : uint8_t {
NONE = 0,
ACS_BOARD = 1,
MGT = 2,
RW = 3,
STR = 4,
IF_BOARD = 5,
TCS_BOARD = 6,
OBC = 7,
OBCIF_BOARD = 8,
SBAND_TRANSCEIVER = 9,
PCDUP60_BOARD = 10,
PCDUACU = 11,
PCDUPDU = 12,
PLPCDU_BOARD = 13,
PLOCMISSION_BOARD = 14,
PLOCPROCESSING_BOARD = 15,
DAC = 16,
CAMERA = 17,
DRO = 18,
X8 = 19,
HPA = 20,
TX = 21,
MPA = 22,
SCEX_BOARD = 23,
NUM_ENTRIES
};
class ThermalController : public ExtendedControllerBase {
public:
static const uint16_t INVALID_TEMPERATURE = 999;
static const uint8_t NUMBER_OF_SENSORS = 16;
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
ThermalController(object_id_t objectId, HeaterHandler& heater);
ReturnValue_t initialize() override;
protected:
void performThermalModuleCtrl();
struct HeaterContext {
public:
HeaterContext(heater::Switchers switchNr, heater::Switchers redundantSwitchNr,
const TempLimits& tempLimit)
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
bool doHeaterHandling = true;
heater::Switchers switchNr;
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
heater::Switchers redSwitchNr;
const TempLimits& tempLimit;
};
void performThermalModuleCtrl(const HeaterSwitchStates& heaterSwitchStates);
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
void performControlOperation() override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -67,16 +123,7 @@ class ThermalController : public ExtendedControllerBase {
uint32_t* msToReachTheMode) override;
private:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_CONTROLLER;
static constexpr Event NO_VALID_SENSOR_TEMPERATURE = MAKE_EVENT(0, severity::MEDIUM);
static constexpr Event NO_HEALTHY_HEATER_AVAILABLE = MAKE_EVENT(1, severity::MEDIUM);
static constexpr Event SYRLINKS_OVERHEATING = MAKE_EVENT(2, severity::HIGH);
static constexpr Event PLOC_OVERHEATING = MAKE_EVENT(3, severity::HIGH);
static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
static constexpr Event HPA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
static constexpr Event PLPCDU_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
static const uint32_t DELAY = 500;
static const uint32_t INIT_DELAY = 1500;
static const uint32_t TEMP_OFFSET = 5;
@ -96,22 +143,22 @@ class ThermalController : public ExtendedControllerBase {
DeviceHandlerThermalSet imtqThermalSet;
// Temperature Sensors
MAX31865::PrimarySet max31865Set0;
MAX31865::PrimarySet max31865Set1;
MAX31865::PrimarySet max31865Set2;
MAX31865::PrimarySet max31865Set3;
MAX31865::PrimarySet max31865Set4;
MAX31865::PrimarySet max31865Set5;
MAX31865::PrimarySet max31865Set6;
MAX31865::PrimarySet max31865Set7;
MAX31865::PrimarySet max31865Set8;
MAX31865::PrimarySet max31865Set9;
MAX31865::PrimarySet max31865Set10;
MAX31865::PrimarySet max31865Set11;
MAX31865::PrimarySet max31865Set12;
MAX31865::PrimarySet max31865Set13;
MAX31865::PrimarySet max31865Set14;
MAX31865::PrimarySet max31865Set15;
MAX31865::PrimarySet maxSet0PlocHspd;
MAX31865::PrimarySet maxSet1PlocMissionBrd;
MAX31865::PrimarySet maxSet2PlCam;
MAX31865::PrimarySet maxSet3DacHspd;
MAX31865::PrimarySet maxSet4Str;
MAX31865::PrimarySet maxSet5Rw1MxMy;
MAX31865::PrimarySet maxSet6Dro;
MAX31865::PrimarySet maxSet7Scex;
MAX31865::PrimarySet maxSet8X8;
MAX31865::PrimarySet maxSet9Hpa;
MAX31865::PrimarySet maxSet10EbandTx;
MAX31865::PrimarySet maxSet11Mpa;
MAX31865::PrimarySet maxSet31865Set12;
MAX31865::PrimarySet maxSet13PlPcduHspd;
MAX31865::PrimarySet maxSet14TcsBrd;
MAX31865::PrimarySet maxSet15Imtq;
TMP1075::Tmp1075Dataset tmp1075SetTcs0;
TMP1075::Tmp1075Dataset tmp1075SetTcs1;
@ -191,18 +238,38 @@ class ThermalController : public ExtendedControllerBase {
TempLimits dacLimits = TempLimits(-65.0, -40.0, 113.0, 118.0, 150.0);
TempLimits cameraLimits = TempLimits(-40.0, -30.0, 60.0, 65.0, 85.0);
TempLimits droLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits x8Limits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
TempLimits hpaLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
TempLimits txLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
TempLimits mpaLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
TempLimits x8Limits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits hpaLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits txLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits mpaLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits scexBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0);
double sensorTemp = INVALID_TEMPERATURE;
ThermalComponents thermalComponent = NONE;
bool redSwitchNrInUse = false;
MessageQueueId_t camId = MessageQueueIF::NO_QUEUE;
bool componentAboveCutOffLimit = false;
bool componentAboveUpperLimit = false;
Event overHeatEventToTrigger;
bool eBandTooHotFlag = false;
bool camTooHotOneShotFlag = false;
bool scexTooHotFlag = false;
bool plocTooHotFlag = false;
bool pcduSystemTooHotFlag = false;
bool syrlinksTooHotFlag = false;
bool obcTooHotFlag = false;
bool strTooHotFlag = false;
bool rwTooHotFlag = false;
// Initial delay to make sure all pool variables have been initialized their owners
Countdown initialCountdown = Countdown(DELAY);
bool transitionToOff = false;
uint32_t transitionToOffCycles = 0;
uint32_t cycles = 0;
std::array<ThermalState, 30> thermalStates{};
std::array<HeaterState, 7> heaterStates{};
// Initial delay to make sure all pool variables have been initialized their owners.
// Also, wait for system initialization to complete.
Countdown initialCountdown = Countdown(INIT_DELAY);
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
@ -221,16 +288,20 @@ class ThermalController : public ExtendedControllerBase {
static constexpr dur_millis_t MUTEX_TIMEOUT = 50;
void startTransition(Mode_t mode, Submode_t submode) override;
void resetSensorsArray();
void copySensors();
void copySus();
void copyDevices();
void ctrlComponentTemperature(heater::Switchers switchNr, heater::Switchers redSwitchNr,
TempLimits& tempLimit);
void ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr, TempLimits& tempLimit);
void ctrlComponentTemperature(HeaterContext& heaterContext);
void checkLimitsAndCtrlHeater(HeaterContext& heaterContext);
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr);
bool selectAndReadSensorTemp();
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
void ctrlAcsBoard();
void ctrlMgt();
@ -255,6 +326,11 @@ class ThermalController : public ExtendedControllerBase {
void ctrlTx();
void ctrlMpa();
void ctrlScexBoard();
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
void setMode(Mode_t mode);
uint32_t tempFloatToU32() const;
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);
};
#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */

View File

@ -5,9 +5,19 @@
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include "devices/heaterSwitcherList.h"
#include "eive/eventSubsystemIds.h"
namespace tcsCtrl {
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_CONTROLLER;
static constexpr Event NO_VALID_SENSOR_TEMPERATURE = MAKE_EVENT(0, severity::MEDIUM);
static constexpr Event NO_HEALTHY_HEATER_AVAILABLE = MAKE_EVENT(1, severity::MEDIUM);
static constexpr Event SYRLINKS_OVERHEATING = MAKE_EVENT(2, severity::HIGH);
static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
static constexpr Event CAMERA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
static constexpr Event PCDU_SYSTEM_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
static constexpr Event HEATER_NOT_OFF_FOR_OFF_MODE = MAKE_EVENT(7, severity::MEDIUM);
enum SetId : uint32_t {
SENSOR_TEMPERATURES = 0,
DEVICE_TEMPERATURES = 1,
@ -93,34 +103,33 @@ static const uint8_t ENTRIES_SUS_TEMPERATURE_SET = 12;
*/
class SensorTemperatures : public StaticLocalDataSet<ENTRIES_SENSOR_TEMPERATURE_SET> {
public:
SensorTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SENSOR_TEMPERATURES) {}
explicit SensorTemperatures(HasLocalDataPoolIF* owner)
: StaticLocalDataSet(owner, SENSOR_TEMPERATURES) {}
SensorTemperatures(object_id_t objectId)
explicit SensorTemperatures(object_id_t objectId)
: StaticLocalDataSet(sid_t(objectId, SENSOR_TEMPERATURES)) {}
lp_var_t<float> sensor_ploc_heatspreader =
lp_var_t<float> plocHeatspreader =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLOC_HEATSPREADER, this);
lp_var_t<float> sensor_ploc_missionboard =
lp_var_t<float> plocMissionboard =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLOC_MISSIONBOARD, this);
lp_var_t<float> sensor_4k_camera = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_4K_CAMERA, this);
lp_var_t<float> sensor_dac_heatspreader =
lp_var_t<float> payload4kCamera = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_4K_CAMERA, this);
lp_var_t<float> dacHeatspreader =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DAC_HEATSPREADER, this);
lp_var_t<float> sensor_startracker =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_STARTRACKER, this);
lp_var_t<float> sensor_rw1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_RW1, this);
lp_var_t<float> sensor_scex = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_SCEX, this);
lp_var_t<float> sensor_tx_modul = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
lp_var_t<float> startracker = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_STARTRACKER, this);
lp_var_t<float> rw1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_RW1, this);
lp_var_t<float> scex = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_SCEX, this);
lp_var_t<float> eBandTx = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
// E-Band module
lp_var_t<float> sensor_dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
lp_var_t<float> sensor_mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
lp_var_t<float> sensor_x8 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_X8, this);
lp_var_t<float> sensor_hpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_HPA, this);
lp_var_t<float> sensor_acu = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_ACU, this);
lp_var_t<float> sensor_plpcdu_heatspreader =
lp_var_t<float> dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
lp_var_t<float> mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
lp_var_t<float> x8 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_X8, this);
lp_var_t<float> hpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_HPA, this);
lp_var_t<float> acu = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_ACU, this);
lp_var_t<float> plpcduHeatspreader =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLPCDU_HEATSPREADER, this);
lp_var_t<float> sensor_tcs_board = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TCS_BOARD, this);
lp_var_t<float> sensor_magnettorquer =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MAGNETTORQUER, this);
lp_var_t<float> tcsBoard = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TCS_BOARD, this);
lp_var_t<float> mgt = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MAGNETTORQUER, this);
lp_var_t<float> tmp1075Tcs0 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_TCS_0, this);
lp_var_t<float> tmp1075Tcs1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_TCS_1, this);
lp_var_t<float> tmp1075PlPcdu0 =
@ -137,9 +146,10 @@ class SensorTemperatures : public StaticLocalDataSet<ENTRIES_SENSOR_TEMPERATURE_
*/
class DeviceTemperatures : public StaticLocalDataSet<ENTRIES_DEVICE_TEMPERATURE_SET> {
public:
DeviceTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, DEVICE_TEMPERATURES) {}
explicit DeviceTemperatures(HasLocalDataPoolIF* owner)
: StaticLocalDataSet(owner, DEVICE_TEMPERATURES) {}
DeviceTemperatures(object_id_t objectId)
explicit DeviceTemperatures(object_id_t objectId)
: StaticLocalDataSet(sid_t(objectId, DEVICE_TEMPERATURES)) {}
lp_var_t<float> q7s = lp_var_t<float>(sid.objectId, PoolIds::TEMP_Q7S, this);
@ -178,9 +188,11 @@ class DeviceTemperatures : public StaticLocalDataSet<ENTRIES_DEVICE_TEMPERATURE_
*/
class SusTemperatures : public StaticLocalDataSet<ENTRIES_SUS_TEMPERATURE_SET> {
public:
SusTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SUS_TEMPERATURES) {}
explicit SusTemperatures(HasLocalDataPoolIF* owner)
: StaticLocalDataSet(owner, SUS_TEMPERATURES) {}
SusTemperatures(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, SUS_TEMPERATURES)) {}
explicit SusTemperatures(object_id_t objectId)
: StaticLocalDataSet(sid_t(objectId, SUS_TEMPERATURES)) {}
lp_var_t<float> sus_0_n_loc_xfyfzm_pt_xf =
lp_var_t<float>(sid.objectId, PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, this);

View File

@ -192,8 +192,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
// HK store and PUS funnel to HK store routing
{
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY,
15, *ramToFileStore, sdcMan);
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 2,
*ramToFileStore, sdcMan);
stores.hkStore =
new PersistentTmStoreWithTmQueue(storeArgs, "HK STORE", config::HK_STORE_QUEUE_SIZE);
(*pusFunnel)
@ -295,7 +295,7 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
{new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
}});
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
power::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
heaterHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
}
@ -347,7 +347,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
AcsBoardHelper acsBoardHelper = AcsBoardHelper(
objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER,
objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER,
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER);
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER,
objects::GPS_0_HEALTH_DEV, objects::GPS_1_HEALTH_DEV);
auto acsAss =
new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF);
for (auto& assChild : assemblyDhbs) {
@ -358,13 +359,17 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
}
}
gpsCtrl->connectModeTreeParent(*acsAss);
auto* gps0HealthDev = new HealthDevice(objects::GPS_0_HEALTH_DEV, acsAss->getCommandQueue());
auto* gps1HealthDev = new HealthDevice(objects::GPS_1_HEALTH_DEV, acsAss->getCommandQueue());
acsAss->registerChild(objects::GPS_0_HEALTH_DEV, gps0HealthDev->getCommandQueue());
acsAss->registerChild(objects::GPS_1_HEALTH_DEV, gps1HealthDev->getCommandQueue());
acsAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
}
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) {
TcsBoardHelper helper(RTD_INFOS);
auto* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
power::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
return tcsBoardAss;
}

View File

@ -2,6 +2,7 @@
#define MISSION_CORE_GENERICFACTORY_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw/devicehandlers/HealthDevice.h>
#include <mission/memory/SdCardMountedIF.h>
#include <mission/persistentTmStoreDefs.h>
#include <mission/tcs/Max31865Definitions.h>

View File

@ -11,6 +11,7 @@
#include <iostream>
#include <random>
#include "eive/definitions.h"
#include "fsfw/globalfunctions/CRC.h"
using std::ofstream;
@ -27,6 +28,7 @@ void ScexDeviceHandler::doStartUp() { setMode(MODE_ON); }
void ScexDeviceHandler::doShutDown() {
reader.reset();
commandActive = false;
fileNameSet = false;
multiFileFinishOutstanding = false;
setMode(_MODE_POWER_DOWN);
}
@ -205,50 +207,13 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
using namespace scex;
ReturnValue_t status = OK;
auto oneFileHandler = [&](std::string cmdName) {
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
fileId = date_time_string();
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();
if (prefix == nullptr) {
return returnvalue::FAILED;
}
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
fileName = oss.str();
ofstream out(fileName, ofstream::binary);
if (out.bad()) {
sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName
<< std::endl;
return FAILED;
}
out << helper;
return OK;
};
auto multiFileHandler = [&](std::string cmdName) {
auto multiFileHandler = [&](const char* cmdName) {
if ((helper.getPacketCounter() == 1) or (not fileNameSet)) {
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
status = generateNewScexFile(cmdName);
if (status != returnvalue::OK) {
return status;
}
fileId = date_time_string();
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();
if (prefix == nullptr) {
return returnvalue::FAILED;
}
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
fileName = oss.str();
fileNameSet = true;
ofstream out(fileName, ofstream::binary);
if (out.bad()) {
sif::error << "ScexDeviceHandler::handleValidReply: Could not open file " << fileName
<< std::endl;
return FAILED;
}
out << helper;
} else {
ofstream out(fileName,
ofstream::binary | ofstream::app); // append
@ -264,31 +229,31 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
id = helper.getCmd();
switch (id) {
case (PING): {
status = oneFileHandler("ping_");
status = generateNewScexFile(PING_IDLE_BASE_NAME);
break;
}
case (ION_CMD): {
status = oneFileHandler("ion_");
status = generateNewScexFile(ION_BASE_NAME);
break;
}
case (TEMP_CMD): {
status = oneFileHandler("temp_");
status = generateNewScexFile(TEMPERATURE_BASE_NAME);
break;
}
case (EXP_STATUS_CMD): {
status = oneFileHandler("exp_status_");
status = generateNewScexFile(EXP_STATUS_BASE_NAME);
break;
}
case (FRAM): {
status = multiFileHandler("fram_");
status = multiFileHandler(FRAM_BASE_NAME);
break;
}
case (ONE_CELL): {
status = multiFileHandler("one_cell_");
status = multiFileHandler(ONE_CELL_BASE_NAME);
break;
}
case (ALL_CELLS_CMD): {
status = multiFileHandler("multi_cell_");
status = multiFileHandler(ALL_CELLS_BASE_NAME);
break;
}
default:
@ -354,37 +319,41 @@ ReturnValue_t ScexDeviceHandler::initializeLocalDataPool(localpool::DataPool& lo
return OK;
}
std::string ScexDeviceHandler::date_time_string() {
using namespace std;
string date_time;
Clock::TimeOfDay_t tod;
Clock::getDateAndTime(&tod);
ostringstream oss(std::ostringstream::ate);
if (tod.hour < 10) {
oss << tod.year << tod.month << tod.day << "_0" << tod.hour;
} else {
oss << tod.year << tod.month << tod.day << "_" << tod.hour;
}
if (tod.minute < 10) {
oss << 0 << tod.minute;
} else {
oss << tod.minute;
}
if (tod.second < 10) {
oss << 0 << tod.second;
} else {
oss << tod.second;
ReturnValue_t ScexDeviceHandler::generateNewScexFile(const char* cmdName) {
char timeString[64]{};
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
date_time = oss.str();
return date_time;
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();
if (prefix == nullptr) {
return returnvalue::FAILED;
}
timeval tv;
Clock::getClock_timeval(&tv);
time_t epoch = tv.tv_sec;
struct tm* time = gmtime(&epoch);
size_t writtenBytes = strftime(reinterpret_cast<char*>(timeString), sizeof(timeString),
config::FILE_DATE_FORMAT, time);
if (writtenBytes == 0) {
sif::error << "PersistentTmStore::createMostRecentFile: Could not create file timestamp"
<< std::endl;
return returnvalue::FAILED;
}
oss << prefix << "/scex/scex-" << cmdName << "-" << timeString << ".bin";
fileName = oss.str();
ofstream out(fileName, ofstream::binary);
if (out.bad()) {
sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName
<< std::endl;
return FAILED;
}
out << helper;
return OK;
}
void ScexDeviceHandler::modeChanged() {}
void ScexDeviceHandler::setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Switch_t switchId) {
DeviceHandlerBase::setPowerSwitcher(&powerSwitcher);
this->switchId = switchId;

View File

@ -13,6 +13,14 @@ class SdCardMountedIF;
class ScexDeviceHandler : public DeviceHandlerBase {
public:
static constexpr char FRAM_BASE_NAME[] = "framContent";
static constexpr char ION_BASE_NAME[] = "ion";
static constexpr char TEMPERATURE_BASE_NAME[] = "temperature";
static constexpr char EXP_STATUS_BASE_NAME[] = "expStatus";
static constexpr char ONE_CELL_BASE_NAME[] = "oneCell";
static constexpr char ALL_CELLS_BASE_NAME[] = "allCells";
static constexpr char PING_IDLE_BASE_NAME[] = "pingIdle";
ScexDeviceHandler(object_id_t objectId, ScexUartReader &reader, CookieIF *cookie,
SdCardMountedIF &sdcMan);
void setPowerSwitcher(PowerSwitchIF &powerSwitcher, power::Switch_t switchId);
@ -35,8 +43,6 @@ class ScexDeviceHandler : public DeviceHandlerBase {
SdCardMountedIF &sdcMan;
Countdown finishCountdown = Countdown(LONG_CD);
std::string date_time_string();
// DeviceHandlerBase private function implementation
void doStartUp() override;
void doShutDown() override;
@ -59,7 +65,8 @@ class ScexDeviceHandler : public DeviceHandlerBase {
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
ReturnValue_t initializeAfterTaskCreation() override;
void modeChanged() override;
ReturnValue_t generateNewScexFile(const char *cmdName);
};
#endif /* MISSION_PAYLOAD_SCEXDEVICEHANDLER_H_ */

View File

@ -26,10 +26,11 @@ ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
static_cast<void>(length);
@ -102,25 +103,25 @@ ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
if (thisSequence->checkSequence() != returnvalue::OK) {
sif::error << "GomSpace PST initialization failed" << std::endl;
return returnvalue::FAILED;

View File

@ -149,9 +149,9 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 20.0));
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 3000.0));
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
return returnvalue::OK;
}

Some files were not shown because too many files have changed in this diff Show More