2022-03-10 10:54:27 +01:00
|
|
|
#ifndef MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_
|
|
|
|
#define MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_
|
|
|
|
|
|
|
|
#include <fsfw/devicehandlers/AssemblyBase.h>
|
2023-03-24 20:50:33 +01:00
|
|
|
#include <mission/system/DualLanePowerStateMachine.h>
|
2022-03-10 10:54:27 +01:00
|
|
|
|
2022-03-10 11:05:43 +01:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2022-03-17 19:23:39 +01:00
|
|
|
class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
|
2022-03-10 10:54:27 +01:00
|
|
|
public:
|
2022-03-17 19:23:39 +01:00
|
|
|
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;
|
2022-03-10 10:54:27 +01:00
|
|
|
|
2023-03-16 18:47:51 +01:00
|
|
|
DualLaneAssemblyBase(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switches switch1,
|
|
|
|
power::Switches switch2, Event pwrSwitchTimeoutEvent,
|
2022-04-07 19:48:09 +02:00
|
|
|
Event sideSwitchNotAllowedEvent, Event transitionOtherSideFailedEvent);
|
2022-03-10 10:54:27 +01:00
|
|
|
|
|
|
|
protected:
|
|
|
|
// This helper object complete encapsulates power switching
|
|
|
|
DualLanePowerStateMachine pwrStateMachine;
|
|
|
|
Event pwrTimeoutEvent;
|
2022-03-17 19:23:39 +01:00
|
|
|
Event sideSwitchNotAllowedEvent;
|
|
|
|
Event transitionOtherSideFailedEvent;
|
2022-03-10 10:54:27 +01:00
|
|
|
uint8_t powerRetryCounter = 0;
|
2022-03-17 19:23:39 +01:00
|
|
|
bool tryingOtherSide = false;
|
|
|
|
bool dualModeErrorSwitch = true;
|
2023-03-20 10:17:41 +01:00
|
|
|
bool dualToSingleSideTransition = false;
|
2022-03-17 19:23:39 +01:00
|
|
|
duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE;
|
|
|
|
|
2023-03-24 19:14:27 +01:00
|
|
|
enum SideSwitchState { NONE, REQUESTED, TO_DUAL, DISABLE_OTHER_SIDE };
|
2023-03-01 20:12:48 +01:00
|
|
|
|
|
|
|
SideSwitchState sideSwitchState = SideSwitchState::NONE;
|
|
|
|
duallane::Submodes targetSubmodeForSideSwitch = duallane::Submodes::B_SIDE;
|
|
|
|
|
2022-03-17 19:23:39 +01:00
|
|
|
enum RecoveryCustomStates {
|
|
|
|
IDLE,
|
|
|
|
POWER_SWITCHING_OFF,
|
|
|
|
POWER_SWITCHING_ON,
|
|
|
|
DONE
|
|
|
|
} customRecoveryStates = RecoveryCustomStates::IDLE;
|
|
|
|
|
|
|
|
MessageQueueIF* eventQueue = nullptr;
|
2022-03-10 10:54:27 +01:00
|
|
|
|
2023-03-31 19:15:54 +02:00
|
|
|
/**
|
|
|
|
* To be called in mode command packer function of the child class.
|
|
|
|
* @param submode
|
|
|
|
* @param needsSecondStep
|
|
|
|
*/
|
2023-03-31 19:14:42 +02:00
|
|
|
void handleSideSwitchStates(uint8_t& submode, bool& needsSecondStep);
|
2022-03-10 10:54:27 +01:00
|
|
|
|
|
|
|
/**
|
2023-03-30 17:16:59 +02:00
|
|
|
* Check whether it makes sense to send mode commands to the device.
|
2022-03-10 10:54:27 +01:00
|
|
|
* @param object
|
|
|
|
* @param mode
|
|
|
|
* @return
|
|
|
|
*/
|
2023-03-30 17:16:59 +02:00
|
|
|
bool isModeCommandable(object_id_t object, Mode_t mode);
|
2022-04-01 14:01:12 +02:00
|
|
|
|
2022-03-10 10:54:27 +01:00
|
|
|
/**
|
|
|
|
* Thin wrapper function which is required because the helper class
|
|
|
|
* can not access protected member functions.
|
|
|
|
* @param mode
|
|
|
|
* @param submode
|
|
|
|
*/
|
|
|
|
virtual ReturnValue_t pwrStateMachineWrapper();
|
2022-03-10 11:02:07 +01:00
|
|
|
virtual ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
|
2022-03-17 19:23:39 +01:00
|
|
|
/**
|
|
|
|
* 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);
|
2022-03-10 11:02:07 +01:00
|
|
|
virtual void performChildOperation() override;
|
|
|
|
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
2022-03-17 19:23:39 +01:00
|
|
|
virtual void handleChildrenLostMode(ReturnValue_t result) override;
|
|
|
|
virtual void handleModeTransitionFailed(ReturnValue_t result) override;
|
2022-03-22 18:48:03 +01:00
|
|
|
virtual void handleModeReached() override;
|
2023-03-02 15:02:02 +01:00
|
|
|
ReturnValue_t checkAndHandleHealthState(Mode_t deviceMode, Submode_t deviceSubmode);
|
2022-03-10 10:54:27 +01:00
|
|
|
|
2022-03-17 19:23:39 +01:00
|
|
|
MessageQueueId_t getEventReceptionQueue() override;
|
|
|
|
|
|
|
|
bool sideSwitchTransition(Mode_t mode, Submode_t submode);
|
|
|
|
|
2022-03-10 10:54:27 +01:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2022-03-17 19:23:39 +01:00
|
|
|
virtual void finishModeOp();
|
2022-03-10 10:54:27 +01:00
|
|
|
|
|
|
|
template <size_t MAX_SIZE>
|
|
|
|
void initModeTableEntry(object_id_t id, ModeListEntry& entry,
|
|
|
|
FixedArrayList<ModeListEntry, MAX_SIZE>& modeTable);
|
|
|
|
|
|
|
|
private:
|
|
|
|
};
|
|
|
|
|
|
|
|
template <size_t MAX_SIZE>
|
|
|
|
inline void DualLaneAssemblyBase::initModeTableEntry(
|
|
|
|
object_id_t id, ModeListEntry& entry, FixedArrayList<ModeListEntry, MAX_SIZE>& modeTable) {
|
|
|
|
entry.setObject(id);
|
|
|
|
entry.setMode(MODE_OFF);
|
|
|
|
entry.setSubmode(SUBMODE_NONE);
|
|
|
|
modeTable.insert(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ */
|