From ff0da65662bf25fd89609ebbe5850eaacde678cc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Mar 2022 15:37:36 +0100 Subject: [PATCH] started SUS assembly fixes for PCDU code and switcher list handling --- .../fsfwconfig/devices/powerSwitcherList.h | 57 ------ bsp_q7s/core/ObjectFactory.cpp | 6 +- common/config/devices/powerSwitcherList.h | 90 +++++---- linux/devices/GPSHyperionLinuxController.cpp | 8 +- linux/fsfwconfig/devices/powerSwitcherList.h | 57 ------ mission/devices/PCDUHandler.cpp | 128 +++++++----- mission/system/AcsBoardAssembly.cpp | 185 ++++++++++-------- mission/system/AcsBoardAssembly.h | 42 ++-- mission/system/CMakeLists.txt | 1 + mission/system/SusAssembly.cpp | 101 ++++++++++ mission/system/SusAssembly.h | 52 +++++ 11 files changed, 418 insertions(+), 309 deletions(-) delete mode 100644 bsp_hosted/fsfwconfig/devices/powerSwitcherList.h delete mode 100644 linux/fsfwconfig/devices/powerSwitcherList.h create mode 100644 mission/system/SusAssembly.cpp create mode 100644 mission/system/SusAssembly.h diff --git a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h b/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index ae259374..00000000 --- a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ -#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ - -#include - -namespace pcduSwitches { -/* Switches are uint8_t datatype and go from 0 to 255 */ -enum SwitcherList { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES -}; - -static const uint8_t ON = 1; -static const uint8_t OFF = 0; - -/* Output states after reboot of the PDUs */ -static const uint8_t INIT_STATE_Q7S = ON; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; -static const uint8_t INIT_STATE_RW = OFF; -#if BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; -#else -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; -#endif -static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; -static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; -static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} // namespace pcduSwitches - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index bcf5a50f..b4d92b23 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -737,7 +737,7 @@ void ObjectFactory::createHeaterComponents() { heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, - objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); + objects::PCDU_HANDLER, pcduSwitches::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } void ObjectFactory::createSolarArrayDeploymentComponents() { @@ -757,8 +757,8 @@ void ObjectFactory::createSolarArrayDeploymentComponents() { // TODO: Find out burn time. For now set to 1000 ms. new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, solarArrayDeplCookie, objects::PCDU_HANDLER, - pcduSwitches::DEPLOYMENT_MECHANISM, gpioIds::DEPLSA1, - gpioIds::DEPLSA2, 1000); + pcduSwitches::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); } void ObjectFactory::createSyrlinksComponents() { diff --git a/common/config/devices/powerSwitcherList.h b/common/config/devices/powerSwitcherList.h index 45428a2e..a9a75ce4 100644 --- a/common/config/devices/powerSwitcherList.h +++ b/common/config/devices/powerSwitcherList.h @@ -6,54 +6,58 @@ #include namespace pcduSwitches { - /* Switches are uint8_t datatype and go from 0 to 255 */ - enum SwitcherList: uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES - }; +/* Switches are uint8_t datatype and go from 0 to 255 */ +enum Switches: uint8_t { + PDU1_CH0_TCS_BOARD_3V3, + PDU1_CH1_SYRLINKS_12V, + PDU1_CH2_STAR_TRACKER_5V, + PDU1_CH3_MGT_5V, + PDU1_CH4_SUS_NOMINAL_3V3, + PDU1_CH5_SOLAR_CELL_EXP_5V, + PDU1_CH6_PLOC_12V, + PDU1_CH7_ACS_A_SIDE_3V3, + PDU1_CH8_UNOCCUPIED, - static const uint8_t ON = 1; - static const uint8_t OFF = 0; + PDU2_CH0_Q7S, + PDU2_CH1_PL_PCDU_BATT_0_14V8, + PDU2_CH2_RW_5V, + PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + PDU2_CH4_SUS_REDUNDANT_3V3, + PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + PDU2_CH6_PL_PCDU_BATT_1_14V8, + PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + PDU2_CH8_PAYLOAD_CAMERA, + NUMBER_OF_SWITCHES +}; - /* Output states after reboot of the PDUs */ - static const uint8_t INIT_STATE_Q7S = ON; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; - static const uint8_t INIT_STATE_RW = OFF; +static const uint8_t ON = 1; +static const uint8_t OFF = 0; + +/* Output states after reboot of the PDUs */ #if BOARD_TE0720 == 1 - /* Because the TE0720 is not connected to the PCDU, this switch is always on */ - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; +/* Because the TE0720 is not connected to the PCDU, this switch is always on */ +static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; #else - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; +static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; #endif - static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; - static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; - static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; - static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; - static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; - static const uint8_t INIT_STATE_SYRLINKS = OFF; - static const uint8_t INIT_STATE_STAR_TRACKER = OFF; - static const uint8_t INIT_STATE_MGT = OFF; - static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; - static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; - static const uint8_t INIT_STATE_PLOC = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; +static const uint8_t INIT_STATE_SYRLINKS = OFF; +static const uint8_t INIT_STATE_STAR_TRACKER = OFF; +static const uint8_t INIT_STATE_MGT = OFF; +static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; +static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; +static const uint8_t INIT_STATE_PLOC = OFF; +static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; + +static const uint8_t INIT_STATE_Q7S = ON; +static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; +static const uint8_t INIT_STATE_RW = OFF; +static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; +static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; +static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; +static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; +static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; +static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; + } diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GPSHyperionLinuxController.cpp index 63050791..d5b2741e 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GPSHyperionLinuxController.cpp @@ -28,8 +28,8 @@ LocalPoolDataSetBase *GPSHyperionLinuxController::getDataSetHandle(sid_t sid) { ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) { - if(not modeCommanded) { - if(mode == MODE_ON or mode == MODE_OFF) { + if (not modeCommanded) { + if (mode == MODE_ON or mode == MODE_OFF) { // 10 minutes time to reach fix *msToReachTheMode = 600000; maxTimeToReachFix.resetTimer(); @@ -122,9 +122,9 @@ void GPSHyperionLinuxController::readGpsDataFromGpsd() { // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix gpsSet.fixMode.value = gps->fix.mode; if (gps->fix.mode == 0 or gps->fix.mode == 1) { - if(modeCommanded and maxTimeToReachFix.hasTimedOut()) { + if (modeCommanded and maxTimeToReachFix.hasTimedOut()) { // We are supposed to be on and functioning, but not fix was found - if(mode == MODE_ON or mode == MODE_NORMAL) { + if (mode == MODE_ON or mode == MODE_NORMAL) { mode = MODE_OFF; } modeCommanded = false; diff --git a/linux/fsfwconfig/devices/powerSwitcherList.h b/linux/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index cc6bc141..00000000 --- a/linux/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ -#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ - -#include "OBSWConfig.h" - -namespace pcduSwitches { -/* Switches are uint8_t datatype and go from 0 to 255 */ -enum SwitcherList : uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES -}; - -static const uint8_t ON = 1; -static const uint8_t OFF = 0; - -/* Output states after reboot of the PDUs */ -static const uint8_t INIT_STATE_Q7S = ON; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; -static const uint8_t INIT_STATE_RW = OFF; -#if BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; -#else -static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; -#endif -static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; -static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; -static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; -static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} // namespace pcduSwitches - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 13bed074..9fc78c04 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -1,10 +1,11 @@ #include "PCDUHandler.h" #include +#include +#include #include #include #include -#include PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) : SystemObject(setObjectId), @@ -74,24 +75,26 @@ ReturnValue_t PCDUHandler::initialize() { } void PCDUHandler::initializeSwitchStates() { - switchStates[pcduSwitches::Q7S] = pcduSwitches::INIT_STATE_Q7S; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1; - switchStates[pcduSwitches::RW] = pcduSwitches::INIT_STATE_RW; - switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = + using namespace pcduSwitches; + switchStates[Switches::PDU2_CH0_Q7S] = pcduSwitches::INIT_STATE_Q7S; + switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1; + switchStates[Switches::PDU2_CH2_RW_5V] = pcduSwitches::INIT_STATE_RW; + switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] = pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN; - switchStates[pcduSwitches::SUS_REDUNDANT] = pcduSwitches::INIT_STATE_SUS_REDUNDANT; - switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6; - switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B; - switchStates[pcduSwitches::PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA; - switchStates[pcduSwitches::TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3; - switchStates[pcduSwitches::SYRLINKS] = pcduSwitches::INIT_STATE_SYRLINKS; - switchStates[pcduSwitches::STAR_TRACKER] = pcduSwitches::INIT_STATE_STAR_TRACKER; - switchStates[pcduSwitches::MGT] = pcduSwitches::INIT_STATE_MGT; - switchStates[pcduSwitches::SUS_NOMINAL] = pcduSwitches::INIT_STATE_SUS_NOMINAL; - switchStates[pcduSwitches::SOLAR_CELL_EXP] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP; - switchStates[pcduSwitches::PLOC] = pcduSwitches::INIT_STATE_PLOC; - switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A; + switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = pcduSwitches::INIT_STATE_SUS_REDUNDANT; + switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] = + pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM; + switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6; + switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B; + switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA; + switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3; + switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pcduSwitches::INIT_STATE_SYRLINKS; + switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = pcduSwitches::INIT_STATE_STAR_TRACKER; + switchStates[Switches::PDU1_CH3_MGT_5V] = pcduSwitches::INIT_STATE_MGT; + switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = pcduSwitches::INIT_STATE_SUS_NOMINAL; + switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP; + switchStates[Switches::PDU1_CH6_PLOC_12V] = pcduSwitches::INIT_STATE_PLOC; + switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A; } void PCDUHandler::readCommandQueue() { @@ -152,36 +155,48 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet } void PCDUHandler::updatePdu2SwitchStates() { - // TODO: pool read helper - if (pdu2HkTableDataset.read() == RETURN_OK) { - switchStates[pcduSwitches::Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pdu2HkTableDataset.outEnabledPlPCDUCh1.value; - switchStates[pcduSwitches::RW] = pdu2HkTableDataset.outEnabledReactionWheels.value; - switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = + using namespace pcduSwitches; + PoolReadGuard rf(&pdu2HkTableDataset); + if (rf.getReadResult() == RETURN_OK) { + switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; + switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] = + pdu2HkTableDataset.outEnabledPlPCDUCh1.value; + switchStates[Switches::PDU2_CH2_RW_5V] = pdu2HkTableDataset.outEnabledReactionWheels.value; + switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] = pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value; - switchStates[pcduSwitches::SUS_REDUNDANT] = pdu2HkTableDataset.outEnabledSUSRedundant.value; - switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = + switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = + pdu2HkTableDataset.outEnabledSUSRedundant.value; + switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] = pdu2HkTableDataset.outEnabledDeplMechanism.value; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pdu2HkTableDataset.outEnabledPlPCDUCh6.value; - switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pdu2HkTableDataset.outEnabledAcsBoardSideB.value; - switchStates[pcduSwitches::PAYLOAD_CAMERA] = pdu2HkTableDataset.outEnabledPayloadCamera.value; + switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = + pdu2HkTableDataset.outEnabledPlPCDUCh6.value; + switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = + pdu2HkTableDataset.outEnabledAcsBoardSideB.value; + switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = + pdu2HkTableDataset.outEnabledPayloadCamera.value; } else { sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" << std::endl; } - pdu2HkTableDataset.commit(); } void PCDUHandler::updatePdu1SwitchStates() { if (pdu1HkTableDataset.read() == RETURN_OK) { - switchStates[pcduSwitches::TCS_BOARD_3V3] = pdu1HkTableDataset.voltageOutTCSBoard3V3.value; - switchStates[pcduSwitches::SYRLINKS] = pdu1HkTableDataset.voltageOutSyrlinks.value; - switchStates[pcduSwitches::STAR_TRACKER] = pdu1HkTableDataset.voltageOutStarTracker.value; - switchStates[pcduSwitches::MGT] = pdu1HkTableDataset.voltageOutMGT.value; - switchStates[pcduSwitches::SUS_NOMINAL] = pdu1HkTableDataset.voltageOutSUSNominal.value; - switchStates[pcduSwitches::SOLAR_CELL_EXP] = pdu1HkTableDataset.voltageOutSolarCellExp.value; - switchStates[pcduSwitches::PLOC] = pdu1HkTableDataset.voltageOutPLOC.value; - switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pdu1HkTableDataset.voltageOutACSBoardSideA.value; + using namespace pcduSwitches; + PoolReadGuard rf(&pdu1HkTableDataset); + switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value; + switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value; + switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = + pdu1HkTableDataset.outEnabledStarTracker.value; + switchStates[Switches::PDU1_CH3_MGT_5V] = pdu1HkTableDataset.outEnabledMGT.value; + switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = + pdu1HkTableDataset.outEnabledSUSNominal.value; + switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = + pdu1HkTableDataset.outEnabledSolarCellExp.value; + switchStates[Switches::PDU1_CH6_PLOC_12V] = pdu1HkTableDataset.outEnabledPLOC.value; + switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = + pdu1HkTableDataset.outEnabledAcsBoardSideA.value; + switchStates[Switches::PDU1_CH8_UNOCCUPIED] = pdu1HkTableDataset.outEnabledChannel8.value; } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; } @@ -191,24 +206,49 @@ void PCDUHandler::updatePdu1SwitchStates() { LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; } void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const { + using namespace pcduSwitches; ReturnValue_t result; - uint16_t memoryAddress; + uint16_t memoryAddress = 0; size_t parameterValueSize = sizeof(uint8_t); - uint8_t parameterValue; - GomspaceDeviceHandler* pdu; + uint8_t parameterValue = 0; + GomspaceDeviceHandler* pdu = nullptr; switch (switchNr) { - case pcduSwitches::TCS_BOARD_8V_HEATER_IN: + case pcduSwitches::PDU1_CH0_TCS_BOARD_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH1_SYRLINKS_12V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SYRLINKS; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH2_STAR_TRACKER_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_STAR_TRACKER; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH3_MGT_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_MGT; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; - case pcduSwitches::DEPLOYMENT_MECHANISM: + } + case pcduSwitches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; - default: + } + + default: { sif::error << "PCDUHandler::sendSwitchCommand: Invalid switch number " << std::endl; return; + } } switch (onOff) { diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 15332901..3d695d8e 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -1,12 +1,11 @@ #include "AcsBoardAssembly.h" -#include #include #include AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, AcsBoardHelper helper) - : AssemblyBase(objectId, parentId), switcher(switcher), helper(helper) { + : AssemblyBase(objectId, parentId), pwrSwitcher(switcher), helper(helper) { if (switcher == nullptr) { sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid Power Switcher " "IF passed" @@ -26,34 +25,31 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { ReturnValue_t result = RETURN_OK; - if (currentMode == mode and submode == currentSubmode) { - return result; - } refreshHelperModes(); - if (state == States::MODE_COMMANDING) { - if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { - powerStateMachine(submode); + powerStateMachine(mode, submode); + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + if (state == States::MODE_COMMANDING) { handleNormalOrOnModeCmd(mode, submode); - } else { - modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } + } else { + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } HybridIterator tableIter(modeTable.begin(), modeTable.end()); @@ -63,25 +59,25 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { refreshHelperModes(); - if(wantedSubmode == A_SIDE) { - if((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or + if (wantedSubmode == A_SIDE) { + if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or helper.gpsMode != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; } else if (wantedSubmode == B_SIDE) { - if((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or + if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return RETURN_OK; - } else if(wantedSubmode == DUAL_MODE) { - if((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and - helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or + } else if (wantedSubmode == DUAL_MODE) { + if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and + helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and - helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or + helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or helper.gpsMode != wantedMode) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } @@ -102,7 +98,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s ReturnValue_t result = RETURN_OK; Mode_t tgtMode = DeviceHandlerIF::MODE_NORMAL; auto cmdSeq = [&](object_id_t objectId, ModeTableIdx tableIdx) { - if(tgtMode == DeviceHandlerIF::MODE_NORMAL) { + if (tgtMode == DeviceHandlerIF::MODE_NORMAL) { if (isUseable(objectId, mode)) { if (helper.gyro0SideAMode != MODE_OFF) { modeTable[tableIdx].setMode(tgtMode); @@ -113,7 +109,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s modeTable[tableIdx].setSubmode(SUBMODE_NONE); } } - } else if(tgtMode == MODE_ON) { + } else if (tgtMode == MODE_ON) { if (isUseable(objectId, mode)) { modeTable[tableIdx].setMode(MODE_ON); modeTable[tableIdx].setSubmode(SUBMODE_NONE); @@ -172,62 +168,82 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s return result; } -void AcsBoardAssembly::powerStateMachine(Submode_t submode) { - ReturnValue_t switchStateA = switcher->getSwitchState(pcduSwitches::ACS_BOARD_SIDE_A); - ReturnValue_t switchStateB = switcher->getSwitchState(pcduSwitches::ACS_BOARD_SIDE_B); - switch (submode) { - case (A_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { +void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { + ReturnValue_t switchStateA = RETURN_OK; + ReturnValue_t switchStateB = RETURN_OK; + if (state == States::IDLE or state == States::SWITCHING_POWER) { + switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); + switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); + if (mode == MODE_OFF) { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { state = States::MODE_COMMANDING; return; } - break; - } - case (B_SIDE): { - if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; - } - break; - } - case (DUAL_MODE): { - if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = States::MODE_COMMANDING; - return; + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and + switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (B_SIDE): { + if (switchStateA == PowerSwitchIF::SWITCH_OFF and + switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (DUAL_MODE): { + if (switchStateA == PowerSwitchIF::SWITCH_ON and + switchStateB == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + } } } } if (state == States::IDLE) { - switch (submode) { - case (A_SIDE): { - if (switchStateA != PowerSwitchIF::SWITCH_ON) { - // Set A side on first in power switcher IF - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, true); - } - if (switchStateB != PowerSwitchIF::SWITCH_OFF) { - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, false); - } - break; + if (mode == MODE_OFF) { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, false); } - case (B_SIDE): { - if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - // Set A side on first in power switcher IF - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, false); - } - if (switchStateB != PowerSwitchIF::SWITCH_ON) { - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, true); - } - break; + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, false); } - case (DUAL_MODE): { - if (switchStateA != PowerSwitchIF::SWITCH_ON) { - // Set A side on first in power switcher IF - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_A, true); + } else { + switch (submode) { + case (A_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, true); + } + if (switchStateB != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, false); + } + break; } - if (switchStateB != PowerSwitchIF::SWITCH_ON) { - switcher->sendSwitchCommand(pcduSwitches::ACS_BOARD_SIDE_B, true); + case (B_SIDE): { + if (switchStateA != PowerSwitchIF::SWITCH_OFF) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, false); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, true); + } + break; + } + case (DUAL_MODE): { + if (switchStateA != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_A, true); + } + if (switchStateB != PowerSwitchIF::SWITCH_ON) { + pwrSwitcher->sendSwitchCommand(SWITCH_B, true); + } + break; } - break; } } state = States::SWITCHING_POWER; @@ -274,7 +290,7 @@ ReturnValue_t AcsBoardAssembly::initialize() { } ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - if(submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { + if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -296,6 +312,11 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { return false; } +void AcsBoardAssembly::handleModeReached() { + AssemblyBase::handleModeReached(); + state = States::IDLE; +} + void AcsBoardAssembly::refreshHelperModes() { helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode; helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode; diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index c1e2a29e..4116f6c9 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -1,6 +1,7 @@ #ifndef MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ #define MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ +#include #include #include @@ -52,37 +53,40 @@ enum ModeTableIdx : uint8_t { GPS = 8 }; -static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; - class PowerSwitchIF; class AcsBoardAssembly : public AssemblyBase { public: - AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, - AcsBoardHelper helper); - - private: - enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING }; - - States state = States::IDLE; - Mode_t currentMode = MODE_OFF; - Submode_t currentSubmode = A_SIDE; - PowerSwitchIF* switcher = nullptr; - - AcsBoardHelper helper; - void initModeTableEntry(object_id_t id, ModeListEntry& entry); - - ReturnValue_t initialize() override; - FixedArrayList modeTable; + static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; static constexpr Submode_t A_SIDE = 0; static constexpr Submode_t B_SIDE = 1; static constexpr Submode_t DUAL_MODE = 2; + AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + AcsBoardHelper helper); + + private: + static constexpr pcduSwitches::Switches SWITCH_A = + pcduSwitches::Switches::PDU1_CH7_ACS_A_SIDE_3V3; + static constexpr pcduSwitches::Switches SWITCH_B = + pcduSwitches::Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3; + + enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; + + PowerSwitchIF* pwrSwitcher = nullptr; + + AcsBoardHelper helper; + FixedArrayList modeTable; + void initModeTableEntry(object_id_t id, ModeListEntry& entry); + + ReturnValue_t initialize() override; + // AssemblyBase overrides ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + void handleModeReached() override; /** * Check whether it makes sense to send mode commands to the device @@ -92,7 +96,7 @@ class AcsBoardAssembly : public AssemblyBase { */ bool isUseable(object_id_t object, Mode_t mode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); - void powerStateMachine(Submode_t submode); + void powerStateMachine(Mode_t mode, Submode_t submode); void refreshHelperModes(); }; diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt index 880055e4..6296de1e 100644 --- a/mission/system/CMakeLists.txt +++ b/mission/system/CMakeLists.txt @@ -1,5 +1,6 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE AcsBoardAssembly.cpp + SusAssembly.cpp AcsSubsystem.cpp TcsSubsystem.cpp EiveSystem.cpp diff --git a/mission/system/SusAssembly.cpp b/mission/system/SusAssembly.cpp new file mode 100644 index 00000000..21e5aa50 --- /dev/null +++ b/mission/system/SusAssembly.cpp @@ -0,0 +1,101 @@ +#include "SusAssembly.h" + +#include +#include +#include + +SusAssembly::SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + SusAssHelper helper) + : AssemblyBase(objectId, parentId), helper(helper), pwrSwitcher(pwrSwitcher) {} + +ReturnValue_t SusAssembly::commandChildren(Mode_t mode, Submode_t submode) { + ReturnValue_t result = RETURN_OK; + refreshHelperModes(); + return RETURN_OK; +} + +ReturnValue_t SusAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + return RETURN_OK; +} + +ReturnValue_t SusAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if (submode != NOMINAL and submode != REDUNDANT and submode != DUAL_MODE) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SusAssembly::initialize() { + ReturnValue_t result = RETURN_OK; + for (const auto& id : helper.susIds) { + result = registerChild(id); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; +} + +bool SusAssembly::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +void SusAssembly::powerStateMachine(Mode_t mode, Submode_t submode) { + ReturnValue_t switchStateNom = RETURN_OK; + ReturnValue_t switchStateRed = RETURN_OK; + if (state == States::IDLE or state == States::SWITCHING_POWER) { + switchStateNom = pwrSwitcher->getSwitchState(pcduSwitches::PDU1_CH4_SUS_NOMINAL_3V3); + switchStateRed = pwrSwitcher->getSwitchState(pcduSwitches::PDU2_CH4_SUS_REDUNDANT_3V3); + if (mode == MODE_OFF) { + if (switchStateNom == PowerSwitchIF::SWITCH_OFF and + switchStateRed == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + } else { + switch (submode) { + case (NOMINAL): { + if (switchStateNom == PowerSwitchIF::SWITCH_ON and + switchStateRed == PowerSwitchIF::SWITCH_OFF) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (REDUNDANT): { + if (switchStateNom == PowerSwitchIF::SWITCH_OFF and + switchStateRed == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + break; + } + case (DUAL_MODE): { + if (switchStateNom == PowerSwitchIF::SWITCH_ON and + switchStateRed == PowerSwitchIF::SWITCH_ON) { + state = States::MODE_COMMANDING; + return; + } + } + } + } + } +} + +void SusAssembly::refreshHelperModes() { + for (uint8_t idx = 0; idx < helper.susModes.size(); idx++) { + helper.susModes[idx] = childrenMap[helper.susIds[idx]].mode; + } +} diff --git a/mission/system/SusAssembly.h b/mission/system/SusAssembly.h new file mode 100644 index 00000000..c09384fb --- /dev/null +++ b/mission/system/SusAssembly.h @@ -0,0 +1,52 @@ +#ifndef MISSION_SYSTEM_SUSASSEMBLY_H_ +#define MISSION_SYSTEM_SUSASSEMBLY_H_ + +#include + +struct SusAssHelper { + public: + SusAssHelper(std::array susIds) : susIds(susIds) {} + std::array susIds = {objects::NO_OBJECT}; + std::array susModes = {HasModesIF::MODE_OFF}; +}; + +class PowerSwitchIF; + +class SusAssembly : AssemblyBase { + public: + static constexpr uint8_t NUMBER_SUN_SENSORS = 12; + + static constexpr Submode_t NOMINAL = 0; + static constexpr Submode_t REDUNDANT = 1; + static constexpr Submode_t DUAL_MODE = 2; + + SusAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + SusAssHelper helper); + + private: + enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; + + FixedArrayList modeTable; + + SusAssHelper helper; + PowerSwitchIF* pwrSwitcher = nullptr; + + ReturnValue_t initialize() override; + + // AssemblyBase overrides + ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; + ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + + /** + * 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); + void powerStateMachine(Mode_t mode, Submode_t submode); + void refreshHelperModes(); +}; + +#endif /* MISSION_SYSTEM_SUSASSEMBLY_H_ */