#ifndef MISSION_SYSTEM_EIVESYSTEM_H_ #define MISSION_SYSTEM_EIVESYSTEM_H_ #include #include #include #include class EiveSystem : public Subsystem, public HasActionsIF { public: static constexpr uint8_t FRAME_DIRTY_COM_REBOOT_LIMIT = 4; static constexpr uint32_t PDEC_RESET_MAX_COUNT_BEFORE_REBOOT = 10; static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10; EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables, std::atomic_uint16_t& i2cErrors); void setI2cRecoveryParams(PowerSwitchIF* pwrSwitcher); [[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, SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT, WAIT_CYCLE, SWITCH_3V3_STACK_ON, SYSTEM_MODE_SAFE } i2cRebootState = I2cRebootState::NONE; MessageQueueIF* eventQueue = nullptr; bool performSafeRecovery = false; bool performI2cReboot = false; 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. Countdown pdecResetCounterResetCd = Countdown(120000); bool waitingForI2cReboot = false; bool waitingForPdecReboot = false; uint32_t pdecResetCounter = 0; ActionHelper actionHelper; PowerSwitchIF* powerSwitcher = nullptr; std::atomic_uint16_t& i2cErrors; MessageQueueId_t plSsQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t plPcduQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t plocMpsocQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t plocSupervisorQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t cameraQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t scexQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t radSensorQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t strQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t pdecHandlerQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t coreCtrlQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE; Countdown i2cRebootHandlingCountdown = Countdown(10000); // After 1 minute, clear the flag to avoid full reboots on I2C issues. Countdown i2cRecoveryClearCountdown = Countdown(60000); 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; ReturnValue_t handleCommandMessage(CommandMessage* message) override; ReturnValue_t sendFullRebootCommand(); ReturnValue_t sendSelfRebootCommand(); void forceOffPayload(); void pdecRecoveryLogic(); void i2cRecoveryLogic(); void handleEventMessages(); void commandSelfToSafe(); void commonI2cRecoverySequenceFinish(); }; #endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */