Compare commits

..

191 Commits

Author SHA1 Message Date
0a11ca6051 Merge pull request 'Update to v1.8.0' (#100) from develop into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #100
2021-09-24 10:17:43 +02:00
b305924e11 Merge branch 'main' into develop
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-24 10:13:18 +02:00
863295cd31 Merge pull request 'RW ReplyHandler fix' (#99) from mueller/rw-replyhandler-fix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #99
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-09-23 20:14:27 +02:00
b1a91da844 Merge remote-tracking branch 'origin/develop' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 17:15:51 +02:00
397e1433fd GPS and RW handler improvements
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 17:14:08 +02:00
31c84d47fe Merge pull request 'ACS board now working' (#98) from mueller/acs-board-working into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #98
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-09-23 16:03:11 +02:00
8fc144b595 RW handler tweaks
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 16:03:09 +02:00
8693075061 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 15:58:03 +02:00
b128455217 RW small improvements
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 15:35:33 +02:00
99c975d0cd Merge branch 'mueller/acs-board-working' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 15:28:44 +02:00
d5205b59c1 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 15:24:47 +02:00
26fbd81d39 Merge branch 'develop' into mueller/acs-board-working
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head Build queued...
2021-09-23 15:23:46 +02:00
0ccf062d51 transition delays
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-23 15:20:55 +02:00
aa71159a9a A side enabled by default
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-23 14:45:42 +02:00
e56a30df06 HW bug fixes, board should work cleanly now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-23 13:13:46 +02:00
7b7bd76703 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 18:38:06 +02:00
ee878d9fe9 bugfix EIVE PST
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 16:14:33 +02:00
0b50d9aedf fix for ADIS device
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 16:00:31 +02:00
4131084973 several tweaks and fixes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 15:43:11 +02:00
b81ff7f8f5 Merge pull request 'GPIO Refactoring' (#97) from mueller/gpio-refactoring into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #97
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-09-22 14:40:27 +02:00
1284d10257 RPI updates
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 14:27:01 +02:00
af9a9b837a added missing GPIO
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 14:10:21 +02:00
9a16544836 cleaning up RPi code
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 14:04:39 +02:00
dbcf4f5d69 more improvements for RPi code
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 12:29:43 +02:00
f9050ab185 fixes for RPi code
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 12:19:45 +02:00
d6e22e7d4d trying other timing
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 11:48:56 +02:00
e1ae1c021a made more spi devices optional
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 11:45:25 +02:00
da45326150 bumped SW subversion
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-22 09:22:06 +02:00
28040f85cc fixes for new gpio update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-21 19:28:22 +02:00
652cfa0986 gpio refactoring
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-21 17:31:55 +02:00
3a76ee366d Merge remote-tracking branch 'origin/develop' into mueller/master
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-21 16:03:39 +02:00
09c602a830 Merge pull request 'meier/gpioNaming' (#96) from meier/gpioNaming into develop
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Reviewed-on: #96
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2021-09-21 16:02:22 +02:00
1d8c4be47a fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-21 14:47:03 +02:00
c4ba578285 fixed warning
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head Build queued...
2021-09-20 18:46:48 +02:00
804afa5d96 add test code now default 0 2021-09-20 18:15:35 +02:00
26162f8e78 gpio chips now opened by label 2021-09-20 17:47:29 +02:00
38903f647b Merge branch 'develop' into meier/gpioNaming 2021-09-20 16:31:15 +02:00
cd92f4a611 open gpio by label test on te0720 2021-09-20 16:30:50 +02:00
8f1d521007 Merge pull request 'Update Package' (#95) from mueller/update-voltage-switch-cmds into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #95
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-09-20 15:59:18 +02:00
cf9ff87560 bugfixes for new print commands
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-20 14:34:39 +02:00
cbb7fdfa99 p60 print command
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-20 11:47:19 +02:00
487b6fd5ca updated print commands for PDUs
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-20 11:22:11 +02:00
87d00dbcee some more acs board tests
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-17 16:53:15 +02:00
5cb6ab8416 more acs tests
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-17 13:08:03 +02:00
4b5f22f013 Merge pull request 'Update Package' (#94) from mueller/update-package into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #94
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-09-17 08:01:17 +02:00
48a8a52b1c moved lis3mdl to fsfw
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 18:51:06 +02:00
8dcd2f0c95 some cfg improvements
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 17:33:47 +02:00
2cb562cdee tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 17:25:16 +02:00
00bafd98fe obsw config, gps update 2021-09-16 17:24:34 +02:00
536c0cb0fe new commands now working
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 15:00:31 +02:00
0f57fc33c8 tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 14:51:51 +02:00
2aa76766af added print commands for PCDU 2021-09-16 14:51:14 +02:00
00711c148a rm3100 changes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 13:40:29 +02:00
d0cba24a37 Merge branch 'mueller/update-package' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 11:52:34 +02:00
adb0147ea9 tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 11:52:03 +02:00
086d076262 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 11:46:55 +02:00
260082c425 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-16 11:46:34 +02:00
ad052462c1 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-16 11:36:40 +02:00
b8b6cd8872 moved RM3100 handler to framework
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-16 11:34:07 +02:00
799e90f617 reverted some change
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-16 11:15:14 +02:00
8afc6dea11 Merge remote-tracking branch 'origin/develop' into mueller/update-package
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-16 11:13:34 +02:00
8af3a91b5a correct RW pin
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2021-09-16 11:11:25 +02:00
bdd5a7dd21 more storage for events
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-15 18:50:23 +02:00
2630d7fae7 tweak for rm3100
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-15 17:49:15 +02:00
df5b0a19de improved preprocessor defines
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-15 17:38:26 +02:00
c7d0a9551e small bugfix for rm3100
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-15 17:26:23 +02:00
26fa568d72 Merge pull request 'GNSS ACS board update' (#92) from mueller/gnss-acs-update into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #92
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-09-15 15:43:01 +02:00
39acc24535 testing ADIS handler
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-15 13:41:13 +02:00
d29b86a0bd Merge remote-tracking branch 'origin/develop' into mueller/master 2021-09-15 13:40:54 +02:00
8e6a2a1f02 Merge pull request 'LIS3MDL scaling bugfix' (#93) from lis3mdl-scaling-bugfix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #93
Looks good.
2021-09-15 10:35:19 +02:00
43fe7e0aa0 using enum for sensitivity now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-14 13:55:56 +02:00
ca79f370b0 Fixed bugs in mag. field scaling math.
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-14 12:30:46 +02:00
10f5933c1e enable pins
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-13 18:10:24 +02:00
3354f2a696 acd board tests continued
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-13 18:07:07 +02:00
c67a7ef1d8 added more package pin comments
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-13 11:48:11 +02:00
63ec5d6338 fsfw update
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-13 10:26:20 +02:00
a66a76609f Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into mueller/master 2021-09-13 10:26:10 +02:00
9f389fb920 added newline 2021-09-13 10:25:58 +02:00
9dff2e1479 enable periodci reply now
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-11 17:40:13 +02:00
299136f1a5 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-10 10:05:53 +02:00
2c65849bc6 tmtc update 2021-09-10 10:05:37 +02:00
0343372910 very important bugfix for reset pin gnss
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 19:27:49 +02:00
366c475b05 bug fixed in fsfw
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 17:25:13 +02:00
46e3956bca generating finish reply
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 17:02:37 +02:00
6409c596f7 fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 16:21:22 +02:00
5779f511cf some tweaks for reset pin command
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 16:03:20 +02:00
63c7903f9b now the print command works
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 13:41:27 +02:00
87495fd3af Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 13:22:43 +02:00
38c60f37da tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-08 13:46:33 +02:00
baba8b5cf0 tmtc 2021-09-08 13:21:56 +02:00
a4cd99ec90 sanity check on altitude, set unix seconds
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-07 16:42:04 +02:00
e837532b22 form improvements
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-07 16:14:54 +02:00
f7c6f16777 added gps reset callback
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-07 16:11:02 +02:00
3b3b2ed8c3 preproc define to log NMEA data
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-07 12:00:22 +02:00
52d0182a52 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-07 09:46:01 +02:00
405b9e7074 tmtc update 2021-09-07 09:45:51 +02:00
24c7a4e7e3 added additional comment 2021-09-07 09:45:12 +02:00
30a57ad5a4 using old transition delay
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-06 18:42:58 +02:00
d78c746552 GPS Handler bugfixes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-06 18:27:33 +02:00
773b745c76 tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-06 14:53:04 +02:00
45409fc2d6 gps handler working properly now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-06 12:07:15 +02:00
f97d5df75f fsfw and tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-06 11:35:23 +02:00
49b8232f12 tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-06 11:12:54 +02:00
ac3812f268 tmtc update 2021-09-06 11:12:29 +02:00
ed6ee02861 Merge remote-tracking branch 'origin/develop' into mueller/gnss-acs-update 2021-09-06 11:12:14 +02:00
94979e3561 pulling reset pin gnss high
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-09-02 20:27:12 +02:00
74e4415d58 updated busConf file
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-09-02 20:04:41 +02:00
08bc44ce8b Merge pull request 'v1.7.0' (#91) from develop into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #91
2021-09-02 09:29:48 +02:00
aeb289b758 Merge branch 'main' into develop
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-02 09:28:08 +02:00
56108aed66 Merge pull request 'meier/plocMemoryDumper' (#90) from meier/plocMemoryDumper into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #90
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2021-09-02 09:16:33 +02:00
225dcf27ba Merge remote-tracking branch 'origin/develop' into meier/plocMemoryDumper
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2021-09-02 09:15:22 +02:00
146035de5a Merge remote-tracking branch 'origin/develop' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-09-02 09:14:28 +02:00
cc602ddada Merge pull request 'meier/plocSupervisor' (#89) from meier/plocSupervisor into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #89
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2021-09-02 09:13:00 +02:00
e13db2e6b6 Merge branch 'develop' into meier/plocMemoryDumper
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-08-31 11:20:43 +02:00
0f79864446 ploc memory dumper complete 2021-08-31 11:20:21 +02:00
01dd2eb92e Merge branch 'develop' into meier/plocSupervisor
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-29 07:32:19 +02:00
89b68940be ploc memory dumper wip 2021-08-29 07:31:34 +02:00
c8150dff17 Merge pull request 'added LICENSE and NOTICE file' (#88) from mueller/license-notice-file into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #88
2021-08-29 07:31:01 +02:00
d8e1e4561d troubleshooting for wayland issue
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-24 16:41:10 +02:00
c1ca43113b update README
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-24 10:40:23 +02:00
26afe1d94a fixes in C++ test code
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-23 20:43:27 +02:00
90622eb25a important fixes 2021-08-23 20:38:18 +02:00
e4e765300d more bugfixes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-23 09:08:48 -04:00
922c33df57 using Q7S_ROOTFS now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-23 09:03:48 -04:00
23894f9749 updated link
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-23 08:50:41 -04:00
1716034926 updated submodule link
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-23 08:49:06 -04:00
acc1849fbb fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-23 09:40:35 +02:00
d1a25bfa65 bugfixes hyperion handler 2021-08-22 20:25:05 +02:00
dc0c8c704c debugging GPS: uart is blocking!
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 20:18:56 +02:00
bb58281fba minor fix for gps
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 18:48:05 +02:00
5b9811a950 disabled all devices except for ADIS device
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 15:46:51 +02:00
e9849bfedd some fixes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 15:25:02 +02:00
6ecd4ec2f3 pin fixes for ACS board
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 14:50:40 +02:00
333c46bdf8 adaptions to build ploc supervisor for trenz te0720
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-08-20 14:48:22 +02:00
23782dc2fa Device update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
1. Sun sensors added but can be disabled with preprocessor defines
2. GPS Handler
2021-08-20 14:08:11 +02:00
95b49ca49d update tmtc and arcsec submodule
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 13:56:43 +02:00
a45d4592c3 lwgps update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 12:05:15 +02:00
9a84abf77f Merge pull request 'Writeprotection handler in CoreController' (#87) from mueller/writeprotect-handler into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #87
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-08-20 11:08:25 +02:00
5789e2a3b5 added LICENSE and NOTICE file
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 10:43:34 +02:00
92528c7350 added LICENSE and NOTICE file
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-20 10:01:37 +02:00
3acb61959a mram dump standalone packet 2021-08-20 06:56:29 +02:00
ef75d92415 smaller tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 18:26:00 +02:00
e821a9700a refactoring and bugfix
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 18:10:19 +02:00
d1afdfe578 bugfix core controller
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 17:31:13 +02:00
24ecfe84ae minor fix 2021-08-19 17:27:13 +02:00
42d225bb6c fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 17:20:40 +02:00
7c828427e9 unix file guard diagnostic prefix adaption
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-08-19 17:08:51 +02:00
8ddd7b02dc renamed function and bugfix
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 14:45:25 +02:00
963e40120f added TODO
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 14:35:36 +02:00
faee071edc bugfixes, more tests
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 14:34:24 +02:00
a6777067da moved test 2021-08-19 14:16:26 +02:00
c1b22af695 several bugfixes for prot handler
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 14:05:25 +02:00
7fc3285272 added functions to handle writeprotection
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 13:34:44 +02:00
19d4349c05 submodule update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-19 10:16:55 +02:00
99a24a9a35 Merge pull request 'ACS board added' (#86) from mueller/acs-board-added into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #86
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-08-18 12:44:28 +02:00
2b061a2b1c fsfw update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-18 11:32:49 +02:00
124abf0213 crc for ploc update 2021-08-18 08:26:31 +02:00
2f72b4e42a cleaned up
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-17 19:50:48 +02:00
e98b985d66 cleaning up preproc defines 2021-08-17 17:48:51 +02:00
9efcd90cc0 Merge pull request 'meier/pcdu' (#85) from meier/pcdu into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #85
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2021-08-17 17:14:19 +02:00
aa248b7997 new busConf file, cleaning up
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-17 17:11:59 +02:00
921e82f6d1 acs board tweaks
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-17 16:35:41 +02:00
aa43bd7d75 Merge remote-tracking branch 'origin/develop' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-17 16:17:24 +02:00
be6056aadb adaptions to build software for Trenz TE0720
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-17 16:14:23 +02:00
a298fff602 tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-17 16:07:33 +02:00
5204afca9e pcdu debug output disabled now
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head Build queued...
2021-08-17 12:00:58 +02:00
1722f14a60 added debug output for pcdu modules
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2021-08-17 11:59:32 +02:00
3a65f1d39f Merge pull request 'Raspberry Pi fixes, GPS Handler update, Stripped Executable' (#84) from mueller/stripped-exec into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #84
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-08-16 13:41:21 +02:00
567199f460 Merge branch 'develop' into mueller/stripped-exec
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-16 10:05:55 +02:00
cfbacd4d80 generating stripped executable now
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2021-08-14 15:25:30 +02:00
95c06d5a09 added make size cfg
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-14 15:19:32 +02:00
dc8879b1af tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 19:33:26 +02:00
1962b30e5f testing HK downlink
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 19:27:17 +02:00
cb330bcf29 hyperion handler: HK packet subscription
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 18:59:40 +02:00
268cd33677 gps handler tweaks
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 18:52:33 +02:00
0ae55e0783 no ARCSEC lib for Raspberry Pi
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 18:13:43 +02:00
be43dbd293 Merge pull request 'Core Controller Bugfix' (#83) from mueller/core-controller-bugfix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #83
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
2021-08-11 16:48:24 +02:00
45b78a0100 Merge remote-tracking branch 'origin/develop' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 16:45:17 +02:00
fc22f7d86f Merge branch 'develop' into mueller/core-controller-bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head Build queued...
2021-08-11 16:30:31 +02:00
0622b78dde Merge branch 'mueller/core-controller-bugfix' into mueller/master
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 16:30:00 +02:00
cf355a0451 missing :
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2021-08-11 16:29:11 +02:00
337aa39ecc Merge pull request 'meier/firmwareChanges' (#82) from meier/firmwareChanges into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #82
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2021-08-11 16:26:53 +02:00
24b58e50d1 Merge core controller bugfix
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
2021-08-11 16:24:41 +02:00
11c2efa733 bugfix core controller
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
1. Increaed robustness of CoreController against invalid state struct
2. Bugfix: If PREFSD not set, set SD card 0 properly now
2021-08-11 16:07:00 +02:00
0efaa13a9f tmtc update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 15:53:27 +02:00
ae08d14626 Merge branch 'develop' into meier/firmwareChanges
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
EIVE/eive-obsw/pipeline/head Build queued...
2021-08-11 13:32:30 +02:00
4fdcb5d7cd minor changes to match software to updated fpga design
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-11 09:41:29 +02:00
12dbc5569e mode power down sus
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2021-08-09 14:44:06 +02:00
8f124de79c set all devices to mode power down in doShutDown
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2021-08-09 14:41:46 +02:00
ce1124472a Merge branch 'develop' into meier/develop 2021-08-09 14:23:27 +02:00
0580784d16 added mode power down in star tracker 2021-08-09 10:41:28 +02:00
108 changed files with 4695 additions and 4009 deletions

2
.gitmodules vendored
View File

@ -15,7 +15,7 @@
url = https://github.com/rmspacefish/lwgps.git
[submodule "generators/fsfwgen"]
path = generators/fsfwgen
url = https://egit.irs.uni-stuttgart.de/fsfw/fsfw-generators.git
url = https://egit.irs.uni-stuttgart.de/fsfw/fsfw-gen.git
[submodule "thirdparty/arcsec_star_tracker"]
path = thirdparty/arcsec_star_tracker
url = https://egit.irs.uni-stuttgart.de/eive/arcsec_star_tracker.git

View File

@ -97,18 +97,18 @@ if(TGT_BSP)
endif()
endif()
if(${TGT_BSP} MATCHES "arm/raspberrypi")
if(TGT_BSP MATCHES "arm/raspberrypi")
# Used by configure file
set(RASPBERRY_PI ON)
set(FSFW_HAL_ADD_RASPBERRY_PI ON)
endif()
if(${TGT_BSP} MATCHES "arm/beagleboneblack")
if(TGT_BSP MATCHES "arm/beagleboneblack")
# Used by configure file
set(BEAGLEBONEBLACK ON)
endif()
if(${TGT_BSP} MATCHES "arm/q7s")
if(TGT_BSP MATCHES "arm/q7s")
# Used by configure file
set(XIPHOS_Q7S ON)
endif()
@ -122,9 +122,9 @@ if(NOT EIVE_BUILD_WATCHDOG)
configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h)
configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h)
configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h)
if(${TGT_BSP} MATCHES "arm/q7s")
if(TGT_BSP MATCHES "arm/q7s")
configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h)
elseif(${TGT_BSP} MATCHES "arm/raspberrypi")
elseif(TGT_BSP MATCHES "arm/raspberrypi")
configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h)
endif()
endif()
@ -135,8 +135,6 @@ set(FSFW_ADDITIONAL_INC_PATHS
"${COMMON_PATH}/config"
${CMAKE_CURRENT_BINARY_DIR}
)
# Set for lwgps library
set(LWGPS_CONFIG_PATH "${COMMON_PATH}/config")
################################################################################
# Executable and Sources
@ -153,8 +151,6 @@ if(ADD_JSON_LIB)
add_subdirectory(${LIB_JSON_PATH})
endif()
if(NOT EIVE_BUILD_WATCHDOG)
if(ADD_LINUX_FILES)
add_subdirectory(${LINUX_PATH})
@ -190,8 +186,13 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG))
${LIB_FSFW_NAME}
${LIB_OS_NAME}
${LIB_LWGPS_NAME}
${LIB_ARCSEC}
)
if(TGT_BSP MATCHES "arm/q7s")
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_ARCSEC}
)
endif()
endif()
if(NOT EIVE_BUILD_WATCHDOG)
@ -214,8 +215,6 @@ if(ADD_JSON_LIB)
)
endif()
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_CXX_FS}
)
@ -228,6 +227,11 @@ target_include_directories(${TARGET_NAME} PRIVATE
${ARCSEC_LIB_PATH}
)
if(TGT_BSP MATCHES "arm/q7s")
target_include_directories(${TARGET_NAME} PRIVATE
${ARCSEC_LIB_PATH}
)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(WARNING_FLAGS

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

13
NOTICE Normal file
View File

@ -0,0 +1,13 @@
Copyright 2021 Institute of Space Systems (IRS), University of Stuttgart
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -65,7 +65,7 @@ prerequisites.
as a [separate download](#arm-toolchain)
2. [Q7S sysroot](#q7s-sysroot) on local development machine
3. Recommended: Eclipse or [Vivado 2018.2 SDK](#vivado) for OBSW development
3. [TCF agent] running on Q7S
3. [TCF agent](https://wiki.eclipse.org/TCF) running on Q7S
## Hardware Design
@ -324,6 +324,33 @@ For Linux, you can also download a more recent version of the
[Linaro 8.3.0 cross-compiler](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads)
from [here](https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz?revision=e09a1c45-0ed3-4a8e-b06b-db3978fd8d56&la=en&hash=93ED4444B8B3A812B893373B490B90BBB28FD2E3)
### Compatibility issues with wayland on more recent Linux distributions
If Vivado crashes and you find following lines in the `hs_err_pid*` files:
```sh
#
# An unexpected error has occurred (11)
#
Stack:
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/server/libjvm.so(+0x923da9) [0x7f666cf5eda9]
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/server/libjvm.so(JVM_handle_linux_signal+0xb6) [0x7f666cf653f6]
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/server/libjvm.so(+0x9209d3) [0x7f666cf5b9d3]
/lib/x86_64-linux-gnu/libc.so.6(+0x35fc0) [0x7f66a993efc0]
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/libawt_xawt.so(+0x42028) [0x7f664e24d028]
...
```
You can [solve this](https://forums.xilinx.com/t5/Design-Entry/Bug-Vivado-2017-4-crashing-on-rightclick-in-console-log/td-p/881811)
by logging in with `xorg` like specified [here](https://www.maketecheasier.com/switch-xorg-wayland-ubuntu1710/).
### Using `docnav` on more recent Linux versions
If you want to use `docnav` for navigating Xilinx documentation, it is recommended to install
it as a standalone version from [here](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/documentation-nav.html).
This is because the `docnav` installed as part of version 2018.2 requires `libpng12`, which is not part of
more recent disitributions anymore.
## <a id="arm-toolchain"></a> Installing toolchain without Vivado
You can download the toolchains for Windows and Linux
@ -924,6 +951,19 @@ Reading data from CAN:
candump can0
````
## Dump content of file in hex
````
cat file.bin | hexdump -C
````
All content will be printed with
````
cat file.bin | hexdump -v
````
To print only the first X bytes of a file
````
cat file.bin | hexdump -v -n X
````
## Preparation of a fresh rootfs and SD card
This section summarizes important changes between a fresh rootfs and the current

View File

@ -5,7 +5,7 @@
namespace pcduSwitches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
enum SwitcherList {
Q7S,
PAYLOAD_PCDU_CH1,
RW,
@ -22,7 +22,7 @@ namespace pcduSwitches {
SUS_NOMINAL,
SOLAR_CELL_EXP,
PLOC,
ACS_BORAD_SIDE_A,
ACS_BOARD_SIDE_A,
NUMBER_OF_SWITCHES
};

View File

@ -36,6 +36,7 @@ void initmission::initMission() {
void initmission::initTasks() {
TaskFactory* factory = TaskFactory::instance();
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if(factory == nullptr) {
/* Should never happen ! */
return;
@ -46,11 +47,11 @@ void initmission::initTasks() {
void (*missedDeadlineFunc) (void) = nullptr;
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
ReturnValue_t result = tmTcDistributor->addComponent(
objects::CCSDS_PACKET_DISTRIBUTOR);
result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
@ -78,21 +79,70 @@ void initmission::initTasks() {
}
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
std::vector<PeriodicTaskIF*> pusTasks;
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
std::vector<PeriodicTaskIF*> pstTasks;
createPstTasks(*factory, missedDeadlineFunc, pstTasks);
#if OBSW_ADD_TEST_CODE == 1
std::vector<PeriodicTaskIF*> testTasks;
createTestTasks(*factory, missedDeadlineFunc, pstTasks);
#endif /* OBSW_ADD_TEST_CODE == 1 */
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
for(const auto& task: taskVector) {
if(task != nullptr) {
task->startTask();
}
else {
sif::error << "Task in vector " << name << " is invalid!" << std::endl;
}
}
};
sif::info << "Starting tasks.." << std::endl;
tmTcDistributor->startTask();
udpBridgeTask->startTask();
udpPollingTask->startTask();
taskStarter(pusTasks, "PUS Tasks");
#if OBSW_ADD_TEST_CODE == 1
taskStarter(testTasks, "Test Tasks");
#endif /* OBSW_ADD_TEST_CODE == 1 */
taskStarter(pstTasks, "PST Tasks");
#if OBSW_ADD_TEST_PST == 1
if(startTestPst) {
pstTestTask->startTask();
}
#endif /* RPI_TEST_ACS_BOARD == 1 */
sif::info << "Tasks started.." << std::endl;
}
void initmission::createPusTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc, std::vector<PeriodicTaskIF*>& taskVec) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
PeriodicTaskIF* pusVerification = factory.createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
taskVec.push_back(pusVerification);
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
PeriodicTaskIF* pusEvents = factory.createPeriodicTask(
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if(result != HasReturnvaluesIF::RETURN_OK){
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
}
result = pusEvents->addComponent(objects::EVENT_MANAGER);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER);
}
taskVec.push_back(pusEvents);
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if(result != HasReturnvaluesIF::RETURN_OK) {
@ -102,8 +152,9 @@ void initmission::initTasks() {
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
}
taskVec.push_back(pusHighPrio);
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if(result != HasReturnvaluesIF::RETURN_OK) {
@ -121,8 +172,9 @@ void initmission::initTasks() {
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING);
}
taskVec.push_back(pusMedPrio);
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
@ -133,24 +185,34 @@ void initmission::initTasks() {
initmission::printAddObjectError("INT_ERR_RPRT",
objects::INTERNAL_ERROR_REPORTER);
}
taskVec.push_back(pusLowPrio);
}
#if OBSW_ADD_TEST_PST == 1
FixedTimeslotTaskIF* pstTestTask = factory->createFixedTimeslotTask("ACS_PST", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc);
result = pst::pstTest(pstTestTask);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "initmission::initTasks: ACS PST initialization failed!" << std::endl;
void initmission::createPstTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc, std::vector<PeriodicTaskIF*> &taskVec) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
#if OBSW_ADD_SPI_TEST_CODE == 0
FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask(
"SPI_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
missedDeadlineFunc);
result = pst::pstSpi(spiPst);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
#endif /* RPI_TEST_ACS_BOARD == 1 */
taskVec.push_back(spiPst);
#endif
}
PeriodicTaskIF* testTask = factory->createPeriodicTask(
void initmission::createTestTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*> &taskVec) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
PeriodicTaskIF* testTask = factory.createPeriodicTask(
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
#if OBSW_ADD_TEST_CODE == 1
result = testTask->addComponent(objects::TEST_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
}
#endif /* OBSW_ADD_TEST_CODE == 1 */
#if RPI_ADD_SPI_TEST == 1
result = testTask->addComponent(objects::SPI_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
@ -170,23 +232,16 @@ void initmission::initTasks() {
}
#endif /* RPI_ADD_GPIO_TEST == 1 */
sif::info << "Starting tasks.." << std::endl;
tmTcDistributor->startTask();
udpBridgeTask->startTask();
udpPollingTask->startTask();
pusVerification->startTask();
pusEvents->startTask();
pusHighPrio->startTask();
pusMedPrio->startTask();
pusLowPrio->startTask();
#if OBSW_ADD_TEST_CODE == 1
testTask->startTask();
#endif /* OBSW_ADD_TEST_CODE == 1 */
bool startTestPst = true;
static_cast<void>(startTestPst);
#if OBSW_ADD_TEST_PST == 1
pstTestTask->startTask();
FixedTimeslotTaskIF* pstTestTask = factory->createFixedTimeslotTask("TEST_PST", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc);
result = pst::pstTest(pstTestTask);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::info << "initmission::initTasks: ACS PST empty or invalid" << std::endl;
startTestPst = false;
}
#endif /* RPI_TEST_ACS_BOARD == 1 */
sif::info << "Tasks started.." << std::endl;
}

View File

@ -1,9 +1,24 @@
#ifndef BSP_LINUX_INITMISSION_H_
#define BSP_LINUX_INITMISSION_H_
#include "fsfw/tasks/Typedef.h"
#include <vector>
class PeriodicTaskIF;
class TaskFactory;
namespace initmission {
void initMission();
void initTasks();
void createPstTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*> &taskVec);
void createTestTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*> &taskVec);
void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*>& taskVec);
};
#endif /* BSP_LINUX_INITMISSION_H_ */

View File

@ -1,6 +1,4 @@
#include <fsfw_hal/linux/uart/UartComIF.h>
#include <fsfw_hal/linux/uart/UartCookie.h>
#include <mission/devices/GPSHyperionHandler.h>
#include <devConf.h>
#include "ObjectFactory.h"
#include "objects/systemObjectList.h"
@ -9,16 +7,13 @@
#include "OBSWConfig.h"
#include "tmtc/apid.h"
#include "tmtc/pusIds.h"
#include "spiConf.h"
#include "linux/boardtest/LibgpiodTest.h"
#include "linux/boardtest/SpiTestClass.h"
#include "linux/boardtest/UartTestClass.h"
#include "mission/core/GenericFactory.h"
#include "mission/utility/TmFunnel.h"
#include "mission/devices/MGMHandlerLIS3MDL.h"
#include "mission/devices/MGMHandlerRM3100.h"
#include <mission/devices/GPSHyperionHandler.h>
#include "mission/devices/GyroADIS16507Handler.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
@ -28,15 +23,24 @@
#include "fsfw/tasks/TaskFactory.h"
/* UDP server includes */
#if OBSW_USE_TMTC_TCP_BRIDGE == 1
#include <fsfw/src/fsfw/osal/common/TcpTmTcBridge.h>
#include <fsfw/src/fsfw/osal/common/TcpTmTcServer.h>
#else
#include "fsfw/osal/common/UdpTmTcBridge.h"
#include "fsfw/osal/common/UdpTcPollingTask.h"
#endif
#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h"
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
#include "fsfw_hal/linux/rpi/GpioRPi.h"
#include "fsfw_hal/common/gpio/GpioCookie.h"
#include "fsfw_hal/linux/spi/SpiCookie.h"
#include "fsfw_hal/linux/spi/SpiComIF.h"
#include <fsfw_hal/linux/uart/UartComIF.h>
#include <fsfw_hal/linux/uart/UartCookie.h>
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
@ -59,12 +63,126 @@ void ObjectFactory::produce(void* args){
Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects();
new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
#if OBSW_USE_TMTC_TCP_BRIDGE == 1
auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
tmtcBridge->setMaxNumberOfPacketsStored(50);
new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
#else
auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
tmtcBridge->setMaxNumberOfPacketsStored(50);
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
#endif
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
GpioCookie* gpioCookie = nullptr;
static_cast<void>(gpioCookie);
new SpiComIF(objects::SPI_COM_IF, gpioIF);
std::string spiDev;
SpiCookie* spiCookie = nullptr;
static_cast<void>(spiCookie);
#if OBSW_ADD_ACS_BOARD == 1
if(gpioCookie == nullptr) {
gpioCookie = new GpioCookie();
}
// TODO: Missing pin for Gyro 2
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN,
"MGM_0_LIS3", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN,
"MGM_1_RM3100", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN,
"MGM_2_LIS3", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN,
"MGM_3_RM3100", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN,
"GYRO_1_L3G", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_2_ADIS_CS, gpio::GYRO_2_BCM_PIN,
"GYRO_2_ADIS", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_3_L3G_CS, gpio::GYRO_3_BCM_PIN,
"GYRO_3_L3G", gpio::Direction::OUT, 1);
gpioIF->addGpios(gpioCookie);
spiDev = "/dev/spidev0.1";
spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
auto mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER,
objects::SPI_COM_IF, spiCookie, 0);
mgmLis3Handler->setStartUpImmediately();
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
mgmLis3Handler->setToGoToNormalMode(true);
#endif
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER,
objects::SPI_COM_IF, spiCookie, 0);
mgmRm3100Handler->setStartUpImmediately();
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
mgmRm3100Handler->setToGoToNormalMode(true);
#endif
spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev,
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER,
objects::SPI_COM_IF, spiCookie, 0);
mgmLis3Handler->setStartUpImmediately();
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
mgmLis3Handler->setToGoToNormalMode(true);
#endif
spiCookie = new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev,
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER,
objects::SPI_COM_IF, spiCookie, 0);
mgmRm3100Handler->setStartUpImmediately();
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
mgmRm3100Handler->setToGoToNormalMode(true);
#endif
spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
auto adisHandler = new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF,
spiCookie);
adisHandler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
spiCookie, 0);
gyroL3gHandler->setStartUpImmediately();
#if FSFW_HAL_L3GD20_GYRO_DEBUG== 1
gyroL3gHandler->setToGoToNormalMode(true);
#endif
spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev,
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
adisHandler = new GyroADIS16507Handler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF,
spiCookie);
adisHandler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev,
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF,
spiCookie, 0);
gyroL3gHandler->setStartUpImmediately();
#if FSFW_HAL_L3GD20_GYRO_DEBUG== 1
gyroL3gHandler->setToGoToNormalMode(true);
#endif
#endif /* RPI_TEST_ACS_BOARD == 1 */
#if OBSW_ADD_TEST_CODE == 1
createTestTasks();
#endif /* OBSW_ADD_TEST_CODE == 1 */
}
void ObjectFactory::createTestTasks() {
new TestTask(objects::TEST_TASK);
#if RPI_ADD_SPI_TEST == 1
new SpiTestClass(objects::SPI_TEST, gpioIF);
#endif
@ -89,53 +207,6 @@ void ObjectFactory::produce(void* args){
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback);
#endif /* RPI_LOOPBACK_TEST_GPIO == 1 */
new SpiComIF(objects::SPI_COM_IF, gpioIF);
std::string spiDev;
SpiCookie* spiCookie = nullptr;
static_cast<void>(spiCookie);
#if RPI_TEST_ACS_BOARD == 1
if(gpioCookie == nullptr) {
gpioCookie = new GpioCookie();
}
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN,
"MGM_0_LIS3", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN,
"MGM_1_RM3100", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN,
"MGM_2_LIS3", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN,
"MGM_3_RM3100", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN,
"GYRO_1_L3G", gpio::Direction::OUT, 1);
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_2_L3G_CS, gpio::GYRO_2_BCM_PIN,
"GYRO_2_L3G", gpio::Direction::OUT, 1);
gpioIF->addGpios(gpioCookie);
spiDev = "/dev/spidev0.0";
spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
auto mgmLis3Handler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmLis3Handler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
auto mgmRm3100Handler = new MGMHandlerRM3100(objects::MGM_1_RM3100_HANDLER,
objects::SPI_COM_IF, spiCookie);
mgmRm3100Handler->setStartUpImmediately();
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
spiCookie);
gyroL3gHandler->setStartUpImmediately();
#endif /* RPI_TEST_ACS_BOARD == 1 */
#if RPI_TEST_ADIS16507 == 1
if(gpioCookie == nullptr) {
gpioCookie = new GpioCookie();
@ -144,7 +215,7 @@ void ObjectFactory::produce(void* args){
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
gpioIF->addGpios(gpioCookie);
spiDev = "/dev/spidev0.0";
spiDev = "/dev/spidev0.1";
spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED,
nullptr, nullptr);
@ -158,7 +229,7 @@ void ObjectFactory::produce(void* args){
uartCookie->setToFlushInput(true);
uartCookie->setReadCycles(6);
GPSHyperionHandler* gpsHandler = new GPSHyperionHandler(objects::GPS0_HANDLER,
objects::UART_COM_IF, uartCookie);
objects::UART_COM_IF, uartCookie, false);
gpsHandler->setStartUpImmediately();
#endif

View File

@ -5,6 +5,8 @@
namespace ObjectFactory {
void setStatics();
void produce(void* args);
void createTestTasks();
};
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */

View File

@ -15,20 +15,18 @@
#define RPI_TEST_ACS_BOARD 0
#endif
#define RPI_ADD_UART_TEST 1
#if RPI_ADD_UART_TEST == 1
#define RPI_TEST_GPS_DEVICE 0
#endif
#define RPI_ADD_UART_TEST 0
/* Adapt these values accordingly */
namespace gpio {
static constexpr uint8_t MGM_0_BCM_PIN = 0;
static constexpr uint8_t MGM_1_BCM_PIN = 1;
static constexpr uint8_t MGM_2_BCM_PIN = 17;
static constexpr uint8_t MGM_3_BCM_PIN = 27;
static constexpr uint8_t MGM_0_BCM_PIN = 17;
static constexpr uint8_t MGM_1_BCM_PIN = 27;
static constexpr uint8_t MGM_2_BCM_PIN = 22;
static constexpr uint8_t MGM_3_BCM_PIN = 23;
static constexpr uint8_t GYRO_0_BCM_PIN = 5;
static constexpr uint8_t GYRO_1_BCM_PIN = 6;
static constexpr uint8_t GYRO_2_BCM_PIN = 4;
static constexpr uint8_t GYRO_2_BCM_PIN = 13;
static constexpr uint8_t GYRO_3_BCM_PIN = 19;
}
#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */

View File

@ -1,4 +1,5 @@
#include "InitMission.h"
#include "OBSWConfig.h"
#include "OBSWVersion.h"
#include "fsfw/FSFWVersion.h"

View File

@ -12,6 +12,6 @@ else()
add_subdirectory(gpio)
add_subdirectory(core)
add_subdirectory(memory)
add_subdirectory(spiCallbacks)
add_subdirectory(callbacks)
add_subdirectory(devices)
endif()

View File

@ -0,0 +1,100 @@
#ifndef BSP_Q7S_BOARDCONFIG_BUSCONF_H_
#define BSP_Q7S_BOARDCONFIG_BUSCONF_H_
namespace q7s {
static constexpr char SPI_DEFAULT_DEV[] = "/dev/spidev2.0";
static constexpr char SPI_RW_DEV[] = "/dev/spidev3.0";
static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-1";
static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ttyUL3";
static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ttyUL4";
static constexpr char UART_SYRLINKS_DEV[] = "/dev/ttyUL5";
static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL8";
static constexpr char UART_GNSS_0_DEV[] = "/dev/ttyUL0";
static constexpr char UART_GNSS_1_DEV[] = "/dev/ttyUL2";
/**************************************************************/
/** OBC1E */
/**************************************************************/
static constexpr char GPIO_MULTIPURPOSE_1V8_OBC1D[] = "/amba_pl/gpio@42020000";
static const char* const GPIO_GYRO_ADIS_LABEL = GPIO_MULTIPURPOSE_1V8_OBC1D;
static constexpr uint32_t GPIO_GYRO_0_ADIS_CS = 0; // Package Pin: W20
static constexpr uint32_t GPIO_GYRO_2_ADIS_CS = 2; // AA22
/**************************************************************/
/** OBC1F B0 */
/**************************************************************/
static constexpr char GPIO_FLEX_OBC1F_B0[] = "/amba_pl/gpio@42030000";
static constexpr uint32_t GPIO_FLEX_OBC1F_B0_WIDTH = 20;
static const char* const GPIO_ACS_BOARD_DEFAULT_LABEL = GPIO_FLEX_OBC1F_B0;
static const char* const GPIO_RW_DEFAULT_LABEL = GPIO_FLEX_OBC1F_B0;
static const char* const GPIO_RAD_SENSOR_LABEL = GPIO_FLEX_OBC1F_B0;
static constexpr uint32_t GPIO_RW_0_CS = 7; // B20
static constexpr uint32_t GPIO_RW_1_CS = 3; // G22
static constexpr uint32_t GPIO_RW_2_CS = 11; // E18
static constexpr uint32_t GPIO_RW_3_CS = 6; // B19
static constexpr uint32_t GPIO_GYRO_1_L3G_CS = 18; // N22
static constexpr uint32_t GPIO_GYRO_3_L3G_CS = 1; // M21
static constexpr uint32_t GPIO_MGM_0_LIS3_CS = 5; // C18
static constexpr uint32_t GPIO_MGM_1_RM3100_CS = 16; // A16
static constexpr uint32_t GPIO_MGM_3_RM3100_CS = 10; // C17
// Active low enable pin (needs to be driven low for regular operations)
static constexpr uint32_t GPIO_GYRO_0_ENABLE = 2; // H22
// Active low reset pin (needs to be driven high for regular operations)
static constexpr uint32_t GPIO_RESET_GNSS_0 = 9; // C22
static constexpr uint32_t GPIO_RESET_GNSS_1 = 12; // B21
static constexpr uint32_t GPIO_RAD_SENSOR_CS = 19; // R18
/**************************************************************/
/** OBC1F B1 */
/**************************************************************/
static constexpr char GPIO_FLEX_OBC1F_B1[] = "/amba_pl/gpio@42030000";
// Need to use chip name here for now because the label name is the name for
// gpiochip 5 and gpiochip6
static constexpr char GPIO_FLEX_OBC1F_B1_CHIP[] = "gpiochip6";
static const char* const GPIO_MGM2_LIS3_LABEL = GPIO_FLEX_OBC1F_B1_CHIP;
static constexpr uint32_t GPIO_MGM_2_LIS3_CS = 0; // D18
/**************************************************************/
/** OBC1C */
/**************************************************************/
static constexpr char GPIO_3V3_OBC1C[] = "/amba_pl/gpio@42040000";
static const char* const GPIO_HEATER_LABEL = GPIO_3V3_OBC1C;
static const char* const GPIO_SOLAR_ARR_DEPL_LABEL = GPIO_3V3_OBC1C;
static constexpr uint32_t GPIO_HEATER_0_PIN = 6;
static constexpr uint32_t GPIO_HEATER_1_PIN = 12;
static constexpr uint32_t GPIO_HEATER_2_PIN = 7;
static constexpr uint32_t GPIO_HEATER_3_PIN = 5;
static constexpr uint32_t GPIO_HEATER_4_PIN = 3;
static constexpr uint32_t GPIO_HEATER_5_PIN = 0;
static constexpr uint32_t GPIO_HEATER_6_PIN = 1;
static constexpr uint32_t GPIO_HEATER_7_PIN = 11;
static constexpr uint32_t GPIO_GYRO_2_ENABLE = 18; // F22
static constexpr uint32_t GPIO_SOL_DEPL_SA_0_PIN = 4;
static constexpr uint32_t GPIO_SOL_DEPL_SA_1_PIN = 2;
static constexpr char GPIO_RW_SPI_MUX_LABEL[] = "zynq_gpio";
// Uses EMIO interface to PL, starts at 54
static constexpr uint32_t GPIO_RW_SPI_MUX_CS = 54;
static constexpr uint32_t SPI_MUX_BIT_1 = 13;
static constexpr uint32_t SPI_MUX_BIT_2 = 14;
static constexpr uint32_t SPI_MUX_BIT_3 = 15;
static constexpr uint32_t SPI_MUX_BIT_4 = 16;
static constexpr uint32_t SPI_MUX_BIT_5 = 17;
static constexpr uint32_t SPI_MUX_BIT_6 = 9;
static constexpr uint32_t EN_RW_CS = 17;
}
#endif /* BSP_Q7S_BOARDCONFIG_BUSCONF_H_ */

View File

@ -5,30 +5,31 @@
#cmakedefine01 Q7S_SIMPLE_MODE
#define Q7S_SD_NONE 0
#define Q7S_SD_COLD_REDUNDANT 1
#define Q7S_SD_HOT_REDUNDANT 2
/*******************************************************************/
/** All of the following flags should be enabled for mission code */
/*******************************************************************/
//! Timers can mess up the code when debugging
//! All of this should be enabled for mission code!
/*******************************************************************/
/** Other flags */
/*******************************************************************/
#define Q7S_SD_NONE 0
#define Q7S_SD_COLD_REDUNDANT 1
#define Q7S_SD_HOT_REDUNDANT 2
// The OBSW will perform different actions to set up the SD cards depending on the flag set here
// Set to Q7S_SD_NONE: Don't do anything
// Set to Q7S_COLD_REDUNDANT: On startup, get the prefered SD card, turn it on and mount it, and
// turn off the second SD card if it is on
// Set to Q7S_HOT_REDUNDANT: On startup, turn on both SD cards and mount them
#define Q7S_SD_CARD_CONFIG Q7S_SD_COLD_REDUNDANT
#define Q7S_SD_CARD_CONFIG Q7S_SD_COLD_REDUNDANT
// Probably better if this is disabled for mission code. Convenient for development
#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1
#define Q7S_ADD_RTD_DEVICES 0
#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1
/* Only one of those 2 should be enabled! */
/* Add code for ACS board */
#define OBSW_ADD_ACS_BOARD 0
#if OBSW_ADD_ACS_BOARD == 0
#define Q7S_ADD_SPI_TEST 0
#endif
#define Q7S_ADD_SYRLINKS_HANDLER 1
#define Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST 0
#define Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST 0
namespace config {

View File

@ -1,3 +1,4 @@
#include <bsp_q7s/core/CoreController.h>
#include <bsp_q7s/memory/FileSystemHandler.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include "Q7STestTask.h"
@ -24,6 +25,7 @@ ReturnValue_t Q7STestTask::performOneShotAction() {
//testScratchApi();
//testJsonLibDirect();
//testDummyParams();
//testProtHandler();
//FsOpCodes opCode = FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY;
//testFileSystemHandlerDirect(opCode);
return TestTask::performOneShotAction();
@ -131,6 +133,87 @@ void Q7STestTask::testDummyParams() {
sif::info << "Test value 2 (\"blirb\" expected): " << test2 << std::endl;
}
ReturnValue_t Q7STestTask::initialize() {
coreController = ObjectManager::instance()->get<CoreController>(objects::CORE_CONTROLLER);
if(coreController == nullptr) {
sif::warning << "Q7STestTask::initialize: Could not retrieve CORE_CONTROLLER object" <<
std::endl;
}
return TestTask::initialize();
}
void Q7STestTask::testProtHandler() {
bool opPerformed = false;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
// If any chips are unlocked, lock them here
result = coreController->setBootCopyProtection(
CoreController::Chip::ALL_CHIP, CoreController::Copy::ALL_COPY, true,
opPerformed, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
}
// unlock own copy
result = coreController->setBootCopyProtection(
CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, false,
opPerformed, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
}
if(not opPerformed) {
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
}
int retval = std::system("print-chip-prot-status.sh");
if(retval != 0) {
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
}
// lock own copy
result = coreController->setBootCopyProtection(
CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, true,
opPerformed, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
}
if(not opPerformed) {
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
}
retval = std::system("print-chip-prot-status.sh");
if(retval != 0) {
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
}
// unlock specific copy
result = coreController->setBootCopyProtection(
CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, false,
opPerformed, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
}
if(not opPerformed) {
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
}
retval = std::system("print-chip-prot-status.sh");
if(retval != 0) {
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
}
// lock specific copy
result = coreController->setBootCopyProtection(
CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, true,
opPerformed, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
}
if(not opPerformed) {
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
}
retval = std::system("print-chip-prot-status.sh");
if(retval != 0) {
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
}
}
void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
auto fsHandler = ObjectManager::instance()->
get<FileSystemHandler>(objects::FILE_SYSTEM_HANDLER);

View File

@ -6,7 +6,10 @@
class Q7STestTask: public TestTask {
public:
Q7STestTask(object_id_t objectId);
ReturnValue_t initialize() override;
private:
CoreController* coreController = nullptr;
ReturnValue_t performOneShotAction() override;
void testSdCard();
@ -15,6 +18,7 @@ private:
void testScratchApi();
void testJsonLibDirect();
void testDummyParams();
void testProtHandler();
enum FsOpCodes {
CREATE_EMPTY_FILE_IN_TMP,

View File

@ -1,3 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
rwSpiCallback.cpp
gnssCallback.cpp
)

View File

@ -0,0 +1,26 @@
#include "gnssCallback.h"
#include "devices/gpioIds.h"
#include "fsfw/tasks/TaskFactory.h"
ReturnValue_t gps::triggerGpioResetPin(void *args) {
ResetArgs* resetArgs = reinterpret_cast<ResetArgs*>(args);
if(args == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
if (resetArgs->gpioComIF == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
gpioId_t gpioId;
if(resetArgs->gnss1) {
gpioId = gpioIds::GNSS_1_NRESET;
}
else {
gpioId = gpioIds::GNSS_0_NRESET;
}
resetArgs->gpioComIF->pullLow(gpioId);
TaskFactory::delayTask(resetArgs->waitPeriodMs);
resetArgs->gpioComIF->pullHigh(gpioId);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,19 @@
#ifndef BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_
#define BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
struct ResetArgs {
bool gnss1 = false;
LinuxLibgpioIF* gpioComIF = nullptr;
uint32_t waitPeriodMs = 100;
};
namespace gps {
ReturnValue_t triggerGpioResetPin(void* args);
}
#endif /* BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_ */

View File

@ -1,9 +1,10 @@
#include <bsp_q7s/spiCallbacks/rwSpiCallback.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <mission/devices/RwHandler.h>
#include <fsfw_hal/linux/spi/SpiCookie.h>
#include <fsfw_hal/linux/UnixFileGuard.h>
#include "rwSpiCallback.h"
#include "devices/gpioIds.h"
#include "mission/devices/RwHandler.h"
#include "fsfw_hal/linux/spi/SpiCookie.h"
#include "fsfw_hal/linux/UnixFileGuard.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
namespace rwSpiCallback {
@ -24,7 +25,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen
int fileDescriptor = 0;
std::string device = cookie->getSpiDevice();
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "rwSpiCallback::spiCallback: ");
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "rwSpiCallback::spiCallback");
if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl;
return SpiComIF::OPENING_FILE_FAILED;
@ -211,7 +212,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen
result = HasReturnvaluesIF::RETURN_OK;
}
cookie->assignTransferSize(decodedFrameLen);
cookie->setTransferSize(decodedFrameLen);
closeSpi(gpioId, gpioIF, mutex);

View File

@ -1,9 +1,9 @@
#ifndef BSP_Q7S_RW_SPI_CALLBACK_H_
#define BSP_Q7S_RW_SPI_CALLBACK_H_
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "fsfw_hal/linux/spi/SpiComIF.h"
#include "fsfw_hal/common/gpio/GpioCookie.h"
namespace rwSpiCallback {

View File

@ -21,12 +21,11 @@
#include <filesystem>
CoreController::Chip CoreController::currentChip = Chip::NO_CHIP;
CoreController::Copy CoreController::currentCopy = Copy::NO_COPY;
CoreController::Chip CoreController::CURRENT_CHIP = Chip::NO_CHIP;
CoreController::Copy CoreController::CURRENT_COPY = Copy::NO_COPY;
CoreController::CoreController(object_id_t objectId):
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5),
opDivider(5) {
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
try {
result = initWatchdogFifo();
@ -86,6 +85,28 @@ ReturnValue_t CoreController::initialize() {
return ExtendedControllerBase::initialize();
}
ReturnValue_t CoreController::initializeAfterTaskCreation() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if(BLOCKING_SD_INIT) {
ReturnValue_t result = initSdCardBlocking();
if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) {
sif::warning << "CoreController::CoreController: SD card init failed" << std::endl;
}
}
sdStateMachine();
result = initVersionFile();
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
}
// Add script folder to path
char* currentEnvPath = getenv("PATH");
std::string updatedEnvPath = std::string(currentEnvPath) + ":/home/root/scripts";
setenv("PATH", updatedEnvPath.c_str(), true);
updateProtInfo();
initPrint();
return result;
}
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
return HasReturnvaluesIF::RETURN_OK;
@ -197,6 +218,10 @@ ReturnValue_t CoreController::sdStateMachine() {
result = sdcMan->getSdCardActiveStatus(sdInfo.currentState);
determinePreferredSdCard();
updateSdInfoOther();
if(sdInfo.pref != sd::SdCard::SLOT_0 and sdInfo.pref != sd::SdCard::SLOT_1) {
sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl;
sdInfo.pref = sd::SdCard::SLOT_0;
}
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Getting SD card activity status failed" << std::endl;
}
@ -535,23 +560,6 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
}
}
ReturnValue_t CoreController::initializeAfterTaskCreation() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if(BLOCKING_SD_INIT) {
ReturnValue_t result = initSdCardBlocking();
if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) {
sif::warning << "CoreController::CoreController: SD card init failed" << std::endl;
}
}
sdStateMachine();
result = initVersionFile();
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
}
initPrint();
return result;
}
ReturnValue_t CoreController::sdColdRedundantBlockingInit() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
@ -610,7 +618,7 @@ ReturnValue_t CoreController::initVersionFile() {
std::to_string(FSFW_SUBVERSION) + "." + std::to_string(FSFW_REVISION);
std::string systemString = "System: " + unameLine;
std::string mountPrefix = SdCardManager::instance()->getCurrentMountPrefix();
std::string versionFilePath = mountPrefix + "/conf/version.txt";
std::string versionFilePath = mountPrefix + VERSION_FILE;
std::fstream versionFile;
if(not std::filesystem::exists(versionFilePath)) {
@ -727,32 +735,31 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
}
ReturnValue_t CoreController::initBootCopy() {
std::string fileName = "/tmp/curr_copy.txt";
if(not std::filesystem::exists(fileName)) {
if(not std::filesystem::exists(CURR_COPY_FILE)) {
// Thils file is created by the systemd service eive-early-config so this should
// not happen normally
std::string cmd = "xsc_boot_copy > " + fileName;
std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE);
int result = std::system(cmd.c_str());
if(result != 0) {
utility::handleSystemError(result, "CoreController::initBootCopy");
}
}
std::ifstream file(fileName);
std::ifstream file(CURR_COPY_FILE);
std::string line;
std::getline(file, line);
std::istringstream iss(line);
int value = 0;
iss >> value;
currentChip = static_cast<Chip>(value);
CURRENT_CHIP = static_cast<Chip>(value);
iss >> value;
currentCopy = static_cast<Copy>(value);
CURRENT_COPY = static_cast<Copy>(value);
return HasReturnvaluesIF::RETURN_OK;
}
void CoreController::getCurrentBootCopy(Chip &chip, Copy &copy) {
// Not really thread-safe but it does not need to be
chip = currentChip;
copy = currentCopy;
chip = CURRENT_CHIP;
copy = CURRENT_COPY;
}
ReturnValue_t CoreController::initWatchdogFifo() {
@ -791,6 +798,7 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
return HasActionsIF::INVALID_PARAMETERS;
}
bool rebootSameBootCopy = data[0];
bool protOpPerformed;
if(rebootSameBootCopy) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "CoreController::actionPerformReboot: Rebooting on current image" << std::endl;
@ -798,6 +806,12 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
// Attempt graceful shutdown by unmounting and switching off SD cards
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0);
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1);
// If any boot copies are unprotected
ReturnValue_t retval = setBootCopyProtection(Chip::SELF_CHIP, Copy::SELF_COPY,
true, protOpPerformed, false);
if(retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
sif::info << "Running slot was writeprotected before reboot" << std::endl;
}
int result = std::system("xsc_boot_copy -r");
if(result != 0) {
utility::handleSystemError(result, "CoreController::executeAction");
@ -812,6 +826,16 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
sif::info << "CoreController::actionPerformReboot: Rebooting on " <<
static_cast<int>(data[1]) << " " << static_cast<int>(data[2]) << std::endl;
#endif
// Check that the target chip and copy is writeprotected first
generateChipStateFile();
// If any boot copies are unprotected, protect them here
ReturnValue_t retval = setBootCopyProtection(static_cast<Chip>(data[1]),
static_cast<Copy>(data[2]), true, protOpPerformed, false);
if(retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
sif::info << "Target slot was writeprotected before reboot" << std::endl;
}
// The second byte in data is the target chip, the third byte is the target copy
std::string cmdString = "xsc_boot_copy " + std::to_string(data[1]) + " " +
std::to_string(data[2]);
@ -833,7 +857,8 @@ void CoreController::determinePreferredSdCard() {
if(result == scratch::KEY_NOT_FOUND) {
sif::warning << "CoreController::sdCardInit: "
"Preferred SD card not set. Setting to 0" << std::endl;
sdcMan->setPreferredSdCard(sdInfo.pref);
sdcMan->setPreferredSdCard(sd::SdCard::SLOT_0);
sdInfo.pref = sd::SdCard::SLOT_0;
}
else {
sif::warning << "CoreController::sdCardInit: Could not get preferred SD card"
@ -852,19 +877,266 @@ void CoreController::updateSdInfoOther() {
sdInfo.other = sd::SdCard::SLOT_1;
}
else {
else if(sdInfo.pref == sd::SdCard::SLOT_1) {
sdInfo.prefChar = "1";
sdInfo.otherChar = "0";
sdInfo.otherState = sdInfo.currentState.first;
sdInfo.prefState = sdInfo.currentState.second;
sdInfo.other = sd::SdCard::SLOT_0;
}
else {
sif::warning << "CoreController::updateSdInfoOther: Invalid SD card passed" << std::endl;
}
}
bool CoreController::sdInitFinished() const {
return sdInfo.initFinished;
}
ReturnValue_t CoreController::generateChipStateFile() {
int result = std::system(CHIP_PROT_SCRIPT);
if(result != 0) {
utility::handleSystemError(result, "CoreController::generateChipStateFile");
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy targetCopy,
bool protect, bool& protOperationPerformed, bool updateProtFile) {
bool allChips = false;
bool allCopies = false;
bool selfChip = false;
bool selfCopy = false;
protOperationPerformed = false;
switch(targetChip) {
case(Chip::ALL_CHIP): {
allChips = true;
break;
}
case(Chip::NO_CHIP): {
return HasReturnvaluesIF::RETURN_OK;
}
case(Chip::SELF_CHIP): {
selfChip = true;
targetChip = CURRENT_CHIP;
break;
}
default: {
break;
}
}
switch(targetCopy) {
case(Copy::ALL_COPY): {
allCopies = true;
break;
}
case(Copy::NO_COPY): {
return HasReturnvaluesIF::RETURN_OK;
}
case(Copy::SELF_COPY): {
selfCopy = true;
targetCopy = CURRENT_COPY;
break;
}
default: {
break;
}
}
for(uint8_t arrIdx = 0; arrIdx < protArray.size(); arrIdx++) {
int result = handleBootCopyProtAtIndex(targetChip, targetCopy, protect,
protOperationPerformed, selfChip, selfCopy, allChips, allCopies, arrIdx);
if(result != 0) {
break;
}
}
if(protOperationPerformed and updateProtFile) {
updateProtInfo();
}
return HasReturnvaluesIF::RETURN_OK;
}
int CoreController::handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
bool &protOperationPerformed, bool selfChip, bool selfCopy, bool allChips,
bool allCopies, uint8_t arrIdx) {
bool currentProt = protArray[arrIdx];
std::ostringstream oss;
bool performOp = false;
if(protect == currentProt) {
return 0;
}
if(protOperationPerformed) {
if((selfChip and selfCopy) or (not allCopies and not allChips)) {
// No need to continue, only one operation was requested
return 1;
}
}
Chip currentChip;
Copy currentCopy;
oss << "writeprotect ";
if(arrIdx == 0 or arrIdx == 1) {
oss << "0 ";
currentChip = Chip::CHIP_0;
}
else {
oss << "1 ";
currentChip = Chip::CHIP_1;
}
if(arrIdx == 0 or arrIdx == 2) {
oss << "0 ";
currentCopy = Copy::COPY_0;
}
else {
oss << "1 ";
currentCopy = Copy::COPY_1;
}
if(protect) {
oss << "1";
}
else {
oss << "0";
}
int result = 0;
if(allChips and allCopies) {
performOp = true;
}
else if(allChips) {
if((selfCopy and CURRENT_COPY == targetCopy) or
(currentCopy == targetCopy)) {
performOp = true;
}
}
else if(allCopies) {
if((selfChip and CURRENT_COPY == targetCopy) or
(currentChip == targetChip)) {
performOp = true;
}
}
else if(selfChip and (currentChip == targetChip)) {
if(selfCopy) {
if(currentCopy == targetCopy) {
performOp = true;
}
}
else {
performOp = true;
}
}
else if(selfCopy and (currentCopy == targetCopy)) {
if(selfChip) {
if(currentChip == targetChip) {
performOp = true;
}
}
else {
performOp = true;
}
}
else if((targetChip == currentChip) and (targetCopy == currentCopy)) {
performOp = true;
}
if(result != 0) {
utility::handleSystemError(result, "CoreController::checkAndSetBootCopyProtection");
}
if(performOp) {
// TODO: Lock operation take a long time. Use command executor? That would require a
// new state machine..
protOperationPerformed = true;
sif::info << "Executing command: " << oss.str() << std::endl;
result = std::system(oss.str().c_str());
}
return 0;
}
ReturnValue_t CoreController::updateProtInfo(bool regenerateChipStateFile) {
using namespace std;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if(regenerateChipStateFile) {
result = generateChipStateFile();
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "CoreController::updateProtInfo: Generating chip state file failed" <<
std::endl;
return result;
}
}
if(not filesystem::exists(CHIP_STATE_FILE)) {
return HasReturnvaluesIF::RETURN_FAILED;
}
ifstream chipStateFile(CHIP_STATE_FILE);
if(not chipStateFile.good()) {
return HasReturnvaluesIF::RETURN_FAILED;
}
string nextLine;
uint8_t lineCounter = 0;
string word;
while(getline(chipStateFile, nextLine)) {
ReturnValue_t result = handleProtInfoUpdateLine(nextLine);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "CoreController::updateProtInfo: Protection info update failed!" <<
std::endl;
return result;
}
++lineCounter;
if(lineCounter > 4) {
sif::warning << "CoreController::checkAndProtectBootCopy: "
"Line counter larger than 4" << std::endl;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CoreController::handleProtInfoUpdateLine(std::string nextLine) {
using namespace std;
string word;
uint8_t wordIdx = 0;
uint8_t arrayIdx = 0;
istringstream iss(nextLine);
Chip currentChip;
Copy currentCopy;
while(iss >> word) {
if(wordIdx == 1) {
currentChip = static_cast<Chip>(stoi(word));
}
if(wordIdx == 3) {
currentCopy = static_cast<Copy>(stoi(word));
}
if(wordIdx == 3) {
if(currentChip == Chip::CHIP_0) {
if(currentCopy == Copy::COPY_0) {
arrayIdx = 0;
}
else if(currentCopy == Copy::COPY_1) {
arrayIdx = 1;
}
}
else if(currentChip == Chip::CHIP_1) {
if(currentCopy == Copy::COPY_0) {
arrayIdx = 2;
}
else if(currentCopy == Copy::COPY_1) {
arrayIdx = 3;
}
}
}
if(wordIdx == 5) {
if(word == "unlocked.") {
protArray[arrayIdx] = false;
}
else {
protArray[arrayIdx] = true;
}
}
wordIdx++;
}
return HasReturnvaluesIF::RETURN_OK;
}
void CoreController::performWatchdogControlOperation() {
// Only perform each fifth iteration
if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) {

View File

@ -16,17 +16,28 @@ public:
enum Chip: uint8_t {
CHIP_0,
CHIP_1,
NO_CHIP
NO_CHIP,
SELF_CHIP,
ALL_CHIP
};
enum Copy: uint8_t {
COPY_0,
COPY_1,
NO_COPY
NO_COPY,
SELF_COPY,
ALL_COPY
};
static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh";
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
static constexpr char VERSION_FILE[] = "/conf/sd_status";
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
static constexpr ActionId_t REBOOT_OBC = 32;
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
@ -46,19 +57,39 @@ public:
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
void performControlOperation() override;
/**
* Generate a file containing the chip lock/unlock states inside /tmp/chip_prot_status.txt
* @return
*/
static ReturnValue_t generateChipStateFile();
static ReturnValue_t incrementAllocationFailureCount();
static void getCurrentBootCopy(Chip& chip, Copy& copy);
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
/**
* Checks whether the target chip and copy are write protected and protect set them to a target
* state where applicable.
* @param targetChip
* @param targetCopy
* @param protect Target state
* @param protOperationPerformed [out] Can be used to determine whether any operation
* was performed
* @param updateProtFile Specify whether the protection info file is updated
* @return
*/
ReturnValue_t setBootCopyProtection(Chip targetChip, Copy targetCopy,
bool protect, bool& protOperationPerformed, bool updateProtFile = true);
bool sdInitFinished() const;
private:
static Chip currentChip;
static Copy currentCopy;
static Chip CURRENT_CHIP;
static Copy CURRENT_COPY;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode);
// Designated value for rechecking FIFO open
static constexpr int RETRY_FIFO_OPEN = -2;
int watchdogFifoFd = 0;
// States for SD state machine, which is used in non-blocking mode
enum class SdStates {
@ -85,9 +116,6 @@ private:
SdCardManager* sdcMan = nullptr;
ReturnValue_t initSdCardBlocking();
ReturnValue_t sdStateMachine();
struct SdInfo {
sd::SdCard pref = sd::SdCard::NONE;
sd::SdState prefState = sd::SdState::OFF;
@ -108,9 +136,30 @@ private:
sd::SdCard commandedCard = sd::SdCard::NONE;
sd::SdState commandedState = sd::SdState::OFF;
};
SdInfo sdInfo;
/**
* Index 0: Chip 0 Copy 0
* Index 1: Chip 0 Copy 1
* Index 2: Chip 1 Copy 0
* Index 3: Chip 1 Copy 1
*/
std::array<bool, 4> protArray;
PeriodicOperationDivider opDivider;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode);
ReturnValue_t initVersionFile();
ReturnValue_t initBootCopy();
ReturnValue_t initWatchdogFifo();
ReturnValue_t initSdCardBlocking();
void initPrint();
ReturnValue_t sdStateMachine();
void updateSdInfoOther();
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
bool printOutput = true);
@ -120,24 +169,16 @@ private:
void executeNextExternalSdCommand();
void checkExternalSdCommandStatus();
ReturnValue_t initVersionFile();
ReturnValue_t initBootCopy();
ReturnValue_t initWatchdogFifo();
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t *data, size_t size);
ReturnValue_t actionPerformReboot(const uint8_t *data, size_t size);
void initPrint();
// Designated value for rechecking FIFO open
static constexpr int RETRY_FIFO_OPEN = -2;
int watchdogFifoFd = 0;
PeriodicOperationDivider opDivider;
void performWatchdogControlOperation();
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
bool &protOperationPerformed, bool selfChip, bool selfCopy, bool allChips,
bool allCopies, uint8_t arrIdx);
};
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */

View File

@ -57,13 +57,14 @@ void initmission::initTasks() {
void (*missedDeadlineFunc) (void) = nullptr;
#endif
#if BOARD_TE0720 == 0
PeriodicTaskIF* coreController = factory->createPeriodicTask(
"CORE_CTRL", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
result = coreController->addComponent(objects::CORE_CONTROLLER);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER);
}
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
@ -95,14 +96,7 @@ void initmission::initTasks() {
initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK);
}
PeriodicTaskIF* plocUpdaterTask = factory->createPeriodicTask(
"PLOC_UPDATER_TASK", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc);
result = plocUpdaterTask->addComponent(objects::PLOC_UPDATER);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PLOC_UPDATER_TASK", objects::PLOC_UPDATER);
}
# if BOARD_TE0720 == 0
// FS task, task interval does not matter because it runs in permanent loop, priority low
// because it is a non-essential background task
PeriodicTaskIF* fsTask = factory->createPeriodicTask(
@ -111,8 +105,9 @@ void initmission::initTasks() {
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER);
}
#endif /* BOARD_TE0720 */
#if TEST_CCSDS_BRIDGE == 1
#if OBSW_TEST_CCSDS_BRIDGE == 1
PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask(
"PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE);
@ -125,8 +120,11 @@ void initmission::initTasks() {
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
std::vector<PeriodicTaskIF*> pstTasks;
createPstTasks(*factory, missedDeadlineFunc, pstTasks);
#if OBSW_ADD_TEST_CODE == 1
std::vector<PeriodicTaskIF*> testTasks;
createTestTasks(*factory, missedDeadlineFunc, testTasks);
#endif
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
for(const auto& task: taskVector) {
@ -143,8 +141,9 @@ void initmission::initTasks() {
tmTcDistributor->startTask();
tmtcBridgeTask->startTask();
tmtcPollingTask->startTask();
#if BOARD_TE0720 == 0
coreController->startTask();
plocUpdaterTask->startTask();
#endif
taskStarter(pstTasks, "PST task vector");
taskStarter(pusTasks, "PUS task vector");
@ -152,10 +151,13 @@ void initmission::initTasks() {
taskStarter(testTasks, "Test task vector");
#endif
#if TEST_CCSDS_BRIDGE == 1
#if OBSW_TEST_CCSDS_BRIDGE == 1
ptmeTestTask->startTask();
#endif
#if BOARD_TE0720 == 0
fsTask->startTask();
#endif
sif::info << "Tasks started.." << std::endl;
}
@ -165,7 +167,7 @@ void initmission::createPstTasks(TaskFactory& factory,
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
#if BOARD_TE0720 == 0
/* Polling Sequence Table Default */
#if Q7S_ADD_SPI_TEST == 0
#if OBSW_ADD_SPI_TEST_CODE == 0
FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask(
"PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
missedDeadlineFunc);
@ -203,9 +205,9 @@ void initmission::createPstTasks(TaskFactory& factory,
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl;
}
taskVec.push_back(i2cPst);
taskVec.push_back(gomSpacePstTask);
#else /* BOARD_TE7020 == 0 */
FixedTimeslotTaskIF * pollingSequenceTaskTE0720 = factory->createFixedTimeslotTask(
FixedTimeslotTaskIF * pollingSequenceTaskTE0720 = factory.createFixedTimeslotTask(
"PST_TASK_TE0720", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE * 8, 3.0,
missedDeadlineFunc);
result = pst::pollingSequenceTE0720(pollingSequenceTaskTE0720);
@ -287,25 +289,29 @@ void initmission::createPusTasks(TaskFactory &factory,
void initmission::createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*>& taskVec) {
#if OBSW_ADD_TEST_TASK == 1 || OBSW_ADD_SPI_TEST_CODE == 1 || (BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1)
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
#endif
PeriodicTaskIF* testTask = factory.createPeriodicTask(
"TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
#if OBSW_ADD_TEST_TASK == 1
result = testTask->addComponent(objects::TEST_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
}
#endif /* OBSW_ADD_TEST_TASK == 1 */
#if Q7S_ADD_SPI_TEST == 1
#if OBSW_ADD_SPI_TEST_CODE == 1
result = testTask->addComponent(objects::SPI_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
}
#endif
#if BOARD_TE0720 == 1 && TEST_LIBGPIOD == 1
#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1
result = testTask->addComponent(objects::LIBGPIOD_TEST);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
}
#endif /* BOARD_TE0720 == 1 && TEST_LIBGPIOD == 1 */
#endif /* BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 */
taskVec.push_back(testTask);
}

File diff suppressed because it is too large Load Diff

View File

@ -2,24 +2,27 @@
#define BSP_Q7S_OBJECTFACTORY_H_
class LinuxLibgpioIF;
class UartComIF;
class SpiComIF;
namespace ObjectFactory {
void setStatics();
void produce(void* args);
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF);
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF,
SpiComIF** spiComIF);
void createTmpComponents();
void createPcduComponents();
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
void createSunSensorComponents(LinuxLibgpioIF* gpioComIF);
void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF);
void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF);
void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF);
void createHeaterComponents();
void createSolarArrayDeploymentComponents();
void createSyrlinksComponents();
void createRtdComponents(LinuxLibgpioIF* gpioComIF);
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF);
void createTestComponents();
void createTestComponents(LinuxLibgpioIF* gpioComIF);
};

