From 9597e3868cad50db403388117e729af287c8b086 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 25 Feb 2022 11:58:02 +0100 Subject: [PATCH 01/72] separate branch for new system components --- fsfw | 2 +- mission/CMakeLists.txt | 3 +-- mission/system/AcsBoardAssembly.cpp | 1 + mission/system/AcsBoardAssembly.h | 8 ++++++++ mission/system/AcsSubsystem.cpp | 1 + mission/system/AcsSubsystem.h | 8 ++++++++ mission/system/CMakeLists.txt | 8 ++++++++ mission/system/ComSubsystem.cpp | 3 +++ mission/system/ComSubsystem.h | 8 ++++++++ mission/system/EiveSystem.cpp | 2 ++ mission/system/EiveSystem.h | 8 ++++++++ mission/system/PayloadSubsystem.cpp | 2 ++ mission/system/PayloadSubsystem.h | 8 ++++++++ mission/system/TcsSubsystem.cpp | 1 + mission/system/TcsSubsystem.h | 8 ++++++++ tmtc | 2 +- 16 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 mission/system/AcsBoardAssembly.cpp create mode 100644 mission/system/AcsBoardAssembly.h create mode 100644 mission/system/AcsSubsystem.cpp create mode 100644 mission/system/AcsSubsystem.h create mode 100644 mission/system/CMakeLists.txt create mode 100644 mission/system/ComSubsystem.cpp create mode 100644 mission/system/ComSubsystem.h create mode 100644 mission/system/EiveSystem.cpp create mode 100644 mission/system/EiveSystem.h create mode 100644 mission/system/PayloadSubsystem.cpp create mode 100644 mission/system/PayloadSubsystem.h create mode 100644 mission/system/TcsSubsystem.cpp create mode 100644 mission/system/TcsSubsystem.h diff --git a/fsfw b/fsfw index 19f8e41c..123f2ff3 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 19f8e41c7f2523d3684ebddd393e3a7700861328 +Subproject commit 123f2ff360e71228e1c0c786d80a4c93d7144a2e diff --git a/mission/CMakeLists.txt b/mission/CMakeLists.txt index b0fc4d00..ac28a332 100644 --- a/mission/CMakeLists.txt +++ b/mission/CMakeLists.txt @@ -3,5 +3,4 @@ add_subdirectory(devices) add_subdirectory(utility) add_subdirectory(memory) add_subdirectory(tmtc) - - +add_subdirectory(system) diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp new file mode 100644 index 00000000..5cd3eff0 --- /dev/null +++ b/mission/system/AcsBoardAssembly.cpp @@ -0,0 +1 @@ +#include "AcsBoardAssembly.h" diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h new file mode 100644 index 00000000..a41257d6 --- /dev/null +++ b/mission/system/AcsBoardAssembly.h @@ -0,0 +1,8 @@ +#ifndef MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ +#define MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ + + + + + +#endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/AcsSubsystem.cpp b/mission/system/AcsSubsystem.cpp new file mode 100644 index 00000000..4d9fe841 --- /dev/null +++ b/mission/system/AcsSubsystem.cpp @@ -0,0 +1 @@ +#include "AcsSubsystem.h" diff --git a/mission/system/AcsSubsystem.h b/mission/system/AcsSubsystem.h new file mode 100644 index 00000000..be2b094c --- /dev/null +++ b/mission/system/AcsSubsystem.h @@ -0,0 +1,8 @@ +#ifndef MISSION_SYSTEM_ACSSUBSYSTEM_H_ +#define MISSION_SYSTEM_ACSSUBSYSTEM_H_ + + + + + +#endif /* MISSION_SYSTEM_ACSSUBSYSTEM_H_ */ diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt new file mode 100644 index 00000000..880055e4 --- /dev/null +++ b/mission/system/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${LIB_EIVE_MISSION} PRIVATE + AcsBoardAssembly.cpp + AcsSubsystem.cpp + TcsSubsystem.cpp + EiveSystem.cpp + ComSubsystem.cpp + TcsSubsystem.cpp +) \ No newline at end of file diff --git a/mission/system/ComSubsystem.cpp b/mission/system/ComSubsystem.cpp new file mode 100644 index 00000000..b4349567 --- /dev/null +++ b/mission/system/ComSubsystem.cpp @@ -0,0 +1,3 @@ +#include "ComSubsystem.h" + + diff --git a/mission/system/ComSubsystem.h b/mission/system/ComSubsystem.h new file mode 100644 index 00000000..bb00aaf2 --- /dev/null +++ b/mission/system/ComSubsystem.h @@ -0,0 +1,8 @@ +#ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_ +#define MISSION_SYSTEM_COMSUBSYSTEM_H_ + + + + + +#endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */ diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp new file mode 100644 index 00000000..5ec47f86 --- /dev/null +++ b/mission/system/EiveSystem.cpp @@ -0,0 +1,2 @@ +#include "EiveSystem.h" + diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h new file mode 100644 index 00000000..39c35f52 --- /dev/null +++ b/mission/system/EiveSystem.h @@ -0,0 +1,8 @@ +#ifndef MISSION_SYSTEM_EIVESYSTEM_H_ +#define MISSION_SYSTEM_EIVESYSTEM_H_ + + + + + +#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */ diff --git a/mission/system/PayloadSubsystem.cpp b/mission/system/PayloadSubsystem.cpp new file mode 100644 index 00000000..0b0d354a --- /dev/null +++ b/mission/system/PayloadSubsystem.cpp @@ -0,0 +1,2 @@ +#include "PayloadSubsystem.h" + diff --git a/mission/system/PayloadSubsystem.h b/mission/system/PayloadSubsystem.h new file mode 100644 index 00000000..79f5cc8b --- /dev/null +++ b/mission/system/PayloadSubsystem.h @@ -0,0 +1,8 @@ +#ifndef MISSION_SYSTEM_PAYLOADSUBSYSTEM_H_ +#define MISSION_SYSTEM_PAYLOADSUBSYSTEM_H_ + + + + + +#endif /* MISSION_SYSTEM_PAYLOADSUBSYSTEM_H_ */ diff --git a/mission/system/TcsSubsystem.cpp b/mission/system/TcsSubsystem.cpp new file mode 100644 index 00000000..3ecfde2b --- /dev/null +++ b/mission/system/TcsSubsystem.cpp @@ -0,0 +1 @@ +#include "TcsSubsystem.h" diff --git a/mission/system/TcsSubsystem.h b/mission/system/TcsSubsystem.h new file mode 100644 index 00000000..536fedce --- /dev/null +++ b/mission/system/TcsSubsystem.h @@ -0,0 +1,8 @@ +#ifndef MISSION_SYSTEM_TCSSUBSYSTEM_H_ +#define MISSION_SYSTEM_TCSSUBSYSTEM_H_ + + + + + +#endif /* MISSION_SYSTEM_TCSSUBSYSTEM_H_ */ diff --git a/tmtc b/tmtc index 6a783112..7e245891 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6a78311239bdf78040e43ef217035fcaa2ab9f3b +Subproject commit 7e24589184bb7bbd427c66ed55b3c29bbeba927f From 5873371d36168a99bfb1f71c6d64c73353574d4a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Mar 2022 17:56:54 +0100 Subject: [PATCH 02/72] continued acs board assembly --- linux/devices/startracker/StrHelper.cpp | 2 +- mission/system/AcsBoardAssembly.cpp | 248 ++++++++++++++++++++++++ mission/system/AcsBoardAssembly.h | 90 +++++++++ mission/system/AcsSubsystem.h | 4 - mission/system/ComSubsystem.cpp | 2 - mission/system/ComSubsystem.h | 4 - mission/system/EiveSystem.cpp | 1 - mission/system/EiveSystem.h | 4 - mission/system/PayloadSubsystem.cpp | 1 - mission/system/PayloadSubsystem.h | 4 - mission/system/TcsSubsystem.h | 4 - mission/utility/ProgressPrinter.cpp | 4 +- 12 files changed, 341 insertions(+), 27 deletions(-) diff --git a/linux/devices/startracker/StrHelper.cpp b/linux/devices/startracker/StrHelper.cpp index cab99a1a..599b706f 100644 --- a/linux/devices/startracker/StrHelper.cpp +++ b/linux/devices/startracker/StrHelper.cpp @@ -6,8 +6,8 @@ #include "OBSWConfig.h" #include "fsfw/timemanager/Countdown.h" #include "linux/devices/devicedefinitions/StarTrackerDefinitions.h" -#include "mission/utility/Timestamp.h" #include "mission/utility/ProgressPrinter.h" +#include "mission/utility/Timestamp.h" StrHelper::StrHelper(object_id_t objectId) : SystemObject(objectId) {} diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 5cd3eff0..b3ef24c6 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -1 +1,249 @@ #include "AcsBoardAssembly.h" + +#include +#include +#include + +AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, + PowerSwitchIF* switcher, AcsBoardHelper helper) + : AssemblyBase(objectId, parentId), switcher(switcher), helper(helper) { + if (switcher == nullptr) { + sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid Power Switcher " + "IF passed" + << std::endl; + } + ModeListEntry entry; + initModeTableEntry(helper.mgm0Lis3IdSideA, entry); + initModeTableEntry(helper.mgm1Rm3100IdSideA, entry); + initModeTableEntry(helper.mgm2Lis3IdSideB, entry); + initModeTableEntry(helper.mgm3Rm3100IdSideB, entry); + initModeTableEntry(helper.gyro0AdisIdSideA, entry); + initModeTableEntry(helper.gyro1L3gIdSideA, entry); + initModeTableEntry(helper.gyro2AdisIdSideB, entry); + initModeTableEntry(helper.gyro3L3gIdSideB, entry); + initModeTableEntry(helper.gpsId, entry); +} + +ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { + ReturnValue_t result = RETURN_OK; + if (currentMode == mode and submode == currentSubmode) { + return result; + } + helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; + helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; + helper.gyro2SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; + helper.gyro3SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; + helper.mgm0SideAMode = childrenMap[helper.mgm0Lis3IdSideA].mode; + helper.mgm1SideAMode = childrenMap[helper.mgm1Rm3100IdSideA].mode; + helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode; + helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode; + helper.gpsMode = childrenMap[helper.gpsId].mode; + if (mode == DeviceHandlerIF::MODE_NORMAL) { + handleNormalModeCmd(submode); + } else if (mode == MODE_ON) { + } else { + } + HybridIterator tableIter(modeTable.begin(), modeTable.end()); + executeTable(tableIter); + return result; +} + +ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AcsBoardAssembly::initialize() { + ReturnValue_t result = registerChild(helper.gyro0AdisIdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.gyro1L3gIdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.gyro2AdisIdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.gyro3L3gIdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm0Lis3IdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm1Rm3100IdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm2Lis3IdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm3Rm3100IdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return result; +} + +void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { + modeTable.insert(entry); + entry.setObject(id); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + entry.setInheritSubmode(false); +} + +ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + return HasReturnvaluesIF::RETURN_OK; +} + +bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +ReturnValue_t AcsBoardAssembly::handleNormalModeCmd(Submode_t submode) { + ReturnValue_t result = RETURN_OK; + Mode_t tgtMode = DeviceHandlerIF::MODE_NORMAL; + powerStateMachine(submode); + if (state == States::MODE_COMMANDING) { + auto cmdSeq = [&](object_id_t objectId, ModeTableIdx tableIdx) { + if (isUseable(objectId, mode)) { + if (helper.gyro0SideAMode != MODE_OFF) { + modeTable[tableIdx].setMode(tgtMode); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); + } else { + result = NEED_SECOND_STEP; + modeTable[tableIdx].setMode(MODE_ON); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); + } + } + }; + switch (submode) { + case (A_SIDE): { + cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); + cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); + cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); + cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + return result; + } + case (B_SIDE): { + cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); + cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); + cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); + cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + return result; + } + case (DUAL_MODE): { + cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); + cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); + cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); + cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); + cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); + cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); + cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); + cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); + return result; + } + default: { + sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl; + } + } + } + return result; +} + +void AcsBoardAssembly::powerStateMachine(Submode_t submode) { + ReturnValue_t switchStateA = switcher->getSwitchState(pcduSwitches::ACS_BOARD_SIDE_A); + ReturnValue_t switchStateB = switcher->getSwitchState(pcduSwitches::ACS_BOARD_SIDE_B); + switch (submode) { + case (A_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (B_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (DUAL_MODE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + } + } + if (state == States::IDLE) { + switch (submode) { + case (A_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + // Set A side on first in power switcher IF + switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, true); + } + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, false); + } + break; + } + case (B_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + // Set A side on first in power switcher IF + switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, false); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, true); + } + break; + } + case (DUAL_MODE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + // Set A side on first in power switcher IF + switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, true); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, true); + } + break; + } + } + state = States::SWITCHING_POWER; + } + if (state == States::SWITCHING_POWER) { + // TODO: Could check for a timeout (temporal or cycles) here and resent command + } +} diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index a41257d6..6ff63dd5 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -1,8 +1,98 @@ #ifndef MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ #define MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ +#include +#include +struct AcsBoardHelper { + AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id, + object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id, + object_id_t gpsId) + : mgm0Lis3IdSideA(mgm0Id), + mgm1Rm3100IdSideA(mgm1Id), + mgm2Lis3IdSideB(mgm2Id), + mgm3Rm3100IdSideB(mgm3Id), + gyro0AdisIdSideA(gyro0Id), + gyro1L3gIdSideA(gyro1Id), + gyro2AdisIdSideB(gyro2Id), + gyro3L3gIdSideB(gyro3Id) {} + object_id_t mgm0Lis3IdSideA = objects::NO_OBJECT; + object_id_t mgm1Rm3100IdSideA = objects::NO_OBJECT; + object_id_t mgm2Lis3IdSideB = objects::NO_OBJECT; + object_id_t mgm3Rm3100IdSideB = objects::NO_OBJECT; + object_id_t gyro0AdisIdSideA = objects::NO_OBJECT; + object_id_t gyro1L3gIdSideA = objects::NO_OBJECT; + object_id_t gyro2AdisIdSideB = objects::NO_OBJECT; + object_id_t gyro3L3gIdSideB = objects::NO_OBJECT; + + object_id_t gpsId = objects::NO_OBJECT; + + Mode_t gyro0SideAMode = HasModesIF::MODE_OFF; + Mode_t gyro1SideAMode = HasModesIF::MODE_OFF; + Mode_t gyro2SideBMode = HasModesIF::MODE_OFF; + Mode_t gyro3SideBMode = HasModesIF::MODE_OFF; + Mode_t mgm0SideAMode = HasModesIF::MODE_OFF; + Mode_t mgm1SideAMode = HasModesIF::MODE_OFF; + Mode_t mgm2SideBMode = HasModesIF::MODE_OFF; + Mode_t mgm3SideBMode = HasModesIF::MODE_OFF; + Mode_t gpsMode = HasModesIF::MODE_OFF; +}; + +enum ModeTableIdx : uint8_t { + MGM_0_A = 0, + MGM_1_A = 1, + MGM_2_B = 2, + MGM_3_B = 3, + GYRO_0_A = 4, + GYRO_1_A = 5, + GYRO_2_B = 6, + GYRO_3_B = 7, + GPS = 8 +}; + +static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; + +class PowerSwitchIF; + +class AcsBoardAssembly : public AssemblyBase { + public: + AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, + AcsBoardHelper helper); + + private: + enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING }; + + States state = States::IDLE; + Mode_t currentMode = MODE_OFF; + Submode_t currentSubmode = A_SIDE; + PowerSwitchIF* switcher = nullptr; + + AcsBoardHelper helper; + void initModeTableEntry(object_id_t id, ModeListEntry& entry); + + ReturnValue_t initialize() override; + FixedArrayList modeTable; + + static constexpr Submode_t A_SIDE = 0; + static constexpr Submode_t B_SIDE = 1; + static constexpr Submode_t DUAL_MODE = 2; + + // AssemblyBase overrides + ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; + ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + + /** + * Check whether it makes sense to send mode commands to the device + * @param object + * @param mode + * @return + */ + bool isUseable(object_id_t object, Mode_t mode); + ReturnValue_t handleNormalModeCmd(Submode_t submode); + void powerStateMachine(Submode_t submode); +}; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/AcsSubsystem.h b/mission/system/AcsSubsystem.h index be2b094c..39d1fca9 100644 --- a/mission/system/AcsSubsystem.h +++ b/mission/system/AcsSubsystem.h @@ -1,8 +1,4 @@ #ifndef MISSION_SYSTEM_ACSSUBSYSTEM_H_ #define MISSION_SYSTEM_ACSSUBSYSTEM_H_ - - - - #endif /* MISSION_SYSTEM_ACSSUBSYSTEM_H_ */ diff --git a/mission/system/ComSubsystem.cpp b/mission/system/ComSubsystem.cpp index b4349567..fe91daff 100644 --- a/mission/system/ComSubsystem.cpp +++ b/mission/system/ComSubsystem.cpp @@ -1,3 +1 @@ #include "ComSubsystem.h" - - diff --git a/mission/system/ComSubsystem.h b/mission/system/ComSubsystem.h index bb00aaf2..a850c228 100644 --- a/mission/system/ComSubsystem.h +++ b/mission/system/ComSubsystem.h @@ -1,8 +1,4 @@ #ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_ #define MISSION_SYSTEM_COMSUBSYSTEM_H_ - - - - #endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */ diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index 5ec47f86..1fcd9b0f 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -1,2 +1 @@ #include "EiveSystem.h" - diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index 39c35f52..d4957787 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -1,8 +1,4 @@ #ifndef MISSION_SYSTEM_EIVESYSTEM_H_ #define MISSION_SYSTEM_EIVESYSTEM_H_ - - - - #endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */ diff --git a/mission/system/PayloadSubsystem.cpp b/mission/system/PayloadSubsystem.cpp index 0b0d354a..a1f277e9 100644 --- a/mission/system/PayloadSubsystem.cpp +++ b/mission/system/PayloadSubsystem.cpp @@ -1,2 +1 @@ #include "PayloadSubsystem.h" - diff --git a/mission/system/PayloadSubsystem.h b/mission/system/PayloadSubsystem.h index 79f5cc8b..6725c02f 100644 --- a/mission/system/PayloadSubsystem.h +++ b/mission/system/PayloadSubsystem.h @@ -1,8 +1,4 @@ #ifndef MISSION_SYSTEM_PAYLOADSUBSYSTEM_H_ #define MISSION_SYSTEM_PAYLOADSUBSYSTEM_H_ - - - - #endif /* MISSION_SYSTEM_PAYLOADSUBSYSTEM_H_ */ diff --git a/mission/system/TcsSubsystem.h b/mission/system/TcsSubsystem.h index 536fedce..51be6b2f 100644 --- a/mission/system/TcsSubsystem.h +++ b/mission/system/TcsSubsystem.h @@ -1,8 +1,4 @@ #ifndef MISSION_SYSTEM_TCSSUBSYSTEM_H_ #define MISSION_SYSTEM_TCSSUBSYSTEM_H_ - - - - #endif /* MISSION_SYSTEM_TCSSUBSYSTEM_H_ */ diff --git a/mission/utility/ProgressPrinter.cpp b/mission/utility/ProgressPrinter.cpp index c3a8e3f6..16a0f148 100644 --- a/mission/utility/ProgressPrinter.cpp +++ b/mission/utility/ProgressPrinter.cpp @@ -1,11 +1,11 @@ #include "ProgressPrinter.h" + #include "fsfw/serviceinterface/ServiceInterfaceStream.h" ProgressPrinter::ProgressPrinter(std::string name, uint32_t numSteps) : name(name), numSteps(numSteps) {} -ProgressPrinter::~ProgressPrinter() { -} +ProgressPrinter::~ProgressPrinter() {} void ProgressPrinter::print(uint32_t currentStep) { float progressInPercent = static_cast(currentStep) / static_cast(numSteps) * 100; From 5255e7d2ed169f8d85898614f51ce59fc6341f0e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 10:12:59 +0100 Subject: [PATCH 03/72] finished ACS board ASS --- linux/devices/GPSHyperionLinuxController.cpp | 15 ++ linux/devices/GPSHyperionLinuxController.h | 3 + mission/system/AcsBoardAssembly.cpp | 136 +++++++++++-------- mission/system/AcsBoardAssembly.h | 2 +- 4 files changed, 101 insertions(+), 55 deletions(-) diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GPSHyperionLinuxController.cpp index fa1f8f02..63050791 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GPSHyperionLinuxController.cpp @@ -28,6 +28,14 @@ LocalPoolDataSetBase *GPSHyperionLinuxController::getDataSetHandle(sid_t sid) { ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) { + if(not modeCommanded) { + if(mode == MODE_ON or mode == MODE_OFF) { + // 10 minutes time to reach fix + *msToReachTheMode = 600000; + maxTimeToReachFix.resetTimer(); + modeCommanded = true; + } + } return HasReturnvaluesIF::RETURN_OK; } @@ -114,6 +122,13 @@ void GPSHyperionLinuxController::readGpsDataFromGpsd() { // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix gpsSet.fixMode.value = gps->fix.mode; if (gps->fix.mode == 0 or gps->fix.mode == 1) { + if(modeCommanded and maxTimeToReachFix.hasTimedOut()) { + // We are supposed to be on and functioning, but not fix was found + if(mode == MODE_ON or mode == MODE_NORMAL) { + mode = MODE_OFF; + } + modeCommanded = false; + } gpsSet.setValidity(false, true); } else if (gps->satellites_used > 0) { gpsSet.setValidity(true, true); diff --git a/linux/devices/GPSHyperionLinuxController.h b/linux/devices/GPSHyperionLinuxController.h index 3615cebd..b8ab028d 100644 --- a/linux/devices/GPSHyperionLinuxController.h +++ b/linux/devices/GPSHyperionLinuxController.h @@ -21,6 +21,7 @@ */ class GPSHyperionLinuxController : public ExtendedControllerBase { public: + static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 600; GPSHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool debugHyperionGps = false); virtual ~GPSHyperionLinuxController(); @@ -46,6 +47,8 @@ class GPSHyperionLinuxController : public ExtendedControllerBase { private: GpsPrimaryDataset gpsSet; + Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000); + bool modeCommanded = true; gpsmm myGpsmm; bool debugHyperionGps = false; diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index b3ef24c6..49190470 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -38,11 +38,32 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode; helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode; helper.gpsMode = childrenMap[helper.gpsId].mode; - if (mode == DeviceHandlerIF::MODE_NORMAL) { - handleNormalModeCmd(submode); - } else if (mode == MODE_ON) { - } else { + if (state == States::MODE_COMMANDING) { + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + powerStateMachine(submode); + handleNormalOrOnModeCmd(mode, submode); + } else { + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); + } } + HybridIterator tableIter(modeTable.begin(), modeTable.end()); executeTable(tableIter); return result; @@ -116,12 +137,11 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { return false; } -ReturnValue_t AcsBoardAssembly::handleNormalModeCmd(Submode_t submode) { +ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; Mode_t tgtMode = DeviceHandlerIF::MODE_NORMAL; - powerStateMachine(submode); - if (state == States::MODE_COMMANDING) { - auto cmdSeq = [&](object_id_t objectId, ModeTableIdx tableIdx) { + auto cmdSeq = [&](object_id_t objectId, ModeTableIdx tableIdx) { + if(tgtMode == DeviceHandlerIF::MODE_NORMAL) { if (isUseable(objectId, mode)) { if (helper.gyro0SideAMode != MODE_OFF) { modeTable[tableIdx].setMode(tgtMode); @@ -132,53 +152,61 @@ ReturnValue_t AcsBoardAssembly::handleNormalModeCmd(Submode_t submode) { modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } - }; - switch (submode) { - case (A_SIDE): { - cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); - cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); - cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); - cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); - modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); - return result; - } - case (B_SIDE): { - cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); - cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); - cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); - cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); - modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); - return result; - } - case (DUAL_MODE): { - cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); - cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); - cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); - cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); - cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); - cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); - cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); - cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); - return result; - } - default: { - sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl; + } else if(tgtMode == MODE_ON) { + if (isUseable(objectId, mode)) { + modeTable[tableIdx].setMode(MODE_ON); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } + }; + switch (submode) { + case (A_SIDE): { + cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); + cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); + cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); + cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); + cmdSeq(helper.gpsId, ModeTableIdx::GPS); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + return result; + } + case (B_SIDE): { + cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); + cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); + cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); + cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); + cmdSeq(helper.gpsId, ModeTableIdx::GPS); + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + return result; + } + case (DUAL_MODE): { + cmdSeq(helper.gpsId, ModeTableIdx::GPS); + cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); + cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); + cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); + cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); + cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); + cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); + cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); + cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); + return result; + } + default: { + sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl; + } } return result; } @@ -244,6 +272,6 @@ void AcsBoardAssembly::powerStateMachine(Submode_t submode) { state = States::SWITCHING_POWER; } if (state == States::SWITCHING_POWER) { - // TODO: Could check for a timeout (temporal or cycles) here and resent command + // TODO: Could check for a timeout (temporal or cycles) here and resend command } } diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 6ff63dd5..63136393 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -91,7 +91,7 @@ class AcsBoardAssembly : public AssemblyBase { * @return */ bool isUseable(object_id_t object, Mode_t mode); - ReturnValue_t handleNormalModeCmd(Submode_t submode); + ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); void powerStateMachine(Submode_t submode); }; From c7183b730eaec7371fc2c72ce8aa0341d79ac130 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 10:28:55 +0100 Subject: [PATCH 04/72] check children state on implementation --- mission/system/AcsBoardAssembly.cpp | 161 +++++++++++++++++----------- mission/system/AcsBoardAssembly.h | 1 + 2 files changed, 97 insertions(+), 65 deletions(-) diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 49190470..15332901 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -29,15 +29,7 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) if (currentMode == mode and submode == currentSubmode) { return result; } - helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; - helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; - helper.gyro2SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; - helper.gyro3SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; - helper.mgm0SideAMode = childrenMap[helper.mgm0Lis3IdSideA].mode; - helper.mgm1SideAMode = childrenMap[helper.mgm1Rm3100IdSideA].mode; - helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode; - helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode; - helper.gpsMode = childrenMap[helper.gpsId].mode; + refreshHelperModes(); if (state == States::MODE_COMMANDING) { if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { powerStateMachine(submode); @@ -70,45 +62,34 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) } ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + refreshHelperModes(); + if(wantedSubmode == A_SIDE) { + if((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or + (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or + helper.gpsMode != wantedMode) { + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + return RETURN_OK; + } else if (wantedSubmode == B_SIDE) { + if((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or + (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or + helper.gpsMode != wantedMode) { + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + return RETURN_OK; + } else if(wantedSubmode == DUAL_MODE) { + if((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and + helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or + (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and + helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or + helper.gpsMode != wantedMode) { + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + return RETURN_OK; + } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t AcsBoardAssembly::initialize() { - ReturnValue_t result = registerChild(helper.gyro0AdisIdSideA); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.gyro1L3gIdSideA); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.gyro2AdisIdSideB); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.gyro3L3gIdSideB); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.mgm0Lis3IdSideA); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.mgm1Rm3100IdSideA); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.mgm2Lis3IdSideB); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = registerChild(helper.mgm3Rm3100IdSideB); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - return result; -} - void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { modeTable.insert(entry); entry.setObject(id); @@ -117,26 +98,6 @@ void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) entry.setInheritSubmode(false); } -ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - return HasReturnvaluesIF::RETURN_OK; -} - -bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { - if (healthHelper.healthTable->isFaulty(object)) { - return false; - } - - // Check if device is already in target mode - if (childrenMap[object].mode == mode) { - return true; - } - - if (healthHelper.healthTable->isCommandable(object)) { - return true; - } - return false; -} - ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; Mode_t tgtMode = DeviceHandlerIF::MODE_NORMAL; @@ -275,3 +236,73 @@ void AcsBoardAssembly::powerStateMachine(Submode_t submode) { // TODO: Could check for a timeout (temporal or cycles) here and resend command } } + +ReturnValue_t AcsBoardAssembly::initialize() { + ReturnValue_t result = registerChild(helper.gyro0AdisIdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.gyro1L3gIdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.gyro2AdisIdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.gyro3L3gIdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm0Lis3IdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm1Rm3100IdSideA); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm2Lis3IdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = registerChild(helper.mgm3Rm3100IdSideB); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return result; +} + +ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if(submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +void AcsBoardAssembly::refreshHelperModes() { + helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; + helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; + helper.gyro2SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; + helper.gyro3SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; + helper.mgm0SideAMode = childrenMap[helper.mgm0Lis3IdSideA].mode; + helper.mgm1SideAMode = childrenMap[helper.mgm1Rm3100IdSideA].mode; + helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode; + helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode; +} diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 63136393..c1e2a29e 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -93,6 +93,7 @@ class AcsBoardAssembly : public AssemblyBase { bool isUseable(object_id_t object, Mode_t mode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); void powerStateMachine(Submode_t submode); + void refreshHelperModes(); }; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ From 1586c3e69a8668049558ddf6deaf3f9a276a850a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 13:43:52 +0100 Subject: [PATCH 05/72] submodule update --- fsfw | 2 +- tmtc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 0ccaf27f..75c56280 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 0ccaf27fcb0e7a0f2dd1ca7175a7051a0267c8ec +Subproject commit 75c56280ad139640d2c12ac4ab78ce66c25fb495 diff --git a/tmtc b/tmtc index 54b319a4..37c1a68d 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 54b319a48757cdae2ed7b89f3af3e29500c31588 +Subproject commit 37c1a68da1b465514e84403b06ce40d035e4ad88 From ff0da65662bf25fd89609ebbe5850eaacde678cc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 15:37:36 +0100 Subject: [PATCH 06/72] started SUS assembly fixes for PCDU code and switcher list handling --- .../fsfwconfig/devices/powerSwitcherList.h | 57 ------ bsp_q7s/core/ObjectFactory.cpp | 6 +- common/config/devices/powerSwitcherList.h | 90 +++++---- linux/devices/GPSHyperionLinuxController.cpp | 8 +- linux/fsfwconfig/devices/powerSwitcherList.h | 57 ------ mission/devices/PCDUHandler.cpp | 128 +++++++----- mission/system/AcsBoardAssembly.cpp | 185 ++++++++++-------- mission/system/AcsBoardAssembly.h | 42 ++-- mission/system/CMakeLists.txt | 1 + mission/system/SusAssembly.cpp | 101 ++++++++++ mission/system/SusAssembly.h | 52 +++++ 11 files changed, 418 insertions(+), 309 deletions(-) delete mode 100644 bsp_hosted/fsfwconfig/devices/powerSwitcherList.h delete mode 100644 linux/fsfwconfig/devices/powerSwitcherList.h create mode 100644 mission/system/SusAssembly.cpp create mode 100644 mission/system/SusAssembly.h diff --git a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h b/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index ae259374..00000000 --- a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ -#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ - -#include - -namespace pcduSwitches { -/* Switches are uint8_t datatype and go from 0 to 255 */ -enum SwitcherList { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES -}; - -static const uint8_t ON = 1; -static const uint8_t OFF = 0; - -/* Output states after reboot of the PDUs */ -static const uint8_t INIT_STATE_Q7S = ON; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; -static const uint8_t INIT_STATE_RW = OFF; -#if BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; -#else -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; -#endif -static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; -static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; -static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} // namespace pcduSwitches - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index bcf5a50f..b4d92b23 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -737,7 +737,7 @@ void ObjectFactory::createHeaterComponents() { heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, - objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); + objects::PCDU_HANDLER, pcduSwitches::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } void ObjectFactory::createSolarArrayDeploymentComponents() { @@ -757,8 +757,8 @@ void ObjectFactory::createSolarArrayDeploymentComponents() { // TODO: Find out burn time. For now set to 1000 ms. new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, solarArrayDeplCookie, objects::PCDU_HANDLER, - pcduSwitches::DEPLOYMENT_MECHANISM, gpioIds::DEPLSA1, - gpioIds::DEPLSA2, 1000); + pcduSwitches::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); } void ObjectFactory::createSyrlinksComponents() { diff --git a/common/config/devices/powerSwitcherList.h b/common/config/devices/powerSwitcherList.h index 45428a2e..a9a75ce4 100644 --- a/common/config/devices/powerSwitcherList.h +++ b/common/config/devices/powerSwitcherList.h @@ -6,54 +6,58 @@ #include namespace pcduSwitches { - /* Switches are uint8_t datatype and go from 0 to 255 */ - enum SwitcherList: uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES - }; +/* Switches are uint8_t datatype and go from 0 to 255 */ +enum Switches: uint8_t { + PDU1_CH0_TCS_BOARD_3V3, + PDU1_CH1_SYRLINKS_12V, + PDU1_CH2_STAR_TRACKER_5V, + PDU1_CH3_MGT_5V, + PDU1_CH4_SUS_NOMINAL_3V3, + PDU1_CH5_SOLAR_CELL_EXP_5V, + PDU1_CH6_PLOC_12V, + PDU1_CH7_ACS_A_SIDE_3V3, + PDU1_CH8_UNOCCUPIED, - static const uint8_t ON = 1; - static const uint8_t OFF = 0; + PDU2_CH0_Q7S, + PDU2_CH1_PL_PCDU_BATT_0_14V8, + PDU2_CH2_RW_5V, + PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + PDU2_CH4_SUS_REDUNDANT_3V3, + PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + PDU2_CH6_PL_PCDU_BATT_1_14V8, + PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + PDU2_CH8_PAYLOAD_CAMERA, + NUMBER_OF_SWITCHES +}; - /* Output states after reboot of the PDUs */ - static const uint8_t INIT_STATE_Q7S = ON; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; - static const uint8_t INIT_STATE_RW = OFF; +static const uint8_t ON = 1; +static const uint8_t OFF = 0; + +/* Output states after reboot of the PDUs */ #if BOARD_TE0720 == 1 - /* Because the TE0720 is not connected to the PCDU, this switch is always on */ - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; +/* Because the TE0720 is not connected to the PCDU, this switch is always on */ +static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; #else - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; +static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; #endif - static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; - static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; - static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; - static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; - static const uint8_t INIT_STATE_SYRLINKS = OFF; - static const uint8_t INIT_STATE_STAR_TRACKER = OFF; - static const uint8_t INIT_STATE_MGT = OFF; - static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; - static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; - static const uint8_t INIT_STATE_PLOC = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; +static const uint8_t INIT_STATE_SYRLINKS = OFF; +static const uint8_t INIT_STATE_STAR_TRACKER = OFF; +static const uint8_t INIT_STATE_MGT = OFF; +static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; +static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; +static const uint8_t INIT_STATE_PLOC = OFF; +static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; + +static const uint8_t INIT_STATE_Q7S = ON; +static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; +static const uint8_t INIT_STATE_RW = OFF; +static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; +static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; +static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; +static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; +static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; +static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; + } diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GPSHyperionLinuxController.cpp index 63050791..d5b2741e 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GPSHyperionLinuxController.cpp @@ -28,8 +28,8 @@ LocalPoolDataSetBase *GPSHyperionLinuxController::getDataSetHandle(sid_t sid) { ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) { - if(not modeCommanded) { - if(mode == MODE_ON or mode == MODE_OFF) { + if (not modeCommanded) { + if (mode == MODE_ON or mode == MODE_OFF) { // 10 minutes time to reach fix *msToReachTheMode = 600000; maxTimeToReachFix.resetTimer(); @@ -122,9 +122,9 @@ void GPSHyperionLinuxController::readGpsDataFromGpsd() { // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix gpsSet.fixMode.value = gps->fix.mode; if (gps->fix.mode == 0 or gps->fix.mode == 1) { - if(modeCommanded and maxTimeToReachFix.hasTimedOut()) { + if (modeCommanded and maxTimeToReachFix.hasTimedOut()) { // We are supposed to be on and functioning, but not fix was found - if(mode == MODE_ON or mode == MODE_NORMAL) { + if (mode == MODE_ON or mode == MODE_NORMAL) { mode = MODE_OFF; } modeCommanded = false; diff --git a/linux/fsfwconfig/devices/powerSwitcherList.h b/linux/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index cc6bc141..00000000 --- a/linux/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ -#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ - -#include "OBSWConfig.h" - -namespace pcduSwitches { -/* Switches are uint8_t datatype and go from 0 to 255 */ -enum SwitcherList : uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES -}; - -static const uint8_t ON = 1; -static const uint8_t OFF = 0; - -/* Output states after reboot of the PDUs */ -static const uint8_t INIT_STATE_Q7S = ON; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; -static const uint8_t INIT_STATE_RW = OFF; -#if BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; -#else -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; -#endif -static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; -static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; -static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} // namespace pcduSwitches - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 13bed074..9fc78c04 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -1,10 +1,11 @@ #include "PCDUHandler.h" #include +#include +#include #include #include #include -#include PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) : SystemObject(setObjectId), @@ -74,24 +75,26 @@ ReturnValue_t PCDUHandler::initialize() { } void PCDUHandler::initializeSwitchStates() { - switchStates[pcduSwitches::Q7S] = pcduSwitches::INIT_STATE_Q7S; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1; - switchStates[pcduSwitches::RW] = pcduSwitches::INIT_STATE_RW; - switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = + using namespace pcduSwitches; + switchStates[Switches::PDU2_CH0_Q7S] = pcduSwitches::INIT_STATE_Q7S; + switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1; + switchStates[Switches::PDU2_CH2_RW_5V] = pcduSwitches::INIT_STATE_RW; + switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] = pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN; - switchStates[pcduSwitches::SUS_REDUNDANT] = pcduSwitches::INIT_STATE_SUS_REDUNDANT; - switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6; - switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B; - switchStates[pcduSwitches::PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA; - switchStates[pcduSwitches::TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3; - switchStates[pcduSwitches::SYRLINKS] = pcduSwitches::INIT_STATE_SYRLINKS; - switchStates[pcduSwitches::STAR_TRACKER] = pcduSwitches::INIT_STATE_STAR_TRACKER; - switchStates[pcduSwitches::MGT] = pcduSwitches::INIT_STATE_MGT; - 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_BOARD_SIDE_A] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A; + switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = pcduSwitches::INIT_STATE_SUS_REDUNDANT; + switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] = + pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM; + switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6; + switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B; + switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA; + switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3; + switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pcduSwitches::INIT_STATE_SYRLINKS; + switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = pcduSwitches::INIT_STATE_STAR_TRACKER; + switchStates[Switches::PDU1_CH3_MGT_5V] = pcduSwitches::INIT_STATE_MGT; + switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = pcduSwitches::INIT_STATE_SUS_NOMINAL; + switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP; + switchStates[Switches::PDU1_CH6_PLOC_12V] = pcduSwitches::INIT_STATE_PLOC; + switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A; } void PCDUHandler::readCommandQueue() { @@ -152,36 +155,48 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet } void PCDUHandler::updatePdu2SwitchStates() { - // TODO: pool read helper - if (pdu2HkTableDataset.read() == RETURN_OK) { - switchStates[pcduSwitches::Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pdu2HkTableDataset.outEnabledPlPCDUCh1.value; - switchStates[pcduSwitches::RW] = pdu2HkTableDataset.outEnabledReactionWheels.value; - switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = + using namespace pcduSwitches; + PoolReadGuard rf(&pdu2HkTableDataset); + if (rf.getReadResult() == RETURN_OK) { + switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; + switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] = + pdu2HkTableDataset.outEnabledPlPCDUCh1.value; + switchStates[Switches::PDU2_CH2_RW_5V] = pdu2HkTableDataset.outEnabledReactionWheels.value; + switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] = pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value; - switchStates[pcduSwitches::SUS_REDUNDANT] = pdu2HkTableDataset.outEnabledSUSRedundant.value; - switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = + switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = + pdu2HkTableDataset.outEnabledSUSRedundant.value; + switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] = pdu2HkTableDataset.outEnabledDeplMechanism.value; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pdu2HkTableDataset.outEnabledPlPCDUCh6.value; - switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pdu2HkTableDataset.outEnabledAcsBoardSideB.value; - switchStates[pcduSwitches::PAYLOAD_CAMERA] = pdu2HkTableDataset.outEnabledPayloadCamera.value; + switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = + pdu2HkTableDataset.outEnabledPlPCDUCh6.value; + switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = + pdu2HkTableDataset.outEnabledAcsBoardSideB.value; + switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = + pdu2HkTableDataset.outEnabledPayloadCamera.value; } else { sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" << std::endl; } - pdu2HkTableDataset.commit(); } void PCDUHandler::updatePdu1SwitchStates() { if (pdu1HkTableDataset.read() == RETURN_OK) { - switchStates[pcduSwitches::TCS_BOARD_3V3] = pdu1HkTableDataset.voltageOutTCSBoard3V3.value; - switchStates[pcduSwitches::SYRLINKS] = pdu1HkTableDataset.voltageOutSyrlinks.value; - switchStates[pcduSwitches::STAR_TRACKER] = pdu1HkTableDataset.voltageOutStarTracker.value; - switchStates[pcduSwitches::MGT] = pdu1HkTableDataset.voltageOutMGT.value; - switchStates[pcduSwitches::SUS_NOMINAL] = pdu1HkTableDataset.voltageOutSUSNominal.value; - switchStates[pcduSwitches::SOLAR_CELL_EXP] = pdu1HkTableDataset.voltageOutSolarCellExp.value; - switchStates[pcduSwitches::PLOC] = pdu1HkTableDataset.voltageOutPLOC.value; - switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pdu1HkTableDataset.voltageOutACSBoardSideA.value; + using namespace pcduSwitches; + PoolReadGuard rf(&pdu1HkTableDataset); + switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value; + switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value; + switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = + pdu1HkTableDataset.outEnabledStarTracker.value; + switchStates[Switches::PDU1_CH3_MGT_5V] = pdu1HkTableDataset.outEnabledMGT.value; + switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = + pdu1HkTableDataset.outEnabledSUSNominal.value; + switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = + pdu1HkTableDataset.outEnabledSolarCellExp.value; + switchStates[Switches::PDU1_CH6_PLOC_12V] = pdu1HkTableDataset.outEnabledPLOC.value; + switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = + pdu1HkTableDataset.outEnabledAcsBoardSideA.value; + switchStates[Switches::PDU1_CH8_UNOCCUPIED] = pdu1HkTableDataset.outEnabledChannel8.value; } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; } @@ -191,24 +206,49 @@ void PCDUHandler::updatePdu1SwitchStates() { LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; } void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const { + using namespace pcduSwitches; ReturnValue_t result; - uint16_t memoryAddress; + uint16_t memoryAddress = 0; size_t parameterValueSize = sizeof(uint8_t); - uint8_t parameterValue; - GomspaceDeviceHandler* pdu; + uint8_t parameterValue = 0; + GomspaceDeviceHandler* pdu = nullptr; switch (switchNr) { - case pcduSwitches::TCS_BOARD_8V_HEATER_IN: + case pcduSwitches::PDU1_CH0_TCS_BOARD_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH1_SYRLINKS_12V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SYRLINKS; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH2_STAR_TRACKER_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_STAR_TRACKER; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH3_MGT_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_MGT; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; - case pcduSwitches::DEPLOYMENT_MECHANISM: + } + case pcduSwitches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; - default: + } + + default: { sif::error << "PCDUHandler::sendSwitchCommand: Invalid switch number " << std::endl; return; + } } switch (onOff) { diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 15332901..3d695d8e 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -1,12 +1,11 @@ #include "AcsBoardAssembly.h" -#include #include #include AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, AcsBoardHelper helper) - : AssemblyBase(objectId, parentId), switcher(switcher), helper(helper) { + : AssemblyBase(objectId, parentId), pwrSwitcher(switcher), helper(helper) { if (switcher == nullptr) { sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid Power Switcher " "IF passed" @@ -26,34 +25,31 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; - if (currentMode == mode and submode == currentSubmode) { - return result; - } refreshHelperModes(); - if (state == States::MODE_COMMANDING) { - if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { - powerStateMachine(submode); + powerStateMachine(mode, submode); + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + if (state == States::MODE_COMMANDING) { handleNormalOrOnModeCmd(mode, submode); - } else { - modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } + } else { + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } HybridIterator tableIter(modeTable.begin(), modeTable.end()); @@ -63,25 +59,25 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { refreshHelperModes(); - if(wantedSubmode == A_SIDE) { - if((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or + if (wantedSubmode == A_SIDE) { + if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or helper.gpsMode != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; } else if (wantedSubmode == B_SIDE) { - if((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or + if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; - } else if(wantedSubmode == DUAL_MODE) { - if((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and - helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or + } else if (wantedSubmode == DUAL_MODE) { + if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and + helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and - helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or + helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } @@ -102,7 +98,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s ReturnValue_t result = RETURN_OK; Mode_t tgtMode = DeviceHandlerIF::MODE_NORMAL; auto cmdSeq = [&](object_id_t objectId, ModeTableIdx tableIdx) { - if(tgtMode == DeviceHandlerIF::MODE_NORMAL) { + if (tgtMode == DeviceHandlerIF::MODE_NORMAL) { if (isUseable(objectId, mode)) { if (helper.gyro0SideAMode != MODE_OFF) { modeTable[tableIdx].setMode(tgtMode); @@ -113,7 +109,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } - } else if(tgtMode == MODE_ON) { + } else if (tgtMode == MODE_ON) { if (isUseable(objectId, mode)) { modeTable[tableIdx].setMode(MODE_ON); modeTable[tableIdx].setSubmode(SUBMODE_NONE); @@ -172,62 +168,82 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s return result; } -void AcsBoardAssembly::powerStateMachine(Submode_t submode) { - ReturnValue_t switchStateA = switcher->getSwitchState(pcduSwitches::ACS_BOARD_SIDE_A); - ReturnValue_t switchStateB = switcher->getSwitchState(pcduSwitches::ACS_BOARD_SIDE_B); - switch (submode) { - case (A_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { +void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { + ReturnValue_t switchStateA = RETURN_OK; + ReturnValue_t switchStateB = RETURN_OK; + if (state == States::IDLE or state == States::SWITCHING_POWER) { + switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); + switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); + if (mode == MODE_OFF) { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { state = States::MODE_COMMANDING; return; } - break; - } - case (B_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } - break; - } - case (DUAL_MODE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and + switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (B_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and + switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (DUAL_MODE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and + switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + } } } } if (state == States::IDLE) { - switch (submode) { - case (A_SIDE): { - if (switchStateA != PowerSwitchIF::SWITCH_ON) { - // Set A side on first in power switcher IF - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, true); - } - if (switchStateB != PowerSwitchIF::SWITCH_OFF) { - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, false); - } - break; + if (mode == MODE_OFF) { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, false); } - case (B_SIDE): { - if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - // Set A side on first in power switcher IF - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, false); - } - if (switchStateB != PowerSwitchIF::SWITCH_ON) { - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, true); - } - break; + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, false); } - case (DUAL_MODE): { - if (switchStateA != PowerSwitchIF::SWITCH_ON) { - // Set A side on first in power switcher IF - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, true); + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, true); + } + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, false); + } + break; } - if (switchStateB != PowerSwitchIF::SWITCH_ON) { - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, true); + case (B_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, false); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, true); + } + break; + } + case (DUAL_MODE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, true); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, true); + } + break; } - break; } } state = States::SWITCHING_POWER; @@ -274,7 +290,7 @@ ReturnValue_t AcsBoardAssembly::initialize() { } ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - if(submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { + if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -296,6 +312,11 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { return false; } +void AcsBoardAssembly::handleModeReached() { + AssemblyBase::handleModeReached(); + state = States::IDLE; +} + void AcsBoardAssembly::refreshHelperModes() { helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index c1e2a29e..4116f6c9 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -1,6 +1,7 @@ #ifndef MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ #define MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ +#include #include #include @@ -52,37 +53,40 @@ enum ModeTableIdx : uint8_t { GPS = 8 }; -static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; - class PowerSwitchIF; class AcsBoardAssembly : public AssemblyBase { public: - AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, - AcsBoardHelper helper); - - private: - enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING }; - - States state = States::IDLE; - Mode_t currentMode = MODE_OFF; - Submode_t currentSubmode = A_SIDE; - PowerSwitchIF* switcher = nullptr; - - AcsBoardHelper helper; - void initModeTableEntry(object_id_t id, ModeListEntry& entry); - - ReturnValue_t initialize() override; - FixedArrayList modeTable; + static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; static constexpr Submode_t A_SIDE = 0; static constexpr Submode_t B_SIDE = 1; static constexpr Submode_t DUAL_MODE = 2; + AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + AcsBoardHelper helper); + + private: + static constexpr pcduSwitches::Switches SWITCH_A = + pcduSwitches::Switches::PDU1_CH7_ACS_A_SIDE_3V3; + static constexpr pcduSwitches::Switches SWITCH_B = + pcduSwitches::Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3; + + enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; + + PowerSwitchIF* pwrSwitcher = nullptr; + + AcsBoardHelper helper; + FixedArrayList modeTable; + void initModeTableEntry(object_id_t id, ModeListEntry& entry); + + ReturnValue_t initialize() override; + // AssemblyBase overrides ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + void handleModeReached() override; /** * Check whether it makes sense to send mode commands to the device @@ -92,7 +96,7 @@ class AcsBoardAssembly : public AssemblyBase { */ bool isUseable(object_id_t object, Mode_t mode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); - void powerStateMachine(Submode_t submode); + void powerStateMachine(Mode_t mode, Submode_t submode); void refreshHelperModes(); }; diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt index 880055e4..6296de1e 100644 --- a/mission/system/CMakeLists.txt +++ b/mission/system/CMakeLists.txt @@ -1,5 +1,6 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE AcsBoardAssembly.cpp + SusAssembly.cpp AcsSubsystem.cpp TcsSubsystem.cpp EiveSystem.cpp diff --git a/mission/system/SusAssembly.cpp b/mission/system/SusAssembly.cpp new file mode 100644 index 00000000..21e5aa50 --- /dev/null +++ b/mission/system/SusAssembly.cpp @@ -0,0 +1,101 @@ +#include "SusAssembly.h" + +#include +#include +#include + +SusAssembly::SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + SusAssHelper helper) + : AssemblyBase(objectId, parentId), helper(helper), pwrSwitcher(pwrSwitcher) {} + +ReturnValue_t SusAssembly::commandChildren(Mode_t mode, Submode_t submode) { + ReturnValue_t result = RETURN_OK; + refreshHelperModes(); + return RETURN_OK; +} + +ReturnValue_t SusAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + return RETURN_OK; +} + +ReturnValue_t SusAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if (submode != NOMINAL and submode != REDUNDANT and submode != DUAL_MODE) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SusAssembly::initialize() { + ReturnValue_t result = RETURN_OK; + for (const auto& id : helper.susIds) { + result = registerChild(id); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; +} + +bool SusAssembly::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +void SusAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { + ReturnValue_t switchStateNom = RETURN_OK; + ReturnValue_t switchStateRed = RETURN_OK; + if (state == States::IDLE or state == States::SWITCHING_POWER) { + switchStateNom = pwrSwitcher->getSwitchState(pcduSwitches::PDU1_CH4_SUS_NOMINAL_3V3); + switchStateRed = pwrSwitcher->getSwitchState(pcduSwitches::PDU2_CH4_SUS_REDUNDANT_3V3); + if (mode == MODE_OFF) { + if (switchStateNom == PowerSwitchIF::SWITCH_OFF and + switchStateRed == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + } else { + switch (submode) { + case (NOMINAL): { + if (switchStateNom == PowerSwitchIF::SWITCH_ON and + switchStateRed == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (REDUNDANT): { + if (switchStateNom == PowerSwitchIF::SWITCH_OFF and + switchStateRed == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (DUAL_MODE): { + if (switchStateNom == PowerSwitchIF::SWITCH_ON and + switchStateRed == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + } + } + } + } +} + +void SusAssembly::refreshHelperModes() { + for (uint8_t idx = 0; idx < helper.susModes.size(); idx++) { + helper.susModes[idx] = childrenMap[helper.susIds[idx]].mode; + } +} diff --git a/mission/system/SusAssembly.h b/mission/system/SusAssembly.h new file mode 100644 index 00000000..c09384fb --- /dev/null +++ b/mission/system/SusAssembly.h @@ -0,0 +1,52 @@ +#ifndef MISSION_SYSTEM_SUSASSEMBLY_H_ +#define MISSION_SYSTEM_SUSASSEMBLY_H_ + +#include + +struct SusAssHelper { + public: + SusAssHelper(std::array susIds) : susIds(susIds) {} + std::array susIds = {objects::NO_OBJECT}; + std::array susModes = {HasModesIF::MODE_OFF}; +}; + +class PowerSwitchIF; + +class SusAssembly : AssemblyBase { + public: + static constexpr uint8_t NUMBER_SUN_SENSORS = 12; + + static constexpr Submode_t NOMINAL = 0; + static constexpr Submode_t REDUNDANT = 1; + static constexpr Submode_t DUAL_MODE = 2; + + SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + SusAssHelper helper); + + private: + enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; + + FixedArrayList modeTable; + + SusAssHelper helper; + PowerSwitchIF* pwrSwitcher = nullptr; + + ReturnValue_t initialize() override; + + // AssemblyBase overrides + ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; + ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + + /** + * Check whether it makes sense to send mode commands to the device + * @param object + * @param mode + * @return + */ + bool isUseable(object_id_t object, Mode_t mode); + void powerStateMachine(Mode_t mode, Submode_t submode); + void refreshHelperModes(); +}; + +#endif /* MISSION_SYSTEM_SUSASSEMBLY_H_ */ From 261b4a808d8e62ce128ebc4529b8f02cc8471ab4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 15:43:21 +0100 Subject: [PATCH 07/72] completed switcher switch case --- mission/devices/PCDUHandler.cpp | 61 +++++++++++++++++++ mission/devices/PDU2Handler.cpp | 2 +- .../devicedefinitions/GomspaceDefinitions.h | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 9fc78c04..1553afe8 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -234,16 +234,77 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); break; } + case pcduSwitches::PDU1_CH4_SUS_NOMINAL_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH5_SOLAR_CELL_EXP_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH6_PLOC_12V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_PLOC; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH7_ACS_A_SIDE_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH8_UNOCCUPIED: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_CHANNEL8; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + // That does not really make sense but let's keep it here for completeness reasons.. + case pcduSwitches::PDU2_CH0_Q7S: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_Q7S; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH1_PL_PCDU_BATT_0_14V8: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH2_RW_5V: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_RW; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } case pcduSwitches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; } + case pcduSwitches::PDU2_CH4_SUS_REDUNDANT_3V3: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } case pcduSwitches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; } + case pcduSwitches::PDU2_CH6_PL_PCDU_BATT_1_14V8: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH8_PAYLOAD_CAMERA: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } default: { sif::error << "PCDUHandler::sendSwitchCommand: Invalid switch number " << std::endl; diff --git a/mission/devices/PDU2Handler.cpp b/mission/devices/PDU2Handler.cpp index 776cae58..5b394a91 100644 --- a/mission/devices/PDU2Handler.cpp +++ b/mission/devices/PDU2Handler.cpp @@ -460,7 +460,7 @@ ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs); break; } - case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC): { + case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6): { channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs); break; } diff --git a/mission/devices/devicedefinitions/GomspaceDefinitions.h b/mission/devices/devicedefinitions/GomspaceDefinitions.h index 995d9a7a..0b3b0a19 100644 --- a/mission/devices/devicedefinitions/GomspaceDefinitions.h +++ b/mission/devices/devicedefinitions/GomspaceDefinitions.h @@ -848,7 +848,7 @@ static const uint16_t CONFIG_ADDRESS_OUT_EN_RW = 0x4A; static const uint16_t CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN = 0x4B; static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT = 0x4C; static const uint16_t CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM = 0x4D; -static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC = 0x4E; +static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6 = 0x4E; static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B = 0x4F; static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA = 0x50; From a7c1dafce5df8ef9243e9101c4603ae06d4e7a27 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 19:39:36 +0100 Subject: [PATCH 08/72] added mutex protection for power switches --- mission/devices/PCDUHandler.cpp | 19 ++++-- mission/devices/PCDUHandler.h | 1 + mission/devices/RadiationSensorHandler.h | 3 +- mission/system/AcsBoardAssembly.cpp | 55 +++++++++-------- mission/system/SusAssembly.cpp | 79 +++++++++++++++--------- mission/system/SusAssembly.h | 6 +- tmtc | 2 +- unittest/mocks/EventManagerMock.h | 6 +- unittest/mocks/HouseKeepingMock.cpp | 1 - unittest/mocks/HouseKeepingMock.h | 3 +- 10 files changed, 104 insertions(+), 71 deletions(-) diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 1553afe8..244cc6db 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -15,6 +16,7 @@ PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) cmdQueueSize(cmdQueueSize) { commandQueue = QueueFactory::instance()->createMessageQueue( cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); + pwrMutex = MutexFactory::instance()->createMutex(); } PCDUHandler::~PCDUHandler() {} @@ -156,8 +158,9 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet void PCDUHandler::updatePdu2SwitchStates() { using namespace pcduSwitches; - PoolReadGuard rf(&pdu2HkTableDataset); - if (rf.getReadResult() == RETURN_OK) { + PoolReadGuard rg(&pdu2HkTableDataset); + if (rg.getReadResult() == RETURN_OK) { + MutexGuard mg(pwrMutex); switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] = pdu2HkTableDataset.outEnabledPlPCDUCh1.value; @@ -181,9 +184,10 @@ void PCDUHandler::updatePdu2SwitchStates() { } void PCDUHandler::updatePdu1SwitchStates() { - if (pdu1HkTableDataset.read() == RETURN_OK) { - using namespace pcduSwitches; - PoolReadGuard rf(&pdu1HkTableDataset); + using namespace pcduSwitches; + PoolReadGuard rg(&pdu1HkTableDataset); + if (rg.getReadResult() == RETURN_OK) { + MutexGuard mg(pwrMutex); switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value; switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value; switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = @@ -352,7 +356,10 @@ ReturnValue_t PCDUHandler::getSwitchState(uint8_t switchNr) const { sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl; return RETURN_FAILED; } - if (switchStates[switchNr] == 1) { + pwrMutex->lockMutex(); + uint8_t currentState = switchStates[switchNr]; + pwrMutex->unlockMutex(); + if (currentState == 1) { return PowerSwitchIF::SWITCH_ON; } else { return PowerSwitchIF::SWITCH_OFF; diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index c045ed03..126f486a 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -47,6 +47,7 @@ class PCDUHandler : public PowerSwitchIF, private: uint32_t pstIntervalMs = 0; + MutexIF* pwrMutex = nullptr; /** Housekeeping manager. Handles updates of local pool variables. */ LocalDataPoolManager poolManager; diff --git a/mission/devices/RadiationSensorHandler.h b/mission/devices/RadiationSensorHandler.h index cc5f4d4f..0061f296 100644 --- a/mission/devices/RadiationSensorHandler.h +++ b/mission/devices/RadiationSensorHandler.h @@ -2,9 +2,8 @@ #define MISSION_DEVICES_RADIATIONSENSORHANDLER_H_ #include -#include #include - +#include /** * @brief This is the device handler class for radiation sensor on the OBC IF Board. The diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 3d695d8e..1f6ffb98 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -174,35 +174,36 @@ void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { if (state == States::IDLE or state == States::SWITCHING_POWER) { switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); - if (mode == MODE_OFF) { - if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; + } else { + return; + } + if (mode == MODE_OFF) { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and + switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + break; } - } else { - switch (submode) { - case (A_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and - switchStateB == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; - } - break; + case (B_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and + switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; } - case (B_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_OFF and - switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } - break; - } - case (DUAL_MODE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and - switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } + break; + } + case (DUAL_MODE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; } } } diff --git a/mission/system/SusAssembly.cpp b/mission/system/SusAssembly.cpp index 21e5aa50..f34665d4 100644 --- a/mission/system/SusAssembly.cpp +++ b/mission/system/SusAssembly.cpp @@ -56,40 +56,61 @@ void SusAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { ReturnValue_t switchStateNom = RETURN_OK; ReturnValue_t switchStateRed = RETURN_OK; if (state == States::IDLE or state == States::SWITCHING_POWER) { - switchStateNom = pwrSwitcher->getSwitchState(pcduSwitches::PDU1_CH4_SUS_NOMINAL_3V3); - switchStateRed = pwrSwitcher->getSwitchState(pcduSwitches::PDU2_CH4_SUS_REDUNDANT_3V3); - if (mode == MODE_OFF) { - if (switchStateNom == PowerSwitchIF::SWITCH_OFF and - switchStateRed == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; - } - } else { - switch (submode) { - case (NOMINAL): { - if (switchStateNom == PowerSwitchIF::SWITCH_ON and - switchStateRed == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; - } - break; + switchStateNom = pwrSwitcher->getSwitchState(SWITCH_NOM); + switchStateRed = pwrSwitcher->getSwitchState(SWITCH_RED); + } else { + return; + } + if (mode == MODE_OFF) { + if (switchStateNom == PowerSwitchIF::SWITCH_OFF and + switchStateRed == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + } else { + if (state == States::IDLE) { + if (mode == MODE_OFF) { + if (switchStateNom != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_NOM, false); } - case (REDUNDANT): { - if (switchStateNom == PowerSwitchIF::SWITCH_OFF and - switchStateRed == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } - break; + if (switchStateRed != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_RED, false); } - case (DUAL_MODE): { - if (switchStateNom == PowerSwitchIF::SWITCH_ON and - switchStateRed == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; + } else { + switch (submode) { + case (NOMINAL): { + if (switchStateNom != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true); + } + if (switchStateRed != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_RED, false); + } + break; + } + case (REDUNDANT): { + if (switchStateRed != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_RED, false); + } + if (switchStateNom != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true); + } + break; + } + case (DUAL_MODE): { + if (switchStateNom != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true); + } + if (switchStateRed != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_RED, true); + } + break; } } } + state = States::SWITCHING_POWER; + } + if (state == States::SWITCHING_POWER) { + // TODO: Could check for a timeout (temporal or cycles) here and resend command } } } diff --git a/mission/system/SusAssembly.h b/mission/system/SusAssembly.h index c09384fb..c7acdd87 100644 --- a/mission/system/SusAssembly.h +++ b/mission/system/SusAssembly.h @@ -1,6 +1,7 @@ #ifndef MISSION_SYSTEM_SUSASSEMBLY_H_ #define MISSION_SYSTEM_SUSASSEMBLY_H_ +#include #include struct SusAssHelper { @@ -25,7 +26,10 @@ class SusAssembly : AssemblyBase { private: enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; - + static constexpr pcduSwitches::Switches SWITCH_NOM = + pcduSwitches::Switches::PDU1_CH4_SUS_NOMINAL_3V3; + static constexpr pcduSwitches::Switches SWITCH_RED = + pcduSwitches::Switches::PDU2_CH4_SUS_REDUNDANT_3V3; FixedArrayList modeTable; SusAssHelper helper; diff --git a/tmtc b/tmtc index 37c1a68d..07601b73 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 37c1a68da1b465514e84403b06ce40d035e4ad88 +Subproject commit 07601b734eec162771251e8e5f5fae16d20f1655 diff --git a/unittest/mocks/EventManagerMock.h b/unittest/mocks/EventManagerMock.h index 84588a97..8e471b59 100644 --- a/unittest/mocks/EventManagerMock.h +++ b/unittest/mocks/EventManagerMock.h @@ -15,10 +15,12 @@ class EventManagerMock : public EventManager { void clearEventList(); bool isEventInEventList(object_id_t object, Event event); - bool isEventInEventList(object_id_t object, Event event, uint32_t parameter1, uint32_t parameter2); + bool isEventInEventList(object_id_t object, Event event, uint32_t parameter1, + uint32_t parameter2); bool isEventInEventList(object_id_t object, EventId_t eventId); - bool isEventInEventList(object_id_t object, EventId_t eventId, uint32_t parameter1, uint32_t parameter2); + bool isEventInEventList(object_id_t object, EventId_t eventId, uint32_t parameter1, + uint32_t parameter2); private: std::list eventList; diff --git a/unittest/mocks/HouseKeepingMock.cpp b/unittest/mocks/HouseKeepingMock.cpp index d2592c93..d6588b1b 100644 --- a/unittest/mocks/HouseKeepingMock.cpp +++ b/unittest/mocks/HouseKeepingMock.cpp @@ -2,7 +2,6 @@ #include - HouseKeepingMock::HouseKeepingMock() : SystemObject(objects::PUS_SERVICE_3_HOUSEKEEPING) {} MessageQueueId_t HouseKeepingMock::getHkQueue() const { return MessageQueueIF::NO_QUEUE; } \ No newline at end of file diff --git a/unittest/mocks/HouseKeepingMock.h b/unittest/mocks/HouseKeepingMock.h index 9cc933ed..6ad3e188 100644 --- a/unittest/mocks/HouseKeepingMock.h +++ b/unittest/mocks/HouseKeepingMock.h @@ -2,8 +2,8 @@ #define HOUSEKEEPINGMOCK_H_ #include -#include #include +#include class HouseKeepingMock : public SystemObject, public AcceptsHkPacketsIF { public: @@ -12,5 +12,4 @@ class HouseKeepingMock : public SystemObject, public AcceptsHkPacketsIF { virtual MessageQueueId_t getHkQueue() const; }; - #endif /*HOUSEKEEPINGMOCK_H_*/ \ No newline at end of file From 0595e2910060804cee056953d213c81d78724c60 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 20:11:12 +0100 Subject: [PATCH 09/72] finished most of sus handler --- mission/system/AcsBoardAssembly.cpp | 77 ++++++++++--------- mission/system/AcsBoardAssembly.h | 3 +- mission/system/SusAssembly.cpp | 113 +++++++++++++++++++++++++++- mission/system/SusAssembly.h | 5 ++ 4 files changed, 161 insertions(+), 37 deletions(-) diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 1f6ffb98..0dd2f99c 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -86,22 +86,13 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ return HasReturnvaluesIF::RETURN_OK; } -void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { - modeTable.insert(entry); - entry.setObject(id); - entry.setMode(MODE_OFF); - entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); -} - ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; - Mode_t tgtMode = DeviceHandlerIF::MODE_NORMAL; - auto cmdSeq = [&](object_id_t objectId, ModeTableIdx tableIdx) { - if (tgtMode == DeviceHandlerIF::MODE_NORMAL) { - if (isUseable(objectId, mode)) { - if (helper.gyro0SideAMode != MODE_OFF) { - modeTable[tableIdx].setMode(tgtMode); + auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) { + if (mode == DeviceHandlerIF::MODE_NORMAL) { + if (isUseable(objectId, devMode)) { + if (mode != MODE_OFF) { + modeTable[tableIdx].setMode(devMode); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } else { result = NEED_SECOND_STEP; @@ -109,8 +100,8 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } - } else if (tgtMode == MODE_ON) { - if (isUseable(objectId, mode)) { + } else if (devMode == MODE_ON) { + if (isUseable(objectId, devMode)) { modeTable[tableIdx].setMode(MODE_ON); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } @@ -118,11 +109,11 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s }; switch (submode) { case (A_SIDE): { - cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); - cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); - cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); - cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); - cmdSeq(helper.gpsId, ModeTableIdx::GPS); + cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); + cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); + cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); + cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A); + cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); @@ -134,11 +125,11 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s return result; } case (B_SIDE): { - cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); - cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); - cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); - cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); - cmdSeq(helper.gpsId, ModeTableIdx::GPS); + cmdSeq(helper.gyro2AdisIdSideB, helper.gyro2SideBMode, ModeTableIdx::GYRO_2_B); + cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); + cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); + cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); + cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); @@ -150,15 +141,15 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s return result; } case (DUAL_MODE): { - cmdSeq(helper.gpsId, ModeTableIdx::GPS); - cmdSeq(helper.gyro0AdisIdSideA, ModeTableIdx::GYRO_0_A); - cmdSeq(helper.gyro1L3gIdSideA, ModeTableIdx::GYRO_1_A); - cmdSeq(helper.gyro2AdisIdSideB, ModeTableIdx::GYRO_2_B); - cmdSeq(helper.gyro3L3gIdSideB, ModeTableIdx::GYRO_3_B); - cmdSeq(helper.mgm0Lis3IdSideA, ModeTableIdx::MGM_0_A); - cmdSeq(helper.mgm1Rm3100IdSideA, ModeTableIdx::MGM_1_A); - cmdSeq(helper.mgm2Lis3IdSideB, ModeTableIdx::MGM_2_B); - cmdSeq(helper.mgm3Rm3100IdSideB, ModeTableIdx::MGM_3_B); + cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); + cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); + cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); + cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); + cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A); + cmdSeq(helper.gyro2AdisIdSideB, helper.gyro2SideBMode, ModeTableIdx::GYRO_2_B); + cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); + cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); + cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); return result; } default: { @@ -318,6 +309,14 @@ void AcsBoardAssembly::handleModeReached() { state = States::IDLE; } +void AcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) { + // Some ACS board components are required for Safe-Mode. It would be good if the software + // transitions from A side to B side and from B side to dual mode autonomously + // to ensure that that enough sensors are available witout an operators intervention. + // Therefore, the failure handler is overriden to perform these steps. + // TODO: Implement transitions mentioned above +} + void AcsBoardAssembly::refreshHelperModes() { helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; @@ -328,3 +327,11 @@ void AcsBoardAssembly::refreshHelperModes() { helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode; helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode; } + +void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { + entry.setObject(id); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + entry.setInheritSubmode(false); + modeTable.insert(entry); +} diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 4116f6c9..3fc4a277 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -78,7 +78,6 @@ class AcsBoardAssembly : public AssemblyBase { AcsBoardHelper helper; FixedArrayList modeTable; - void initModeTableEntry(object_id_t id, ModeListEntry& entry); ReturnValue_t initialize() override; @@ -87,6 +86,7 @@ class AcsBoardAssembly : public AssemblyBase { ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; void handleModeReached() override; + void handleModeTransitionFailed(ReturnValue_t result) override; /** * Check whether it makes sense to send mode commands to the device @@ -97,6 +97,7 @@ class AcsBoardAssembly : public AssemblyBase { bool isUseable(object_id_t object, Mode_t mode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); void powerStateMachine(Mode_t mode, Submode_t submode); + void initModeTableEntry(object_id_t id, ModeListEntry& entry); void refreshHelperModes(); }; diff --git a/mission/system/SusAssembly.cpp b/mission/system/SusAssembly.cpp index f34665d4..5da464fb 100644 --- a/mission/system/SusAssembly.cpp +++ b/mission/system/SusAssembly.cpp @@ -6,15 +6,105 @@ SusAssembly::SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, SusAssHelper helper) - : AssemblyBase(objectId, parentId), helper(helper), pwrSwitcher(pwrSwitcher) {} + : AssemblyBase(objectId, parentId), helper(helper), pwrSwitcher(pwrSwitcher) { + ModeListEntry entry; + for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS; idx++) { + initModeTableEntry(helper.susIds[idx], entry); + } +} ReturnValue_t SusAssembly::commandChildren(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; refreshHelperModes(); + powerStateMachine(mode, submode); + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + if (state == States::MODE_COMMANDING) { + handleNormalOrOnModeCmd(mode, submode); + } + } else { + for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS; idx++) { + modeTable[idx].setMode(MODE_OFF); + modeTable[idx].setSubmode(SUBMODE_NONE); + } + } + + HybridIterator tableIter(modeTable.begin(), modeTable.end()); + executeTable(tableIter); + return result; +} + +ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { + ReturnValue_t result = RETURN_OK; + auto cmdSeq = [&](object_id_t objectId, uint8_t tableIdx) { + if (mode == DeviceHandlerIF::MODE_NORMAL) { + if (isUseable(objectId, mode)) { + if (helper.susModes[tableIdx] != MODE_OFF) { + modeTable[tableIdx].setMode(mode); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); + } else { + result = NEED_SECOND_STEP; + modeTable[tableIdx].setMode(MODE_ON); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); + } + } + } else if (mode == MODE_ON) { + if (isUseable(objectId, mode)) { + modeTable[tableIdx].setMode(MODE_ON); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); + } + } + }; + switch (submode) { + case (NOMINAL): { + for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS_ONE_SIDE; idx++) { + cmdSeq(helper.susIds[idx], idx); + // Switch off devices on redundant side + modeTable[idx + NUMBER_SUN_SENSORS_ONE_SIDE].setMode(MODE_OFF); + modeTable[idx + NUMBER_SUN_SENSORS_ONE_SIDE].setSubmode(SUBMODE_NONE); + } + return result; + } + case (REDUNDANT): { + for (uint8_t idx = NUMBER_SUN_SENSORS_ONE_SIDE; idx < NUMBER_SUN_SENSORS; idx++) { + cmdSeq(helper.susIds[idx], idx); + // Switch devices on nominal side + modeTable[idx - NUMBER_SUN_SENSORS_ONE_SIDE].setMode(MODE_OFF); + modeTable[idx - NUMBER_SUN_SENSORS_ONE_SIDE].setSubmode(SUBMODE_NONE); + } + return result; + } + case (DUAL_MODE): { + for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS; idx++) { + cmdSeq(helper.susIds[idx], idx); + } + return result; + } + } return RETURN_OK; } ReturnValue_t SusAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + refreshHelperModes(); + if (wantedSubmode == NOMINAL) { + for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS_ONE_SIDE; idx++) { + if (helper.susModes[idx] != wantedMode) { + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + } + return RETURN_OK; + } else if (wantedSubmode == REDUNDANT) { + for (uint8_t idx = NUMBER_SUN_SENSORS_ONE_SIDE; idx < NUMBER_SUN_SENSORS; idx++) { + if (helper.susModes[idx] != wantedMode) { + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + } + return RETURN_OK; + } else { + // Trigger event if devices are faulty? This is the last fallback mode, returning + // a failure here would trigger a transition to MODE_OFF unless handleModeTransitionFailed + // is overriden + return RETURN_OK; + } return RETURN_OK; } @@ -115,8 +205,29 @@ void SusAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { } } +void SusAssembly::handleModeReached() { + AssemblyBase::handleModeReached(); + state = States::IDLE; +} + +void SusAssembly::handleModeTransitionFailed(ReturnValue_t result) { + // The sun-sensors are required for the Safe-Mode. It would be good if the software + // transitions from nominal side to redundant side and from redundant side to dual mode + // autonomously to ensure that that enough sensors are available witout an operators intervention. + // Therefore, the failure handler is overriden to perform these steps. + // TODO: Implement transitions mentioned above +} + void SusAssembly::refreshHelperModes() { for (uint8_t idx = 0; idx < helper.susModes.size(); idx++) { helper.susModes[idx] = childrenMap[helper.susIds[idx]].mode; } } + +void SusAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { + entry.setObject(id); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + entry.setInheritSubmode(false); + modeTable.insert(entry); +} diff --git a/mission/system/SusAssembly.h b/mission/system/SusAssembly.h index c7acdd87..b4941724 100644 --- a/mission/system/SusAssembly.h +++ b/mission/system/SusAssembly.h @@ -15,6 +15,7 @@ class PowerSwitchIF; class SusAssembly : AssemblyBase { public: + static constexpr uint8_t NUMBER_SUN_SENSORS_ONE_SIDE = 6; static constexpr uint8_t NUMBER_SUN_SENSORS = 12; static constexpr Submode_t NOMINAL = 0; @@ -41,6 +42,8 @@ class SusAssembly : AssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + void handleModeReached() override; + void handleModeTransitionFailed(ReturnValue_t result) override; /** * Check whether it makes sense to send mode commands to the device @@ -50,6 +53,8 @@ class SusAssembly : AssemblyBase { */ bool isUseable(object_id_t object, Mode_t mode); void powerStateMachine(Mode_t mode, Submode_t submode); + ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); + void initModeTableEntry(object_id_t id, ModeListEntry& entry); void refreshHelperModes(); }; From 120153e9c72ac71c19c5f2a4f0d869caaae18ca5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 4 Mar 2022 00:55:51 +0100 Subject: [PATCH 10/72] added some missing acs board ass code --- common/config/commonSubsystemIds.h | 1 + fsfw | 2 +- mission/system/AcsBoardAssembly.cpp | 121 +++++++++++++++++++++++++--- mission/system/AcsBoardAssembly.h | 28 +++++-- 4 files changed, 133 insertions(+), 19 deletions(-) diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 9f293ec6..554f4812 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -20,6 +20,7 @@ enum: uint8_t { PDEC_HANDLER = 119, STR_HELPER = 120, PL_PCDU_HANDLER = 121, + ACS_BOARD_ASS = 122, COMMON_SUBSYSTEM_ID_END }; } diff --git a/fsfw b/fsfw index 75c56280..4e6c1cb7 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 75c56280ad139640d2c12ac4ab78ce66c25fb495 +Subproject commit 4e6c1cb72ad623208ea8e08349f6ab39bfa45ed0 diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 0dd2f99c..7cecf66b 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -1,16 +1,20 @@ #include "AcsBoardAssembly.h" +#include #include #include AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, - PowerSwitchIF* switcher, AcsBoardHelper helper) - : AssemblyBase(objectId, parentId), pwrSwitcher(switcher), helper(helper) { + PowerSwitchIF* switcher, AcsBoardHelper helper, GpioIF* gpioIF) + : AssemblyBase(objectId, parentId), pwrSwitcher(switcher), helper(helper), gpioIF(gpioIF) { if (switcher == nullptr) { sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid Power Switcher " "IF passed" << std::endl; } + if (gpioIF == nullptr) { + sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid GPIO IF passed" << std::endl; + } ModeListEntry entry; initModeTableEntry(helper.mgm0Lis3IdSideA, entry); initModeTableEntry(helper.mgm1Rm3100IdSideA, entry); @@ -59,27 +63,34 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { refreshHelperModes(); - if (wantedSubmode == A_SIDE) { + if (submode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or helper.gpsMode != wantedMode) { + submode = B_SIDE; return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; - } else if (wantedSubmode == B_SIDE) { + } else if (submode == B_SIDE) { if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { + submode = DUAL_MODE; return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; - } else if (wantedSubmode == DUAL_MODE) { + } else if (submode == DUAL_MODE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { - return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + // Trigger event, but don't start any other transitions. This is the last fallback mode. + if (dualModeErrorSwitch) { + triggerEvent(NOT_ENOUGH_DEVICES_DUAL_MODE, 0, 0); + dualModeErrorSwitch = false; + } + return RETURN_OK; } return RETURN_OK; } @@ -107,13 +118,20 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s } } }; - switch (submode) { + switch (this->submode) { case (A_SIDE): { cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A); cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); + ReturnValue_t result = gpioIF->pullLow(gpioIds::GNSS_SELECT); + if (result != HasReturnvaluesIF::RETURN_OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low" + << std::endl; +#endif + } modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); @@ -130,6 +148,13 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); + gpioIF->pullHigh(gpioIds::GNSS_SELECT); + if (result != HasReturnvaluesIF::RETURN_OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high" + << std::endl; +#endif + } modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); @@ -150,6 +175,18 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); + if (defaultSubmode == Submodes::A_SIDE) { + result = gpioIF->pullLow(gpioIds::GNSS_SELECT); + } else { + result = gpioIF->pullHigh(gpioIds::GNSS_SELECT); + } + if (result != HasReturnvaluesIF::RETURN_OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to" + "default side for dual mode" + << std::endl; +#endif + } return result; } default: { @@ -174,7 +211,7 @@ void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { return; } } else { - switch (submode) { + switch (this->submode) { case (A_SIDE): { if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { @@ -307,14 +344,72 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { void AcsBoardAssembly::handleModeReached() { AssemblyBase::handleModeReached(); state = States::IDLE; + tryingOtherSide = false; + dualModeErrorSwitch = true; +} + +void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { + // Some ACS board components are required for Safe-Mode. It would be good if the software + // transitions from A side to B side and from B side to dual mode autonomously + // to ensure that that enough sensors are available without an operators intervention. + // Therefore, the lost mode handler was overwritten to start these transitions + Submode_t nextSubmode = Submodes::A_SIDE; + if (submode == Submodes::A_SIDE) { + nextSubmode = Submodes::B_SIDE; + } + if (not tryingOtherSide) { + triggerEvent(CANT_KEEP_MODE, mode, submode); + startTransition(mode, nextSubmode); + tryingOtherSide = true; + } else { + // Not sure when this would happen. This flag is reset if the mode was reached. If it + // was not reached, the transition failure handler should be called. + sif::error << "AcsBoardAssembly::handleChildrenLostMode: Wrong handler called" << std::endl; + triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode); + startTransition(mode, Submodes::DUAL_MODE); + } } void AcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) { - // Some ACS board components are required for Safe-Mode. It would be good if the software - // transitions from A side to B side and from B side to dual mode autonomously - // to ensure that that enough sensors are available witout an operators intervention. - // Therefore, the failure handler is overriden to perform these steps. - // TODO: Implement transitions mentioned above + Submode_t nextSubmode = Submodes::A_SIDE; + if (submode == Submodes::A_SIDE) { + nextSubmode = Submodes::B_SIDE; + } + // Check whether the transition was started because the mode could not be kept (not commanded). + // If this is not the case, start transition to other side. If it is the case, start + // transition to dual mode. + if (not tryingOtherSide) { + triggerEvent(CANT_KEEP_MODE, mode, submode); + startTransition(mode, nextSubmode); + tryingOtherSide = true; + } else { + triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode); + startTransition(mode, Submodes::DUAL_MODE); + } +} + +void AcsBoardAssembly::setPreferredSide(Submodes submode) { + if (submode != Submodes::A_SIDE and submode != Submodes::B_SIDE) { + return; + } + this->defaultSubmode = submode; +} + +void AcsBoardAssembly::selectGpsInDualMode(Submodes side) { + if (submode != Submodes::DUAL_MODE) { + return; + } + ReturnValue_t result = RETURN_OK; + if (side == Submodes::A_SIDE) { + result = gpioIF->pullLow(gpioIds::GNSS_SELECT); + } else { + result = gpioIF->pullHigh(gpioIds::GNSS_SELECT); + } + if (result != HasReturnvaluesIF::RETURN_OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::error << "AcsBoardAssembly::switchGpsInDualMode: Switching GPS failed" << std::endl; +#endif + } } void AcsBoardAssembly::refreshHelperModes() { diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 3fc4a277..37da581e 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -1,6 +1,7 @@ #ifndef MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ #define MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ +#include #include #include #include @@ -54,17 +55,30 @@ enum ModeTableIdx : uint8_t { }; class PowerSwitchIF; +class GpioIF; class AcsBoardAssembly : public AssemblyBase { public: + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_BOARD_ASS; + static constexpr Event TRANSITION_OTHER_SIDE_FAILED = + event::makeEvent(SUBSYSTEM_ID, 0, severity::HIGH); + static constexpr Event NOT_ENOUGH_DEVICES_DUAL_MODE = + event::makeEvent(SUBSYSTEM_ID, 1, severity::HIGH); static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; - static constexpr Submode_t A_SIDE = 0; - static constexpr Submode_t B_SIDE = 1; - static constexpr Submode_t DUAL_MODE = 2; + enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, - AcsBoardHelper helper); + AcsBoardHelper helper, GpioIF* gpioIF); + + void setPreferredSide(Submodes submode); + + /** + * In dual mode, the A side or the B side GPS device can be used, but not both. + * This function can be used to switch the used GPS device. + * @param side + */ + void selectGpsInDualMode(Submodes side); private: static constexpr pcduSwitches::Switches SWITCH_A = @@ -75,8 +89,11 @@ class AcsBoardAssembly : public AssemblyBase { enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; PowerSwitchIF* pwrSwitcher = nullptr; - + bool tryingOtherSide = false; AcsBoardHelper helper; + GpioIF* gpioIF = nullptr; + Submodes defaultSubmode = Submodes::A_SIDE; + bool dualModeErrorSwitch = true; FixedArrayList modeTable; ReturnValue_t initialize() override; @@ -87,6 +104,7 @@ class AcsBoardAssembly : public AssemblyBase { ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; void handleModeReached() override; void handleModeTransitionFailed(ReturnValue_t result) override; + void handleChildrenLostMode(ReturnValue_t result) override; /** * Check whether it makes sense to send mode commands to the device From 4eb948c5ef628209a0422cd71bfa3395668f5233 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 4 Mar 2022 16:03:57 +0100 Subject: [PATCH 11/72] start acs task --- bsp_q7s/core/InitMission.cpp | 10 ++++-- bsp_q7s/core/ObjectFactory.cpp | 39 +++++++++++++++------ bsp_q7s/core/ObjectFactory.h | 7 ++-- common/config/commonObjects.h | 3 ++ linux/fsfwconfig/OBSWConfig.h.in | 3 +- linux/fsfwconfig/events/translateEvents.cpp | 2 +- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 9d28e1d3..927381c8 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -116,12 +116,16 @@ void initmission::initTasks() { #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ #if OBSW_ADD_ACS_HANDLERS == 1 - PeriodicTaskIF* acsCtrl = factory->createPeriodicTask( + PeriodicTaskIF* acsTask = factory->createPeriodicTask( "ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); - result = acsCtrl->addComponent(objects::GPS_CONTROLLER); + result = acsTask->addComponent(objects::GPS_CONTROLLER); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER); } + result = acsTask->addComponent(objects::ACS_BOARD_ASS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("ACS_ASS", objects::GPS_CONTROLLER); + } #endif /* OBSW_ADD_ACS_HANDLERS */ #if BOARD_TE0720 == 0 @@ -209,7 +213,7 @@ void initmission::initTasks() { #endif #if OBSW_ADD_ACS_HANDLERS == 1 - acsCtrl->startTask(); + acsTask->startTask(); #endif sif::info << "Tasks started.." << std::endl; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index b4d92b23..657de665 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -83,6 +83,7 @@ #include "mission/devices/devicedefinitions/RwDefinitions.h" #include "mission/devices/devicedefinitions/SusDefinitions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" +#include "mission/system/AcsBoardAssembly.h" #include "mission/tmtc/CCSDSHandler.h" #include "mission/tmtc/VirtualChannel.h" #include "mission/utility/TmFunnel.h" @@ -124,18 +125,19 @@ void ObjectFactory::produce(void* args) { UartComIF* uartComIF = nullptr; SpiComIF* spiComIF = nullptr; I2cComIF* i2cComIF = nullptr; + PowerSwitchIF* pwrSwitcher = nullptr; createCommunicationInterfaces(&gpioComIF, &uartComIF, &spiComIF, &i2cComIF); createTmpComponents(); #if BOARD_TE0720 == 0 new CoreController(objects::CORE_CONTROLLER); gpioCallbacks::disableAllDecoder(); - createPcduComponents(gpioComIF); + createPcduComponents(gpioComIF, &pwrSwitcher); createRadSensorComponent(gpioComIF); createSunSensorComponents(gpioComIF, spiComIF); #if OBSW_ADD_ACS_BOARD == 1 - createAcsBoardComponents(gpioComIF, uartComIF); + createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher); #endif createHeaterComponents(); @@ -260,7 +262,7 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua #endif } -void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) { +void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher) { CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK); CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1); CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2); @@ -275,7 +277,7 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) { new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); pdu2handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); - new PCDUHandler(objects::PCDU_HANDLER, 50); + auto pcduHandler = new PCDUHandler(objects::PCDU_HANDLER, 50); /** * Setting PCDU devices to mode normal immediately after start up because PCDU is always @@ -285,6 +287,9 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) { pdu1handler->setModeNormal(); pdu2handler->setModeNormal(); acuhandler->setModeNormal(); + if (pwrSwitcher != nullptr) { + *pwrSwitcher = pcduHandler; + } } void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) { @@ -473,7 +478,8 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI #endif /* OBSW_ADD_SUN_SENSORS == 1 */ } -void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF) { +void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF, + PowerSwitchIF* pwrSwitcher) { using namespace gpio; GpioCookie* gpioCookieAcsBoard = new GpioCookie(); @@ -580,6 +586,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI 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, spi::LIS3_TRANSITION_DELAY); + static_cast(mgmLis3Handler); #if OBSW_TEST_ACS == 1 mgmLis3Handler->setStartUpImmediately(); mgmLis3Handler->setToGoToNormalMode(true); @@ -593,6 +600,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI 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, spi::RM3100_TRANSITION_DELAY); + static_cast(mgmRm3100Handler); #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setStartUpImmediately(); mgmRm3100Handler->setToGoToNormalMode(true); @@ -604,13 +612,14 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI 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); - auto mgmLis3Handler2 = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, - spiCookie, spi::LIS3_TRANSITION_DELAY); + mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, + spiCookie, spi::LIS3_TRANSITION_DELAY); + static_cast(mgmLis3Handler); #if OBSW_TEST_ACS == 1 - mgmLis3Handler2->setStartUpImmediately(); - mgmLis3Handler2->setToGoToNormalMode(true); + mgmLis3Handler->setStartUpImmediately(); + mgmLis3Handler->setToGoToNormalMode(true); #if OBSW_DEBUG_ACS == 1 - mgmLis3Handler2->enablePeriodicPrintouts(true, 10); + mgmLis3Handler->enablePeriodicPrintouts(true, 10); #endif #endif @@ -634,6 +643,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI spi::DEFAULT_ADIS16507_SPEED); auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie, ADIS1650X::Type::ADIS16505); + static_cast(adisHandler); #if OBSW_TEST_ACS == 1 adisHandler->setStartUpImmediately(); adisHandler->setToGoToNormalModeImmediately(); @@ -648,6 +658,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, spi::L3G_TRANSITION_DELAY); + static_cast(gyroL3gHandler); #if OBSW_TEST_ACS == 1 gyroL3gHandler->setStartUpImmediately(); gyroL3gHandler->setToGoToNormalMode(true); @@ -692,6 +703,14 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI auto gpsHandler0 = new GPSHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); + + AcsBoardHelper acsBoardHelper = AcsBoardHelper( + objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER, + objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER, + objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER); + auto acsAss = new AcsBoardAssembly(objects::ACS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, + acsBoardHelper, gpioComIF); + static_cast(acsAss); #endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index ecc92f01..d680a7c9 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -5,6 +5,7 @@ class LinuxLibgpioIF; class UartComIF; class SpiComIF; class I2cComIF; +class PowerSwitchIF; namespace ObjectFactory { @@ -13,13 +14,13 @@ void produce(void* args); void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, SpiComIF** spiComIF, I2cComIF** i2cComIF); - +void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher); void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); void createTmpComponents(); -void createPcduComponents(LinuxLibgpioIF* gpioComIF); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); -void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF); +void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF, + PowerSwitchIF* pwrSwitcher); void createHeaterComponents(); void createSolarArrayDeploymentComponents(); void createSyrlinksComponents(); diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 6cc90be9..30b05333 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -91,6 +91,9 @@ enum commonObjects: uint32_t { STR_HELPER = 0x44330002, AXI_PTME_CONFIG = 44330003, PTME_CONFIG = 44330004, + + // 0x73 ('s') for assemblies and system/subsystem components + ACS_BOARD_ASS = 0x73000001 }; } diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index cc90cd78..10d2e912 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -48,7 +48,7 @@ debugging. */ #define OBSW_ADD_PLOC_MPSOC 0 #define OBSW_ADD_SUN_SENSORS 0 #define OBSW_ADD_ACS_BOARD 1 -#define OBSW_ADD_ACS_HANDLERS 0 +#define OBSW_ADD_ACS_HANDLERS 1 #define OBSW_ADD_RW 0 #define OBSW_ADD_RTD_DEVICES 0 #define OBSW_ADD_TMP_DEVICES 0 @@ -56,7 +56,6 @@ debugging. */ #define OBSW_ADD_PL_PCDU 0 #define OBSW_ADD_SYRLINKS 0 #define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 -#define OBSW_SYRLINKS_SIMULATED 1 #define OBSW_STAR_TRACKER_GROUND_CONFIG 1 #define OBSW_ENABLE_PERIODIC_HK 0 diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index b9619d3e..57c3eb96 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -148,7 +148,7 @@ const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; const char *translateEvents(Event event) { - switch((event & 0xFFFF)) { + switch ((event & 0xFFFF)) { case (2200): return STORE_SEND_WRITE_FAILED_STRING; case (2201): From 0904cadde51323252140aa69b692e0bba116bfcb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 4 Mar 2022 18:12:16 +0100 Subject: [PATCH 12/72] continued ACS board assembly --- bsp_q7s/core/ObjectFactory.cpp | 29 ++++--- fsfw | 2 +- generators/bsp_q7s_objects.csv | 1 + generators/events/translateEvents.cpp | 2 +- generators/objects/translateObjects.cpp | 7 +- linux/fsfwconfig/OBSWConfig.h.in | 1 + linux/fsfwconfig/events/translateEvents.cpp | 2 +- linux/fsfwconfig/objects/translateObjects.cpp | 7 +- mission/devices/PCDUHandler.cpp | 4 +- mission/devices/PCDUHandler.h | 3 +- mission/system/AcsBoardAssembly.cpp | 84 +++++++++++-------- mission/system/AcsBoardAssembly.h | 4 +- 12 files changed, 89 insertions(+), 57 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 657de665..2b7ccd7d 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,5 +1,6 @@ #include "ObjectFactory.h" +#include #include #include #include @@ -590,11 +591,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 mgmLis3Handler->setStartUpImmediately(); mgmLis3Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmLis3Handler->enablePeriodicPrintouts(true, 10); #endif -#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); @@ -604,11 +604,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setStartUpImmediately(); mgmRm3100Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmRm3100Handler->enablePeriodicPrintouts(true, 10); #endif -#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); @@ -618,11 +617,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 mgmLis3Handler->setStartUpImmediately(); mgmLis3Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmLis3Handler->enablePeriodicPrintouts(true, 10); #endif -#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); @@ -631,11 +629,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setStartUpImmediately(); mgmRm3100Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmRm3100Handler->enablePeriodicPrintouts(true, 10); #endif -#endif - // Commented until ACS board V2 in in clean room again // Gyro 0 Side A spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, @@ -647,9 +644,9 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 adisHandler->setStartUpImmediately(); adisHandler->setToGoToNormalModeImmediately(); +#endif #if OBSW_DEBUG_ACS == 1 adisHandler->enablePeriodicPrintouts(true, 10); -#endif #endif // Gyro 1 Side A @@ -662,9 +659,9 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 gyroL3gHandler->setStartUpImmediately(); gyroL3gHandler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 gyroL3gHandler->enablePeriodicPrintouts(true, 10); -#endif #endif // Gyro 2 Side B spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, @@ -685,9 +682,9 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 gyroL3gHandler->setStartUpImmediately(); gyroL3gHandler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 gyroL3gHandler->enablePeriodicPrintouts(true, 10); -#endif #endif bool debugGps = false; @@ -711,6 +708,16 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI auto acsAss = new AcsBoardAssembly(objects::ACS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, acsBoardHelper, gpioComIF); static_cast(acsAss); + +#if OBSW_TEST_ACS_BAORD_ASS == 1 + CommandMessage msg; + ModeMessage::setModeMessage(&msg, ModeMessage::CMD_MODE_COMMAND, DeviceHandlerIF::MODE_NORMAL, + AcsBoardAssembly::A_SIDE); + ReturnValue_t result = MessageQueueSenderIF::sendMessage(acsAss->getCommandQueue(), &msg); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Sending mode command failed" << std::endl; + } +#endif #endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } diff --git a/fsfw b/fsfw index 4e6c1cb7..45f0d7fd 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4e6c1cb72ad623208ea8e08349f6ab39bfa45ed0 +Subproject commit 45f0d7fd453eafddbc8a364e6c61a90b5f577c85 diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index a0c0a6dc..da127d35 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -107,6 +107,7 @@ 0x5400CAFE;DUMMY_INTERFACE 0x54123456;LIBGPIOD_TEST 0x54694269;TEST_TASK +0x73000001;ACS_BOARD_ASS 0x73000100;TM_FUNNEL 0x73500000;CCSDS_IP_CORE_BRIDGE 0xFFFFFFFF;NO_OBJECT diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index b9619d3e..4f647544 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 141 translations. * @details - * Generated on: 2022-03-01 18:04:34 + * Generated on: 2022-03-04 16:42:09 */ #include "translateEvents.h" diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index e09434a2..37ef3255 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2022-03-01 18:04:38 + * Contains 113 translations. + * Generated on: 2022-03-04 16:42:21 */ #include "translateObjects.h" @@ -115,6 +115,7 @@ const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE"; const char *LIBGPIOD_TEST_STRING = "LIBGPIOD_TEST"; const char *TEST_TASK_STRING = "TEST_TASK"; +const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -339,6 +340,8 @@ const char *translateObject(object_id_t object) { return LIBGPIOD_TEST_STRING; case 0x54694269: return TEST_TASK_STRING; + case 0x73000001: + return ACS_BOARD_ASS_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73500000: diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 10d2e912..efdc4b63 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -84,6 +84,7 @@ debugging. */ #define OBSW_ADD_UART_TEST_CODE 0 #define OBSW_TEST_ACS 0 +#define OBSW_TEST_ACS_BAORD_ASS 0 #define OBSW_DEBUG_ACS 0 #define OBSW_TEST_SUS 0 #define OBSW_DEBUG_SUS 0 diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 57c3eb96..e29fd1b2 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 141 translations. * @details - * Generated on: 2022-03-01 18:04:34 + * Generated on: 2022-03-04 16:42:09 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index e09434a2..37ef3255 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2022-03-01 18:04:38 + * Contains 113 translations. + * Generated on: 2022-03-04 16:42:21 */ #include "translateObjects.h" @@ -115,6 +115,7 @@ const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE"; const char *LIBGPIOD_TEST_STRING = "LIBGPIOD_TEST"; const char *TEST_TASK_STRING = "TEST_TASK"; +const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -339,6 +340,8 @@ const char *translateObject(object_id_t object) { return LIBGPIOD_TEST_STRING; case 0x54694269: return TEST_TASK_STRING; + case 0x73000001: + return ACS_BOARD_ASS_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73500000: diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 244cc6db..f5593aa2 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -26,7 +26,6 @@ ReturnValue_t PCDUHandler::performOperation(uint8_t counter) { readCommandQueue(); return RETURN_OK; } - return RETURN_OK; } @@ -116,7 +115,7 @@ void PCDUHandler::readCommandQueue() { MessageQueueId_t PCDUHandler::getCommandQueue() const { return commandQueue->getId(); } -void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) { +void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) { if (sid == sid_t(objects::PDU2_HANDLER, PDU2::HK_TABLE_DATA_SET_ID)) { updateHkTableDataset(storeId, &pdu2HkTableDataset, &timeStampPdu2HkDataset); updatePdu2SwitchStates(); @@ -204,7 +203,6 @@ void PCDUHandler::updatePdu1SwitchStates() { } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; } - pdu1HkTableDataset.commit(); } LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; } diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index 126f486a..b96ce018 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -27,7 +27,8 @@ class PCDUHandler : public PowerSwitchIF, virtual ReturnValue_t initialize() override; virtual ReturnValue_t performOperation(uint8_t counter) override; virtual void handleChangedDataset(sid_t sid, - store_address_t storeId = storeId::INVALID_STORE_ADDRESS); + store_address_t storeId = storeId::INVALID_STORE_ADDRESS, + bool* clearMessage = nullptr) override; virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override; virtual void sendFuseOnCommand(uint8_t fuseNr) const override; diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 7cecf66b..5613e155 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -27,42 +27,54 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, initModeTableEntry(helper.gpsId, entry); } +void AcsBoardAssembly::handleChildrenTransition() { + if (state == States::SWITCHING_POWER) { + powerStateMachine(targetMode, targetSubmode); + } else { + AssemblyBase::handleChildrenTransition(); + } +} + ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; refreshHelperModes(); powerStateMachine(mode, submode); - if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { - if (state == States::MODE_COMMANDING) { + if (state == States::MODE_COMMANDING) { + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { handleNormalOrOnModeCmd(mode, submode); + } else { + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } - } else { - modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); + HybridIterator tableIter(modeTable.begin(), modeTable.end()); + executeTable(tableIter); } - - HybridIterator tableIter(modeTable.begin(), modeTable.end()); - executeTable(tableIter); return result; } ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { refreshHelperModes(); + if (state == States::SWITCHING_POWER) { + // Wrong mode + sif::error << "Wrong mode, currently swichting power" << std::endl; + return RETURN_OK; + } if (submode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or @@ -211,7 +223,7 @@ void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { return; } } else { - switch (this->submode) { + switch (submode) { case (A_SIDE): { if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { @@ -239,37 +251,37 @@ void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { if (state == States::IDLE) { if (mode == MODE_OFF) { if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, false); + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); } if (switchStateB != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, false); + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } } else { switch (submode) { case (A_SIDE): { if (switchStateA != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, true); + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); } if (switchStateB != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, false); + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } break; } case (B_SIDE): { if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, false); + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF); } if (switchStateB != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, true); + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } break; } case (DUAL_MODE): { if (switchStateA != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, true); + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); } if (switchStateB != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, true); + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_ON); } break; } @@ -315,7 +327,11 @@ ReturnValue_t AcsBoardAssembly::initialize() { if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return result; + result = registerChild(helper.gpsId); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return AssemblyBase::initialize(); } ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 37da581e..640bbad3 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -17,7 +17,8 @@ struct AcsBoardHelper { gyro0AdisIdSideA(gyro0Id), gyro1L3gIdSideA(gyro1Id), gyro2AdisIdSideB(gyro2Id), - gyro3L3gIdSideB(gyro3Id) {} + gyro3L3gIdSideB(gyro3Id), + gpsId(gpsId) {} object_id_t mgm0Lis3IdSideA = objects::NO_OBJECT; object_id_t mgm1Rm3100IdSideA = objects::NO_OBJECT; @@ -102,6 +103,7 @@ class AcsBoardAssembly : public AssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + void handleChildrenTransition() override; void handleModeReached() override; void handleModeTransitionFailed(ReturnValue_t result) override; void handleChildrenLostMode(ReturnValue_t result) override; From cbb8103278849ea4c818973ea6f8729eb2c983cf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 4 Mar 2022 18:33:23 +0100 Subject: [PATCH 13/72] some more bugfixes --- .../pollingSequenceFactory.cpp | 2 +- mission/system/AcsBoardAssembly.cpp | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 81d47a4b..73f00814 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -349,7 +349,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { #endif #if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 - bool enableAside = false; + bool enableAside = true; bool enableBside = true; if (enableAside) { // A side diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 5613e155..eb4afbd5 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -30,6 +30,9 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, void AcsBoardAssembly::handleChildrenTransition() { if (state == States::SWITCHING_POWER) { powerStateMachine(targetMode, targetSubmode); + if (state == States::MODE_COMMANDING) { + AssemblyBase::handleChildrenTransition(); + } } else { AssemblyBase::handleChildrenTransition(); } @@ -72,26 +75,24 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ refreshHelperModes(); if (state == States::SWITCHING_POWER) { // Wrong mode - sif::error << "Wrong mode, currently swichting power" << std::endl; + sif::error << "Wrong mode, currently switching power" << std::endl; return RETURN_OK; } - if (submode == A_SIDE) { + if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or helper.gpsMode != wantedMode) { - submode = B_SIDE; return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; - } else if (submode == B_SIDE) { + } else if (wantedSubmode == B_SIDE) { if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { - submode = DUAL_MODE; return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; - } else if (submode == DUAL_MODE) { + } else if (wantedSubmode == DUAL_MODE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and @@ -115,7 +116,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s if (mode == DeviceHandlerIF::MODE_NORMAL) { if (isUseable(objectId, devMode)) { if (mode != MODE_OFF) { - modeTable[tableIdx].setMode(devMode); + modeTable[tableIdx].setMode(mode); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } else { result = NEED_SECOND_STEP; @@ -123,14 +124,14 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } - } else if (devMode == MODE_ON) { + } else if (mode == MODE_ON) { if (isUseable(objectId, devMode)) { modeTable[tableIdx].setMode(MODE_ON); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } }; - switch (this->submode) { + switch (submode) { case (A_SIDE): { cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); From 32def715028d6da05f54a40dd02720424f192052 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 5 Mar 2022 03:02:09 +0100 Subject: [PATCH 14/72] first version of ACS board ASS working - Testes transition OFF to NORMAL for A side - Refactored power switching so it can be used by SUS ass as well - Generate events for sending switch command - Generate event if switch state changes - Deny Q7S switch commanding --- bsp_q7s/core/ObjectFactory.cpp | 4 +- fsfw | 2 +- linux/devices/GPSHyperionLinuxController.cpp | 6 +- linux/devices/GPSHyperionLinuxController.h | 2 +- .../startracker/StarTrackerHandler.cpp | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 2 +- mission/controller/ThermalController.cpp | 2 +- mission/devices/GomspaceDeviceHandler.cpp | 11 +- mission/devices/PCDUHandler.cpp | 82 ++-- mission/devices/PCDUHandler.h | 12 +- .../devicedefinitions/powerDefinitions.h | 18 + mission/system/AcsBoardAssembly.cpp | 423 +++++++++--------- mission/system/AcsBoardAssembly.h | 39 +- mission/system/CMakeLists.txt | 1 + mission/system/DualLanePowerStateMachine.cpp | 98 ++++ mission/system/DualLanePowerStateMachine.h | 25 ++ mission/system/definitions.h | 14 + 17 files changed, 469 insertions(+), 274 deletions(-) create mode 100644 mission/devices/devicedefinitions/powerDefinitions.h create mode 100644 mission/system/DualLanePowerStateMachine.cpp create mode 100644 mission/system/DualLanePowerStateMachine.h create mode 100644 mission/system/definitions.h diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 2b7ccd7d..bcef64b9 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -709,10 +709,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI acsBoardHelper, gpioComIF); static_cast(acsAss); -#if OBSW_TEST_ACS_BAORD_ASS == 1 +#if OBSW_TEST_ACS_BOARD_ASS == 1 CommandMessage msg; ModeMessage::setModeMessage(&msg, ModeMessage::CMD_MODE_COMMAND, DeviceHandlerIF::MODE_NORMAL, - AcsBoardAssembly::A_SIDE); + duallane::A_SIDE); ReturnValue_t result = MessageQueueSenderIF::sendMessage(acsAss->getCommandQueue(), &msg); if (result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Sending mode command failed" << std::endl; diff --git a/fsfw b/fsfw index 45f0d7fd..3c53e2c2 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 45f0d7fd453eafddbc8a364e6c61a90b5f577c85 +Subproject commit 3c53e2c259c43d2ebcc8fc3642fbb6bff84093c6 diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GPSHyperionLinuxController.cpp index d5b2741e..d0e7fb80 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GPSHyperionLinuxController.cpp @@ -30,10 +30,12 @@ ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_ uint32_t *msToReachTheMode) { if (not modeCommanded) { if (mode == MODE_ON or mode == MODE_OFF) { - // 10 minutes time to reach fix - *msToReachTheMode = 600000; + // 5h time to reach fix + *msToReachTheMode = MAX_SECONDS_TO_REACH_FIX; maxTimeToReachFix.resetTimer(); modeCommanded = true; + } else if (mode == MODE_NORMAL) { + return HasModesIF::INVALID_MODE_RETVAL; } } return HasReturnvaluesIF::RETURN_OK; diff --git a/linux/devices/GPSHyperionLinuxController.h b/linux/devices/GPSHyperionLinuxController.h index b8ab028d..f0e4e6e0 100644 --- a/linux/devices/GPSHyperionLinuxController.h +++ b/linux/devices/GPSHyperionLinuxController.h @@ -21,7 +21,7 @@ */ class GPSHyperionLinuxController : public ExtendedControllerBase { public: - static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 600; + static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 60 * 5; GPSHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool debugHyperionGps = false); virtual ~GPSHyperionLinuxController(); diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index d06b73f1..378aa2a0 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -672,7 +672,7 @@ ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t return INVALID_SUBMODE; } default: - return HasModesIF::INVALID_MODE; + return HasModesIF::INVALID_MODE_RETVAL; } } diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index efdc4b63..e8c2dff6 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -84,7 +84,7 @@ debugging. */ #define OBSW_ADD_UART_TEST_CODE 0 #define OBSW_TEST_ACS 0 -#define OBSW_TEST_ACS_BAORD_ASS 0 +#define OBSW_TEST_ACS_BOARD_ASS 0 #define OBSW_DEBUG_ACS 0 #define OBSW_TEST_SUS 0 #define OBSW_DEBUG_SUS 0 diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index 2b6f704f..a92e3415 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -42,7 +42,7 @@ ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode return INVALID_SUBMODE; } if ((mode != MODE_OFF) && (mode != MODE_ON) && (mode != MODE_NORMAL)) { - return INVALID_MODE; + return INVALID_MODE_RETVAL; } return RETURN_OK; } \ No newline at end of file diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index 4cec651e..6decef16 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -1,5 +1,7 @@ -#include -#include +#include "GomspaceDeviceHandler.h" + +#include "devicedefinitions/GomSpacePackets.h" +#include "devicedefinitions/powerDefinitions.h" GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, uint16_t maxConfigTableAddress, @@ -189,6 +191,11 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm size_t commandDataLen) { ReturnValue_t result = setParamCacher.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG); + // This breaks layering but I really don't want to accept this command.. + if (setParamCacher.getAddress() == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S) { + triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0); + return HasReturnvaluesIF::RETURN_FAILED; + } if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " "message" diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index f5593aa2..cd07e1d9 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -160,22 +160,24 @@ void PCDUHandler::updatePdu2SwitchStates() { PoolReadGuard rg(&pdu2HkTableDataset); if (rg.getReadResult() == RETURN_OK) { MutexGuard mg(pwrMutex); - switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; - switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] = - pdu2HkTableDataset.outEnabledPlPCDUCh1.value; - switchStates[Switches::PDU2_CH2_RW_5V] = pdu2HkTableDataset.outEnabledReactionWheels.value; - switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] = - pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value; - switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = - pdu2HkTableDataset.outEnabledSUSRedundant.value; - switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] = - pdu2HkTableDataset.outEnabledDeplMechanism.value; - switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = - pdu2HkTableDataset.outEnabledPlPCDUCh6.value; - switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = - pdu2HkTableDataset.outEnabledAcsBoardSideB.value; - switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = - pdu2HkTableDataset.outEnabledPayloadCamera.value; + checkAndUpdateSwitch(Switches::PDU2_CH0_Q7S, pdu2HkTableDataset.outEnabledQ7S.value); + + checkAndUpdateSwitch(Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8, + pdu2HkTableDataset.outEnabledPlPCDUCh1.value); + checkAndUpdateSwitch(Switches::PDU2_CH2_RW_5V, + pdu2HkTableDataset.outEnabledReactionWheels.value); + checkAndUpdateSwitch(Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value); + checkAndUpdateSwitch(Switches::PDU2_CH4_SUS_REDUNDANT_3V3, + pdu2HkTableDataset.outEnabledSUSRedundant.value); + checkAndUpdateSwitch(Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + pdu2HkTableDataset.outEnabledDeplMechanism.value); + checkAndUpdateSwitch(Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8, + pdu2HkTableDataset.outEnabledPlPCDUCh6.value); + checkAndUpdateSwitch(Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + pdu2HkTableDataset.outEnabledAcsBoardSideB.value); + checkAndUpdateSwitch(Switches::PDU2_CH8_PAYLOAD_CAMERA, + pdu2HkTableDataset.outEnabledPayloadCamera.value); } else { sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" << std::endl; @@ -187,19 +189,22 @@ void PCDUHandler::updatePdu1SwitchStates() { PoolReadGuard rg(&pdu1HkTableDataset); if (rg.getReadResult() == RETURN_OK) { MutexGuard mg(pwrMutex); - switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value; - switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value; - switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = - pdu1HkTableDataset.outEnabledStarTracker.value; - switchStates[Switches::PDU1_CH3_MGT_5V] = pdu1HkTableDataset.outEnabledMGT.value; - switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = - pdu1HkTableDataset.outEnabledSUSNominal.value; - switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = - pdu1HkTableDataset.outEnabledSolarCellExp.value; - switchStates[Switches::PDU1_CH6_PLOC_12V] = pdu1HkTableDataset.outEnabledPLOC.value; - switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = - pdu1HkTableDataset.outEnabledAcsBoardSideA.value; - switchStates[Switches::PDU1_CH8_UNOCCUPIED] = pdu1HkTableDataset.outEnabledChannel8.value; + checkAndUpdateSwitch(Switches::PDU1_CH0_TCS_BOARD_3V3, + pdu1HkTableDataset.outEnabledTCSBoard3V3.value); + checkAndUpdateSwitch(Switches::PDU1_CH1_SYRLINKS_12V, + pdu1HkTableDataset.outEnabledSyrlinks.value); + checkAndUpdateSwitch(Switches::PDU1_CH2_STAR_TRACKER_5V, + pdu1HkTableDataset.outEnabledStarTracker.value); + checkAndUpdateSwitch(Switches::PDU1_CH3_MGT_5V, pdu1HkTableDataset.outEnabledMGT.value); + checkAndUpdateSwitch(Switches::PDU1_CH4_SUS_NOMINAL_3V3, + pdu1HkTableDataset.outEnabledSUSNominal.value); + checkAndUpdateSwitch(Switches::PDU1_CH5_SOLAR_CELL_EXP_5V, + pdu1HkTableDataset.outEnabledSolarCellExp.value); + checkAndUpdateSwitch(Switches::PDU1_CH6_PLOC_12V, pdu1HkTableDataset.outEnabledPLOC.value); + checkAndUpdateSwitch(Switches::PDU1_CH7_ACS_A_SIDE_3V3, + pdu1HkTableDataset.outEnabledAcsBoardSideA.value); + checkAndUpdateSwitch(Switches::PDU1_CH8_UNOCCUPIED, + pdu1HkTableDataset.outEnabledChannel8.value); } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; } @@ -261,11 +266,12 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); break; } - // That does not really make sense but let's keep it here for completeness reasons.. + // This is a dangerous command. Reject/Igore it for now case pcduSwitches::PDU2_CH0_Q7S: { - memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_Q7S; - pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); - break; + return; + // memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_Q7S; + // pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + // break; } case pcduSwitches::PDU2_CH1_PL_PCDU_BATT_0_14V8: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1; @@ -344,6 +350,9 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const if (result != RETURN_OK) { sif::debug << "PCDUHandler::sendSwitchCommand: Failed to send message to PDU Handler" << std::endl; + } else { + // Can't use trigger event because of const function constraint, but this hack seems to work + this->forwardEvent(power::SWITCH_CMD_SENT, parameterValue, switchNr); } } @@ -592,3 +601,10 @@ LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) { return nullptr; } } + +void PCDUHandler::checkAndUpdateSwitch(pcduSwitches::Switches switchIdx, uint8_t setValue) { + if (switchStates[switchIdx] != setValue) { + triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); + } + switchStates[switchIdx] = setValue; +} diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index b96ce018..e9649041 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -8,13 +8,16 @@ #include #include #include -#include + +#include "devicedefinitions/GomspaceDefinitions.h" +#include "devicedefinitions/powerDefinitions.h" /** * @brief The PCDUHandler provides a compact interface to handle all devices related to the - * control of power. This is necessary because the fsfw manages all power - * related functionalities via one power object. This includes for example the switch on and off of - * devices. + * control of power. + * @details + * This is necessary because the FSFW manages all power related functionalities via one + * power object. This includes for example switching on and off of devices. */ class PCDUHandler : public PowerSwitchIF, public HasLocalDataPoolIF, @@ -114,6 +117,7 @@ class PCDUHandler : public PowerSwitchIF, */ void updateHkTableDataset(store_address_t storeId, LocalPoolDataSetBase* dataset, CCSDSTime::CDS_short* datasetTimeStamp); + void checkAndUpdateSwitch(pcduSwitches::Switches switchIdx, uint8_t setValue); }; #endif /* MISSION_DEVICES_PCDUHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/powerDefinitions.h b/mission/devices/devicedefinitions/powerDefinitions.h new file mode 100644 index 00000000..c5e40f12 --- /dev/null +++ b/mission/devices/devicedefinitions/powerDefinitions.h @@ -0,0 +1,18 @@ +#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ +#define MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ + +#include +#include + +namespace power { + +static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_HANDLER; +//! [EXPORT] : [COMMENT] Indicated that a FSFW object requested setting a switch +//! P1: 1 if on was requested, 0 for off | P2: Switch Index +static constexpr Event SWITCH_CMD_SENT = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO); +static constexpr Event SWITCH_HAS_CHANGED = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); +static constexpr Event SWITCHING_Q7S_DENIED = event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); + +} // namespace power + +#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ */ diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index eb4afbd5..39162129 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -6,7 +6,10 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, AcsBoardHelper helper, GpioIF* gpioIF) - : AssemblyBase(objectId, parentId), pwrSwitcher(switcher), helper(helper), gpioIF(gpioIF) { + : AssemblyBase(objectId, parentId), + pwrStateMachine(SWITCH_A, SWITCH_B, switcher, state), + helper(helper), + gpioIF(gpioIF) { if (switcher == nullptr) { sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid Power Switcher " "IF passed" @@ -27,24 +30,54 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, initModeTableEntry(helper.gpsId, entry); } -void AcsBoardAssembly::handleChildrenTransition() { - if (state == States::SWITCHING_POWER) { - powerStateMachine(targetMode, targetSubmode); - if (state == States::MODE_COMMANDING) { - AssemblyBase::handleChildrenTransition(); +void AcsBoardAssembly::performChildOperation() { + using namespace duallane; + if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) { + if (targetMode != MODE_OFF) { + pwrStateMachineWrapper(targetMode, targetSubmode); + } + // This state is the indicator that the power state machine is done + if (state == PwrStates::MODE_COMMANDING) { + AssemblyBase::performChildOperation(); } } else { - AssemblyBase::handleChildrenTransition(); + AssemblyBase::performChildOperation(); + // This state is the indicator that the mode state machine is done + if (state == PwrStates::SWITCHING_POWER) { + pwrStateMachineWrapper(targetMode, targetSubmode); + } + } +} + +void AcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) { + using namespace duallane; + // If anything other than MODE_OFF is commanded, perform power state machine first + if (mode != MODE_OFF) { + if (state != PwrStates::IDLE) { + state = PwrStates::IDLE; + } + // Cache the target modes, required by power state machine + targetMode = mode; + targetSubmode = submode; + state = PwrStates::SWITCHING_POWER; + // Perform power state machine first, then start mode transition. The power state machine will + // start the transition after it has finished + pwrStateMachineWrapper(mode, submode); + } else { + // Command the devices to off first before switching off the power. The handleModeReached + // custom implementation will take care of starting the power state machine. + AssemblyBase::startTransition(mode, submode); } } ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { + using namespace duallane; ReturnValue_t result = RETURN_OK; refreshHelperModes(); - powerStateMachine(mode, submode); - if (state == States::MODE_COMMANDING) { + pwrStateMachineWrapper(mode, submode); + if (state == PwrStates::MODE_COMMANDING) { if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { - handleNormalOrOnModeCmd(mode, submode); + result = handleNormalOrOnModeCmd(mode, submode); } else { modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); @@ -72,8 +105,9 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) } ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + using namespace duallane; refreshHelperModes(); - if (state == States::SWITCHING_POWER) { + if (state == PwrStates::SWITCHING_POWER) { // Wrong mode sif::error << "Wrong mode, currently switching power" << std::endl; return RETURN_OK; @@ -81,14 +115,14 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or - helper.gpsMode != wantedMode) { + helper.gpsMode != MODE_ON) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; } else if (wantedSubmode == B_SIDE) { if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or - helper.gpsMode != wantedMode) { + helper.gpsMode != MODE_ON) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; @@ -97,7 +131,7 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or - helper.gpsMode != wantedMode) { + helper.gpsMode != MODE_ON) { // Trigger event, but don't start any other transitions. This is the last fallback mode. if (dualModeErrorSwitch) { triggerEvent(NOT_ENOUGH_DEVICES_DUAL_MODE, 0, 0); @@ -111,16 +145,16 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ } ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { + using namespace duallane; ReturnValue_t result = RETURN_OK; auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) { if (mode == DeviceHandlerIF::MODE_NORMAL) { if (isUseable(objectId, devMode)) { - if (mode != MODE_OFF) { - modeTable[tableIdx].setMode(mode); + if (devMode == MODE_OFF or devMode == HasModesIF::UNDEFINED_MODE) { + modeTable[tableIdx].setMode(MODE_ON); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } else { - result = NEED_SECOND_STEP; - modeTable[tableIdx].setMode(MODE_ON); + modeTable[tableIdx].setMode(mode); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } @@ -131,15 +165,20 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s } } }; + if (this->mode == MODE_OFF and mode == DeviceHandlerIF::MODE_NORMAL) { + if (internalState != STATE_SECOND_STEP) { + result = NEED_SECOND_STEP; + } + } switch (submode) { case (A_SIDE): { cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A); - cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); - ReturnValue_t result = gpioIF->pullLow(gpioIds::GNSS_SELECT); - if (result != HasReturnvaluesIF::RETURN_OK) { + modeTable[ModeTableIdx::GPS].setMode(MODE_ON); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); + if (gpioIF->pullLow(gpioIds::GNSS_SELECT) != HasReturnvaluesIF::RETURN_OK) { #if OBSW_VERBOSE_LEVEL >= 1 sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low" << std::endl; @@ -161,8 +200,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); - gpioIF->pullHigh(gpioIds::GNSS_SELECT); - if (result != HasReturnvaluesIF::RETURN_OK) { + if (gpioIF->pullHigh(gpioIds::GNSS_SELECT) != HasReturnvaluesIF::RETURN_OK) { #if OBSW_VERBOSE_LEVEL >= 1 sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high" << std::endl; @@ -188,12 +226,13 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); + ReturnValue_t status = RETURN_OK; if (defaultSubmode == Submodes::A_SIDE) { - result = gpioIF->pullLow(gpioIds::GNSS_SELECT); + status = gpioIF->pullLow(gpioIds::GNSS_SELECT); } else { - result = gpioIF->pullHigh(gpioIds::GNSS_SELECT); + status = gpioIF->pullHigh(gpioIds::GNSS_SELECT); } - if (result != HasReturnvaluesIF::RETURN_OK) { + if (status != HasReturnvaluesIF::RETURN_OK) { #if OBSW_VERBOSE_LEVEL >= 1 sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to" "default side for dual mode" @@ -209,89 +248,154 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s return result; } -void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { - ReturnValue_t switchStateA = RETURN_OK; - ReturnValue_t switchStateB = RETURN_OK; - if (state == States::IDLE or state == States::SWITCHING_POWER) { - switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); - switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); +ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + using namespace duallane; + if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +void AcsBoardAssembly::handleModeReached() { + using namespace duallane; + if (targetMode == MODE_OFF) { + if (state != PwrStates::IDLE) { + state = PwrStates::IDLE; + } + state = PwrStates::SWITCHING_POWER; + // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function + // will be called + pwrStateMachineWrapper(targetMode, targetSubmode); } else { + finishModeOp(); + } +} + +void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { + using namespace duallane; + // Some ACS board components are required for Safe-Mode. It would be good if the software + // transitions from A side to B side and from B side to dual mode autonomously + // to ensure that that enough sensors are available without an operators intervention. + // Therefore, the lost mode handler was overwritten to start these transitions + Submode_t nextSubmode = Submodes::A_SIDE; + if (submode == Submodes::A_SIDE) { + nextSubmode = Submodes::B_SIDE; + } + if (not tryingOtherSide) { + triggerEvent(CANT_KEEP_MODE, mode, submode); + startTransition(mode, nextSubmode); + tryingOtherSide = true; + } else { + // Not sure when this would happen. This flag is reset if the mode was reached. If it + // was not reached, the transition failure handler should be called. + sif::error << "AcsBoardAssembly::handleChildrenLostMode: Wrong handler called" << std::endl; + triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode); + startTransition(mode, Submodes::DUAL_MODE); + } +} + +void AcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) { + using namespace duallane; + Submode_t nextSubmode = Submodes::A_SIDE; + if (submode == Submodes::A_SIDE) { + nextSubmode = Submodes::B_SIDE; + } + // Check whether the transition was started because the mode could not be kept (not commanded). + // If this is not the case, start transition to other side. If it is the case, start + // transition to dual mode. + if (not tryingOtherSide) { + triggerEvent(CANT_KEEP_MODE, mode, submode); + startTransition(mode, nextSubmode); + tryingOtherSide = true; + } else { + triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode); + startTransition(mode, Submodes::DUAL_MODE); + } +} + +void AcsBoardAssembly::setPreferredSide(duallane::Submodes submode) { + using namespace duallane; + if (submode != Submodes::A_SIDE and submode != Submodes::B_SIDE) { return; } - if (mode == MODE_OFF) { - if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; - } + this->defaultSubmode = submode; +} + +void AcsBoardAssembly::selectGpsInDualMode(duallane::Submodes side) { + using namespace duallane; + if (submode != Submodes::DUAL_MODE) { + return; + } + ReturnValue_t result = RETURN_OK; + if (side == Submodes::A_SIDE) { + result = gpioIF->pullLow(gpioIds::GNSS_SELECT); } else { - switch (submode) { - case (A_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and - switchStateB == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; - } - break; - } - case (B_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_OFF and - switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } - break; - } - case (DUAL_MODE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } - } - } + result = gpioIF->pullHigh(gpioIds::GNSS_SELECT); } - if (state == States::IDLE) { - if (mode == MODE_OFF) { - if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); - } - if (switchStateB != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); - } - } else { - switch (submode) { - case (A_SIDE): { - if (switchStateA != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); - } - if (switchStateB != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); - } - break; - } - case (B_SIDE): { - if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF); - } - if (switchStateB != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); - } - break; - } - case (DUAL_MODE): { - if (switchStateA != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); - } - if (switchStateB != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_ON); - } - break; - } - } - } - state = States::SWITCHING_POWER; + if (result != HasReturnvaluesIF::RETURN_OK) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::error << "AcsBoardAssembly::switchGpsInDualMode: Switching GPS failed" << std::endl; +#endif } - if (state == States::SWITCHING_POWER) { - // TODO: Could check for a timeout (temporal or cycles) here and resend command +} + +void AcsBoardAssembly::refreshHelperModes() { + try { + helper.gyro0SideAMode = childrenMap.at(helper.gyro0AdisIdSideA).mode; + helper.gyro1SideAMode = childrenMap.at(helper.gyro1L3gIdSideA).mode; + helper.gyro2SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode; + helper.gyro3SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode; + helper.mgm0SideAMode = childrenMap.at(helper.mgm0Lis3IdSideA).mode; + helper.mgm1SideAMode = childrenMap.at(helper.mgm1Rm3100IdSideA).mode; + helper.mgm2SideBMode = childrenMap.at(helper.mgm2Lis3IdSideB).mode; + helper.mgm3SideBMode = childrenMap.at(helper.mgm3Rm3100IdSideB).mode; + helper.gpsMode = childrenMap.at(helper.gpsId).mode; + } catch (const std::out_of_range& e) { + sif::error << "AcsBoardAssembly::refreshHelperModes: Invalid map: " << e.what() << std::endl; + } +} + +void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { + entry.setObject(id); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + entry.setInheritSubmode(false); + modeTable.insert(entry); +} + +void AcsBoardAssembly::finishModeOp() { + using namespace duallane; + AssemblyBase::handleModeReached(); + state = PwrStates::IDLE; + tryingOtherSide = false; + dualModeErrorSwitch = true; +} + +void AcsBoardAssembly::pwrStateMachineWrapper(Mode_t mode, Submode_t submode) { + using namespace duallane; + OpCodes opCode = pwrStateMachine.powerStateMachine(mode, submode); + if (opCode == OpCodes::NONE) { + return; + } else if (opCode == OpCodes::FINISH_OP) { + finishModeOp(); + } else if (opCode == OpCodes::START_TRANSITION) { + AssemblyBase::startTransition(mode, submode); } } @@ -334,116 +438,3 @@ ReturnValue_t AcsBoardAssembly::initialize() { } return AssemblyBase::initialize(); } - -ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; -} - -bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { - if (healthHelper.healthTable->isFaulty(object)) { - return false; - } - - // Check if device is already in target mode - if (childrenMap[object].mode == mode) { - return true; - } - - if (healthHelper.healthTable->isCommandable(object)) { - return true; - } - return false; -} - -void AcsBoardAssembly::handleModeReached() { - AssemblyBase::handleModeReached(); - state = States::IDLE; - tryingOtherSide = false; - dualModeErrorSwitch = true; -} - -void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { - // Some ACS board components are required for Safe-Mode. It would be good if the software - // transitions from A side to B side and from B side to dual mode autonomously - // to ensure that that enough sensors are available without an operators intervention. - // Therefore, the lost mode handler was overwritten to start these transitions - Submode_t nextSubmode = Submodes::A_SIDE; - if (submode == Submodes::A_SIDE) { - nextSubmode = Submodes::B_SIDE; - } - if (not tryingOtherSide) { - triggerEvent(CANT_KEEP_MODE, mode, submode); - startTransition(mode, nextSubmode); - tryingOtherSide = true; - } else { - // Not sure when this would happen. This flag is reset if the mode was reached. If it - // was not reached, the transition failure handler should be called. - sif::error << "AcsBoardAssembly::handleChildrenLostMode: Wrong handler called" << std::endl; - triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode); - startTransition(mode, Submodes::DUAL_MODE); - } -} - -void AcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) { - Submode_t nextSubmode = Submodes::A_SIDE; - if (submode == Submodes::A_SIDE) { - nextSubmode = Submodes::B_SIDE; - } - // Check whether the transition was started because the mode could not be kept (not commanded). - // If this is not the case, start transition to other side. If it is the case, start - // transition to dual mode. - if (not tryingOtherSide) { - triggerEvent(CANT_KEEP_MODE, mode, submode); - startTransition(mode, nextSubmode); - tryingOtherSide = true; - } else { - triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode); - startTransition(mode, Submodes::DUAL_MODE); - } -} - -void AcsBoardAssembly::setPreferredSide(Submodes submode) { - if (submode != Submodes::A_SIDE and submode != Submodes::B_SIDE) { - return; - } - this->defaultSubmode = submode; -} - -void AcsBoardAssembly::selectGpsInDualMode(Submodes side) { - if (submode != Submodes::DUAL_MODE) { - return; - } - ReturnValue_t result = RETURN_OK; - if (side == Submodes::A_SIDE) { - result = gpioIF->pullLow(gpioIds::GNSS_SELECT); - } else { - result = gpioIF->pullHigh(gpioIds::GNSS_SELECT); - } - if (result != HasReturnvaluesIF::RETURN_OK) { -#if OBSW_VERBOSE_LEVEL >= 1 - sif::error << "AcsBoardAssembly::switchGpsInDualMode: Switching GPS failed" << std::endl; -#endif - } -} - -void AcsBoardAssembly::refreshHelperModes() { - helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; - helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; - helper.gyro2SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; - helper.gyro3SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode; - helper.mgm0SideAMode = childrenMap[helper.mgm0Lis3IdSideA].mode; - helper.mgm1SideAMode = childrenMap[helper.mgm1Rm3100IdSideA].mode; - helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode; - helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode; -} - -void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { - entry.setObject(id); - entry.setMode(MODE_OFF); - entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); - modeTable.insert(entry); -} diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 640bbad3..ea3d020b 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -6,6 +6,8 @@ #include #include +#include "DualLanePowerStateMachine.h" + struct AcsBoardHelper { AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id, object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id, @@ -58,6 +60,17 @@ enum ModeTableIdx : uint8_t { class PowerSwitchIF; class GpioIF; +/** + * @brief Assembly class which manages redundant ACS board sides + * @details + * This class takes care of ensuring that enough devices on the ACS board are available at all + * times. It does so by doing autonomous transitions to the redundant side or activating both sides + * if not enough devices are available. + * + * This class also takes care of switching on the A side and/or B side power lanes. Normally, + * doing this task would be performed by the device handlers, but this is not possible for the + * ACS board where multiple sensors share the same power supply. + */ class AcsBoardAssembly : public AssemblyBase { public: static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_BOARD_ASS; @@ -67,19 +80,17 @@ class AcsBoardAssembly : public AssemblyBase { event::makeEvent(SUBSYSTEM_ID, 1, severity::HIGH); static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; - enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; - AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, AcsBoardHelper helper, GpioIF* gpioIF); - void setPreferredSide(Submodes submode); + void setPreferredSide(duallane::Submodes submode); /** * In dual mode, the A side or the B side GPS device can be used, but not both. * This function can be used to switch the used GPS device. * @param side */ - void selectGpsInDualMode(Submodes side); + void selectGpsInDualMode(duallane::Submodes side); private: static constexpr pcduSwitches::Switches SWITCH_A = @@ -87,13 +98,13 @@ class AcsBoardAssembly : public AssemblyBase { static constexpr pcduSwitches::Switches SWITCH_B = pcduSwitches::Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3; - enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; - - PowerSwitchIF* pwrSwitcher = nullptr; + // This helper object complete encapsulates power switching + DualLanePowerStateMachine pwrStateMachine; bool tryingOtherSide = false; AcsBoardHelper helper; GpioIF* gpioIF = nullptr; - Submodes defaultSubmode = Submodes::A_SIDE; + duallane::PwrStates state = duallane::PwrStates::IDLE; + duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; bool dualModeErrorSwitch = true; FixedArrayList modeTable; @@ -103,7 +114,8 @@ class AcsBoardAssembly : public AssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; - void handleChildrenTransition() override; + void performChildOperation() override; + void startTransition(Mode_t mode, Submode_t submode) override; void handleModeReached() override; void handleModeTransitionFailed(ReturnValue_t result) override; void handleChildrenLostMode(ReturnValue_t result) override; @@ -116,9 +128,16 @@ class AcsBoardAssembly : public AssemblyBase { */ bool isUseable(object_id_t object, Mode_t mode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); - void powerStateMachine(Mode_t mode, Submode_t submode); void initModeTableEntry(object_id_t id, ModeListEntry& entry); void refreshHelperModes(); + void finishModeOp(); + /** + * Thin wrapper function which is required because the helper class + * can not access protected member functions. + * @param mode + * @param submode + */ + void pwrStateMachineWrapper(Mode_t mode, Submode_t submode); }; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt index 6296de1e..fb8d7096 100644 --- a/mission/system/CMakeLists.txt +++ b/mission/system/CMakeLists.txt @@ -6,4 +6,5 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE EiveSystem.cpp ComSubsystem.cpp TcsSubsystem.cpp + DualLanePowerStateMachine.cpp ) \ No newline at end of file diff --git a/mission/system/DualLanePowerStateMachine.cpp b/mission/system/DualLanePowerStateMachine.cpp new file mode 100644 index 00000000..063814b5 --- /dev/null +++ b/mission/system/DualLanePowerStateMachine.cpp @@ -0,0 +1,98 @@ +#include "DualLanePowerStateMachine.h" + +#include +#include + +DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches switchA, + pcduSwitches::Switches switchB, + PowerSwitchIF* pwrSwitcher, + duallane::PwrStates& state) + : SWITCH_A(switchA), SWITCH_B(switchB), state(state), pwrSwitcher(pwrSwitcher) {} + +duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Submode_t submode) { + using namespace duallane; + ReturnValue_t switchStateA = RETURN_OK; + ReturnValue_t switchStateB = RETURN_OK; + if (state == PwrStates::IDLE or state == PwrStates::SWITCHING_POWER or + state == PwrStates::CHECKING_POWER) { + switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); + switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); + } else { + return OpCodes::NONE; + } + if (mode == HasModesIF::MODE_OFF) { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { + return OpCodes::FINISH_OP; + } + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and + switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = PwrStates::MODE_COMMANDING; + return OpCodes::START_TRANSITION; + } + break; + } + case (B_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and + switchStateB == PowerSwitchIF::SWITCH_ON) { + state = PwrStates::MODE_COMMANDING; + return OpCodes::START_TRANSITION; + } + break; + } + case (DUAL_MODE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { + state = PwrStates::MODE_COMMANDING; + return OpCodes::START_TRANSITION; + } + } + } + } + if (state == PwrStates::SWITCHING_POWER) { + if (mode == HasModesIF::MODE_OFF) { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); + } + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); + } + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); + } + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); + } + break; + } + case (B_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); + } + break; + } + case (DUAL_MODE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_ON); + } + break; + } + } + } + state = PwrStates::CHECKING_POWER; + } + if (state == PwrStates::CHECKING_POWER) { + // TODO: Could check for a timeout (temporal or cycles) here and resend command + } + return OpCodes::NONE; +} diff --git a/mission/system/DualLanePowerStateMachine.h b/mission/system/DualLanePowerStateMachine.h new file mode 100644 index 00000000..f61f6a6f --- /dev/null +++ b/mission/system/DualLanePowerStateMachine.h @@ -0,0 +1,25 @@ +#ifndef MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_ +#define MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_ + +#include +#include + +#include "definitions.h" + +class AssemblyBase; +class PowerSwitchIF; + +class DualLanePowerStateMachine : public HasReturnvaluesIF { + public: + DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, + PowerSwitchIF* pwrSwitcher, duallane::PwrStates& state); + duallane::OpCodes powerStateMachine(Mode_t mode, Submode_t submode); + const pcduSwitches::Switches SWITCH_A; + const pcduSwitches::Switches SWITCH_B; + + private: + duallane::PwrStates& state; + PowerSwitchIF* pwrSwitcher = nullptr; +}; + +#endif /* MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_ */ diff --git a/mission/system/definitions.h b/mission/system/definitions.h new file mode 100644 index 00000000..0d906e6e --- /dev/null +++ b/mission/system/definitions.h @@ -0,0 +1,14 @@ +#ifndef MISSION_SYSTEM_DEFINITIONS_H_ +#define MISSION_SYSTEM_DEFINITIONS_H_ + +#include + +namespace duallane { + +enum class PwrStates { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING }; +enum class OpCodes { NONE, FINISH_OP, START_TRANSITION }; +enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; + +} // namespace duallane + +#endif /* MISSION_SYSTEM_DEFINITIONS_H_ */ From debc72014ae76492226827c25f3bb87bdfb6e320 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 11:08:50 +0100 Subject: [PATCH 15/72] regenerate object and events --- generators/bsp_q7s_events.csv | 7 +++++-- generators/events/translateEvents.cpp | 21 +++++++++++++------ generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 21 +++++++++++++------ linux/fsfwconfig/objects/translateObjects.cpp | 2 +- tmtc | 2 +- 6 files changed, 38 insertions(+), 17 deletions(-) diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 058ca594..9d27debe 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -77,6 +77,9 @@ 8901;CLOCK_SET_FAILURE;LOW;;./fsfw/src/fsfw/pus/Service9TimeManagement.h 9700;TEST;INFO;;./fsfw/src/fsfw/pus/Service17Test.h 10600;CHANGE_OF_SETUP_PARAMETER;LOW;;./fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +10800;SWITCH_CMD_SENT;INFO;Indicated that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;./mission/devices/devicedefinitions/powerDefinitions.h +10801;SWITCH_HAS_CHANGED;INFO;;./mission/devices/devicedefinitions/powerDefinitions.h +10802;SWITCHING_Q7S_DENIED;MEDIUM;;./mission/devices/devicedefinitions/powerDefinitions.h 10900;GPIO_PULL_HIGH_FAILED;LOW;;./mission/devices/HeaterHandler.h 10901;GPIO_PULL_LOW_FAILED;LOW;;./mission/devices/HeaterHandler.h 10902;SWITCH_ALREADY_ON;LOW;;./mission/devices/HeaterHandler.h @@ -106,8 +109,8 @@ 11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;./bsp_q7s/devices/PlocSupervisorHandler.h 11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;./bsp_q7s/devices/PlocSupervisorHandler.h 11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;./bsp_q7s/devices/PlocSupervisorHandler.h -11600;ALLOC_FAILURE;MEDIUM;;./bsp_q7s/core/CoreController.h -11601;REBOOT_SW;MEDIUM; Software reboot occured. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;./bsp_q7s/core/CoreController.h +11600;SANITIZATION_FAILED;LOW;;./bsp_q7s/memory/SdCardManager.h +11601;MOUNTED_SD_CARD;INFO;;./bsp_q7s/memory/SdCardManager.h 11603;REBOOT_HW;MEDIUM;;./bsp_q7s/core/CoreController.h 11700;UPDATE_FILE_NOT_EXISTS;LOW;;./bsp_q7s/devices/PlocUpdater.h 11701;ACTION_COMMANDING_FAILED;LOW;Failed to send command to supervisor handler P1: Return value of CommandActionHelper::commandAction P2: Action ID of command to send;./bsp_q7s/devices/PlocUpdater.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 4f647544..9053e2dd 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 141 translations. + * @brief Auto-generated event translation file. Contains 144 translations. * @details - * Generated on: 2022-03-04 16:42:09 + * Generated on: 2022-03-07 11:07:14 */ #include "translateEvents.h" @@ -84,6 +84,9 @@ const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TEST_STRING = "TEST"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; +const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; +const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; +const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED"; const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED"; const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON"; @@ -113,8 +116,8 @@ 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 *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; +const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS"; const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED"; @@ -307,6 +310,12 @@ const char *translateEvents(Event event) { return TEST_STRING; case (10600): return CHANGE_OF_SETUP_PARAMETER_STRING; + case (10800): + return SWITCH_CMD_SENT_STRING; + case (10801): + return SWITCH_HAS_CHANGED_STRING; + case (10802): + return SWITCHING_Q7S_DENIED_STRING; case (10900): return GPIO_PULL_HIGH_FAILED_STRING; case (10901): @@ -366,9 +375,9 @@ const char *translateEvents(Event event) { case (11504): return SUPV_CRC_FAILURE_EVENT_STRING; case (11600): - return ALLOC_FAILURE_STRING; + return SANITIZATION_FAILED_STRING; case (11601): - return REBOOT_SW_STRING; + return MOUNTED_SD_CARD_STRING; case (11603): return REBOOT_HW_STRING; case (11700): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 37ef3255..c2b56ac5 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-04 16:42:21 + * Generated on: 2022-03-07 11:07:18 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index e29fd1b2..c4c42309 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 141 translations. + * @brief Auto-generated event translation file. Contains 144 translations. * @details - * Generated on: 2022-03-04 16:42:09 + * Generated on: 2022-03-07 11:07:14 */ #include "translateEvents.h" @@ -84,6 +84,9 @@ const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TEST_STRING = "TEST"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; +const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; +const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; +const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED"; const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED"; const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON"; @@ -113,8 +116,8 @@ 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 *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; +const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS"; const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED"; @@ -307,6 +310,12 @@ const char *translateEvents(Event event) { return TEST_STRING; case (10600): return CHANGE_OF_SETUP_PARAMETER_STRING; + case (10800): + return SWITCH_CMD_SENT_STRING; + case (10801): + return SWITCH_HAS_CHANGED_STRING; + case (10802): + return SWITCHING_Q7S_DENIED_STRING; case (10900): return GPIO_PULL_HIGH_FAILED_STRING; case (10901): @@ -366,9 +375,9 @@ const char *translateEvents(Event event) { case (11504): return SUPV_CRC_FAILURE_EVENT_STRING; case (11600): - return ALLOC_FAILURE_STRING; + return SANITIZATION_FAILED_STRING; case (11601): - return REBOOT_SW_STRING; + return MOUNTED_SD_CARD_STRING; case (11603): return REBOOT_HW_STRING; case (11700): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 37ef3255..c2b56ac5 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-04 16:42:21 + * Generated on: 2022-03-07 11:07:18 */ #include "translateObjects.h" diff --git a/tmtc b/tmtc index 07601b73..0bdc8f04 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 07601b734eec162771251e8e5f5fae16d20f1655 +Subproject commit 0bdc8f04a84eea798018f05cc31d079739eab527 From 59b89b730dd9dc2fd7b01f2e298052f13173e50f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 11:34:32 +0100 Subject: [PATCH 16/72] bump fsfwgen dependency --- generators/events/translateEvents.cpp | 2 +- generators/fsfwgen | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 4 ++-- tmtc | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 9053e2dd..cdc81aa6 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 144 translations. * @details - * Generated on: 2022-03-07 11:07:14 + * Generated on: 2022-03-07 11:27:09 */ #include "translateEvents.h" diff --git a/generators/fsfwgen b/generators/fsfwgen index bd767600..52f29169 160000 --- a/generators/fsfwgen +++ b/generators/fsfwgen @@ -1 +1 @@ -Subproject commit bd76760052482f6f8fcdd84b88da963e61c9a48c +Subproject commit 52f291692c4074a23743c799148b0432a4e405fa diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index c4c42309..cdc81aa6 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 144 translations. * @details - * Generated on: 2022-03-07 11:07:14 + * Generated on: 2022-03-07 11:27:09 */ #include "translateEvents.h" @@ -151,7 +151,7 @@ const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; const char *translateEvents(Event event) { - switch ((event & 0xFFFF)) { + switch((event & 0xFFFF)) { case (2200): return STORE_SEND_WRITE_FAILED_STRING; case (2201): diff --git a/tmtc b/tmtc index 0bdc8f04..20753e7c 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 0bdc8f04a84eea798018f05cc31d079739eab527 +Subproject commit 20753e7c75b31c654a7790bc8fcda43771030136 From d5c755a331efe48d29f77ea9da2990f208db6742 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 11:36:40 +0100 Subject: [PATCH 17/72] update events and objects --- generators/bsp_q7s_events.csv | 18 ++++++- generators/bsp_q7s_objects.csv | 1 + generators/events/translateEvents.cpp | 54 ++++++++++++++++--- generators/objects/translateObjects.cpp | 7 ++- linux/fsfwconfig/events/translateEvents.cpp | 54 ++++++++++++++++--- linux/fsfwconfig/objects/translateObjects.cpp | 7 ++- tmtc | 2 +- 7 files changed, 124 insertions(+), 19 deletions(-) diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index fa39dd9b..5850bacd 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -77,6 +77,9 @@ 8901;0x22c5;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h 9700;0x25e4;TEST;INFO;;fsfw/src/fsfw/pus/Service17Test.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;;fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +10800;0x2a30;SWITCH_CMD_SENT;INFO;Indicated that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h +10801;0x2a31;SWITCH_HAS_CHANGED;INFO;;mission/devices/devicedefinitions/powerDefinitions.h +10802;0x2a32;SWITCHING_Q7S_DENIED;MEDIUM;;mission/devices/devicedefinitions/powerDefinitions.h 10900;0x2a94;GPIO_PULL_HIGH_FAILED;LOW;;mission/devices/HeaterHandler.h 10901;0x2a95;GPIO_PULL_LOW_FAILED;LOW;;mission/devices/HeaterHandler.h 10902;0x2a96;SWITCH_ALREADY_ON;LOW;;mission/devices/HeaterHandler.h @@ -106,8 +109,8 @@ 11502;0x2cee;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;bsp_q7s/devices/PlocSupervisorHandler.h 11503;0x2cef;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;bsp_q7s/devices/PlocSupervisorHandler.h 11504;0x2cf0;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;bsp_q7s/devices/PlocSupervisorHandler.h -11600;0x2d50;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h -11601;0x2d51;REBOOT_SW;MEDIUM; Software reboot occured. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +11600;0x2d50;SANITIZATION_FAILED;LOW;;bsp_q7s/memory/SdCardManager.h +11601;0x2d51;MOUNTED_SD_CARD;INFO;;bsp_q7s/memory/SdCardManager.h 11603;0x2d53;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h 11700;0x2db4;UPDATE_FILE_NOT_EXISTS;LOW;;bsp_q7s/devices/PlocUpdater.h 11701;0x2db5;ACTION_COMMANDING_FAILED;LOW;Failed to send command to supervisor handler P1: Return value of CommandActionHelper::commandAction P2: Action ID of command to send;bsp_q7s/devices/PlocUpdater.h @@ -139,3 +142,14 @@ 12014;0x2eee;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/devices/startracker/StrHelper.h 12015;0x2eef;STR_HELPER_SENDING_PACKET_FAILED;LOW;;linux/devices/startracker/StrHelper.h 12016;0x2ef0;STR_HELPER_REQUESTING_MSG_FAILED;LOW;;linux/devices/startracker/StrHelper.h +12101;0x2f45;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12102;0x2f46;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12103;0x2f47;I_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12104;0x2f48;U_X8_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12105;0x2f49;I_X8_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12106;0x2f4a;U_TX_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12107;0x2f4b;I_TX_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12108;0x2f4c;U_MPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12109;0x2f4d;I_MPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12110;0x2f4e;U_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12111;0x2f4f;I_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index a0c0a6dc..da127d35 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -107,6 +107,7 @@ 0x5400CAFE;DUMMY_INTERFACE 0x54123456;LIBGPIOD_TEST 0x54694269;TEST_TASK +0x73000001;ACS_BOARD_ASS 0x73000100;TM_FUNNEL 0x73500000;CCSDS_IP_CORE_BRIDGE 0xFFFFFFFF;NO_OBJECT diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 4b46ede3..9e2ad079 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 141 translations. + * @brief Auto-generated event translation file. Contains 155 translations. * @details - * Generated on: 2022-03-04 15:13:02 + * Generated on: 2022-03-07 11:35:37 */ #include "translateEvents.h" @@ -84,6 +84,9 @@ const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TEST_STRING = "TEST"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; +const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; +const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; +const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED"; const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED"; const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON"; @@ -113,8 +116,8 @@ 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 *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; +const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS"; const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED"; @@ -146,6 +149,17 @@ const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH"; const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS"; const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED"; const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; +const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS"; +const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS"; +const char *I_DRO_OUT_OF_BOUNDS_STRING = "I_DRO_OUT_OF_BOUNDS"; +const char *U_X8_OUT_OF_BOUNDS_STRING = "U_X8_OUT_OF_BOUNDS"; +const char *I_X8_OUT_OF_BOUNDS_STRING = "I_X8_OUT_OF_BOUNDS"; +const char *U_TX_OUT_OF_BOUNDS_STRING = "U_TX_OUT_OF_BOUNDS"; +const char *I_TX_OUT_OF_BOUNDS_STRING = "I_TX_OUT_OF_BOUNDS"; +const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS"; +const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS"; +const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS"; +const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -307,6 +321,12 @@ const char *translateEvents(Event event) { return TEST_STRING; case (10600): return CHANGE_OF_SETUP_PARAMETER_STRING; + case (10800): + return SWITCH_CMD_SENT_STRING; + case (10801): + return SWITCH_HAS_CHANGED_STRING; + case (10802): + return SWITCHING_Q7S_DENIED_STRING; case (10900): return GPIO_PULL_HIGH_FAILED_STRING; case (10901): @@ -366,9 +386,9 @@ const char *translateEvents(Event event) { case (11504): return SUPV_CRC_FAILURE_EVENT_STRING; case (11600): - return ALLOC_FAILURE_STRING; + return SANITIZATION_FAILED_STRING; case (11601): - return REBOOT_SW_STRING; + return MOUNTED_SD_CARD_STRING; case (11603): return REBOOT_HW_STRING; case (11700): @@ -431,6 +451,28 @@ const char *translateEvents(Event event) { return STR_HELPER_SENDING_PACKET_FAILED_STRING; case (12016): return STR_HELPER_REQUESTING_MSG_FAILED_STRING; + case (12101): + return NEG_V_OUT_OF_BOUNDS_STRING; + case (12102): + return U_DRO_OUT_OF_BOUNDS_STRING; + case (12103): + return I_DRO_OUT_OF_BOUNDS_STRING; + case (12104): + return U_X8_OUT_OF_BOUNDS_STRING; + case (12105): + return I_X8_OUT_OF_BOUNDS_STRING; + case (12106): + return U_TX_OUT_OF_BOUNDS_STRING; + case (12107): + return I_TX_OUT_OF_BOUNDS_STRING; + case (12108): + return U_MPA_OUT_OF_BOUNDS_STRING; + case (12109): + return I_MPA_OUT_OF_BOUNDS_STRING; + case (12110): + return U_HPA_OUT_OF_BOUNDS_STRING; + case (12111): + return I_HPA_OUT_OF_BOUNDS_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index b0b6d55d..08724f76 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2022-03-04 15:13:13 + * Contains 113 translations. + * Generated on: 2022-03-07 11:35:40 */ #include "translateObjects.h" @@ -115,6 +115,7 @@ const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE"; const char *LIBGPIOD_TEST_STRING = "LIBGPIOD_TEST"; const char *TEST_TASK_STRING = "TEST_TASK"; +const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -339,6 +340,8 @@ const char *translateObject(object_id_t object) { return LIBGPIOD_TEST_STRING; case 0x54694269: return TEST_TASK_STRING; + case 0x73000001: + return ACS_BOARD_ASS_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73500000: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 4b46ede3..9e2ad079 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 141 translations. + * @brief Auto-generated event translation file. Contains 155 translations. * @details - * Generated on: 2022-03-04 15:13:02 + * Generated on: 2022-03-07 11:35:37 */ #include "translateEvents.h" @@ -84,6 +84,9 @@ const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TEST_STRING = "TEST"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; +const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; +const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; +const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED"; const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED"; const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON"; @@ -113,8 +116,8 @@ 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 *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; +const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS"; const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED"; @@ -146,6 +149,17 @@ const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH"; const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS"; const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED"; const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; +const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS"; +const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS"; +const char *I_DRO_OUT_OF_BOUNDS_STRING = "I_DRO_OUT_OF_BOUNDS"; +const char *U_X8_OUT_OF_BOUNDS_STRING = "U_X8_OUT_OF_BOUNDS"; +const char *I_X8_OUT_OF_BOUNDS_STRING = "I_X8_OUT_OF_BOUNDS"; +const char *U_TX_OUT_OF_BOUNDS_STRING = "U_TX_OUT_OF_BOUNDS"; +const char *I_TX_OUT_OF_BOUNDS_STRING = "I_TX_OUT_OF_BOUNDS"; +const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS"; +const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS"; +const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS"; +const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -307,6 +321,12 @@ const char *translateEvents(Event event) { return TEST_STRING; case (10600): return CHANGE_OF_SETUP_PARAMETER_STRING; + case (10800): + return SWITCH_CMD_SENT_STRING; + case (10801): + return SWITCH_HAS_CHANGED_STRING; + case (10802): + return SWITCHING_Q7S_DENIED_STRING; case (10900): return GPIO_PULL_HIGH_FAILED_STRING; case (10901): @@ -366,9 +386,9 @@ const char *translateEvents(Event event) { case (11504): return SUPV_CRC_FAILURE_EVENT_STRING; case (11600): - return ALLOC_FAILURE_STRING; + return SANITIZATION_FAILED_STRING; case (11601): - return REBOOT_SW_STRING; + return MOUNTED_SD_CARD_STRING; case (11603): return REBOOT_HW_STRING; case (11700): @@ -431,6 +451,28 @@ const char *translateEvents(Event event) { return STR_HELPER_SENDING_PACKET_FAILED_STRING; case (12016): return STR_HELPER_REQUESTING_MSG_FAILED_STRING; + case (12101): + return NEG_V_OUT_OF_BOUNDS_STRING; + case (12102): + return U_DRO_OUT_OF_BOUNDS_STRING; + case (12103): + return I_DRO_OUT_OF_BOUNDS_STRING; + case (12104): + return U_X8_OUT_OF_BOUNDS_STRING; + case (12105): + return I_X8_OUT_OF_BOUNDS_STRING; + case (12106): + return U_TX_OUT_OF_BOUNDS_STRING; + case (12107): + return I_TX_OUT_OF_BOUNDS_STRING; + case (12108): + return U_MPA_OUT_OF_BOUNDS_STRING; + case (12109): + return I_MPA_OUT_OF_BOUNDS_STRING; + case (12110): + return U_HPA_OUT_OF_BOUNDS_STRING; + case (12111): + return I_HPA_OUT_OF_BOUNDS_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index b0b6d55d..08724f76 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2022-03-04 15:13:13 + * Contains 113 translations. + * Generated on: 2022-03-07 11:35:40 */ #include "translateObjects.h" @@ -115,6 +115,7 @@ const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE"; const char *LIBGPIOD_TEST_STRING = "LIBGPIOD_TEST"; const char *TEST_TASK_STRING = "TEST_TASK"; +const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -339,6 +340,8 @@ const char *translateObject(object_id_t object) { return LIBGPIOD_TEST_STRING; case 0x54694269: return TEST_TASK_STRING; + case 0x73000001: + return ACS_BOARD_ASS_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73500000: diff --git a/tmtc b/tmtc index 20753e7c..d132747c 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 20753e7c75b31c654a7790bc8fcda43771030136 +Subproject commit d132747cf98b576fad98f85fc7c5882e8259f051 From b53900071c4b3cf3fd25aa812be06f27427c112f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 13:20:17 +0100 Subject: [PATCH 18/72] subsystem ID bugfix --- generators/bsp_q7s_events.csv | 4 +++- generators/events/event_parser.py | 7 +++++-- generators/events/translateEvents.cpp | 16 +++++++++++----- generators/fsfwgen | 2 +- generators/objects/objects.py | 2 +- generators/returnvalues/returnvalues_parser.py | 2 +- linux/fsfwconfig/events/subsystemIdRanges.h | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 16 +++++++++++----- tmtc | 2 +- 9 files changed, 35 insertions(+), 18 deletions(-) diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 5850bacd..5548ee83 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -111,7 +111,6 @@ 11504;0x2cf0;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;bsp_q7s/devices/PlocSupervisorHandler.h 11600;0x2d50;SANITIZATION_FAILED;LOW;;bsp_q7s/memory/SdCardManager.h 11601;0x2d51;MOUNTED_SD_CARD;INFO;;bsp_q7s/memory/SdCardManager.h -11603;0x2d53;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h 11700;0x2db4;UPDATE_FILE_NOT_EXISTS;LOW;;bsp_q7s/devices/PlocUpdater.h 11701;0x2db5;ACTION_COMMANDING_FAILED;LOW;Failed to send command to supervisor handler P1: Return value of CommandActionHelper::commandAction P2: Action ID of command to send;bsp_q7s/devices/PlocUpdater.h 11702;0x2db6;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;bsp_q7s/devices/PlocUpdater.h @@ -153,3 +152,6 @@ 12109;0x2f4d;I_MPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h 12110;0x2f4e;U_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h 12111;0x2f4f;I_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +13600;0x3520;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h +13601;0x3521;REBOOT_SW;MEDIUM; Software reboot occured. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +13603;0x3523;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h diff --git a/generators/events/event_parser.py b/generators/events/event_parser.py index 7b6b86c8..9398ba98 100644 --- a/generators/events/event_parser.py +++ b/generators/events/event_parser.py @@ -82,7 +82,10 @@ def parse_events( handle_csv_export( file_name=CSV_FILENAME, event_list=event_list, file_separator=FILE_SEPARATOR ) - copy_file(filename=CSV_FILENAME, destination=CSV_COPY_DEST, delete_existing_file=True) + LOGGER.info(f"Copying CSV file to {CSV_COPY_DEST}") + copy_file( + filename=CSV_FILENAME, destination=CSV_COPY_DEST, delete_existing_file=True + ) if generate_cpp: handle_cpp_export( @@ -93,7 +96,7 @@ def parse_events( header_file_name=CPP_H_FILENAME, ) if COPY_CPP_FILE: - LOGGER.info(f"EventParser: Copying file to {CPP_COPY_DESTINATION}") + LOGGER.info(f"EventParser: Copying CPP translation file to {CPP_COPY_DESTINATION}") copy_file(CPP_FILENAME, CPP_COPY_DESTINATION) copy_file(CPP_H_FILENAME, CPP_COPY_DESTINATION) diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 9e2ad079..1f4c169f 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 155 translations. + * @brief Auto-generated event translation file. Contains 157 translations. * @details - * Generated on: 2022-03-07 11:35:37 + * Generated on: 2022-03-07 13:17:06 */ #include "translateEvents.h" @@ -118,7 +118,6 @@ 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 *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; -const char *REBOOT_HW_STRING = "REBOOT_HW"; 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"; @@ -160,6 +159,9 @@ const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS"; const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS"; const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS"; const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS"; +const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; +const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -389,8 +391,6 @@ const char *translateEvents(Event event) { return SANITIZATION_FAILED_STRING; case (11601): return MOUNTED_SD_CARD_STRING; - case (11603): - return REBOOT_HW_STRING; case (11700): return UPDATE_FILE_NOT_EXISTS_STRING; case (11701): @@ -473,6 +473,12 @@ const char *translateEvents(Event event) { return U_HPA_OUT_OF_BOUNDS_STRING; case (12111): return I_HPA_OUT_OF_BOUNDS_STRING; + case (13600): + return ALLOC_FAILURE_STRING; + case (13601): + return REBOOT_SW_STRING; + case (13603): + return REBOOT_HW_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/fsfwgen b/generators/fsfwgen index 52f29169..348877b5 160000 --- a/generators/fsfwgen +++ b/generators/fsfwgen @@ -1 +1 @@ -Subproject commit 52f291692c4074a23743c799148b0432a4e405fa +Subproject commit 348877b5d93ad17db4b03d08b134a2e1c87af2df diff --git a/generators/objects/objects.py b/generators/objects/objects.py index 3ea80e8e..fa174bc1 100644 --- a/generators/objects/objects.py +++ b/generators/objects/objects.py @@ -118,5 +118,5 @@ def handle_file_export(list_items): copy_file( filename=CSV_OBJECT_FILENAME, destination=CSV_COPY_DEST, - delete_existing_file=True + delete_existing_file=True, ) diff --git a/generators/returnvalues/returnvalues_parser.py b/generators/returnvalues/returnvalues_parser.py index 48d929ea..53c84564 100644 --- a/generators/returnvalues/returnvalues_parser.py +++ b/generators/returnvalues/returnvalues_parser.py @@ -87,7 +87,7 @@ def parse_returnvalues(): copy_file( filename=CSV_RETVAL_FILENAME, destination=CSV_COPY_DEST, - delete_existing_file=True + delete_existing_file=True, ) if EXPORT_TO_SQL: LOGGER.info("ReturnvalueParser: Exporting to SQL") diff --git a/linux/fsfwconfig/events/subsystemIdRanges.h b/linux/fsfwconfig/events/subsystemIdRanges.h index 33ef1a09..768797b5 100644 --- a/linux/fsfwconfig/events/subsystemIdRanges.h +++ b/linux/fsfwconfig/events/subsystemIdRanges.h @@ -13,7 +13,7 @@ namespace SUBSYSTEM_ID { enum : uint8_t { SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END, - CORE = 116, + CORE = 136, }; } diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 9e2ad079..1f4c169f 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 155 translations. + * @brief Auto-generated event translation file. Contains 157 translations. * @details - * Generated on: 2022-03-07 11:35:37 + * Generated on: 2022-03-07 13:17:06 */ #include "translateEvents.h" @@ -118,7 +118,6 @@ 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 *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; -const char *REBOOT_HW_STRING = "REBOOT_HW"; 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"; @@ -160,6 +159,9 @@ const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS"; const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS"; const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS"; const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS"; +const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; +const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -389,8 +391,6 @@ const char *translateEvents(Event event) { return SANITIZATION_FAILED_STRING; case (11601): return MOUNTED_SD_CARD_STRING; - case (11603): - return REBOOT_HW_STRING; case (11700): return UPDATE_FILE_NOT_EXISTS_STRING; case (11701): @@ -473,6 +473,12 @@ const char *translateEvents(Event event) { return U_HPA_OUT_OF_BOUNDS_STRING; case (12111): return I_HPA_OUT_OF_BOUNDS_STRING; + case (13600): + return ALLOC_FAILURE_STRING; + case (13601): + return REBOOT_SW_STRING; + case (13603): + return REBOOT_HW_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/tmtc b/tmtc index d132747c..e1d43b8d 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit d132747cf98b576fad98f85fc7c5882e8259f051 +Subproject commit e1d43b8de9e2b09493245fdf6c050b8b819eab41 From f83153934ce5dd1b8d41a7901b5a63c2981c4fee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 14:46:46 +0100 Subject: [PATCH 19/72] command init switch state --- bsp_q7s/core/ObjectFactory.cpp | 2 +- common/config/devices/powerSwitcherList.h | 49 ++++---- mission/devices/PCDUHandler.cpp | 112 +++++++++++------- mission/devices/PCDUHandler.h | 1 + .../devicedefinitions/powerDefinitions.h | 4 +- mission/system/AcsBoardAssembly.cpp | 9 +- 6 files changed, 104 insertions(+), 73 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index cdf95aa2..c0ccb036 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -83,8 +83,8 @@ #include "mission/devices/devicedefinitions/RwDefinitions.h" #include "mission/devices/devicedefinitions/SusDefinitions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" -#include "mission/system/AcsBoardAssembly.h" #include "mission/devices/devicedefinitions/payloadPcduDefinitions.h" +#include "mission/system/AcsBoardAssembly.h" #include "mission/tmtc/CCSDSHandler.h" #include "mission/tmtc/VirtualChannel.h" #include "mission/utility/TmFunnel.h" diff --git a/common/config/devices/powerSwitcherList.h b/common/config/devices/powerSwitcherList.h index a9a75ce4..f99e0930 100644 --- a/common/config/devices/powerSwitcherList.h +++ b/common/config/devices/powerSwitcherList.h @@ -3,6 +3,7 @@ #include "OBSWConfig.h" +#include #include namespace pcduSwitches { @@ -33,32 +34,36 @@ enum Switches: uint8_t { static const uint8_t ON = 1; static const uint8_t OFF = 0; -/* Output states after reboot of the PDUs */ +// Output states after reboot of the PDUs + +const std::array INIT_SWITCH_STATES = { + // PDU 1 +// Because the TE0720 is not connected to the PCDU, this switch is always on #if BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; + ON, #else -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; + OFF, #endif -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; - -static const uint8_t INIT_STATE_Q7S = ON; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; -static const uint8_t INIT_STATE_RW = OFF; -static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; -static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; -static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + // PDU 2 + ON, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF +}; } - #endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index cd07e1d9..b9a1721e 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -77,25 +77,9 @@ ReturnValue_t PCDUHandler::initialize() { void PCDUHandler::initializeSwitchStates() { using namespace pcduSwitches; - switchStates[Switches::PDU2_CH0_Q7S] = pcduSwitches::INIT_STATE_Q7S; - switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1; - switchStates[Switches::PDU2_CH2_RW_5V] = pcduSwitches::INIT_STATE_RW; - switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] = - pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN; - switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = pcduSwitches::INIT_STATE_SUS_REDUNDANT; - switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] = - pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM; - switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6; - switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B; - switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA; - switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3; - switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pcduSwitches::INIT_STATE_SYRLINKS; - switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = pcduSwitches::INIT_STATE_STAR_TRACKER; - switchStates[Switches::PDU1_CH3_MGT_5V] = pcduSwitches::INIT_STATE_MGT; - switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = pcduSwitches::INIT_STATE_SUS_NOMINAL; - switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP; - switchStates[Switches::PDU1_CH6_PLOC_12V] = pcduSwitches::INIT_STATE_PLOC; - switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A; + for (uint8_t idx = 0; idx < Switches::NUMBER_OF_SWITCHES; idx++) { + switchStates[idx] = INIT_SWITCH_STATES[idx]; + } } void PCDUHandler::readCommandQueue() { @@ -178,6 +162,9 @@ void PCDUHandler::updatePdu2SwitchStates() { pdu2HkTableDataset.outEnabledAcsBoardSideB.value); checkAndUpdateSwitch(Switches::PDU2_CH8_PAYLOAD_CAMERA, pdu2HkTableDataset.outEnabledPayloadCamera.value); + if (firstSwitchInfo) { + firstSwitchInfo = false; + } } else { sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" << std::endl; @@ -205,6 +192,9 @@ void PCDUHandler::updatePdu1SwitchStates() { pdu1HkTableDataset.outEnabledAcsBoardSideA.value); checkAndUpdateSwitch(Switches::PDU1_CH8_UNOCCUPIED, pdu1HkTableDataset.outEnabledChannel8.value); + if (firstSwitchInfo) { + firstSwitchInfo = false; + } } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; } @@ -381,6 +371,7 @@ object_id_t PCDUHandler::getObjectId() const { return SystemObject::getObjectId( ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { + using namespace pcduSwitches; localDataPoolMap.emplace(P60System::PDU2_CURRENT_OUT_Q7S, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, new PoolEntry({0})); @@ -419,28 +410,34 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat localDataPoolMap.emplace(P60System::PDU2_CONV_EN_3, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_OUT_EN_Q7S, - new PoolEntry({pcduSwitches::INIT_STATE_Q7S})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, - new PoolEntry({pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1})); + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH0_Q7S]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8]})); localDataPoolMap.emplace(P60System::PDU2_OUT_EN_RW, - new PoolEntry({pcduSwitches::INIT_STATE_RW})); + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH2_RW_5V]})); #if BOARD_TE0720 == 1 localDataPoolMap.emplace(P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry({1})); #else localDataPoolMap.emplace( P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, - new PoolEntry({pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN})); + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V]})); #endif - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_SUS_REDUNDANT, - new PoolEntry({pcduSwitches::INIT_STATE_SUS_REDUNDANT})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, - new PoolEntry({pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, - new PoolEntry({pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_ACS_BOARD_SIDE_B, - new PoolEntry({pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_CAMERA, - new PoolEntry({pcduSwitches::INIT_STATE_PAYLOAD_CAMERA})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_SUS_REDUNDANT, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH4_SUS_REDUNDANT_3V3]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_ACS_BOARD_SIDE_B, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_PAYLOAD_CAMERA, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH8_PAYLOAD_CAMERA]})); localDataPoolMap.emplace(P60System::PDU2_BOOTCAUSE, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_BOOTCNT, new PoolEntry({0})); @@ -502,16 +499,32 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU1_CURRENT_OUT_CHANNEL8, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SYRLINKS, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_STAR_TRACKER, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_MGT, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SUS_NOMINAL, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_PLOC, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A, - new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_CHANNEL8, new PoolEntry({0})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH0_TCS_BOARD_3V3]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_SYRLINKS, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH1_SYRLINKS_12V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_STAR_TRACKER, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH2_STAR_TRACKER_5V]})); + localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_MGT, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH3_MGT_5V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_SUS_NOMINAL, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH4_SUS_NOMINAL_3V3]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_PLOC, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH6_PLOC_12V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH7_ACS_A_SIDE_3V3]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_CHANNEL8, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH8_UNOCCUPIED]})); localDataPoolMap.emplace(P60System::PDU1_VCC, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU1_VBAT, new PoolEntry({0})); @@ -603,8 +616,17 @@ LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) { } void PCDUHandler::checkAndUpdateSwitch(pcduSwitches::Switches switchIdx, uint8_t setValue) { + using namespace pcduSwitches; if (switchStates[switchIdx] != setValue) { - triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); + if (firstSwitchInfo) { + ReturnValue_t state = PowerSwitchIF::SWITCH_OFF; + if (INIT_SWITCH_STATES[switchIdx] == ON) { + state = PowerSwitchIF::SWITCH_ON; + } + sendSwitchCommand(switchIdx, state); + } else { + triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); + } } switchStates[switchIdx] = setValue; } diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index e9649041..cd74a593 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -84,6 +84,7 @@ class PCDUHandler : public PowerSwitchIF, MessageQueueIF* commandQueue = nullptr; size_t cmdQueueSize; + bool firstSwitchInfo = true; PeriodicTaskIF* executingTask = nullptr; diff --git a/mission/devices/devicedefinitions/powerDefinitions.h b/mission/devices/devicedefinitions/powerDefinitions.h index c5e40f12..746bda34 100644 --- a/mission/devices/devicedefinitions/powerDefinitions.h +++ b/mission/devices/devicedefinitions/powerDefinitions.h @@ -7,9 +7,11 @@ namespace power { static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_HANDLER; -//! [EXPORT] : [COMMENT] Indicated that a FSFW object requested setting a switch +//! [EXPORT] : [COMMENT] Indicates that a FSFW object requested setting a switch //! P1: 1 if on was requested, 0 for off | P2: Switch Index static constexpr Event SWITCH_CMD_SENT = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO); +//! [EXPORT] : [COMMENT] Indicated that a swithc state has changed +//! P1: New switch state, 1 for on, 0 for off | P2: Switch Index static constexpr Event SWITCH_HAS_CHANGED = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); static constexpr Event SWITCHING_Q7S_DENIED = event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 39162129..46add801 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -150,12 +150,13 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) { if (mode == DeviceHandlerIF::MODE_NORMAL) { if (isUseable(objectId, devMode)) { - if (devMode == MODE_OFF or devMode == HasModesIF::UNDEFINED_MODE) { - modeTable[tableIdx].setMode(MODE_ON); - modeTable[tableIdx].setSubmode(SUBMODE_NONE); - } else { + if (devMode == MODE_ON) { modeTable[tableIdx].setMode(mode); modeTable[tableIdx].setSubmode(SUBMODE_NONE); + + } else { + modeTable[tableIdx].setMode(MODE_ON); + modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } } else if (mode == MODE_ON) { From b5660d582ea863e39cb18ec9767d88eca9e91e9d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 14:56:21 +0100 Subject: [PATCH 20/72] update switch initializer --- mission/devices/PCDUHandler.cpp | 54 ++++++++++++++++++--------------- mission/devices/PCDUHandler.h | 5 +-- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index b9a1721e..11c84118 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -141,29 +141,30 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet void PCDUHandler::updatePdu2SwitchStates() { using namespace pcduSwitches; + GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2; PoolReadGuard rg(&pdu2HkTableDataset); if (rg.getReadResult() == RETURN_OK) { MutexGuard mg(pwrMutex); - checkAndUpdateSwitch(Switches::PDU2_CH0_Q7S, pdu2HkTableDataset.outEnabledQ7S.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH0_Q7S, pdu2HkTableDataset.outEnabledQ7S.value); - checkAndUpdateSwitch(Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8, pdu2HkTableDataset.outEnabledPlPCDUCh1.value); - checkAndUpdateSwitch(Switches::PDU2_CH2_RW_5V, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH2_RW_5V, pdu2HkTableDataset.outEnabledReactionWheels.value); - checkAndUpdateSwitch(Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V, pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value); - checkAndUpdateSwitch(Switches::PDU2_CH4_SUS_REDUNDANT_3V3, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH4_SUS_REDUNDANT_3V3, pdu2HkTableDataset.outEnabledSUSRedundant.value); - checkAndUpdateSwitch(Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, pdu2HkTableDataset.outEnabledDeplMechanism.value); - checkAndUpdateSwitch(Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8, pdu2HkTableDataset.outEnabledPlPCDUCh6.value); - checkAndUpdateSwitch(Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3, pdu2HkTableDataset.outEnabledAcsBoardSideB.value); - checkAndUpdateSwitch(Switches::PDU2_CH8_PAYLOAD_CAMERA, + checkAndUpdateSwitch(pdu, Switches::PDU2_CH8_PAYLOAD_CAMERA, pdu2HkTableDataset.outEnabledPayloadCamera.value); - if (firstSwitchInfo) { - firstSwitchInfo = false; + if (firstSwitchInfoPdu2) { + firstSwitchInfoPdu2 = false; } } else { sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" @@ -174,26 +175,27 @@ void PCDUHandler::updatePdu2SwitchStates() { void PCDUHandler::updatePdu1SwitchStates() { using namespace pcduSwitches; PoolReadGuard rg(&pdu1HkTableDataset); + GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1; if (rg.getReadResult() == RETURN_OK) { MutexGuard mg(pwrMutex); - checkAndUpdateSwitch(Switches::PDU1_CH0_TCS_BOARD_3V3, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH0_TCS_BOARD_3V3, pdu1HkTableDataset.outEnabledTCSBoard3V3.value); - checkAndUpdateSwitch(Switches::PDU1_CH1_SYRLINKS_12V, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH1_SYRLINKS_12V, pdu1HkTableDataset.outEnabledSyrlinks.value); - checkAndUpdateSwitch(Switches::PDU1_CH2_STAR_TRACKER_5V, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH2_STAR_TRACKER_5V, pdu1HkTableDataset.outEnabledStarTracker.value); - checkAndUpdateSwitch(Switches::PDU1_CH3_MGT_5V, pdu1HkTableDataset.outEnabledMGT.value); - checkAndUpdateSwitch(Switches::PDU1_CH4_SUS_NOMINAL_3V3, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH3_MGT_5V, pdu1HkTableDataset.outEnabledMGT.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH4_SUS_NOMINAL_3V3, pdu1HkTableDataset.outEnabledSUSNominal.value); - checkAndUpdateSwitch(Switches::PDU1_CH5_SOLAR_CELL_EXP_5V, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH5_SOLAR_CELL_EXP_5V, pdu1HkTableDataset.outEnabledSolarCellExp.value); - checkAndUpdateSwitch(Switches::PDU1_CH6_PLOC_12V, pdu1HkTableDataset.outEnabledPLOC.value); - checkAndUpdateSwitch(Switches::PDU1_CH7_ACS_A_SIDE_3V3, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH6_PLOC_12V, pdu1HkTableDataset.outEnabledPLOC.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH7_ACS_A_SIDE_3V3, pdu1HkTableDataset.outEnabledAcsBoardSideA.value); - checkAndUpdateSwitch(Switches::PDU1_CH8_UNOCCUPIED, + checkAndUpdateSwitch(pdu, Switches::PDU1_CH8_UNOCCUPIED, pdu1HkTableDataset.outEnabledChannel8.value); - if (firstSwitchInfo) { - firstSwitchInfo = false; + if (firstSwitchInfoPdu1) { + firstSwitchInfoPdu1 = false; } } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; @@ -615,10 +617,14 @@ LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) { } } -void PCDUHandler::checkAndUpdateSwitch(pcduSwitches::Switches switchIdx, uint8_t setValue) { +void PCDUHandler::checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches switchIdx, + uint8_t setValue) { using namespace pcduSwitches; if (switchStates[switchIdx] != setValue) { - if (firstSwitchInfo) { + // This code initializes the switches to the default init switch states on every reboot. + // This is not done by the PCDU unless it is power-cycled. + if (((pdu == GOMSPACE::Pdu::PDU1) and firstSwitchInfoPdu1) or + ((pdu == GOMSPACE::Pdu::PDU2) and firstSwitchInfoPdu2)) { ReturnValue_t state = PowerSwitchIF::SWITCH_OFF; if (INIT_SWITCH_STATES[switchIdx] == ON) { state = PowerSwitchIF::SWITCH_ON; diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index cd74a593..3d014205 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -84,7 +84,8 @@ class PCDUHandler : public PowerSwitchIF, MessageQueueIF* commandQueue = nullptr; size_t cmdQueueSize; - bool firstSwitchInfo = true; + bool firstSwitchInfoPdu1 = true; + bool firstSwitchInfoPdu2 = true; PeriodicTaskIF* executingTask = nullptr; @@ -118,7 +119,7 @@ class PCDUHandler : public PowerSwitchIF, */ void updateHkTableDataset(store_address_t storeId, LocalPoolDataSetBase* dataset, CCSDSTime::CDS_short* datasetTimeStamp); - void checkAndUpdateSwitch(pcduSwitches::Switches switchIdx, uint8_t setValue); + void checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches switchIdx, uint8_t setValue); }; #endif /* MISSION_DEVICES_PCDUHANDLER_H_ */ From a1ea5db4f0c645eb7362cc87cb23c84f6930321e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 15:27:21 +0100 Subject: [PATCH 21/72] improved preproc handling in obj factory --- bsp_q7s/core/ObjectFactory.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index c0ccb036..6542aa85 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -459,6 +459,7 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI susHandler9->setToGoToNormalMode(true); susHandler10->setToGoToNormalMode(true); susHandler11->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_SUS == 1 susHandler0->enablePeriodicPrintout(true, 3); susHandler1->enablePeriodicPrintout(true, 3); @@ -473,8 +474,6 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI susHandler10->enablePeriodicPrintout(true, 3); susHandler11->enablePeriodicPrintout(true, 3); #endif -#endif - #endif /* OBSW_ADD_SUN_SENSORS == 1 */ } @@ -1240,11 +1239,11 @@ void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* static_cast(plPcduHandler); #if OBSW_TEST_PL_PCDU == 1 plPcduHandler->setStartUpImmediately(); +#endif #if OBSW_DEBUG_PL_PCDU == 1 plPcduHandler->setToGoToNormalModeImmediately(true); plPcduHandler->enablePeriodicPrintout(true, 5); #endif -#endif } void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { From e678b5345214cbff510595fb97487ce7986be843 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 15:55:26 +0100 Subject: [PATCH 22/72] switch initialization is now optional (default on) --- fsfw | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 1 + mission/devices/PCDUHandler.cpp | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 7571987a..a7cb2d43 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 7571987a1d90528d067e2ab86d1b589bc0e89b42 +Subproject commit a7cb2d435456235c28a5041ae783eeee6426ee6d diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index e8c2dff6..36802829 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -41,6 +41,7 @@ debugging. */ #define OBSW_TC_FROM_PDEC 0 #define OBSW_ENABLE_TIMERS 1 +#define OBSW_INITIALIZE_SWITCHES 1 #define OBSW_ADD_MGT 1 #define OBSW_ADD_BPX_BATTERY_HANDLER 1 #define OBSW_ADD_STAR_TRACKER 0 diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 11c84118..2960a6f5 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -621,6 +621,7 @@ void PCDUHandler::checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches uint8_t setValue) { using namespace pcduSwitches; if (switchStates[switchIdx] != setValue) { +#if OBSW_INITIALIZE_SWITCHES == 1 // This code initializes the switches to the default init switch states on every reboot. // This is not done by the PCDU unless it is power-cycled. if (((pdu == GOMSPACE::Pdu::PDU1) and firstSwitchInfoPdu1) or @@ -633,6 +634,9 @@ void PCDUHandler::checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches } else { triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); } +#else + triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); +#endif } switchStates[switchIdx] = setValue; } From d262b8ab8bb4f65bc19e8689ff1d6b497b787d8d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 16:47:15 +0100 Subject: [PATCH 23/72] reattempt power switching at least once --- mission/system/AcsBoardAssembly.cpp | 32 ++++++++++++++------ mission/system/AcsBoardAssembly.h | 6 +++- mission/system/DualLanePowerStateMachine.cpp | 26 ++++++++++++++-- mission/system/DualLanePowerStateMachine.h | 6 +++- mission/system/definitions.h | 2 +- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 46add801..5a82e467 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -53,9 +53,7 @@ void AcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) { using namespace duallane; // If anything other than MODE_OFF is commanded, perform power state machine first if (mode != MODE_OFF) { - if (state != PwrStates::IDLE) { - state = PwrStates::IDLE; - } + pwrStateMachine.reset(); // Cache the target modes, required by power state machine targetMode = mode; targetSubmode = submode; @@ -74,7 +72,10 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) using namespace duallane; ReturnValue_t result = RETURN_OK; refreshHelperModes(); - pwrStateMachineWrapper(mode, submode); + result = pwrStateMachineWrapper(mode, submode); + if (result != RETURN_OK) { + return result; + } if (state == PwrStates::MODE_COMMANDING) { if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { result = handleNormalOrOnModeCmd(mode, submode); @@ -276,9 +277,7 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { void AcsBoardAssembly::handleModeReached() { using namespace duallane; if (targetMode == MODE_OFF) { - if (state != PwrStates::IDLE) { - state = PwrStates::IDLE; - } + pwrStateMachine.reset(); state = PwrStates::SWITCHING_POWER; // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function // will be called @@ -383,21 +382,34 @@ void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) void AcsBoardAssembly::finishModeOp() { using namespace duallane; AssemblyBase::handleModeReached(); - state = PwrStates::IDLE; + pwrStateMachine.reset(); + powerRetryCounter = 0; tryingOtherSide = false; dualModeErrorSwitch = true; } -void AcsBoardAssembly::pwrStateMachineWrapper(Mode_t mode, Submode_t submode) { +ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper(Mode_t mode, Submode_t submode) { using namespace duallane; OpCodes opCode = pwrStateMachine.powerStateMachine(mode, submode); if (opCode == OpCodes::NONE) { - return; + return RETURN_OK; } else if (opCode == OpCodes::FINISH_OP) { finishModeOp(); } else if (opCode == OpCodes::START_TRANSITION) { AssemblyBase::startTransition(mode, submode); + } else if (opCode == OpCodes::TIMEOUT_OCCURED) { + if (powerRetryCounter == 0) { + powerRetryCounter++; + pwrStateMachine.reset(); + } else { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::warning << "Timeout occured in power state machine" << std::endl; +#endif + triggerEvent(POWER_STATE_MACHINE_TIMEOUT, 0, 0); + return RETURN_FAILED; + } } + return RETURN_OK; } ReturnValue_t AcsBoardAssembly::initialize() { diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index ea3d020b..f8c1fb3d 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -78,6 +78,9 @@ class AcsBoardAssembly : public AssemblyBase { event::makeEvent(SUBSYSTEM_ID, 0, severity::HIGH); static constexpr Event NOT_ENOUGH_DEVICES_DUAL_MODE = event::makeEvent(SUBSYSTEM_ID, 1, severity::HIGH); + static constexpr Event POWER_STATE_MACHINE_TIMEOUT = + event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); + static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, @@ -103,6 +106,7 @@ class AcsBoardAssembly : public AssemblyBase { bool tryingOtherSide = false; AcsBoardHelper helper; GpioIF* gpioIF = nullptr; + uint8_t powerRetryCounter = 0; duallane::PwrStates state = duallane::PwrStates::IDLE; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; bool dualModeErrorSwitch = true; @@ -137,7 +141,7 @@ class AcsBoardAssembly : public AssemblyBase { * @param mode * @param submode */ - void pwrStateMachineWrapper(Mode_t mode, Submode_t submode); + ReturnValue_t pwrStateMachineWrapper(Mode_t mode, Submode_t submode); }; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/DualLanePowerStateMachine.cpp b/mission/system/DualLanePowerStateMachine.cpp index 063814b5..1c446ba5 100644 --- a/mission/system/DualLanePowerStateMachine.cpp +++ b/mission/system/DualLanePowerStateMachine.cpp @@ -6,8 +6,17 @@ DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, PowerSwitchIF* pwrSwitcher, - duallane::PwrStates& state) - : SWITCH_A(switchA), SWITCH_B(switchB), state(state), pwrSwitcher(pwrSwitcher) {} + duallane::PwrStates& state, + dur_millis_t checkTimeout) + : SWITCH_A(switchA), + SWITCH_B(switchB), + state(state), + pwrSwitcher(pwrSwitcher), + checkTimeout(checkTimeout) {} + +void DualLanePowerStateMachine::setCheckTimeout(dur_millis_t timeout) { + checkTimeout.setTimeout(timeout); +} duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Submode_t submode) { using namespace duallane; @@ -58,6 +67,7 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm if (switchStateB != PowerSwitchIF::SWITCH_OFF) { pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } + checkTimeout.resetTimer(); } else { switch (submode) { case (A_SIDE): { @@ -67,6 +77,7 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm if (switchStateB != PowerSwitchIF::SWITCH_OFF) { pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } + checkTimeout.resetTimer(); break; } case (B_SIDE): { @@ -76,6 +87,7 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm if (switchStateB != PowerSwitchIF::SWITCH_ON) { pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } + checkTimeout.resetTimer(); break; } case (DUAL_MODE): { @@ -85,6 +97,7 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm if (switchStateB != PowerSwitchIF::SWITCH_ON) { pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_ON); } + checkTimeout.resetTimer(); break; } } @@ -92,7 +105,14 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm state = PwrStates::CHECKING_POWER; } if (state == PwrStates::CHECKING_POWER) { - // TODO: Could check for a timeout (temporal or cycles) here and resend command + if (checkTimeout.hasTimedOut()) { + return OpCodes::TIMEOUT_OCCURED; + } } return OpCodes::NONE; } + +void DualLanePowerStateMachine::reset() { + state = duallane::PwrStates::IDLE; + checkTimeout.resetTimer(); +} diff --git a/mission/system/DualLanePowerStateMachine.h b/mission/system/DualLanePowerStateMachine.h index f61f6a6f..162d34b2 100644 --- a/mission/system/DualLanePowerStateMachine.h +++ b/mission/system/DualLanePowerStateMachine.h @@ -12,7 +12,10 @@ class PowerSwitchIF; class DualLanePowerStateMachine : public HasReturnvaluesIF { public: DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, - PowerSwitchIF* pwrSwitcher, duallane::PwrStates& state); + PowerSwitchIF* pwrSwitcher, duallane::PwrStates& state, + dur_millis_t checkTimeout = 3000); + void setCheckTimeout(dur_millis_t timeout); + void reset(); duallane::OpCodes powerStateMachine(Mode_t mode, Submode_t submode); const pcduSwitches::Switches SWITCH_A; const pcduSwitches::Switches SWITCH_B; @@ -20,6 +23,7 @@ class DualLanePowerStateMachine : public HasReturnvaluesIF { private: duallane::PwrStates& state; PowerSwitchIF* pwrSwitcher = nullptr; + Countdown checkTimeout; }; #endif /* MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_ */ diff --git a/mission/system/definitions.h b/mission/system/definitions.h index 0d906e6e..361f9f65 100644 --- a/mission/system/definitions.h +++ b/mission/system/definitions.h @@ -6,7 +6,7 @@ namespace duallane { enum class PwrStates { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING }; -enum class OpCodes { NONE, FINISH_OP, START_TRANSITION }; +enum class OpCodes { NONE, FINISH_OP, START_TRANSITION, TIMEOUT_OCCURED }; enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; } // namespace duallane From b9139d5c4036769fa348b66c1ac433066941f2fa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 17:03:08 +0100 Subject: [PATCH 24/72] update event list --- generators/bsp_q7s_events.csv | 4 ++-- generators/events/translateEvents.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 2 +- tmtc | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 5548ee83..589a1b76 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -77,8 +77,8 @@ 8901;0x22c5;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h 9700;0x25e4;TEST;INFO;;fsfw/src/fsfw/pus/Service17Test.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;;fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h -10800;0x2a30;SWITCH_CMD_SENT;INFO;Indicated that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h -10801;0x2a31;SWITCH_HAS_CHANGED;INFO;;mission/devices/devicedefinitions/powerDefinitions.h +10800;0x2a30;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h +10801;0x2a31;SWITCH_HAS_CHANGED;INFO;Indicated that a swithc state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 10802;0x2a32;SWITCHING_Q7S_DENIED;MEDIUM;;mission/devices/devicedefinitions/powerDefinitions.h 10900;0x2a94;GPIO_PULL_HIGH_FAILED;LOW;;mission/devices/HeaterHandler.h 10901;0x2a95;GPIO_PULL_LOW_FAILED;LOW;;mission/devices/HeaterHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 1f4c169f..da6f8da3 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 157 translations. * @details - * Generated on: 2022-03-07 13:17:06 + * Generated on: 2022-03-07 17:02:20 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 1f4c169f..da6f8da3 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 157 translations. * @details - * Generated on: 2022-03-07 13:17:06 + * Generated on: 2022-03-07 17:02:20 */ #include "translateEvents.h" diff --git a/tmtc b/tmtc index e1d43b8d..e3344cfb 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e1d43b8de9e2b09493245fdf6c050b8b819eab41 +Subproject commit e3344cfbd237783d42d21c2d7ad97a8381994552 From 597ab9c74c8a88aa2a90f2a924a751602b570799 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 17:10:30 +0100 Subject: [PATCH 25/72] update event list again --- generators/bsp_q7s_events.csv | 5 +++++ generators/events/translateEvents.cpp | 19 +++++++++++++++++-- generators/fsfwgen | 2 +- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 19 +++++++++++++++++-- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- tmtc | 2 +- 7 files changed, 43 insertions(+), 8 deletions(-) diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 589a1b76..6bb34d7d 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -141,6 +141,7 @@ 12014;0x2eee;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/devices/startracker/StrHelper.h 12015;0x2eef;STR_HELPER_SENDING_PACKET_FAILED;LOW;;linux/devices/startracker/StrHelper.h 12016;0x2ef0;STR_HELPER_REQUESTING_MSG_FAILED;LOW;;linux/devices/startracker/StrHelper.h +12100;0x2f44;TRANSITION_BACK_TO_OFF;MEDIUM;Could not transition properly and went back to ALL OFF;mission/devices/PayloadPcduHandler.h 12101;0x2f45;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h 12102;0x2f46;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h 12103;0x2f47;I_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h @@ -152,6 +153,10 @@ 12109;0x2f4d;I_MPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h 12110;0x2f4e;U_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h 12111;0x2f4f;I_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h +12200;0x2fa8;TRANSITION_OTHER_SIDE_FAILED;HIGH;;mission/system/AcsBoardAssembly.h +12201;0x2fa9;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;;mission/system/AcsBoardAssembly.h +12202;0x2faa;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;;mission/system/AcsBoardAssembly.h 13600;0x3520;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h 13601;0x3521;REBOOT_SW;MEDIUM; Software reboot occured. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +13602;0x3522;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h 13603;0x3523;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index da6f8da3..9cbd0bef 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 157 translations. + * @brief Auto-generated event translation file. Contains 162 translations. * @details - * Generated on: 2022-03-07 17:02:20 + * Generated on: 2022-03-07 17:09:35 */ #include "translateEvents.h" @@ -148,6 +148,7 @@ const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH"; const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS"; const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED"; const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; +const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF"; const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS"; const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS"; const char *I_DRO_OUT_OF_BOUNDS_STRING = "I_DRO_OUT_OF_BOUNDS"; @@ -159,8 +160,12 @@ const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS"; const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS"; const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS"; const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS"; +const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"; +const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; +const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *translateEvents(Event event) { @@ -451,6 +456,8 @@ const char *translateEvents(Event event) { return STR_HELPER_SENDING_PACKET_FAILED_STRING; case (12016): return STR_HELPER_REQUESTING_MSG_FAILED_STRING; + case (12100): + return TRANSITION_BACK_TO_OFF_STRING; case (12101): return NEG_V_OUT_OF_BOUNDS_STRING; case (12102): @@ -473,10 +480,18 @@ const char *translateEvents(Event event) { return U_HPA_OUT_OF_BOUNDS_STRING; case (12111): return I_HPA_OUT_OF_BOUNDS_STRING; + case (12200): + return TRANSITION_OTHER_SIDE_FAILED_STRING; + case (12201): + return NOT_ENOUGH_DEVICES_DUAL_MODE_STRING; + case (12202): + return POWER_STATE_MACHINE_TIMEOUT_STRING; case (13600): return ALLOC_FAILURE_STRING; case (13601): return REBOOT_SW_STRING; + case (13602): + return REBOOT_MECHANISM_TRIGGERED_STRING; case (13603): return REBOOT_HW_STRING; default: diff --git a/generators/fsfwgen b/generators/fsfwgen index 348877b5..c5ef1783 160000 --- a/generators/fsfwgen +++ b/generators/fsfwgen @@ -1 +1 @@ -Subproject commit 348877b5d93ad17db4b03d08b134a2e1c87af2df +Subproject commit c5ef1783a3b082c0e88561bd91bc3ee0f459fafc diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 08724f76..5986eeac 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-07 11:35:40 + * Generated on: 2022-03-07 17:04:59 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index da6f8da3..9cbd0bef 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 157 translations. + * @brief Auto-generated event translation file. Contains 162 translations. * @details - * Generated on: 2022-03-07 17:02:20 + * Generated on: 2022-03-07 17:09:35 */ #include "translateEvents.h" @@ -148,6 +148,7 @@ const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH"; const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS"; const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED"; const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; +const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF"; const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS"; const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS"; const char *I_DRO_OUT_OF_BOUNDS_STRING = "I_DRO_OUT_OF_BOUNDS"; @@ -159,8 +160,12 @@ const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS"; const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS"; const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS"; const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS"; +const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"; +const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; +const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *translateEvents(Event event) { @@ -451,6 +456,8 @@ const char *translateEvents(Event event) { return STR_HELPER_SENDING_PACKET_FAILED_STRING; case (12016): return STR_HELPER_REQUESTING_MSG_FAILED_STRING; + case (12100): + return TRANSITION_BACK_TO_OFF_STRING; case (12101): return NEG_V_OUT_OF_BOUNDS_STRING; case (12102): @@ -473,10 +480,18 @@ const char *translateEvents(Event event) { return U_HPA_OUT_OF_BOUNDS_STRING; case (12111): return I_HPA_OUT_OF_BOUNDS_STRING; + case (12200): + return TRANSITION_OTHER_SIDE_FAILED_STRING; + case (12201): + return NOT_ENOUGH_DEVICES_DUAL_MODE_STRING; + case (12202): + return POWER_STATE_MACHINE_TIMEOUT_STRING; case (13600): return ALLOC_FAILURE_STRING; case (13601): return REBOOT_SW_STRING; + case (13602): + return REBOOT_MECHANISM_TRIGGERED_STRING; case (13603): return REBOOT_HW_STRING; default: diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 08724f76..5986eeac 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-07 11:35:40 + * Generated on: 2022-03-07 17:04:59 */ #include "translateObjects.h" diff --git a/tmtc b/tmtc index e3344cfb..eb7fd71e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e3344cfbd237783d42d21c2d7ad97a8381994552 +Subproject commit eb7fd71eaf9872281ee086e858028658863dd89d From 62229cb9992742525faa1a622b9012285bd4297a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 18:39:33 +0100 Subject: [PATCH 26/72] bugfixes for NORMAL to OFF transition --- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- mission/system/AcsBoardAssembly.cpp | 98 ++++++++----------- mission/system/AcsBoardAssembly.h | 4 +- mission/system/DualLanePowerStateMachine.cpp | 44 ++++++--- mission/system/DualLanePowerStateMachine.h | 12 ++- tmtc | 2 +- 7 files changed, 85 insertions(+), 79 deletions(-) diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 5986eeac..b29ed5db 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-07 17:04:59 + * Generated on: 2022-03-07 17:15:28 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 5986eeac..b29ed5db 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-07 17:04:59 + * Generated on: 2022-03-07 17:15:28 */ #include "translateObjects.h" diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 5a82e467..286bb106 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -7,7 +7,7 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, AcsBoardHelper helper, GpioIF* gpioIF) : AssemblyBase(objectId, parentId), - pwrStateMachine(SWITCH_A, SWITCH_B, switcher, state), + pwrStateMachine(SWITCH_A, SWITCH_B, switcher), helper(helper), gpioIF(gpioIF) { if (switcher == nullptr) { @@ -32,35 +32,28 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, void AcsBoardAssembly::performChildOperation() { using namespace duallane; - if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) { - if (targetMode != MODE_OFF) { - pwrStateMachineWrapper(targetMode, targetSubmode); - } + if (pwrStateMachine.active()) { + pwrStateMachineWrapper(); // This state is the indicator that the power state machine is done - if (state == PwrStates::MODE_COMMANDING) { - AssemblyBase::performChildOperation(); - } - } else { + } + if (not pwrStateMachine.active()) { AssemblyBase::performChildOperation(); - // This state is the indicator that the mode state machine is done - if (state == PwrStates::SWITCHING_POWER) { - pwrStateMachineWrapper(targetMode, targetSubmode); - } } } void AcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) { using namespace duallane; + pwrStateMachine.reset(); // If anything other than MODE_OFF is commanded, perform power state machine first if (mode != MODE_OFF) { - pwrStateMachine.reset(); // Cache the target modes, required by power state machine + pwrStateMachine.start(mode, submode); + // Cache these for later after the power state machine has finished targetMode = mode; targetSubmode = submode; - state = PwrStates::SWITCHING_POWER; // Perform power state machine first, then start mode transition. The power state machine will // start the transition after it has finished - pwrStateMachineWrapper(mode, submode); + pwrStateMachineWrapper(); } else { // Command the devices to off first before switching off the power. The handleModeReached // custom implementation will take care of starting the power state machine. @@ -72,47 +65,41 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) using namespace duallane; ReturnValue_t result = RETURN_OK; refreshHelperModes(); - result = pwrStateMachineWrapper(mode, submode); - if (result != RETURN_OK) { - return result; - } - if (state == PwrStates::MODE_COMMANDING) { - if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { - result = handleNormalOrOnModeCmd(mode, submode); - } else { - modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); - } - HybridIterator tableIter(modeTable.begin(), modeTable.end()); - executeTable(tableIter); + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + result = handleNormalOrOnModeCmd(mode, submode); + } else { + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } + HybridIterator tableIter(modeTable.begin(), modeTable.end()); + executeTable(tableIter); return result; } ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { using namespace duallane; refreshHelperModes(); - if (state == PwrStates::SWITCHING_POWER) { - // Wrong mode - sif::error << "Wrong mode, currently switching power" << std::endl; - return RETURN_OK; - } + // if (state == PwrStates::SWITCHING_POWER) { + // // Wrong mode + // sif::error << "Wrong mode, currently switching power" << std::endl; + // return RETURN_OK; + // } if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or @@ -277,11 +264,10 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { void AcsBoardAssembly::handleModeReached() { using namespace duallane; if (targetMode == MODE_OFF) { - pwrStateMachine.reset(); - state = PwrStates::SWITCHING_POWER; + pwrStateMachine.start(targetMode, targetSubmode); // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function // will be called - pwrStateMachineWrapper(targetMode, targetSubmode); + pwrStateMachineWrapper(); } else { finishModeOp(); } @@ -388,15 +374,15 @@ void AcsBoardAssembly::finishModeOp() { dualModeErrorSwitch = true; } -ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper(Mode_t mode, Submode_t submode) { +ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper() { using namespace duallane; - OpCodes opCode = pwrStateMachine.powerStateMachine(mode, submode); + OpCodes opCode = pwrStateMachine.powerStateMachine(); if (opCode == OpCodes::NONE) { return RETURN_OK; } else if (opCode == OpCodes::FINISH_OP) { finishModeOp(); } else if (opCode == OpCodes::START_TRANSITION) { - AssemblyBase::startTransition(mode, submode); + AssemblyBase::startTransition(targetMode, targetSubmode); } else if (opCode == OpCodes::TIMEOUT_OCCURED) { if (powerRetryCounter == 0) { powerRetryCounter++; diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index f8c1fb3d..7f2a85fa 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -107,7 +107,7 @@ class AcsBoardAssembly : public AssemblyBase { AcsBoardHelper helper; GpioIF* gpioIF = nullptr; uint8_t powerRetryCounter = 0; - duallane::PwrStates state = duallane::PwrStates::IDLE; + // duallane::PwrStates state = duallane::PwrStates::IDLE; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; bool dualModeErrorSwitch = true; FixedArrayList modeTable; @@ -141,7 +141,7 @@ class AcsBoardAssembly : public AssemblyBase { * @param mode * @param submode */ - ReturnValue_t pwrStateMachineWrapper(Mode_t mode, Submode_t submode); + ReturnValue_t pwrStateMachineWrapper(); }; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/DualLanePowerStateMachine.cpp b/mission/system/DualLanePowerStateMachine.cpp index 1c446ba5..16465358 100644 --- a/mission/system/DualLanePowerStateMachine.cpp +++ b/mission/system/DualLanePowerStateMachine.cpp @@ -6,35 +6,49 @@ DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, PowerSwitchIF* pwrSwitcher, - duallane::PwrStates& state, dur_millis_t checkTimeout) - : SWITCH_A(switchA), - SWITCH_B(switchB), - state(state), - pwrSwitcher(pwrSwitcher), - checkTimeout(checkTimeout) {} + : SWITCH_A(switchA), SWITCH_B(switchB), pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {} void DualLanePowerStateMachine::setCheckTimeout(dur_millis_t timeout) { checkTimeout.setTimeout(timeout); } -duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Submode_t submode) { +void DualLanePowerStateMachine::start(Mode_t mode, Submode_t submode) { + checkTimeout.resetTimer(); + targetMode = mode; + targetSubmode = submode; + state = duallane::PwrStates::SWITCHING_POWER; +} + +duallane::PwrStates DualLanePowerStateMachine::getState() const { return state; } + +bool DualLanePowerStateMachine::active() { + if (state == duallane::PwrStates::IDLE or state == duallane::PwrStates::MODE_COMMANDING) { + return false; + } + return true; +} + +duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { using namespace duallane; ReturnValue_t switchStateA = RETURN_OK; ReturnValue_t switchStateB = RETURN_OK; - if (state == PwrStates::IDLE or state == PwrStates::SWITCHING_POWER or - state == PwrStates::CHECKING_POWER) { + if (state == PwrStates::IDLE or state == PwrStates::MODE_COMMANDING) { + return duallane::OpCodes::NONE; + } + if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) { switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); } else { return OpCodes::NONE; } - if (mode == HasModesIF::MODE_OFF) { + if (targetMode == HasModesIF::MODE_OFF) { if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = PwrStates::IDLE; return OpCodes::FINISH_OP; } } else { - switch (submode) { + switch (targetSubmode) { case (A_SIDE): { if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { @@ -60,16 +74,16 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm } } if (state == PwrStates::SWITCHING_POWER) { - if (mode == HasModesIF::MODE_OFF) { + if (targetMode == HasModesIF::MODE_OFF) { if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF); } if (switchStateB != PowerSwitchIF::SWITCH_OFF) { pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } checkTimeout.resetTimer(); } else { - switch (submode) { + switch (targetSubmode) { case (A_SIDE): { if (switchStateA != PowerSwitchIF::SWITCH_ON) { pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); @@ -114,5 +128,7 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm void DualLanePowerStateMachine::reset() { state = duallane::PwrStates::IDLE; + targetMode = HasModesIF::MODE_OFF; + targetSubmode = 0; checkTimeout.resetTimer(); } diff --git a/mission/system/DualLanePowerStateMachine.h b/mission/system/DualLanePowerStateMachine.h index 162d34b2..bb4b3946 100644 --- a/mission/system/DualLanePowerStateMachine.h +++ b/mission/system/DualLanePowerStateMachine.h @@ -12,17 +12,21 @@ class PowerSwitchIF; class DualLanePowerStateMachine : public HasReturnvaluesIF { public: DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, - PowerSwitchIF* pwrSwitcher, duallane::PwrStates& state, - dur_millis_t checkTimeout = 3000); + PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout = 5000); void setCheckTimeout(dur_millis_t timeout); void reset(); - duallane::OpCodes powerStateMachine(Mode_t mode, Submode_t submode); + void start(Mode_t mode, Submode_t submode); + bool active(); + duallane::PwrStates getState() const; + duallane::OpCodes powerStateMachine(); const pcduSwitches::Switches SWITCH_A; const pcduSwitches::Switches SWITCH_B; private: - duallane::PwrStates& state; + duallane::PwrStates state = duallane::PwrStates::IDLE; PowerSwitchIF* pwrSwitcher = nullptr; + Mode_t targetMode = HasModesIF::MODE_OFF; + Submode_t targetSubmode = 0; Countdown checkTimeout; }; diff --git a/tmtc b/tmtc index eb7fd71e..d64d443a 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit eb7fd71eaf9872281ee086e858028658863dd89d +Subproject commit d64d443a99a911f946402e59b276566954b5b52b From 84dead546c113965b30175ee05fc2d89fd0d22c6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Mar 2022 09:54:02 +0100 Subject: [PATCH 27/72] name fix --- linux/devices/GPSHyperionLinuxController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GPSHyperionLinuxController.cpp index f10b144b..3260818c 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GPSHyperionLinuxController.cpp @@ -36,7 +36,7 @@ ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_ maxTimeToReachFix.resetTimer(); modeCommanded = true; } else if (mode == MODE_NORMAL) { - return HasModesIF::INVALID_MODE_RETVAL; + return HasModesIF::INVALID_MODE; } } return HasReturnvaluesIF::RETURN_OK; From b66b1e0fff34074d543ad0be138fe5a4780426ef Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Mar 2022 10:17:24 +0100 Subject: [PATCH 28/72] use new version getter function --- bsp_q7s/core/obsw.cpp | 7 +++++-- bsp_q7s/devices/PlocSupervisorHandler.h | 2 +- bsp_q7s/memory/SdCardManager.cpp | 2 +- fsfw | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 04163a82..4b0639f7 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -6,13 +6,15 @@ #include "InitMission.h" #include "OBSWConfig.h" #include "OBSWVersion.h" -#include "fsfw/FSFWVersion.h" #include "fsfw/tasks/TaskFactory.h" +#include "fsfw/version.h" #include "watchdogConf.h" static int OBSW_ALREADY_RUNNING = -2; int obsw::obsw() { + fsfw::Version version; + fsfw::getVersion(version); std::cout << "-- EIVE OBSW --" << std::endl; #if BOARD_TE0720 == 0 std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl; @@ -20,7 +22,8 @@ int obsw::obsw() { std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; #endif std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" - << FSFW_VERSION << "." << FSFW_SUBVERSION << "." << FSFW_REVISION << "--" << std::endl; + << version.major << "." << version.minor << "." << version.revision << "--" + << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; #if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 diff --git a/bsp_q7s/devices/PlocSupervisorHandler.h b/bsp_q7s/devices/PlocSupervisorHandler.h index 1a77af6a..b85b8ace 100644 --- a/bsp_q7s/devices/PlocSupervisorHandler.h +++ b/bsp_q7s/devices/PlocSupervisorHandler.h @@ -1,11 +1,11 @@ #ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ #define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ -#include "OBSWConfig.h" #include #include #include +#include "OBSWConfig.h" #include "devicedefinitions/PlocSupervisorDefinitions.h" /** diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index b76cee12..b336b84c 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -1,6 +1,5 @@ #include "SdCardManager.h" -#include "OBSWConfig.h" #include #include #include @@ -10,6 +9,7 @@ #include #include +#include "OBSWConfig.h" #include "common/config/commonObjects.h" #include "fsfw/ipc/MutexFactory.h" #include "fsfw/serviceinterface/ServiceInterface.h" diff --git a/fsfw b/fsfw index 84f95e8d..3b497dbb 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 84f95e8d7641be7a83faf1cbee718c6cc5de152d +Subproject commit 3b497dbb8dae77f1cf28f50f7ba770c4256acd2d From b9c1523e81ae80bcb274e8d741fb42f105d64d4a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Mar 2022 10:28:07 +0100 Subject: [PATCH 29/72] bump version --- common/config/OBSWVersion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/OBSWVersion.h b/common/config/OBSWVersion.h index 39cb356a..f719a274 100644 --- a/common/config/OBSWVersion.h +++ b/common/config/OBSWVersion.h @@ -4,7 +4,7 @@ const char* const SW_NAME = "eive"; #define SW_VERSION 1 -#define SW_SUBVERSION 8 +#define SW_SUBVERSION 9 #define SW_REVISION 0 #endif /* COMMON_CONFIG_OBSWVERSION_H_ */ From 3dbf66383ab854d080c908769ab2dcd0591c7af0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Mar 2022 11:57:27 +0100 Subject: [PATCH 30/72] minor fixes --- bsp_q7s/memory/SdCardManager.cpp | 2 +- bsp_q7s/memory/scratchApi.h | 2 +- fsfw | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index b336b84c..4ca11787 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -406,7 +406,7 @@ SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations& currentOp) { bool bytesRead = false; #if OBSW_ENABLE_TIMERS == 1 - Countdown timer(100); + Countdown timer(1000); #endif while (true) { ReturnValue_t result = cmdExecutor.check(bytesRead); diff --git a/bsp_q7s/memory/scratchApi.h b/bsp_q7s/memory/scratchApi.h index babd26dc..96264995 100644 --- a/bsp_q7s/memory/scratchApi.h +++ b/bsp_q7s/memory/scratchApi.h @@ -75,7 +75,7 @@ ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& fil int result = std::system(oss.str().c_str()); if (result != 0) { - if (result == 256) { + if (WEXITSTATUS(result) == 1) { sif::warning << "scratch::readNumber: Key " << name << " does not exist" << std::endl; // Could not find value std::remove(filename.c_str()); diff --git a/fsfw b/fsfw index 3b497dbb..d63c01b9 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 3b497dbb8dae77f1cf28f50f7ba770c4256acd2d +Subproject commit d63c01b96f2eb031eb4d568879dfee2e2151537a From 95e694d01a7bdf2a36bcdb10629472c8b0d09c06 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Mar 2022 13:08:50 +0100 Subject: [PATCH 31/72] add quiet flag --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03d51ac2..e6c07ee5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,7 @@ set(FSFW_ADDITIONAL_INC_PATHS ) # Check whether the user has already installed Catch2 first -find_package(Catch2 3) +find_package(Catch2 3 QUIET) ################################################################################ # Executable and Sources From d836f6ea10fa2f13e03165ac6f904434f13a0389 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 9 Mar 2022 18:21:05 +0100 Subject: [PATCH 32/72] small tweaks --- generators/returnvalues/returnvalues_parser.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/generators/returnvalues/returnvalues_parser.py b/generators/returnvalues/returnvalues_parser.py index 53c84564..5bcf3bc2 100644 --- a/generators/returnvalues/returnvalues_parser.py +++ b/generators/returnvalues/returnvalues_parser.py @@ -1,14 +1,7 @@ -#! /usr/bin/python3 +#! /usr/bin/env python3 # -*- coding: utf-8 -*- -""" -:file: returnvalues_parser.py -:brief: Part of the MOD export tools for the SOURCE project by KSat. -TODO: Integrate into Parser Structure instead of calling this file (no cpp file generated yet) -:details: -Return Value exporter. -To use MySQLdb, run pip install mysqlclient or install in IDE. On Windows, Build Tools -installation might be necessary. -:data: 21.11.2019 +"""Part of the MIB export tools for the EIVE project by. +Returnvalue exporter. """ from fsfwgen.core import get_console_logger from fsfwgen.utility.file_management import copy_file From 85372a10c8a7e60f7f5adfdfcf68f1d97f290b29 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 9 Mar 2022 19:12:08 +0100 Subject: [PATCH 33/72] fsfw and tmtc update --- fsfw | 2 +- tmtc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index d63c01b9..06577ed7 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit d63c01b96f2eb031eb4d568879dfee2e2151537a +Subproject commit 06577ed78ae404bdb457be7c78bd29bffbc04f6a diff --git a/tmtc b/tmtc index abe9c8bc..de68ad93 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit abe9c8bc000e834b99a2c367ed10f927eeb666b0 +Subproject commit de68ad9341fbe5570b84305f33562702e3486364 From 406f44ae2665fca2ccf681a2c98d2a2d3b111e95 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 9 Mar 2022 19:26:49 +0100 Subject: [PATCH 34/72] update for version handling --- bsp_q7s/core/obsw.cpp | 6 +++--- tmtc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 4b0639f7..ca7271ce 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -13,7 +13,7 @@ static int OBSW_ALREADY_RUNNING = -2; int obsw::obsw() { - fsfw::Version version; + using namespace fsfw; fsfw::getVersion(version); std::cout << "-- EIVE OBSW --" << std::endl; #if BOARD_TE0720 == 0 @@ -22,8 +22,8 @@ int obsw::obsw() { std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; #endif std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" - << version.major << "." << version.minor << "." << version.revision << "--" - << std::endl; + << FSFW_VERSION.major << "." << FSFW_VERSION.minor << "." << FSFW_VERSION.revision + << "--" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; #if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 diff --git a/tmtc b/tmtc index de68ad93..eedb45e4 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit de68ad9341fbe5570b84305f33562702e3486364 +Subproject commit eedb45e4f34bd77d328745808e9acfe4668a1e35 From 3f54a3a5a5dc768147bcd5ea41e1d5f414391df7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 09:48:01 +0100 Subject: [PATCH 35/72] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 06577ed7..60639f56 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 06577ed78ae404bdb457be7c78bd29bffbc04f6a +Subproject commit 60639f56dc924576e9d98c0a271cb6515e3c87b6 From 662e8cae17e5bfca71c5260a4f30439cb8fe5a25 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 09:56:31 +0100 Subject: [PATCH 36/72] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 60639f56..b5d6b974 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 60639f56dc924576e9d98c0a271cb6515e3c87b6 +Subproject commit b5d6b9745f3e5fdd10463677ca2acb688cad4e84 From 1dcf34f3baaf9cb55a34e6b0d85180ad23a2223f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 09:59:25 +0100 Subject: [PATCH 37/72] small fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index b5d6b974..17262a1d 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit b5d6b9745f3e5fdd10463677ca2acb688cad4e84 +Subproject commit 17262a1da91a92c3b5995ccfbd67d439d01bb456 From 03aba8b08083cdc386f5682a49e495db3d988f79 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 10:04:26 +0100 Subject: [PATCH 38/72] fixes where FSFW version is used --- bsp_q7s/core/CoreController.cpp | 8 ++++---- bsp_q7s/core/obsw.cpp | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b1783054..6c176eb1 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,7 +4,7 @@ #include "OBSWConfig.h" #include "OBSWVersion.h" -#include "fsfw/FSFWVersion.h" +#include "fsfw/version.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/timemanager/Stopwatch.h" #include "watchdogConf.h" @@ -624,9 +624,9 @@ ReturnValue_t CoreController::initVersionFile() { std::string fullObswVersionString = "OBSW: v" + std::to_string(SW_VERSION) + "." + std::to_string(SW_SUBVERSION) + "." + std::to_string(SW_REVISION); - std::string fullFsfwVersionString = "FSFW: v" + std::to_string(FSFW_VERSION) + "." + - std::to_string(FSFW_SUBVERSION) + "." + - std::to_string(FSFW_REVISION); + char versionString[16] = {}; + fsfw::FSFW_VERSION.getVersion(versionString, sizeof(versionString)); + std::string fullFsfwVersionString = "FSFW: v" + std::string(versionString); std::string systemString = "System: " + unameLine; std::string mountPrefix = SdCardManager::instance()->getCurrentMountPrefix(); std::string versionFilePath = mountPrefix + VERSION_FILE; diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index ca7271ce..197ca66b 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -14,7 +14,6 @@ static int OBSW_ALREADY_RUNNING = -2; int obsw::obsw() { using namespace fsfw; - fsfw::getVersion(version); std::cout << "-- EIVE OBSW --" << std::endl; #if BOARD_TE0720 == 0 std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl; @@ -22,8 +21,7 @@ int obsw::obsw() { std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; #endif std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" - << FSFW_VERSION.major << "." << FSFW_VERSION.minor << "." << FSFW_VERSION.revision - << "--" << std::endl; + << FSFW_VERSION << "--" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; #if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 From 1742371c1429dd664963fb31e16416e7ef4a629d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 10:54:27 +0100 Subject: [PATCH 39/72] created new dual lane assembly base --- bsp_q7s/core/CoreController.cpp | 2 +- mission/system/AcsBoardAssembly.cpp | 118 +++--------------------- mission/system/AcsBoardAssembly.h | 33 ++----- mission/system/CMakeLists.txt | 1 + mission/system/DualLaneAssemblyBase.cpp | 92 ++++++++++++++++++ mission/system/DualLaneAssemblyBase.h | 66 +++++++++++++ 6 files changed, 178 insertions(+), 134 deletions(-) create mode 100644 mission/system/DualLaneAssemblyBase.cpp create mode 100644 mission/system/DualLaneAssemblyBase.h diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 6c176eb1..89d9ce14 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,9 +4,9 @@ #include "OBSWConfig.h" #include "OBSWVersion.h" -#include "fsfw/version.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/timemanager/Stopwatch.h" +#include "fsfw/version.h" #include "watchdogConf.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 286bb106..76e2d916 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -6,8 +6,8 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, AcsBoardHelper helper, GpioIF* gpioIF) - : AssemblyBase(objectId, parentId), - pwrStateMachine(SWITCH_A, SWITCH_B, switcher), + : DualLaneAssemblyBase(objectId, parentId, switcher, SWITCH_A, SWITCH_B, + POWER_STATE_MACHINE_TIMEOUT), helper(helper), gpioIF(gpioIF) { if (switcher == nullptr) { @@ -19,46 +19,15 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid GPIO IF passed" << std::endl; } ModeListEntry entry; - initModeTableEntry(helper.mgm0Lis3IdSideA, entry); - initModeTableEntry(helper.mgm1Rm3100IdSideA, entry); - initModeTableEntry(helper.mgm2Lis3IdSideB, entry); - initModeTableEntry(helper.mgm3Rm3100IdSideB, entry); - initModeTableEntry(helper.gyro0AdisIdSideA, entry); - initModeTableEntry(helper.gyro1L3gIdSideA, entry); - initModeTableEntry(helper.gyro2AdisIdSideB, entry); - initModeTableEntry(helper.gyro3L3gIdSideB, entry); - initModeTableEntry(helper.gpsId, entry); -} - -void AcsBoardAssembly::performChildOperation() { - using namespace duallane; - if (pwrStateMachine.active()) { - pwrStateMachineWrapper(); - // This state is the indicator that the power state machine is done - } - if (not pwrStateMachine.active()) { - AssemblyBase::performChildOperation(); - } -} - -void AcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) { - using namespace duallane; - pwrStateMachine.reset(); - // If anything other than MODE_OFF is commanded, perform power state machine first - if (mode != MODE_OFF) { - // Cache the target modes, required by power state machine - pwrStateMachine.start(mode, submode); - // Cache these for later after the power state machine has finished - targetMode = mode; - targetSubmode = submode; - // Perform power state machine first, then start mode transition. The power state machine will - // start the transition after it has finished - pwrStateMachineWrapper(); - } else { - // Command the devices to off first before switching off the power. The handleModeReached - // custom implementation will take care of starting the power state machine. - AssemblyBase::startTransition(mode, submode); - } + initModeTableEntry(helper.mgm0Lis3IdSideA, entry, modeTable); + initModeTableEntry(helper.mgm1Rm3100IdSideA, entry, modeTable); + initModeTableEntry(helper.mgm2Lis3IdSideB, entry, modeTable); + initModeTableEntry(helper.mgm3Rm3100IdSideB, entry, modeTable); + initModeTableEntry(helper.gyro0AdisIdSideA, entry, modeTable); + initModeTableEntry(helper.gyro1L3gIdSideA, entry, modeTable); + initModeTableEntry(helper.gyro2AdisIdSideB, entry, modeTable); + initModeTableEntry(helper.gyro3L3gIdSideB, entry, modeTable); + initModeTableEntry(helper.gpsId, entry, modeTable); } ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { @@ -95,11 +64,6 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { using namespace duallane; refreshHelperModes(); - // if (state == PwrStates::SWITCHING_POWER) { - // // Wrong mode - // sif::error << "Wrong mode, currently switching power" << std::endl; - // return RETURN_OK; - // } if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or @@ -245,34 +209,6 @@ ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t su return HasReturnvaluesIF::RETURN_OK; } -bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { - if (healthHelper.healthTable->isFaulty(object)) { - return false; - } - - // Check if device is already in target mode - if (childrenMap[object].mode == mode) { - return true; - } - - if (healthHelper.healthTable->isCommandable(object)) { - return true; - } - return false; -} - -void AcsBoardAssembly::handleModeReached() { - using namespace duallane; - if (targetMode == MODE_OFF) { - pwrStateMachine.start(targetMode, targetSubmode); - // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function - // will be called - pwrStateMachineWrapper(); - } else { - finishModeOp(); - } -} - void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { using namespace duallane; // Some ACS board components are required for Safe-Mode. It would be good if the software @@ -357,14 +293,6 @@ void AcsBoardAssembly::refreshHelperModes() { } } -void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { - entry.setObject(id); - entry.setMode(MODE_OFF); - entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); - modeTable.insert(entry); -} - void AcsBoardAssembly::finishModeOp() { using namespace duallane; AssemblyBase::handleModeReached(); @@ -374,30 +302,6 @@ void AcsBoardAssembly::finishModeOp() { dualModeErrorSwitch = true; } -ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper() { - using namespace duallane; - OpCodes opCode = pwrStateMachine.powerStateMachine(); - if (opCode == OpCodes::NONE) { - return RETURN_OK; - } else if (opCode == OpCodes::FINISH_OP) { - finishModeOp(); - } else if (opCode == OpCodes::START_TRANSITION) { - AssemblyBase::startTransition(targetMode, targetSubmode); - } else if (opCode == OpCodes::TIMEOUT_OCCURED) { - if (powerRetryCounter == 0) { - powerRetryCounter++; - pwrStateMachine.reset(); - } else { -#if OBSW_VERBOSE_LEVEL >= 1 - sif::warning << "Timeout occured in power state machine" << std::endl; -#endif - triggerEvent(POWER_STATE_MACHINE_TIMEOUT, 0, 0); - return RETURN_FAILED; - } - } - return RETURN_OK; -} - ReturnValue_t AcsBoardAssembly::initialize() { ReturnValue_t result = registerChild(helper.gyro0AdisIdSideA); if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 7f2a85fa..20b8d748 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -3,9 +3,9 @@ #include #include -#include #include +#include "DualLaneAssemblyBase.h" #include "DualLanePowerStateMachine.h" struct AcsBoardHelper { @@ -71,15 +71,15 @@ class GpioIF; * doing this task would be performed by the device handlers, but this is not possible for the * ACS board where multiple sensors share the same power supply. */ -class AcsBoardAssembly : public AssemblyBase { +class AcsBoardAssembly : public DualLaneAssemblyBase { public: static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_BOARD_ASS; static constexpr Event TRANSITION_OTHER_SIDE_FAILED = - event::makeEvent(SUBSYSTEM_ID, 0, severity::HIGH); + event::makeEvent(SUBSYSTEM_ID, TRANSITION_OTHER_SIDE_FAILED_ID, severity::HIGH); static constexpr Event NOT_ENOUGH_DEVICES_DUAL_MODE = - event::makeEvent(SUBSYSTEM_ID, 1, severity::HIGH); + event::makeEvent(SUBSYSTEM_ID, NOT_ENOUGH_DEVICES_DUAL_MODE_ID, severity::HIGH); static constexpr Event POWER_STATE_MACHINE_TIMEOUT = - event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); + event::makeEvent(SUBSYSTEM_ID, POWER_STATE_MACHINE_TIMEOUT_ID, severity::MEDIUM); static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; @@ -101,12 +101,10 @@ class AcsBoardAssembly : public AssemblyBase { static constexpr pcduSwitches::Switches SWITCH_B = pcduSwitches::Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3; - // This helper object complete encapsulates power switching - DualLanePowerStateMachine pwrStateMachine; bool tryingOtherSide = false; AcsBoardHelper helper; GpioIF* gpioIF = nullptr; - uint8_t powerRetryCounter = 0; + // duallane::PwrStates state = duallane::PwrStates::IDLE; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; bool dualModeErrorSwitch = true; @@ -118,30 +116,13 @@ class AcsBoardAssembly : public AssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; - void performChildOperation() override; - void startTransition(Mode_t mode, Submode_t submode) override; - void handleModeReached() override; + void handleModeTransitionFailed(ReturnValue_t result) override; void handleChildrenLostMode(ReturnValue_t result) override; - /** - * Check whether it makes sense to send mode commands to the device - * @param object - * @param mode - * @return - */ - bool isUseable(object_id_t object, Mode_t mode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); - void initModeTableEntry(object_id_t id, ModeListEntry& entry); void refreshHelperModes(); void finishModeOp(); - /** - * Thin wrapper function which is required because the helper class - * can not access protected member functions. - * @param mode - * @param submode - */ - ReturnValue_t pwrStateMachineWrapper(); }; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt index fb8d7096..333de2f9 100644 --- a/mission/system/CMakeLists.txt +++ b/mission/system/CMakeLists.txt @@ -7,4 +7,5 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE ComSubsystem.cpp TcsSubsystem.cpp DualLanePowerStateMachine.cpp + DualLaneAssemblyBase.cpp ) \ No newline at end of file diff --git a/mission/system/DualLaneAssemblyBase.cpp b/mission/system/DualLaneAssemblyBase.cpp new file mode 100644 index 00000000..8ed549b1 --- /dev/null +++ b/mission/system/DualLaneAssemblyBase.cpp @@ -0,0 +1,92 @@ +#include "DualLaneAssemblyBase.h" + +DualLaneAssemblyBase::DualLaneAssemblyBase(object_id_t objectId, object_id_t parentId, + PowerSwitchIF* pwrSwitcher, + pcduSwitches::Switches switch1, + pcduSwitches::Switches switch2, Event pwrTimeoutEvent) + : AssemblyBase(objectId, parentId), + pwrStateMachine(switch1, switch2, pwrSwitcher), + pwrTimeoutEvent(pwrTimeoutEvent) {} + +void DualLaneAssemblyBase::performChildOperation() { + using namespace duallane; + if (pwrStateMachine.active()) { + pwrStateMachineWrapper(); + // This state is the indicator that the power state machine is done + } + if (not pwrStateMachine.active()) { + AssemblyBase::performChildOperation(); + } +} + +void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { + using namespace duallane; + pwrStateMachine.reset(); + // If anything other than MODE_OFF is commanded, perform power state machine first + if (mode != MODE_OFF) { + // Cache the target modes, required by power state machine + pwrStateMachine.start(mode, submode); + // Cache these for later after the power state machine has finished + targetMode = mode; + targetSubmode = submode; + // Perform power state machine first, then start mode transition. The power state machine will + // start the transition after it has finished + pwrStateMachineWrapper(); + } else { + // Command the devices to off first before switching off the power. The handleModeReached + // custom implementation will take care of starting the power state machine. + AssemblyBase::startTransition(mode, submode); + } +} + +bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() { + using namespace duallane; + OpCodes opCode = pwrStateMachine.powerStateMachine(); + if (opCode == OpCodes::NONE) { + return RETURN_OK; + } else if (opCode == OpCodes::FINISH_OP) { + finishModeOp(); + } else if (opCode == OpCodes::START_TRANSITION) { + AssemblyBase::startTransition(targetMode, targetSubmode); + } else if (opCode == OpCodes::TIMEOUT_OCCURED) { + if (powerRetryCounter == 0) { + powerRetryCounter++; + pwrStateMachine.reset(); + } else { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::warning << "Timeout occured in power state machine" << std::endl; +#endif + triggerEvent(pwrTimeoutEvent, 0, 0); + return RETURN_FAILED; + } + } + return RETURN_OK; +} + +void DualLaneAssemblyBase::handleModeReached() { + using namespace duallane; + if (targetMode == MODE_OFF) { + pwrStateMachine.start(targetMode, targetSubmode); + // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function + // will be called + pwrStateMachineWrapper(); + } else { + finishModeOp(); + } +} diff --git a/mission/system/DualLaneAssemblyBase.h b/mission/system/DualLaneAssemblyBase.h new file mode 100644 index 00000000..79037efa --- /dev/null +++ b/mission/system/DualLaneAssemblyBase.h @@ -0,0 +1,66 @@ +#ifndef MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ +#define MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ + +#include +#include + +class DualLaneAssemblyBase : public AssemblyBase { + public: + static constexpr uint8_t TRANSITION_OTHER_SIDE_FAILED_ID = 0; + static constexpr uint8_t NOT_ENOUGH_DEVICES_DUAL_MODE_ID = 1; + static constexpr uint8_t POWER_STATE_MACHINE_TIMEOUT_ID = 2; + + DualLaneAssemblyBase(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + pcduSwitches::Switches switch1, pcduSwitches::Switches switch2, + Event pwrSwitchTimeoutEvent); + + virtual void performChildOperation() override; + virtual void startTransition(Mode_t mode, Submode_t submode) override; + + protected: + // This helper object complete encapsulates power switching + DualLanePowerStateMachine pwrStateMachine; + Event pwrTimeoutEvent; + uint8_t powerRetryCounter = 0; + + /** + * Check whether it makes sense to send mode commands to the device + * @param object + * @param mode + * @return + */ + bool isUseable(object_id_t object, Mode_t mode); + /** + * Thin wrapper function which is required because the helper class + * can not access protected member functions. + * @param mode + * @param submode + */ + virtual ReturnValue_t pwrStateMachineWrapper(); + virtual void handleModeReached(); + + /** + * Implemented by user. Will be called if a full mode operation has finished. + * This includes both the regular mode state machine operations and the power state machine + * operations + */ + virtual void finishModeOp() = 0; + + template + void initModeTableEntry(object_id_t id, ModeListEntry& entry, + FixedArrayList& modeTable); + + private: +}; + +template +inline void DualLaneAssemblyBase::initModeTableEntry( + object_id_t id, ModeListEntry& entry, FixedArrayList& modeTable) { + entry.setObject(id); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + entry.setInheritSubmode(false); + modeTable.insert(entry); +} + +#endif /* MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ */ From 3cfb58d68138c6c309d1888d9b10357aa03186e6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 11:02:07 +0100 Subject: [PATCH 40/72] started integrating new base obj into sus assembly --- common/config/commonSubsystemIds.h | 1 + mission/system/AcsBoardAssembly.cpp | 8 -- mission/system/AcsBoardAssembly.h | 1 - mission/system/DualLaneAssemblyBase.cpp | 8 ++ mission/system/DualLaneAssemblyBase.h | 6 +- mission/system/SusAssembly.cpp | 103 +++--------------------- mission/system/SusAssembly.h | 15 ++-- 7 files changed, 33 insertions(+), 109 deletions(-) diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 554f4812..0e64e634 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -21,6 +21,7 @@ enum: uint8_t { STR_HELPER = 120, PL_PCDU_HANDLER = 121, ACS_BOARD_ASS = 122, + SUS_BOARD_ASS = 123, COMMON_SUBSYSTEM_ID_END }; } diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 76e2d916..903202b3 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -201,14 +201,6 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s return result; } -ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - using namespace duallane; - if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; -} - void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { using namespace duallane; // Some ACS board components are required for Safe-Mode. It would be good if the software diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index 20b8d748..788a7227 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -115,7 +115,6 @@ class AcsBoardAssembly : public DualLaneAssemblyBase { // AssemblyBase overrides ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; - ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; void handleModeTransitionFailed(ReturnValue_t result) override; void handleChildrenLostMode(ReturnValue_t result) override; diff --git a/mission/system/DualLaneAssemblyBase.cpp b/mission/system/DualLaneAssemblyBase.cpp index 8ed549b1..24759f58 100644 --- a/mission/system/DualLaneAssemblyBase.cpp +++ b/mission/system/DualLaneAssemblyBase.cpp @@ -79,6 +79,14 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() { return RETURN_OK; } +ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_t submode) { + using namespace duallane; + if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + void DualLaneAssemblyBase::handleModeReached() { using namespace duallane; if (targetMode == MODE_OFF) { diff --git a/mission/system/DualLaneAssemblyBase.h b/mission/system/DualLaneAssemblyBase.h index 79037efa..78d47437 100644 --- a/mission/system/DualLaneAssemblyBase.h +++ b/mission/system/DualLaneAssemblyBase.h @@ -14,9 +14,6 @@ class DualLaneAssemblyBase : public AssemblyBase { pcduSwitches::Switches switch1, pcduSwitches::Switches switch2, Event pwrSwitchTimeoutEvent); - virtual void performChildOperation() override; - virtual void startTransition(Mode_t mode, Submode_t submode) override; - protected: // This helper object complete encapsulates power switching DualLanePowerStateMachine pwrStateMachine; @@ -37,6 +34,9 @@ class DualLaneAssemblyBase : public AssemblyBase { * @param submode */ virtual ReturnValue_t pwrStateMachineWrapper(); + virtual ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + virtual void performChildOperation() override; + virtual void startTransition(Mode_t mode, Submode_t submode) override; virtual void handleModeReached(); /** diff --git a/mission/system/SusAssembly.cpp b/mission/system/SusAssembly.cpp index 5da464fb..7f41f159 100644 --- a/mission/system/SusAssembly.cpp +++ b/mission/system/SusAssembly.cpp @@ -6,10 +6,13 @@ SusAssembly::SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, SusAssHelper helper) - : AssemblyBase(objectId, parentId), helper(helper), pwrSwitcher(pwrSwitcher) { + : DualLaneAssemblyBase(objectId, parentId, pwrSwitcher, SWITCH_NOM, SWITCH_RED, + POWER_STATE_MACHINE_TIMEOUT), + helper(helper), + pwrSwitcher(pwrSwitcher) { ModeListEntry entry; for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS; idx++) { - initModeTableEntry(helper.susIds[idx], entry); + initModeTableEntry(helper.susIds[idx], entry, modeTable); } } @@ -34,6 +37,7 @@ ReturnValue_t SusAssembly::commandChildren(Mode_t mode, Submode_t submode) { } ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { + using namespace duallane; ReturnValue_t result = RETURN_OK; auto cmdSeq = [&](object_id_t objectId, uint8_t tableIdx) { if (mode == DeviceHandlerIF::MODE_NORMAL) { @@ -55,7 +59,7 @@ ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submod } }; switch (submode) { - case (NOMINAL): { + case (A_SIDE): { for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS_ONE_SIDE; idx++) { cmdSeq(helper.susIds[idx], idx); // Switch off devices on redundant side @@ -64,7 +68,7 @@ ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submod } return result; } - case (REDUNDANT): { + case (B_SIDE): { for (uint8_t idx = NUMBER_SUN_SENSORS_ONE_SIDE; idx < NUMBER_SUN_SENSORS; idx++) { cmdSeq(helper.susIds[idx], idx); // Switch devices on nominal side @@ -84,15 +88,16 @@ ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submod } ReturnValue_t SusAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + using namespace duallane; refreshHelperModes(); - if (wantedSubmode == NOMINAL) { + if (wantedSubmode == A_SIDE) { for (uint8_t idx = 0; idx < NUMBER_SUN_SENSORS_ONE_SIDE; idx++) { if (helper.susModes[idx] != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } } return RETURN_OK; - } else if (wantedSubmode == REDUNDANT) { + } else if (wantedSubmode == B_SIDE) { for (uint8_t idx = NUMBER_SUN_SENSORS_ONE_SIDE; idx < NUMBER_SUN_SENSORS; idx++) { if (helper.susModes[idx] != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; @@ -108,13 +113,6 @@ ReturnValue_t SusAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wan return RETURN_OK; } -ReturnValue_t SusAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - if (submode != NOMINAL and submode != REDUNDANT and submode != DUAL_MODE) { - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t SusAssembly::initialize() { ReturnValue_t result = RETURN_OK; for (const auto& id : helper.susIds) { @@ -142,92 +140,13 @@ bool SusAssembly::isUseable(object_id_t object, Mode_t mode) { return false; } -void SusAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { - ReturnValue_t switchStateNom = RETURN_OK; - ReturnValue_t switchStateRed = RETURN_OK; - if (state == States::IDLE or state == States::SWITCHING_POWER) { - switchStateNom = pwrSwitcher->getSwitchState(SWITCH_NOM); - switchStateRed = pwrSwitcher->getSwitchState(SWITCH_RED); - } else { - return; - } - if (mode == MODE_OFF) { - if (switchStateNom == PowerSwitchIF::SWITCH_OFF and - switchStateRed == PowerSwitchIF::SWITCH_OFF) { - state = States::MODE_COMMANDING; - return; - } - } else { - if (state == States::IDLE) { - if (mode == MODE_OFF) { - if (switchStateNom != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_NOM, false); - } - if (switchStateRed != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_RED, false); - } - } else { - switch (submode) { - case (NOMINAL): { - if (switchStateNom != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true); - } - if (switchStateRed != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_RED, false); - } - break; - } - case (REDUNDANT): { - if (switchStateRed != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_RED, false); - } - if (switchStateNom != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true); - } - break; - } - case (DUAL_MODE): { - if (switchStateNom != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true); - } - if (switchStateRed != PowerSwitchIF::SWITCH_ON) { - pwrSwitcher->sendSwitchCommand(SWITCH_RED, true); - } - break; - } - } - } - state = States::SWITCHING_POWER; - } - if (state == States::SWITCHING_POWER) { - // TODO: Could check for a timeout (temporal or cycles) here and resend command - } - } -} - void SusAssembly::handleModeReached() { AssemblyBase::handleModeReached(); state = States::IDLE; } -void SusAssembly::handleModeTransitionFailed(ReturnValue_t result) { - // The sun-sensors are required for the Safe-Mode. It would be good if the software - // transitions from nominal side to redundant side and from redundant side to dual mode - // autonomously to ensure that that enough sensors are available witout an operators intervention. - // Therefore, the failure handler is overriden to perform these steps. - // TODO: Implement transitions mentioned above -} - void SusAssembly::refreshHelperModes() { for (uint8_t idx = 0; idx < helper.susModes.size(); idx++) { helper.susModes[idx] = childrenMap[helper.susIds[idx]].mode; } } - -void SusAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) { - entry.setObject(id); - entry.setMode(MODE_OFF); - entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); - modeTable.insert(entry); -} diff --git a/mission/system/SusAssembly.h b/mission/system/SusAssembly.h index b4941724..37f3d3a5 100644 --- a/mission/system/SusAssembly.h +++ b/mission/system/SusAssembly.h @@ -4,6 +4,8 @@ #include #include +#include "DualLaneAssemblyBase.h" + struct SusAssHelper { public: SusAssHelper(std::array susIds) : susIds(susIds) {} @@ -13,14 +15,18 @@ struct SusAssHelper { class PowerSwitchIF; -class SusAssembly : AssemblyBase { +class SusAssembly : DualLaneAssemblyBase { public: static constexpr uint8_t NUMBER_SUN_SENSORS_ONE_SIDE = 6; static constexpr uint8_t NUMBER_SUN_SENSORS = 12; - static constexpr Submode_t NOMINAL = 0; - static constexpr Submode_t REDUNDANT = 1; - static constexpr Submode_t DUAL_MODE = 2; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SUS_BOARD_ASS; + static constexpr Event TRANSITION_OTHER_SIDE_FAILED = + event::makeEvent(SUBSYSTEM_ID, TRANSITION_OTHER_SIDE_FAILED_ID, severity::HIGH); + static constexpr Event NOT_ENOUGH_DEVICES_DUAL_MODE = + event::makeEvent(SUBSYSTEM_ID, NOT_ENOUGH_DEVICES_DUAL_MODE_ID, severity::HIGH); + static constexpr Event POWER_STATE_MACHINE_TIMEOUT = + event::makeEvent(SUBSYSTEM_ID, POWER_STATE_MACHINE_TIMEOUT_ID, severity::MEDIUM); SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, SusAssHelper helper); @@ -54,7 +60,6 @@ class SusAssembly : AssemblyBase { bool isUseable(object_id_t object, Mode_t mode); void powerStateMachine(Mode_t mode, Submode_t submode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); - void initModeTableEntry(object_id_t id, ModeListEntry& entry); void refreshHelperModes(); }; From 8c41669d1f2673abda6279c2f9d75cb861e623a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 11:05:43 +0100 Subject: [PATCH 41/72] docs --- mission/system/DualLaneAssemblyBase.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mission/system/DualLaneAssemblyBase.h b/mission/system/DualLaneAssemblyBase.h index 78d47437..c806561a 100644 --- a/mission/system/DualLaneAssemblyBase.h +++ b/mission/system/DualLaneAssemblyBase.h @@ -4,6 +4,13 @@ #include #include +/** + * @brief Encapsulates assemblies which are also responsible for dual lane power switching + * @details + * This is the base class for both the ACS board and the SUS board. Both boards have redundant + * power lanes and are required for the majority of satellite modes. Therefore, there is a lot + * of common code, for example the power switching. + */ class DualLaneAssemblyBase : public AssemblyBase { public: static constexpr uint8_t TRANSITION_OTHER_SIDE_FAILED_ID = 0; From fec6cc3ea98011ea34eddd08781e873066c6035c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 10 Mar 2022 11:10:42 +0100 Subject: [PATCH 42/72] more docs --- mission/system/DualLaneAssemblyBase.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mission/system/DualLaneAssemblyBase.cpp b/mission/system/DualLaneAssemblyBase.cpp index 24759f58..9c163721 100644 --- a/mission/system/DualLaneAssemblyBase.cpp +++ b/mission/system/DualLaneAssemblyBase.cpp @@ -12,8 +12,10 @@ void DualLaneAssemblyBase::performChildOperation() { using namespace duallane; if (pwrStateMachine.active()) { pwrStateMachineWrapper(); - // This state is the indicator that the power state machine is done } + // Only perform the regular child operation if the power state machine is not active. + // It does not make any sense to command device modes while the power switcher is busy + // switching off or on devices. if (not pwrStateMachine.active()) { AssemblyBase::performChildOperation(); } @@ -61,8 +63,11 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() { if (opCode == OpCodes::NONE) { return RETURN_OK; } else if (opCode == OpCodes::FINISH_OP) { + // Will be called for transitions to MODE_OFF, where everything is done after power switching finishModeOp(); } else if (opCode == OpCodes::START_TRANSITION) { + // Will be called for transitions from MODE_OFF to anything else, where the mode still has + // to be commanded after power switching AssemblyBase::startTransition(targetMode, targetSubmode); } else if (opCode == OpCodes::TIMEOUT_OCCURED) { if (powerRetryCounter == 0) { From dd37f90b4730259b92865ed40e7c87b67b84a222 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 11 Mar 2022 14:33:09 +0100 Subject: [PATCH 43/72] update for gen scripts, small fixes --- fsfw | 2 +- generators/.run/events.run.xml | 2 +- generators/.run/objects.run.xml | 2 +- generators/.run/returnvalues.run.xml | 2 +- generators/bsp_q7s_returnvalues.csv | 6 +----- generators/events/translateEvents.cpp | 2 +- generators/fsfwgen | 2 +- generators/{fsfwgen.py => gen.py} | 0 generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 2 +- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- mission/system/AcsBoardAssembly.h | 10 +++++++--- 12 files changed, 17 insertions(+), 17 deletions(-) rename generators/{fsfwgen.py => gen.py} (100%) diff --git a/fsfw b/fsfw index 17262a1d..fec5f83f 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 17262a1da91a92c3b5995ccfbd67d439d01bb456 +Subproject commit fec5f83f4f2459facee25939e0292115f89a6d73 diff --git a/generators/.run/events.run.xml b/generators/.run/events.run.xml index 18f71033..6bc73c96 100644 --- a/generators/.run/events.run.xml +++ b/generators/.run/events.run.xml @@ -12,7 +12,7 @@