#ifndef CCSDSHANDLER_H_ #define CCSDSHANDLER_H_ #include #include #include #include #include "OBSWConfig.h" #include "eive/definitions.h" #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" #include "fsfw/events/EventMessage.h" #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" #include "fsfw/tmtcservices/AcceptsTelemetryIF.h" #include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "linux/ipcore/PtmeConfig.h" #include "mission/com/defs.h" struct PtmeGpios { gpioId_t enableTxClock = gpio::NO_GPIO; gpioId_t enableTxData = gpio::NO_GPIO; gpioId_t ptmeResetn = gpio::NO_GPIO; }; /** * @brief This class handles the data exchange with the CCSDS IP cores implemented in the * programmable logic of the Q7S. * * @details * From a system view, OFF means that the transmitter is off, on means that the transmitter is on. * The handler will only take care of the IP configuration, the actual swithing and configuration * of the COM hardware (Syrlinks for the EIVE project) will be done in a separate device handler. * * After reboot default CADU bitrate is always set to 100 kbps (results in downlink rate * of 200 kbps due to convolutional code added by syrlinks transceiver). The IP core handler exposes * a parameter to enable the priority selection mode for the PTME core. * * If the transmitter is on, the selection mode will be enabled when the transmitter goes off. * If the transmitter is off, the update of the PTME will be done immediately on a parameter update. * This is done because changing this parameter requires a reset of the PTME core to avoid bugs * while the transmitter is enabled. * * @author J. Meier */ class CcsdsIpCoreHandler : public SystemObject, public ExecutableObjectIF, public ModeTreeChildIF, public ModeTreeConnectionIF, public HasModesIF, public AcceptsTelecommandsIF, public ReceivesParameterMessagesIF, public HasActionsIF { public: enum ParamId : uint8_t { BAT_PRIORITY = 0 }; static const bool LINK_UP = true; static const bool LINK_DOWN = false; using VcId_t = uint8_t; /** * @brief Constructor * * @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. * @param gpioIF Required to enable TX data and TX clock RS485 transceiver chips. * @param enTxClock GPIO ID of RS485 tx clock enable * @param enTxData GPIO ID of RS485 tx data enable */ CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig, std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds, std::atomic_bool& ptmeLocked); ~CcsdsIpCoreHandler(); ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t initialize(); 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; ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex); uint32_t getIdentifier() const override; MessageQueueId_t getRequestQueue() const override; const char* getName() const override; 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; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER; static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE; static const ActionId_t SET_LOW_RATE = 0; static const ActionId_t SET_HIGH_RATE = 1; static const ActionId_t EN_TRANSMITTER = 2; static const ActionId_t DISABLE_TRANSMITTER = 3; static const ActionId_t ARBITRARY_RATE = 4; static const ActionId_t ENABLE_TX_CLK_MANIPULATOR = 5; static const ActionId_t DISABLE_TX_CLK_MANIPULATOR = 6; // Will update data with respect to tx clock signal of cadu bitstream on rising edge static const ActionId_t UPDATE_ON_RISING_EDGE = 7; // Will update data with respect to tx clock signal of cadu bitstream on falling edge static const ActionId_t UPDATE_ON_FALLING_EDGE = 8; // Syrlinks supports two bitrates (200 kbps and 1000 kbps) // Due to convolutional code added by the syrlinks the input frequency must be half the // target frequency static const uint32_t RATE_100KBPS = 100000; static const uint32_t RATE_500KBPS = 500000; //! [EXPORT] : [COMMENT] Received action message with unknown action id static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0); std::atomic_bool& linkState; std::atomic_bool& ptmeLocked; object_id_t tcDestination; MessageQueueIF* commandQueue = nullptr; MessageQueueIF* eventQueue = nullptr; ParameterHelper parameterHelper; ActionHelper actionHelper; Mode_t mode = HasModesIF::MODE_OFF; Submode_t submode = static_cast(com::CcsdsSubmode::UNSET); ModeHelper modeHelper; MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE; PtmeConfig& ptmeConfig; PtmeGpios ptmeGpios; // BAT priority bit on by default to enable priority selection mode for the PTME. uint8_t batPriorityParam = 0; struct UpdateContext { bool updateBatPrio = false; bool updateClockRate = false; bool enableTransmitAfterPtmeUpdate = false; uint8_t ptmeUpdateCycleCount = 0; bool performPtmeUpdateAfterXCycles = false; bool setModeAfterUpdate = false; } updateContext{}; GpioIF* gpioIF = nullptr; void readCommandQueue(void); /** * @brief Forward link state to virtual channels. */ void updateLinkState(); /** * @brief Starts transmit timer and enables transmitter. */ void enableTransmit(bool resetPtmeUpdateParams); /** * @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the * RS485 transceiver chips to high. */ void disableTransmit(); void performPtmeUpdateWhenApplicable(); /** * The following set of functions configure the mode of the PTME bandwith allocation table (BAT) * module. This consists of the following 2 steps: * 1. Update the BAT priority bit in the PTME wrapper * 2. Reset the PTME as specified in the datasheet. */ void enablePrioritySelectMode(); void disablePrioritySelectMode(); void updateBatPriorityFromParam(); void setMode(Mode_t mode, Submode_t submode); void resetPtme(); void initPtmeUpdateAfterXCycles(); void finishPtmeUpdateAfterXCycles(bool doResetPtme); }; #endif /* CCSDSHANDLER_H_ */