Merge pull request 'PL PCDU Refactoring v1' (#189) from mueller/plpcdu-refactoring into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

Reviewed-on: #189
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
This commit is contained in:
Jakob Meier 2022-03-31 15:31:46 +02:00
commit ee497ecf2a
12 changed files with 214 additions and 204 deletions

View File

@ -149,7 +149,7 @@ void ObjectFactory::produce(void* args) {
createHeaterComponents(); createHeaterComponents();
createSolarArrayDeploymentComponents(); createSolarArrayDeploymentComponents();
createPlPcduComponents(gpioComIF, spiComIF); createPlPcduComponents(gpioComIF, spiComIF, pwrSwitcher);
#if OBSW_ADD_SYRLINKS == 1 #if OBSW_ADD_SYRLINKS == 1
createSyrlinksComponents(); createSyrlinksComponents();
#endif /* OBSW_ADD_SYRLINKS == 1 */ #endif /* OBSW_ADD_SYRLINKS == 1 */
@ -1151,7 +1151,8 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
gpioComIF->addGpios(gpioRS485Chip); gpioComIF->addGpios(gpioRS485Chip);
} }
void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF) { void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF,
PowerSwitchIF* pwrSwitcher) {
using namespace gpio; using namespace gpio;
// Create all GPIO components first // Create all GPIO components first
GpioCookie* plPcduGpios = new GpioCookie; GpioCookie* plPcduGpios = new GpioCookie;
@ -1197,9 +1198,10 @@ void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF*
q7s::SPI_DEFAULT_DEV, plpcdu::MAX_ADC_REPLY_SIZE, q7s::SPI_DEFAULT_DEV, plpcdu::MAX_ADC_REPLY_SIZE,
spi::DEFAULT_MAX_1227_MODE, spi::PL_PCDU_MAX_1227_SPEED); spi::DEFAULT_MAX_1227_MODE, spi::PL_PCDU_MAX_1227_SPEED);
// Create device handler components // Create device handler components
auto plPcduHandler = auto plPcduHandler = new PayloadPcduHandler(
new PayloadPcduHandler(objects::PLPCDU_HANDLER, objects::SPI_COM_IF, spiCookie, gpioComIF, objects::PLPCDU_HANDLER, objects::SPI_COM_IF, spiCookie, gpioComIF, SdCardManager::instance(),
SdCardManager::instance(), false); pwrSwitcher, pcduSwitches::Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8,
pcduSwitches::Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8, false);
spiCookie->setCallbackMode(PayloadPcduHandler::extConvAsTwoCallback, plPcduHandler); spiCookie->setCallbackMode(PayloadPcduHandler::extConvAsTwoCallback, plPcduHandler);
// plPcduHandler->enablePeriodicPrintout(true, 5); // plPcduHandler->enablePeriodicPrintout(true, 5);
// static_cast<void>(plPcduHandler); // static_cast<void>(plPcduHandler);

View File

@ -15,7 +15,8 @@ void produce(void* args);
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF,
SpiComIF** spiComIF, I2cComIF** i2cComIF); SpiComIF** spiComIF, I2cComIF** i2cComIF);
void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher); void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher);
void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF,
PowerSwitchIF* pwrSwitcher);
void createTmpComponents(); void createTmpComponents();
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF, void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF,

View File

