#ifndef MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ #define MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ #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 ConfirmsFailuresIF { public: static constexpr UniqueEventId_t TRANSITION_OTHER_SIDE_FAILED_ID = 0; static constexpr UniqueEventId_t NOT_ENOUGH_DEVICES_DUAL_MODE_ID = 1; static constexpr UniqueEventId_t POWER_STATE_MACHINE_TIMEOUT_ID = 2; static constexpr UniqueEventId_t SIDE_SWITCH_TRANSITION_NOT_ALLOWED_ID = 3; DualLaneAssemblyBase(object_id_t objectId, PowerSwitchIF* pwrSwitcher, pcdu::Switches switch1, pcdu::Switches switch2, Event pwrSwitchTimeoutEvent, Event sideSwitchNotAllowedEvent, Event transitionOtherSideFailedEvent); protected: // This helper object complete encapsulates power switching DualLanePowerStateMachine pwrStateMachine; Event pwrTimeoutEvent; Event sideSwitchNotAllowedEvent; Event transitionOtherSideFailedEvent; uint8_t powerRetryCounter = 0; bool tryingOtherSide = false; bool dualModeErrorSwitch = true; bool dualToSingleSideTransition = false; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; enum RecoveryCustomStates { IDLE, POWER_SWITCHING_OFF, POWER_SWITCHING_ON, DONE } customRecoveryStates = RecoveryCustomStates::IDLE; MessageQueueIF* eventQueue = nullptr; /** * 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 ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; /** * Custom recovery implementation to ensure that the power lines are commanded off for a * recovery. * @return */ virtual bool checkAndHandleRecovery() override; void setPreferredSide(duallane::Submodes submode); virtual void performChildOperation() override; virtual void startTransition(Mode_t mode, Submode_t submode) override; virtual void handleChildrenLostMode(ReturnValue_t result) override; virtual void handleModeTransitionFailed(ReturnValue_t result) override; virtual void handleModeReached() override; ReturnValue_t checkAndHandleHealthState(Mode_t deviceMode, Submode_t deviceSubmode); MessageQueueId_t getEventReceptionQueue() override; bool sideSwitchTransition(Mode_t mode, Submode_t submode); /** * 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(); 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); modeTable.insert(entry); } #endif /* MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ */