Merge remote-tracking branch 'origin/develop' into heater_handling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
2023-02-03 11:47:16 +01:00
51 changed files with 1415 additions and 534 deletions

View File

@ -7,3 +7,4 @@ add_subdirectory(tmtc)
add_subdirectory(system)
add_subdirectory(csp)
add_subdirectory(cfdp)
add_subdirectory(config)

31
mission/comDefs.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef MISSION_COMDEFS_H_
#define MISSION_COMDEFS_H_
namespace com {
enum class Datarate : uint8_t {
LOW_RATE_MODULATION_BPSK,
HIGH_RATE_MODULATION_0QPSK,
NUM_DATARATES
};
enum Submode : uint8_t {
RX_ONLY,
RX_AND_TX_DEFAULT_DATARATE,
RX_AND_TX_LOW_DATARATE,
RX_AND_TX_HIGH_DATARATE,
RX_AND_TX_CW,
NUM_SUBMODES
};
enum class CcsdsSubmode : uint8_t {
UNSET = 0,
DATARATE_LOW = 1,
DATARATE_HIGH = 2,
DATARATE_DEFAULT = 3
};
enum class ParameterId : uint8_t { DATARATE = 0 };
} // namespace com
#endif /* MISSION_COMDEFS_H_ */

View File

@ -0,0 +1 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE comCfg.cpp torquer.cpp)

26
mission/config/comCfg.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "comCfg.h"
#include <fsfw/ipc/MutexFactory.h>
#include <fsfw/ipc/MutexGuard.h>
com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK;
MutexIF* DATARATE_LOCK = nullptr;
MutexIF* lazyLock();
com::Datarate com::getCurrentDatarate() {
MutexGuard mg(lazyLock());
return DATARATE_CFG_RAW;
}
void com::setCurrentDatarate(com::Datarate newRate) {
MutexGuard mg(lazyLock());
DATARATE_CFG_RAW = newRate;
}
MutexIF* lazyLock() {
if (DATARATE_LOCK == nullptr) {
return MutexFactory::instance()->createMutex();
}
return DATARATE_LOCK;
}

15
mission/config/comCfg.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef MISSION_COMCFG_H_
#define MISSION_COMCFG_H_
#include <fsfw/ipc/MutexIF.h>
#include "mission/comDefs.h"
namespace com {
com::Datarate getCurrentDatarate();
void setCurrentDatarate(com::Datarate newRate);
} // namespace com
#endif /* MISSION_COMCFG_H_ */

View File

@ -2,7 +2,7 @@
#include <fsfw/datapool/PoolReadGuard.h>
#include "mission/devices/torquer.h"
#include "mission/config/torquer.h"
AcsController::AcsController(object_id_t objectId)
: ExtendedControllerBase(objectId),

View File

