Merge pull request 'PL PCDU Update Mode Handling' (#200) from mueller/pl-pcdu-update-mode-handling into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

Reviewed-on: #200
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
This commit is contained in:
Jakob Meier 2022-04-07 11:12:02 +02:00
commit b5ce035c09
6 changed files with 68 additions and 81 deletions

2
fsfw

@ -1 +1 @@
Subproject commit aded4fae1e4f8a8a325c49b8c0d4bb4d7408d676 Subproject commit a11d7455dfaf2e736f73f6c4dda1f8c06b9f1234

View File

@ -76,11 +76,9 @@ ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>()); localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>()); localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>()); localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
bool enablePeriodicHk = false;
#if OBSW_ENABLE_PERIODIC_HK == 1 #if OBSW_ENABLE_PERIODIC_HK == 1
enablePeriodicHk = true; poolManager.subscribeForPeriodicPacket(gpsSet.getSid(), true, 2.0, false);
#endif #endif
poolManager.subscribeForPeriodicPacket(gpsSet.getSid(), enablePeriodicHk, 2.0, false);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -177,14 +177,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) {
bool addSus9 = true; bool addSus9 = true;
bool addSus10 = true; bool addSus10 = true;
bool addSus11 = true; bool addSus11 = true;
/**
* The sun sensor will be shutdown as soon as the chip select is pulled high. Thus all
* requests to a sun sensor must be performed consecutively. Another reason for calling multiple
* device handler cycles is that the ADC conversions take some time. Thus first the ADC
* conversions are initiated and in a next step the results can be read from the internal FIFO.
* One sun sensor communication sequence also blocks the SPI bus. So other devices can not be
* inserted between the device handler cycles of one SUS.
*/
if (addSus0) { if (addSus0) {
/* Write setup */ /* Write setup */
thisSequence->addSlot(objects::SUS_0, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::SUS_0, length * 0, DeviceHandlerIF::PERFORM_OPERATION);

View File

@ -51,6 +51,7 @@ void PayloadPcduHandler::doShutDown() {
auto opCode = pwrStateMachine.fsm(); auto opCode = pwrStateMachine.fsm();
if (opCode == power::OpCodes::TO_OFF_DONE or opCode == power::OpCodes::TIMEOUT_OCCURED) { if (opCode == power::OpCodes::TO_OFF_DONE or opCode == power::OpCodes::TIMEOUT_OCCURED) {
pwrStateMachine.reset(); pwrStateMachine.reset();
state = States::PL_PCDU_OFF;
// 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);
} }
@ -66,7 +67,8 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) { ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) {
using namespace plpcdu; using namespace plpcdu;
if (submode == NormalSubmodes::SOLID_STATE_RELAYS_ADC_ON) { bool doFinish = true;
if (((submode >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == 1) {
if (state == States::PL_PCDU_OFF) { if (state == States::PL_PCDU_OFF) {
sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF" sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF"
<< "detected" << std::endl; << "detected" << std::endl;
@ -82,22 +84,24 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_VBAT1); gpioIF->pullHigh(gpioIds::PLPCDU_ENB_VBAT1);
state = States::ON_TRANS_SSR; state = States::ON_TRANS_SSR;
transitionOk = true; transitionOk = true;
doFinish = false;
} }
if (state == States::ON_TRANS_SSR) { if (state == States::ON_TRANS_SSR) {
// If necessary, check whether a certain amount of time has elapsed // If necessary, check whether a certain amount of time has elapsed
if (transitionOk) { if (transitionOk) {
transitionOk = false; transitionOk = false;
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 = AdcStates::BOOT_DELAY;
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 == AdcStates::BOOT_DELAY) {
doFinish = false;
if (adcCountdown.hasTimedOut()) { if (adcCountdown.hasTimedOut()) {
adcState = AdcStates::SEND_SETUP; adcState = AdcStates::SEND_SETUP;
adcCmdExecuted = false; adcCmdExecuted = false;
@ -106,68 +110,38 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
if (adcState == AdcStates::SEND_SETUP) { if (adcState == AdcStates::SEND_SETUP) {
if (adcCmdExecuted) { if (adcCmdExecuted) {
adcState = AdcStates::NORMAL; adcState = AdcStates::NORMAL;
doFinish = true;
adcCountdown.setTimeout(100); adcCountdown.setTimeout(100);
adcCountdown.resetTimer(); adcCountdown.resetTimer();
adcCmdExecuted = false; adcCmdExecuted = false;
setMode(MODE_NORMAL, submode);
return HasReturnvaluesIF::RETURN_OK;
} }
} }
} }
} }
if (submode == NormalSubmodes::DRO_ON) { auto switchHandler = [&](NormalSubmodeBits bit, gpioId_t id, std::string info) {
if (((diffMask >> bit) & 1) == 1) {
if (((submode >> bit) & 1) == 1) {
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Enabling PL PCDU DRO module" << std::endl; sif::info << "Enabling PL PCDU " << info << " module" << std::endl;
#endif #endif
// Switch on DRO and start monitoring for negative voltages // Switch on DRO and start monitoring for negative voltages
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_DRO); updateSwitchGpio(id, gpio::Levels::HIGH);
adcCountdown.setTimeout(100); } else {
adcCountdown.resetTimer(); #if OBSW_VERBOSE_LEVEL >= 1
setMode(MODE_NORMAL, submode); sif::info << "Disabling PL PCDU " << info << " module" << std::endl;
} #endif
updateSwitchGpio(id, gpio::Levels::LOW);
}
}
};
if (submode == NormalSubmodes::X8_ON) { switchHandler(DRO_ON, gpioIds::PLPCDU_ENB_DRO, "DRO");
#if OBSW_VERBOSE_LEVEL >= 1 switchHandler(X8_ON, gpioIds::PLPCDU_ENB_X8, "X8");
sif::info << "Enabling PL PCDU X8 module" << std::endl; switchHandler(TX_ON, gpioIds::PLPCDU_ENB_TX, "TX");
#endif switchHandler(MPA_ON, gpioIds::PLPCDU_ENB_MPA, "MPA");
// Switch on DRO and start monitoring for negative voltages switchHandler(HPA_ON, gpioIds::PLPCDU_ENB_HPA, "HPA");
gpioIF->pullHigh(gpioIds::PLPCDU_ENB_X8); if (doFinish) {
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); setMode(MODE_NORMAL, submode);
} }
return RETURN_OK; return RETURN_OK;
@ -201,6 +175,16 @@ ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t
return NOTHING_TO_SEND; return NOTHING_TO_SEND;
} }
void PayloadPcduHandler::updateSwitchGpio(gpioId_t id, gpio::Levels level) {
if (level == gpio::Levels::HIGH) {
gpioIF->pullHigh(id);
} else {
gpioIF->pullLow(id);
}
adcCountdown.setTimeout(100);
adcCountdown.resetTimer();
}
void PayloadPcduHandler::fillCommandAndReplyMap() { void PayloadPcduHandler::fillCommandAndReplyMap() {
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet); insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet);
insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1, &adcSet); insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1, &adcSet);
@ -548,25 +532,33 @@ bool PayloadPcduHandler::checkCurrent(float val, float upperBound, Event event)
ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
using namespace plpcdu; using namespace plpcdu;
if (mode == MODE_NORMAL) { if (mode == MODE_NORMAL) {
diffMask = submode ^ this->submode;
// Also deals with the case where the mode is MODE_ON, submode should be 0 here // 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 if ((((submode >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == SOLID_STATE_RELAYS_ADC_ON) and
(this->mode == MODE_NORMAL and this->submode != NormalSubmodes::ALL_OFF)) { (this->mode == MODE_NORMAL and this->submode != ALL_OFF_SUBMODE)) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if ((submode == NormalSubmodes::DRO_ON and if (((((submode >> DRO_ON) & 1) == 1) and
this->submode != NormalSubmodes::SOLID_STATE_RELAYS_ADC_ON)) { ((this->submode & 0b1) != (1 << SOLID_STATE_RELAYS_ADC_ON)))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if ((submode == NormalSubmodes::X8_ON and this->submode != NormalSubmodes::DRO_ON)) { if ((((submode >> X8_ON) & 1) == 1) and
((this->submode & 0b11) != ((1 << SOLID_STATE_RELAYS_ADC_ON) | (1 << DRO_ON)))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if ((submode == NormalSubmodes::TX_ON and this->submode != NormalSubmodes::X8_ON)) { if (((((submode >> TX_ON) & 1) == 1) and
((this->submode & 0b111) !=
((1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if ((submode == NormalSubmodes::MPA_ON and this->submode != NormalSubmodes::TX_ON)) { if ((((submode >> MPA_ON) & 1) == 1 and
((this->submode & 0b1111) !=
((1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if ((submode == NormalSubmodes::HPA_ON and this->submode != NormalSubmodes::MPA_ON)) { if ((((submode >> HPA_ON) & 1) == 1 and
((this->submode & 0b11111) != ((1 << MPA_ON) | (1 << TX_ON) | (1 << X8_ON) |
(1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;

View File

@ -134,6 +134,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
SdCardMountedIF* sdcMan; SdCardMountedIF* sdcMan;
plpcdu::PlPcduParameter params; plpcdu::PlPcduParameter params;
bool quickTransitionAlreadyCalled = true; bool quickTransitionAlreadyCalled = true;
uint8_t diffMask = 0;
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 =
@ -141,6 +142,8 @@ class PayloadPcduHandler : public DeviceHandlerBase {
PoolEntry<float> tempC = PoolEntry<float>({0.0}); PoolEntry<float> tempC = PoolEntry<float>({0.0});
DualLanePowerStateMachine pwrStateMachine; DualLanePowerStateMachine pwrStateMachine;
void updateSwitchGpio(gpioId_t id, gpio::Levels level);
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;

View File

@ -91,16 +91,17 @@ 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;
enum NormalSubmodes { enum NormalSubmodeBits {
ALL_OFF = 0, SOLID_STATE_RELAYS_ADC_ON = 0,
SOLID_STATE_RELAYS_ADC_ON = 1, DRO_ON = 1,
DRO_ON = 2, X8_ON = 2,
X8_ON = 3, TX_ON = 3,
TX_ON = 4, MPA_ON = 4,
MPA_ON = 5, HPA_ON = 5
HPA_ON = 6
}; };
static constexpr Submode_t ALL_OFF_SUBMODE = 0;
// 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;
// Conversion byte + 24 * zero // Conversion byte + 24 * zero