diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 2c1179d9..eab396c6 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -110,7 +110,7 @@ void initmission::initTasks() { // If a command has not been read before the next one arrives, the old command will be // overwritten by the PDEC. PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask( - "PDEC_HANDLER", 10, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + "PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.6, missedDeadlineFunc); result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); diff --git a/linux/obc/CMakeLists.txt b/linux/obc/CMakeLists.txt index 371ea7cd..4119624c 100644 --- a/linux/obc/CMakeLists.txt +++ b/linux/obc/CMakeLists.txt @@ -3,6 +3,7 @@ target_sources(${TARGET_NAME} PUBLIC Ptme.cpp PdecHandler.cpp PdecConfig.cpp + PtmeRateSetter.cpp ) diff --git a/linux/obc/PtmeRateSetter.cpp b/linux/obc/PtmeRateSetter.cpp new file mode 100644 index 00000000..92886623 --- /dev/null +++ b/linux/obc/PtmeRateSetter.cpp @@ -0,0 +1,27 @@ +#include "PtmeRateSetter.h" +#include "fsfw/serviceinterface/ServiceInterface.h" + +PtmeRateSetter::PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif) : + bitrateSel(bitrateSel), gpioif(gpioif) { +} + +PtmeRateSetter::~PtmeRateSetter() { +} + +ReturnValue_t PtmeRateSetter::setRate(BitRates rate) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + switch(rate) { + case RATE_2000KHZ: + result = gpioif->pullHigh(bitrateSel); + break; + case RATE_400KHZ: + result = gpioif->pullLow(bitrateSel); + break; + default: + sif::debug << "PtmeRateSetter::setRate: Invalid rate" << std::endl; + result = HasReturnvaluesIF::RETURN_FAILED; + break; + } + return result; +} + diff --git a/linux/obc/PtmeRateSetter.h b/linux/obc/PtmeRateSetter.h new file mode 100644 index 00000000..ece78e91 --- /dev/null +++ b/linux/obc/PtmeRateSetter.h @@ -0,0 +1,40 @@ +#ifndef LINUX_OBC_PTMERATESETTER_H_ +#define LINUX_OBC_PTMERATESETTER_H_ + +#include "TxRateSetterIF.h" +#include "fsfw_hal/common/gpio/gpioDefinitions.h" +#include "fsfw_hal/common/gpio/GpioIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +/** + * @brief Class to set the downlink bit rate by using the cadu_rate_switcher implemented in + * the programmable logic. + * + * @details The cadu_rate_switcher module sets the input rate to the syrlinks transceiver either + * to 2000 kHz (bitrateSel = 1) or 400 kHz (bitrate = 0). + * + * @author J. Meier + */ +class PtmeRateSetter: public TxRateSetterIF { +public: + + /** + * @brief Constructor + * + * @param bitrateSel GPIO ID of the GPIO connected to the bitrate_sel input of the + * cadu_rate_switcher. + * @param gpioif GPIO interface to drive the bitrateSel GPIO + */ + PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif); + virtual ~PtmeRateSetter(); + + virtual ReturnValue_t setRate(BitRates rate); + +private: + + gpioId_t bitrateSel = gpio::NO_GPIO; + + GpioIF* gpioif = nullptr; +}; + +#endif /* LINUX_OBC_PTMERATESETTER_H_ */ diff --git a/linux/obc/TxRateSetterIF.h b/linux/obc/TxRateSetterIF.h new file mode 100644 index 00000000..c07106e4 --- /dev/null +++ b/linux/obc/TxRateSetterIF.h @@ -0,0 +1,25 @@ +#ifndef LINUX_OBC_TXRATESETTERIF_H_ +#define LINUX_OBC_TXRATESETTERIF_H_ + +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +enum BitRates : uint32_t { + RATE_2000KHZ, + RATE_400KHZ +}; + +/** + * @brief Abstract class for objects implementing the functionality to switch the + * downlink bit rate. + * + * @author J. Meier + */ +class TxRateSetterIF { +public: + TxRateSetterIF() {}; + virtual ~TxRateSetterIF() {}; + + virtual ReturnValue_t setRate(BitRates bitRate) = 0; +}; + +#endif /* LINUX_OBC_TXRATESETTERIF_H_ */ diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CCSDSHandler.cpp index ad630044..caf99515 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CCSDSHandler.cpp @@ -5,8 +5,10 @@ #include "CCSDSHandler.h" -CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination) : - SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this) { +CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, + TxRateSetterIF* txRateSetterIF) : + SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this), actionHelper( + this, nullptr), txRateSetterIF(txRateSetterIF) { commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); } @@ -55,6 +57,11 @@ ReturnValue_t CCSDSHandler::initialize() { return result; } + result = actionHelper.initialize(commandQueue); + if (result != RETURN_OK) { + return result; + } + VirtualChannelMapIter iter; for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { result = iter->second->initialize(); @@ -77,10 +84,15 @@ void CCSDSHandler::readCommandQueue(void) { if (result == RETURN_OK) { return; } + result = actionHelper.handleActionMessage(&commandMessage); + if (result == RETURN_OK) { + return; + } CommandMessage reply; reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand()); commandQueue->reply(&reply); + return; } } @@ -140,3 +152,18 @@ MessageQueueId_t CCSDSHandler::getRequestQueue() { // Forward packets directly to TC distributor return tcDistributorQueueId; } + +ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + + switch(actionId) { + case SET_LOW_RATE: + txRateSetterIF->setRate(BitRates::RATE_400KHZ); + return EXECUTION_FINISHED; + case SET_HIGH_RATE: + txRateSetterIF->setRate(BitRates::RATE_2000KHZ); + return EXECUTION_FINISHED; + default: + return COMMAND_NOT_IMPLEMENTED; + } +} diff --git a/mission/tmtc/CCSDSHandler.h b/mission/tmtc/CCSDSHandler.h index b1c3dd60..6ed5abbe 100644 --- a/mission/tmtc/CCSDSHandler.h +++ b/mission/tmtc/CCSDSHandler.h @@ -8,6 +8,9 @@ #include "fsfw/tmtcservices/AcceptsTelemetryIF.h" #include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" #include "fsfw/parameters/ParameterHelper.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/action/HasActionsIF.h" +#include "linux/obc/TxRateSetterIF.h" #include "VirtualChannel.h" #include @@ -22,7 +25,8 @@ class CCSDSHandler: public SystemObject, public AcceptsTelemetryIF, public AcceptsTelecommandsIF, public HasReturnvaluesIF, - public ReceivesParameterMessagesIF { + public ReceivesParameterMessagesIF, + public HasActionsIF { public: using VcId_t = uint8_t; @@ -33,8 +37,11 @@ public: * @param objectId Object ID of the CCSDS handler * @param ptmeId Object ID of the PTME object providing access to the PTME IP Core. * @param tcDestination Object ID of object handling received TC space packets + * @param txRateSetter Object providing the functionality to switch the input bitrate of + * the S-Band transceiver. */ - CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination); + CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, + TxRateSetterIF* txRateSetterIF); ~CCSDSHandler(); @@ -58,10 +65,21 @@ public: uint16_t getIdentifier() override; MessageQueueId_t getRequestQueue() override; + virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size); + private: + static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER; + static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; + static const ActionId_t SET_LOW_RATE = 0; + static const ActionId_t SET_HIGH_RATE = 1; + + //! [EXPORT] : [COMMENT] Received action message with unknown action id + static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0); + using VirtualChannelMap = std::unordered_map; using VirtualChannelMapIter = VirtualChannelMap::iterator; @@ -76,8 +94,12 @@ private: ParameterHelper parameterHelper; + ActionHelper actionHelper; + MessageQueueId_t tcDistributorQueueId; + TxRateSetterIF* txRateSetterIF = nullptr; + void readCommandQueue(void); void handleTelemetry(); void handleTelecommands();