From 3bd434bbc3b28dc52e0e157a4230d0fe44e91c09 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 6 Apr 2023 16:50:33 +0200 Subject: [PATCH] I2C reboot procedure for EIVE system --- bsp_q7s/em/emObjectFactory.cpp | 2 +- bsp_q7s/obsw.cpp | 2 +- mission/system/CMakeLists.txt | 4 +- mission/system/EiveSystem.cpp | 203 ++++++++++++++++++ mission/system/EiveSystem.h | 46 ++++ mission/system/acs/acsModeTree.cpp | 2 +- mission/system/com/comModeTree.cpp | 2 +- mission/system/objects/CMakeLists.txt | 9 +- mission/system/objects/EiveSystem.cpp | 111 ---------- mission/system/objects/EiveSystem.h | 21 -- .../{tree/system.cpp => systemTree.cpp} | 8 +- .../system/{tree/system.h => systemTree.h} | 2 +- mission/system/tree/CMakeLists.txt | 3 +- mission/system/tree/payloadModeTree.cpp | 2 +- mission/system/tree/tcsModeTree.cpp | 2 +- .../system/{tree/util.cpp => treeUtil.cpp} | 2 +- mission/system/{tree/util.h => treeUtil.h} | 0 17 files changed, 267 insertions(+), 154 deletions(-) create mode 100644 mission/system/EiveSystem.cpp create mode 100644 mission/system/EiveSystem.h delete mode 100644 mission/system/objects/EiveSystem.cpp delete mode 100644 mission/system/objects/EiveSystem.h rename mission/system/{tree/system.cpp => systemTree.cpp} (98%) rename mission/system/{tree/system.h => systemTree.h} (82%) rename mission/system/{tree/util.cpp => treeUtil.cpp} (96%) rename mission/system/{tree/util.h => treeUtil.h} (100%) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index ad520441..ca1a54ae 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include "OBSWConfig.h" diff --git a/bsp_q7s/obsw.cpp b/bsp_q7s/obsw.cpp index d2d640f3..dc547b03 100644 --- a/bsp_q7s/obsw.cpp +++ b/bsp_q7s/obsw.cpp @@ -16,7 +16,7 @@ #include "fsfw/version.h" #include "mission/acs/defs.h" #include "mission/com/defs.h" -#include "mission/system/tree/system.h" +#include "mission/system/systemTree.h" #include "q7sConfig.h" #include "watchdog/definitions.h" diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt index 44122d7e..51e47ef4 100644 --- a/mission/system/CMakeLists.txt +++ b/mission/system/CMakeLists.txt @@ -5,4 +5,6 @@ add_subdirectory(com) add_subdirectory(fdir) add_subdirectory(power) -target_sources(${LIB_EIVE_MISSION} PRIVATE DualLanePowerStateMachine.cpp) +target_sources( + ${LIB_EIVE_MISSION} PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp + EiveSystem.cpp treeUtil.cpp) diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp new file mode 100644 index 00000000..9e01e7b2 --- /dev/null +++ b/mission/system/EiveSystem.cpp @@ -0,0 +1,203 @@ +#include "EiveSystem.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "mission/power/bpxBattDefs.h" +#include "mission/power/defs.h" +#include "mission/sysDefs.h" + +EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, + uint32_t maxNumberOfTables) + : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables), + actionHelper(this, commandQueue) { + auto mqArgs = MqArgs(SubsystemBase::getObjectId(), static_cast(this)); + eventQueue = + QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs); +} + +void EiveSystem::announceMode(bool recursive) { + const char* modeStr = "UNKNOWN"; + switch (mode) { + case (satsystem::Mode::BOOT): { + modeStr = "OFF/BOOT"; + break; + } + case (satsystem::Mode::SAFE): { + modeStr = "SAFE"; + break; + } + case (satsystem::Mode::PTG_IDLE): { + modeStr = "POINTING IDLE"; + break; + } + case (acs::AcsMode::PTG_INERTIAL): { + modeStr = "POINTING INERTIAL"; + break; + } + case (acs::AcsMode::PTG_TARGET): { + modeStr = "POINTING TARGET"; + break; + } + case (acs::AcsMode::PTG_TARGET_GS): { + modeStr = "POINTING TARGET GS"; + break; + } + } + sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl; + return Subsystem::announceMode(recursive); +} + +void EiveSystem::performChildOperation() { + ReturnValue_t result; + Subsystem::performChildOperation(); + handleEventMessages(); + if (not isInTransition and performSafeRecovery) { + commandSelfToSafe(); + performSafeRecovery = false; + return; + } + if (not isInTransition and performI2cReboot) { + if (i2cRebootState == I2cRebootState::SYSTEM_MODE_BOOT) { + startTransition(satsystem::Mode::BOOT, 0); + i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT; + i2cRebootCountdown.resetTimer(); + } else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT) { + if (mode == satsystem::Mode::BOOT) { + result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK, + PowerSwitchIF::SWITCH_OFF); + if (result != returnvalue::OK) { + actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result); + performI2cReboot = false; + } + CommandMessage msg; + ActionMessage::setCommand(&msg, BpxBattery::REBOOT, store_address_t()); + result = commandQueue->sendMessage(bpxBattQueueId, &msg); + if (result != returnvalue::OK) { + actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result); + performI2cReboot = false; + } + i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_ON; + } + if (i2cRebootCountdown.hasTimedOut()) { + actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED); + performI2cReboot = false; + } + } else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_ON) { + result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK, + PowerSwitchIF::SWITCH_ON); + if (result != returnvalue::OK) { + actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result); + performI2cReboot = false; + } + i2cRebootState = I2cRebootState::SYSTEM_MODE_SAFE; + } else if (i2cRebootState == I2cRebootState::SYSTEM_MODE_SAFE) { + if (powerSwitcher->getSwitchState(power::Switches::P60_DOCK_3V3_STACK) == + PowerSwitchIF::SWITCH_ON) { + // This should always be accepted + commandSelfToSafe(); + i2cRebootState = I2cRebootState::NONE; + performI2cReboot = false; + actionHelper.finish(true, actionCommandedBy, EXECUTE_I2C_REBOOT); + } + } + + // Timeout handling for the internal procedure. + if (i2cRebootState != I2cRebootState::NONE and i2cRebootCountdown.hasTimedOut()) { + actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED); + powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK, + PowerSwitchIF::SWITCH_ON); + // This should always be accepted + commandSelfToSafe(); + } + } +} + +ReturnValue_t EiveSystem::initialize() { + if (powerSwitcher == nullptr) { + return ObjectManager::CHILD_INIT_FAILED; + } + ReturnValue_t result = actionHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + auto* bpxDest = ObjectManager::instance()->get(objects::BPX_BATT_HANDLER); + if (bpxDest == nullptr) { + return ObjectManager::CHILD_INIT_FAILED; + } + bpxBattQueueId = bpxDest->getCommandQueue(); + auto* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + result = manager->registerListener(eventQueue->getId()); + if (result != returnvalue::OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "AcsSubsystem::registerListener: Failed to register as " + "listener" + << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + manager->subscribeToEvent(eventQueue->getId(), + event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING)); + manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING)); + + return Subsystem::initialize(); +} + +void EiveSystem::handleEventMessages() { + EventMessage event; + for (ReturnValue_t status = eventQueue->receiveMessage(&event); status == returnvalue::OK; + status = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + switch (event.getEvent()) { + case tcsCtrl::OBC_OVERHEATING: + case tcsCtrl::PCDU_SYSTEM_OVERHEATING: { + if (isInTransition) { + performSafeRecovery = true; + return; + } + + commandSelfToSafe(); + break; + } + } + break; + default: + sif::debug << "EiveSystem: Did not subscribe to event " << event.getEvent() << std::endl; + break; + } + } +} + +MessageQueueId_t EiveSystem::getCommandQueue() const { return Subsystem::getCommandQueue(); } + +ReturnValue_t EiveSystem::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) { + switch (actionId) { + case (EXECUTE_I2C_REBOOT): { + performI2cReboot = true; + i2cRebootState = I2cRebootState::SYSTEM_MODE_BOOT; + this->actionCommandedBy = commandedBy; + return returnvalue::OK; + } + default: { + return HasActionsIF::INVALID_ACTION_ID; + } + } + return returnvalue::OK; +} + +void EiveSystem::setPowerSwitcher(PowerSwitchIF* pwrSwitcher) {} + +void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); } diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h new file mode 100644 index 00000000..cc720828 --- /dev/null +++ b/mission/system/EiveSystem.h @@ -0,0 +1,46 @@ +#ifndef MISSION_SYSTEM_EIVESYSTEM_H_ +#define MISSION_SYSTEM_EIVESYSTEM_H_ + +#include +#include +#include + +class EiveSystem : public Subsystem, public HasActionsIF { + public: + static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10; + + EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables); + + void setPowerSwitcher(PowerSwitchIF* pwrSwitcher); + + [[nodiscard]] MessageQueueId_t getCommandQueue() const override; + + private: + enum class I2cRebootState { + NONE, + SYSTEM_MODE_BOOT, + SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT, + SWITCH_3V3_STACK_ON, + SYSTEM_MODE_SAFE + } i2cRebootState = I2cRebootState::NONE; + + MessageQueueIF* eventQueue = nullptr; + bool performSafeRecovery = false; + bool performI2cReboot = false; + ActionHelper actionHelper; + PowerSwitchIF* powerSwitcher = nullptr; + MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE; + MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE; + Countdown i2cRebootCountdown = Countdown(10000); + + ReturnValue_t initialize() override; + void performChildOperation() override; + void announceMode(bool recursive) override; + + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; + void handleEventMessages(); + void commandSelfToSafe(); +}; + +#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */ diff --git a/mission/system/acs/acsModeTree.cpp b/mission/system/acs/acsModeTree.cpp index 85d2ea45..185ad9eb 100644 --- a/mission/system/acs/acsModeTree.cpp +++ b/mission/system/acs/acsModeTree.cpp @@ -11,7 +11,7 @@ #include "eive/objects.h" #include "mission/acs/defs.h" #include "mission/power/defs.h" -#include "mission/system/tree/util.h" +#include "mission/system/treeUtil.h" AcsSubsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24); diff --git a/mission/system/com/comModeTree.cpp b/mission/system/com/comModeTree.cpp index bb9a8d10..23611ea2 100644 --- a/mission/system/com/comModeTree.cpp +++ b/mission/system/com/comModeTree.cpp @@ -6,7 +6,7 @@ #include "eive/objects.h" #include "mission/com/defs.h" -#include "mission/system/tree/util.h" +#include "mission/system/treeUtil.h" const auto check = subsystem::checkInsert; diff --git a/mission/system/objects/CMakeLists.txt b/mission/system/objects/CMakeLists.txt index 53cc200d..b2fe6056 100644 --- a/mission/system/objects/CMakeLists.txt +++ b/mission/system/objects/CMakeLists.txt @@ -1,9 +1,4 @@ target_sources( ${LIB_EIVE_MISSION} - PRIVATE EiveSystem.cpp - CamSwitcher.cpp - TcsSubsystem.cpp - PayloadSubsystem.cpp - Stack5VHandler.cpp - PowerStateMachineBase.cpp - TcsBoardAssembly.cpp) + PRIVATE CamSwitcher.cpp TcsSubsystem.cpp PayloadSubsystem.cpp + Stack5VHandler.cpp PowerStateMachineBase.cpp TcsBoardAssembly.cpp) diff --git a/mission/system/objects/EiveSystem.cpp b/mission/system/objects/EiveSystem.cpp deleted file mode 100644 index f6b99b1e..00000000 --- a/mission/system/objects/EiveSystem.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "EiveSystem.h" - -#include -#include -#include -#include -#include -#include - -#include "mission/sysDefs.h" - -EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, - uint32_t maxNumberOfTables) - : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) { - auto mqArgs = MqArgs(SubsystemBase::getObjectId(), static_cast(this)); - eventQueue = - QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs); -} - -void EiveSystem::announceMode(bool recursive) { - const char* modeStr = "UNKNOWN"; - switch (mode) { - case (satsystem::Mode::BOOT): { - modeStr = "OFF/BOOT"; - break; - } - case (satsystem::Mode::SAFE): { - modeStr = "SAFE"; - break; - } - case (satsystem::Mode::PTG_IDLE): { - modeStr = "POINTING IDLE"; - break; - } - case (acs::AcsMode::PTG_INERTIAL): { - modeStr = "POINTING INERTIAL"; - break; - } - case (acs::AcsMode::PTG_TARGET): { - modeStr = "POINTING TARGET"; - break; - } - case (acs::AcsMode::PTG_TARGET_GS): { - modeStr = "POINTING TARGET GS"; - break; - } - } - sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl; - return Subsystem::announceMode(recursive); -} - -void EiveSystem::performChildOperation() { - Subsystem::performChildOperation(); - handleEventMessages(); - if (not isInTransition and performSafeRecovery) { - commandSelfToSafe(); - performSafeRecovery = false; - } -} - -ReturnValue_t EiveSystem::initialize() { - auto* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); - if (manager == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - ReturnValue_t result = manager->registerListener(eventQueue->getId()); - if (result != returnvalue::OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "AcsSubsystem::registerListener: Failed to register as " - "listener" - << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - manager->subscribeToEvent(eventQueue->getId(), - event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING)); - manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING)); - - return Subsystem::initialize(); -} - -void EiveSystem::handleEventMessages() { - EventMessage event; - for (ReturnValue_t status = eventQueue->receiveMessage(&event); status == returnvalue::OK; - status = eventQueue->receiveMessage(&event)) { - switch (event.getMessageId()) { - case EventMessage::EVENT_MESSAGE: - switch (event.getEvent()) { - case tcsCtrl::OBC_OVERHEATING: - case tcsCtrl::PCDU_SYSTEM_OVERHEATING: { - if (isInTransition) { - performSafeRecovery = true; - return; - } - - commandSelfToSafe(); - break; - } - } - break; - default: - sif::debug << "EiveSystem: Did not subscribe to event " << event.getEvent() << std::endl; - break; - } - } -} - -void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); } diff --git a/mission/system/objects/EiveSystem.h b/mission/system/objects/EiveSystem.h deleted file mode 100644 index 06110775..00000000 --- a/mission/system/objects/EiveSystem.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MISSION_SYSTEM_EIVESYSTEM_H_ -#define MISSION_SYSTEM_EIVESYSTEM_H_ - -#include - -class EiveSystem : public Subsystem { - public: - EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables); - - private: - MessageQueueIF* eventQueue = nullptr; - bool performSafeRecovery = false; - - ReturnValue_t initialize() override; - void performChildOperation() override; - void announceMode(bool recursive) override; - void handleEventMessages(); - void commandSelfToSafe(); -}; - -#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */ diff --git a/mission/system/tree/system.cpp b/mission/system/systemTree.cpp similarity index 98% rename from mission/system/tree/system.cpp rename to mission/system/systemTree.cpp index 6e3b3f72..2cecf244 100644 --- a/mission/system/tree/system.cpp +++ b/mission/system/systemTree.cpp @@ -1,4 +1,4 @@ -#include "system.h" +#include "systemTree.h" #include #include @@ -9,9 +9,9 @@ #include "eive/objects.h" #include "mission/com/defs.h" #include "mission/system/acs/acsModeTree.h" -#include "payloadModeTree.h" -#include "tcsModeTree.h" -#include "util.h" +#include "mission/system/tree/payloadModeTree.h" +#include "mission/system/tree/tcsModeTree.h" +#include "treeUtil.h" namespace { // Alias for checker function diff --git a/mission/system/tree/system.h b/mission/system/systemTree.h similarity index 82% rename from mission/system/tree/system.h rename to mission/system/systemTree.h index b1c90c82..9d769277 100644 --- a/mission/system/tree/system.h +++ b/mission/system/systemTree.h @@ -1,7 +1,7 @@ #ifndef MISSION_SYSTEM_TREE_SYSTEM_H_ #define MISSION_SYSTEM_TREE_SYSTEM_H_ -#include +#include namespace satsystem { diff --git a/mission/system/tree/CMakeLists.txt b/mission/system/tree/CMakeLists.txt index a6764013..8715d8e1 100644 --- a/mission/system/tree/CMakeLists.txt +++ b/mission/system/tree/CMakeLists.txt @@ -1,2 +1 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp tcsModeTree.cpp - system.cpp util.cpp) +target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp tcsModeTree.cpp) diff --git a/mission/system/tree/payloadModeTree.cpp b/mission/system/tree/payloadModeTree.cpp index ab67852d..b2d74dd2 100644 --- a/mission/system/tree/payloadModeTree.cpp +++ b/mission/system/tree/payloadModeTree.cpp @@ -10,7 +10,7 @@ #include "eive/objects.h" #include "mission/power/defs.h" #include "mission/system/objects/PayloadSubsystem.h" -#include "util.h" +#include "mission/system/treeUtil.h" namespace { void initOffSequence(Subsystem& ss, ModeListEntry& eh); diff --git a/mission/system/tree/tcsModeTree.cpp b/mission/system/tree/tcsModeTree.cpp index b7188b17..2cdb5052 100644 --- a/mission/system/tree/tcsModeTree.cpp +++ b/mission/system/tree/tcsModeTree.cpp @@ -3,7 +3,7 @@ #include "eive/objects.h" #include "fsfw/devicehandlers/DeviceHandlerIF.h" #include "fsfw/subsystem/Subsystem.h" -#include "mission/system/tree/util.h" +#include "mission/system/treeUtil.h" TcsSubsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24); diff --git a/mission/system/tree/util.cpp b/mission/system/treeUtil.cpp similarity index 96% rename from mission/system/tree/util.cpp rename to mission/system/treeUtil.cpp index 935e9d79..0e95f273 100644 --- a/mission/system/tree/util.cpp +++ b/mission/system/treeUtil.cpp @@ -1,4 +1,4 @@ -#include "util.h" +#include "treeUtil.h" #include "fsfw/container/FixedMap.h" #include "fsfw/serviceinterface.h" diff --git a/mission/system/tree/util.h b/mission/system/treeUtil.h similarity index 100% rename from mission/system/tree/util.h rename to mission/system/treeUtil.h