View File

@ -1,4 +1,5 @@
target_sources(${TARGET_NAME} PRIVATE
PlocSupervisorHandler.cpp
PlocUpdater.cpp
PlocMemoryDumper.cpp
)

View File

@ -0,0 +1,206 @@
#include <fsfw/src/fsfw/serialize/SerializeAdapter.h>
#include "fsfw/ipc/QueueFactory.h"
#include "PlocMemoryDumper.h"
#include <fstream>
#include <filesystem>
#include <string>
PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId) :
SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
}
PlocMemoryDumper::~PlocMemoryDumper() {
}
ReturnValue_t PlocMemoryDumper::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = commandActionHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PlocMemoryDumper::performOperation(uint8_t operationCode) {
readCommandQueue();
doStateMachine();
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PlocMemoryDumper::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
if (state != State::IDLE) {
return IS_BUSY;
}
switch (actionId) {
case DUMP_MRAM: {
size_t deserializeSize = sizeof(mram.startAddress) + sizeof(mram.endAddress);
SerializeAdapter::deSerialize(&mram.startAddress, &data, &deserializeSize,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&mram.endAddress, &data, &deserializeSize,
SerializeIF::Endianness::BIG);
if (mram.endAddress > MAX_MRAM_ADDRESS) {
return MRAM_ADDRESS_TOO_HIGH;
}
if (mram.endAddress <= mram.startAddress) {
return MRAM_INVALID_ADDRESS_COMBINATION;
}
state = State::COMMAND_FIRST_MRAM_DUMP;
break;
}
default: {
sif::warning << "PlocMemoryDumper::executeAction: Received command with invalid action id"
<< std::endl;
return INVALID_ACTION_ID;
}
}
return EXECUTION_FINISHED;
}
MessageQueueId_t PlocMemoryDumper::getCommandQueue() const {
return commandQueue->getId();
}
MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() {
return commandQueue;
}
void PlocMemoryDumper::readCommandQueue() {
CommandMessage message;
ReturnValue_t result;
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
result = commandQueue->receiveMessage(&message)) {
if (result != RETURN_OK) {
continue;
}
result = actionHelper.handleActionMessage(&message);
if (result == HasReturnvaluesIF::RETURN_OK) {
continue;
}
result = commandActionHelper.handleReply(&message);
if (result == HasReturnvaluesIF::RETURN_OK) {
continue;
}
sif::debug << "PlocMemoryDumper::readCommandQueue: Received message with invalid format"
<< std::endl;
}
}
void PlocMemoryDumper::doStateMachine() {
switch (state) {
case State::IDLE:
break;
case State::COMMAND_FIRST_MRAM_DUMP:
commandNextMramDump(PLOC_SPV::FIRST_MRAM_DUMP);
break;
case State::COMMAND_CONSECUTIVE_MRAM_DUMP:
commandNextMramDump(PLOC_SPV::CONSECUTIVE_MRAM_DUMP);
break;
case State::EXECUTING_MRAM_DUMP:
break;
default:
sif::debug << "PlocMemoryDumper::doStateMachine: Invalid state" << std::endl;
break;
}
}
void PlocMemoryDumper::stepSuccessfulReceived(ActionId_t actionId,
uint8_t step) {
}
void PlocMemoryDumper::stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) {
}
void PlocMemoryDumper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
}
void PlocMemoryDumper::completionSuccessfulReceived(ActionId_t actionId) {
switch (pendingCommand) {
case (PLOC_SPV::FIRST_MRAM_DUMP):
case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
if (mram.endAddress == mram.startAddress) {
triggerEvent(MRAM_DUMP_FINISHED);
state = State::IDLE;
}
else {
state = State::COMMAND_CONSECUTIVE_MRAM_DUMP;
}
break;
default:
sif::debug << "PlocMemoryDumper::completionSuccessfulReceived: Invalid pending command"
<< std::endl;
state = State::IDLE;
break;
}
}
void PlocMemoryDumper::completionFailedReceived(ActionId_t actionId,
ReturnValue_t returnCode) {
switch(pendingCommand) {
case(PLOC_SPV::FIRST_MRAM_DUMP):
case(PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
triggerEvent(MRAM_DUMP_FAILED, mram.lastStartAddress);
break;
default:
sif::debug << "PlocMemoryDumper::completionFailedReceived: Invalid pending command "
<< std::endl;
break;
}
state = State::IDLE;
}
void PlocMemoryDumper::commandNextMramDump(ActionId_t dumpCommand) {
ReturnValue_t result = RETURN_OK;
uint32_t tempStartAddress = 0;
uint32_t tempEndAddress = 0;
if (mram.endAddress - mram.startAddress > MAX_MRAM_DUMP_SIZE) {
tempStartAddress = mram.startAddress;
tempEndAddress = mram.startAddress + MAX_MRAM_DUMP_SIZE;
mram.startAddress += MAX_MRAM_DUMP_SIZE;
mram.lastStartAddress = tempStartAddress;
}
else {
tempStartAddress = mram.startAddress;
tempEndAddress = mram.endAddress;
mram.startAddress = mram.endAddress;
}
MemoryParams params(tempStartAddress, tempEndAddress);
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
dumpCommand, &params);
if (result != RETURN_OK) {
sif::warning << "PlocMemoryDumper::commandNextMramDump: Failed to send mram dump command "
<< "with start address " << tempStartAddress << " and end address "
<< tempEndAddress << std::endl;
triggerEvent(SEND_MRAM_DUMP_FAILED, result, tempStartAddress);
state = State::IDLE;
pendingCommand = NONE;
return;
}
state = State::EXECUTING_MRAM_DUMP;
pendingCommand = dumpCommand;
return;
}

View File

@ -0,0 +1,115 @@
#ifndef MISSION_DEVICES_PLOCMEMORYDUMPER_H_
#define MISSION_DEVICES_PLOCMEMORYDUMPER_H_
#include <bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h>
#include <bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h>
#include "OBSWConfig.h"
#include "fsfw/action/CommandActionHelper.h"
#include "fsfw/action/ActionHelper.h"
#include "fsfw/action/HasActionsIF.h"
#include "fsfw/action/CommandsActionsIF.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "bsp_q7s/memory/SdCardManager.h"
#include "linux/fsfwconfig/objects/systemObjectList.h"
#include "fsfw/tmtcpacket/SpacePacket.h"
/**
* @brief Because the buffer of the linux tty driver is limited to 2 x 65535 bytes, this class is
* created to perform large dumps of PLOC memories.
*
* @details Currently the PLOC supervisor only implements the functionality to dump the MRAM.
*
* @author J. Meier
*/
class PlocMemoryDumper : public SystemObject,
public HasActionsIF,
public ExecutableObjectIF,
public HasReturnvaluesIF,
public CommandsActionsIF {
public:
static const ActionId_t NONE = 0;
static const ActionId_t DUMP_MRAM = 1;
PlocMemoryDumper(object_id_t objectId);
virtual ~PlocMemoryDumper();
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
MessageQueueId_t getCommandQueue() const;
ReturnValue_t initialize() override;
MessageQueueIF* getCommandQueuePtr() override;
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
void completionSuccessfulReceived(ActionId_t actionId) override;
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
private:
static const uint32_t QUEUE_SIZE = 10;
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER;
//! [EXPORT] : [COMMENT] The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.
static const ReturnValue_t MRAM_ADDRESS_TOO_HIGH = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] The specified end address is lower than the start address
static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MEMORY_DUMPER;
//! [EXPORT] : [COMMENT] Failed to send mram dump command to supervisor handler
//! P1: Return value of commandAction function
//! P2: Start address of MRAM to dump with this command
static const Event SEND_MRAM_DUMP_FAILED = MAKE_EVENT(0, severity::LOW);
//! [EXPORT] : [COMMENT] Received completion failure report form PLOC supervisor handler
//! P1: MRAM start address of failing dump command
static const Event MRAM_DUMP_FAILED = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] MRAM dump finished successfully
static const Event MRAM_DUMP_FINISHED = MAKE_EVENT(2, severity::LOW);
// Maximum size of mram dump which can be retrieved with one command
static const uint32_t MAX_MRAM_DUMP_SIZE = 100000;
static const uint32_t MAX_MRAM_ADDRESS = 0x7d000;
MessageQueueIF* commandQueue = nullptr;
CommandActionHelper commandActionHelper;
ActionHelper actionHelper;
enum class State: uint8_t {
IDLE,
COMMAND_FIRST_MRAM_DUMP,
COMMAND_CONSECUTIVE_MRAM_DUMP,
EXECUTING_MRAM_DUMP
};
State state = State::IDLE;
ActionId_t pendingCommand = NONE;
typedef struct MemoryInfo {
// Stores the start address of the next memory range to dump
uint32_t startAddress;
uint32_t endAddress;
// Stores the start address of the last sent dump command
uint32_t lastStartAddress;
} MemoryInfo_t;
MemoryInfo_t mram = {0, 0, 0};
void readCommandQueue();
void doStateMachine();
/**
* @brief Sends the next mram dump command to the PLOC supervisor handler.
*/
void commandNextMramDump(ActionId_t dumpCommand);
};
#endif /* MISSION_DEVICES_PLOCMEMORYDUMPER_H_ */

View File