@ -775,7 +775,7 @@ void ThermalController::copyDevices() {
{
lp_var_t<float> tempSyrlinksPowerAmplifier =
lp_var_t<float>(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER);
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER);
PoolReadGuard pg(&tempSyrlinksPowerAmplifier, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT);
if (pg.getReadResult() != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read syrlinks power amplifier temperature"
@ -790,7 +790,7 @@ void ThermalController::copyDevices() {
{
lp_var_t<float> tempSyrlinksBasebandBoard =
lp_var_t<float>(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
PoolReadGuard pg(&tempSyrlinksBasebandBoard, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT);
if (pg.getReadResult() != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read syrlinks baseband board temperature"

View File

@ -37,21 +37,24 @@ class AcsParameters /*: public HasParametersIF*/ {
float mgm3orientationMatrix[3][3] = {{0, 0, 1}, {0, -1, 0}, {1, 0, 0}};
float mgm4orientationMatrix[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}};
float mgm0hardIronOffset[3] = {19.89364, -29.94111, -31.07508};
float mgm1hardIronOffset[3] = {10.95500, -8.053403, -33.36383};
float mgm2hardIronOffset[3] = {15.72181, -26.87090, -62.19010};
float mgm0hardIronOffset[3] = {0.0, 0.0, 0.0}; //{19.89364, -29.94111, -31.07508};
float mgm1hardIronOffset[3] = {0.0, 0.0, 0.0}; //{10.95500, -8.053403, -33.36383};
float mgm2hardIronOffset[3] = {0.0, 0.0, 0.0}; //{15.72181, -26.87090, -62.19010};
float mgm3hardIronOffset[3] = {0.0, 0.0, 0.0};
float mgm4hardIronOffset[3] = {0.0, 0.0, 0.0};
float mgm0softIronInverse[3][3] = {{1420.727e-3, 9.352825e-3, -127.1979e-3},
{9.352825e-3, 1031.965e-3, -80.02734e-3},
{-127.1979e-3, -80.02734e-3, 934.8899e-3}};
float mgm1softIronInverse[3][3] = {{126.7325e-2, -4.146410e-2, -18.37963e-2},
{-4.146410e-2, 109.3310e-2, -5.246314e-2},
{-18.37963e-2, -5.246314e-2, 105.7300e-2}};
float mgm2softIronInverse[3][3] = {{143.0438e-2, 7.095763e-2, 15.67482e-2},
{7.095763e-2, 99.65167e-2, -6.958760e-2},
{15.67482e-2, -6.958760e-2, 94.50124e-2}};
float mgm0softIronInverse[3][3] = {
{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /*{{1420.727e-3, 9.352825e-3,
-127.1979e-3}, {9.352825e-3, 1031.965e-3, -80.02734e-3},
{-127.1979e-3, -80.02734e-3, 934.8899e-3}};*/
float mgm1softIronInverse[3][3] = {
{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /*{{126.7325e-2, -4.146410e-2, -18.37963e-2},
{-4.146410e-2, 109.3310e-2, -5.246314e-2},
{-18.37963e-2, -5.246314e-2, 105.7300e-2}};*/
float mgm2softIronInverse[3][3] = {
{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /*{{143.0438e-2, 7.095763e-2,
15.67482e-2}, {7.095763e-2, 99.65167e-2, -6.958760e-2},
{15.67482e-2, -6.958760e-2, 94.50124e-2}};*/
float mgm3softIronInverse[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
float mgm4softIronInverse[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
float mgm02variance[3] = {1, 1, 1};

View File

@ -3,12 +3,13 @@
#include <fsfw/cfdp/CfdpDistributor.h>
#include <fsfw/cfdp/handler/CfdpHandler.h>
#include <fsfw/cfdp/handler/RemoteConfigTableIF.h>
#include <fsfw/controller/ControllerBase.h>
#include <fsfw/events/EventManager.h>
#include <fsfw/health/HealthTable.h>
#include <fsfw/internalerror/InternalErrorReporter.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/pus/CService200ModeCommanding.h>
#include <fsfw/pus/CService201HealthCommanding.h>
#include <fsfw/pus/CServiceHealthCommanding.h>
#include <fsfw/pus/Service17Test.h>
#include <fsfw/pus/Service1TelecommandVerification.h>
#include <fsfw/pus/Service20ParameterManagement.h>
@ -34,6 +35,7 @@
#include "eive/definitions.h"
#include "fsfw/pus/Service11TelecommandScheduling.h"
#include "mission/cfdp/Config.h"
#include "mission/system/tree/tcsModeTree.h"
#include "objects/systemObjectList.h"
#include "tmtc/pusIds.h"
@ -109,16 +111,17 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
new UdpTcPollingTask(objects::UDP_TMTC_POLLING_TASK, objects::UDP_TMTC_SERVER);
sif::info << "Created UDP server for TMTC commanding with listener port "
<< udpBridge->getUdpPort() << std::endl;
udpBridge->setMaxNumberOfPacketsStored(150);
udpBridge->setMaxNumberOfPacketsStored(config::MAX_STORED_CMDS_UDP);
#endif
#if OBSW_ADD_TMTC_TCP_SERVER == 1
auto tcpBridge = new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR);
auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER);
TcpTmTcServer::TcpConfig cfg(true, true);
auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER, cfg);
// TCP is stream based. Use packet ID as start marker when parsing for space packets
tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID, common::CFDP_PACKET_ID});
sif::info << "Created TCP server for TMTC commanding with listener port "
<< tcpServer->getTcpPort() << std::endl;
tcpBridge->setMaxNumberOfPacketsStored(150);
tcpBridge->setMaxNumberOfPacketsStored(config::MAX_STORED_CMDS_TCP);
#endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */
#endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */
@ -127,7 +130,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
*cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50);
*pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 100);
*pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore,
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
(*cfdpFunnel)->addDestination(*udpBridge, 0);
@ -165,8 +169,9 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
pus::PUS_SERVICE_20);
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID,
pus::PUS_SERVICE_200, 8);
new CService201HealthCommanding(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID,
pus::PUS_SERVICE_201);
HealthServiceCfg healthCfg(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID, *healthTable,
20);
new CServiceHealthCommanding(healthCfg);
#if OBSW_ADD_CFDP_COMPONENTS == 1
using namespace cfdp;
@ -209,5 +214,6 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
}
void ObjectFactory::createThermalController(HeaterHandler& heaterHandler) {
new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler);
auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler);
tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
}

View File

@ -8,7 +8,7 @@ target_sources(
PDU1Handler.cpp
PDU2Handler.cpp
ACUHandler.cpp
SyrlinksHkHandler.cpp
SyrlinksHandler.cpp
Max31865PT1000Handler.cpp
Max31865EiveHandler.cpp
ImtqHandler.cpp
@ -20,7 +20,6 @@ target_sources(
SusHandler.cpp
PayloadPcduHandler.cpp
SolarArrayDeploymentHandler.cpp
ScexDeviceHandler.cpp
torquer.cpp)
ScexDeviceHandler.cpp)
add_subdirectory(devicedefinitions)

View File

@ -25,7 +25,7 @@
#include <cmath>
#include <fsfw/datapoollocal/LocalPoolVariable.tpp>
#include "mission/devices/torquer.h"
#include "mission/config/torquer.h"
static constexpr bool ACTUATION_WIRETAPPING = false;

View File

@ -1,11 +1,12 @@
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/CRC.h>
#include <mission/devices/SyrlinksHkHandler.h>
#include <mission/devices/SyrlinksHandler.h>
#include "OBSWConfig.h"
#include "mission/config/comCfg.h"
SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
power::Switch_t powerSwitch, FailureIsolationBase* customFdir)
SyrlinksHandler::SyrlinksHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
power::Switch_t powerSwitch, FailureIsolationBase* customFdir)
: DeviceHandlerBase(objectId, comIF, comCookie, customFdir),
rxDataset(this),
txDataset(this),
@ -16,29 +17,40 @@ SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, Co
}
}
SyrlinksHkHandler::~SyrlinksHkHandler() {}
SyrlinksHandler::~SyrlinksHandler() = default;
void SyrlinksHkHandler::doStartUp() {
switch (startupState) {
case StartupState::OFF: {
startupState = StartupState::ENABLE_TEMPERATURE_PROTECTION;
break;
void SyrlinksHandler::doStartUp() {
if (internalState == InternalState::OFF) {
internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION;
commandExecuted = false;
}
if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) {
if (commandExecuted) {
// Go to normal mode immediately and disable transmitter on startup.
setMode(_MODE_TO_NORMAL);
internalState = InternalState::IDLE;
commandExecuted = false;
}
case StartupState::DONE: {
setMode(_MODE_TO_ON);
break;
}
default:
break;
}
}
void SyrlinksHkHandler::doShutDown() {
setMode(_MODE_POWER_DOWN);
temperatureSet.setValidity(false, true);
void SyrlinksHandler::doShutDown() {
// In any case, always disable TX first.
if (internalState != InternalState::SET_TX_STANDBY) {
internalState = InternalState::SET_TX_STANDBY;
commandExecuted = false;
}
if (internalState == InternalState::SET_TX_STANDBY) {
if (commandExecuted) {
temperatureSet.setValidity(false, true);
internalState = InternalState::OFF;
commandExecuted = false;
setMode(_MODE_POWER_DOWN);
}
}
}
ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
switch (nextCommand) {
case (syrlinks::READ_RX_STATUS_REGISTERS):
*id = syrlinks::READ_RX_STATUS_REGISTERS;
@ -84,21 +96,41 @@ ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(DeviceCommandId_t* id)
return buildCommandFromCommand(*id, nullptr, 0);
}
ReturnValue_t SyrlinksHkHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
switch (startupState) {
case StartupState::ENABLE_TEMPERATURE_PROTECTION: {
ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
switch (internalState) {
case InternalState::ENABLE_TEMPERATURE_PROTECTION: {
*id = syrlinks::WRITE_LCL_CONFIG;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SET_TX_MODULATION: {
*id = syrlinks::SET_TX_MODE_MODULATION;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SELECT_MODULATION_BPSK: {
*id = syrlinks::SET_WAVEFORM_BPSK;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SELECT_MODULATION_0QPSK: {
*id = syrlinks::SET_WAVEFORM_0QPSK;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SET_TX_CW: {
*id = syrlinks::SET_TX_MODE_CW;
return buildCommandFromCommand(*id, nullptr, 0);
}
case InternalState::SET_TX_STANDBY: {
*id = syrlinks::SET_TX_MODE_STANDBY;
return buildCommandFromCommand(*id, nullptr, 0);
}
default:
break;
}
return NOTHING_TO_SEND;
}
ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
ReturnValue_t SyrlinksHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
switch (deviceCommand) {
case (syrlinks::RESET_UNIT): {
prepareCommand(resetCommand, deviceCommand);
@ -160,11 +192,11 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic
prepareCommand(tempBasebandBoardLowByte, deviceCommand);
return returnvalue::OK;
}
case (syrlinks::CONFIG_BPSK): {
case (syrlinks::SET_WAVEFORM_BPSK): {
prepareCommand(configBPSK, deviceCommand);
return returnvalue::OK;
}
case (syrlinks::CONFIG_OQPSK): {
case (syrlinks::SET_WAVEFORM_0QPSK): {
prepareCommand(configOQPSK, deviceCommand);
return returnvalue::OK;
}
@ -184,7 +216,7 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic
return returnvalue::FAILED;
}
void SyrlinksHkHandler::fillCommandAndReplyMap() {
void SyrlinksHandler::fillCommandAndReplyMap() {
this->insertInCommandAndReplyMap(syrlinks::RESET_UNIT, 1, nullptr, syrlinks::ACK_SIZE, false,
true, syrlinks::ACK_REPLY);
this->insertInCommandAndReplyMap(syrlinks::SET_TX_MODE_STANDBY, 1, nullptr, syrlinks::ACK_SIZE,
@ -195,10 +227,10 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() {
true, syrlinks::ACK_REPLY);
this->insertInCommandAndReplyMap(syrlinks::WRITE_LCL_CONFIG, 1, nullptr, syrlinks::ACK_SIZE,
false, true, syrlinks::ACK_REPLY);
this->insertInCommandAndReplyMap(syrlinks::CONFIG_BPSK, 1, nullptr, syrlinks::ACK_SIZE, false,
true, syrlinks::ACK_REPLY);
this->insertInCommandAndReplyMap(syrlinks::CONFIG_OQPSK, 1, nullptr, syrlinks::ACK_SIZE, false,
true, syrlinks::ACK_REPLY);
this->insertInCommandAndReplyMap(syrlinks::SET_WAVEFORM_BPSK, 1, nullptr, syrlinks::ACK_SIZE,
false, true, syrlinks::ACK_REPLY);
this->insertInCommandAndReplyMap(syrlinks::SET_WAVEFORM_0QPSK, 1, nullptr, syrlinks::ACK_SIZE,
false, true, syrlinks::ACK_REPLY);
this->insertInCommandMap(syrlinks::ENABLE_DEBUG);
this->insertInCommandMap(syrlinks::DISABLE_DEBUG);
this->insertInCommandAndReplyMap(syrlinks::READ_LCL_CONFIG, 1, nullptr,
@ -223,8 +255,8 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() {
syrlinks::RX_STATUS_REGISTERS_REPLY_SIZE);
}
ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
ReturnValue_t SyrlinksHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
ReturnValue_t result = returnvalue::OK;
if (*start != '<') {
@ -254,7 +286,7 @@ ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t* start, size_t remai
return result;
}
ReturnValue_t SyrlinksHkHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) {
ReturnValue_t SyrlinksHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) {
if (powerSwitch == power::NO_SWITCH) {
return DeviceHandlerBase::NO_SWITCH;
}
@ -263,7 +295,7 @@ ReturnValue_t SyrlinksHkHandler::getSwitches(const uint8_t** switches, uint8_t*
return returnvalue::OK;
}
ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
ReturnValue_t result;
switch (id) {
@ -414,7 +446,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons
return returnvalue::OK;
}
LocalPoolDataSetBase* SyrlinksHkHandler::getDataSetHandle(sid_t sid) {
LocalPoolDataSetBase* SyrlinksHandler::getDataSetHandle(sid_t sid) {
if (sid == rxDataset.getSid()) {
return &rxDataset;
} else if (sid == txDataset.getSid()) {
@ -427,13 +459,13 @@ LocalPoolDataSetBase* SyrlinksHkHandler::getDataSetHandle(sid_t sid) {
}
}
std::string SyrlinksHkHandler::convertUint16ToHexString(uint16_t intValue) {
std::string SyrlinksHandler::convertUint16ToHexString(uint16_t intValue) {
std::stringstream stream;
stream << std::setfill('0') << std::setw(4) << std::hex << std::uppercase << intValue;
return stream.str();
}
uint8_t SyrlinksHkHandler::convertHexStringToUint8(const char* twoChars) {
uint8_t SyrlinksHandler::convertHexStringToUint8(const char* twoChars) {
uint32_t value;
std::string hexString(twoChars, 2);
std::stringstream stream;
@ -442,13 +474,13 @@ uint8_t SyrlinksHkHandler::convertHexStringToUint8(const char* twoChars) {
return static_cast<uint8_t>(value);
}
uint16_t SyrlinksHkHandler::convertHexStringToUint16(const char* fourChars) {
uint16_t SyrlinksHandler::convertHexStringToUint16(const char* fourChars) {
uint16_t value = 0;
value = convertHexStringToUint8(fourChars) << 8 | convertHexStringToUint8(fourChars + 2);
return value;
}
ReturnValue_t SyrlinksHkHandler::parseReplyStatus(const char* status) {
ReturnValue_t SyrlinksHandler::parseReplyStatus(const char* status) {
switch (*status) {
case '0':
return returnvalue::OK;
@ -480,7 +512,7 @@ ReturnValue_t SyrlinksHkHandler::parseReplyStatus(const char* status) {
}
}
ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size) {
ReturnValue_t SyrlinksHandler::verifyReply(const uint8_t* packet, uint8_t size) {
int result = 0;
/* Calculate crc from received packet */
uint16_t crc =
@ -500,7 +532,7 @@ ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size
return returnvalue::OK;
}
void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) {
void SyrlinksHandler::parseRxStatusRegistersReply(const uint8_t* packet) {
PoolReadGuard readHelper(&rxDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
rxDataset.rxStatus = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
@ -540,7 +572,7 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) {
}
}
void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) {
void SyrlinksHandler::parseLclConfigReply(const uint8_t* packet) {
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
uint8_t lclConfig = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
if (debugMode) {
@ -549,7 +581,7 @@ void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) {
}
}
void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) {
void SyrlinksHandler::parseTxStatusReply(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
txDataset.txStatus = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
@ -560,7 +592,7 @@ void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) {
}
}
void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) {
void SyrlinksHandler::parseTxWaveformReply(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
txDataset.txWaveform = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
@ -571,7 +603,7 @@ void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) {
}
}
void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) {
void SyrlinksHandler::parseAgcLowByte(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
txDataset.txAgcValue = agcValueHighByte << 8 |
@ -582,18 +614,18 @@ void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) {
}
}
void SyrlinksHkHandler::parseAgcHighByte(const uint8_t* packet) {
void SyrlinksHandler::parseAgcHighByte(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
agcValueHighByte = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
}
void SyrlinksHkHandler::setNormalDatapoolEntriesInvalid() {}
void SyrlinksHandler::setNormalDatapoolEntriesInvalid() {}
uint32_t SyrlinksHkHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; }
ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(syrlinks::RX_STATUS, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(syrlinks::RX_SENSITIVITY, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(syrlinks::RX_FREQUENCY_SHIFT, new PoolEntry<int32_t>({0}));
@ -618,26 +650,162 @@ ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& lo
return returnvalue::OK;
}
void SyrlinksHkHandler::setModeNormal() { setMode(MODE_NORMAL); }
void SyrlinksHandler::setModeNormal() { setMode(MODE_NORMAL); }
float SyrlinksHkHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; }
float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; }
ReturnValue_t SyrlinksHkHandler::handleAckReply(const uint8_t* packet) {
ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
ReturnValue_t result =
parseReplyStatus(reinterpret_cast<const char*>(packet + syrlinks::MESSAGE_HEADER_SIZE));
if (rememberCommandId == syrlinks::WRITE_LCL_CONFIG and result != returnvalue::OK) {
startupState = StartupState::OFF;
} else if (rememberCommandId == syrlinks::WRITE_LCL_CONFIG and result == returnvalue::OK) {
startupState = StartupState::DONE;
switch (rememberCommandId) {
case (syrlinks::WRITE_LCL_CONFIG): {
if (isTransitionalMode()) {
if (result != returnvalue::OK) {
internalState = InternalState::OFF;
} else if (result == returnvalue::OK) {
commandExecuted = true;
}
}
break;
}
case (syrlinks::SET_WAVEFORM_BPSK):
case (syrlinks::SET_WAVEFORM_0QPSK):
case (syrlinks::SET_TX_MODE_STANDBY):
case (syrlinks::SET_TX_MODE_MODULATION):
case (syrlinks::SET_TX_MODE_CW): {
if (result == returnvalue::OK and isTransitionalMode()) {
commandExecuted = true;
}
break;
}
}
switch (rememberCommandId) {
case (syrlinks::SET_TX_MODE_STANDBY): {
triggerEvent(syrlinks::TX_OFF, 0, 0);
break;
}
case (syrlinks::SET_TX_MODE_MODULATION):
case (syrlinks::SET_TX_MODE_CW): {
triggerEvent(syrlinks::TX_ON, getSubmode(), static_cast<uint8_t>(com::getCurrentDatarate()));
break;
}
}
return result;
}
void SyrlinksHkHandler::prepareCommand(std::string command, DeviceCommandId_t commandId) {
ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
if (submode >= com::Submode::NUM_SUBMODES) {
return HasModesIF::INVALID_SUBMODE;
}
return returnvalue::OK;
}
return DeviceHandlerBase::isModeCombinationValid(mode, submode);
}
ReturnValue_t SyrlinksHandler::getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues,
uint16_t startAtIndex) {
return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues,
startAtIndex);
}
void SyrlinksHandler::prepareCommand(std::string command, DeviceCommandId_t commandId) {
command.copy(reinterpret_cast<char*>(commandBuffer), command.size(), 0);
rawPacketLen = command.size();
rememberCommandId = commandId;
rawPacket = commandBuffer;
}
void SyrlinksHkHandler::setDebugMode(bool enable) { this->debugMode = enable; }
void SyrlinksHandler::setDebugMode(bool enable) { this->debugMode = enable; }
void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
Mode_t tgtMode = getBaseMode(getMode());
auto commandDone = [&]() {
setMode(tgtMode);
internalState = InternalState::IDLE;
};
auto txOnHandler = [&](InternalState selMod) {
if (internalState == InternalState::IDLE) {
commandExecuted = false;
internalState = selMod;
}
// Select modulation first (BPSK or 0QPSK).
if (internalState == selMod) {
if (commandExecuted) {
internalState = InternalState::SET_TX_MODULATION;
commandExecuted = false;
}
}
// Now go into modulation mode.
if (internalState == InternalState::SET_TX_MODULATION) {
if (commandExecuted) {
commandDone();
return true;
}
}
return false;
};
auto txStandbyHandler = [&]() {
if (internalState == InternalState::IDLE) {
internalState = InternalState::SET_TX_STANDBY;
commandExecuted = false;
}
if (internalState == InternalState::SET_TX_STANDBY) {
if (commandExecuted) {
commandDone();
return;
}
}
};
if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) {
switch (getSubmode()) {
case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): {
auto currentDatarate = com::getCurrentDatarate();
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
return;
}
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
return;
}
}
break;
}
case (com::Submode::RX_AND_TX_LOW_DATARATE): {
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
return;
}
break;
}
case (com::Submode::RX_AND_TX_HIGH_DATARATE): {
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
return;
}
break;
}
case (com::Submode::RX_ONLY): {
txStandbyHandler();
return;
}
case (com::Submode::RX_AND_TX_CW): {
if (internalState == InternalState::IDLE) {
internalState = InternalState::SET_TX_STANDBY;
commandExecuted = false;
}
if (commandExecuted) {
commandDone();
return;
}
break;
}
default: {
commandDone();
}
}
} else if (tgtMode == HasModesIF::MODE_OFF) {
txStandbyHandler();
}
}

View File

@ -1,5 +1,5 @@
#ifndef MISSION_DEVICES_SYRLINKSHKHANDLER_H_
#define MISSION_DEVICES_SYRLINKSHKHANDLER_H_
#ifndef MISSION_DEVICES_SYRLINKSHANDLER_H_
#define MISSION_DEVICES_SYRLINKSHANDLER_H_
#include <string.h>
@ -7,6 +7,7 @@
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/timemanager/Countdown.h"
#include "fsfw_hal/linux/gpio/Gpio.h"
#include "mission/comDefs.h"
#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h"
#include "returnvalues/classIds.h"
@ -18,11 +19,11 @@
*
* @author J. Meier
*/
class SyrlinksHkHandler : public DeviceHandlerBase {
class SyrlinksHandler : public DeviceHandlerBase {
public:
SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
power::Switch_t powerSwitch, FailureIsolationBase* customFdir);
virtual ~SyrlinksHkHandler();
SyrlinksHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
power::Switch_t powerSwitch, FailureIsolationBase* customFdir);
virtual ~SyrlinksHandler();
/**
* @brief Sets mode to MODE_NORMAL. Can be used for debugging.
@ -34,6 +35,8 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
protected:
void doStartUp() override;
void doShutDown() override;
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
@ -49,6 +52,10 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
LocalDataPoolManager& poolManager) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
// Parameter IF
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::SYRLINKS_HANDLER;
@ -104,12 +111,22 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
uint16_t rawTempBasebandBoard = 0;
float tempPowerAmplifier = 0;
float tempBasebandBoard = 0;
bool commandExecuted = false;
uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE];
enum class StartupState { OFF, ENABLE_TEMPERATURE_PROTECTION, DONE };
enum class InternalState {
OFF,
ENABLE_TEMPERATURE_PROTECTION,
SELECT_MODULATION_BPSK,
SELECT_MODULATION_0QPSK,
SET_TX_MODULATION,
SET_TX_CW,
SET_TX_STANDBY,
IDLE
};
StartupState startupState = StartupState::OFF;
InternalState internalState = InternalState::OFF;
/**
* This object is used to store the id of the next command to execute. This controls the
@ -216,7 +233,7 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
};
template <typename T>
T SyrlinksHkHandler::convertHexStringTo32bit(const char* characters, uint8_t numberOfChars) {
T SyrlinksHandler::convertHexStringTo32bit(const char* characters, uint8_t numberOfChars) {
if (sizeof(T) < 4) {
sif::error << "SyrlinksHkHandler::convertHexStringToRaw: Only works for 32-bit conversion"
<< std::endl;
@ -244,4 +261,4 @@ T SyrlinksHkHandler::convertHexStringTo32bit(const char* characters, uint8_t num
return 0;
}
}
#endif /* MISSION_DEVICES_SYRLINKSHKHANDLER_H_ */
#endif /* MISSION_DEVICES_SYRLINKSHANDLER_H_ */

View File

@ -6,9 +6,15 @@
namespace syrlinks {
enum class ParameterId : uint8_t { DATARATE = 0 };
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYRLINKS;
static constexpr Event FDIR_REACTION_IGNORED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
//! [EXPORT] : [COMMENT] Transmitter is on now. P1: Submode, P2: Current default datarate.
static constexpr Event TX_ON = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
//! [EXPORT] : [COMMENT] Transmitter is off now.
static constexpr Event TX_OFF = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
static const DeviceCommandId_t NONE = 0;
static const DeviceCommandId_t RESET_UNIT = 1;
@ -31,9 +37,9 @@ static const DeviceCommandId_t TEMP_POWER_AMPLIFIER_HIGH_BYTE = 13;
static const DeviceCommandId_t TEMP_POWER_AMPLIFIER_LOW_BYTE = 14;
static const DeviceCommandId_t TEMP_BASEBAND_BOARD_HIGH_BYTE = 15;
static const DeviceCommandId_t TEMP_BASEBAND_BOARD_LOW_BYTE = 16;
static const DeviceCommandId_t CONFIG_OQPSK = 17;
static const DeviceCommandId_t SET_WAVEFORM_0QPSK = 17;
// After startup syrlinks always in BSPK configuration
static const DeviceCommandId_t CONFIG_BPSK = 18;
static const DeviceCommandId_t SET_WAVEFORM_BPSK = 18;
static const DeviceCommandId_t ENABLE_DEBUG = 20;
static const DeviceCommandId_t DISABLE_DEBUG = 21;

View File

@ -1,5 +1,48 @@
#include "ComSubsystem.h"
#include <fsfw/ipc/MutexGuard.h>
#include "mission/config/comCfg.h"
ComSubsystem::ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {}
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables), paramHelper(this) {
com::setCurrentDatarate(com::Datarate::LOW_RATE_MODULATION_BPSK);
}
MessageQueueId_t ComSubsystem::getCommandQueue() const { return Subsystem::getCommandQueue(); }
ReturnValue_t ComSubsystem::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) {
if ((domainId == 0) and (uniqueIdentifier == static_cast<uint8_t>(com::ParameterId::DATARATE))) {
uint8_t newVal = 0;
ReturnValue_t result = newValues->getElement(&newVal);
if (result != returnvalue::OK) {
return result;
}
if (newVal >= static_cast<uint8_t>(com::Datarate::NUM_DATARATES)) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(datarateCfg);
com::setCurrentDatarate(static_cast<com::Datarate>(newVal));
return returnvalue::OK;
}
return returnvalue::OK;
}
ReturnValue_t ComSubsystem::handleCommandMessage(CommandMessage *message) {
ReturnValue_t result = paramHelper.handleParameterMessage(message);
if (result == returnvalue::OK) {
return result;
}
return Subsystem::handleCommandMessage(message);
}
ReturnValue_t ComSubsystem::initialize() {
ReturnValue_t result = paramHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
return Subsystem::initialize();
}

View File

@ -1,13 +1,29 @@
#ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_
#define MISSION_SYSTEM_COMSUBSYSTEM_H_
#include <fsfw/parameters/HasParametersIF.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/subsystem/Subsystem.h>
class ComSubsystem : public Subsystem {
#include "mission/comDefs.h"
class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF {
public:
ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
virtual ~ComSubsystem() = default;
MessageQueueId_t getCommandQueue() const override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
uint16_t startAtIndex) override;
private:
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
ReturnValue_t initialize() override;
uint8_t datarateCfg = static_cast<uint8_t>(com::Datarate::LOW_RATE_MODULATION_BPSK);
ParameterHelper paramHelper;
};
#endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */

View File

@ -1,2 +1,4 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE acsModeTree.cpp payloadModeTree.cpp
tcsModeTree.cpp system.cpp util.cpp)
target_sources(
${LIB_EIVE_MISSION}
PRIVATE acsModeTree.cpp payloadModeTree.cpp comModeTree.cpp tcsModeTree.cpp
system.cpp util.cpp)

View File

@ -0,0 +1,281 @@
#include "comModeTree.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/returnvalues/returnvalue.h>
#include <fsfw/subsystem/Subsystem.h>
#include "eive/objects.h"
#include "mission/comDefs.h"
#include "util.h"
const auto check = subsystem::checkInsert;
ComSubsystem satsystem::com::SUBSYSTEM = ComSubsystem(objects::COM_SUBSYSTEM, 12, 24);
static const auto OFF = HasModesIF::MODE_OFF;
static const auto ON = HasModesIF::MODE_ON;
static const auto NML = DeviceHandlerIF::MODE_NORMAL;
auto COM_SEQUENCE_RX_ONLY =
std::make_pair(::com::Submode::RX_ONLY, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TGT =
std::make_pair((::com::Submode::RX_ONLY << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_0 =
std::make_pair((::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_1 =
std::make_pair((::com::Submode::RX_ONLY << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_SEQUENCE_RX_AND_TX_LOW_RATE =
std::make_pair(::com::Submode::RX_AND_TX_LOW_DATARATE, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TGT = std::make_pair(
(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 = std::make_pair(
(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 = std::make_pair(
(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE =
std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TGT = std::make_pair(
(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 = std::make_pair(
(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 = std::make_pair(
(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE =
std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT = std::make_pair(
(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 = std::make_pair(
(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 = std::make_pair(
(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
namespace {
void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh);
void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh);
void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh);
void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh);
} // namespace
void satsystem::com::init() {
ModeListEntry entry;
buildRxOnlySequence(SUBSYSTEM, entry);
buildTxAndRxLowRateSequence(SUBSYSTEM, entry);
buildTxAndRxHighRateSequence(SUBSYSTEM, entry);
buildTxAndRxDefaultRateSequence(SUBSYSTEM, entry);
SUBSYSTEM.setInitialMode(NML, ::com::Submode::RX_ONLY);
}
namespace {
void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::com::buildRxOnlySequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
// Build RX Only table. We could track the state of the CCSDS IP core handler
// as well but I do not think this is necessary because enabling that should
// not intefere with the Syrlinks Handler.
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TGT.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TGT.first, &COM_TABLE_RX_ONLY_TGT.second)), ctxc);
// Build RX Only transition 0
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TRANS_0.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_0.first, &COM_TABLE_RX_ONLY_TRANS_0.second)),
ctxc);
// Build RX Only transition 1
iht(objects::CCSDS_HANDLER, OFF, 0, COM_TABLE_RX_ONLY_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_1.first, &COM_TABLE_RX_ONLY_TRANS_1.second)),
ctxc);
// Build TX OFF sequence
ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TGT.first, 0, true);
ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TRANS_0.first, 0, false);
ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TRANS_1.first, 0, false);
check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_ONLY.first, &COM_SEQUENCE_RX_ONLY.second,
COM_SEQUENCE_RX_ONLY.first)),
ctxc);
}
void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::com::buildTxAndRxLowRateSequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
// Build RX and TX low datarate table.
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE,
COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second);
iht(objects::CCSDS_HANDLER, ON, static_cast<Submode_t>(::com::CcsdsSubmode::DATARATE_LOW),
COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TGT.first,
&COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second)),
ctxc);
// Build TX and RX low datarate transition 0, switch CCSDS handler first
iht(objects::CCSDS_HANDLER, ON, static_cast<Submode_t>(::com::CcsdsSubmode::DATARATE_LOW),
COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.first,
&COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.second)),
ctxc);
// Build TX and RX low transition 1
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE,
COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first,
&COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)),
ctxc);
// Build TX and RX low datarate sequence
ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TGT.first, 0, true);
ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.first, 0, false);
ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first, 0, false);
check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_LOW_RATE.first,
&COM_SEQUENCE_RX_AND_TX_LOW_RATE.second,
COM_SEQUENCE_RX_ONLY.first)),
ctxc);
}
void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::com::buildTxAndRxHighRateSequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
// Build RX and TX high datarate table.
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE,
COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second);
iht(objects::CCSDS_HANDLER, ON, static_cast<Submode_t>(::com::CcsdsSubmode::DATARATE_HIGH),
COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.first,
&COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second)),
ctxc);
// Build TX and RX high datarate transition 0, switch CCSDS handler first
iht(objects::CCSDS_HANDLER, ON, static_cast<Submode_t>(::com::CcsdsSubmode::DATARATE_HIGH),
COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.first,
&COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.second)),
ctxc);
// Build TX and RX high transition 1
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE,
COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first,
&COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)),
ctxc);
// Build TX and RX low datarate sequence
ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.first, 0, true);
ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.first, 0,
false);
ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first, 0,
false);
check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.first,
&COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second,
COM_SEQUENCE_RX_ONLY.first)),
ctxc);
}
void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::com::buildTxAndRxDefaultRateSequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
// Build RX and TX default datarate table.
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE,
COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second);
iht(objects::CCSDS_HANDLER, ON, static_cast<Submode_t>(::com::CcsdsSubmode::DATARATE_DEFAULT),
COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.first,
&COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second)),
ctxc);
// Build TX and RX low datarate transition 0, switch CCSDS handler first
iht(objects::CCSDS_HANDLER, ON, static_cast<Submode_t>(::com::CcsdsSubmode::DATARATE_DEFAULT),
COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.first,
&COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.second)),
ctxc);
// Build TX and RX default transition 1
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE,
COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first,
&COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)),
ctxc);
// Build TX and RX default datarate sequence
ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.first, 0,
true);
ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.first, 0,
false);
ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first, 0,
false);
check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.first,
&COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second,
COM_SEQUENCE_RX_ONLY.first)),
ctxc);
}
} // namespace

