diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d3336ae..df2d01dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ will consitute of a breaking change warranting a new major release: ## Added +- PL PCDU: Add command to enable and disable channel order checks. - Added new PUS 15 subservice `DELETE_BY_TIME_RANGE` which allows to also specify a deletion start time when deleting packets from the persistent TM store. - Introduced a new `RELOAD_JSON_CFG_FILE` command for the STR to reload the JSON configuration diff --git a/mission/payload/PayloadPcduHandler.cpp b/mission/payload/PayloadPcduHandler.cpp index b3b71aea..1fc3fa99 100644 --- a/mission/payload/PayloadPcduHandler.cpp +++ b/mission/payload/PayloadPcduHandler.cpp @@ -4,6 +4,7 @@ #include "OBSWConfig.h" #include "fsfw/thermal/tcsDefinitions.h" +#include "mission/payload/payloadPcduDefinitions.h" #ifdef XIPHOS_Q7S #include @@ -428,20 +429,20 @@ void PayloadPcduHandler::checkAdcValues() { params.getValue(PARAM_KEY_MAP[NEG_V_UPPER_BOUND], upperBound); if (not checkVoltage(adcSet.processed[U_NEG_V_FB], lowerBound, upperBound, NEG_V_OUT_OF_BOUNDS)) { + sif::warning << "Negative voltage was out of bounds, went back to OFF" << std::endl; return; } params.getValue(PARAM_KEY_MAP[DRO_U_LOWER_BOUND], lowerBound); params.getValue(PARAM_KEY_MAP[DRO_U_UPPER_BOUND], upperBound); if (not checkVoltage(adcSet.processed[U_DRO_DIV_6], lowerBound, upperBound, U_DRO_OUT_OF_BOUNDS)) { + sif::warning << "DRO voltage was out of bounds, went back to OFF" << std::endl; return; } params.getValue(PARAM_KEY_MAP[DRO_I_UPPER_BOUND], upperBound); if (not checkCurrent(adcSet.processed[I_DRO], upperBound, I_DRO_OUT_OF_BOUNDS)) { -#if OBSW_VERBOSE_LEVEL >= 1 sif::warning << "Detected out of bounds current for DRO: " << adcSet.processed[I_DRO] << ", Raw: " << adcSet.channels[I_DRO] << std::endl; -#endif return; } } @@ -455,10 +456,12 @@ void PayloadPcduHandler::checkAdcValues() { params.getValue(PARAM_KEY_MAP[X8_U_UPPER_BOUND], upperBound); if (not checkVoltage(adcSet.processed[U_X8_DIV_6], lowerBound, upperBound, U_X8_OUT_OF_BOUNDS)) { + sif::warning << "X8 voltage was out of bounds, went back to OFF" << std::endl; return; } params.getValue(PARAM_KEY_MAP[X8_I_UPPER_BOUND], upperBound); if (not checkCurrent(adcSet.processed[I_X8], upperBound, I_X8_OUT_OF_BOUNDS)) { + sif::warning << "X8 current was out of bounds, went back to OFF" << std::endl; return; } } @@ -472,10 +475,12 @@ void PayloadPcduHandler::checkAdcValues() { params.getValue(PARAM_KEY_MAP[TX_U_UPPER_BOUND], upperBound); if (not checkVoltage(adcSet.processed[U_TX_DIV_6], lowerBound, upperBound, U_TX_OUT_OF_BOUNDS)) { + sif::warning << "TX voltage was out of bounds, went back to OFF" << std::endl; return; } params.getValue(PARAM_KEY_MAP[TX_I_UPPER_BOUND], upperBound); if (not checkCurrent(adcSet.processed[I_TX], upperBound, I_TX_OUT_OF_BOUNDS)) { + sif::warning << "TX current was out of bounds, went back to OFF" << std::endl; return; } } @@ -489,10 +494,12 @@ void PayloadPcduHandler::checkAdcValues() { params.getValue(PARAM_KEY_MAP[MPA_U_UPPER_BOUND], upperBound); if (not checkVoltage(adcSet.processed[U_MPA_DIV_6], lowerBound, upperBound, U_MPA_OUT_OF_BOUNDS)) { + sif::warning << "MPA voltage was out of bounds, went back to OFF" << std::endl; return; } params.getValue(PARAM_KEY_MAP[MPA_I_UPPER_BOUND], upperBound); if (not checkCurrent(adcSet.processed[I_MPA], upperBound, I_MPA_OUT_OF_BOUNDS)) { + sif::warning << "MPA current was out of bounds, went back to OFF" << std::endl; return; } } @@ -506,6 +513,7 @@ void PayloadPcduHandler::checkAdcValues() { params.getValue(PARAM_KEY_MAP[HPA_U_UPPER_BOUND], upperBound); if (not checkVoltage(adcSet.processed[U_HPA_DIV_6], lowerBound, upperBound, U_HPA_OUT_OF_BOUNDS)) { + sif::warning << "HPA voltage was out of bounds, went back to OFF" << std::endl; return; } params.getValue(PARAM_KEY_MAP[HPA_I_UPPER_BOUND], upperBound); @@ -576,6 +584,7 @@ void PayloadPcduHandler::performOperationHook() { checkJsonFileInit(); } ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, uint32_t* msToReachTheMode) { + using namespace plpcdu; if (commandedMode != MODE_OFF) { PoolReadGuard pg(&enablePl); if (pg.getReadResult() == returnvalue::OK) { @@ -584,45 +593,59 @@ ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode } } } - return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode); -} - -ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { - using namespace plpcdu; - if (mode == MODE_NORMAL) { + if (commandedMode == MODE_NORMAL) { uint8_t dhbSubmode = getSubmode(); - diffMask = submode ^ dhbSubmode; - // Also deals with the case where the mode is MODE_ON, submode should be 0 here - if ((((submode >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == SOLID_STATE_RELAYS_ADC_ON) and - (getMode() == MODE_NORMAL and dhbSubmode != ALL_OFF_SUBMODE)) { + diffMask = commandedSubmode ^ dhbSubmode; + // For all higher level modes, SSR needs to be on. This is to ensure we have valid ADC + // measurements + if ((droOnForSubmode(commandedSubmode) or x8OnForSubmode(commandedSubmode) or + txOnForSubmode(commandedSubmode) or mpaOnForSubmode(commandedSubmode) or + hpaOnForSubmode(commandedSubmode)) and + not ssrOnForSubmode(dhbSubmode)) { return TRANS_NOT_ALLOWED; } - if (((((submode >> DRO_ON) & 1) == 1) and - ((dhbSubmode & 0b1) != (1 << SOLID_STATE_RELAYS_ADC_ON)))) { + if (disableChannelOrderCheck) { + return returnvalue::OK; + } + if (x8OnForSubmode(commandedSubmode) and not droOnForSubmode(dhbSubmode)) { return TRANS_NOT_ALLOWED; } - if ((((submode >> X8_ON) & 1) == 1) and - ((dhbSubmode & 0b11) != ((1 << SOLID_STATE_RELAYS_ADC_ON) | (1 << DRO_ON)))) { + if (txOnForSubmode(commandedSubmode) and + (not droOnForSubmode(dhbSubmode) or not x8OnForSubmode(dhbSubmode))) { return TRANS_NOT_ALLOWED; } - if (((((submode >> TX_ON) & 1) == 1) and - ((dhbSubmode & 0b111) != - ((1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) { + if (mpaOnForSubmode(commandedSubmode) and + (not droOnForSubmode(dhbSubmode) or not x8OnForSubmode(dhbSubmode) or + not txOnForSubmode(dhbSubmode))) { return TRANS_NOT_ALLOWED; } - if ((((submode >> MPA_ON) & 1) == 1 and - ((dhbSubmode & 0b1111) != - ((1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) { - return TRANS_NOT_ALLOWED; - } - if ((((submode >> HPA_ON) & 1) == 1 and - ((dhbSubmode & 0b11111) != ((1 << MPA_ON) | (1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) | - (1 << SOLID_STATE_RELAYS_ADC_ON))))) { + if (hpaOnForSubmode(commandedSubmode) and + (not droOnForSubmode(dhbSubmode) or not x8OnForSubmode(dhbSubmode) or + not txOnForSubmode(dhbSubmode) or not mpaOnForSubmode(dhbSubmode))) { return TRANS_NOT_ALLOWED; } return returnvalue::OK; } - return DeviceHandlerBase::isModeCombinationValid(mode, submode); + return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode); +} + +bool PayloadPcduHandler::ssrOnForSubmode(uint8_t submode) { + return submode & (1 << plpcdu::SOLID_STATE_RELAYS_ADC_ON); +} +bool PayloadPcduHandler::droOnForSubmode(uint8_t submode) { + return submode & (1 << plpcdu::DRO_ON); +} + +bool PayloadPcduHandler::x8OnForSubmode(uint8_t submode) { return submode & (1 << plpcdu::X8_ON); } + +bool PayloadPcduHandler::txOnForSubmode(uint8_t submode) { return submode & (1 << plpcdu::TX_ON); } + +bool PayloadPcduHandler::mpaOnForSubmode(uint8_t submode) { + return submode & (1 << plpcdu::MPA_ON); +} + +bool PayloadPcduHandler::hpaOnForSubmode(uint8_t submode) { + return submode & (1 << plpcdu::HPA_ON); } ReturnValue_t PayloadPcduHandler::serializeFloat(uint32_t& param, float val) { @@ -637,56 +660,68 @@ ReturnValue_t PayloadPcduHandler::getParameter(uint8_t domainId, uint8_t uniqueI uint16_t startAtIndex) { using namespace plpcdu; switch (uniqueId) { - case (PlPcduParamIds::NEG_V_LOWER_BOUND): - case (PlPcduParamIds::NEG_V_UPPER_BOUND): - case (PlPcduParamIds::DRO_U_LOWER_BOUND): - case (PlPcduParamIds::DRO_U_UPPER_BOUND): - case (PlPcduParamIds::DRO_I_UPPER_BOUND): - case (PlPcduParamIds::X8_U_LOWER_BOUND): - case (PlPcduParamIds::X8_U_UPPER_BOUND): - case (PlPcduParamIds::X8_I_UPPER_BOUND): - case (PlPcduParamIds::TX_U_LOWER_BOUND): - case (PlPcduParamIds::TX_U_UPPER_BOUND): - case (PlPcduParamIds::TX_I_UPPER_BOUND): - case (PlPcduParamIds::MPA_U_LOWER_BOUND): - case (PlPcduParamIds::MPA_U_UPPER_BOUND): - case (PlPcduParamIds::MPA_I_UPPER_BOUND): - case (PlPcduParamIds::HPA_U_LOWER_BOUND): - case (PlPcduParamIds::HPA_U_UPPER_BOUND): - case (PlPcduParamIds::HPA_I_UPPER_BOUND): - case (PlPcduParamIds::SSR_TO_DRO_WAIT_TIME): - case (PlPcduParamIds::DRO_TO_X8_WAIT_TIME): - case (PlPcduParamIds::X8_TO_TX_WAIT_TIME): - case (PlPcduParamIds::TX_TO_MPA_WAIT_TIME): - case (PlPcduParamIds::MPA_TO_HPA_WAIT_TIME): { - handleDoubleParamUpdate(PARAM_KEY_MAP[static_cast(uniqueId)], - parameterWrapper, newValues); + case (PlPcduParamId::NEG_V_LOWER_BOUND): + case (PlPcduParamId::NEG_V_UPPER_BOUND): + case (PlPcduParamId::DRO_U_LOWER_BOUND): + case (PlPcduParamId::DRO_U_UPPER_BOUND): + case (PlPcduParamId::DRO_I_UPPER_BOUND): + case (PlPcduParamId::X8_U_LOWER_BOUND): + case (PlPcduParamId::X8_U_UPPER_BOUND): + case (PlPcduParamId::X8_I_UPPER_BOUND): + case (PlPcduParamId::TX_U_LOWER_BOUND): + case (PlPcduParamId::TX_U_UPPER_BOUND): + case (PlPcduParamId::TX_I_UPPER_BOUND): + case (PlPcduParamId::MPA_U_LOWER_BOUND): + case (PlPcduParamId::MPA_U_UPPER_BOUND): + case (PlPcduParamId::MPA_I_UPPER_BOUND): + case (PlPcduParamId::HPA_U_LOWER_BOUND): + case (PlPcduParamId::HPA_U_UPPER_BOUND): + case (PlPcduParamId::HPA_I_UPPER_BOUND): + case (PlPcduParamId::SSR_TO_DRO_WAIT_TIME): + case (PlPcduParamId::DRO_TO_X8_WAIT_TIME): + case (PlPcduParamId::X8_TO_TX_WAIT_TIME): + case (PlPcduParamId::TX_TO_MPA_WAIT_TIME): + case (PlPcduParamId::MPA_TO_HPA_WAIT_TIME): { + handleDoubleParamUpdate(PARAM_KEY_MAP[static_cast(uniqueId)], parameterWrapper, + newValues); break; } - case (PlPcduParamIds::INJECT_SSR_TO_DRO_FAILURE): { + case (PlPcduParamId::INJECT_SSR_TO_DRO_FAILURE): { ssrToDroInjectionRequested = true; break; } - case (PlPcduParamIds::INJECT_DRO_TO_X8_FAILURE): { + case (PlPcduParamId::INJECT_DRO_TO_X8_FAILURE): { droToX8InjectionRequested = true; break; } - case (PlPcduParamIds::INJECT_X8_TO_TX_FAILURE): { + case (PlPcduParamId::INJECT_X8_TO_TX_FAILURE): { x8ToTxInjectionRequested = true; break; } - case (PlPcduParamIds::INJECT_TX_TO_MPA_FAILURE): { + case (PlPcduParamId::INJECT_TX_TO_MPA_FAILURE): { txToMpaInjectionRequested = true; break; } - case (PlPcduParamIds::INJECT_MPA_TO_HPA_FAILURE): { + case (PlPcduParamId::INJECT_MPA_TO_HPA_FAILURE): { mpaToHpaInjectionRequested = true; break; } - case (PlPcduParamIds::INJECT_ALL_ON_FAILURE): { + case (PlPcduParamId::INJECT_ALL_ON_FAILURE): { allOnInjectRequested = true; break; } + case (PlPcduParamId::DISABLE_ORDER_CHECK_CHANNELS): { + uint8_t newValue = 0; + ReturnValue_t result = newValues->getElement(&newValue); + if (result != returnvalue::OK) { + return result; + } + if (newValue > 1) { + return HasParametersIF::INVALID_VALUE; + } + parameterWrapper->set(disableChannelOrderCheck); + break; + } default: { return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues, startAtIndex); diff --git a/mission/payload/PayloadPcduHandler.h b/mission/payload/PayloadPcduHandler.h index d48d0f89..da9da1e1 100644 --- a/mission/payload/PayloadPcduHandler.h +++ b/mission/payload/PayloadPcduHandler.h @@ -137,6 +137,12 @@ class PayloadPcduHandler : public DeviceHandlerBase { PoolEntry({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); PoolEntry tempC = PoolEntry({0.0}); + /** + * This parameter disables all checks for the channels except the SSR on check. The SSR on check + * is kept to ensure that there is a common start point where the ADC is enabled. + */ + uint8_t disableChannelOrderCheck = false; + void updateSwitchGpio(gpioId_t id, gpio::Levels level); void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; @@ -155,7 +161,6 @@ class PayloadPcduHandler : public DeviceHandlerBase { uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; - ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex) override; @@ -177,6 +182,12 @@ class PayloadPcduHandler : public DeviceHandlerBase { pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER); ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, uint32_t* msToReachTheMode) override; + static bool ssrOnForSubmode(uint8_t submode); + static bool droOnForSubmode(uint8_t submode); + static bool x8OnForSubmode(uint8_t submode); + static bool txOnForSubmode(uint8_t submode); + static bool mpaOnForSubmode(uint8_t submode); + static bool hpaOnForSubmode(uint8_t submode); }; #endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */ diff --git a/mission/payload/payloadPcduDefinitions.h b/mission/payload/payloadPcduDefinitions.h index e6c7b653..dbd38a9d 100644 --- a/mission/payload/payloadPcduDefinitions.h +++ b/mission/payload/payloadPcduDefinitions.h @@ -35,7 +35,7 @@ enum PlPcduAdcChannels : uint8_t { NUM_CHANNELS = 12 }; -enum PlPcduParamIds : uint8_t { +enum PlPcduParamId : uint8_t { NEG_V_LOWER_BOUND = 0, NEG_V_UPPER_BOUND = 1, DRO_U_LOWER_BOUND = 2, @@ -65,10 +65,12 @@ enum PlPcduParamIds : uint8_t { INJECT_X8_TO_TX_FAILURE = 32, INJECT_TX_TO_MPA_FAILURE = 33, INJECT_MPA_TO_HPA_FAILURE = 34, - INJECT_ALL_ON_FAILURE = 35 + INJECT_ALL_ON_FAILURE = 35, + + DISABLE_ORDER_CHECK_CHANNELS = 40 }; -static std::map PARAM_KEY_MAP = { +static std::map PARAM_KEY_MAP = { {NEG_V_LOWER_BOUND, "negVoltLowerBound"}, {NEG_V_UPPER_BOUND, "negVoltUpperBound"}, {DRO_U_LOWER_BOUND, "droVoltLowerBound"}, {DRO_U_UPPER_BOUND, "droVoltUpperBound"}, {DRO_I_UPPER_BOUND, "droCurrUpperBound"}, {X8_U_LOWER_BOUND, "x8VoltLowerBound"}, diff --git a/tmtc b/tmtc index a41dc9b6..3b047094 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a41dc9b691ab51b8526b3a3982f35072f5d82632 +Subproject commit 3b047094e691abfe114fd5b87dd85a4c69403394