@ -34,7 +34,9 @@ ReturnValue_t PlocSupervisorHandler::initialize() {
return INVALID_UART_COM_IF;
}
#if BOARD_TE0720 == 0
sdcMan = SdCardManager::instance();
#endif /* BOARD_TE0720 == 0 */
return result;
}
@ -49,7 +51,7 @@ void PlocSupervisorHandler::doStartUp(){
}
void PlocSupervisorHandler::doShutDown(){
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(
@ -197,10 +199,10 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(
result = prepareWipeMramCmd(commandData);
break;
}
case(PLOC_SPV::DUMP_MRAM): {
case(PLOC_SPV::FIRST_MRAM_DUMP):
case(PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
result = prepareDumpMramCmd(commandData);
break;
}
case(PLOC_SPV::PRINT_CPU_STATS): {
preparePrintCpuStatsCmd(commandData);
result = RETURN_OK;
@ -317,7 +319,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR);
this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR);
this->insertInCommandMap(PLOC_SPV::CAN_LOOPBACK_TEST);
this->insertInCommandAndReplyMap(PLOC_SPV::DUMP_MRAM, 3);
this->insertInCommandAndReplyMap(PLOC_SPV::FIRST_MRAM_DUMP, 3);
this->insertInCommandAndReplyMap(PLOC_SPV::CONSECUTIVE_MRAM_DUMP, 3);
this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT);
this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT);
this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT);
@ -330,8 +333,12 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start,
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
if (nextReplyId == PLOC_SPV::DUMP_MRAM) {
*foundId = PLOC_SPV::DUMP_MRAM;
if (nextReplyId == PLOC_SPV::FIRST_MRAM_DUMP) {
*foundId = PLOC_SPV::FIRST_MRAM_DUMP;
return parseMramPackets(start, remainingSize, foundLen);
}
else if (nextReplyId == PLOC_SPV::CONSECUTIVE_MRAM_DUMP) {
*foundId = PLOC_SPV::CONSECUTIVE_MRAM_DUMP;
return parseMramPackets(start, remainingSize, foundLen);
}
@ -400,10 +407,10 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
result = handleLatchupStatusReport(packet);
break;
}
case (PLOC_SPV::DUMP_MRAM): {
result = handleMramDumpPacket();
case (PLOC_SPV::FIRST_MRAM_DUMP):
case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
result = handleMramDumpPacket(id);
break;
}
case (PLOC_SPV::EXE_REPORT): {
result = handleExecutionReport(packet);
break;
@ -465,6 +472,7 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MON, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_YEAR, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MSEC, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_IS_SET, new PoolEntry<uint32_t>( { 0 }));
return HasReturnvaluesIF::RETURN_OK;
}
@ -508,13 +516,23 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
}
break;
}
case PLOC_SPV::DUMP_MRAM: {
case PLOC_SPV::FIRST_MRAM_DUMP: {
enabledReplies = 2; // expected replies will be increased in handleMramDumpPacket
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
PLOC_SPV::DUMP_MRAM);
PLOC_SPV::FIRST_MRAM_DUMP);
if (result != RETURN_OK) {
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
<< PLOC_SPV::LATCHUP_REPORT << " not in replyMap" << std::endl;
<< PLOC_SPV::FIRST_MRAM_DUMP << " not in replyMap" << std::endl;
}
break;
}
case PLOC_SPV::CONSECUTIVE_MRAM_DUMP: {
enabledReplies = 2; // expected replies will be increased in handleMramDumpPacket
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
PLOC_SPV::CONSECUTIVE_MRAM_DUMP);
if (result != RETURN_OK) {
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
<< PLOC_SPV::CONSECUTIVE_MRAM_DUMP << " not in replyMap" << std::endl;
}
break;
}
@ -555,6 +573,7 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
case PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR:
case PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR:
case PLOC_SPV::REQUEST_LOGGING_DATA:
case PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION:
enabledReplies = 2;
break;
default:
@ -736,7 +755,7 @@ ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) {
nextReplyId = PLOC_SPV::EXE_REPORT;
#if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
sif::info << "PlocSupervisorHandler::handleHkReport: temp_ps: " << hkset.tempPs << std::endl;
sif::info << "PlocSupervisorHandler::handleHkReport: temp_pl: " << hkset.tempPl << std::endl;
sif::info << "PlocSupervisorHandler::handleHkReport: temp_sup: " << hkset.tempSup << std::endl;
@ -793,7 +812,7 @@ ReturnValue_t PlocSupervisorHandler::handleBootStatusReport(const uint8_t* data)
nextReplyId = PLOC_SPV::EXE_REPORT;
#if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot signal: "
<< static_cast<unsigned int>(bootStatusReport.bootSignal.value) << std::endl;
sif::info << "PlocSupervisorHandler::handleBootStatusReport: Reset counter: "
@ -865,10 +884,13 @@ ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* da
latchupStatusReport.timeMsec = *(data + offset) << 24 | *(data + offset + 1) << 16 |
*(data + offset + 2) << 8 | *(data + offset + 3);
offset += 4;
latchupStatusReport.isSet = *(data + offset) << 24 | *(data + offset + 1) << 16 |
*(data + offset + 2) << 8 | *(data + offset + 3);
offset += 4;
nextReplyId = PLOC_SPV::EXE_REPORT;
#if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup ID: "
<< static_cast<unsigned int>(latchupStatusReport.id.value) << std::endl;
sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT0: "
@ -899,6 +921,8 @@ ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* da
<< latchupStatusReport.timeYear << std::endl;
sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Msec: "
<< latchupStatusReport.timeMsec << std::endl;
sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: isSet: 0x"
<< std::hex << latchupStatusReport.timeMsec << std::dec << std::endl;
#endif
return result;
@ -915,8 +939,11 @@ void PlocSupervisorHandler::setNextReplyId() {
case PLOC_SPV::GET_LATCHUP_STATUS_REPORT:
nextReplyId = PLOC_SPV::LATCHUP_REPORT;
break;
case PLOC_SPV::DUMP_MRAM:
nextReplyId = PLOC_SPV::DUMP_MRAM;
case PLOC_SPV::FIRST_MRAM_DUMP:
nextReplyId = PLOC_SPV::FIRST_MRAM_DUMP;
break;
case PLOC_SPV::CONSECUTIVE_MRAM_DUMP:
nextReplyId = PLOC_SPV::CONSECUTIVE_MRAM_DUMP;
break;
default:
/* If no telemetry is expected the next reply is always the execution report */
@ -933,7 +960,8 @@ size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId){
return replyLen;
}
if (nextReplyId == PLOC_SPV::DUMP_MRAM) {
if (nextReplyId == PLOC_SPV::FIRST_MRAM_DUMP
|| nextReplyId == PLOC_SPV::CONSECUTIVE_MRAM_DUMP) {
/**
* Try to read 20 MRAM packets. If reply is larger, the packets will be read with the
* next doSendRead call. The command will be as long active as the packet with the sequence
@ -1338,7 +1366,7 @@ ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, siz
return result;
}
ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() {
ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket(DeviceCommandId_t id) {
ReturnValue_t result = RETURN_FAILED;
@ -1350,24 +1378,24 @@ ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() {
sif::warning << "PlocSupervisorHandler::handleMramDumpPacket: CRC failure" << std::endl;
return result;
}
handleMramDumpFile();
handleMramDumpFile(id);
if (downlinkMramDump == true) {
handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1,
PLOC_SPV::DUMP_MRAM);
id);
}
packetInBuffer = false;
receivedMramDumpPackets++;
if (expectedMramDumpPackets == receivedMramDumpPackets) {
nextReplyId = PLOC_SPV::EXE_REPORT;
}
increaseExpectedMramReplies();
increaseExpectedMramReplies(id);
return RETURN_OK;
}
return result;
}
void PlocSupervisorHandler::increaseExpectedMramReplies() {
DeviceReplyMap::iterator mramDumpIter = deviceReplyMap.find(PLOC_SPV::DUMP_MRAM);
void PlocSupervisorHandler::increaseExpectedMramReplies(DeviceCommandId_t id) {
DeviceReplyMap::iterator mramDumpIter = deviceReplyMap.find(id);
DeviceReplyMap::iterator exeReportIter = deviceReplyMap.find(PLOC_SPV::EXE_REPORT);
if (mramDumpIter == deviceReplyMap.end()) {
sif::debug << "PlocSupervisorHandler::increaseExpectedMramReplies: Dump MRAM reply not "
@ -1398,7 +1426,8 @@ void PlocSupervisorHandler::increaseExpectedMramReplies() {
return;
}
uint8_t sequenceFlags = spacePacketBuffer[2] >> 6;
if (sequenceFlags != static_cast<uint8_t>(PLOC_SPV::SequenceFlags::LAST_PKT)) {
if (sequenceFlags != static_cast<uint8_t>(PLOC_SPV::SequenceFlags::LAST_PKT)
&& (sequenceFlags != static_cast<uint8_t>(PLOC_SPV::SequenceFlags::STANDALONE_PKT))) {
// Command expects at least one MRAM packet more and the execution report
info->expectedReplies = 2;
// Wait maximum of 2 cycles for next MRAM packet
@ -1422,14 +1451,17 @@ ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() {
return APERIODIC_REPLY;
}
ReturnValue_t PlocSupervisorHandler::handleMramDumpFile() {
ReturnValue_t PlocSupervisorHandler::handleMramDumpFile(DeviceCommandId_t id) {
ReturnValue_t result = RETURN_OK;
uint16_t packetLen = readSpacePacketLength(spacePacketBuffer);
uint8_t sequenceFlags = readSequenceFlags(spacePacketBuffer);
if (sequenceFlags == static_cast<uint8_t>(PLOC_SPV::SequenceFlags::FIRST_PKT)) {
result = createMramDumpFile();
if (result != RETURN_OK) {
return result;
if (id == PLOC_SPV::FIRST_MRAM_DUMP) {
if (sequenceFlags == static_cast<uint8_t>(PLOC_SPV::SequenceFlags::FIRST_PKT)
|| (sequenceFlags == static_cast<uint8_t>(PLOC_SPV::SequenceFlags::STANDALONE_PKT))) {
result = createMramDumpFile();
if (result != RETURN_OK) {
return result;
}
}
}
if (not std::filesystem::exists(activeMramFile)) {
@ -1462,7 +1494,12 @@ ReturnValue_t PlocSupervisorHandler::createMramDumpFile() {
}
std::string filename = "mram-dump--" + timeStamp + ".bin";
#if BOARD_TE0720 == 0
std::string currentMountPrefix = sdcMan->getCurrentMountPrefix();
#else
std::string currentMountPrefix("/mnt/sd0");
#endif /* BOARD_TE0720 == 0 */
// Check if path to PLOC directory exists
if (not std::filesystem::exists(std::string(currentMountPrefix + "/" + plocFilePath))) {

View File

@ -125,7 +125,9 @@ private:
/** This buffer is used to concatenate space packets received in two different read steps */
uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE];
#if BOARD_TE0720 == 0
SdCardManager* sdcMan = nullptr;
#endif /* BOARD_TE0720 == 0 */
/** Path to PLOC specific files on SD card */
std::string plocFilePath = "ploc";
@ -293,14 +295,14 @@ private:
/**
* @brief This function generates the Service 8 packets for the MRAM dump data.
*/
ReturnValue_t handleMramDumpPacket();
ReturnValue_t handleMramDumpPacket(DeviceCommandId_t id);
/**
* @brief With this function the number of expected replies following an MRAM dump command
* will be increased. This is necessary to release the command in case not all replies
* have been received.
*/
void increaseExpectedMramReplies();
void increaseExpectedMramReplies(DeviceCommandId_t id);
/**
* @brief Function checks if the packet written to the space packet buffer is really a
@ -312,7 +314,7 @@ private:
* @brief Writes the data of the MRAM dump to a file. The file will be created when receiving
* the first packet.
*/
ReturnValue_t handleMramDumpFile();
ReturnValue_t handleMramDumpFile(DeviceCommandId_t id);
/**
* @brief Extracts the length field of a spacePacket referenced by the spacePacket pointer.

View File

@ -14,8 +14,9 @@ PlocUpdater::~PlocUpdater() {
}
ReturnValue_t PlocUpdater::initialize() {
#if BOARD_TE0720 == 0
sdcMan = SdCardManager::instance();
#endif
ReturnValue_t result = SystemObject::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
@ -51,21 +52,37 @@ ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId,
}
switch (actionId) {
case UPDATE_NVM0_A:
updatePartition = Partition::A;
updateMemory = Memory::NVM0;
case UPDATE_A_UBOOT:
image = Image::A;
partition = Partition::UBOOT;
break;
case UPDATE_NVM0_B:
updatePartition = Partition::B;
updateMemory = Memory::NVM0;
case UPDATE_A_BITSTREAM:
image = Image::A;
partition = Partition::BITSTREAM;
break;
case UPDATE_NVM1_A:
updatePartition = Partition::A;
updateMemory = Memory::NVM1;
case UPDATE_A_LINUX:
image = Image::A;
partition = Partition::LINUX_OS;
break;
case UPDATE_NVM1_B:
updatePartition = Partition::B;
updateMemory = Memory::NVM1;
case UPDATE_A_APP_SW:
image = Image::A;
partition = Partition::APP_SW;
break;
case UPDATE_B_UBOOT:
image = Image::B;
partition = Partition::UBOOT;
break;
case UPDATE_B_BITSTREAM:
image = Image::B;
partition = Partition::BITSTREAM;
break;
case UPDATE_B_LINUX:
image = Image::B;
partition = Partition::LINUX_OS;
break;
case UPDATE_B_APP_SW:
image = Image::B;
partition = Partition::APP_SW;
break;
default:
return INVALID_ACTION_ID;
@ -148,6 +165,7 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
return result;
}
#if BOARD_TE0720 == 0
// Check if file is stored on SD card and if associated SD card is mounted
if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) {
if (!isSdCardMounted(sd::SLOT_0)) {
@ -164,6 +182,7 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
else {
//update image not stored on SD card
}
#endif /* BOARD_TE0720 == 0 */
updateFile = std::string(reinterpret_cast<const char*>(data), size);
@ -174,6 +193,7 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
return RETURN_OK;
}
#if BOARD_TE0720 == 0
bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) {
SdCardManager::SdStatePair active;
ReturnValue_t result = sdcMan->getSdCardActiveStatus(active);
@ -202,6 +222,7 @@ bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) {
}
return false;
}
#endif /* #if BOARD_TE0720 == 0 */
void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId,
uint8_t step) {
@ -287,10 +308,10 @@ void PlocUpdater::commandUpdateAvailable() {
remainingPackets = numOfUpdatePackets;
packetsSent = 0;
uint32_t imageCrc = makeCrc();
calcImageCrc();
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast<uint8_t>(updateMemory),
static_cast<uint8_t>(updatePartition), imageSize, imageCrc, numOfUpdatePackets);
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast<uint8_t>(image),
static_cast<uint8_t>(partition), imageSize, imageCrc, numOfUpdatePackets);
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize());
@ -333,7 +354,7 @@ void PlocUpdater::commandUpdatePacket() {
file.close();
// sequence count of first packet is 1
packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK);
if (numOfUpdatePackets > 0) {
if (numOfUpdatePackets > 1) {
adjustSequenceFlags(packet);
}
packet.makeCrc();
@ -360,8 +381,8 @@ void PlocUpdater::commandUpdatePacket() {
void PlocUpdater::commandUpdateVerify() {
ReturnValue_t result = RETURN_OK;
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast<uint8_t>(updateMemory),
static_cast<uint8_t>(updatePartition), imageSize, imageCrc, numOfUpdatePackets);
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast<uint8_t>(image),
static_cast<uint8_t>(partition), imageSize, imageCrc, numOfUpdatePackets);
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize());
@ -378,9 +399,27 @@ void PlocUpdater::commandUpdateVerify() {
return;
}
ReturnValue_t PlocUpdater::makeCrc() {
//TODO: Waiting on input from TAS about the CRC to use
return 0;
void PlocUpdater::calcImageCrc() {
std::ifstream file(updateFile, std::ifstream::binary);
file.seekg(0, file.end);
uint32_t count;
uint32_t bit;
uint32_t remainder = INITIAL_REMAINDER_32;
char input;
for (count = 0; count < imageSize; count++) {
file.seekg(count, file.beg);
file.read(&input, 1);
remainder ^= (input << 16);
for (bit = 8; bit > 0; --bit) {
if (remainder & TOPBIT_32) {
remainder = (remainder << 1) ^ POLYNOMIAL_32;
} else {
remainder = (remainder << 1);
}
}
}
file.close();
imageCrc = (remainder ^ FINAL_XOR_VALUE_32);
}
void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) {

View File

@ -33,10 +33,14 @@ class PlocUpdater : public SystemObject,
public CommandsActionsIF {
public:
static const ActionId_t UPDATE_NVM0_A = 0;
static const ActionId_t UPDATE_NVM0_B = 1;
static const ActionId_t UPDATE_NVM1_A = 2;
static const ActionId_t UPDATE_NVM1_B = 3;
static const ActionId_t UPDATE_A_UBOOT = 0;
static const ActionId_t UPDATE_A_BITSTREAM = 1;
static const ActionId_t UPDATE_A_LINUX = 2;
static const ActionId_t UPDATE_A_APP_SW = 3;
static const ActionId_t UPDATE_B_UBOOT = 4;
static const ActionId_t UPDATE_B_BITSTREAM = 5;
static const ActionId_t UPDATE_B_LINUX = 6;
static const ActionId_t UPDATE_B_APP_SW = 7;
PlocUpdater(object_id_t objectId);
virtual ~PlocUpdater();
@ -92,10 +96,16 @@ private:
// Maximum size of update payload data per space packet (max size of space packet is 1024 bytes)
static const size_t MAX_SP_DATA = 1016;
static const uint32_t TOPBIT_32 = (1 << 31);
static const uint32_t POLYNOMIAL_32 = 0x04C11DB7;
static const uint32_t INITIAL_REMAINDER_32 = 0xFFFFFFFF;
static const uint32_t FINAL_XOR_VALUE_32 = 0xFFFFFFFF;
MessageQueueIF* commandQueue = nullptr;
#if BOARD_TE0720 == 0
SdCardManager* sdcMan = nullptr;
#endif
CommandActionHelper commandActionHelper;
ActionHelper actionHelper;
@ -112,19 +122,23 @@ private:
ActionId_t pendingCommand = PLOC_SPV::NONE;
enum class Memory: uint8_t {
NVM0,
NVM1
};
Memory updateMemory = Memory::NVM0;
enum class Partition: uint8_t {
enum class Image: uint8_t {
NONE,
A,
B
};
Partition updatePartition = Partition::A;
Image image = Image::NONE;
enum class Partition: uint8_t {
NONE,
UBOOT,
BITSTREAM,
LINUX_OS,
APP_SW
};
Partition partition = Partition::NONE;
uint32_t packetsSent = 0;
uint32_t remainingPackets = 0;
@ -160,12 +174,14 @@ private:
*/
void commandUpdateVerify();
#if BOARD_TE0720 == 0
/**
* @brief Checks whether the SD card to read from is mounted or not.
*/
bool isSdCardMounted(sd::SdCard sdCard);
#endif
ReturnValue_t makeCrc();
void calcImageCrc();
void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet);
};

View File

@ -0,0 +1,33 @@
#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_
#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_
#include <fsfw/src/fsfw/serialize/SerialLinkedListAdapter.h>
class MemoryParams: public SerialLinkedListAdapter<SerializeIF> {
public:
/**
* @brief Constructor
* @param startAddress Start of address range to dump
* @param endAddress End of address range to dump
*/
MemoryParams(uint32_t startAddress, uint32_t endAddress) :
startAddress(startAddress), endAddress(endAddress) {
setLinks();
}
private:
void setLinks() {
setStart(&startAddress);
startAddress.setNext(&endAddress);
}
SerializeElement<uint32_t> startAddress;
SerializeElement<uint32_t> endAddress;
};
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ */

View File

@ -42,7 +42,7 @@ static const DeviceCommandId_t ENABLE_NVMS = 26;
static const DeviceCommandId_t SELECT_NVM = 27;
static const DeviceCommandId_t RUN_AUTO_EM_TESTS = 28;
static const DeviceCommandId_t WIPE_MRAM = 29;
static const DeviceCommandId_t DUMP_MRAM = 30;
static const DeviceCommandId_t FIRST_MRAM_DUMP = 30;
static const DeviceCommandId_t SET_DBG_VERBOSITY = 31;
static const DeviceCommandId_t CAN_LOOPBACK_TEST = 32;
static const DeviceCommandId_t PRINT_CPU_STATS = 33;
@ -55,6 +55,7 @@ static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39;
static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40;
static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41;
static const DeviceCommandId_t UPDATE_VERIFY = 42;
static const DeviceCommandId_t CONSECUTIVE_MRAM_DUMP = 43;
/** Reply IDs */
static const DeviceCommandId_t ACK_REPORT = 50;
@ -67,7 +68,7 @@ static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_HK_REPORT = 48;
static const uint16_t SIZE_BOOT_STATUS_REPORT = 22;
static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 51;
static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 55;
/**
* SpacePacket apids of telemetry packets
@ -196,11 +197,12 @@ enum PoolIds
LATCHUP_RPT_TIME_YEAR,
LATCHUP_RPT_TIME_MSEC,
LATCHUP_RPT_TIME_USEC,
LATCHUP_RPT_TIME_IS_SET,
};
static const uint8_t HK_SET_ENTRIES = 13;
static const uint8_t BOOT_REPORT_SET_ENTRIES = 8;
static const uint8_t LATCHUP_RPT_SET_ENTRIES = 15;
static const uint8_t LATCHUP_RPT_SET_ENTRIES = 16;
static const uint32_t HK_SET_ID = HK_REPORT;
static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT;
@ -1445,15 +1447,16 @@ public:
*
* @param apid Packet can be used to generate the update available and the update verify
* packet. Thus the APID must be specified here.
* @param memory The memory to apply the update (NVM0 - 0, NVM1 - 1)
* @param partition The partition to update (A - 0, B - 1)
* @param image The image to update on a NVM (A - 0, B - 1)
* @param partition The partition to update. uboot - 1, bitstream - 2, linux - 3,
* application - 4
* @param imageSize The size of the update image
* param numPackets The number of space packets required to transfer all data.
*/
UpdateInfo(uint16_t apid, uint8_t memory, uint8_t partition, uint32_t imageSize,
UpdateInfo(uint16_t apid, uint8_t image, uint8_t partition, uint32_t imageSize,
uint32_t imageCrc, uint32_t numPackets) :
SupvTcSpacePacket(PAYLOAD_LENGTH, apid), memory(memory), partition(partition), imageSize(
imageSize), numPackets(numPackets) {
SupvTcSpacePacket(PAYLOAD_LENGTH, apid), image(image), partition(partition), imageSize(
imageSize), imageCrc(imageCrc), numPackets(numPackets) {
initPacket();
makeCrc();
}
@ -1462,7 +1465,7 @@ private:
static const uint16_t PAYLOAD_LENGTH = 14; // length without CRC field
uint8_t memory = 0;
uint8_t image = 0;
uint8_t partition = 0;
uint32_t imageSize = 0;
uint32_t imageCrc = 0;
@ -1471,8 +1474,8 @@ private:
void initPacket() {
size_t serializedSize = 0;
uint8_t* data_field_ptr = this->localData.fields.buffer;
SerializeAdapter::serialize<uint8_t>(&memory, &data_field_ptr, &serializedSize,
sizeof(memory), SerializeIF::Endianness::BIG);
SerializeAdapter::serialize<uint8_t>(&image, &data_field_ptr, &serializedSize,
sizeof(image), SerializeIF::Endianness::BIG);
serializedSize = 0;
SerializeAdapter::serialize<uint8_t>(&partition, &data_field_ptr, &serializedSize,
sizeof(partition), SerializeIF::Endianness::BIG);
@ -1599,6 +1602,7 @@ public:
lp_var_t<uint32_t> timeMon = lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MON, this);
lp_var_t<uint32_t> timeYear = lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_YEAR, this);
lp_var_t<uint32_t> timeMsec = lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MSEC, this);
lp_var_t<uint32_t> isSet = lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_IS_SET, this);
};
}

View File

@ -1,4 +1,5 @@
#include "gpioCallbacks.h"
#include "busConf.h"
#include <devices/gpioIds.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
@ -23,30 +24,31 @@ void initSpiCsDecoder(GpioIF* gpioComIF) {
GpioCookie* spiMuxGpios = new GpioCookie;
GpiodRegularByLabel* spiMuxBit = nullptr;
/** Setting mux bit 1 to low will disable IC21 on the interface board */
GpiodRegular* spiMuxBit1 = new GpiodRegular(std::string("gpiochip7"), 13,
std::string("SPI Mux Bit 1"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit1);
spiMuxBit = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::SPI_MUX_BIT_1,
"SPI Mux Bit 1", gpio::OUT, gpio::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit);
/** Setting mux bit 2 to low disables IC1 on the TCS board */
GpiodRegular* spiMuxBit2 = new GpiodRegular(std::string("gpiochip7"), 14,
std::string("SPI Mux Bit 2"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit2);
spiMuxBit = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::SPI_MUX_BIT_2,
"SPI Mux Bit 2", gpio::OUT, gpio::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit);
/** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */
GpiodRegular* spiMuxBit3 = new GpiodRegular(std::string("gpiochip7"), 15,
std::string("SPI Mux Bit 3"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit3);
spiMuxBit = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::SPI_MUX_BIT_3,
"SPI Mux Bit 3", gpio::OUT, gpio::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit);
/** The following gpios can take arbitrary initial values */
GpiodRegular* spiMuxBit4 = new GpiodRegular(std::string("gpiochip7"), 16,
std::string("SPI Mux Bit 4"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit4);
GpiodRegular* spiMuxBit5 = new GpiodRegular(std::string("gpiochip7"), 17,
std::string("SPI Mux Bit 5"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit5);
GpiodRegular* spiMuxBit6 = new GpiodRegular(std::string("gpiochip7"), 18,
std::string("SPI Mux Bit 6"), gpio::OUT, 0);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit6);
GpiodRegular* enRwDecoder = new GpiodRegular(std::string("gpiochip5"), 17,
std::string("EN_RW_CS"), gpio::OUT, 1);
spiMuxBit = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::SPI_MUX_BIT_4,
"SPI Mux Bit 4", gpio::OUT, gpio::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit);
spiMuxBit = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::SPI_MUX_BIT_5,
"SPI Mux Bit 5", gpio::OUT, gpio::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit);
spiMuxBit = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::SPI_MUX_BIT_6,
"SPI Mux Bit 6", gpio::OUT, gpio::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit);
GpiodRegularByLabel* enRwDecoder = new GpiodRegularByLabel(q7s::GPIO_FLEX_OBC1F_B1,
q7s::EN_RW_CS, "EN_RW_CS", gpio::OUT, gpio::HIGH);
spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder);
result = gpioComInterface->addGpios(spiMuxGpios);

View File

@ -11,6 +11,10 @@ int simple::simple() {
{
FileSystemTest fileSystemTest;
}
#endif
#if TE0720_GPIO_TEST
#endif
return 0;
}

View File

@ -11,17 +11,6 @@ if(LINK_LWIP)
endif()
endif()
if(LINK_HAL)
message(STATUS "Linking against ${LIB_HAL_NAME} HAL library")
if(LIB_HAL_NAME)
target_link_libraries(${TARGET_NAME} PUBLIC
${LIB_HAL_NAME}
)
else()
message(WARNING "HAL library name not set!")
endif()
endif()
if(LINKER_SCRIPT)
target_link_options(${TARGET_NAME} PRIVATE
-T${LINKER_SCRIPT}
@ -52,11 +41,14 @@ target_compile_options(${TARGET_NAME} PRIVATE
$<$<COMPILE_LANGUAGE:ASM>:${ASM_FLAGS}>
)
set(STRIPPED_TARGET_NAME ${TARGET_NAME}-stripped)
add_custom_command(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET_NAME} ${TARGET_NAME}.bin
COMMENT "Generating binary file ${CMAKE_PROJECT_NAME}.bin.."
COMMAND ${CMAKE_STRIP} --strip-all ${TARGET_NAME} -o ${STRIPPED_TARGET_NAME}
BYPRODUCTS ${STRIPPED_TARGET_NAME}
COMMENT "Generating stripped executable ${STRIPPED_TARGET_NAME}.."
)
endfunction()

View File

@ -53,9 +53,9 @@ endif()
if(TGT_BSP)
if (${TGT_BSP} MATCHES "arm/raspberrypi" OR ${TGT_BSP} MATCHES "arm/beagleboneblack")
if (TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack")
set(BSP_PATH "bsp_linux_board")
elseif(${TGT_BSP} MATCHES "arm/q7s")
elseif(TGT_BSP MATCHES "arm/q7s")
set(BSP_PATH "bsp_q7s")
else()
message(WARNING "CMake not configured for this target!")

View File

@ -1,5 +1,8 @@
if(DEFINED ENV{Q7S_SYSROOT})
set(ENV{Q7S_ROOTFS} $ENV{Q7S_SYSROOT})
endif()
# CROSS_COMPILE also needs to be set accordingly or passed to the CMake command
if(NOT DEFINED ENV{Q7S_SYSROOT})
if(NOT DEFINED ENV{Q7S_ROOTFS})
# Sysroot has not been cached yet and was not set in environment either
if(NOT DEFINED SYSROOT_PATH)
message(FATAL_ERROR
@ -7,7 +10,7 @@ if(NOT DEFINED ENV{Q7S_SYSROOT})
)
endif()
else()
set(SYSROOT_PATH "$ENV{Q7S_SYSROOT}" CACHE PATH "Q7S root filesystem path")
set(SYSROOT_PATH "$ENV{Q7S_ROOTFS}" CACHE PATH "Q7S root filesystem path")
endif()
if(NOT DEFINED ENV{CROSS_COMPILE})
@ -42,6 +45,7 @@ find_program (CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX} REQUIRED)
# Useful utilities, not strictly necessary
find_program(CMAKE_SIZE ${CROSS_COMPILE_SIZE})
find_program(CMAKE_OBJCOPY ${CROSS_COMPILE_OBJCOPY})
find_program(CMAKE_STRIP ${CROSS_COMPILE_STRIP})
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSROOT "${SYSROOT_PATH}")

View File

@ -0,0 +1,35 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Release-Q7S"
build_generator=""
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
python="py"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "size" -t "${tgt_bsp}" \
-l"${build_dir}"
# set +x

View File

@ -4,7 +4,7 @@
const char* const SW_NAME = "eive";
#define SW_VERSION 1
#define SW_SUBVERSION 6
#define SW_REVISION 1
#define SW_SUBVERSION 7
#define SW_REVISION 0
#endif /* COMMON_CONFIG_OBSWVERSION_H_ */

View File

@ -21,6 +21,7 @@ enum commonClassIds: uint8_t {
CCSDS_IP_CORE_BRIDGE, //IPCI
PLOC_UPDATER, //PLUD
GOM_SPACE_HANDLER, //GOMS
PLOC_MEMORY_DUMPER, //PLMEMDUMP
COMMON_CLASS_ID_END // [EXPORT] : [END]
};

View File

@ -75,14 +75,15 @@ enum commonObjects: uint32_t {
GPS0_HANDLER = 0x44130045,
GPS1_HANDLER = 0x44130146,
RW1 = 0x44120001,
RW2 = 0x44120002,
RW3 = 0x44120003,
RW4 = 0x44120004,
RW1 = 0x44120047,
RW2 = 0x44120148,
RW3 = 0x44120249,
RW4 = 0x44120350,
START_TRACKER = 0x44130001,
PLOC_UPDATER = 0x44330000
PLOC_UPDATER = 0x44330000,
PLOC_MEMORY_DUMPER = 0x44330001
};
}

View File

@ -18,6 +18,7 @@ enum: uint8_t {
PLOC_SUPERVISOR_HANDLER = 115,
FILE_SYSTEM = 116,
PLOC_UPDATER = 117,
PLOC_MEMORY_DUMPER = 118,
COMMON_SUBSYSTEM_ID_END
};
}

50
common/config/devConf.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef COMMON_CONFIG_DEVCONF_H_
#define COMMON_CONFIG_DEVCONF_H_
#include <cstdint>
#include <fsfw_hal/linux/spi/spiDefinitions.h>
/**
* SPI configuration will be contained here to let the device handlers remain independent
* of SPI specific properties.
*/
namespace spi {
// Default values, changing them is not supported for now
static constexpr uint32_t DEFAULT_LIS3_SPEED = 976'000;
static constexpr uint32_t LIS3_TRANSITION_DELAY = 10000;
static constexpr spi::SpiModes DEFAULT_LIS3_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_RM3100_SPEED = 976'000;
static constexpr uint32_t RM3100_TRANSITION_DELAY = 10000;
static constexpr spi::SpiModes DEFAULT_RM3100_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_L3G_SPEED = 976'000;
static constexpr uint32_t L3G_TRANSITION_DELAY = 10000;
static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 3'900'000;
static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_ADIS16507_SPEED = 976'000;
static constexpr spi::SpiModes DEFAULT_ADIS16507_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t RW_SPEED = 300'000;
static constexpr spi::SpiModes RW_MODE = spi::SpiModes::MODE_0;
static constexpr uint32_t RTD_SPEED = 2'000'000;
}
namespace uart {
static constexpr size_t HYPERION_GPS_REPLY_MAX_BUFFER = 1024;
static constexpr uint32_t SYRLINKS_BAUD = 38400;
static constexpr uint32_t GNSS_BAUD = 9600;
static constexpr uint32_t PLOC_MPSOC_BAUD = 115200;
static constexpr uint32_t PLOC_SUPERVISOR_BAUD = 115200;
static constexpr uint32_t STAR_TRACKER_BAUD = 115200;
}
#endif /* COMMON_CONFIG_DEVCONF_H_ */

View File

@ -1,34 +0,0 @@
#ifndef COMMON_CONFIG_SPICONF_H_
#define COMMON_CONFIG_SPICONF_H_
#include <cstdint>
#include <fsfw_hal/linux/spi/spiDefinitions.h>
/**
* SPI configuration will be contained here to let the device handlers remain independent
* of SPI specific properties.
*/
namespace spi {
/* Default values, changing them is not supported for now */
static constexpr uint32_t DEFAULT_LIS3_SPEED = 3'900'000;
static constexpr spi::SpiModes DEFAULT_LIS3_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_RM3100_SPEED = 976'000;
static constexpr spi::SpiModes DEFAULT_RM3100_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_L3G_SPEED = 3'900'000;
static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 3'900'000;
static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t DEFAULT_ADIS16507_SPEED = 976'000;
static constexpr spi::SpiModes DEFAULT_ADIS16507_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t RW_SPEED = 300000;
static constexpr spi::SpiModes RW_MODE = spi::SpiModes::MODE_0;
}
#endif /* COMMON_CONFIG_SPICONF_H_ */

2
fsfw

Submodule fsfw updated: 1ac372cb89...e1a85b47c5

1
generators/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.~lock*

View File

@ -90,13 +90,17 @@
11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h
11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h
11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h
11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h
11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h
11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h
11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h
11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h
11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h
11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h
11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h
11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h
11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h
11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11600;SANITIZATION_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h
11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11800;SEND_MRAM_DUMP_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h

1 2200 STORE_SEND_WRITE_FAILED LOW C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
90 11207 SELF_TEST_COIL_CURRENT_FAILURE LOW Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h
91 11208 INVALID_ERROR_BYTE LOW Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC. C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h
92 11301 ERROR_STATE HIGH Reaction wheel signals an error state C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h
93 11501 SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC supervisor crc failure in telemetry packet C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
94 11502 SUPV_ACK_FAILURE LOW PLOC supervisor received acknowledgment failure report C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
95 11503 SUPV_EXE_FAILURE LOW PLOC received execution failure report C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
96 11504 SUPV_CRC_FAILURE_EVENT LOW PLOC supervisor reply has invalid crc C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
97 11700 11600 UPDATE_FILE_NOT_EXISTS SANITIZATION_FAILED LOW C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h
98 11701 11700 ACTION_COMMANDING_FAILED UPDATE_FILE_NOT_EXISTS LOW C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
99 11702 11701 UPDATE_AVAILABLE_FAILED ACTION_COMMANDING_FAILED LOW Supervisor handler replied action message indicating a command execution failure of the update available command C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
100 11703 11702 UPDATE_TRANSFER_FAILED UPDATE_AVAILABLE_FAILED LOW Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent. Supervisor handler replied action message indicating a command execution failure of the update available command C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
101 11704 11703 UPDATE_VERIFY_FAILED UPDATE_TRANSFER_FAILED LOW Supervisor failed to execute the update verify command. Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet) C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
102 11705 11704 UPDATE_FINISHED UPDATE_VERIFY_FAILED INFO LOW MPSoC update successful completed Supervisor failed to execute the update verify command. C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
103 11705 UPDATE_FINISHED INFO MPSoC update successful completed C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
104 11800 SEND_MRAM_DUMP_FAILED LOW C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
105 11801 MRAM_DUMP_FAILED LOW Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
106 11802 MRAM_DUMP_FINISHED LOW MRAM dump finished successfully C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h

View File

@ -2,10 +2,6 @@
0x43000003;CORE_CONTROLLER
0x43100002;ACS_CONTROLLER
0x43400001;THERMAL_CONTROLLER
0x44120001;RW1
0x44120002;RW2
0x44120003;RW3
0x44120004;RW4
0x44120006;MGM_0_LIS3_HANDLER
0x44120010;GYRO_0_ADIS_HANDLER
0x44120032;SUS_1
@ -21,12 +17,16 @@
0x44120042;SUS_11
0x44120043;SUS_12
0x44120044;SUS_13
0x44120047;RW1
0x44120107;MGM_1_RM3100_HANDLER
0x44120111;GYRO_1_L3G_HANDLER
0x44120148;RW2
0x44120208;MGM_2_LIS3_HANDLER
0x44120212;GYRO_2_ADIS_HANDLER
0x44120249;RW3
0x44120309;MGM_3_RM3100_HANDLER
0x44120313;GYRO_3_L3G_HANDLER
0x44120350;RW4
0x44130001;START_TRACKER
0x44130045;GPS0_HANDLER
0x44130146;GPS1_HANDLER
@ -38,6 +38,7 @@
0x44250003;ACU_HANDLER
0x443200A5;RAD_SENSOR
0x44330000;PLOC_UPDATER
0x44330001;PLOC_MEMORY_DUMPER
0x44330015;PLOC_MPSOC_HANDLER
0x44330016;PLOC_SUPERVISOR_HANDLER
0x444100A2;SOLAR_ARRAY_DEPL_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
2 0x43000003 CORE_CONTROLLER
3 0x43100002 ACS_CONTROLLER
4 0x43400001 THERMAL_CONTROLLER
0x44120001 RW1
0x44120002 RW2
0x44120003 RW3
0x44120004 RW4
5 0x44120006 MGM_0_LIS3_HANDLER
6 0x44120010 GYRO_0_ADIS_HANDLER
7 0x44120032 SUS_1
17 0x44120042 SUS_11
18 0x44120043 SUS_12
19 0x44120044 SUS_13
20 0x44120047 RW1
21 0x44120107 MGM_1_RM3100_HANDLER
22 0x44120111 GYRO_1_L3G_HANDLER
23 0x44120148 RW2
24 0x44120208 MGM_2_LIS3_HANDLER
25 0x44120212 GYRO_2_ADIS_HANDLER
26 0x44120249 RW3
27 0x44120309 MGM_3_RM3100_HANDLER
28 0x44120313 GYRO_3_L3G_HANDLER
29 0x44120350 RW4
30 0x44130001 START_TRACKER
31 0x44130045 GPS0_HANDLER
32 0x44130146 GPS1_HANDLER
38 0x44250003 ACU_HANDLER
39 0x443200A5 RAD_SENSOR
40 0x44330000 PLOC_UPDATER
41 0x44330001 PLOC_MEMORY_DUMPER
42 0x44330015 PLOC_MPSOC_HANDLER
43 0x44330016 PLOC_SUPERVISOR_HANDLER
44 0x444100A2 SOLAR_ARRAY_DEPL_HANDLER

View File

