Merge branch 'develop' into move_cfdp_handler
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
This commit is contained in:
commit
b20e38a2bc
@ -22,6 +22,12 @@ will consitute of a breaking change warranting a new major release:
|
||||
to a regression, so commanding the SDC state machine externally lead to confusing results.
|
||||
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
|
||||
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
|
||||
- Add a way for the SUS polling to detect broken or off devices by checking the retrieved
|
||||
temperature for the all-ones value (0x0fff).
|
||||
- Better reply result handling for the ACS board devices.
|
||||
- ADIS1650X initial timeout handling now performed in device handler.
|
||||
- The RW assembly and TCS board assembly now perform proper power switch handling for their
|
||||
recovery handling.
|
||||
|
||||
## Changed
|
||||
|
||||
@ -29,6 +35,8 @@ will consitute of a breaking change warranting a new major release:
|
||||
the active SD card is switched or there is a transition from hot redundant to cold redundant mode.
|
||||
This gives other tasks some time to register the SD cards being unusable, and therefore provides
|
||||
a way for them to perform any re-initialization tasks necessary after SD card switches.
|
||||
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
|
||||
the primary control loop) while a TCS board recovery is on-going.
|
||||
|
||||
## Changed
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "mission/system/com/comModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "mission/tcs/defs.h"
|
||||
|
||||
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {
|
||||
new ComIFDummy(objects::DUMMY_COM_IF);
|
||||
@ -202,7 +203,8 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
||||
|
||||
new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies,
|
||||
tmpSensorDummies);
|
||||
TcsBoardAssembly* tcsBoardAssy = ObjectFactory::createTcsBoardAssy(pwrSwitcher);
|
||||
TcsBoardAssembly* tcsBoardAssy =
|
||||
ObjectFactory::createTcsBoardAssy(pwrSwitcher, tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||
for (auto& rtd : rtdSensorDummies) {
|
||||
rtd.second->connectModeTreeParent(*tcsBoardAssy);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "mission/tcs/defs.h"
|
||||
|
||||
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
|
||||
PowerSwitchIF& pwrSwitcher, std::string spiDev,
|
||||
@ -278,7 +279,8 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
||||
std::array<Max31865EiveHandler*, NUM_RTDS> rtds = {};
|
||||
RtdFdir* rtdFdir = nullptr;
|
||||
|
||||
TcsBoardAssembly* tcsBoardAss = ObjectFactory::createTcsBoardAssy(*pwrSwitcher);
|
||||
TcsBoardAssembly* tcsBoardAss =
|
||||
ObjectFactory::createTcsBoardAssy(*pwrSwitcher, tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||
|
||||
// Create special low level reader communication interface
|
||||
new Max31865RtdPolling(objects::SPI_RTD_COM_IF, comIF, gpioComIF);
|
||||
|
@ -113,7 +113,8 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
||||
if (req->mode != adis.mode) {
|
||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||
adis.type = req->type;
|
||||
adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
||||
// The initial countdown is handled by the device handler now.
|
||||
// adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
||||
if (adis.type == adis1650x::Type::ADIS16507) {
|
||||
adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
|
||||
} else if (adis.type == adis1650x::Type::ADIS16505) {
|
||||
@ -127,6 +128,7 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
||||
adis.ownReply.cfgWasSet = false;
|
||||
adis.ownReply.dataWasSet = false;
|
||||
}
|
||||
adis.replyResult = returnvalue::FAILED;
|
||||
adis.mode = req->mode;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -145,6 +147,7 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
||||
} else {
|
||||
gyro.ownReply.cfgWasSet = false;
|
||||
}
|
||||
gyro.replyResult = returnvalue::FAILED;
|
||||
gyro.mode = req->mode;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -163,6 +166,7 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
||||
mgm.ownReply.dataWasSet = false;
|
||||
mgm.ownReply.temperatureWasSet = false;
|
||||
}
|
||||
mgm.replyResult = returnvalue::FAILED;
|
||||
mgm.mode = req->mode;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -180,6 +184,7 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
||||
} else {
|
||||
mgm.ownReply.dataWasRead = false;
|
||||
}
|
||||
mgm.replyResult = returnvalue::FAILED;
|
||||
mgm.mode = req->mode;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -309,18 +314,18 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
||||
std::memcpy(cmdBuf.data() + 1, l3g.sensorCfg, 5);
|
||||
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
||||
if (result != returnvalue::OK) {
|
||||
l3g.replyResult = returnvalue::OK;
|
||||
l3g.replyResult = result;
|
||||
}
|
||||
// Ignore useless reply and red config
|
||||
cmdBuf[0] = l3gd20h::CTRL_REG_1 | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
||||
std::memset(cmdBuf.data() + 1, 0, 5);
|
||||
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
||||
if (result != returnvalue::OK) {
|
||||
l3g.replyResult = returnvalue::OK;
|
||||
l3g.replyResult = result;
|
||||
}
|
||||
result = spiComIF.readReceivedMessage(l3g.cookie, &rawReply, &dummy);
|
||||
if (result != returnvalue::OK) {
|
||||
l3g.replyResult = returnvalue::OK;
|
||||
l3g.replyResult = result;
|
||||
}
|
||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
// Cross check configuration as verification that communication is working
|
||||
@ -331,6 +336,7 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
l3g.replyResult = returnvalue::OK;
|
||||
l3g.performStartup = false;
|
||||
l3g.ownReply.cfgWasSet = true;
|
||||
l3g.ownReply.sensitivity = l3gd20h::ctrlReg4ToSensitivity(l3g.sensorCfg[3]);
|
||||
@ -357,6 +363,7 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
l3g.replyResult = returnvalue::OK;
|
||||
l3g.ownReply.statusReg = rawReply[l3gd20h::STATUS_IDX];
|
||||
l3g.ownReply.angVelocities[0] = (rawReply[l3gd20h::OUT_X_H] << 8) | rawReply[l3gd20h::OUT_X_L];
|
||||
l3g.ownReply.angVelocities[1] = (rawReply[l3gd20h::OUT_Y_H] << 8) | rawReply[l3gd20h::OUT_Y_L];
|
||||
@ -443,20 +450,15 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
||||
void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
||||
ReturnValue_t result;
|
||||
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||
bool cdHasTimedOut = false;
|
||||
bool mustPerformStartup = false;
|
||||
{
|
||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
mode = gyro.mode;
|
||||
cdHasTimedOut = gyro.countdown.hasTimedOut();
|
||||
mustPerformStartup = gyro.performStartup;
|
||||
}
|
||||
if (mode == acs::SimpleSensorMode::OFF) {
|
||||
return;
|
||||
}
|
||||
if (not cdHasTimedOut) {
|
||||
return;
|
||||
}
|
||||
if (mustPerformStartup) {
|
||||
uint8_t regList[6];
|
||||
// Read configuration
|
||||
@ -495,6 +497,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
||||
gyro.ownReply.cfg.prodId = prodId;
|
||||
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
||||
gyro.performStartup = false;
|
||||
gyro.replyResult = returnvalue::OK;
|
||||
}
|
||||
// Read regular registers
|
||||
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
|
||||
@ -533,6 +536,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
||||
}
|
||||
|
||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
gyro.replyResult = returnvalue::OK;
|
||||
gyro.ownReply.dataWasSet = true;
|
||||
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3];
|
||||
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5];
|
||||
@ -590,6 +594,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
||||
}
|
||||
// Done here. We can always read back config and data during periodic handling
|
||||
mgm.performStartup = false;
|
||||
mgm.replyResult = returnvalue::OK;
|
||||
}
|
||||
cmdBuf[0] = mgmLis3::readCommand(mgmLis3::CTRL_REG1, true);
|
||||
std::memset(cmdBuf.data() + 1, 0, mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS);
|
||||
@ -607,7 +612,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
||||
// Verify communication by re-checking config
|
||||
if (rawReply[1] != mgm.cfg[0] or rawReply[2] != mgm.cfg[1] or rawReply[3] != mgm.cfg[2] or
|
||||
rawReply[4] != mgm.cfg[3] or rawReply[5] != mgm.cfg[4]) {
|
||||
mgm.replyResult = result;
|
||||
mgm.replyResult = returnvalue::FAILED;
|
||||
return;
|
||||
}
|
||||
{
|
||||
@ -634,6 +639,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
||||
return;
|
||||
}
|
||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
mgm.replyResult = returnvalue::OK;
|
||||
mgm.ownReply.temperatureWasSet = true;
|
||||
mgm.ownReply.temperatureRaw = (rawReply[2] << 8) | rawReply[1];
|
||||
}
|
||||
@ -704,6 +710,7 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
||||
return;
|
||||
}
|
||||
mgm.performStartup = false;
|
||||
mgm.replyResult = returnvalue::OK;
|
||||
}
|
||||
// Regular read operation
|
||||
cmdBuf[0] = mgmRm3100::MEASUREMENT_REG_START | mgmRm3100::READ_MASK;
|
||||
@ -725,6 +732,7 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
||||
mgm.ownReply.scaleFactors[idx] = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
||||
}
|
||||
mgm.ownReply.dataWasRead = true;
|
||||
mgm.replyResult = returnvalue::OK;
|
||||
// Bitshift trickery to account for 24 bit signed value.
|
||||
mgm.ownReply.mgmValuesRaw[0] =
|
||||
((rawReply[1] << 24) | (rawReply[2] << 16) | (rawReply[3] << 8)) >> 8;
|
||||
|
@ -73,6 +73,7 @@ ReturnValue_t SusPolling::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
susDevs[susIdx].ownReply.cfgWasSet = false;
|
||||
susDevs[susIdx].ownReply.dataWasSet = false;
|
||||
}
|
||||
susDevs[susIdx].replyResult = returnvalue::FAILED;
|
||||
susDevs[susIdx].mode = susReq->mode;
|
||||
}
|
||||
if (state == InternalState::IDLE) {
|
||||
@ -95,11 +96,14 @@ ReturnValue_t SusPolling::readReceivedMessage(CookieIF* cookie, uint8_t** buffer
|
||||
if (susIdx < 0) {
|
||||
return FAILED;
|
||||
}
|
||||
if (susDevs[susIdx].replyResult != returnvalue::OK) {
|
||||
return susDevs[susIdx].replyResult;
|
||||
}
|
||||
MutexGuard mg(ipcLock);
|
||||
std::memcpy(&susDevs[susIdx].readerReply, &susDevs[susIdx].ownReply, sizeof(acs::SusReply));
|
||||
*buffer = reinterpret_cast<uint8_t*>(&susDevs[susIdx].readerReply);
|
||||
*size = sizeof(acs::SusReply);
|
||||
return OK;
|
||||
return susDevs[susIdx].replyResult;
|
||||
}
|
||||
|
||||
ReturnValue_t SusPolling::handleSusPolling() {
|
||||
@ -164,6 +168,12 @@ ReturnValue_t SusPolling::handleSusPolling() {
|
||||
}
|
||||
MutexGuard mg(ipcLock);
|
||||
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
|
||||
// Reply is all ones. Sensor is probably off or faulty when
|
||||
// it should not be.
|
||||
if (susDevs[idx].ownReply.tempRaw == 0x0fff) {
|
||||
susDevs[idx].replyResult = returnvalue::FAILED;
|
||||
} else {
|
||||
susDevs[idx].replyResult = returnvalue::OK;
|
||||
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
|
||||
susDevs[idx].ownReply.channelsRaw[chIdx] =
|
||||
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
|
||||
@ -171,6 +181,7 @@ ReturnValue_t SusPolling::handleSusPolling() {
|
||||
susDevs[idx].ownReply.dataWasSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,9 @@ ReturnValue_t GyrAdis1650XHandler::buildNormalDeviceCommand(DeviceCommandId_t *i
|
||||
ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||
switch (internalState) {
|
||||
case (InternalState::STARTUP): {
|
||||
if (breakCountdown.isBusy()) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
*id = adis1650x::REQUEST;
|
||||
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
||||
}
|
||||
|
@ -21,7 +21,8 @@
|
||||
#define LOWER_EBAND_UPPER_LIMITS 0
|
||||
#define LOWER_PLOC_UPPER_LIMITS 0
|
||||
|
||||
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater)
|
||||
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||
const std::atomic_bool& tcsBoardShortUnavailable)
|
||||
: ExtendedControllerBase(objectId),
|
||||
heaterHandler(heater),
|
||||
sensorTemperatures(this),
|
||||
@ -66,7 +67,8 @@ ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater
|
||||
susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB),
|
||||
susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF),
|
||||
susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF),
|
||||
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) {
|
||||
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB),
|
||||
tcsBrdShortlyUnavailable(tcsBoardShortUnavailable) {
|
||||
resetSensorsArray();
|
||||
}
|
||||
|
||||
@ -134,12 +136,14 @@ void ThermalController::performControlOperation() {
|
||||
}
|
||||
}
|
||||
|
||||
if (not tcsBrdShortlyUnavailable) {
|
||||
{
|
||||
PoolReadGuard pg(&sensorTemperatures);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
copySensors();
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&susTemperatures);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
@ -182,7 +186,7 @@ void ThermalController::performControlOperation() {
|
||||
}
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
} else if (mode != MODE_OFF) {
|
||||
} else if (mode != MODE_OFF and not tcsBrdShortlyUnavailable) {
|
||||
performThermalModuleCtrl(heaterSwitchStateArray);
|
||||
}
|
||||
cycles++;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <mission/tcs/Tmp1075Definitions.h>
|
||||
#include <mission/utility/trace.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
|
||||
/**
|
||||
@ -94,7 +95,8 @@ class ThermalController : public ExtendedControllerBase {
|
||||
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
|
||||
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
|
||||
|
||||
ThermalController(object_id_t objectId, HeaterHandler& heater);
|
||||
ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||
const std::atomic_bool& tcsBoardShortUnavailable);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
@ -181,6 +183,10 @@ class ThermalController : public ExtendedControllerBase {
|
||||
susMax1227::SusDataset susSet10;
|
||||
susMax1227::SusDataset susSet11;
|
||||
|
||||
// If the TCS board in unavailable, for example due to a recovery, skip
|
||||
// some TCS controller tasks to avoid unnecessary events.
|
||||
const std::atomic_bool& tcsBrdShortlyUnavailable = false;
|
||||
|
||||
lp_var_t<float> tempQ7s = lp_var_t<float>(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE);
|
||||
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_1);
|
||||
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_2);
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "mission/system/acs/RwAssembly.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "mission/tcs/defs.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
#include "objects/systemObjectList.h"
|
||||
#include "tmtc/pusIds.h"
|
||||
@ -90,6 +91,8 @@ EiveFaultHandler EIVE_FAULT_HANDLER;
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
std::atomic_bool tcs::TCS_BOARD_SHORTLY_UNAVAILABLE = false;
|
||||
|
||||
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
|
||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
||||
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
||||
@ -300,7 +303,8 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
|
||||
}
|
||||
|
||||
void ObjectFactory::createThermalController(HeaterHandler& heaterHandler) {
|
||||
auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler);
|
||||
auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler,
|
||||
tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||
tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||
}
|
||||
void ObjectFactory::createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
|
||||
@ -366,10 +370,12 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||
acsAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
}
|
||||
|
||||
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) {
|
||||
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||
std::atomic_bool& tcsShortlyUnavailable) {
|
||||
TcsBoardHelper helper(RTD_INFOS);
|
||||
auto* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
|
||||
power::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
|
||||
auto* tcsBoardAss =
|
||||
new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
|
||||
power::Switches::PDU1_CH0_TCS_BOARD_3V3, helper, tcsShortlyUnavailable);
|
||||
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||
return tcsBoardAss;
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ void createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
|
||||
void createSusAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 12> suses);
|
||||
void createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 8> assemblyDhbs,
|
||||
ExtendedControllerBase* gpsCtrl, GpioIF* gpioComIF);
|
||||
TcsBoardAssembly* createTcsBoardAssy(PowerSwitchIF& pwrSwitcher);
|
||||
TcsBoardAssembly* createTcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||
std::atomic_bool& tcsShortlyUnavailable);
|
||||
|
||||
} // namespace ObjectFactory
|
||||
|
||||
|
@ -50,6 +50,7 @@ static constexpr Event FDIR_REACTION_IGNORED = event::makeEvent(SUBSYSTEM_ID, 3,
|
||||
enum class States { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING };
|
||||
enum class OpCodes { NONE, TO_OFF_DONE, TO_NOT_OFF_DONE, TIMEOUT_OCCURED };
|
||||
|
||||
enum RecoveryCustomStates { IDLE, POWER_SWITCHING_OFF, POWER_SWITCHING_ON, DONE };
|
||||
} // namespace power
|
||||
|
||||
namespace duallane {
|
||||
|
@ -6,5 +6,6 @@ add_subdirectory(fdir)
|
||||
add_subdirectory(power)
|
||||
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION} PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp
|
||||
EiveSystem.cpp treeUtil.cpp)
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp EiveSystem.cpp
|
||||
treeUtil.cpp SharedPowerAssemblyBase.cpp)
|
||||
|
91
mission/system/SharedPowerAssemblyBase.cpp
Normal file
91
mission/system/SharedPowerAssemblyBase.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "SharedPowerAssemblyBase.h"
|
||||
|
||||
SharedPowerAssemblyBase::SharedPowerAssemblyBase(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||
power::Switch_t switchId, uint16_t cmdQueueDepth)
|
||||
: AssemblyBase(objectId, cmdQueueDepth), switcher(pwrSwitcher, switchId) {}
|
||||
|
||||
void SharedPowerAssemblyBase::performChildOperation() {
|
||||
auto state = switcher.getState();
|
||||
if (state != PowerSwitcher::WAIT_OFF and state != PowerSwitcher::WAIT_ON) {
|
||||
AssemblyBase::performChildOperation();
|
||||
return;
|
||||
}
|
||||
switcher.doStateMachine();
|
||||
if (state == PowerSwitcher::WAIT_OFF and switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
// Indicator that a transition to off is finished
|
||||
AssemblyBase::handleModeReached();
|
||||
} else if (state == PowerSwitcher::WAIT_ON and
|
||||
switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
// Indicator that mode commanding can be performed now
|
||||
AssemblyBase::startTransition(targetMode, targetSubmode);
|
||||
}
|
||||
}
|
||||
|
||||
void SharedPowerAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||
if (mode != MODE_OFF) {
|
||||
switcher.turnOn(true);
|
||||
switcher.doStateMachine();
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
} else {
|
||||
// Need to wait with mode commanding until power switcher is done
|
||||
targetMode = mode;
|
||||
targetSubmode = submode;
|
||||
}
|
||||
} else {
|
||||
// Perform regular mode commanding first
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
void SharedPowerAssemblyBase::handleModeReached() {
|
||||
if (targetMode == MODE_OFF) {
|
||||
switcher.turnOff(true);
|
||||
switcher.doStateMachine();
|
||||
// Need to wait with call to AssemblyBase::handleModeReached until power switcher is done
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
AssemblyBase::handleModeReached();
|
||||
}
|
||||
} else {
|
||||
AssemblyBase::handleModeReached();
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedPowerAssemblyBase::checkAndHandleRecovery() {
|
||||
using namespace power;
|
||||
if (recoveryState == RECOVERY_IDLE) {
|
||||
return AssemblyBase::checkAndHandleRecovery();
|
||||
}
|
||||
if (customRecoveryStates == IDLE) {
|
||||
switcher.turnOff();
|
||||
customRecoveryStates = RecoveryCustomStates::POWER_SWITCHING_OFF;
|
||||
}
|
||||
if (customRecoveryStates == POWER_SWITCHING_OFF) {
|
||||
switcher.doStateMachine();
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
customRecoveryStates = RecoveryCustomStates::POWER_SWITCHING_ON;
|
||||
switcher.turnOn();
|
||||
}
|
||||
}
|
||||
if (customRecoveryStates == POWER_SWITCHING_ON) {
|
||||
switcher.doStateMachine();
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
customRecoveryStates = RecoveryCustomStates::DONE;
|
||||
}
|
||||
}
|
||||
if (customRecoveryStates == DONE) {
|
||||
bool pendingRecovery = AssemblyBase::checkAndHandleRecovery();
|
||||
if (not pendingRecovery) {
|
||||
customRecoveryStates = RecoveryCustomStates::IDLE;
|
||||
}
|
||||
// For a recovery on one side, only do the recovery once
|
||||
for (auto& child : childrenMap) {
|
||||
if (healthHelper.healthTable->getHealth(child.first) == HasHealthIF::NEEDS_RECOVERY) {
|
||||
sendHealthCommand(child.second.commandQueue, HEALTHY);
|
||||
child.second.healthChanged = false;
|
||||
}
|
||||
}
|
||||
return pendingRecovery;
|
||||
}
|
||||
return true;
|
||||
}
|
27
mission/system/SharedPowerAssemblyBase.h
Normal file
27
mission/system/SharedPowerAssemblyBase.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef MISSION_SYSTEM_SHAREDPOWERASSEMBLYBASE_H_
|
||||
#define MISSION_SYSTEM_SHAREDPOWERASSEMBLYBASE_H_
|
||||
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
#include <fsfw/power/PowerSwitcher.h>
|
||||
#include <mission/power/defs.h>
|
||||
|
||||
/**
|
||||
* Base class which contains common functions for assemblies where the power line is shared
|
||||
* among the devices in the assembly.
|
||||
*/
|
||||
class SharedPowerAssemblyBase : public AssemblyBase {
|
||||
public:
|
||||
SharedPowerAssemblyBase(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||
power::Switch_t switchId, uint16_t cmdQueueDepth = 8);
|
||||
|
||||
protected:
|
||||
PowerSwitcher switcher;
|
||||
power::RecoveryCustomStates customRecoveryStates = power::RecoveryCustomStates::IDLE;
|
||||
|
||||
void performChildOperation() override;
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void handleModeReached() override;
|
||||
virtual bool checkAndHandleRecovery() override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_SHAREDPOWERASSEMBLYBASE_H_ */
|
@ -39,12 +39,7 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
|
||||
SideSwitchState sideSwitchState = SideSwitchState::NONE;
|
||||
duallane::Submodes targetSubmodeForSideSwitch = duallane::Submodes::B_SIDE;
|
||||
|
||||
enum RecoveryCustomStates {
|
||||
IDLE,
|
||||
POWER_SWITCHING_OFF,
|
||||
POWER_SWITCHING_ON,
|
||||
DONE
|
||||
} customRecoveryStates = RecoveryCustomStates::IDLE;
|
||||
power::RecoveryCustomStates customRecoveryStates = power::RecoveryCustomStates::IDLE;
|
||||
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "RwAssembly.h"
|
||||
|
||||
RwAssembly::RwAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t switcher,
|
||||
RwAssembly::RwAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t switchId,
|
||||
RwHelper helper)
|
||||
: AssemblyBase(objectId), helper(helper), switcher(pwrSwitcher, switcher) {
|
||||
: SharedPowerAssemblyBase(objectId, pwrSwitcher, switchId), helper(helper) {
|
||||
ModeListEntry entry;
|
||||
for (uint8_t idx = 0; idx < NUMBER_RWS; idx++) {
|
||||
entry.setObject(helper.rwIds[idx]);
|
||||
@ -12,26 +12,8 @@ RwAssembly::RwAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::
|
||||
}
|
||||
}
|
||||
|
||||
void RwAssembly::performChildOperation() {
|
||||
auto state = switcher.getState();
|
||||
if (state != PowerSwitcher::WAIT_OFF and state != PowerSwitcher::WAIT_ON) {
|
||||
AssemblyBase::performChildOperation();
|
||||
return;
|
||||
}
|
||||
switcher.doStateMachine();
|
||||
if (state == PowerSwitcher::WAIT_OFF and switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
// Indicator that a transition to off is finished
|
||||
AssemblyBase::handleModeReached();
|
||||
} else if (state == PowerSwitcher::WAIT_ON and
|
||||
switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
// Indicator that mode commanding can be performed now
|
||||
AssemblyBase::startTransition(targetMode, targetSubmode);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t RwAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
modeTransitionFailedSwitch = true;
|
||||
// Initialize the mode table to ensure all devices are in a defined state
|
||||
for (uint8_t idx = 0; idx < NUMBER_RWS; idx++) {
|
||||
modeTable[idx].setMode(MODE_OFF);
|
||||
@ -76,36 +58,6 @@ ReturnValue_t RwAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode)
|
||||
return HasModesIF::INVALID_MODE;
|
||||
}
|
||||
|
||||
void RwAssembly::startTransition(Mode_t mode, Submode_t submode) {
|
||||
if (mode != MODE_OFF) {
|
||||
switcher.turnOn(true);
|
||||
switcher.doStateMachine();
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
} else {
|
||||
// Need to wait with mode commanding until power switcher is done
|
||||
targetMode = mode;
|
||||
targetSubmode = submode;
|
||||
}
|
||||
} else {
|
||||
// Perform regular mode commanding first
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
void RwAssembly::handleModeReached() {
|
||||
if (targetMode == MODE_OFF) {
|
||||
switcher.turnOff(true);
|
||||
switcher.doStateMachine();
|
||||
// Need to wait with call to AssemblyBase::handleModeReached until power switcher is done
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
AssemblyBase::handleModeReached();
|
||||
}
|
||||
} else {
|
||||
AssemblyBase::handleModeReached();
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t RwAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
object_id_t objId = 0;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef MISSION_SYSTEM_RWASS_H_
|
||||
#define MISSION_SYSTEM_RWASS_H_
|
||||
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
#include <fsfw/power/PowerSwitcher.h>
|
||||
#include <mission/system/SharedPowerAssemblyBase.h>
|
||||
|
||||
struct RwHelper {
|
||||
RwHelper(std::array<object_id_t, 4> rwIds) : rwIds(rwIds) {}
|
||||
@ -10,17 +10,15 @@ struct RwHelper {
|
||||
std::array<object_id_t, 4> rwIds = {};
|
||||
};
|
||||
|
||||
class RwAssembly : public AssemblyBase {
|
||||
class RwAssembly : public SharedPowerAssemblyBase {
|
||||
public:
|
||||
RwAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t switcher,
|
||||
RwAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t switchId,
|
||||
RwHelper helper);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t NUMBER_RWS = 4;
|
||||
RwHelper helper;
|
||||
PowerSwitcher switcher;
|
||||
bool warningSwitch = true;
|
||||
bool modeTransitionFailedSwitch = true;
|
||||
FixedArrayList<ModeListEntry, NUMBER_RWS> modeTable;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
@ -35,12 +33,9 @@ class RwAssembly : public AssemblyBase {
|
||||
bool isUseable(object_id_t object, Mode_t mode);
|
||||
|
||||
// AssemblyBase implementation
|
||||
void performChildOperation() override;
|
||||
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 startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void handleModeReached() override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_RWASS_H_ */
|
||||
|
@ -3,4 +3,4 @@
|
||||
#include "eive/objects.h"
|
||||
|
||||
RtdFdir::RtdFdir(object_id_t sensorId)
|
||||
: DeviceHandlerFailureIsolation(sensorId, objects::TCS_BOARD_ASS) {}
|
||||
: DeviceHandlerFailureIsolation(sensorId, objects::NO_OBJECT) {}
|
||||
|
@ -4,9 +4,11 @@
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
|
||||
TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||
power::Switch_t theSwitch, TcsBoardHelper helper)
|
||||
: AssemblyBase(objectId, 24), switcher(pwrSwitcher, theSwitch), helper(helper) {
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(24);
|
||||
power::Switch_t theSwitch, TcsBoardHelper helper,
|
||||
std::atomic_bool& tcsShortlyUnavailable)
|
||||
: SharedPowerAssemblyBase(objectId, pwrSwitcher, theSwitch, 16),
|
||||
helper(helper),
|
||||
tcsShortlyUnavailable(tcsShortlyUnavailable) {
|
||||
ModeListEntry entry;
|
||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||
entry.setObject(helper.rtdInfos[idx].first);
|
||||
@ -16,23 +18,6 @@ TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitc
|
||||
}
|
||||
}
|
||||
|
||||
void TcsBoardAssembly::performChildOperation() {
|
||||
auto state = switcher.getState();
|
||||
if (state != PowerSwitcher::WAIT_OFF and state != PowerSwitcher::WAIT_ON) {
|
||||
AssemblyBase::performChildOperation();
|
||||
return;
|
||||
}
|
||||
switcher.doStateMachine();
|
||||
if (state == PowerSwitcher::WAIT_OFF and switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
// Indicator that a transition to off is finished
|
||||
AssemblyBase::handleModeReached();
|
||||
} else if (state == PowerSwitcher::WAIT_ON and
|
||||
switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
// Indicator that mode commanding can be performed now
|
||||
AssemblyBase::startTransition(targetMode, targetSubmode);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
// Initialize the mode table to ensure all devices are in a defined state
|
||||
@ -50,6 +35,8 @@ ReturnValue_t TcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode)
|
||||
if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) {
|
||||
result = handleNormalOrOnModeCmd(mode, submode);
|
||||
}
|
||||
} else {
|
||||
tcsShortlyUnavailable = true;
|
||||
}
|
||||
HybridIterator<ModeListEntry> tableIter(modeTable.begin(), modeTable.end());
|
||||
executeTable(tableIter);
|
||||
@ -94,25 +81,6 @@ ReturnValue_t TcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t su
|
||||
return HasModesIF::INVALID_MODE;
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::initialize() { return AssemblyBase::initialize(); }
|
||||
|
||||
void TcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) {
|
||||
if (mode != MODE_OFF) {
|
||||
switcher.turnOn(true);
|
||||
switcher.doStateMachine();
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
} else {
|
||||
// Need to wait with mode commanding until power switcher is done
|
||||
targetMode = mode;
|
||||
targetSubmode = submode;
|
||||
}
|
||||
} else {
|
||||
// Perform regular mode commanding first
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
bool needsSecondStep = false;
|
||||
@ -169,21 +137,6 @@ bool TcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageQueueId_t TcsBoardAssembly::getEventReceptionQueue() { return eventQueue->getId(); }
|
||||
|
||||
void TcsBoardAssembly::handleModeReached() {
|
||||
if (targetMode == MODE_OFF) {
|
||||
switcher.turnOff(true);
|
||||
switcher.doStateMachine();
|
||||
// Need to wait with call to AssemblyBase::handleModeReached until power switcher is done
|
||||
if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||
AssemblyBase::handleModeReached();
|
||||
}
|
||||
} else {
|
||||
AssemblyBase::handleModeReached();
|
||||
}
|
||||
}
|
||||
|
||||
void TcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) {
|
||||
triggerEvent(CHILDREN_LOST_MODE, result);
|
||||
startTransition(mode, submode);
|
||||
@ -210,6 +163,12 @@ ReturnValue_t TcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
||||
return status;
|
||||
}
|
||||
|
||||
bool TcsBoardAssembly::checkAndHandleRecovery() {
|
||||
bool recoveryPending = SharedPowerAssemblyBase::checkAndHandleRecovery();
|
||||
tcsShortlyUnavailable = recoveryPending;
|
||||
return recoveryPending;
|
||||
}
|
||||
|
||||
void TcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
if (targetMode == MODE_OFF) {
|
||||
AssemblyBase::handleModeTransitionFailed(result);
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include <fsfw/container/FixedArrayList.h>
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
#include <fsfw/power/PowerSwitcher.h>
|
||||
#include <mission/power/defs.h>
|
||||
#include <mission/system/SharedPowerAssemblyBase.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "events/subsystemIdRanges.h"
|
||||
#include "returnvalues/classIds.h"
|
||||
@ -15,23 +19,20 @@ struct TcsBoardHelper {
|
||||
std::array<std::pair<object_id_t, std::string>, 16> rtdInfos = {};
|
||||
};
|
||||
|
||||
class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF {
|
||||
class TcsBoardAssembly : public SharedPowerAssemblyBase {
|
||||
public:
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_BOARD_ASS;
|
||||
static constexpr Event CHILDREN_LOST_MODE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
|
||||
TcsBoardAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t switcher,
|
||||
TcsBoardHelper helper);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
TcsBoardHelper helper, std::atomic_bool& tcsShortlyUnavailable);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t NUMBER_RTDS = 16;
|
||||
PowerSwitcher switcher;
|
||||
bool warningSwitch = true;
|
||||
TcsBoardHelper helper;
|
||||
FixedArrayList<ModeListEntry, NUMBER_RTDS> modeTable;
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
std::atomic_bool& tcsShortlyUnavailable;
|
||||
|
||||
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
||||
/**
|
||||
@ -42,17 +43,12 @@ class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF {
|
||||
*/
|
||||
bool isUseable(object_id_t object, Mode_t mode);
|
||||
|
||||
// ConfirmFailureIF implementation
|
||||
MessageQueueId_t getEventReceptionQueue() override;
|
||||
|
||||
// AssemblyBase implementation
|
||||
void performChildOperation() override;
|
||||
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 startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void handleModeReached() override;
|
||||
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
|
||||
bool checkAndHandleRecovery() override;
|
||||
|
||||
// These two overrides prevent a transition of the whole assembly back to off just because
|
||||
// some devices are not working
|
||||
|
9
mission/tcs/defs.h
Normal file
9
mission/tcs/defs.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace tcs {
|
||||
|
||||
extern std::atomic_bool TCS_BOARD_SHORTLY_UNAVAILABLE;
|
||||
|
||||
}
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
||||
Subproject commit 43b530cdb7dfe6774962bf4b8a880e1c9a6e6580
|
||||
Subproject commit f075d28905b42a018b275d8c640cb0fd9d64dc26
|
@ -15,6 +15,7 @@
|
||||
|
||||
TEST_CASE("Thermal Controller", "[ThermalController]") {
|
||||
const object_id_t THERMAL_CONTROLLER_ID = 0x123;
|
||||
std::atomic_bool tcsBrdShortlyUnavailable = false;
|
||||
|
||||
TemperatureSensorInserter::Max31865DummyMap map0;
|
||||
TemperatureSensorInserter::Tmp1075DummyMap map1;
|
||||
@ -29,7 +30,7 @@ TEST_CASE("Thermal Controller", "[ThermalController]") {
|
||||
|
||||
// testEnvironment::initialize();
|
||||
|
||||
ThermalController controller(THERMAL_CONTROLLER_ID, *heaterHandler);
|
||||
ThermalController controller(THERMAL_CONTROLLER_ID, *heaterHandler, tcsBrdShortlyUnavailable);
|
||||
ReturnValue_t result = controller.initialize();
|
||||
REQUIRE(result == returnvalue::OK);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user