diff --git a/CHANGELOG.md b/CHANGELOG.md index 9308d71d..6575d053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ will consitute of a breaking change warranting a new major release: CFDP interface. - Proper back pressure handling for the CFDP handler, where the `LiveTmTask` is able to throttle the CFDP handler. +- The EIVE system will command the payload OFF explicitely again when receiving the + `power::POWER_LEVEL_CRITICAL` event. ## Fixed @@ -36,6 +38,11 @@ will consitute of a breaking change warranting a new major release: is not in normal mode. - MPSoC debug mode. +## Changed + +- Added a 3 second delay in the EIVE system between commanding all PL components except the SUPV, + and the SUPV itself OFF when the power level becomes low or critical. + # [v7.1.0] 2023-10-11 - Bumped `eive-tmtc` to v5.8.0. diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index 0df0fc95..cd450502 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -70,6 +70,9 @@ void EiveSystem::performChildOperation() { } pdecRecoveryLogic(); i2cRecoveryLogic(); + if (forcePlOffState != ForcePlOffState::NONE) { + forceOffPayload(); + } } ReturnValue_t EiveSystem::initialize() { @@ -203,10 +206,14 @@ void EiveSystem::handleEventMessages() { break; } case power::POWER_LEVEL_LOW: { - forceOffPayload(); + forcePlOffState = ForcePlOffState::FORCE_ALL_EXCEPT_SUPV_OFF; break; } - case power::POWER_LEVEL_CRITICAL: + case power::POWER_LEVEL_CRITICAL: { + // Force payload off in any case. It really should not be on when the power level + // becomes critical, but better be safe than sorry.. + forcePlOffState = ForcePlOffState::FORCE_ALL_EXCEPT_SUPV_OFF; + // Also set the STR assembly to faulty, which should cause a fallback to SAFE mode. CommandMessage msg; HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY); ReturnValue_t result = MessageQueueSenderIF::sendMessage( @@ -216,6 +223,7 @@ void EiveSystem::handleEventMessages() { << std::endl; } break; + } } break; default: @@ -403,37 +411,45 @@ void EiveSystem::pdecRecoveryLogic() { void EiveSystem::forceOffPayload() { CommandMessage msg; + ReturnValue_t result; // set PL to faulty HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY); - ReturnValue_t result = commandQueue->sendMessage(plPcduQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PL PCDU failed" << std::endl; + if (forcePlOffState == ForcePlOffState::FORCE_ALL_EXCEPT_SUPV_OFF) { + result = commandQueue->sendMessage(plocMpsocQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PLOC MPSOC failed" << std::endl; + } + result = commandQueue->sendMessage(cameraQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PL CAM failed" << std::endl; + } + result = commandQueue->sendMessage(scexQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to SCEX failed" << std::endl; + } + result = commandQueue->sendMessage(radSensorQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to RAD SENSOR failed" << std::endl; + } + result = commandQueue->sendMessage(plPcduQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PL PCDU failed" << std::endl; + } + forcePlOffState = ForcePlOffState::WAITING; + supvOffDelay.resetTimer(); } - result = commandQueue->sendMessage(plocMpsocQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PLOC MPSOC failed" << std::endl; + if (forcePlOffState == ForcePlOffState::WAITING and supvOffDelay.hasTimedOut()) { + forcePlOffState = ForcePlOffState::FORCE_SUPV_OFF; } - result = commandQueue->sendMessage(plocSupervisorQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PLOC SUPERVISOR failed" << std::endl; - } - - result = commandQueue->sendMessage(cameraQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PL CAM failed" << std::endl; - } - - result = commandQueue->sendMessage(scexQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to SCEX failed" << std::endl; - } - - result = commandQueue->sendMessage(radSensorQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to RAD SENSOR failed" << std::endl; + if (forcePlOffState == ForcePlOffState::FORCE_SUPV_OFF) { + result = commandQueue->sendMessage(plocSupervisorQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PLOC SUPERVISOR failed" << std::endl; + } + forcePlOffState = ForcePlOffState::NONE; } } diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index 78f8bdc9..fed5791a 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -22,6 +22,12 @@ class EiveSystem : public Subsystem, public HasActionsIF { [[nodiscard]] MessageQueueId_t getCommandQueue() const override; private: + enum class ForcePlOffState { + NONE, + FORCE_ALL_EXCEPT_SUPV_OFF, + WAITING, + FORCE_SUPV_OFF + } forcePlOffState = ForcePlOffState::NONE; enum class I2cRebootState { NONE, SYSTEM_MODE_BOOT, @@ -37,6 +43,7 @@ class EiveSystem : public Subsystem, public HasActionsIF { bool alreadyTriedI2cRecovery = false; uint8_t frameDirtyErrorCounter = 0; + Countdown supvOffDelay = Countdown(3000); Countdown frameDirtyCheckCd = Countdown(10000); // If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that // only a full reboot will fix the issue.