@ -51,7 +51,7 @@ SUBSYSTEM_DEFINITION_DESTINATIONS = [
]
HEADER_DEFINITION_DESTINATIONS = [
f"{OBSW_ROOT_DIR}/mission/", f"{OBSW_ROOT_DIR}/fsfw/", f"{FSFW_CONFIG_ROOT}",
f"{OBSW_ROOT_DIR}/test/"
f"{OBSW_ROOT_DIR}/test/", f"{OBSW_ROOT_DIR}/bsp_q7s"
]

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 102 translations.
* @brief Auto-generated event translation file. Contains 106 translations.
* @details
* Generated on: 2021-08-07 18:11:16
* Generated on: 2021-08-31 10:50:10
*/
#include "translateEvents.h"
@ -101,12 +101,16 @@ const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS";
const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED";
const char *UPDATE_AVAILABLE_FAILED_STRING = "UPDATE_AVAILABLE_FAILED";
const char *UPDATE_TRANSFER_FAILED_STRING = "UPDATE_TRANSFER_FAILED";
const char *UPDATE_VERIFY_FAILED_STRING = "UPDATE_VERIFY_FAILED";
const char *UPDATE_FINISHED_STRING = "UPDATE_FINISHED";
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
const char *MRAM_DUMP_FAILED_STRING = "MRAM_DUMP_FAILED";
const char *MRAM_DUMP_FINISHED_STRING = "MRAM_DUMP_FINISHED";
const char * translateEvents(Event event) {
switch( (event & 0xffff) ) {
@ -302,6 +306,8 @@ const char * translateEvents(Event event) {
return SUPV_EXE_FAILURE_STRING;
case(11504):
return SUPV_CRC_FAILURE_EVENT_STRING;
case(11600):
return SANITIZATION_FAILED_STRING;
case(11700):
return UPDATE_FILE_NOT_EXISTS_STRING;
case(11701):
@ -314,6 +320,12 @@ const char * translateEvents(Event event) {
return UPDATE_VERIFY_FAILED_STRING;
case(11705):
return UPDATE_FINISHED_STRING;
case(11800):
return SEND_MRAM_DUMP_FAILED_STRING;
case(11801):
return MRAM_DUMP_FAILED_STRING;
case(11802):
return MRAM_DUMP_FINISHED_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 104 translations.
* Generated on: 2021-08-07 18:08:35
* Contains 105 translations.
* Generated on: 2021-08-31 10:31:24
*/
#include "translateObjects.h"
@ -10,10 +10,6 @@ const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK";
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
const char *RW1_STRING = "RW1";
const char *RW2_STRING = "RW2";
const char *RW3_STRING = "RW3";
const char *RW4_STRING = "RW4";
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER";
const char *SUS_1_STRING = "SUS_1";
@ -29,12 +25,16 @@ const char *SUS_10_STRING = "SUS_10";
const char *SUS_11_STRING = "SUS_11";
const char *SUS_12_STRING = "SUS_12";
const char *SUS_13_STRING = "SUS_13";
const char *RW1_STRING = "RW1";
const char *MGM_1_RM3100_HANDLER_STRING = "MGM_1_RM3100_HANDLER";
const char *GYRO_1_L3G_HANDLER_STRING = "GYRO_1_L3G_HANDLER";
const char *RW2_STRING = "RW2";
const char *MGM_2_LIS3_HANDLER_STRING = "MGM_2_LIS3_HANDLER";
const char *GYRO_2_ADIS_HANDLER_STRING = "GYRO_2_ADIS_HANDLER";
const char *RW3_STRING = "RW3";
const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER";
const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *START_TRACKER_STRING = "START_TRACKER";
const char *GPS0_HANDLER_STRING = "GPS0_HANDLER";
const char *GPS1_HANDLER_STRING = "GPS1_HANDLER";
@ -46,6 +46,7 @@ const char *PDU2_HANDLER_STRING = "PDU2_HANDLER";
const char *ACU_HANDLER_STRING = "ACU_HANDLER";
const char *RAD_SENSOR_STRING = "RAD_SENSOR";
const char *PLOC_UPDATER_STRING = "PLOC_UPDATER";
const char *PLOC_MEMORY_DUMPER_STRING = "PLOC_MEMORY_DUMPER";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
@ -121,14 +122,6 @@ const char* translateObject(object_id_t object) {
return ACS_CONTROLLER_STRING;
case 0x43400001:
return THERMAL_CONTROLLER_STRING;
case 0x44120001:
return RW1_STRING;
case 0x44120002:
return RW2_STRING;
case 0x44120003:
return RW3_STRING;
case 0x44120004:
return RW4_STRING;
case 0x44120006:
return MGM_0_LIS3_HANDLER_STRING;
case 0x44120010:
@ -159,18 +152,26 @@ const char* translateObject(object_id_t object) {
return SUS_12_STRING;
case 0x44120044:
return SUS_13_STRING;
case 0x44120047:
return RW1_STRING;
case 0x44120107:
return MGM_1_RM3100_HANDLER_STRING;
case 0x44120111:
return GYRO_1_L3G_HANDLER_STRING;
case 0x44120148:
return RW2_STRING;
case 0x44120208:
return MGM_2_LIS3_HANDLER_STRING;
case 0x44120212:
return GYRO_2_ADIS_HANDLER_STRING;
case 0x44120249:
return RW3_STRING;
case 0x44120309:
return MGM_3_RM3100_HANDLER_STRING;
case 0x44120313:
return GYRO_3_L3G_HANDLER_STRING;
case 0x44120350:
return RW4_STRING;
case 0x44130001:
return START_TRACKER_STRING;
case 0x44130045:
@ -193,6 +194,8 @@ const char* translateObject(object_id_t object) {
return RAD_SENSOR_STRING;
case 0x44330000:
return PLOC_UPDATER_STRING;
case 0x44330001:
return PLOC_MEMORY_DUMPER_STRING;
case 0x44330015:
return PLOC_MPSOC_HANDLER_STRING;
case 0x44330016:

View File

@ -10,6 +10,9 @@
LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) {
struct gpiod_chip* chip = gpiod_chip_open_by_label("/amba_pl/gpio@42030000");
sif::debug << chip->name << std::endl;
}
LinuxLibgpioIF::~LinuxLibgpioIF() {

View File

@ -47,9 +47,9 @@ private:
* @param gpioId The GPIO ID of the GPIO to drive.
* @param logiclevel The logic level to set. O or 1.
*/
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio, unsigned int logiclevel);
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, unsigned int logiclevel);
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio);
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio);
/**
* @brief This function checks if GPIOs are already registered and whether

View File

@ -15,7 +15,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId,
sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl;
}
gpioInterface->addGpios(gpioCookie);
testCase = TestCases::LOOPBACK;
testCase = TestCases::BLINK;
}
LibgpiodTest::~LibgpiodTest() {
@ -29,7 +29,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() {
case(TestCases::READ): {
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
if (result != RETURN_OK) {
sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
<< std::endl;
return RETURN_FAILED;
}
@ -42,6 +42,38 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() {
case(TestCases::LOOPBACK): {
break;
}
case(TestCases::BLINK): {
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
<< std::endl;
return RETURN_FAILED;
}
if (gpioState == 1) {
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO low!"
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
else if (gpioState == 0) {
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO high!"
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
else {
sif::warning << "LibgpiodTest::performPeriodicAction: Invalid GPIO state" << std::endl;
}
break;
}
default:
sif::debug << "LibgpiodTest::performPeriodicAction: Invalid test case" << std::endl;
break;
}
@ -56,6 +88,9 @@ ReturnValue_t LibgpiodTest::performOneShotAction() {
case(TestCases::READ): {
break;
}
case(TestCases::BLINK): {
break;
}
case(TestCases::LOOPBACK): {
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
if(result == HasReturnvaluesIF::RETURN_OK) {

View File

@ -14,7 +14,8 @@ class LibgpiodTest: public TestTask {
public:
enum TestCases {
READ = 0,
LOOPBACK = 1
LOOPBACK = 1,
BLINK
};
TestCases testCase;

View File

@ -1,5 +1,4 @@
#include "SpiTestClass.h"
#include "OBSWConfig.h"
#include "devices/gpioIds.h"
@ -20,13 +19,12 @@
#include <sys/ioctl.h>
#include <bitset>
SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objectId),
gpioIF(gpioIF) {
if(gpioIF == nullptr) {
sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl;
}
testMode = TestModes::GYRO_L3GD20H;
testMode = TestModes::MGM_LIS3MDL;
spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data());
spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data());
}
@ -37,11 +35,11 @@ ReturnValue_t SpiTestClass::performOneShotAction() {
break;
}
case(TestModes::MGM_LIS3MDL): {
performLis3MdlTest(mgm2Lis3mdlChipSelect);
performLis3MdlTest(mgm0Lis3mdlChipSelect);
break;
}
case(TestModes::MGM_RM3100): {
performRm3100Test(mgm3Rm3100ChipSelect);
performRm3100Test(mgm1Rm3100ChipSelect);
break;
}
case(TestModes::GYRO_L3GD20H): {
@ -85,7 +83,7 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) {
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
"SpiComIF::initializeInterface: ");
"SpiComIF::initializeInterface");
if(fileHelper.getOpenResult()) {
sif::error << "SpiTestClass::performRm3100Test: File descriptor could not be opened!"
<< std::endl;
@ -115,7 +113,7 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) {
sif::info << "Cycle count Y: " << cycleCountY << std::endl;
sif::info << "Cycle count z: " << cycleCountZ << std::endl;
writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x95);
writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x96);
uint8_t tmrcReg = readRm3100Register(fileDescriptor, currentGpioId, 0x0B);
sif::info << "SpiTestClass::performRm3100Test: TMRC register value: " <<
std::hex << "0x" << static_cast<int>(tmrcReg) << std::dec << std::endl;
@ -150,10 +148,10 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) {
float fieldStrengthY = rawY * scaleFactor;
float fieldStrengthZ = rawZ * scaleFactor;
sif::info << "RM3100 measured field strenghts in microtesla:" << std::endl;
sif::info << "Field Strength X: " << fieldStrengthX << " \xC2\xB5T" << std::endl;
sif::info << "Field Strength Y: " << fieldStrengthY << " \xC2\xB5T" << std::endl;
sif::info << "Field Strength Z: " << fieldStrengthZ << " \xC2\xB5T" << std::endl;
sif::info << "RM3100 measured field strengths in microtesla:" << std::endl;
sif::info << "Field Strength X: " << fieldStrengthX << " uT" << std::endl;
sif::info << "Field Strength Y: " << fieldStrengthY << " uT" << std::endl;
sif::info << "Field Strength Z: " << fieldStrengthZ << " uT" << std::endl;
}
void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) {
@ -174,8 +172,8 @@ void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) {
else {
currentGpioId = gpioIds::MGM_2_LIS3_CS;
}
uint32_t spiSpeed = 3'900'000;
spi::SpiModes spiMode = spi::SpiModes::MODE_3;
uint32_t spiSpeed = 10'000'000;
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
#ifdef RASPBERRY_PI
std::string deviceName = "/dev/spidev0.0";
#else
@ -184,7 +182,7 @@ void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) {
int fileDescriptor = 0;
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
"SpiComIF::initializeInterface: ");
"SpiComIF::initializeInterface");
if(fileHelper.getOpenResult()) {
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
<< std::endl;
@ -208,10 +206,10 @@ void SpiTestClass::performL3gTest(uint8_t l3gId) {
/* Configure all SPI chip selects and pull them high */
acsInit();
l3gId = gyro2L3gd20ChipSelect;
l3gId = gyro1L3gd20ChipSelect;
/* Adapt accordingly */
if(l3gId != gyro1L3gd20ChipSelect and l3gId != gyro2L3gd20ChipSelect) {
if(l3gId != gyro1L3gd20ChipSelect and l3gId != gyro3L3gd20ChipSelect) {
sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl;
}
gpioId_t currentGpioId = 0;
@ -223,7 +221,7 @@ void SpiTestClass::performL3gTest(uint8_t l3gId) {
currentGpioId = gpioIds::GYRO_1_L3G_CS;
}
else {
currentGpioId = gpioIds::GYRO_2_L3G_CS;
currentGpioId = gpioIds::GYRO_3_L3G_CS;
}
uint32_t spiSpeed = 3'900'000;
spi::SpiModes spiMode = spi::SpiModes::MODE_3;
@ -235,7 +233,7 @@ void SpiTestClass::performL3gTest(uint8_t l3gId) {
int fileDescriptor = 0;
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
"SpiComIF::initializeInterface: ");
"SpiComIF::initializeInterface");
if(fileHelper.getOpenResult()) {
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
<< std::endl;
@ -300,69 +298,74 @@ void SpiTestClass::performL3gTest(uint8_t l3gId) {
void SpiTestClass::acsInit() {
GpioCookie* gpioCookie = new GpioCookie();
GpiodRegular* gpio = nullptr;
#ifdef RASPBERRY_PI
GpiodRegularByChip* gpio = nullptr;
std::string rpiGpioName = "gpiochip0";
gpio = new GpiodRegular(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3",
gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
gpio = new GpiodRegular(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100",
gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
gpio = new GpiodRegular(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS",
gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
gpio = new GpiodRegular(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G",
gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
gpio = new GpiodRegular(rpiGpioName, gyro2L3gd20ChipSelect, "GYRO_2_L3G",
gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::GYRO_2_L3G_CS, gpio);
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
gpio = new GpiodRegular(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3",
gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
gpio = new GpiodRegular(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100",
gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100",
gpio::Direction::OUT, 1);
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
#elif defined(XIPHOS_Q7S)
std::string q7sGpioName5 = "gpiochip5";
std::string q7sGpioName6 = "gpiochip6";
gpio = new GpiodRegular(q7sGpioName5, mgm0Lis3mdlChipSelect, "MGM_0_LIS3",
gpio::Direction::OUT, gpio::HIGH);
GpiodRegularByLabel* gpio = nullptr;
gpio = new GpiodRegularByLabel(q7s::GPIO_ACS_BOARD_DEFAULT_LABEL, mgm0Lis3mdlChipSelect,
"MGM_0_LIS3", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
gpio = new GpiodRegular(q7sGpioName5, mgm1Rm3100ChipSelect, "MGM_1_RM3100",
gpio::Direction::OUT, gpio::HIGH);
gpio = new GpiodRegularByLabel(q7s::GPIO_ACS_BOARD_DEFAULT_LABEL, mgm1Rm3100ChipSelect,
"MGM_1_RM3100", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
gpio = new GpiodRegular(q7sGpioName5, gyro0AdisChipSelect, "GYRO_0_ADIS",
gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
gpio = new GpiodRegular(q7sGpioName5, gyro1L3gd20ChipSelect, "GYRO_1_L3G",
gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
gpio = new GpiodRegular(q7sGpioName5, gyro2L3gd20ChipSelect, "GYRO_2_L3G",
gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_2_L3G_CS, gpio);
gpio = new GpiodRegular(q7sGpioName6, mgm2Lis3mdlChipSelect, "MGM_2_LIS3",
gpio::Direction::OUT, gpio::HIGH);
gpio = new GpiodRegularByLabel(q7s::GPIO_MGM2_LIS3_LABEL, mgm2Lis3mdlChipSelect,
"MGM_2_LIS3", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
gpio = new GpiodRegular(q7sGpioName5, mgm3Rm3100ChipSelect, "MGM_3_RM3100",
gpio::Direction::OUT, gpio::HIGH);
gpio = new GpiodRegularByLabel(q7s::GPIO_ACS_BOARD_DEFAULT_LABEL, mgm3Rm3100ChipSelect,
"MGM_3_RM3100", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
gpio = new GpiodRegularByLabel(q7s::GPIO_GYRO_ADIS_LABEL, gyro0AdisChipSelect,
"GYRO_0_ADIS", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
gpio = new GpiodRegularByLabel(q7s::GPIO_ACS_BOARD_DEFAULT_LABEL, gyro1L3gd20ChipSelect,
"GYRO_1_L3G", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
gpio = new GpiodRegularByLabel(q7s::GPIO_GYRO_ADIS_LABEL, gyro2AdisChipSelect, "GYRO_2_ADIS",
gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio);
gpio = new GpiodRegularByLabel(q7s::GPIO_ACS_BOARD_DEFAULT_LABEL, gyro3L3gd20ChipSelect,
"GYRO_3_L3G", gpio::Direction::OUT, gpio::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
// Enable pins must be pulled low for regular operations
gpio = new GpiodRegularByLabel(q7s::GPIO_FLEX_OBC1F_B0, q7s::GPIO_GYRO_0_ENABLE,
"GYRO_0_ENABLE", gpio::OUT, gpio::LOW);
gpioCookie->addGpio(gpioIds::GYRO_0_ENABLE, gpio);
gpio = new GpiodRegularByLabel(q7s::GPIO_3V3_OBC1C, q7s::GPIO_GYRO_2_ENABLE,
"GYRO_2_ENABLE", gpio::OUT, gpio::LOW);
gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
#endif
if(gpioIF != nullptr) {
if (gpioIF != nullptr) {
gpioIF->addGpios(gpioCookie);
}
}

View File

@ -1,6 +1,12 @@
#ifndef LINUX_BOARDTEST_SPITESTCLASS_H_
#define LINUX_BOARDTEST_SPITESTCLASS_H_
#include "OBSWConfig.h"
#if defined(XIPHOS_Q7S)
#include "busConf.h"
#endif
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <fsfw_hal/linux/spi/SpiCookie.h>
#include <test/testtasks/TestTask.h>
@ -39,22 +45,24 @@ private:
/* ACS board specific variables */
#ifdef RASPBERRY_PI
uint8_t mgm0Lis3mdlChipSelect = 0;
uint8_t mgm1Rm3100ChipSelect = 1;
uint8_t gyro0AdisChipSelect = 5;
uint8_t gyro1L3gd20ChipSelect = 6;
uint8_t gyro2L3gd20ChipSelect = 4;
uint8_t mgm2Lis3mdlChipSelect = 17;
uint8_t mgm3Rm3100ChipSelect = 27;
uint8_t mgm0Lis3mdlChipSelect = gpio::MGM_0_BCM_PIN;
uint8_t mgm1Rm3100ChipSelect = gpio::MGM_1_BCM_PIN;
uint8_t mgm2Lis3mdlChipSelect = gpio::MGM_2_BCM_PIN;
uint8_t mgm3Rm3100ChipSelect = gpio::MGM_3_BCM_PIN;
uint8_t gyro0AdisChipSelect = gpio::GYRO_0_BCM_PIN;
uint8_t gyro1L3gd20ChipSelect = gpio::GYRO_1_BCM_PIN;
uint8_t gyro2AdisChipSelect = gpio::GYRO_2_BCM_PIN;
uint8_t gyro3L3gd20ChipSelect = gpio::GYRO_3_BCM_PIN;
#elif defined(XIPHOS_Q7S)
uint8_t mgm0Lis3mdlChipSelect = 5;
uint8_t mgm1Rm3100ChipSelect = 17;
uint8_t gyro0AdisResetLine = 20;
uint8_t gyro0AdisChipSelect = 21;
uint8_t gyro1L3gd20ChipSelect = 10;
uint8_t gyro2L3gd20ChipSelect = 3;
uint8_t mgm2Lis3mdlChipSelect = 0;
uint8_t mgm3Rm3100ChipSelect = 23;
uint8_t mgm0Lis3mdlChipSelect = q7s::GPIO_MGM_0_LIS3_CS;
uint8_t mgm1Rm3100ChipSelect = q7s::GPIO_MGM_1_RM3100_CS;
uint8_t gyro0AdisChipSelect = q7s::GPIO_GYRO_0_ADIS_CS;
uint8_t gyro2AdisChipSelect = q7s::GPIO_GYRO_2_ADIS_CS;
uint8_t gyro1L3gd20ChipSelect = q7s::GPIO_GYRO_1_L3G_CS;
uint8_t gyro3L3gd20ChipSelect = q7s::GPIO_GYRO_3_L3G_CS;
uint8_t mgm2Lis3mdlChipSelect = q7s::GPIO_MGM_2_LIS3_CS;
uint8_t mgm3Rm3100ChipSelect = q7s::GPIO_MGM_3_RM3100_CS;
#else
uint8_t mgm0Lis3mdlChipSelect = 0;
uint8_t mgm1Rm3100ChipSelect = 0;

View File

@ -173,7 +173,7 @@ ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id,
dataset.ain3 = (*(packet + 8) << 8 | *(packet + 9));
dataset.ain4 = (*(packet + 10) << 8 | *(packet + 11));
dataset.ain5 = (*(packet + 12) << 8 | *(packet + 13));
#if OBSW_VERBOSE_LEVEL >= 1 && DEBUG_SUS
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SUS
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", Temperature: "
<< dataset.temperatureCelcius << " °C" << std::endl;
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN0: "

View File

@ -72,6 +72,12 @@ static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048;
}
#define FSFW_HAL_LINUX_SPI_WIRETAPPING 1
#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0
#define FSFW_DEV_HYPERION_GPS_CREATE_NMEA_CSV 0
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0
#define FSFW_HAL_RM3100_MGM_DEBUG 0
#define FSFW_HAL_LIS3MDL_MGM_DEBUG 0
#define FSFW_HAL_ADIS16507_GYRO_DEBUG 0
#endif /* CONFIG_FSFWCONFIG_H_ */

View File

@ -1,12 +1,12 @@
/**
* @brief This file can be used to add preprocessor define for conditional
* code inclusion exclusion or various other project constants and
* properties in one place.
* @brief This file can be used to add preprocessor define for conditional
* code inclusion exclusion or various other project constants and
* properties in one place.
*/
#ifndef FSFWCONFIG_OBSWCONFIG_H_
#define FSFWCONFIG_OBSWCONFIG_H_
#cmakedefine RASPBERRY_Pi
#cmakedefine RASPBERRY_PI
#cmakedefine XIPHOS_Q7S
#cmakedefine BEAGLEBONEBLACK
@ -20,55 +20,96 @@
/* These defines should be disabled for mission code but are useful for
debugging. */
#define OBSW_VERBOSE_LEVEL 1
#define OBSW_VERBOSE_LEVEL 1
//! Board defines
#define BOARD_TE0720 0
/*******************************************************************/
/** All of the following flags should be enabled for mission code */
/*******************************************************************/
//! Timers can mess up the code when debugging
//! TODO: Enable for mission code, disable for debug code
#define OBSW_ENABLE_TIMERS 0
//! All of this should be enabled for mission code!
#if defined XIPHOS_Q7S
#define OBSW_PRINT_MISSED_DEADLINES 1
#define OBSW_ADD_TEST_CODE 1
#define OBSW_ADD_TEST_PST 1
#define OBSW_ADD_GPS 0
#define OBSW_ADD_STAR_TRACKER 0
#define OBSW_ENABLE_TIMERS 1
#define OBSW_ADD_STAR_TRACKER 0
#define OBSW_ADD_PLOC_SUPERVISOR 0
#define OBSW_ADD_PLOC_MPSOC 0
#define OBSW_ADD_SUN_SENSORS 0
#define OBSW_ADD_ACS_BOARD 0
#define OBSW_ADD_GPS_0 0
#define OBSW_ADD_GPS_1 0
#define OBSW_ADD_RW 0
#define OBSW_ADD_RTD_DEVICES 0
#define OBSW_ADD_TMP_DEVICES 0
#define OBSW_ADD_RAD_SENSORS 0
#define OBSW_ADD_SYRLINKS 0
#define TEST_LIBGPIOD 0
#define TEST_RADIATION_SENSOR_HANDLER 0
#define TEST_SUS_HANDLER 0
#define TEST_PLOC_HANDLER 0
#define TEST_CCSDS_BRIDGE 0
#define PERFORM_PTME_TEST 0
#define ADD_PLOC_SUPERVISOR 1
#define ADD_PLOC_MPSOC 0
#elif defined RASPBERRY_PI
#define BOARD_TE0720 0
#define TE0720_HEATER_TEST 0
#define OBSW_ENABLE_TIMERS 1
#define OBSW_ADD_STAR_TRACKER 0
#define OBSW_ADD_PLOC_SUPERVISOR 0
#define OBSW_ADD_PLOC_MPSOC 0
#define OBSW_ADD_SUN_SENSORS 0
#define OBSW_ADD_ACS_BOARD 0
#define OBSW_ADD_GPS_0 0
#define OBSW_ADD_GPS_1 0
#define OBSW_ADD_RW 0
#define OBSW_ADD_RTD_DEVICES 0
#define OBSW_ADD_TMP_DEVICES 0
#define OBSW_ADD_RAD_SENSORS 0
#define OBSW_ADD_SYRLINKS 0
#define P60DOCK_DEBUG 0
#define PDU1_DEBUG 0
#define PDU2_DEBUG 0
#define ACU_DEBUG 0
#define SYRLINKS_DEBUG 0
#define IMQT_DEBUG 0
#define ADIS16507_DEBUG 1
#define L3GD20_GYRO_DEBUG 0
#define DEBUG_RAD_SENSOR 0
#define DEBUG_SUS 1
#define DEBUG_RTD 1
#define IMTQ_DEBUG 1
#define RW_DEBUG 0
#define START_TRACKER_DEBUG 0
#define PLOC_MPSOC_DEBUG 0
#define PLOC_SUPERVISOR_DEBUG 1
#endif
/*******************************************************************/
/** All of the following flags should be disabled for mission code */
/*******************************************************************/
//! /* Can be used to switch device to NORMAL mode immediately */
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1
#define OBSW_PRINT_MISSED_DEADLINES 1
// If this is enabled, all other SPI code should be disabled
#define OBSW_ADD_TEST_CODE 0
#define OBSW_ADD_SPI_TEST_CODE 0
#define OBSW_ADD_TEST_PST 0
#define OBSW_ADD_TEST_TASK 0
#define OBSW_TEST_LIBGPIOD 0
#define OBSW_TEST_RADIATION_SENSOR_HANDLER 0
#define OBSW_TEST_SUS_HANDLER 0
#define OBSW_TEST_PLOC_HANDLER 0
#define OBSW_TEST_CCSDS_BRIDGE 0
#define OBSW_TEST_CCSDS_PTME 0
#define OBSW_TEST_TE7020_HEATER 0
#define OBSW_TEST_GPIO_LABEL 0
#define OBSW_DEBUG_P60DOCK 0
#define OBSW_DEBUG_PDU1 0
#define OBSW_DEBUG_PDU2 0
#define OBSW_DEBUG_GPS 0
#define OBSW_DEBUG_ACU 0
#define OBSW_DEBUG_SYRLINKS 0
#define OBSW_DEBUG_IMQT 0
#define OBSW_DEBUG_ADIS16507 0
#define OBSW_DEBUG_RAD_SENSOR 0
#define OBSW_DEBUG_SUS 0
#define OBSW_DEBUG_RTD 0
#define OBSW_DEBUG_RW 0
#define OBSW_DEBUG_STARTRACKER 0
#define OBSW_DEBUG_PLOC_MPSOC 0
#define OBSW_DEBUG_PLOC_SUPERVISOR 0
/*******************************************************************/
/** Hardcoded */
/*******************************************************************/
// Leave at one as the BSP is linux. Used by the ADIS16507 device handler
#define OBSW_ADIS16507_LINUX_COM_IF 1
#include "OBSWVersion.h"
/* Can be used to switch device to NORMAL mode immediately */
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1
#ifdef __cplusplus
#include "objects/systemObjectList.h"

View File

@ -4,86 +4,93 @@
#include <fsfw_hal/common/gpio/GpioIF.h>
namespace gpioIds {
enum gpioId_t {
HEATER_0,
HEATER_1,
HEATER_2,
HEATER_3,
HEATER_4,
HEATER_5,
HEATER_6,
HEATER_7,
DEPLSA1,
DEPLSA2,
enum gpioId_t {
HEATER_0,
HEATER_1,
HEATER_2,
HEATER_3,
HEATER_4,
HEATER_5,
HEATER_6,
HEATER_7,
DEPLSA1,
DEPLSA2,
MGM_0_LIS3_CS,
MGM_1_RM3100_CS,
GYRO_0_ADIS_CS,
GYRO_1_L3G_CS,
GYRO_2_L3G_CS,
MGM_2_LIS3_CS,
MGM_3_RM3100_CS,
MGM_0_LIS3_CS,
MGM_1_RM3100_CS,
GYRO_0_ADIS_CS,
GYRO_1_L3G_CS,
GYRO_2_ADIS_CS,
GYRO_3_L3G_CS,
MGM_2_LIS3_CS,
MGM_3_RM3100_CS,
TEST_ID_0,
TEST_ID_1,
GNSS_0_NRESET,
GNSS_1_NRESET,
RTD_IC3,
RTD_IC4,
RTD_IC5,
RTD_IC6,
RTD_IC7,
RTD_IC8,
RTD_IC9,
RTD_IC10,
RTD_IC11,
RTD_IC12,
RTD_IC13,
RTD_IC14,
RTD_IC15,
RTD_IC16,
RTD_IC17,
RTD_IC18,
GYRO_0_ENABLE,
GYRO_2_ENABLE,
CS_SUS_1,
CS_SUS_2,
CS_SUS_3,
CS_SUS_4,
CS_SUS_5,
CS_SUS_6,
CS_SUS_7,
CS_SUS_8,
CS_SUS_9,
CS_SUS_10,
CS_SUS_11,
CS_SUS_12,
CS_SUS_13,
TEST_ID_0,
TEST_ID_1,
SPI_MUX_BIT_1,
SPI_MUX_BIT_2,
SPI_MUX_BIT_3,
SPI_MUX_BIT_4,
SPI_MUX_BIT_5,
SPI_MUX_BIT_6,
RTD_IC3,
RTD_IC4,
RTD_IC5,
RTD_IC6,
RTD_IC7,
RTD_IC8,
RTD_IC9,
RTD_IC10,
RTD_IC11,
RTD_IC12,
RTD_IC13,
RTD_IC14,
RTD_IC15,
RTD_IC16,
RTD_IC17,
RTD_IC18,
CS_RAD_SENSOR,
CS_SUS_1,
CS_SUS_2,
CS_SUS_3,
CS_SUS_4,
CS_SUS_5,
CS_SUS_6,
CS_SUS_7,
CS_SUS_8,
CS_SUS_9,
CS_SUS_10,
CS_SUS_11,
CS_SUS_12,
CS_SUS_13,
PAPB_BUSY_N,
PAPB_EMPTY,
SPI_MUX_BIT_1,
SPI_MUX_BIT_2,
SPI_MUX_BIT_3,
SPI_MUX_BIT_4,
SPI_MUX_BIT_5,
SPI_MUX_BIT_6,
EN_RW1,
EN_RW2,
EN_RW3,
EN_RW4,
CS_RAD_SENSOR,
CS_RW1,
CS_RW2,
CS_RW3,
CS_RW4,
PAPB_BUSY_N,
PAPB_EMPTY,
EN_RW_CS,
EN_RW1,
EN_RW2,
EN_RW3,
EN_RW4,
SPI_MUX
};
CS_RW1,
CS_RW2,
CS_RW3,
CS_RW4,
EN_RW_CS,
SPI_MUX
};
}

View File

@ -5,7 +5,7 @@
namespace pcduSwitches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
enum SwitcherList: uint8_t {
Q7S,
PAYLOAD_PCDU_CH1,
RW,
@ -22,7 +22,7 @@ namespace pcduSwitches {
SUS_NOMINAL,
SOLAR_CELL_EXP,
PLOC,
ACS_BORAD_SIDE_A,
ACS_BOARD_SIDE_A,
NUMBER_OF_SWITCHES
};

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 102 translations.
* @brief Auto-generated event translation file. Contains 106 translations.
* @details
* Generated on: 2021-08-07 18:11:16
* Generated on: 2021-08-31 10:50:10
*/
#include "translateEvents.h"
@ -101,12 +101,16 @@ const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS";
const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED";
const char *UPDATE_AVAILABLE_FAILED_STRING = "UPDATE_AVAILABLE_FAILED";
const char *UPDATE_TRANSFER_FAILED_STRING = "UPDATE_TRANSFER_FAILED";
const char *UPDATE_VERIFY_FAILED_STRING = "UPDATE_VERIFY_FAILED";
const char *UPDATE_FINISHED_STRING = "UPDATE_FINISHED";
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
const char *MRAM_DUMP_FAILED_STRING = "MRAM_DUMP_FAILED";
const char *MRAM_DUMP_FINISHED_STRING = "MRAM_DUMP_FINISHED";
const char * translateEvents(Event event) {
switch( (event & 0xffff) ) {
@ -302,6 +306,8 @@ const char * translateEvents(Event event) {
return SUPV_EXE_FAILURE_STRING;
case(11504):
return SUPV_CRC_FAILURE_EVENT_STRING;
case(11600):
return SANITIZATION_FAILED_STRING;
case(11700):
return UPDATE_FILE_NOT_EXISTS_STRING;
case(11701):
@ -314,6 +320,12 @@ const char * translateEvents(Event event) {
return UPDATE_VERIFY_FAILED_STRING;
case(11705):
return UPDATE_FINISHED_STRING;
case(11800):
return SEND_MRAM_DUMP_FAILED_STRING;
case(11801):
return MRAM_DUMP_FAILED_STRING;
case(11802):
return MRAM_DUMP_FINISHED_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,15 +0,0 @@
CXXSRC += $(wildcard $(CURRENTPATH)/cdatapool/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp)
INCLUDES += $(CURRENTPATH)
INCLUDES += $(CURRENTPATH)/objects
INCLUDES += $(CURRENTPATH)/ipc
INCLUDES += $(CURRENTPATH)/pollingsequence
INCLUDES += $(CURRENTPATH)/returnvalues
INCLUDES += $(CURRENTPATH)/tmtc
INCLUDES += $(CURRENTPATH)/events
INCLUDES += $(CURRENTPATH)/devices
INCLUDES += $(CURRENTPATH)/cdatapool

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 104 translations.
* Generated on: 2021-08-07 18:08:35
* Contains 105 translations.
* Generated on: 2021-08-31 10:31:24
*/
#include "translateObjects.h"
@ -10,10 +10,6 @@ const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK";
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
const char *RW1_STRING = "RW1";
const char *RW2_STRING = "RW2";
const char *RW3_STRING = "RW3";
const char *RW4_STRING = "RW4";
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER";
const char *SUS_1_STRING = "SUS_1";
@ -29,12 +25,16 @@ const char *SUS_10_STRING = "SUS_10";
const char *SUS_11_STRING = "SUS_11";
const char *SUS_12_STRING = "SUS_12";
const char *SUS_13_STRING = "SUS_13";
const char *RW1_STRING = "RW1";
const char *MGM_1_RM3100_HANDLER_STRING = "MGM_1_RM3100_HANDLER";
const char *GYRO_1_L3G_HANDLER_STRING = "GYRO_1_L3G_HANDLER";
const char *RW2_STRING = "RW2";
const char *MGM_2_LIS3_HANDLER_STRING = "MGM_2_LIS3_HANDLER";
const char *GYRO_2_ADIS_HANDLER_STRING = "GYRO_2_ADIS_HANDLER";
const char *RW3_STRING = "RW3";
const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER";
const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *START_TRACKER_STRING = "START_TRACKER";
const char *GPS0_HANDLER_STRING = "GPS0_HANDLER";
const char *GPS1_HANDLER_STRING = "GPS1_HANDLER";
@ -46,6 +46,7 @@ const char *PDU2_HANDLER_STRING = "PDU2_HANDLER";
const char *ACU_HANDLER_STRING = "ACU_HANDLER";
const char *RAD_SENSOR_STRING = "RAD_SENSOR";
const char *PLOC_UPDATER_STRING = "PLOC_UPDATER";
const char *PLOC_MEMORY_DUMPER_STRING = "PLOC_MEMORY_DUMPER";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
@ -121,14 +122,6 @@ const char* translateObject(object_id_t object) {
return ACS_CONTROLLER_STRING;
case 0x43400001:
return THERMAL_CONTROLLER_STRING;
case 0x44120001:
return RW1_STRING;
case 0x44120002:
return RW2_STRING;
case 0x44120003:
return RW3_STRING;
case 0x44120004:
return RW4_STRING;
case 0x44120006:
return MGM_0_LIS3_HANDLER_STRING;
case 0x44120010:
@ -159,18 +152,26 @@ const char* translateObject(object_id_t object) {
return SUS_12_STRING;
case 0x44120044:
return SUS_13_STRING;
case 0x44120047:
return RW1_STRING;
case 0x44120107:
return MGM_1_RM3100_HANDLER_STRING;
case 0x44120111:
return GYRO_1_L3G_HANDLER_STRING;
case 0x44120148:
return RW2_STRING;
case 0x44120208:
return MGM_2_LIS3_HANDLER_STRING;
case 0x44120212:
return GYRO_2_ADIS_HANDLER_STRING;
case 0x44120249:
return RW3_STRING;
case 0x44120309:
return MGM_3_RM3100_HANDLER_STRING;
case 0x44120313:
return GYRO_3_L3G_HANDLER_STRING;
case 0x44120350:
return RW4_STRING;
case 0x44130001:
return START_TRACKER_STRING;
case 0x44130045:
@ -193,6 +194,8 @@ const char* translateObject(object_id_t object) {
return RAD_SENSOR_STRING;
case 0x44330000:
return PLOC_UPDATER_STRING;
case 0x44330001:
return PLOC_MEMORY_DUMPER_STRING;
case 0x44330015:
return PLOC_MPSOC_HANDLER_STRING;
case 0x44330016:

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ ReturnValue_t pstI2c(FixedTimeslotTaskIF* thisSequence);
*/
ReturnValue_t pstTest(FixedTimeslotTaskIF* thisSequence);
#if TE0720 == 1
#if BOARD_TE0720 == 1
/**
* @brief This polling sequence will be created when the software is compiled for the TE0720.
*/

View File

@ -39,7 +39,7 @@ ReturnValue_t CCSDSIPCoreBridge::initialize() {
ReturnValue_t CCSDSIPCoreBridge::handleTm() {
#if PERFORM_PTME_TEST == 1
#if OBSW_TEST_CCSDS_PTME == 1
return sendTestFrame();
#else
return TmTcBridge::handleTm();

View File

@ -36,22 +36,22 @@ void ObjectFactory::produceGenericObjects() {
{
PoolManager::LocalPoolConfig poolCfg = {
{100, 16}, {50, 32}, {25, 64}, {15, 128}, {10, 1024}, {5, 2048}
{300, 16}, {300, 32}, {200, 64}, {200, 128}, {100, 1024}, {10, 2048}
};
new PoolManager(objects::TC_STORE, poolCfg);
}
{
PoolManager::LocalPoolConfig poolCfg = {
{100, 16}, {50, 32}, {25, 64}, {15, 128}, {10, 1024}, {5, 2048}
{300, 16}, {300, 32}, {100, 64}, {100, 128}, {100, 1024}, {10, 2048}
};
new PoolManager(objects::TM_STORE, poolCfg);
}
{
PoolManager::LocalPoolConfig poolCfg = {
{ 100, 16 }, { 100, 32 }, { 100, 64 },
{ 100, 128 }, { 50, 256 }, { 50, 512 }, { 50, 1024 }, { 10, 2048 }
{ 300, 16 }, { 200, 32 }, { 150, 64 },
{ 150, 128 }, { 100, 256 }, { 50, 512 }, { 50, 1024 }, { 10, 2048 }
};
new PoolManager(objects::IPC_STORE, poolCfg);
}

View File

@ -21,7 +21,7 @@ void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pack
parseHkTableReply(packet);
handleDeviceTM(&acuHkTableDataset, id, true);
#if OBSW_ENHANCED_PRINTOUT == 1 && ACU_DEBUG == 1
#if OBSW_ENHANCED_PRINTOUT == 1 && OBSW_DEBUG_ACU == 1
acuHkTableDataset.read();
float temperatureC_1 = acuHkTableDataset.temperature1.value * 0.1;
float temperatureC_2 = acuHkTableDataset.temperature2.value * 0.1;

View File

@ -1,7 +1,5 @@
target_sources(${TARGET_NAME} PUBLIC
GPSHyperionHandler.cpp
MGMHandlerLIS3MDL.cpp
MGMHandlerRM3100.cpp
GomspaceDeviceHandler.cpp
Tmp1075Handler.cpp
PCDUHandler.cpp

View File

@ -6,9 +6,15 @@
#include "lwgps/lwgps.h"
#if FSFW_DEV_HYPERION_GPS_CREATE_NMEA_CSV == 1
#include <filesystem>
#include <fstream>
#endif
GPSHyperionHandler::GPSHyperionHandler(object_id_t objectId, object_id_t deviceCommunication,
CookieIF *comCookie):
DeviceHandlerBase(objectId, deviceCommunication, comCookie), gpsSet(this) {
CookieIF *comCookie, bool debugHyperionGps):
DeviceHandlerBase(objectId, deviceCommunication, comCookie), gpsSet(this),
debugHyperionGps(debugHyperionGps) {
lwgps_init(&gpsData);
}
@ -32,30 +38,44 @@ void GPSHyperionHandler::doStartUp() {
void GPSHyperionHandler::doShutDown() {
internalState = InternalStates::NONE;
commandExecuted = false;
setMode(MODE_OFF);
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t GPSHyperionHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
return HasReturnvaluesIF::RETURN_OK;
return NOTHING_TO_SEND;
}
ReturnValue_t GPSHyperionHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
return HasReturnvaluesIF::RETURN_OK;
return NOTHING_TO_SEND;
}
ReturnValue_t GPSHyperionHandler::buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) {
return HasReturnvaluesIF::RETURN_OK;
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) {
// By default, send nothing
rawPacketLen = 0;
switch(deviceCommand) {
case(GpsHyperion::TRIGGER_RESET_PIN): {
if(resetCallback != nullptr) {
PoolReadGuard pg(&gpsSet);
// Set HK entries invalid
gpsSet.setValidity(false, true);
resetCallback(resetCallbackArgs);
return HasActionsIF::EXECUTION_FINISHED;
}
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GPSHyperionHandler::scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) {
DeviceCommandId_t *foundId, size_t *foundLen) {
// Pass data to GPS library
if(len > 0) {
sif::info << "GPSHandler::scanForReply: Received " << len << " bytes" << std::endl;
// sif::debug << "GPSHandler::scanForReply: Received " << len << " bytes" << std::endl;
if (internalState == InternalStates::WAIT_FIRST_MESSAGE) {
// TODO: Check whether data is valid by chcking whether NMEA start string is valid
// TODO: Check whether data is valid by checking whether NMEA start string is valid?
commandExecuted = true;
}
int result = lwgps_process(&gpsData, start, len);
@ -81,7 +101,14 @@ ReturnValue_t GPSHyperionHandler::scanForReply(const uint8_t *start, size_t len,
// Negative latitude -> South direction
gpsSet.latitude.value = gpsData.latitude;
// Negative longitude -> West direction
gpsSet.longitude.value = gpsData.latitude;
gpsSet.longitude.value = gpsData.longitude;
if(gpsData.altitude > 600000.0 or gpsData.altitude < 400000.0) {
gpsSet.altitude.setValid(false);
}
else {
gpsSet.altitude.setValid(true);
gpsSet.altitude.value = gpsData.altitude;
}
gpsSet.fixMode.value = gpsData.fix_mode;
gpsSet.satInUse.value = gpsData.sats_in_use;
Clock::TimeOfDay_t timeStruct = {};
@ -100,31 +127,43 @@ ReturnValue_t GPSHyperionHandler::scanForReply(const uint8_t *start, size_t len,
gpsSet.hours = gpsData.hours;
gpsSet.minutes = gpsData.minutes;
gpsSet.seconds = gpsData.seconds;
#if FSFW_HAL_DEBUG_HYPERION_GPS == 1
sif::info << "GPS Data" << std::endl;
printf("Valid status: %d\n", gpsData.is_valid);
printf("Latitude: %f degrees\n", gpsData.latitude);
printf("Longitude: %f degrees\n", gpsData.longitude);
printf("Altitude: %f meters\n", gpsData.altitude);
gpsSet.unixSeconds = timeval.tv_sec;
if(debugHyperionGps) {
sif::info << "GPS Data" << std::endl;
printf("Valid status: %d\n", gpsData.is_valid);
printf("Latitude: %f degrees\n", gpsData.latitude);
printf("Longitude: %f degrees\n", gpsData.longitude);
printf("Altitude: %f meters\n", gpsData.altitude);
}
#if FSFW_DEV_HYPERION_GPS_CREATE_NMEA_CSV == 1
std::string filename = "/mnt/sd0/gps_log.txt";
std::ofstream gpsFile;
if(not std::filesystem::exists(filename)) {
gpsFile.open(filename, std::ofstream::out);
}
gpsFile.open(filename, std::ofstream::out | std::ofstream::app);
gpsFile.write("\n", 1);
gpsFile.write(reinterpret_cast<const char*>(start), len);
#endif
}
*foundLen = len;
*foundId = GpsHyperion::GPS_REPLY;
}
return HasReturnvaluesIF::RETURN_OK;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GPSHyperionHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) {
return HasReturnvaluesIF::RETURN_OK;
const uint8_t *packet) {
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t GPSHyperionHandler::getTransitionDelayMs(Mode_t from, Mode_t to) {
return 5000;
return 5000;
}
ReturnValue_t GPSHyperionHandler::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(GpsHyperion::ALTITUDE, new PoolEntry<double>({0.0}));
localDataPoolMap.emplace(GpsHyperion::LONGITUDE, new PoolEntry<double>({0.0}));
localDataPoolMap.emplace(GpsHyperion::LATITUDE, new PoolEntry<double>({0.0}));
@ -137,14 +176,39 @@ ReturnValue_t GPSHyperionHandler::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::UNIX_SECONDS, new PoolEntry<uint32_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
return HasReturnvaluesIF::RETURN_OK;
poolManager.subscribeForPeriodicPacket(gpsSet.getSid(), true, 2.0, false);
return HasReturnvaluesIF::RETURN_OK;
}
void GPSHyperionHandler::fillCommandAndReplyMap() {
// Reply length does not matter, packets should always arrive periodically
insertInReplyMap(GpsHyperion::GPS_REPLY, 4, nullptr, 0, true);
insertInReplyMap(GpsHyperion::GPS_REPLY, 4, &gpsSet, 0, true);
insertInCommandMap(GpsHyperion::TRIGGER_RESET_PIN);
}
void GPSHyperionHandler::modeChanged() {
internalState = InternalStates::NONE;
}
void GPSHyperionHandler::setResetPinTriggerFunction(gpioResetFunction_t resetCallback,
void *args) {
this->resetCallback = resetCallback;
resetCallbackArgs = args;
}
void GPSHyperionHandler::debugInterface(uint8_t positionTracker, object_id_t objectId,
uint32_t parameter) {
}
ReturnValue_t GPSHyperionHandler::initialize() {
ReturnValue_t result = DeviceHandlerBase::initialize();
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
// Enable reply immediately for now
return updatePeriodicReply(true, GpsHyperion::GPS_REPLY);
}
ReturnValue_t GPSHyperionHandler::acceptExternalDeviceCommands() {
return DeviceHandlerBase::acceptExternalDeviceCommands();
}

View File

@ -1,14 +1,11 @@
#ifndef MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#include "fsfw/FSFW.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "devicedefinitions/GPSDefinitions.h"
#include "lwgps/lwgps.h"
#ifndef FSFW_HAL_DEBUG_HYPERION_GPS
#define FSFW_HAL_DEBUG_HYPERION_GPS 0
#endif
/**
* @brief Device handler for the Hyperion HT-GPS200 device
* @details
@ -17,11 +14,22 @@
*/
class GPSHyperionHandler: public DeviceHandlerBase {
public:
GPSHyperionHandler(object_id_t objectId, object_id_t deviceCommunication,
CookieIF* comCookie);
CookieIF* comCookie, bool debugHyperionGps = false);
virtual ~GPSHyperionHandler();
using gpioResetFunction_t = ReturnValue_t (*) (void* args);
void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void*args);
ReturnValue_t acceptExternalDeviceCommands() override;
ReturnValue_t initialize() override;
protected:
gpioResetFunction_t resetCallback = nullptr;
void* resetCallbackArgs = nullptr;
enum class InternalStates {
NONE,
WAIT_FIRST_MESSAGE,
@ -50,10 +58,12 @@ protected:
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
virtual void debugInterface(uint8_t positionTracker = 0,
object_id_t objectId = 0, uint32_t parameter = 0) override;
private:
lwgps_t gpsData = {};
GpsPrimaryDataset gpsSet;
bool debugHyperionGps = false;
};
#endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */

View File

@ -7,11 +7,11 @@ GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t c
DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(maxConfigTableAddress),
maxHkTableAddress(maxHkTableAddress), hkTableReplySize(hkTableReplySize),
hkTableDataset(hkTableDataset) {
if (comCookie == NULL) {
if (comCookie == nullptr) {
sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie"
<< std::endl;
}
if (hkTableDataset == NULL) {
if (hkTableDataset == nullptr) {
sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid hk table data set"
<< std::endl;
}
@ -75,6 +75,10 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(
}
break;
}
case(GOMSPACE::PRINT_SWITCH_V_I): {
result = printStatus(deviceCommand);
break;
}
case(GOMSPACE::REQUEST_HK_TABLE): {
result = generateRequestFullHkTableCmd(hkTableReplySize);
if(result != HasReturnvaluesIF::RETURN_OK){
@ -95,6 +99,7 @@ void GomspaceDeviceHandler::fillCommandAndReplyMap(){
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3);
this->insertInCommandMap(GOMSPACE::GNDWDT_RESET);
this->insertInCommandMap(GOMSPACE::PRINT_SWITCH_V_I);
}
ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t *start,
@ -396,3 +401,8 @@ LocalPoolDataSetBase* GomspaceDeviceHandler::getDataSetHandle(sid_t sid) {
void GomspaceDeviceHandler::setModeNormal() {
mode = MODE_NORMAL;
}
ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) {
sif::info << "No printHkTable implementation given.." << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -88,6 +88,13 @@ protected:
*/
virtual ReturnValue_t generateRequestFullHkTableCmd(uint16_t hkTableSize);
/**
* This command handles printing the HK table to the console. This is useful for debugging
* purposes
* @return
*/
virtual ReturnValue_t printStatus(DeviceCommandId_t cmd);
/**
* @brief Because housekeeping tables are device specific the handling of the reply is
* given to the child class.

View File

@ -1,8 +1,7 @@
#include "GyroADIS16507Handler.h"
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include "GyroADIS16507Handler.h"
#if OBSW_ADIS16507_LINUX_COM_IF == 1
#include "fsfw_hal/linux/utility.h"
#include "fsfw_hal/linux/spi/SpiCookie.h"
@ -16,7 +15,7 @@ GyroADIS16507Handler::GyroADIS16507Handler(object_id_t objectId,
object_id_t deviceCommunication, CookieIF * comCookie):
DeviceHandlerBase(objectId, deviceCommunication, comCookie), primaryDataset(this),
configDataset(this), breakCountdown() {
#if ADIS16507_DEBUG == 1
#if FSFW_HAL_ADIS16507_GYRO_DEBUG == 1
debugDivider = new PeriodicOperationDivider(5);
#endif
@ -57,6 +56,7 @@ void GyroADIS16507Handler::doStartUp() {
void GyroADIS16507Handler::doShutDown() {
commandExecuted = false;
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t GyroADIS16507Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
@ -72,6 +72,7 @@ ReturnValue_t GyroADIS16507Handler::buildTransitionDeviceCommand(DeviceCommandId
break;
}
case(InternalState::STARTUP): {
return NOTHING_TO_SEND;
break;
}
default: {
@ -199,7 +200,7 @@ ReturnValue_t GyroADIS16507Handler::interpretDeviceReply(DeviceCommandId_t id,
uint16_t readProdId = packet[10] << 8 | packet[11];
if (readProdId != ADIS16507::PROD_ID) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::debug << "GyroADIS16507Handler::interpretDeviceReply: Invalid product ID!"
sif::warning << "GyroADIS16507Handler::interpretDeviceReply: Invalid product ID!"
<< std::endl;
#endif
return HasReturnvaluesIF::RETURN_FAILED;
@ -283,7 +284,7 @@ ReturnValue_t GyroADIS16507Handler::handleSensorData(const uint8_t *packet) {
primaryDataset.setValidity(true, true);
}
#if ADIS16507_DEBUG == 1
#if FSFW_HAL_ADIS16507_GYRO_DEBUG == 1
if(debugDivider->checkAndIncrement()) {
sif::info << "GyroADIS16507Handler: Angular velocities in deg / s" << std::endl;
sif::info << "X: " << primaryDataset.angVelocX.value << std::endl;
@ -392,7 +393,7 @@ ReturnValue_t GyroADIS16507Handler::spiSendCallback(SpiComIF *comIf, SpiCookie *
// Prepare transfer
int fileDescriptor = 0;
std::string device = cookie->getSpiDevice();
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage: ");
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
return SpiComIF::OPENING_FILE_FAILED;
}
@ -401,7 +402,7 @@ ReturnValue_t GyroADIS16507Handler::spiSendCallback(SpiComIF *comIf, SpiCookie *
cookie->getSpiParameters(spiMode, spiSpeed, nullptr);
comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
cookie->assignWriteBuffer(sendData);
cookie->assignTransferSize(2);
cookie->setTransferSize(2);
gpioId_t gpioId = cookie->getChipSelectPin();
GpioIF* gpioIF = comIf->getGpioInterface();

View File

@ -1,11 +1,13 @@
#ifndef MISSION_DEVICES_GYROADIS16507HANDLER_H_
#define MISSION_DEVICES_GYROADIS16507HANDLER_H_
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include "OBSWConfig.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "FSFWConfig.h"
#include "devicedefinitions/GyroADIS16507Definitions.h"
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#if OBSW_ADIS16507_LINUX_COM_IF == 1
class SpiComIF;
class SpiCookie;
@ -69,7 +71,7 @@ private:
const uint8_t *sendData, size_t sendLen, void* args);
#endif
#if ADIS16507_DEBUG == 1
#if FSFW_HAL_ADIS16507_GYRO_DEBUG == 1
PeriodicOperationDivider* debugDivider;
#endif
Countdown breakCountdown;

View File

@ -27,7 +27,7 @@ void IMTQHandler::doStartUp() {
}
void IMTQHandler::doShutDown() {
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t IMTQHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) {
@ -683,7 +683,7 @@ void IMTQHandler::fillEngHkDataset(const uint8_t* packet) {
offset += 2;
engHkDataset.mcuTemperature = (*(packet + offset + 1) << 8 | *(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ digital voltage: " << engHkDataset.digitalVoltageMv << " mV" << std::endl;
sif::info << "IMTQ analog voltage: " << engHkDataset.analogVoltageMv << " mV" << std::endl;
sif::info << "IMTQ digital current: " << engHkDataset.digitalCurrentmA << " mA" << std::endl;
@ -757,7 +757,7 @@ void IMTQHandler::fillCalibratedMtmDataset(const uint8_t* packet) {
offset += 4;
calMtmMeasurementSet.coilActuationStatus = (*(packet + offset + 3) << 24)
| (*(packet + offset + 2) << 16) | (*(packet + offset + 1) << 8) | (*(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ calibrated MTM measurement X: " << calMtmMeasurementSet.mtmXnT << " nT"
<< std::endl;
sif::info << "IMTQ calibrated MTM measurement Y: " << calMtmMeasurementSet.mtmYnT << " nT"
@ -783,7 +783,7 @@ void IMTQHandler::fillRawMtmDataset(const uint8_t* packet) {
offset += 4;
rawMtmMeasurementSet.coilActuationStatus = (*(packet + offset + 3) << 24)
| (*(packet + offset + 2) << 16) | (*(packet + offset + 1) << 8) | (*(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ raw MTM measurement X: " << rawMtmMeasurementSet.mtmXnT << " nT"
<< std::endl;
sif::info << "IMTQ raw MTM measurement Y: " << rawMtmMeasurementSet.mtmYnT << " nT"
@ -946,7 +946,7 @@ void IMTQHandler::handlePositiveXSelfTestReply(const uint8_t* packet) {
posXselfTestDataset.finaCoilZTemperature = *(packet + offset + 1) << 8 | *(packet + offset);
offset += 4;
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ self test (INIT) err: "
<< static_cast<unsigned int>(posXselfTestDataset.initErr.value) << std::endl;
sif::info << "IMTQ self test (INIT) raw magnetic field X: " << posXselfTestDataset.initRawMagX
@ -1147,7 +1147,7 @@ void IMTQHandler::handleNegativeXSelfTestReply(const uint8_t* packet) {
negXselfTestDataset.finaCoilZTemperature = *(packet + offset + 1) << 8 | *(packet + offset);
offset += 4;
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ self test (INIT) err: "
<< static_cast<unsigned int>(negXselfTestDataset.initErr.value) << std::endl;
sif::info << "IMTQ self test (INIT) raw magnetic field X: " << negXselfTestDataset.initRawMagX
@ -1348,7 +1348,7 @@ void IMTQHandler::handlePositiveYSelfTestReply(const uint8_t* packet) {
posYselfTestDataset.finaCoilZTemperature = *(packet + offset + 1) << 8 | *(packet + offset);
offset += 4;
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ self test (INIT) err: "
<< static_cast<unsigned int>(posYselfTestDataset.initErr.value) << std::endl;
sif::info << "IMTQ self test (INIT) raw magnetic field X: " << posYselfTestDataset.initRawMagX
@ -1549,7 +1549,7 @@ void IMTQHandler::handleNegativeYSelfTestReply(const uint8_t* packet) {
negYselfTestDataset.finaCoilZTemperature = *(packet + offset + 1) << 8 | *(packet + offset);
offset += 4;
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ self test (INIT) err: "
<< static_cast<unsigned int>(negYselfTestDataset.initErr.value) << std::endl;
sif::info << "IMTQ self test (INIT) raw magnetic field X: " << negYselfTestDataset.initRawMagX
@ -1750,7 +1750,7 @@ void IMTQHandler::handlePositiveZSelfTestReply(const uint8_t* packet) {
posZselfTestDataset.finaCoilZTemperature = *(packet + offset + 1) << 8 | *(packet + offset);
offset += 4;
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ self test (INIT) err: "
<< static_cast<unsigned int>(posZselfTestDataset.initErr.value) << std::endl;
sif::info << "IMTQ self test (INIT) raw magnetic field X: " << posZselfTestDataset.initRawMagX
@ -1951,7 +1951,7 @@ void IMTQHandler::handleNegativeZSelfTestReply(const uint8_t* packet) {
negZselfTestDataset.finaCoilZTemperature = *(packet + offset + 1) << 8 | *(packet + offset);
offset += 4;
#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_IMTQ == 1
sif::info << "IMTQ self test (INIT) err: "
<< static_cast<unsigned int>(negZselfTestDataset.initErr.value) << std::endl;
sif::info << "IMTQ self test (INIT) raw magnetic field X: " << negZselfTestDataset.initRawMagX

View File

@ -1,486 +0,0 @@
#include "MGMHandlerLIS3MDL.h"
#include "fsfw/datapool/PoolReadGuard.h"
#if OBSW_VERBOSE_LEVEL >= 1
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
#endif
MGMHandlerLIS3MDL::MGMHandlerLIS3MDL(object_id_t objectId,
object_id_t deviceCommunication, CookieIF* comCookie):
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
dataset(this) {
#if OBSW_VERBOSE_LEVEL >= 1
debugDivider = new PeriodicOperationDivider(5);
#endif
/* Set to default values right away. */
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
}
MGMHandlerLIS3MDL::~MGMHandlerLIS3MDL() {
}
void MGMHandlerLIS3MDL::doStartUp() {
switch (internalState) {
case(InternalState::STATE_NONE): {
internalState = InternalState::STATE_FIRST_CONTACT;
break;
}
case(InternalState::STATE_FIRST_CONTACT): {
/* Will be set by checking device ID (WHO AM I register) */
if(commandExecuted) {
commandExecuted = false;
internalState = InternalState::STATE_SETUP;
}
break;
}
case(InternalState::STATE_SETUP): {
internalState = InternalState::STATE_CHECK_REGISTERS;
break;
}
case(InternalState::STATE_CHECK_REGISTERS): {
/* Set up cached registers which will be used to configure the MGM. */
if(commandExecuted) {
commandExecuted = false;
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
setMode(MODE_NORMAL);
#else
setMode(_MODE_TO_ON);
#endif
}
break;
}
default:
break;
}
}
void MGMHandlerLIS3MDL::doShutDown() {
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t MGMHandlerLIS3MDL::buildTransitionDeviceCommand(
DeviceCommandId_t *id) {
switch (internalState) {
case(InternalState::STATE_NONE):
case(InternalState::STATE_NORMAL): {
return HasReturnvaluesIF::RETURN_OK;
}
case(InternalState::STATE_FIRST_CONTACT): {
*id = MGMLIS3MDL::IDENTIFY_DEVICE;
break;
}
case(InternalState::STATE_SETUP): {
*id = MGMLIS3MDL::SETUP_MGM;
break;
}
case(InternalState::STATE_CHECK_REGISTERS): {
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
break;
}
default: {
/* might be a configuration error. */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" <<
std::endl;
#else
sif::printWarning("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
return HasReturnvaluesIF::RETURN_OK;
}
}
return buildCommandFromCommand(*id, NULL, 0);
}
uint8_t MGMHandlerLIS3MDL::readCommand(uint8_t command, bool continuousCom) {
command |= (1 << MGMLIS3MDL::RW_BIT);
if (continuousCom == true) {
command |= (1 << MGMLIS3MDL::MS_BIT);
}
return command;
}
uint8_t MGMHandlerLIS3MDL::writeCommand(uint8_t command, bool continuousCom) {
command &= ~(1 << MGMLIS3MDL::RW_BIT);
if (continuousCom == true) {
command |= (1 << MGMLIS3MDL::MS_BIT);
}
return command;
}
void MGMHandlerLIS3MDL::setupMgm() {
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
prepareCtrlRegisterWrite();
}
ReturnValue_t MGMHandlerLIS3MDL::buildNormalDeviceCommand(
DeviceCommandId_t *id) {
// Data/config register will be read in an alternating manner.
if(communicationStep == CommunicationStep::DATA) {
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
communicationStep = CommunicationStep::TEMPERATURE;
return buildCommandFromCommand(*id, NULL, 0);
}
else {
*id = MGMLIS3MDL::READ_TEMPERATURE;
communicationStep = CommunicationStep::DATA;
return buildCommandFromCommand(*id, NULL, 0);
}
}
ReturnValue_t MGMHandlerLIS3MDL::buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) {
switch(deviceCommand) {
case(MGMLIS3MDL::READ_CONFIG_AND_DATA): {
std::memset(commandBuffer, 0, sizeof(commandBuffer));
commandBuffer[0] = readCommand(MGMLIS3MDL::CTRL_REG1, true);
rawPacket = commandBuffer;
rawPacketLen = MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1;
return RETURN_OK;
}
case(MGMLIS3MDL::READ_TEMPERATURE): {
std::memset(commandBuffer, 0, 3);
commandBuffer[0] = readCommand(MGMLIS3MDL::TEMP_LOWBYTE, true);
rawPacket = commandBuffer;
rawPacketLen = 3;
return RETURN_OK;
}
case(MGMLIS3MDL::IDENTIFY_DEVICE): {
return identifyDevice();
}
case(MGMLIS3MDL::TEMP_SENSOR_ENABLE): {
return enableTemperatureSensor(commandData, commandDataLen);
}
case(MGMLIS3MDL::SETUP_MGM): {
setupMgm();
return HasReturnvaluesIF::RETURN_OK;
}
case(MGMLIS3MDL::ACCURACY_OP_MODE_SET): {
return setOperatingMode(commandData, commandDataLen);
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t MGMHandlerLIS3MDL::identifyDevice() {
uint32_t size = 2;
commandBuffer[0] = readCommand(MGMLIS3MDL::IDENTIFY_DEVICE_REG_ADDR);
commandBuffer[1] = 0x00;
rawPacket = commandBuffer;
rawPacketLen = size;
return RETURN_OK;
}
ReturnValue_t MGMHandlerLIS3MDL::scanForReply(const uint8_t *start,
size_t len, DeviceCommandId_t *foundId, size_t *foundLen) {
*foundLen = len;
if (len == MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1) {
*foundLen = len;
*foundId = MGMLIS3MDL::READ_CONFIG_AND_DATA;
// Check validity by checking config registers
if (start[1] != registers[0] or start[2] != registers[1] or
start[3] != registers[2] or start[4] != registers[3] or
start[5] != registers[4]) {
#if OBSW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl;
#else
sif::printWarning("MGMHandlerLIS3MDL::scanForReply: Invalid registers!\n");
#endif
#endif
return DeviceHandlerIF::INVALID_DATA;
}
if(mode == _MODE_START_UP) {
commandExecuted = true;
}
}
else if(len == MGMLIS3MDL::TEMPERATURE_REPLY_LEN) {
*foundLen = len;
*foundId = MGMLIS3MDL::READ_TEMPERATURE;
}
else if (len == MGMLIS3MDL::SETUP_REPLY_LEN) {
*foundLen = len;
*foundId = MGMLIS3MDL::SETUP_MGM;
}
else if (len == SINGLE_COMMAND_ANSWER_LEN) {
*foundLen = len;
*foundId = getPendingCommand();
if(*foundId == MGMLIS3MDL::IDENTIFY_DEVICE) {
if(start[1] != MGMLIS3MDL::DEVICE_ID) {
#if OBSW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl;
#else
sif::printWarning("MGMHandlerLIS3MDL::scanForReply: Invalid registers!\n");
#endif
#endif
return DeviceHandlerIF::INVALID_DATA;
}
if(mode == _MODE_START_UP) {
commandExecuted = true;
}
}
}
else {
return DeviceHandlerIF::INVALID_DATA;
}
/* Data with SPI Interface always has this answer */
if (start[0] == 0b11111111) {
return RETURN_OK;
}
else {
return DeviceHandlerIF::INVALID_DATA;
}
}
ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) {
switch (id) {
case MGMLIS3MDL::IDENTIFY_DEVICE: {
break;
}
case MGMLIS3MDL::SETUP_MGM: {
break;
}
case MGMLIS3MDL::READ_CONFIG_AND_DATA: {
// TODO: Store configuration in new local datasets.
uint8_t scale = getFullScale(registers[2]);
float sensitivityFactor = getSensitivityFactor(scale);
int16_t mgmMeasurementRawX = packet[MGMLIS3MDL::X_HIGHBYTE_IDX] << 8
| packet[MGMLIS3MDL::X_LOWBYTE_IDX] ;
int16_t mgmMeasurementRawY = packet[MGMLIS3MDL::Y_HIGHBYTE_IDX] << 8
| packet[MGMLIS3MDL::Y_LOWBYTE_IDX] ;
int16_t mgmMeasurementRawZ = packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8
| packet[MGMLIS3MDL::Z_LOWBYTE_IDX] ;
/* Target value in microtesla */
float mgmX = static_cast<float>(mgmMeasurementRawX) * sensitivityFactor
* MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
float mgmY = static_cast<float>(mgmMeasurementRawY) * sensitivityFactor
* MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
float mgmZ = static_cast<float>(mgmMeasurementRawZ) * sensitivityFactor
* MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
#if OBSW_VERBOSE_LEVEL >= 1
if(debugDivider->checkAndIncrement()) {
/* Set terminal to utf-8 if there is an issue with micro printout. */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "MGMHandlerLIS3: Magnetic field strength in"
" microtesla:" << std::endl;
sif::info << "X: " << mgmX << " \xC2\xB5T" << std::endl;
sif::info << "Y: " << mgmY << " \xC2\xB5T" << std::endl;
sif::info << "Z: " << mgmZ << " \xC2\xB5T" << std::endl;
#else
sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n");
sif::printInfo("X: %f " "\xC2\xB5" "T\n", mgmX);
sif::printInfo("Y: %f " "\xC2\xB5" "T\n", mgmY);
sif::printInfo("Z: %f " "\xC2\xB5" "T\n", mgmZ);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */
}
#endif /* OBSW_VERBOSE_LEVEL >= 1 */
PoolReadGuard readHelper(&dataset);
if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
dataset.fieldStrengthX = mgmX;
dataset.fieldStrengthY = mgmY;
dataset.fieldStrengthZ = mgmZ;
dataset.setValidity(true, true);
}
break;
}
case MGMLIS3MDL::READ_TEMPERATURE: {
int16_t tempValueRaw = packet[2] << 8 | packet[1];
float tempValue = 25.0 + ((static_cast<float>(tempValueRaw)) / 8.0);
#if OBSW_VERBOSE_LEVEL >= 1
if(debugDivider->check()) {
/* Set terminal to utf-8 if there is an issue with micro printout. */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " \xC2\xB0" << "C" <<
std::endl;
#else
sif::printInfo("MGMHandlerLIS3: Temperature: %f" "\xC2\xB0" "C\n");
#endif
}
#endif
ReturnValue_t result = dataset.read();
if(result == HasReturnvaluesIF::RETURN_OK) {
dataset.temperature = tempValue;
dataset.commit();
}
break;
}
default: {
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
}
return RETURN_OK;
}
uint8_t MGMHandlerLIS3MDL::getFullScale(uint8_t ctrlRegister2) {
bool FS0 = false;
bool FS1 = false;
if ((ctrlRegister2 >> 5) == 1)
FS0 = true;
if ((ctrlRegister2 >> 6) == 1)
FS1 = true;
if ((FS0 == true) && (FS1 == true))
return 16;
else if ((FS0 == false) && (FS1 == true))
return 12;
else if ((FS0 == true) && (FS1 == false))
return 8;
else
return 4;
}
float MGMHandlerLIS3MDL::getSensitivityFactor(uint8_t scale) {
return (float) scale / (INT16_MAX);
}
ReturnValue_t MGMHandlerLIS3MDL::enableTemperatureSensor(
const uint8_t *commandData, size_t commandDataLen) {
triggerEvent(CHANGE_OF_SETUP_PARAMETER);
uint32_t size = 2;
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1);
if (commandDataLen > 1) {
return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
}
switch (*commandData) {
case (MGMLIS3MDL::ON): {
commandBuffer[1] = registers[0] | (1 << 7);
break;
}
case (MGMLIS3MDL::OFF): {
commandBuffer[1] = registers[0] & ~(1 << 7);
break;
}
default:
return INVALID_COMMAND_PARAMETER;
}
registers[0] = commandBuffer[1];
rawPacket = commandBuffer;
rawPacketLen = size;
return RETURN_OK;
}
ReturnValue_t MGMHandlerLIS3MDL::setOperatingMode(const uint8_t *commandData,
size_t commandDataLen) {
triggerEvent(CHANGE_OF_SETUP_PARAMETER);
if (commandDataLen != 1) {
return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
}
switch (commandData[0]) {
case MGMLIS3MDL::LOW:
registers[0] = (registers[0] & (~(1 << MGMLIS3MDL::OM1))) & (~(1 << MGMLIS3MDL::OM0));
registers[3] = (registers[3] & (~(1 << MGMLIS3MDL::OMZ1))) & (~(1 << MGMLIS3MDL::OMZ0));
break;
case MGMLIS3MDL::MEDIUM:
registers[0] = (registers[0] & (~(1 << MGMLIS3MDL::OM1))) | (1 << MGMLIS3MDL::OM0);
registers[3] = (registers[3] & (~(1 << MGMLIS3MDL::OMZ1))) | (1 << MGMLIS3MDL::OMZ0);
break;
case MGMLIS3MDL::HIGH:
registers[0] = (registers[0] | (1 << MGMLIS3MDL::OM1)) & (~(1 << MGMLIS3MDL::OM0));
registers[3] = (registers[3] | (1 << MGMLIS3MDL::OMZ1)) & (~(1 << MGMLIS3MDL::OMZ0));
break;
case MGMLIS3MDL::ULTRA:
registers[0] = (registers[0] | (1 << MGMLIS3MDL::OM1)) | (1 << MGMLIS3MDL::OM0);
registers[3] = (registers[3] | (1 << MGMLIS3MDL::OMZ1)) | (1 << MGMLIS3MDL::OMZ0);
break;
default:
break;
}
return prepareCtrlRegisterWrite();
}
void MGMHandlerLIS3MDL::fillCommandAndReplyMap() {
/*
* Regarding ArduinoBoard:
* Actually SPI answers directly, but as commanding ArduinoBoard the
* communication could be delayed
* SPI always has to be triggered, so there could be no periodic answer of
* the device, the device has to asked with a command, so periodic is zero.
*
* We dont read single registers, we just expect special
* reply from he Readall_MGM
*/
insertInCommandAndReplyMap(MGMLIS3MDL::READ_CONFIG_AND_DATA, 1, &dataset);
insertInCommandAndReplyMap(MGMLIS3MDL::READ_TEMPERATURE, 1);
insertInCommandAndReplyMap(MGMLIS3MDL::SETUP_MGM, 1);
insertInCommandAndReplyMap(MGMLIS3MDL::IDENTIFY_DEVICE, 1);
insertInCommandAndReplyMap(MGMLIS3MDL::TEMP_SENSOR_ENABLE, 1);
insertInCommandAndReplyMap(MGMLIS3MDL::ACCURACY_OP_MODE_SET, 1);
}
ReturnValue_t MGMHandlerLIS3MDL::prepareCtrlRegisterWrite() {
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1, true);
for (size_t i = 0; i < MGMLIS3MDL::NR_OF_CTRL_REGISTERS; i++) {
commandBuffer[i + 1] = registers[i];
}
rawPacket = commandBuffer;
rawPacketLen = MGMLIS3MDL::NR_OF_CTRL_REGISTERS + 1;
/* We dont have to check if this is working because we just did it */
return RETURN_OK;
}
void MGMHandlerLIS3MDL::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
}
uint32_t MGMHandlerLIS3MDL::getTransitionDelayMs(Mode_t from, Mode_t to) {
return 20000;
}
void MGMHandlerLIS3MDL::modeChanged(void) {
internalState = InternalState::STATE_NONE;
}
ReturnValue_t MGMHandlerLIS3MDL::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_X,
new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Y,
new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Z,
new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS,
new PoolEntry<float>({0.0}));
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,167 +0,0 @@
#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
#include "OBSWConfig.h"
#include "devicedefinitions/MGMHandlerLIS3Definitions.h"
#include "events/subsystemIdRanges.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
class PeriodicOperationDivider;
/**
* @brief Device handler object for the LIS3MDL 3-axis magnetometer
* by STMicroeletronics
* @details
* Datasheet can be found online by googling LIS3MDL.
* Flight manual:
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/LIS3MDL_MGM
* @author L. Loidold, R. Mueller
*/
class MGMHandlerLIS3MDL: public DeviceHandlerBase {
public:
enum class CommunicationStep {
DATA,
TEMPERATURE
};
static const uint8_t INTERFACE_ID = CLASS_ID::MGM_LIS3MDL;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MGM_LIS3MDL;
//Notifies a command to change the setup parameters
static const Event CHANGE_OF_SETUP_PARAMETER = MAKE_EVENT(0, severity::LOW);
MGMHandlerLIS3MDL(uint32_t objectId, object_id_t deviceCommunication,
CookieIF* comCookie);
virtual ~MGMHandlerLIS3MDL();
protected:
/** DeviceHandlerBase overrides */
void doShutDown() override;
void doStartUp() override;
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) override;
ReturnValue_t buildTransitionDeviceCommand(
DeviceCommandId_t *id) override;
ReturnValue_t buildNormalDeviceCommand(
DeviceCommandId_t *id) override;
ReturnValue_t scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) override;
void fillCommandAndReplyMap() override;
void modeChanged(void) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
private:
MGMLIS3MDL::MgmPrimaryDataset dataset;
/*------------------------------------------------------------------------*/
/* Device specific commands and variables */
/*------------------------------------------------------------------------*/
/**
* Sets the read bit for the command
* @param single command to set the read-bit at
* @param boolean to select a continuous read bit, default = false
*/
uint8_t readCommand(uint8_t command, bool continuousCom = false);
/**
* Sets the write bit for the command
* @param single command to set the write-bit at
* @param boolean to select a continuous write bit, default = false
*/
uint8_t writeCommand(uint8_t command, bool continuousCom = false);
/**
* This Method gets the full scale for the measurement range
* e.g.: +- 4 gauss. See p.25 datasheet.
* @return The ReturnValue does not contain the sign of the value
*/
uint8_t getFullScale(uint8_t ctrlReg2);
/**
* The 16 bit value needs to be divided by the full range of a 16bit value
* and then multiplied with the current scale of the MGM.
* This factor returns the factor required to achieve this with
* one multiplication.
*
* @param scale is the return value of the getFulscale Method
* @return Multiplication factor to get the sensor value from raw data.
*/
float getSensitivityFactor(uint8_t scale);
/**
* This Command detects the device ID
*/
ReturnValue_t identifyDevice();
virtual void setupMgm();
/*------------------------------------------------------------------------*/
/* Non normal commands */
/*------------------------------------------------------------------------*/
/**
* Enables/Disables the integrated Temperaturesensor
* @param commandData On or Off
* @param length of the commandData: has to be 1
*/
virtual ReturnValue_t enableTemperatureSensor(const uint8_t *commandData,
size_t commandDataLen);
/**
* Sets the accuracy of the measurement of the axis. The noise is changing.
* @param commandData LOW, MEDIUM, HIGH, ULTRA
* @param length of the command, has to be 1
*/
virtual ReturnValue_t setOperatingMode(const uint8_t *commandData,
size_t commandDataLen);
//Length a sindgle command SPI answer
static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2;
//Single SPIcommand has 2 bytes, first for adress, second for content
size_t singleComandSize = 2;
//has the size for all adresses of the lis3mdl + the continous write bit
uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1];
/**
* We want to save the registers we set, so we dont have to read the
* registers when we want to change something.
* --> everytime we change set a register we have to save it
*/
uint8_t registers[MGMLIS3MDL::NR_OF_CTRL_REGISTERS];
uint8_t statusRegister = 0;
/**
* We always update all registers together, so this method updates
* the rawpacket and rawpacketLen, so we just manipulate the local
* saved register
*
*/
ReturnValue_t prepareCtrlRegisterWrite();
enum class InternalState {
STATE_NONE,
STATE_FIRST_CONTACT,
STATE_SETUP,
STATE_CHECK_REGISTERS,
STATE_NORMAL
};
InternalState internalState = InternalState::STATE_NONE;
CommunicationStep communicationStep = CommunicationStep::DATA;
bool commandExecuted = false;
#if OBSW_VERBOSE_LEVEL >= 1
PeriodicOperationDivider* debugDivider;
#endif
};
#endif /* MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ */

View File

@ -1,363 +0,0 @@
#include "MGMHandlerRM3100.h"
#include "fsfw/datapool/PoolReadGuard.h"
#include "fsfw/globalfunctions/bitutility.h"
#include "fsfw/devicehandlers/DeviceHandlerMessage.h"
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
MGMHandlerRM3100::MGMHandlerRM3100(object_id_t objectId,
object_id_t deviceCommunication, CookieIF* comCookie):
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
primaryDataset(this) {
#if OBSW_VERBOSE_LEVEL >= 1
debugDivider = new PeriodicOperationDivider(5);
#endif
}
MGMHandlerRM3100::~MGMHandlerRM3100() {}
void MGMHandlerRM3100::doStartUp() {
switch(internalState) {
case(InternalState::NONE): {
internalState = InternalState::CONFIGURE_CMM;
break;
}
case(InternalState::CONFIGURE_CMM): {
internalState = InternalState::READ_CMM;
break;
}
case(InternalState::READ_CMM): {
if(commandExecuted) {
internalState = InternalState::STATE_CONFIGURE_TMRC;
}
break;
}
case(InternalState::STATE_CONFIGURE_TMRC): {
if(commandExecuted) {
internalState = InternalState::STATE_READ_TMRC;
}
break;
}
case(InternalState::STATE_READ_TMRC): {
if(commandExecuted) {
internalState = InternalState::NORMAL;
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
setMode(MODE_NORMAL);
#else
setMode(_MODE_TO_ON);
#endif
}
break;
}
default: {
break;
}
}
}
void MGMHandlerRM3100::doShutDown() {
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t MGMHandlerRM3100::buildTransitionDeviceCommand(
DeviceCommandId_t *id) {
switch(internalState) {
case(InternalState::NONE):
case(InternalState::NORMAL): {
return HasReturnvaluesIF::RETURN_OK;
}
case(InternalState::CONFIGURE_CMM): {
*id = RM3100::CONFIGURE_CMM;
break;
}
case(InternalState::READ_CMM): {
*id = RM3100::READ_CMM;
break;
}
case(InternalState::STATE_CONFIGURE_TMRC): {
*id = RM3100::CONFIGURE_TMRC;
break;
}
case(InternalState::STATE_READ_TMRC): {
*id = RM3100::READ_TMRC;
break;
}
default:
/* Might be a configuration error. */
sif::debug << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" <<
std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
return buildCommandFromCommand(*id, nullptr, 0);
}
ReturnValue_t MGMHandlerRM3100::buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) {
switch(deviceCommand) {
case(RM3100::CONFIGURE_CMM): {
commandBuffer[0] = RM3100::CMM_REGISTER;
commandBuffer[1] = RM3100::CMM_VALUE;
rawPacket = commandBuffer;
rawPacketLen = 2;
break;
}
case(RM3100::READ_CMM): {
commandBuffer[0] = RM3100::CMM_REGISTER | RM3100::READ_MASK;
commandBuffer[1] = 0;
rawPacket = commandBuffer;
rawPacketLen = 2;
break;
}
case(RM3100::CONFIGURE_TMRC): {
return handleTmrcConfigCommand(deviceCommand, commandData,
commandDataLen);
}
case(RM3100::READ_TMRC): {
commandBuffer[0] = RM3100::TMRC_REGISTER | RM3100::READ_MASK;
commandBuffer[1] = 0;
rawPacket = commandBuffer;
rawPacketLen = 2;
break;
}
case(RM3100::CONFIGURE_CYCLE_COUNT): {
return handleCycleCountConfigCommand(deviceCommand, commandData,
commandDataLen);
}
case(RM3100::READ_CYCLE_COUNT): {
commandBuffer[0] = RM3100::CYCLE_COUNT_START_REGISTER | RM3100::READ_MASK;
std::memset(commandBuffer + 1, 0, 6);
rawPacket = commandBuffer;
rawPacketLen = 7;
break;
}
case(RM3100::READ_DATA): {
commandBuffer[0] = RM3100::MEASUREMENT_REG_START | RM3100::READ_MASK;
std::memset(commandBuffer + 1, 0, 9);
rawPacketLen = 10;
break;
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
return RETURN_OK;
}
ReturnValue_t MGMHandlerRM3100::buildNormalDeviceCommand(
DeviceCommandId_t *id) {
*id = RM3100::READ_DATA;
return buildCommandFromCommand(*id, nullptr, 0);
}
ReturnValue_t MGMHandlerRM3100::scanForReply(const uint8_t *start,
size_t len, DeviceCommandId_t *foundId,
size_t *foundLen) {
/* For SPI, ID will always be the one of the last sent command. */
*foundId = this->getPendingCommand();
*foundLen = len;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t MGMHandlerRM3100::interpretDeviceReply(
DeviceCommandId_t id, const uint8_t *packet) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
switch(id) {
case(RM3100::CONFIGURE_CMM):
case(RM3100::CONFIGURE_CYCLE_COUNT):
case(RM3100::CONFIGURE_TMRC): {
/* We can only check whether write was successful with read operation. */
if(mode == _MODE_START_UP) {
commandExecuted = true;
}
break;
}
case(RM3100::READ_CMM): {
uint8_t cmmValue = packet[1];
/* We clear the seventh bit in any case
* because this one is zero sometimes for some reason */
bitutil::bitClear(&cmmValue, 6);
if(cmmValue == cmmRegValue and internalState == InternalState::READ_CMM) {
commandExecuted = true;
}
else {
/* Attempt reconfiguration. */
internalState = InternalState::CONFIGURE_CMM;
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
}
break;
}
case(RM3100::READ_TMRC): {
if(packet[1] == tmrcRegValue) {
commandExecuted = true;
/* Reading TMRC was commanded. Trigger event to inform ground. */
if(mode != _MODE_START_UP) {
triggerEvent(tmrcSet, tmrcRegValue, 0);
}
}
else {
/* Attempt reconfiguration. */
internalState = InternalState::STATE_CONFIGURE_TMRC;
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
}
break;
}
case(RM3100::READ_CYCLE_COUNT): {
uint16_t cycleCountX = packet[1] << 8 | packet[2];
uint16_t cycleCountY = packet[3] << 8 | packet[4];
uint16_t cycleCountZ = packet[5] << 8 | packet[6];
if(cycleCountX != cycleCountRegValueX or cycleCountY != cycleCountRegValueY or
cycleCountZ != cycleCountRegValueZ) {
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
}
/* Reading TMRC was commanded. Trigger event to inform ground. */
if(mode != _MODE_START_UP) {
uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY;
triggerEvent(cycleCountersSet, eventParam1, cycleCountZ);
}
break;
}
case(RM3100::READ_DATA): {
result = handleDataReadout(packet);
break;
}
default:
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
return result;
}
ReturnValue_t MGMHandlerRM3100::handleCycleCountConfigCommand(DeviceCommandId_t deviceCommand,
const uint8_t *commandData, size_t commandDataLen) {
if(commandData == nullptr) {
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
}
// Set cycle count
if(commandDataLen == 2) {
handleCycleCommand(true, commandData, commandDataLen);
}
else if(commandDataLen == 6) {
handleCycleCommand(false, commandData, commandDataLen);
}
else {
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
}
commandBuffer[0] = RM3100::CYCLE_COUNT_VALUE;
std::memcpy(commandBuffer + 1, &cycleCountRegValueX, 2);
std::memcpy(commandBuffer + 3, &cycleCountRegValueY, 2);
std::memcpy(commandBuffer + 5, &cycleCountRegValueZ, 2);
rawPacketLen = 7;
rawPacket = commandBuffer;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t MGMHandlerRM3100::handleCycleCommand(bool oneCycleValue,
const uint8_t *commandData, size_t commandDataLen) {
RM3100::CycleCountCommand command(oneCycleValue);
ReturnValue_t result = command.deSerialize(&commandData, &commandDataLen,
SerializeIF::Endianness::BIG);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
/* Data sheet p.30 "while noise limits the useful upper range to ~400 cycle counts." */
if(command.cycleCountX > 450 ) {
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
}
if(not oneCycleValue and (command.cycleCountY > 450 or command.cycleCountZ > 450)) {
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
}
cycleCountRegValueX = command.cycleCountX;
cycleCountRegValueY = command.cycleCountY;
cycleCountRegValueZ = command.cycleCountZ;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t MGMHandlerRM3100::handleTmrcConfigCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) {
if(commandData == nullptr) {
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
}
if(commandDataLen != 1) {
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
}
commandBuffer[0] = RM3100::TMRC_REGISTER;
commandBuffer[1] = commandData[1];
rawPacketLen = 2;
rawPacket = commandBuffer;
return HasReturnvaluesIF::RETURN_OK;
}
void MGMHandlerRM3100::fillCommandAndReplyMap() {
insertInCommandAndReplyMap(RM3100::CONFIGURE_CMM, 1);
insertInCommandAndReplyMap(RM3100::READ_CMM, 1);
insertInCommandAndReplyMap(RM3100::CONFIGURE_TMRC, 1);
insertInCommandAndReplyMap(RM3100::READ_TMRC, 1);
insertInCommandAndReplyMap(RM3100::CONFIGURE_CYCLE_COUNT, 1);
insertInCommandAndReplyMap(RM3100::READ_CYCLE_COUNT, 1);
insertInCommandAndReplyMap(RM3100::READ_DATA, 1, &primaryDataset);
}
void MGMHandlerRM3100::modeChanged(void) {
internalState = InternalState::NONE;
}
ReturnValue_t MGMHandlerRM3100::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X, new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y, new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Z, new PoolEntry<float>({0.0}));
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t MGMHandlerRM3100::getTransitionDelayMs(Mode_t from, Mode_t to) {
return 10000;
}
ReturnValue_t MGMHandlerRM3100::handleDataReadout(const uint8_t *packet) {
/* Analyze data here. The sensor generates 24 bit signed values so we need to do some bitshift
* trickery here to calculate the raw values first */
int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8;
int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8;
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8;
/* Now scale to physical value in microtesla */
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
#if OBSW_VERBOSE_LEVEL >= 1
if(debugDivider->checkAndIncrement()) {
sif::info << "MGMHandlerRM3100: Magnetic field strength in"
" microtesla:" << std::endl;
/* Set terminal to utf-8 if there is an issue with micro printout. */
sif::info << "X: " << fieldStrengthX << " \xC2\xB5T" << std::endl;
sif::info << "Y: " << fieldStrengthY << " \xC2\xB5T" << std::endl;
sif::info << "Z: " << fieldStrengthZ << " \xC2\xB5T" << std::endl;
}
#endif
/* TODO: Sanity check on values */
PoolReadGuard readGuard(&primaryDataset);
if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
primaryDataset.fieldStrengthX = fieldStrengthX;
primaryDataset.fieldStrengthY = fieldStrengthY;
primaryDataset.fieldStrengthZ = fieldStrengthZ;
primaryDataset.setValidity(true, true);
}
return RETURN_OK;
}

View File

@ -1,104 +0,0 @@
#ifndef MISSION_DEVICES_MGMRM3100HANDLER_H_
#define MISSION_DEVICES_MGMRM3100HANDLER_H_
#include "OBSWConfig.h"
#include "devicedefinitions/MGMHandlerRM3100Definitions.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#if OBSW_VERBOSE_LEVEL >= 1
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
#endif
/**
* @brief Device Handler for the RM3100 geomagnetic magnetometer sensor
* (https://www.pnicorp.com/rm3100/)
* @details
* Flight manual:
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/RM3100_MGM
*/
class MGMHandlerRM3100: public DeviceHandlerBase {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::MGM_RM3100;
//! [EXPORT] : [COMMENT] P1: TMRC value which was set, P2: 0
static constexpr Event tmrcSet = event::makeEvent(SUBSYSTEM_ID::MGM_RM3100,
0x00, severity::INFO);
//! [EXPORT] : [COMMENT] Cycle counter set. P1: First two bytes new Cycle Count X
//! P1: Second two bytes new Cycle Count Y
//! P2: New cycle count Z
static constexpr Event cycleCountersSet = event::makeEvent(
SUBSYSTEM_ID::MGM_RM3100, 0x01, severity::INFO);
MGMHandlerRM3100(object_id_t objectId, object_id_t deviceCommunication,
CookieIF* comCookie);
virtual ~MGMHandlerRM3100();
protected:
/* DeviceHandlerBase overrides */
ReturnValue_t buildTransitionDeviceCommand(
DeviceCommandId_t *id) override;
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(
DeviceCommandId_t *id) override;
ReturnValue_t buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) override;
void fillCommandAndReplyMap() override;
void modeChanged(void) override;
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
private:
enum class InternalState {
NONE,
CONFIGURE_CMM,
READ_CMM,
// The cycle count states are propably not going to be used because
// the default cycle count will be used.
STATE_CONFIGURE_CYCLE_COUNT,
STATE_READ_CYCLE_COUNT,
STATE_CONFIGURE_TMRC,
STATE_READ_TMRC,
NORMAL
};
InternalState internalState = InternalState::NONE;
bool commandExecuted = false;
RM3100::Rm3100PrimaryDataset primaryDataset;
uint8_t commandBuffer[10];
uint8_t commandBufferLen = 0;
uint8_t cmmRegValue = RM3100::CMM_VALUE;
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;
uint16_t cycleCountRegValueX = RM3100::CYCLE_COUNT_VALUE;
uint16_t cycleCountRegValueY = RM3100::CYCLE_COUNT_VALUE;
uint16_t cycleCountRegValueZ = RM3100::CYCLE_COUNT_VALUE;
float scaleFactorX = 1 / RM3100::DEFAULT_GAIN;
float scaleFactorY = 1 / RM3100::DEFAULT_GAIN;
float scaleFactorZ = 1 / RM3100::DEFAULT_GAIN;
ReturnValue_t handleCycleCountConfigCommand(DeviceCommandId_t deviceCommand,
const uint8_t *commandData,size_t commandDataLen);
ReturnValue_t handleCycleCommand(bool oneCycleValue,
const uint8_t *commandData, size_t commandDataLen);
ReturnValue_t handleTmrcConfigCommand(DeviceCommandId_t deviceCommand,
const uint8_t *commandData,size_t commandDataLen);
ReturnValue_t handleDataReadout(const uint8_t* packet);
#if OBSW_VERBOSE_LEVEL >= 1
PeriodicOperationDivider* debugDivider;
#endif
};
#endif /* MISSION_DEVICEHANDLING_MGMRM3100HANDLER_H_ */

View File

@ -78,7 +78,7 @@ void Max31865PT1000Handler::doStartUp() {
void Max31865PT1000Handler::doShutDown() {
commandExecuted = false;
setMode(MODE_OFF);
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t Max31865PT1000Handler::buildNormalDeviceCommand(
@ -325,7 +325,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(
case(Max31865Definitions::REQUEST_LOW_THRESHOLD): {
uint16_t readLowThreshold = packet[0] << 8 | packet[1];
if(readLowThreshold != LOW_THRESHOLD) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 && DEBUG_RTD == 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 && OBSW_DEBUG_RTD == 1
sif::error
<< "Max31865PT1000Handler::interpretDeviceReply: Missmatch between written "
<< "and readback value of low threshold register"
@ -338,7 +338,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(
case(Max31865Definitions::REQUEST_HIGH_THRESHOLD): {
uint16_t readHighThreshold = packet[0] << 8 | packet[1];
if(readHighThreshold != HIGH_THRESHOLD) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 && DEBUG_RTD == 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 && OBSW_DEBUG_RTD == 1
sif::error
<< "Max31865PT1000Handler::interpretDeviceReply: Missmatch between written "
<< "and readback value of high threshold register"

View File

@ -1,3 +1,4 @@
#include <fsfw/datapool/PoolReadGuard.h>
#include "P60DockHandler.h"
#include "OBSWConfig.h"
@ -25,8 +26,26 @@ void P60DockHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *
*/
handleDeviceTM(&p60dockHkTableDataset, id, true);
#if OBSW_VERBOSE_LEVEL >= 1 && P60DOCK_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_P60DOCK == 1
p60dockHkTableDataset.read();
sif::info << "P60 Dock: ACU VCC switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateAcuVcc.value) << std::endl;
sif::info << "P60 Dock: PDU1 VCC switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu1Vcc.value) << std::endl;
sif::info << "P60 Dock: PDU2 VCC switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu2Vcc.value) << std::endl;
sif::info << "P60 Dock: ACU VBAT switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateAcuVbat.value) << std::endl;
sif::info << "P60 Dock: PDU1 VBAT switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu1Vbat.value) << std::endl;
sif::info << "P60 Dock: PDU2 VBAT switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu2Vbat.value) << std::endl;
sif::info << "P60 Dock: Stack VBAT switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateStackVbat.value) << std::endl;
sif::info << "P60 Dock: Stack 3V3 switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateStack3V3.value) << std::endl;
sif::info << "P60 Dock: Stack 5V switch: " <<
static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateStack5V.value) << std::endl;
float temperatureC = p60dockHkTableDataset.temperature1.value * 0.1;
sif::info << "P60 Dock: Temperature 1: " << temperatureC << " °C" << std::endl;
@ -386,3 +405,76 @@ ReturnValue_t P60DockHandler::initializeLocalDataPool(
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t P60DockHandler::printStatus(DeviceCommandId_t cmd) {
switch(cmd) {
case(GOMSPACE::PRINT_SWITCH_V_I): {
PoolReadGuard pg(&p60dockHkTableDataset);
ReturnValue_t readResult = pg.getReadResult();
if(readResult != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Reading PDU1 HK table failed!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
printHkTable();
return HasReturnvaluesIF::RETURN_OK;
}
default: {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
}
void P60DockHandler::printHkTable() {
sif::info << "P60 Dock Info: SwitchState, Currents [mA], Voltages [mV]" << std::endl;
sif::info << std::setw(30) << std::left << "ACU VCC" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStateAcuVcc.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentAcuVcc.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltageAcuVcc.value << std::endl;
sif::info << std::setw(30) << std::left << "ACU VBAT" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStateAcuVbat.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentAcuVbat.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltageAcuVbat.value << std::endl;
sif::info << std::setw(30) << std::left << "PDU1 VCC" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStatePdu1Vcc.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentPdu1Vcc.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltagePdu1Vcc.value << std::endl;
sif::info << std::setw(30) << std::left << "PDU1 VBAT" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStatePdu1Vbat.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentPdu1Vbat.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltagePdu1Vbat.value << std::endl;
sif::info << std::setw(30) << std::left << "PDU2 VCC" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStatePdu2Vcc.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentPdu2Vcc.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltagePdu2Vcc.value << std::endl;
sif::info << std::setw(30) << std::left << "PDU2 VBAT" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStatePdu2Vbat.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentPdu2Vbat.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltagePdu2Vbat.value << std::endl;
sif::info << std::setw(30) << std::left << "Stack VBAT" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStateStackVbat.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentStackVbat.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltageStackVbat.value << std::endl;
sif::info << std::setw(30) << std::left << "Stack 3V3" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStateStack3V3.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentStack3V3.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltageStack3V3.value << std::endl;
sif::info << std::setw(30) << std::left << "Stack 5V" << std::dec << "| " <<
unsigned(p60dockHkTableDataset.outputEnableStateStack5V.value) << ", " <<
std::setw(4) << std::right <<
p60dockHkTableDataset.currentStack5V.value << ", " << std::setw(5) <<
p60dockHkTableDataset.voltageStack5V.value << std::endl;
}

View File

@ -26,6 +26,14 @@ protected:
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
/**
* This command handles printing the HK table to the console. This is useful for debugging
* purposes
* @return
*/
ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
void printHkTable();
private:
P60Dock::HkTableDataset p60dockHkTableDataset;

View File

@ -93,7 +93,7 @@ void PCDUHandler::initializeSwitchStates() {
switchStates[pcduSwitches::SUS_NOMINAL] = pcduSwitches::INIT_STATE_SUS_NOMINAL;
switchStates[pcduSwitches::SOLAR_CELL_EXP] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP;
switchStates[pcduSwitches::PLOC] = pcduSwitches::INIT_STATE_PLOC;
switchStates[pcduSwitches::ACS_BORAD_SIDE_A] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A;
switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A;
}
void PCDUHandler::readCommandQueue() {
@ -186,7 +186,7 @@ void PCDUHandler::updatePdu1SwitchStates() {
switchStates[pcduSwitches::SUS_NOMINAL] = pdu1HkTableDataset.voltageOutSUSNominal.value;
switchStates[pcduSwitches::SOLAR_CELL_EXP] = pdu1HkTableDataset.voltageOutSolarCellExp.value;
switchStates[pcduSwitches::PLOC] = pdu1HkTableDataset.voltageOutPLOC.value;
switchStates[pcduSwitches::ACS_BORAD_SIDE_A] = pdu1HkTableDataset.voltageOutACSBoardSideA.value;
switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pdu1HkTableDataset.voltageOutACSBoardSideA.value;
}
else {
sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl;

View File

@ -1,11 +1,12 @@
#include "OBSWConfig.h"
#include "PDU1Handler.h"
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <OBSWConfig.h>
#include <fsfw/datapool/PoolReadGuard.h>
PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) :
GomspaceDeviceHandler(objectId, comIF, comCookie, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_REPLY_SIZE, &pdu1HkTableDataset), pdu1HkTableDataset(
this) {
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_REPLY_SIZE, &pdu1HkTableDataset),
pdu1HkTableDataset(this) {
}
PDU1Handler::~PDU1Handler() {
@ -22,24 +23,63 @@ void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac
parseHkTableReply(packet);
handleDeviceTM(&pdu1HkTableDataset, id, true);
#if OBSW_VERBOSE_LEVEL >= 1 && PDU1_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PDU1 == 1
pdu1HkTableDataset.read();
sif::info << "PDU1 TCS Board voltage: " << pdu1HkTableDataset.voltageOutTCSBoard3V3
<< std::endl;
sif::info << "PDU1 Syrlinks voltage: " << pdu1HkTableDataset.voltageOutSyrlinks << std::endl;
sif::info << "PDU1 star tracker voltage: " << pdu1HkTableDataset.voltageOutStarTracker
<< std::endl;
sif::info << "PDU1 MGT voltage: " << pdu1HkTableDataset.voltageOutMGT << std::endl;
sif::info << "PDU1 SUS nominal voltage: " << pdu1HkTableDataset.voltageOutSUSNominal
<< std::endl;
sif::info << "PDU1 solar cell experiment voltage: " << pdu1HkTableDataset.voltageOutSolarCellExp
<< std::endl;
sif::info << "PDU1 PLOC voltage: " << pdu1HkTableDataset.voltageOutPLOC << std::endl;
sif::info << "PDU1 ACS Side A voltage: " << pdu1HkTableDataset.voltageOutACSBoardSideA
<< std::endl;
sif::info << "PDU1 channel 8 voltage: " << pdu1HkTableDataset.voltageOutACSBoardSideA
<< std::endl;
sif::info << "PDU1 TCS Board current: " << pdu1HkTableDataset.currentOutTCSBoard3V3
<< std::endl;
sif::info << "PDU1 Syrlinks current: " << pdu1HkTableDataset.currentOutSyrlinks << std::endl;
sif::info << "PDU1 star tracker current: " << pdu1HkTableDataset.currentOutStarTracker
<< std::endl;
sif::info << "PDU1 MGT current: " << pdu1HkTableDataset.currentOutMGT << std::endl;
sif::info << "PDU1 SUS nominal current: " << pdu1HkTableDataset.currentOutSUSNominal
<< std::endl;
sif::info << "PDU1 solar cell experiment current: " << pdu1HkTableDataset.currentOutSolarCellExp
<< std::endl;
sif::info << "PDU1 PLOC current: " << pdu1HkTableDataset.currentOutPLOC << std::endl;
sif::info << "PDU1 ACS Side A current: " << pdu1HkTableDataset.currentOutACSBoardSideA
<< std::endl;
sif::info << "PDU1 channel 8 current: " << pdu1HkTableDataset.currentOutChannel8
<< std::endl;
printOutputSwitchStates();
sif::info << "PDU1 battery mode: " <<
static_cast<unsigned int>(pdu1HkTableDataset.battMode.value) << std::endl;
sif::info << "PDU1 VCC: " << pdu1HkTableDataset.vcc << " mV" << std::endl;
float vbat = pdu1HkTableDataset.vbat.value * 0.1;
sif::info << "PDU1 VBAT: " << vbat << std::endl;
float vbat = pdu1HkTableDataset.vbat.value * 0.001;
sif::info << "PDU1 VBAT: " << vbat << "V" << std::endl;
float temperatureC = pdu1HkTableDataset.temperature.value * 0.1;
sif::info << "PDU1 Temperature: " << temperatureC << " °C" << std::endl;
sif::info << "PDU1 csp1 watchdog pings before reboot: "
<< unsigned(pdu1HkTableDataset.csp1WatchdogPingsLeft.value) << std::endl;
<< static_cast<unsigned int>(pdu1HkTableDataset.csp1WatchdogPingsLeft.value) << std::endl;
sif::info << "PDU1 csp2 watchdog pings before reboot: "
<< unsigned(pdu1HkTableDataset.csp2WatchdogPingsLeft.value) << std::endl;
<< static_cast<unsigned int>(pdu1HkTableDataset.csp2WatchdogPingsLeft.value) << std::endl;
pdu1HkTableDataset.commit();
#endif
}
void PDU1Handler::parseHkTableReply(const uint8_t *packet) {
uint16_t dataOffset = 0;
pdu1HkTableDataset.read();
PoolReadGuard pg(&pdu1HkTableDataset);
ReturnValue_t readResult = pg.getReadResult();
if(readResult != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Reading PDU1 HK table failed!" << std::endl;
return;
}
/* Fist 10 bytes contain the gomspace header. Each variable is preceded by the 16-bit table
* address. */
dataOffset += 12;
@ -199,8 +239,10 @@ void PDU1Handler::parseHkTableReply(const uint8_t *packet) {
dataOffset += 3;
pdu1HkTableDataset.csp2WatchdogPingsLeft = *(packet + dataOffset);
pdu1HkTableDataset.commit();
pdu1HkTableDataset.setChanged(true);
if(not pdu1HkTableDataset.isValid()) {
pdu1HkTableDataset.setValidity(true, true);
}
}
ReturnValue_t PDU1Handler::initializeLocalDataPool(
@ -291,3 +333,70 @@ ReturnValue_t PDU1Handler::initializeLocalDataPool(
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PDU1Handler::printStatus(DeviceCommandId_t cmd) {
switch(cmd) {
case(GOMSPACE::PRINT_SWITCH_V_I): {
PoolReadGuard pg(&pdu1HkTableDataset);
ReturnValue_t readResult = pg.getReadResult();
if(readResult != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Reading PDU1 HK table failed!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
printHkTable();
return HasReturnvaluesIF::RETURN_OK;
}
default: {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
}
void PDU1Handler::printHkTable() {
sif::info << "PDU1 Info: SwitchState, Currents [mA], Voltages [mV]" << std::endl;
sif::info << std::setw(30) << std::left << "TCS Board" << std::dec << "| " <<
unsigned(pdu1HkTableDataset.outEnabledTCSBoard3V3.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutTCSBoard3V3.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutTCSBoard3V3.value << std::endl;
sif::info << std::setw(30) << std::left << "Syrlinks" << std::dec << "| " <<
unsigned(pdu1HkTableDataset.outEnabledSyrlinks.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutSyrlinks.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutSyrlinks.value << std::endl;
sif::info << std::setw(30) << std::left << "Star Tracker" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledStarTracker.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutStarTracker.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutStarTracker.value << std::endl;
sif::info << std::setw(30) << std::left << "MGT" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledMGT.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutMGT.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutMGT.value << std::endl;
sif::info << std::setw(30) << std::left << "SuS nominal" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledSUSNominal.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutSUSNominal.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutSUSNominal.value << std::endl;
sif::info << std::setw(30) << std::left << "Solar Cell Experiment" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledSolarCellExp.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutSolarCellExp.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutSolarCellExp.value << std::endl;
sif::info << std::setw(30) << std::left << "PLOC" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledPLOC.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutPLOC.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutPLOC.value << std::endl;
sif::info << std::setw(30) << std::left << "ACS Side A" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledAcsBoardSideA.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutACSBoardSideA.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutACSBoardSideA.value << std::endl;
sif::info << std::setw(30) << std::left << "Channel 8" << std::dec << "| " <<
static_cast<unsigned int>(pdu1HkTableDataset.outEnabledChannel8.value) << ", " <<
std::setw(4) << std::right <<
pdu1HkTableDataset.currentOutChannel8.value << ", " << std::setw(4) <<
pdu1HkTableDataset.voltageOutChannel8.value << std::right << std::endl;
}

View File

@ -2,7 +2,7 @@
#define MISSION_DEVICES_PDU1Handler_H_
#include "GomspaceDeviceHandler.h"
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include "devicedefinitions/GomspaceDefinitions.h"
/**
* @brief This is the device handler for the PDU1.
@ -32,11 +32,13 @@ protected:
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
private:
/** Dataset for the housekeeping table of the PDU1 */
PDU1::PDU1HkTableDataset pdu1HkTableDataset;
void printHkTable();
void parseHkTableReply(const uint8_t *packet);
};

View File

@ -1,20 +1,22 @@
#include "OBSWConfig.h"
#include "PDU2Handler.h"
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <OBSWConfig.h>
#include <fsfw/datapool/PoolReadGuard.h>
PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) :
GomspaceDeviceHandler(objectId, comIF, comCookie, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_REPLY_SIZE, &pdu2HkTableDataset), pdu2HkTableDataset(
this) {
GomspaceDeviceHandler(objectId, comIF, comCookie, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_REPLY_SIZE, &pdu2HkTableDataset),
pdu2HkTableDataset(this) {
}
PDU2Handler::~PDU2Handler() {
}
ReturnValue_t PDU2Handler::buildNormalDeviceCommand(
DeviceCommandId_t * id) {
*id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0);
DeviceCommandId_t * id) {
*id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0);
}
void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
@ -26,7 +28,7 @@ void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac
*/
handleDeviceTM(&pdu2HkTableDataset, id, true);
#if OBSW_VERBOSE_LEVEL >= 1 && PDU2_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PDU2 == 1
pdu2HkTableDataset.read();
sif::info << "PDU2 Q7S current voltage: " << pdu2HkTableDataset.voltageOutQ7S << " mV" << std::endl;
sif::info << "PDU2 VCC: " << pdu2HkTableDataset.vcc << " mV" << std::endl;
@ -34,23 +36,7 @@ void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac
sif::info << "PDU2 VBAT: " << vbat << std::endl;
float temperatureC = pdu2HkTableDataset.temperature.value * 0.1;
sif::info << "PDU2 Temperature: " << temperatureC << " °C" << std::endl;
sif::info << "PDU2 Q7S enable state: " << unsigned(pdu2HkTableDataset.outEnabledQ7S.value) << std::endl;
sif::info << "PDU2 Payload PCDU channel 1 enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledPlPCDUCh1.value) << std::endl;
sif::info << "PDU2 reaction wheels enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledReactionWheels.value) << std::endl;
sif::info << "PDU2 TCS Board 8V heater input enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value) << std::endl;
sif::info << "PDU2 redundant SUS group enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledSUSRedundant.value) << std::endl;
sif::info << "PDU2 deployment mechanism enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledDeplMechanism.value) << std::endl;
sif::info << "PDU2 PCDU channel 6 enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledPlPCDUCh6.value) << std::endl;
sif::info << "PDU2 ACS board side B enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledAcsBoardSideB.value) << std::endl;
sif::info << "PDU2 payload camera enable state: "
<< unsigned(pdu2HkTableDataset.outEnabledPayloadCamera.value) << std::endl;
printOutputSwitchStates();
sif::info << "PDU2 uptime: " << pdu2HkTableDataset.uptime << " seconds" << std::endl;
sif::info << "PDU2 battery mode: " << unsigned(pdu2HkTableDataset.battMode.value) << std::endl;
sif::info << "PDU2 ground watchdog reboots: " << pdu2HkTableDataset.gndWdtReboots << std::endl;
@ -323,3 +309,70 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool(
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PDU2Handler::printStatus(DeviceCommandId_t cmd) {
switch(cmd) {
case(GOMSPACE::PRINT_SWITCH_V_I): {
PoolReadGuard pg(&pdu2HkTableDataset);
ReturnValue_t readResult = pg.getReadResult();
if(readResult != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Reading PDU1 HK table failed!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
printHkTable();
return HasReturnvaluesIF::RETURN_OK;
}
default: {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
}
void PDU2Handler::printHkTable() {
sif::info << "PDU2 Info: SwitchState, Currents [mA], Voltages [mV]" << std::endl;
sif::info << std::setw(30) << std::left << "Q7S" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledQ7S.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutQ7S.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutQ7S.value << std::endl;
sif::info << std::setw(30) << std::left << "Payload PCDU Channel 1" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledPlPCDUCh1.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutPayloadPCDUCh1.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutPayloadPCDUCh1.value << std::endl;
sif::info << std::setw(30) << std::left << "Reaction Wheels" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledReactionWheels.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutReactionWheels.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutReactionWheels.value << std::endl;
sif::info << std::setw(30) << std::left << "TCS Board 8V heater input" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutTCSBoardHeaterIn.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutTCSBoardHeaterIn.value << std::endl;
sif::info << std::setw(30) << std::left << "Redundant SUS group" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledSUSRedundant.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutSUSRedundant.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutSUSRedundant.value << std::endl;
sif::info << std::setw(30) << std::left << "Deployment mechanism" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledDeplMechanism.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutDeplMechanism.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutDeplMechanism.value << std::endl;
sif::info << std::setw(30) << std::left << "Payload PCDU Channel 6" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledPlPCDUCh6.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutPayloadPCDUCh6.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutPayloadPCDUCh6.value<< std::endl;
sif::info << std::setw(30) << std::left << "ACS Board Side B" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledAcsBoardSideB.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutACSBoardSideB.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutACSBoardSideB.value << std::endl;
sif::info << std::setw(30) << std::left << "Payload Camera enable state" << std::dec << "| " <<
unsigned(pdu2HkTableDataset.outEnabledPayloadCamera.value) << ", " <<
std::setw(4) << std::right <<
pdu2HkTableDataset.currentOutPayloadCamera.value << ", " << std::setw(4) <<
pdu2HkTableDataset.voltageOutPayloadCamera.value << std::right << std::endl;
}

View File

@ -20,25 +20,28 @@
*/
class PDU2Handler: public GomspaceDeviceHandler {
public:
PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie);
virtual ~PDU2Handler();
PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie);
virtual ~PDU2Handler();
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
protected:
/**
* @brief As soon as the device is in MODE_NORMAL, this function is executed periodically.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
/**
* @brief As soon as the device is in MODE_NORMAL, this function is executed periodically.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
private:
/** Dataset for the housekeeping table of the PDU2 */
PDU2::PDU2HkTableDataset pdu2HkTableDataset;
/** Dataset for the housekeeping table of the PDU2 */
PDU2::PDU2HkTableDataset pdu2HkTableDataset;
void parseHkTableReply(const uint8_t *packet);
void printHkTable();
void parseHkTableReply(const uint8_t *packet);
};
#endif /* MISSION_DEVICES_PDU2HANDLER_H_ */

View File

@ -22,7 +22,7 @@ void PlocMPSoCHandler::doStartUp(){
}
void PlocMPSoCHandler::doShutDown(){
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t PlocMPSoCHandler::buildNormalDeviceCommand(

View File

@ -147,7 +147,7 @@ ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id,
offset += 2;
dataset.ain7 = (*(packet + offset) << 8 | *(packet + offset + 1));
#if OBSW_VERBOSE_LEVEL >= 1 && DEBUG_RAD_SENSOR
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RAD_SENSOR
sif::info << "Radiation sensor temperature: " << dataset.temperatureCelcius << " °C"
<< std::endl;
sif::info << "Radiation sensor ADC value channel 0: " << dataset.ain0

View File

@ -38,6 +38,7 @@ void RwHandler::doShutDown() {
if(gpioComIF->pullLow(enableGpio) != RETURN_OK) {
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to low";
}
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) {
@ -143,47 +144,48 @@ void RwHandler::fillCommandAndReplyMap() {
ReturnValue_t RwHandler::scanForReply(const uint8_t *start, size_t remainingSize,
DeviceCommandId_t *foundId, size_t *foundLen) {
switch (*(start)) {
case (static_cast<uint8_t>(RwDefinitions::GET_LAST_RESET_STATUS)): {
uint8_t replyByte = *start;
switch (replyByte) {
case (RwDefinitions::GET_LAST_RESET_STATUS): {
*foundLen = RwDefinitions::SIZE_GET_RESET_STATUS;
*foundId = RwDefinitions::GET_LAST_RESET_STATUS;
break;
}
case (static_cast<uint8_t>(RwDefinitions::CLEAR_LAST_RESET_STATUS)): {
case (RwDefinitions::CLEAR_LAST_RESET_STATUS): {
*foundLen = RwDefinitions::SIZE_CLEAR_RESET_STATUS;
*foundId = RwDefinitions::CLEAR_LAST_RESET_STATUS;
break;
}
case (static_cast<uint8_t>(RwDefinitions::GET_RW_STATUS)): {
case (RwDefinitions::GET_RW_STATUS): {
*foundLen = RwDefinitions::SIZE_GET_RW_STATUS;
*foundId = RwDefinitions::GET_RW_STATUS;
break;
}
case (static_cast<uint8_t>(RwDefinitions::INIT_RW_CONTROLLER)): {
case (RwDefinitions::INIT_RW_CONTROLLER): {
*foundLen = RwDefinitions::SIZE_INIT_RW;
*foundId = RwDefinitions::INIT_RW_CONTROLLER;
break;
}
case (static_cast<uint8_t>(RwDefinitions::SET_SPEED)): {
case (RwDefinitions::SET_SPEED): {
*foundLen = RwDefinitions::SIZE_SET_SPEED_REPLY;
*foundId = RwDefinitions::SET_SPEED;
break;
}
case (static_cast<uint8_t>(RwDefinitions::GET_TEMPERATURE)): {
case (RwDefinitions::GET_TEMPERATURE): {
*foundLen = RwDefinitions::SIZE_GET_TEMPERATURE_REPLY;
*foundId = RwDefinitions::GET_TEMPERATURE;
break;
}
case (static_cast<uint8_t>(RwDefinitions::GET_TM)): {
case (RwDefinitions::GET_TM): {
*foundLen = RwDefinitions::SIZE_GET_TELEMETRY_REPLY;
*foundId = RwDefinitions::GET_TM;
break;
}
default: {
sif::debug << "RwHandler::scanForReply: Reply contains invalid command code" << std::endl;
sif::warning << "RwHandler::scanForReply: Reply contains invalid command code" <<
std::endl;
*foundLen = remainingSize;
return RETURN_FAILED;
break;
}
}
@ -346,7 +348,7 @@ void RwHandler::handleResetStatusReply(const uint8_t* packet) {
lastResetStatusSet.lastResetStatus = resetStatus;
}
lastResetStatusSet.currentResetStatus = resetStatus;
#if OBSW_VERBOSE_LEVEL >= 1 && RW_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleResetStatusReply: Last reset status: "
<< static_cast<unsigned int>(lastResetStatusSet.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleResetStatusReply: Current reset status: "
@ -377,7 +379,7 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
<< std::endl;
}
#if OBSW_VERBOSE_LEVEL >= 1 && RW_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleGetRwStatusReply: Current speed is: " << statusSet.currSpeed
<< " * 0.1 RPM" << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: Reference speed is: "
@ -394,7 +396,7 @@ void RwHandler::handleTemperatureReply(const uint8_t* packet) {
uint8_t offset = 2;
temperatureSet.temperatureCelcius = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16
| *(packet + offset + 1) << 8 | *(packet + offset);
#if OBSW_VERBOSE_LEVEL >= 1 && RW_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleTemperatureReply: Temperature: "
<< temperatureSet.temperatureCelcius << " °C" << std::endl;
#endif
@ -471,7 +473,7 @@ void RwHandler::handleGetTelemetryReply(const uint8_t* packet) {
offset += 4;
tmDataset.spiTotalNumOfErrors = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16
| *(packet + offset + 1) << 8 | *(packet + offset);
#if OBSW_VERBOSE_LEVEL >= 1 && RW_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleTemperatureReply: Last reset status: "
<< static_cast<unsigned int>(tmDataset.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleTemperatureReply: MCU temperature: " << tmDataset.mcuTemperature

View File

@ -28,10 +28,10 @@ void StarTrackerHandler::doStartUp() {
#else
setMode(_MODE_TO_ON);
#endif
}
void StarTrackerHandler::doShutDown() {
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) {
@ -207,7 +207,7 @@ void StarTrackerHandler::handleTemperatureTm() {
temperatureSet.cmosTemperature = *(decodedFrame + offset) << 24
| *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8
| *(decodedFrame + offset + 3);
#if OBSW_VERBOSE_LEVEL >= 1 && START_TRACKER_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1
sif::info << "StarTrackerHandler::handleTemperatureTm: MCU Temperature: "
<< temperatureSet.mcuTemperature << " °C" << std::endl;
sif::info << "StarTrackerHandler::handleTemperatureTm: CMOS Temperature: "

View File

@ -23,7 +23,7 @@ void SyrlinksHkHandler::doStartUp(){
}
void SyrlinksHkHandler::doShutDown(){
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(
@ -384,7 +384,7 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) {
offset += 6;
rxDataset.rxDataRate = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SYRLINKS == 1
sif::info << "Syrlinks RX Status: 0x" << std::hex << (unsigned int)rxDataset.rxStatus.value << std::endl;
sif::info << "Syrlinks RX Sensitivity: " << std::dec << rxDataset.rxSensitivity << std::endl;
sif::info << "Syrlinks RX Frequency Shift: " << rxDataset.rxFrequencyShift << std::endl;
@ -400,7 +400,7 @@ void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE;
txDataset.txStatus = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SYRLINKS == 1
sif::info << "Syrlinks TX Status: 0x" << std::hex << (unsigned int) txDataset.txStatus.value
<< std::endl;
#endif
@ -410,7 +410,7 @@ void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE;
txDataset.txWaveform = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SYRLINKS == 1
sif::info << "Syrlinks TX Waveform: 0x" << std::hex << (unsigned int) txDataset.txWaveform.value
<< std::endl;
#endif
@ -420,7 +420,7 @@ void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE;
txDataset.txAgcValue = agcValueHighByte << 8 | convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SYRLINKS == 1
sif::info << "Syrlinks TX AGC Value: " << txDataset.txAgcValue << std::endl;
#endif
}

View File

@ -22,7 +22,7 @@ void Tmp1075Handler::doStartUp(){
}
void Tmp1075Handler::doShutDown(){
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t Tmp1075Handler::buildNormalDeviceCommand(

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