eive-obsw/mission/system/objects/DualLaneAssemblyBase.h

103 lines
3.7 KiB
C
Raw Normal View History

2022-03-10 10:54:27 +01:00
#ifndef MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_
#define MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_
#include <fsfw/devicehandlers/AssemblyBase.h>
2022-04-25 10:36:03 +02:00
#include <mission/system/objects/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.
*/
class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
2022-03-10 10:54:27 +01:00
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;
2022-03-10 10:54:27 +01:00
2022-09-29 19:40:00 +02:00
DualLaneAssemblyBase(object_id_t objectId, PowerSwitchIF* pwrSwitcher, pcdu::Switches switch1,
pcdu::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;
Event sideSwitchNotAllowedEvent;
Event transitionOtherSideFailedEvent;
2022-03-10 10:54:27 +01:00
uint8_t powerRetryCounter = 0;
bool tryingOtherSide = false;
bool dualModeErrorSwitch = true;
duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE;
enum RecoveryCustomStates {
IDLE,
POWER_SWITCHING_OFF,
POWER_SWITCHING_ON,
DONE
} customRecoveryStates = RecoveryCustomStates::IDLE;
MessageQueueIF* eventQueue = nullptr;
2022-03-10 10:54:27 +01:00
/**
* 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);
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();
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;
2022-03-22 18:48:03 +01:00
virtual void handleModeReached() override;
2022-03-10 10:54:27 +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
*/
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);
entry.setInheritSubmode(false);
modeTable.insert(entry);
}
#endif /* MISSION_SYSTEM_DUALLANEASSEMBLYBASE_H_ */