@ -3,12 +3,15 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include <fsfw/power/definitions.h>
#include <array> #include <array>
#include <cstdint> #include <cstdint>
namespace pcduSwitches { namespace pcduSwitches {
/* Switches are uint8_t datatype and go from 0 to 255 */ /* Switches are uint8_t datatype and go from 0 to 255 */
enum Switches: uint8_t { enum Switches: power::Switch_t {
PDU1_CH0_TCS_BOARD_3V3, PDU1_CH0_TCS_BOARD_3V3,
PDU1_CH1_SYRLINKS_12V, PDU1_CH1_SYRLINKS_12V,
PDU1_CH2_STAR_TRACKER_5V, PDU1_CH2_STAR_TRACKER_5V,

View File

@ -50,7 +50,7 @@ debugging. */
#define OBSW_ADD_RTD_DEVICES 1 #define OBSW_ADD_RTD_DEVICES 1
#define OBSW_ADD_TMP_DEVICES 0 #define OBSW_ADD_TMP_DEVICES 0
#define OBSW_ADD_RAD_SENSORS 1 #define OBSW_ADD_RAD_SENSORS 1
#define OBSW_ADD_PL_PCDU 0 #define OBSW_ADD_PL_PCDU 1
#define OBSW_ADD_SYRLINKS 0 #define OBSW_ADD_SYRLINKS 0
#define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 #define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0
#define OBSW_STAR_TRACKER_GROUND_CONFIG 1 #define OBSW_STAR_TRACKER_GROUND_CONFIG 1
@ -88,10 +88,10 @@ debugging. */
#define OBSW_ADD_PL_PCDU 0 #define OBSW_ADD_PL_PCDU 0
#define OBSW_ADD_SYRLINKS 0 #define OBSW_ADD_SYRLINKS 0
#define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 #define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0
#define OBSW_SYRLINKS_SIMULATED 1 #define OBSW_SYRLINKS_SIMULATED 1
#define OBSW_STAR_TRACKER_GROUND_CONFIG 1 #define OBSW_STAR_TRACKER_GROUND_CONFIG 1
#define OBSW_ENABLE_PERIODIC_HK 0 #define OBSW_ENABLE_PERIODIC_HK 0
#define OBSW_PRINT_CORE_HK 0 #define OBSW_PRINT_CORE_HK 0
#define OBSW_INITIALIZE_SWITCHES 0 #define OBSW_INITIALIZE_SWITCHES 0
#endif #endif

View File

@ -14,197 +14,164 @@
PayloadPcduHandler::PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie, PayloadPcduHandler::PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie,
GpioIF* gpioIF, SdCardMountedIF* sdcMan, GpioIF* gpioIF, SdCardMountedIF* sdcMan,
bool periodicPrintout) PowerSwitchIF* pwrSwitcher, power::Switch_t switchA,
power::Switch_t switchB, bool periodicPrintout)
: DeviceHandlerBase(objectId, comIF, cookie), : DeviceHandlerBase(objectId, comIF, cookie),
adcSet(this), adcSet(this),
periodicPrintout(periodicPrintout), periodicPrintout(periodicPrintout),
gpioIF(gpioIF), gpioIF(gpioIF),
sdcMan(sdcMan) {} sdcMan(sdcMan),
pwrStateMachine(switchA, switchB, pwrSwitcher) {}
void PayloadPcduHandler::doStartUp() { void PayloadPcduHandler::doStartUp() {
if ((state != States::PCDU_OFF) and (state != States::ON_TRANS_SSR)) { if ((state != States::PL_PCDU_OFF) and (state != States::ON_TRANS_SSR)) {
// Config error // Config error
sif::error << "PayloadPcduHandler::doStartUp: Invalid state" << std::endl; sif::error << "PayloadPcduHandler::doStartUp: Invalid state" << std::endl;
} }
if (state == States::PCDU_OFF) { if (pwrStateMachine.getState() == power::States::IDLE) {
// Switch on relays here pwrStateMachine.start(MODE_ON, pwrSubmode);
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_VBAT0);
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_VBAT1);
state = States::ON_TRANS_SSR;
transitionOk = true;
} }
if (state == States::ON_TRANS_SSR) { auto opCode = pwrStateMachine.fsm();
// If necessary, check whether a certain amount of time has elapsed if (opCode == power::OpCodes::TO_NOT_OFF_DONE or opCode == power::OpCodes::TIMEOUT_OCCURED) {
if (transitionOk) { pwrStateMachine.reset();
transitionOk = false; quickTransitionAlreadyCalled = false;
state = States::ON_TRANS_ADC_CLOSE_ZERO; state = States::POWER_CHANNELS_ON;
// We are now in ON mode setMode(_MODE_TO_ON);
startTransition(MODE_NORMAL, 0);
adcCountdown.setTimeout(50);
adcCountdown.resetTimer();
adcState = AdcStates::BOOT_DELAY;
// The ADC can now be read. If the values are not close to zero, we should not allow
// transition
monMode = MonitoringMode::CLOSE_TO_ZERO;
}
} }
} }
void PayloadPcduHandler::stateMachineToNormal() { void PayloadPcduHandler::doShutDown() {
using namespace plpcdu; if (not quickTransitionAlreadyCalled) {
if (adcState == AdcStates::BOOT_DELAY) { quickTransitionBackToOff(false, false);
if (adcCountdown.hasTimedOut()) { quickTransitionAlreadyCalled = true;
adcState = AdcStates::SEND_SETUP;
adcCmdExecuted = false;
}
} }
if (adcState == AdcStates::SEND_SETUP) { if (pwrStateMachine.getState() == power::States::IDLE) {
if (adcCmdExecuted) { pwrStateMachine.start(MODE_OFF, 0);
adcState = AdcStates::NORMAL;
setMode(MODE_NORMAL, NORMAL_ADC_ONLY);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
adcCmdExecuted = false;
}
} }
if (submode == plpcdu::NORMAL_ALL_ON) { auto opCode = pwrStateMachine.fsm();
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) { if (opCode == power::OpCodes::TO_OFF_DONE or opCode == power::OpCodes::TIMEOUT_OCCURED) {
if (not commandExecuted) { pwrStateMachine.reset();
float waitTime = DFT_SSR_TO_DRO_WAIT_TIME; // No need to set mode _MODE_POWER_DOWN, power switching was already handled
params.getValue(PARAM_KEY_MAP[SSR_TO_DRO_WAIT_TIME], waitTime); setMode(MODE_OFF);
countdown.setTimeout(std::round(waitTime * 1000));
countdown.resetTimer();
commandExecuted = true;
// TODO: For now, skip ADC check
transitionOk = true;
}
// ADC values are ok, 5 seconds have elapsed
if (transitionOk and countdown.hasTimedOut()) {
state = States::ON_TRANS_DRO;
// Now start monitoring for negative voltages instead
monMode = MonitoringMode::NEGATIVE;
commandExecuted = false;
transitionOk = false;
}
}
if (state == States::ON_TRANS_DRO) {
if (not commandExecuted) {
float waitTime = DFT_DRO_TO_X8_WAIT_TIME;
params.getValue(PARAM_KEY_MAP[DRO_TO_X8_WAIT_TIME], waitTime);
countdown.setTimeout(std::round(waitTime * 1000));
countdown.resetTimer();
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU DRO module" << std::endl;
#endif
// Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_DRO);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
commandExecuted = true;
}
// ADC values are ok, 5 seconds have elapsed
if (transitionOk and countdown.hasTimedOut()) {
state = States::ON_TRANS_X8;
commandExecuted = false;
transitionOk = false;
}
}
if (state == States::ON_TRANS_X8) {
if (not commandExecuted) {
float waitTime = DFT_X8_TO_TX_WAIT_TIME;
params.getValue(PARAM_KEY_MAP[X8_TO_TX_WAIT_TIME], waitTime);
countdown.setTimeout(std::round(waitTime * 1000));
countdown.resetTimer();
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU X8 module" << std::endl;
#endif
// Switch on X8
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_X8);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
commandExecuted = true;
}
// ADC values are ok, 5 seconds have elapsed
if (transitionOk and countdown.hasTimedOut()) {
state = States::ON_TRANS_TX;
commandExecuted = false;
transitionOk = false;
}
}
if (state == States::ON_TRANS_TX) {
if (not commandExecuted) {
float waitTime = DFT_TX_TO_MPA_WAIT_TIME;
params.getValue(PARAM_KEY_MAP[TX_TO_MPA_WAIT_TIME], waitTime);
countdown.setTimeout(std::round(waitTime * 1000));
countdown.resetTimer();
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU TX module" << std::endl;
#endif
// Switch on TX
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_TX);
// Wait for 100 ms before checking ADC values
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
commandExecuted = true;
}
// ADC values are ok, 5 seconds have elapsed
if (transitionOk and countdown.hasTimedOut()) {
state = States::ON_TRANS_MPA;
commandExecuted = false;
transitionOk = false;
}
}
if (state == States::ON_TRANS_MPA) {
if (not commandExecuted) {
float waitTime = DFT_MPA_TO_HPA_WAIT_TIME;
params.getValue(PARAM_KEY_MAP[MPA_TO_HPA_WAIT_TIME], waitTime);
countdown.setTimeout(std::round(waitTime * 1000));
countdown.resetTimer();
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU MPA module" << std::endl;
#endif
// Switch on MPA
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_MPA);
// Wait for 100 ms before checking ADC values
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
commandExecuted = true;
}
// ADC values are ok, 5 seconds have elapsed
if (transitionOk and countdown.hasTimedOut()) {
state = States::ON_TRANS_HPA;
commandExecuted = false;
transitionOk = false;
}
}
if (state == States::ON_TRANS_HPA) {
if (not commandExecuted) {
// Switch on HPA
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_HPA);
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU HPA module" << std::endl;
#endif
commandExecuted = true;
}
// ADC values are ok, 5 seconds have elapsed
if (transitionOk and countdown.hasTimedOut()) {
state = States::PCDU_ON;
setMode(MODE_NORMAL, plpcdu::NORMAL_ALL_ON);
countdown.resetTimer();
commandExecuted = false;
transitionOk = false;
}
}
} }
} }
void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
if (mode == _MODE_TO_NORMAL) { if (mode == _MODE_TO_NORMAL) {
stateMachineToNormal(); stateMachineToNormal(modeFrom, subModeFrom);
return;
} }
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
} }
void PayloadPcduHandler::doShutDown() { transitionBackToOff(false); } ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) {
using namespace plpcdu;
if (submode == NormalSubmodes::SOLID_STATE_RELAYS_ADC_ON) {
if (state == States::PL_PCDU_OFF) {
sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF"
<< "detected" << std::endl;
setMode(MODE_OFF);
return HasReturnvaluesIF::RETURN_FAILED;
}
if (state == States::POWER_CHANNELS_ON) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Switching on SSR VBAT0 & VBAT1 GPIOs" << std::endl;
#endif
// Switch on relays here
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_VBAT0);
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_VBAT1);
state = States::ON_TRANS_SSR;
transitionOk = true;
}
if (state == States::ON_TRANS_SSR) {
// If necessary, check whether a certain amount of time has elapsed
if (transitionOk) {
transitionOk = false;
state = States::ON_TRANS_ADC_CLOSE_ZERO;
adcCountdown.setTimeout(50);
adcCountdown.resetTimer();
adcState = AdcStates::BOOT_DELAY;
// If the values are not close to zero, we should not allow transition
monMode = MonitoringMode::CLOSE_TO_ZERO;
}
}
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) {
if (adcState == AdcStates::BOOT_DELAY) {
if (adcCountdown.hasTimedOut()) {
adcState = AdcStates::SEND_SETUP;
adcCmdExecuted = false;
}
}
if (adcState == AdcStates::SEND_SETUP) {
if (adcCmdExecuted) {
adcState = AdcStates::NORMAL;
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
adcCmdExecuted = false;
setMode(MODE_NORMAL, submode);
return HasReturnvaluesIF::RETURN_OK;
}
}
}
}
if (submode == NormalSubmodes::DRO_ON) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU DRO module" << std::endl;
#endif
// Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_DRO);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
setMode(MODE_NORMAL, submode);
}
if (submode == NormalSubmodes::X8_ON) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU X8 module" << std::endl;
#endif
// Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_X8);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
setMode(MODE_NORMAL, submode);
}
if (submode == NormalSubmodes::TX_ON) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU TX module" << std::endl;
#endif
// Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_TX);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
setMode(MODE_NORMAL, submode);
}
if (submode == NormalSubmodes::MPA_ON) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU MPA module" << std::endl;
#endif
// Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_MPA);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
setMode(MODE_NORMAL, submode);
}
if (submode == NormalSubmodes::HPA_ON) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU HPA module" << std::endl;
#endif
// Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_HPA);
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
setMode(MODE_NORMAL, submode);
}
return RETURN_OK;
}
ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
switch (adcState) { switch (adcState) {
@ -388,7 +355,7 @@ void PayloadPcduHandler::enablePeriodicPrintout(bool enable, uint8_t divider) {
opDivider.setDivider(divider); opDivider.setDivider(divider);
} }
void PayloadPcduHandler::transitionBackToOff(bool notifyFdir) { void PayloadPcduHandler::quickTransitionBackToOff(bool startTransitionToOff, bool notifyFdir) {
States currentState = state; States currentState = state;
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA); gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA); gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
@ -398,9 +365,11 @@ void PayloadPcduHandler::transitionBackToOff(bool notifyFdir) {
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX); gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0); gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1); gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
state = States::PCDU_OFF; state = States::PL_PCDU_OFF;
adcState = AdcStates::OFF; adcState = AdcStates::OFF;
setMode(MODE_OFF); if (startTransitionToOff) {
startTransition(MODE_OFF, 0);
}
if (notifyFdir) { if (notifyFdir) {
triggerEvent(TRANSITION_BACK_TO_OFF, static_cast<uint32_t>(currentState)); triggerEvent(TRANSITION_BACK_TO_OFF, static_cast<uint32_t>(currentState));
} }
@ -556,7 +525,8 @@ bool PayloadPcduHandler::checkVoltage(float val, float lowerBound, float upperBo
serializeFloat(p2, val); serializeFloat(p2, val);
triggerEvent(event, tooLarge, p2); triggerEvent(event, tooLarge, p2);
transitionOk = false; transitionOk = false;
transitionBackToOff(true); quickTransitionBackToOff(true, true);
quickTransitionAlreadyCalled = true;
return false; return false;
} }
return true; return true;
@ -568,14 +538,37 @@ bool PayloadPcduHandler::checkCurrent(float val, float upperBound, Event event)
serializeFloat(p2, val); serializeFloat(p2, val);
triggerEvent(event, true, p2); triggerEvent(event, true, p2);
transitionOk = false; transitionOk = false;
transitionBackToOff(true); quickTransitionBackToOff(true, true);
quickTransitionAlreadyCalled = true;
return false; return false;
} }
return true; return true;
} }
ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
if (mode == MODE_NORMAL and submode <= 1) { using namespace plpcdu;
if (mode == MODE_NORMAL) {
// Also deals with the case where the mode is MODE_ON, submode should be 0 here
if (submode == NormalSubmodes::SOLID_STATE_RELAYS_ADC_ON and
(this->mode == MODE_NORMAL and this->submode != NormalSubmodes::ALL_OFF)) {
return TRANS_NOT_ALLOWED;
}
if ((submode == NormalSubmodes::DRO_ON and
this->submode != NormalSubmodes::SOLID_STATE_RELAYS_ADC_ON)) {
return TRANS_NOT_ALLOWED;
}
if ((submode == NormalSubmodes::X8_ON and this->submode != NormalSubmodes::DRO_ON)) {
return TRANS_NOT_ALLOWED;
}
if ((submode == NormalSubmodes::TX_ON and this->submode != NormalSubmodes::X8_ON)) {
return TRANS_NOT_ALLOWED;
}
if ((submode == NormalSubmodes::MPA_ON and this->submode != NormalSubmodes::TX_ON)) {
return TRANS_NOT_ALLOWED;
}
if ((submode == NormalSubmodes::HPA_ON and this->submode != NormalSubmodes::MPA_ON)) {
return TRANS_NOT_ALLOWED;
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
return DeviceHandlerBase::isModeCombinationValid(mode, submode); return DeviceHandlerBase::isModeCombinationValid(mode, submode);
@ -658,7 +651,8 @@ void PayloadPcduHandler::handleFailureInjection(std::string output, Event event)
<< std::endl; << std::endl;
triggerEvent(event, 0, 0); triggerEvent(event, 0, 0);
transitionOk = false; transitionOk = false;
transitionBackToOff(true); quickTransitionBackToOff(true, true);
quickTransitionAlreadyCalled = true;
droToX8InjectionRequested = false; droToX8InjectionRequested = false;
} }

View File

@ -10,6 +10,8 @@
#include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/GpioIF.h"
#include "mission/devices/devicedefinitions/payloadPcduDefinitions.h" #include "mission/devices/devicedefinitions/payloadPcduDefinitions.h"
#include "mission/memory/SdCardMountedIF.h" #include "mission/memory/SdCardMountedIF.h"
#include "mission/system/DualLanePowerStateMachine.h"
#include "mission/system/definitions.h"
#ifdef FSFW_OSAL_LINUX #ifdef FSFW_OSAL_LINUX
class SpiComIF; class SpiComIF;
@ -60,7 +62,8 @@ class PayloadPcduHandler : public DeviceHandlerBase {
static constexpr Event I_HPA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM); static constexpr Event I_HPA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM);
PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie, GpioIF* gpioIF, PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie, GpioIF* gpioIF,
SdCardMountedIF* sdcMan, bool periodicPrintout); SdCardMountedIF* sdcMan, PowerSwitchIF* pwrSwitcher, power::Switch_t switchCh0,
power::Switch_t switchCh1, bool periodicPrintout);
void setToGoToNormalModeImmediately(bool enable); void setToGoToNormalModeImmediately(bool enable);
void enablePeriodicPrintout(bool enable, uint8_t divider); void enablePeriodicPrintout(bool enable, uint8_t divider);
@ -75,7 +78,8 @@ class PayloadPcduHandler : public DeviceHandlerBase {
private: private:
enum class States : uint8_t { enum class States : uint8_t {
PCDU_OFF, PL_PCDU_OFF,
POWER_CHANNELS_ON,
// 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,
@ -92,8 +96,10 @@ class PayloadPcduHandler : public DeviceHandlerBase {
// Switch on HPA component and monitor voltages for 5 seconds // Switch on HPA component and monitor voltages for 5 seconds
ON_TRANS_HPA, ON_TRANS_HPA,
// All components of the experiment are on // All components of the experiment are on
PCDU_ON, PL_PCDU_ON,
} state = States::PCDU_OFF; } state = States::PL_PCDU_OFF;
duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE;
enum class AdcMode { EXT_CONV, INT_CONV } adcMode = AdcMode::INT_CONV; enum class AdcMode { EXT_CONV, INT_CONV } adcMode = AdcMode::INT_CONV;
@ -127,17 +133,19 @@ class PayloadPcduHandler : public DeviceHandlerBase {
GpioIF* gpioIF; GpioIF* gpioIF;
SdCardMountedIF* sdcMan; SdCardMountedIF* sdcMan;
plpcdu::PlPcduParameter params; plpcdu::PlPcduParameter params;
bool quickTransitionAlreadyCalled = true;
PoolEntry<uint16_t> channelValues = PoolEntry<uint16_t>({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); PoolEntry<uint16_t> channelValues = PoolEntry<uint16_t>({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
PoolEntry<float> processedValues = PoolEntry<float> processedValues =
PoolEntry<float>({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<float>({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<float> tempC = PoolEntry<float>({0.0}); PoolEntry<float> tempC = PoolEntry<float>({0.0});
DualLanePowerStateMachine pwrStateMachine;
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
// Main FDIR function which goes from any PL PCDU state back to all off // Main FDIR function which goes from any PL PCDU state back to all off
void transitionBackToOff(bool notifyFdir); void quickTransitionBackToOff(bool startTransitionToOff, bool notifyFdir);
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
void fillCommandAndReplyMap() override; void fillCommandAndReplyMap() override;
@ -158,7 +166,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
void checkAdcValues(); void checkAdcValues();
void handleOutOfBoundsPrintout(); void handleOutOfBoundsPrintout();
void checkJsonFileInit(); void checkJsonFileInit();
void stateMachineToNormal(); ReturnValue_t stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom);
bool checkVoltage(float val, float lowerBound, float upperBound, Event event); bool checkVoltage(float val, float lowerBound, float upperBound, Event event);
bool checkCurrent(float val, float upperBound, Event event); bool checkCurrent(float val, float upperBound, Event event);
void handleFailureInjection(std::string output, Event event); void handleFailureInjection(std::string output, Event event);

View File

@ -91,8 +91,15 @@ static constexpr DeviceCommandId_t SETUP_CMD = 1;
static constexpr DeviceCommandId_t READ_TEMP_EXT = 2; static constexpr DeviceCommandId_t READ_TEMP_EXT = 2;
static constexpr DeviceCommandId_t READ_WITH_TEMP_EXT = 3; static constexpr DeviceCommandId_t READ_WITH_TEMP_EXT = 3;
static constexpr Submode_t NORMAL_ADC_ONLY = 0; enum NormalSubmodes {
static constexpr Submode_t NORMAL_ALL_ON = 1; ALL_OFF = 0,
SOLID_STATE_RELAYS_ADC_ON = 1,
DRO_ON = 2,
X8_ON = 3,
TX_ON = 4,
MPA_ON = 5,
HPA_ON = 6
};
// 12 ADC values * 2 + trailing zero // 12 ADC values * 2 + trailing zero
static constexpr size_t ADC_REPLY_SIZE = 25; static constexpr size_t ADC_REPLY_SIZE = 25;

View File

@ -3,8 +3,8 @@
#include <fsfw/devicehandlers/AssemblyBase.h> #include <fsfw/devicehandlers/AssemblyBase.h>
#include <fsfw/power/PowerSwitchIF.h> #include <fsfw/power/PowerSwitchIF.h>
DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches switchA, DualLanePowerStateMachine::DualLanePowerStateMachine(power::Switch_t switchA,
pcduSwitches::Switches switchB, power::Switch_t switchB,
PowerSwitchIF* pwrSwitcher, PowerSwitchIF* pwrSwitcher,
dur_millis_t checkTimeout) dur_millis_t checkTimeout)
: PowerStateMachineBase(pwrSwitcher, checkTimeout), SWITCH_A(switchA), SWITCH_B(switchB) {} : PowerStateMachineBase(pwrSwitcher, checkTimeout), SWITCH_A(switchA), SWITCH_B(switchB) {}

View File

@ -12,12 +12,12 @@ class PowerSwitchIF;
class DualLanePowerStateMachine : public PowerStateMachineBase { class DualLanePowerStateMachine : public PowerStateMachineBase {
public: public:
DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, DualLanePowerStateMachine(power::Switch_t switchA, power::Switch_t switchB,
PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout = 5000); PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout = 5000);
power::OpCodes fsm() override; power::OpCodes fsm() override;
const pcduSwitches::Switches SWITCH_A; const power::Switch_t SWITCH_A;
const pcduSwitches::Switches SWITCH_B; const power::Switch_t SWITCH_B;
private: private:
}; };

View File

@ -1 +0,0 @@
#include "PlPcduAssembly.h"

View File

@ -1,4 +0,0 @@
#ifndef MISSION_SYSTEM_PLPCDUASSEMBLY_H_
#define MISSION_SYSTEM_PLPCDUASSEMBLY_H_
#endif /* MISSION_SYSTEM_PLPCDUASSEMBLY_H_ */

2
tmtc

@ -1 +1 @@
Subproject commit e13bb402a2780142cc1b3b56c2873a4cbcf12a3b Subproject commit 5ac8912dd2b47f01f66093187f15a9f9824ffd66