View File

@ -0,0 +1,16 @@
#ifndef MISSION_SYSTEM_TREE_COMMODETREE_H_
#define MISSION_SYSTEM_TREE_COMMODETREE_H_
#include <mission/system/objects/ComSubsystem.h>
namespace satsystem {
namespace com {
extern ComSubsystem SUBSYSTEM;
void init();
} // namespace com
} // namespace satsystem
#endif /* MISSION_SYSTEM_TREE_COMMODETREE_H_ */

View File

@ -1,6 +1,7 @@
#include "system.h"
#include "acsModeTree.h"
#include "comModeTree.h"
#include "payloadModeTree.h"
#include "tcsModeTree.h"
@ -8,4 +9,5 @@ void satsystem::init() {
acs::init();
pl::init();
tcs::init();
com::init();
}

View File

@ -1,7 +1,6 @@
#ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_
#define MISSION_SYSTEM_TREE_TCSMODETREE_H_
class Subsystem;
#include <fsfw/subsystem/Subsystem.h>
namespace satsystem {
namespace tcs {

View File

@ -1,7 +1,9 @@
#include "CcsdsIpCoreHandler.h"
#include <fsfw/subsystem/helper.h>
#include <linux/ipcore/PdecHandler.h>
#include <linux/ipcore/PtmeConfig.h>
#include <mission/config/comCfg.h>
#include "eive/definitions.h"
#include "fsfw/events/EventManagerIF.h"
@ -21,6 +23,7 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId,
tcDestination(tcDestination),
parameterHelper(this),
actionHelper(this, nullptr),
modeHelper(this),
ptmeConfig(ptmeConfig),
gpioIF(gpioIF),
enTxClock(enTxClock),
@ -81,6 +84,11 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
return result;
}
result = modeHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
VirtualChannelMapIter iter;
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
result = iter->second->initialize();
@ -127,10 +135,12 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
transmitterCountdown.setTimeout(transmitterTimeout);
transmitterCountdown.timeOut();
#if OBSW_SYRLINKS_SIMULATED == 1
// Update data on rising edge
ptmeConfig->invertTxClock(false);
transmitterCountdown.setTimeout(transmitterTimeout);
linkState = UP;
forwardLinkstate();
#endif /* OBSW_SYRLINKS_SIMULATED == 1*/
@ -152,6 +162,10 @@ void CcsdsIpCoreHandler::readCommandQueue(void) {
if (result == returnvalue::OK) {
return;
}
result = modeHelper.handleModeCommand(&commandMessage);
if (result == returnvalue::OK) {
return;
}
CommandMessage reply;
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
commandQueue->reply(&reply);
@ -218,10 +232,12 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
ReturnValue_t result = returnvalue::OK;
switch (actionId) {
case SET_LOW_RATE: {
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW);
result = ptmeConfig->setRate(RATE_100KBPS);
break;
}
case SET_HIGH_RATE: {
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH);
result = ptmeConfig->setRate(RATE_500KBPS);
break;
}
@ -233,10 +249,16 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
}
case EN_TRANSMITTER: {
enableTransmit();
if (mode == HasModesIF::MODE_OFF) {
mode = HasModesIF::MODE_ON;
}
return EXECUTION_FINISHED;
}
case DISABLE_TRANSMITTER: {
disableTransmit();
if (mode == HasModesIF::MODE_ON) {
mode = HasModesIF::MODE_OFF;
}
return EXECUTION_FINISHED;
}
case ENABLE_TX_CLK_MANIPULATOR: {
@ -328,6 +350,9 @@ void CcsdsIpCoreHandler::enableTransmit() {
gpioIF->pullHigh(enTxClock);
gpioIF->pullHigh(enTxData);
#endif
linkState = UP;
forwardLinkstate();
transmitterCountdown.resetTimer();
}
void CcsdsIpCoreHandler::checkTxTimer() {
@ -336,9 +361,69 @@ void CcsdsIpCoreHandler::checkTxTimer() {
}
if (transmitterCountdown.hasTimedOut()) {
disableTransmit();
// TODO: set mode to off (move timer to subsystem)
}
}
void CcsdsIpCoreHandler::getMode(Mode_t* mode, Submode_t* submode) {
*mode = this->mode;
*submode = this->submode;
}
ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if (mode == HasModesIF::MODE_ON) {
if (submode != static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH) and
submode != static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW) and
submode != static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
return HasModesIF::INVALID_SUBMODE;
}
} else if (mode != HasModesIF::MODE_OFF) {
return returnvalue::FAILED;
}
*msToReachTheMode = 2000;
return returnvalue::OK;
}
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
auto rateHigh = [&]() {
ReturnValue_t result = ptmeConfig->setRate(RATE_500KBPS);
if (result == returnvalue::OK) {
this->mode = HasModesIF::MODE_ON;
}
};
auto rateLow = [&]() {
ReturnValue_t result = ptmeConfig->setRate(RATE_100KBPS);
if (result == returnvalue::OK) {
this->mode = HasModesIF::MODE_ON;
}
};
if (mode == HasModesIF::MODE_ON) {
enableTransmit();
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
com::Datarate currentDatarate = com::getCurrentDatarate();
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
rateLow();
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
rateHigh();
}
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
rateHigh();
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
rateLow();
}
} else if (mode == HasModesIF::MODE_OFF) {
disableTransmit();
this->mode = HasModesIF::MODE_OFF;
}
this->submode = submode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
void CcsdsIpCoreHandler::disableTransmit() {
#ifndef TE0720_1CFA
gpioIF->pullLow(enTxClock);
@ -346,7 +431,19 @@ void CcsdsIpCoreHandler::disableTransmit() {
#endif
linkState = DOWN;
forwardLinkstate();
transmitterCountdown.setTimeout(0);
transmitterCountdown.timeOut();
}
const char* CcsdsIpCoreHandler::getName() const { return "CCSDS Handler"; }
const HasHealthIF* CcsdsIpCoreHandler::getOptHealthIF() const { return nullptr; }
const HasModesIF& CcsdsIpCoreHandler::getModeIF() const { return *this; }
ReturnValue_t CcsdsIpCoreHandler::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
}
ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; }
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }

View File

@ -1,6 +1,8 @@
#ifndef CCSDSHANDLER_H_
#define CCSDSHANDLER_H_
#include <fsfw/modes/HasModesIF.h>
#include <cstdint>
#include <unordered_map>
@ -13,6 +15,7 @@
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/parameters/ParameterHelper.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/timemanager/Countdown.h"
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
@ -20,6 +23,7 @@
#include "fsfw_hal/common/gpio/GpioIF.h"
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
#include "linux/ipcore/PtmeConfig.h"
#include "mission/comDefs.h"
/**
* @brief This class handles the data exchange with the CCSDS IP cores implemented in the
@ -32,6 +36,9 @@
*/
class CcsdsIpCoreHandler : public SystemObject,
public ExecutableObjectIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF,
public HasModesIF,
public AcceptsTelemetryIF,
public AcceptsTelecommandsIF,
public ReceivesParameterMessagesIF,
@ -59,7 +66,14 @@ class CcsdsIpCoreHandler : public SystemObject,
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t initialize();
MessageQueueId_t getCommandQueue() const;
MessageQueueId_t getCommandQueue() const override;
// ModesIF
void getMode(Mode_t* mode, Submode_t* submode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
void startTransition(Mode_t mode, Submode_t submode) override;
void announceMode(bool recursive) override;
/**
* @brief Function to add a virtual channel
@ -80,6 +94,11 @@ class CcsdsIpCoreHandler : public SystemObject,
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
const HasHealthIF* getOptHealthIF() const override;
const HasModesIF& getModeIF() const override;
object_id_t getObjectId() const override;
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
ModeTreeChildIF& getModeTreeChildIF() override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER;
@ -126,6 +145,9 @@ class CcsdsIpCoreHandler : public SystemObject,
ParameterHelper parameterHelper;
ActionHelper actionHelper;
Mode_t mode = HasModesIF::MODE_OFF;
Submode_t submode = static_cast<Submode_t>(com::CcsdsSubmode::UNSET);
ModeHelper modeHelper;
MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE;