that should do the job
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good

This commit is contained in:
Robin Müller 2023-08-02 15:29:13 +02:00
parent b23ae2e152
commit d2c0c1709e
Signed by: muellerr
GPG Key ID: 407F9B00F858F270
2 changed files with 130 additions and 139 deletions

View File

@ -66,7 +66,11 @@ void PayloadPcduHandler::doShutDown() {
} }
state = States::PL_PCDU_OFF; state = States::PL_PCDU_OFF;
quickTransitionAlreadyCalled = false; quickTransitionAlreadyCalled = false;
adcSet.setReportingEnabled(false); {
PoolReadGuard pg(&adcSet);
adcSet.setReportingEnabled(false);
adcSet.setValidity(false, true);
}
// No need to set mode _MODE_POWER_DOWN, power switching was already handled // No need to set mode _MODE_POWER_DOWN, power switching was already handled
setMode(MODE_OFF); setMode(MODE_OFF);
} }
@ -86,6 +90,7 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
using namespace plpcdu; using namespace plpcdu;
bool doFinish = true; bool doFinish = true;
if (toNormalOneShot) { if (toNormalOneShot) {
PoolReadGuard pg(&adcSet);
adcSet.setReportingEnabled(true); adcSet.setReportingEnabled(true);
toNormalOneShot = false; toNormalOneShot = false;
} }
@ -114,23 +119,23 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
state = States::ON_TRANS_ADC_CLOSE_ZERO; state = States::ON_TRANS_ADC_CLOSE_ZERO;
adcCountdown.setTimeout(50); adcCountdown.setTimeout(50);
adcCountdown.resetTimer(); adcCountdown.resetTimer();
adcState = AdcStates::BOOT_DELAY; adcState = AdcState::BOOT_DELAY;
doFinish = false; doFinish = false;
// If the values are not close to zero, we should not allow transition // If the values are not close to zero, we should not allow transition
monMode = MonitoringMode::CLOSE_TO_ZERO; monMode = MonitoringMode::CLOSE_TO_ZERO;
} }
} }
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) { if (state == States::ON_TRANS_ADC_CLOSE_ZERO) {
if (adcState == AdcStates::BOOT_DELAY) { if (adcState == AdcState::BOOT_DELAY) {
doFinish = false; doFinish = false;
if (adcCountdown.hasTimedOut()) { if (adcCountdown.hasTimedOut()) {
adcState = AdcStates::SEND_SETUP; adcState = AdcState::SEND_SETUP;
adcCmdExecuted = false; adcCmdExecuted = false;
} }
} }
if (adcState == AdcStates::SEND_SETUP) { if (adcState == AdcState::SEND_SETUP) {
if (adcCmdExecuted) { if (adcCmdExecuted) {
adcState = AdcStates::NORMAL; adcState = AdcState::NORMAL;
doFinish = true; doFinish = true;
adcCountdown.setTimeout(100); adcCountdown.setTimeout(100);
adcCountdown.resetTimer(); adcCountdown.resetTimer();
@ -175,11 +180,11 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
switch (adcState) { switch (adcState) {
case (AdcStates::SEND_SETUP): { case (AdcState::SEND_SETUP): {
*id = plpcdu::SETUP_CMD; *id = plpcdu::SETUP_CMD;
return buildCommandFromCommand(*id, nullptr, 0); return buildCommandFromCommand(*id, nullptr, 0);
} }
case (AdcStates::NORMAL): { case (AdcState::NORMAL): {
*id = plpcdu::READ_WITH_TEMP_EXT; *id = plpcdu::READ_WITH_TEMP_EXT;
return buildCommandFromCommand(*id, nullptr, 0); return buildCommandFromCommand(*id, nullptr, 0);
} }
@ -191,7 +196,7 @@ ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id
} }
ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
if (adcState == AdcStates::SEND_SETUP) { if (adcState == AdcState::SEND_SETUP) {
*id = plpcdu::SETUP_CMD; *id = plpcdu::SETUP_CMD;
return buildCommandFromCommand(*id, nullptr, 0); return buildCommandFromCommand(*id, nullptr, 0);
} }
@ -212,9 +217,9 @@ void PayloadPcduHandler::updateSwitchGpio(gpioId_t id, gpio::Levels level) {
} }
void PayloadPcduHandler::fillCommandAndReplyMap() { void PayloadPcduHandler::fillCommandAndReplyMap() {
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet); insertInCommandAndReplyMap(plpcdu::READ_CMD, 2);
insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1, &adcSet); insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1);
insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP_EXT, 1, &adcSet); insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP_EXT, 1);
insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1); insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1);
} }
@ -278,27 +283,31 @@ ReturnValue_t PayloadPcduHandler::interpretDeviceReply(DeviceCommandId_t id,
break; break;
} }
case (READ_CMD): { case (READ_CMD): {
PoolReadGuard pg(&adcSet); {
if (pg.getReadResult() != returnvalue::OK) { PoolReadGuard pg(&adcSet);
return pg.getReadResult(); if (pg.getReadResult() != returnvalue::OK) {
return pg.getReadResult();
}
handleExtConvRead(packet);
checkAdcValues();
adcSet.setValidity(true, true);
} }
handleExtConvRead(packet);
checkAdcValues();
adcSet.setValidity(true, true);
handlePrintout(); handlePrintout();
break; break;
} }
case (READ_WITH_TEMP_EXT): { case (READ_WITH_TEMP_EXT): {
PoolReadGuard pg(&adcSet); {
if (pg.getReadResult() != returnvalue::OK) { PoolReadGuard pg(&adcSet);
return pg.getReadResult(); if (pg.getReadResult() != returnvalue::OK) {
return pg.getReadResult();
}
handleExtConvRead(packet);
uint8_t tempStartIdx = ADC_REPLY_SIZE + TEMP_REPLY_SIZE - 2;
adcSet.tempC.value =
max1227::getTemperature(packet[tempStartIdx] << 8 | packet[tempStartIdx + 1]);
checkAdcValues();
adcSet.setValidity(true, true);
} }
handleExtConvRead(packet);
uint8_t tempStartIdx = ADC_REPLY_SIZE + TEMP_REPLY_SIZE - 2;
adcSet.tempC.value =
max1227::getTemperature(packet[tempStartIdx] << 8 | packet[tempStartIdx + 1]);
checkAdcValues();
adcSet.setValidity(true, true);
handlePrintout(); handlePrintout();
break; break;
} }
@ -370,9 +379,11 @@ void PayloadPcduHandler::quickTransitionBackToOff(bool startTransitionToOff, boo
States currentState = state; States currentState = state;
pullAllGpiosLow(200); pullAllGpiosLow(200);
state = States::STACK_5V_SWITCHING; state = States::STACK_5V_SWITCHING;
adcState = AdcStates::OFF; adcState = AdcState::OFF;
if (startTransitionToOff) { if (startTransitionToOff) {
sif::debug << "transition back to off" << std::endl;
startTransition(MODE_OFF, 0); startTransition(MODE_OFF, 0);
sif::debug << "blubwapfwa" << std::endl;
} }
if (notifyFdir) { if (notifyFdir) {
triggerEvent(TRANSITION_BACK_TO_OFF, static_cast<uint32_t>(currentState)); triggerEvent(TRANSITION_BACK_TO_OFF, static_cast<uint32_t>(currentState));
@ -400,108 +411,94 @@ void PayloadPcduHandler::checkAdcValues() {
float lowerBound = 0.0; float lowerBound = 0.0;
float upperBound = 0.0; float upperBound = 0.0;
bool adcTransition = false; bool adcTransition = false;
adcTransition = state == States::ON_TRANS_DRO and adcCountdown.isBusy(); adcTransition = adcState == AdcState::NORMAL and adcCountdown.isBusy();
// Now check against voltage and current limits, depending on state if (NO_ADC_CHECKS) {
if (state >= States::ON_TRANS_DRO and not adcTransition) { return;
if (ssrToDroInjectionRequested) { }
handleFailureInjection("SSR to DRO", NEG_V_OUT_OF_BOUNDS); // Now check against voltage and current limits.
ssrToDroInjectionRequested = false; if (ssrToDroInjectionRequested) {
return; handleFailureInjection("SSR to DRO", NEG_V_OUT_OF_BOUNDS);
} ssrToDroInjectionRequested = false;
params.getValue(PARAM_KEY_MAP[NEG_V_LOWER_BOUND], lowerBound); return;
params.getValue(PARAM_KEY_MAP[NEG_V_UPPER_BOUND], upperBound); }
if (not checkVoltage(adcSet.processed[U_NEG_V_FB], lowerBound, upperBound, if (droToX8InjectionRequested) {
NEG_V_OUT_OF_BOUNDS)) { handleFailureInjection("X8 to TX", U_X8_OUT_OF_BOUNDS);
return; droToX8InjectionRequested = false;
} return;
params.getValue(PARAM_KEY_MAP[DRO_U_LOWER_BOUND], lowerBound); }
params.getValue(PARAM_KEY_MAP[DRO_U_UPPER_BOUND], upperBound); if (txToMpaInjectionRequested) {
if (not checkVoltage(adcSet.processed[U_DRO_DIV_6], lowerBound, upperBound, handleFailureInjection("TX to MPA", U_TX_OUT_OF_BOUNDS);
U_DRO_OUT_OF_BOUNDS)) { txToMpaInjectionRequested = false;
return; return;
} }
params.getValue(PARAM_KEY_MAP[DRO_I_UPPER_BOUND], upperBound); if (mpaToHpaInjectionRequested) {
if (not checkCurrent(adcSet.processed[I_DRO], upperBound, I_DRO_OUT_OF_BOUNDS)) { handleFailureInjection("MPA to HPA", U_HPA_OUT_OF_BOUNDS);
mpaToHpaInjectionRequested = false;
return;
}
if (allOnInjectRequested) {
handleFailureInjection("All On", U_HPA_OUT_OF_BOUNDS);
allOnInjectRequested = false;
return;
}
params.getValue(PARAM_KEY_MAP[NEG_V_LOWER_BOUND], lowerBound);
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)) {
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)) {
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 #if OBSW_VERBOSE_LEVEL >= 1
sif::warning << "Detected out of bounds current for DRO: " << adcSet.processed[I_DRO] sif::warning << "Detected out of bounds current for DRO: " << adcSet.processed[I_DRO]
<< ", Raw: " << adcSet.channels[I_DRO] << std::endl; << ", Raw: " << adcSet.channels[I_DRO] << std::endl;
#endif #endif
return; return;
}
} }
adcTransition = state == States::ON_TRANS_X8 and adcCountdown.isBusy(); params.getValue(PARAM_KEY_MAP[X8_U_LOWER_BOUND], lowerBound);
if (state >= States::ON_TRANS_X8 and not adcTransition) { params.getValue(PARAM_KEY_MAP[X8_U_UPPER_BOUND], upperBound);
if (droToX8InjectionRequested) { if (not checkVoltage(adcSet.processed[U_X8_DIV_6], lowerBound, upperBound, U_X8_OUT_OF_BOUNDS)) {
handleFailureInjection("X8 to TX", U_X8_OUT_OF_BOUNDS); return;
droToX8InjectionRequested = false;
return;
}
params.getValue(PARAM_KEY_MAP[X8_U_LOWER_BOUND], lowerBound);
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)) {
return;
}
params.getValue(PARAM_KEY_MAP[X8_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_X8], upperBound, I_X8_OUT_OF_BOUNDS)) {
return;
}
} }
adcTransition = state == States::ON_TRANS_TX and adcCountdown.isBusy(); params.getValue(PARAM_KEY_MAP[X8_I_UPPER_BOUND], upperBound);
if (state >= States::ON_TRANS_TX and not adcTransition) { if (not checkCurrent(adcSet.processed[I_X8], upperBound, I_X8_OUT_OF_BOUNDS)) {
if (txToMpaInjectionRequested) { return;
handleFailureInjection("TX to MPA", U_TX_OUT_OF_BOUNDS);
txToMpaInjectionRequested = false;
return;
}
params.getValue(PARAM_KEY_MAP[TX_U_LOWER_BOUND], lowerBound);
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)) {
return;
}
params.getValue(PARAM_KEY_MAP[TX_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_TX], upperBound, I_TX_OUT_OF_BOUNDS)) {
return;
}
} }
adcTransition = state == States::ON_TRANS_MPA and adcCountdown.isBusy(); params.getValue(PARAM_KEY_MAP[TX_U_LOWER_BOUND], lowerBound);
if (state >= States::ON_TRANS_MPA and not adcTransition) { params.getValue(PARAM_KEY_MAP[TX_U_UPPER_BOUND], upperBound);
if (mpaToHpaInjectionRequested) { if (not checkVoltage(adcSet.processed[U_TX_DIV_6], lowerBound, upperBound, U_TX_OUT_OF_BOUNDS)) {
handleFailureInjection("MPA to HPA", U_HPA_OUT_OF_BOUNDS); return;
mpaToHpaInjectionRequested = false;
return;
}
params.getValue(PARAM_KEY_MAP[MPA_U_LOWER_BOUND], lowerBound);
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)) {
return;
}
params.getValue(PARAM_KEY_MAP[MPA_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_MPA], upperBound, I_MPA_OUT_OF_BOUNDS)) {
return;
}
} }
adcTransition = state == States::ON_TRANS_HPA and adcCountdown.isBusy(); params.getValue(PARAM_KEY_MAP[TX_I_UPPER_BOUND], upperBound);
if (state >= States::ON_TRANS_HPA and not adcTransition) { if (not checkCurrent(adcSet.processed[I_TX], upperBound, I_TX_OUT_OF_BOUNDS)) {
if (allOnInjectRequested) { return;
handleFailureInjection("All On", U_HPA_OUT_OF_BOUNDS); }
allOnInjectRequested = false; params.getValue(PARAM_KEY_MAP[MPA_U_LOWER_BOUND], lowerBound);
return; params.getValue(PARAM_KEY_MAP[MPA_U_UPPER_BOUND], upperBound);
} if (not checkVoltage(adcSet.processed[U_MPA_DIV_6], lowerBound, upperBound,
params.getValue(PARAM_KEY_MAP[HPA_U_LOWER_BOUND], lowerBound); U_MPA_OUT_OF_BOUNDS)) {
params.getValue(PARAM_KEY_MAP[HPA_U_UPPER_BOUND], upperBound); return;
if (not checkVoltage(adcSet.processed[U_HPA_DIV_6], lowerBound, upperBound, }
U_HPA_OUT_OF_BOUNDS)) { params.getValue(PARAM_KEY_MAP[MPA_I_UPPER_BOUND], upperBound);
return; if (not checkCurrent(adcSet.processed[I_MPA], upperBound, I_MPA_OUT_OF_BOUNDS)) {
} return;
params.getValue(PARAM_KEY_MAP[HPA_I_UPPER_BOUND], upperBound); }
if (not checkCurrent(adcSet.processed[I_HPA], upperBound, I_HPA_OUT_OF_BOUNDS)) { params.getValue(PARAM_KEY_MAP[HPA_U_LOWER_BOUND], lowerBound);
sif::warning << "PayloadPcduHandler::checkCurrent: I HPA exceeded limit: Measured " params.getValue(PARAM_KEY_MAP[HPA_U_UPPER_BOUND], upperBound);
<< adcSet.processed[I_HPA] << " mA" << std::endl; if (not checkVoltage(adcSet.processed[U_HPA_DIV_6], lowerBound, upperBound,
return; U_HPA_OUT_OF_BOUNDS)) {
} return;
}
params.getValue(PARAM_KEY_MAP[HPA_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_HPA], upperBound, I_HPA_OUT_OF_BOUNDS)) {
sif::warning << "PayloadPcduHandler::checkCurrent: I HPA exceeded limit: Measured "
<< adcSet.processed[I_HPA] << " mA" << std::endl;
return;
} }
transitionOk = true; transitionOk = true;
} }
@ -521,6 +518,8 @@ void PayloadPcduHandler::checkJsonFileInit() {
bool PayloadPcduHandler::checkVoltage(float val, float lowerBound, float upperBound, Event event) { bool PayloadPcduHandler::checkVoltage(float val, float lowerBound, float upperBound, Event event) {
bool tooLarge = false; bool tooLarge = false;
sif::debug << "CHecking voltage. Value: " << val << ", lower bound: " << lowerBound
<< ", upper bound: " << upperBound << std::endl;
if (val < lowerBound or val > upperBound) { if (val < lowerBound or val > upperBound) {
if (val > upperBound) { if (val > upperBound) {
tooLarge = true; tooLarge = true;
@ -698,6 +697,8 @@ ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
return params.writeJsonFile(); return params.writeJsonFile();
} }
LocalPoolDataSetBase* PayloadPcduHandler::getDataSetHandle(sid_t sid) { return &adcSet; }
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
ReturnValue_t PayloadPcduHandler::extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie, ReturnValue_t PayloadPcduHandler::extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie,
const uint8_t* sendData, size_t sendLen, const uint8_t* sendData, size_t sendLen,

View File

@ -76,6 +76,8 @@ class PayloadPcduHandler : public DeviceHandlerBase {
#endif #endif
private: private:
static constexpr bool NO_ADC_CHECKS = false;
enum class States : uint8_t { enum class States : uint8_t {
PL_PCDU_OFF, PL_PCDU_OFF,
STACK_5V_SWITCHING, STACK_5V_SWITCHING,
@ -84,20 +86,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
// Solid State Relay, enable battery voltages VBAT0 and VBAT1. This will also switch on // Solid State Relay, enable battery voltages VBAT0 and VBAT1. This will also switch on
// the ADC // the ADC
ON_TRANS_SSR, ON_TRANS_SSR,
ON_TRANS_ADC_CLOSE_ZERO, ON_TRANS_ADC_CLOSE_ZERO
// Enable Dielectric Resonant Oscillator and start monitoring voltages as
// soon as DRO voltage reaches 6V
ON_TRANS_DRO,
// Switch on X8 compoennt and monitor voltages for 5 seconds
ON_TRANS_X8,
// Switch on TX component and monitor voltages for 5 seconds
ON_TRANS_TX,
// Switch on MPA component and monitor voltages for 5 seconds
ON_TRANS_MPA,
// Switch on HPA component and monitor voltages for 5 seconds
ON_TRANS_HPA,
// All components of the experiment are on
PL_PCDU_ON,
} state = States::PL_PCDU_OFF; } state = States::PL_PCDU_OFF;
duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE; duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE;
@ -106,7 +95,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE; enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE;
enum class AdcStates { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcStates::OFF; enum class AdcState { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcState::OFF;
bool goToNormalMode = false; bool goToNormalMode = false;
plpcdu::PlPcduAdcSet adcSet; plpcdu::PlPcduAdcSet adcSet;
@ -180,6 +169,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
ReturnValue_t serializeFloat(uint32_t& param, float val); ReturnValue_t serializeFloat(uint32_t& param, float val);
ReturnValue_t handleDoubleParamUpdate(std::string key, ParameterWrapper* parameterWrapper, ReturnValue_t handleDoubleParamUpdate(std::string key, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues); const ParameterWrapper* newValues);
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
}; };
#endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */ #endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */