From 67ac4060d72235d79d06026b6db870a494df63ae Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sun, 21 Nov 2021 13:58:05 +0100 Subject: [PATCH 01/12] physical ram base adress for q7s --- linux/obc/PdecHandler.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 7696a7a0..6a8a6562 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -124,7 +124,12 @@ private: static const size_t MAX_TC_SEGMENT_SIZE = 1017; static const uint8_t MAP_ID_MASK = 0x3F; +#if BOARD_TE0720 == 1 static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000; +#else + static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000; +#endif + static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0; static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90; -- 2.43.0 From 63965e2f6836cb54bbe14baa3f74671fb5100f59 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sun, 21 Nov 2021 13:59:18 +0100 Subject: [PATCH 02/12] enabled rx lines of syrlinks rs485 transceiver chips --- bsp_q7s/boardconfig/busConf.h | 3 +++ bsp_q7s/core/ObjectFactory.cpp | 23 ++++++++++++++++++++++- linux/fsfwconfig/devices/gpioIds.h | 6 +++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index e68a1f19..af89d346 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -66,7 +66,10 @@ namespace gpioNames { static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3"; static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872"; static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872"; + static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872"; + static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872"; static constexpr char PDEC_RESET[] = "pdec_reset"; + static constexpr char BIT_RATE_SEL[] = "bit_rate_sel"; } } diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index a64a1493..c7738679 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -79,6 +79,8 @@ #include #include #include +#include +#include ResetArgs resetArgsGnss0; ResetArgs resetArgsGnss1; @@ -937,8 +939,19 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { ptme->addVcInterface(ccsds::VC2, vc2); ptme->addVcInterface(ccsds::VC3, vc3); + GpioCookie* gpioCookieRateSetter = new GpioCookie; + consumer.str(""); + consumer << "ptme rate setter"; + // Init to low -> default bit rate is low bit rate (200 kbps in downlink with syrlinks) + gpio = new GpiodRegularByLineName(q7s::gpioNames::BIT_RATE_SEL, consumer.str(), gpio::OUT, + gpio::LOW); + gpioCookieRateSetter->addGpio(gpioIds::BIT_RATE_SEL, gpio); + gpioComIF->addGpios(gpioCookieRateSetter); + + TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(gpioIds::BIT_RATE_SEL, gpioComIF); + CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME, - objects::CCSDS_PACKET_DISTRIBUTOR); + objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF); VirtualChannel* vc = nullptr; vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE); @@ -973,6 +986,14 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { gpio::Direction::OUT, gpio::HIGH); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); + // Default configuration enables RX channels (RXEN = LOW) + gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver", + gpio::Direction::OUT, gpio::LOW); + gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio); + gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver", + gpio::Direction::OUT, gpio::LOW); + gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio); + gpioComIF->addGpios(gpioRS485Chip); #endif /* BOARD_TE0720 == 0 */ } diff --git a/linux/fsfwconfig/devices/gpioIds.h b/linux/fsfwconfig/devices/gpioIds.h index 2fe715ea..8d3f94ca 100644 --- a/linux/fsfwconfig/devices/gpioIds.h +++ b/linux/fsfwconfig/devices/gpioIds.h @@ -104,7 +104,11 @@ enum gpioId_t { RS485_EN_TX_DATA, - RS485_EN_TX_CLOCK + RS485_EN_TX_CLOCK, + RS485_EN_RX_DATA, + RS485_EN_RX_CLOCK, + + BIT_RATE_SEL }; } -- 2.43.0 From dc0f435dbd420242953805b9e783b7a0119cc58f Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sun, 21 Nov 2021 18:07:05 +0100 Subject: [PATCH 03/12] bit rate setter --- bsp_q7s/core/InitMission.cpp | 2 +- linux/obc/CMakeLists.txt | 1 + linux/obc/PtmeRateSetter.cpp | 27 +++++++++++++++++++++++ linux/obc/PtmeRateSetter.h | 40 +++++++++++++++++++++++++++++++++++ linux/obc/TxRateSetterIF.h | 25 ++++++++++++++++++++++ mission/tmtc/CCSDSHandler.cpp | 31 +++++++++++++++++++++++++-- mission/tmtc/CCSDSHandler.h | 26 +++++++++++++++++++++-- 7 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 linux/obc/PtmeRateSetter.cpp create mode 100644 linux/obc/PtmeRateSetter.h create mode 100644 linux/obc/TxRateSetterIF.h 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(); -- 2.43.0 From 283921cba189e2c988404b3a08792edead17cea2 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 22 Nov 2021 10:38:32 +0100 Subject: [PATCH 04/12] print clcw command --- linux/obc/PdecHandler.cpp | 65 +++++++++++++++++++++++++++++---------- linux/obc/PdecHandler.h | 44 ++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 3d80af8a..d68f79a4 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -9,14 +9,16 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/ipc/QueueFactory.h" + PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory, std::string uioRegisters) : SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset( pdecReset), uioConfigMemory(uioConfigMemory), uioRamMemory(uioRamMemory), uioRegisters( - uioRegisters) { - + uioRegisters), actionHelper(this, nullptr) { + commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); } PdecHandler::~PdecHandler() { @@ -62,9 +64,18 @@ ReturnValue_t PdecHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } + result = actionHelper.initialize(commandQueue); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; } +MessageQueueId_t PdecHandler::getCommandQueue() const { + return commandQueue->getId(); +} + ReturnValue_t PdecHandler::getRegisterAddress() { int fd = open(uioRegisters.c_str(), O_RDWR); if (fd < 1) { @@ -168,6 +179,8 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { ReturnValue_t result = RETURN_OK; + readCommandQueue(); + switch(state) { case State::INIT: resetFarStatFlag(); @@ -183,7 +196,6 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { if (newTcReceived()) { handleNewTc(); } - getClcw(); break; case State::WAIT_FOR_RECOVERY: break; @@ -195,6 +207,24 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { return RETURN_OK; } +void PdecHandler::readCommandQueue(void) { + CommandMessage commandMessage; + ReturnValue_t result = RETURN_FAILED; + + result = commandQueue->receiveMessage(&commandMessage); + if (result == RETURN_OK) { + result = actionHelper.handleActionMessage(&commandMessage); + if (result == RETURN_OK) { + return; + } + CommandMessage reply; + reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, + commandMessage.getCommand()); + commandQueue->reply(&reply); + return; + } +} + bool PdecHandler::newTcReceived() { uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); @@ -434,21 +464,12 @@ uint8_t PdecHandler::getOddParity(uint8_t number) { return parityBit; } -void PdecHandler::getClcw() { - -#if OBSW_DEBUG_PDEC_HANDLER == 1 - uint32_t clcw = *(registerBaseAddress + PDEC_CLCW_OFFSET); - if (debugDivider == 10) { - printClcw(clcw); - debugDivider = 0; - return; - } - debugDivider++; -#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ - +uint32_t PdecHandler::getClcw() { + return *(registerBaseAddress + PDEC_CLCW_OFFSET); } -void PdecHandler::printClcw(uint32_t clcw) { +void PdecHandler::printClcw() { + uint32_t clcw = getClcw(); uint8_t type = static_cast((clcw >> 31) & 0x1); uint8_t versionNo = static_cast((clcw >> 29) & 0x3); uint8_t status = static_cast((clcw >> 26) & 0x7); @@ -487,3 +508,15 @@ void PdecHandler::printClcw(uint32_t clcw) { sif::info << std::setw(30) << std::left << "CLCW rep value: " << std::hex << "0x" << static_cast(repValue) << std::endl; } + + +ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + switch(actionId) { + case PRINT_CLCW: + printClcw(); + return EXECUTION_FINISHED; + default: + return COMMAND_NOT_IMPLEMENTED; + } +} diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 6a8a6562..d7c7d236 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -10,6 +10,8 @@ #include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/action/HasActionsIF.h" /** * @brief This class controls the PDEC IP Core implemented in the programmable logic of the @@ -29,7 +31,10 @@ * * @author J. Meier */ -class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { +class PdecHandler : public SystemObject, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public HasActionsIF { public: /** @@ -51,6 +56,21 @@ public: ReturnValue_t initialize() override; + MessageQueueId_t getCommandQueue() const; + + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; + + /** + * brief Returns the 32-bit wide communication link control word (CLCW) + */ + uint32_t getClcw(); + + /** + * @rief Reads and prints the CLCW. Can be useful for debugging. + */ + void printClcw(); + private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; @@ -63,6 +83,9 @@ private: static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4); static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] Received action message with unknown action id + static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0); + static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6); //! Error in version number and reserved A and B fields static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7); @@ -88,6 +111,11 @@ private: //! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH); + static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; + + // Action IDs + static const ActionId_t PRINT_CLCW = 0; + static const uint8_t STAT_POSITION = 31; static const uint8_t FRAME_ANA_POSITION = 28; static const uint8_t IREASON_POSITION = 25; @@ -182,6 +210,11 @@ private: WAIT_FOR_RECOVERY }; + /** + * @brief Reads and handles messages stored in the commandQueue + */ + void readCommandQueue(void); + /** * @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC * registers. The register base address will be mapped into the virtual address space. @@ -284,9 +317,6 @@ private: */ uint8_t getOddParity(uint8_t number); - void getClcw(); - void printClcw(uint32_t clcw); - object_id_t tcDestinationId; AcceptsTelecommandsIF* tcDestination = nullptr; @@ -309,8 +339,12 @@ private: // UIO device file giving access to the PDEC register space std::string uioRegisters; + ActionHelper actionHelper; + StorageManagerIF* tcStore = nullptr; + MessageQueueIF* commandQueue = nullptr; + State state = State::INIT; /** @@ -328,8 +362,6 @@ private: uint32_t pdecFar = 0; uint8_t tcSegment[TC_SEGMENT_LEN]; - - uint8_t debugDivider = 0; }; #endif /* LINUX_OBC_PDECHANDLER_H_ */ -- 2.43.0 From 15b2f9a13e0ebe83b6efef48fd8434f16958125a Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 22 Nov 2021 17:55:40 +0100 Subject: [PATCH 05/12] run event parser --- generators/events/translateEvents.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 18f6ba50..b0a9ee6a 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 106 translations. * @details - * Generated on: 2021-10-31 17:56:40 + * Generated on: 2021-11-22 17:04:42 */ #include "translateEvents.h" -- 2.43.0 From cb6db97fc1797137d7b00dd4c155f7032024f17e Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 22 Nov 2021 17:56:46 +0100 Subject: [PATCH 06/12] run object parser --- generators/objects/translateObjects.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 15f82c2c..48eb29e7 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 111 translations. - * Generated on: 2021-10-13 15:54:21 + * Contains 112 translations. + * Generated on: 2021-11-22 17:04:51 */ #include "translateObjects.h" @@ -86,6 +86,7 @@ const char *PAPB_VC0_STRING = "PAPB_VC0"; const char *PAPB_VC1_STRING = "PAPB_VC1"; const char *PAPB_VC2_STRING = "PAPB_VC2"; const char *PAPB_VC3_STRING = "PAPB_VC3"; +const char *PDEC_HANDLER_STRING = "PDEC_HANDLER"; const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER"; const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6"; const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START"; @@ -280,6 +281,8 @@ const char* translateObject(object_id_t object) { return PAPB_VC2_STRING; case 0x50000703: return PAPB_VC3_STRING; + case 0x50000704: + return PDEC_HANDLER_STRING; case 0x50000800: return CCSDS_HANDLER_STRING; case 0x51000500: -- 2.43.0 From c2dbebe56be196f309118cebf2441c29f5f1c9e4 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 22 Nov 2021 17:57:33 +0100 Subject: [PATCH 07/12] gen events --- linux/fsfwconfig/events/translateEvents.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 18f6ba50..b0a9ee6a 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 106 translations. * @details - * Generated on: 2021-10-31 17:56:40 + * Generated on: 2021-11-22 17:04:42 */ #include "translateEvents.h" -- 2.43.0 From ec7568337cbf082a240234eb657d0a40b8b2e9c4 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 22 Nov 2021 17:58:24 +0100 Subject: [PATCH 08/12] object parser --- linux/fsfwconfig/objects/translateObjects.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 15f82c2c..48eb29e7 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 111 translations. - * Generated on: 2021-10-13 15:54:21 + * Contains 112 translations. + * Generated on: 2021-11-22 17:04:51 */ #include "translateObjects.h" @@ -86,6 +86,7 @@ const char *PAPB_VC0_STRING = "PAPB_VC0"; const char *PAPB_VC1_STRING = "PAPB_VC1"; const char *PAPB_VC2_STRING = "PAPB_VC2"; const char *PAPB_VC3_STRING = "PAPB_VC3"; +const char *PDEC_HANDLER_STRING = "PDEC_HANDLER"; const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER"; const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6"; const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START"; @@ -280,6 +281,8 @@ const char* translateObject(object_id_t object) { return PAPB_VC2_STRING; case 0x50000703: return PAPB_VC3_STRING; + case 0x50000704: + return PDEC_HANDLER_STRING; case 0x50000800: return CCSDS_HANDLER_STRING; case 0x51000500: -- 2.43.0 From 345ccf5392385a7f64f14cc89669cbe29bfd5a28 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 22 Nov 2021 18:01:16 +0100 Subject: [PATCH 09/12] transmit enable and timeout --- bsp_q7s/core/InitMission.cpp | 2 +- bsp_q7s/core/ObjectFactory.cpp | 3 +- generators/bsp_q7s_objects.csv | 1 + linux/fsfwconfig/OBSWConfig.h.in | 2 +- linux/obc/PdecHandler.cpp | 14 ++++ linux/obc/PdecHandler.h | 34 ++++++-- mission/tmtc/CCSDSHandler.cpp | 137 ++++++++++++++++++++++++++++++- mission/tmtc/CCSDSHandler.h | 58 ++++++++++++- 8 files changed, 234 insertions(+), 17 deletions(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index eab396c6..bd70c1c0 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", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.6, missedDeadlineFunc); + "PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index c7738679..ec0c085f 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -951,7 +951,8 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(gpioIds::BIT_RATE_SEL, gpioComIF); CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME, - objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF); + objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF, gpioComIF, + gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA); VirtualChannel* vc = nullptr; vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE); diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 3d8a4d40..fded183b 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -78,6 +78,7 @@ 0x50000701;PAPB_VC1 0x50000702;PAPB_VC2 0x50000703;PAPB_VC3 +0x50000704;PDEC_HANDLER 0x50000800;CCSDS_HANDLER 0x51000500;PUS_SERVICE_6 0x53000000;FSFW_OBJECTS_START diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 9dbc5428..3e3bf5c3 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -37,7 +37,7 @@ debugging. */ // Set to 1 if all telemetry should be sent to the PTME IP Core #define OBSW_TM_TO_PTME 1 // Set to 1 if telecommands are received via the PDEC IP Core -#define OBSW_TC_FROM_PDEC 0 +#define OBSW_TC_FROM_PDEC 1 #define OBSW_ENABLE_TIMERS 1 #define OBSW_ADD_STAR_TRACKER 0 diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index d68f79a4..f99a1a30 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -196,6 +196,7 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { if (newTcReceived()) { handleNewTc(); } + checkLocks(); break; case State::WAIT_FOR_RECOVERY: break; @@ -237,6 +238,19 @@ bool PdecHandler::newTcReceived() { return true; } +void PdecHandler::checkLocks() { + uint32_t clcw = getClcw(); + if (!(clcw & NO_RF_MASK) && (lastClcw & NO_RF_MASK)) { + // Rf available changed from 0 to 1 + triggerEvent(CARRIER_LOCK); + } + if (!(clcw & NO_BITLOCK_MASK) && (lastClcw & NO_BITLOCK_MASK)) { + // Bit lock changed from 0 to 1 + triggerEvent(BIT_LOCK); + } + lastClcw = clcw; +} + bool PdecHandler::checkFrameAna(uint32_t pdecFar) { bool frameValid = false; FrameAna_t frameAna = static_cast((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION); diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index d7c7d236..83e4a253 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -71,6 +71,19 @@ public: */ void printClcw(); + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; + + //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame + //! P1: The frame analysis information (FrameAna field of PDEC_FAR register) + //! P2: When frame declared illegal this parameter this parameter gives information about the reason (IReason field of the PDEC_FAR register) + static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH); + //! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup + static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH); + //! [EXPORT] : [COMMENT] Carrier lock detected + static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO); + //! [EXPORT] : [COMMENT] Bit lock detected (data valid) + static const Event BIT_LOCK = MAKE_EVENT(4, severity::INFO); + private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; @@ -102,15 +115,6 @@ private: //! Invalid BC control command static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE); - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; - - //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame - //! P1: The frame analysis information (FrameAna field of PDEC_FAR register) - //! P2: When frame declared illegal this parameter this parameter gives information about the reason (IReason field of the PDEC_FAR register) - static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH); - //! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup - static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH); - static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; // Action IDs @@ -172,6 +176,9 @@ private: static const uint32_t TC_SEGMENT_LEN = 1017; + static const uint32_t NO_RF_MASK = 0x8000; + static const uint32_t NO_BITLOCK_MASK = 0x4000; + /** * TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in * the PDEC memory. @@ -260,6 +267,12 @@ private: */ bool newTcReceived(); + /** + * @brief Checks if carrier lock or bit lock has been detected and triggers appropriate + * event. + */ + void checkLocks(); + /** * @brief Analyzes the FramAna field (frame analysis data) of a FAR report. * @@ -362,6 +375,9 @@ private: uint32_t pdecFar = 0; uint8_t tcSegment[TC_SEGMENT_LEN]; + + // Used to check carrier and bit lock changes (default set to no rf and no bitlock) + uint32_t lastClcw = 0xC000; }; #endif /* LINUX_OBC_PDECHANDLER_H_ */ diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CCSDSHandler.cpp index caf99515..a9c6df27 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CCSDSHandler.cpp @@ -1,24 +1,32 @@ +#include "OBSWConfig.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/serviceInterfaceDefintions.h" #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/ipc/QueueFactory.h" +#include "fsfw/events/EventManagerIF.h" + +#include #include "CCSDSHandler.h" CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, - TxRateSetterIF* txRateSetterIF) : + TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData) : SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this), actionHelper( - this, nullptr), txRateSetterIF(txRateSetterIF) { + this, nullptr), txRateSetterIF(txRateSetterIF), gpioIF(gpioIF), enTxClock( + enTxClock), enTxData(enTxData) { commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); + eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 2); } CCSDSHandler::~CCSDSHandler() { } ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) { + checkEvents(); readCommandQueue(); handleTelemetry(); handleTelecommands(); + checkTxTimer(); return RETURN_OK; } @@ -71,6 +79,27 @@ ReturnValue_t CCSDSHandler::initialize() { iter->second->setPtmeObject(ptme); } + EventManagerIF* manager = ObjectManager::instance()->get( + objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "CCSDSHandler::initialize: Invalid event manager" << std::endl; +#endif + return RETURN_FAILED; + } + result = manager->registerListener(eventQueue->getId()); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = manager->subscribeToEventRange(eventQueue->getId(), + event::getEventId(PdecHandler::CARRIER_LOCK), event::getEventId(PdecHandler::BIT_LOCK)); + if (result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "CCSDSHandler::initialize: Failed to subscribe to events from PDEC " + "handler" << std::endl; +#endif + return result; + } return result; } @@ -157,13 +186,113 @@ ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { switch(actionId) { - case SET_LOW_RATE: + case SET_LOW_RATE: { txRateSetterIF->setRate(BitRates::RATE_400KHZ); return EXECUTION_FINISHED; - case SET_HIGH_RATE: + } + case SET_HIGH_RATE: { txRateSetterIF->setRate(BitRates::RATE_2000KHZ); return EXECUTION_FINISHED; + } + case EN_TRANSMITTER: { + enableTransmit(); + return EXECUTION_FINISHED; + } + case DIS_TRANSMITTER: { + disableTransmit(); + return EXECUTION_FINISHED; + } default: return COMMAND_NOT_IMPLEMENTED; } } + +void CCSDSHandler::checkEvents() { + EventMessage event; + for (ReturnValue_t result = eventQueue->receiveMessage(&event); + result == RETURN_OK; result = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + handleEvent(&event); + break; + default: + sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message" + << std::endl; + break; + } + } +} + + +void CCSDSHandler::handleEvent(EventMessage* eventMessage) { + Event event = eventMessage->getEvent(); + switch(event){ + case PdecHandler::BIT_LOCK: { + handleBitLockEvent(); + break; + } + case PdecHandler::CARRIER_LOCK: { + handleCarrierLockEvent(); + break; + } + default: + sif::debug << "CCSDSHandler::handleEvent: Did not subscribe to this event" + << std::endl; + break; + } +} + +void CCSDSHandler::handleBitLockEvent() { + if(transmitterCountdown.isBusy()) { + // Transmitter already enabled + return; + } + enableTransmit(); +} + +void CCSDSHandler::handleCarrierLockEvent() { + if (!enableTxWhenCarrierLock) { + return; + } + enableTransmit(); +} + +void CCSDSHandler::forwardLinkstate() { + VirtualChannelMapIter iter; + for(iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { + iter->second->setLinkState(linkState); + } +} + +void CCSDSHandler::enableTransmit() { + if(transmitterCountdown.isBusy()) { + // Transmitter already enabled + return; + } + transmitterCountdown.setTimeout(TRANSMITTER_TIMEOUT); +#if BOARD_TE0720 == 0 + gpioIF->pullLow(enTxClock); + gpioIF->pullLow(enTxData); +#endif /* BOARD_TE0720 == 0 */ + linkState = UP; + // Set link state of all virtual channels to link up + forwardLinkstate(); +} + +void CCSDSHandler::checkTxTimer() { + if(linkState == DOWN) { + return; + } + if (transmitterCountdown.hasTimedOut()) { + disableTransmit(); + } +} + +void CCSDSHandler::disableTransmit() { +#if BOARD_TE0720 == 0 + gpioIF->pullHigh(enTxClock); + gpioIF->pullHigh(enTxData); +#endif /* BOARD_TE0720 == 0 */ + linkState = DOWN; + forwardLinkstate(); +} diff --git a/mission/tmtc/CCSDSHandler.h b/mission/tmtc/CCSDSHandler.h index 6ed5abbe..cdab72e0 100644 --- a/mission/tmtc/CCSDSHandler.h +++ b/mission/tmtc/CCSDSHandler.h @@ -10,7 +10,11 @@ #include "fsfw/parameters/ParameterHelper.h" #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" +#include "fsfw/timemanager/Countdown.h" +#include "fsfw/events/EventMessage.h" #include "linux/obc/TxRateSetterIF.h" +#include "fsfw_hal/common/gpio/gpioDefinitions.h" +#include "fsfw_hal/common/gpio/GpioIF.h" #include "VirtualChannel.h" #include @@ -39,9 +43,12 @@ public: * @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 */ CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, - TxRateSetterIF* txRateSetterIF); + TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData); ~CCSDSHandler(); @@ -76,10 +83,19 @@ private: 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 DIS_TRANSMITTER = 3; //! [EXPORT] : [COMMENT] Received action message with unknown action id static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0); + // syrlinks must not be transmitting more than 15 minutes (according to datasheet) +// static const uint32_t TRANSMITTER_TIMEOUT = 900000; //900000 ms = 15 min + static const uint32_t TRANSMITTER_TIMEOUT = 10000; //900000 ms = 15 min + + static const bool UP = true; + static const bool DOWN = false; + using VirtualChannelMap = std::unordered_map; using VirtualChannelMapIter = VirtualChannelMap::iterator; @@ -91,6 +107,7 @@ private: object_id_t tcDestination; MessageQueueIF* commandQueue = nullptr; + MessageQueueIF* eventQueue = nullptr; ParameterHelper parameterHelper; @@ -100,9 +117,48 @@ private: TxRateSetterIF* txRateSetterIF = nullptr; + GpioIF* gpioIF = nullptr; + gpioId_t enTxClock = gpio::NO_GPIO; + gpioId_t enTxData = gpio::NO_GPIO; + + // Countdown to disable transmitter after 15 minutes + Countdown transmitterCountdown; + + // When true transmitting is started as soon as carrier lock has been detected + bool enableTxWhenCarrierLock = false; + + bool linkState = DOWN; + void readCommandQueue(void); void handleTelemetry(); void handleTelecommands(); + void checkEvents(); + void handleEvent(EventMessage* eventMessage); + + void handleBitLockEvent(); + void handleCarrierLockEvent(); + + /** + * @brief Forward link state to virtual channels. + */ + void forwardLinkstate(); + + /** + * @brief Starts transmit timer and enables transmitter. + */ + void enableTransmit(); + + /** + * @brief Checks Tx timer for timeout and disables RS485 tx clock and tx data in case + * timer has expired. + */ + void checkTxTimer(); + + /** + * @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the + * RS485 transceiver chips to high. + */ + void disableTransmit(); }; #endif /* CCSDSHANDLER_H_ */ -- 2.43.0 From 542aa994b712c7c2cfaea36f8c14194a4a773f50 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 24 Nov 2021 15:55:25 +0100 Subject: [PATCH 10/12] link state now detected by bit and carrier lock flags --- bsp_q7s/core/InitMission.cpp | 2 +- bsp_q7s/core/ObjectFactory.cpp | 4 ++-- linux/fsfwconfig/OBSWConfig.h.in | 5 +++-- mission/tmtc/CCSDSHandler.cpp | 10 +++++----- mission/tmtc/CCSDSHandler.h | 8 ++++++-- mission/tmtc/VirtualChannel.cpp | 4 ++-- mission/tmtc/VirtualChannel.h | 6 +----- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index bd70c1c0..7923a2cd 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", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); + "PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index ec0c085f..bf8a2fba 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -981,10 +981,10 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { #if BOARD_TE0720 == 0 GpioCookie* gpioRS485Chip = new GpioCookie; gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", - gpio::Direction::OUT, gpio::HIGH); + gpio::Direction::OUT, gpio::LOW); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver", - gpio::Direction::OUT, gpio::HIGH); + gpio::Direction::OUT, gpio::LOW); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); // Default configuration enables RX channels (RXEN = LOW) diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 3e3bf5c3..0ca7bae2 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -39,6 +39,8 @@ debugging. */ // Set to 1 if telecommands are received via the PDEC IP Core #define OBSW_TC_FROM_PDEC 1 +#define TMTC_TEST_SETUP 1 + #define OBSW_ENABLE_TIMERS 1 #define OBSW_ADD_STAR_TRACKER 0 #define OBSW_ADD_PLOC_SUPERVISOR 0 @@ -92,7 +94,6 @@ debugging. */ #define OBSW_TEST_TE7020_HEATER 0 #define OBSW_TEST_GPIO_OPEN_BY_LABEL 0 #define OBSW_TEST_GPIO_OPEN_BY_LINE_NAME 0 -#define OBSW_LINK_IS_UP 1 #define OBSW_DEBUG_P60DOCK 0 #define OBSW_DEBUG_PDU1 0 @@ -109,7 +110,7 @@ debugging. */ #define OBSW_DEBUG_STARTRACKER 0 #define OBSW_DEBUG_PLOC_MPSOC 0 #define OBSW_DEBUG_PLOC_SUPERVISOR 0 -#define OBSW_DEBUG_PDEC_HANDLER 0 +#define OBSW_DEBUG_PDEC_HANDLER 1 /*******************************************************************/ /** Hardcoded */ diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CCSDSHandler.cpp index a9c6df27..71307bd9 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CCSDSHandler.cpp @@ -1,4 +1,3 @@ -#include "OBSWConfig.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/serviceInterfaceDefintions.h" #include "fsfw/objectmanager/ObjectManager.h" @@ -271,8 +270,8 @@ void CCSDSHandler::enableTransmit() { } transmitterCountdown.setTimeout(TRANSMITTER_TIMEOUT); #if BOARD_TE0720 == 0 - gpioIF->pullLow(enTxClock); - gpioIF->pullLow(enTxData); + gpioIF->pullHigh(enTxClock); + gpioIF->pullHigh(enTxData); #endif /* BOARD_TE0720 == 0 */ linkState = UP; // Set link state of all virtual channels to link up @@ -290,9 +289,10 @@ void CCSDSHandler::checkTxTimer() { void CCSDSHandler::disableTransmit() { #if BOARD_TE0720 == 0 - gpioIF->pullHigh(enTxClock); - gpioIF->pullHigh(enTxData); + gpioIF->pullLow(enTxClock); + gpioIF->pullLow(enTxData); #endif /* BOARD_TE0720 == 0 */ linkState = DOWN; forwardLinkstate(); + transmitterCountdown.setTimeout(0); } diff --git a/mission/tmtc/CCSDSHandler.h b/mission/tmtc/CCSDSHandler.h index cdab72e0..6fb6168b 100644 --- a/mission/tmtc/CCSDSHandler.h +++ b/mission/tmtc/CCSDSHandler.h @@ -89,9 +89,13 @@ private: //! [EXPORT] : [COMMENT] Received action message with unknown action id static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0); +#if TMTC_TEST_SETUP == 0 // syrlinks must not be transmitting more than 15 minutes (according to datasheet) -// static const uint32_t TRANSMITTER_TIMEOUT = 900000; //900000 ms = 15 min - static const uint32_t TRANSMITTER_TIMEOUT = 10000; //900000 ms = 15 min + static const uint32_t TRANSMITTER_TIMEOUT = 900000; //900000 ms = 15 min +#else + // Set to high value when not sending via syrlinks + static const uint32_t TRANSMITTER_TIMEOUT = 86400000; // 1 day +#endif /* TMTC_TEST_SETUP == 0 */ static const bool UP = true; static const bool DOWN = false; diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 3423692b..0273f5ce 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -64,6 +64,6 @@ void VirtualChannel::setPtmeObject(PtmeIF* ptme_) { ptme = ptme_; } -void VirtualChannel::setLinkState(bool linkIsUp) { - linkIsUp = linkIsUp; +void VirtualChannel::setLinkState(bool linkIsUp_) { + linkIsUp = linkIsUp_; } diff --git a/mission/tmtc/VirtualChannel.h b/mission/tmtc/VirtualChannel.h index d7d95cb7..c6e2eb6d 100644 --- a/mission/tmtc/VirtualChannel.h +++ b/mission/tmtc/VirtualChannel.h @@ -38,7 +38,7 @@ class VirtualChannel: public AcceptsTelemetryIF, public HasReturnvaluesIF { * @brief Can be used by the owner to set the link state. Packets will be discarded if link * to ground station is down. */ - void setLinkState(bool linkIsUp); + void setLinkState(bool linkIsUp_); private: @@ -46,11 +46,7 @@ private: MessageQueueIF* tmQueue = nullptr; uint8_t vcId; -#if OBSW_LINK_IS_UP == 1 - bool linkIsUp = true; -#else bool linkIsUp = false; -#endif /* OBSW_LINK_IS_UP == 1 */ StorageManagerIF* tmStore = nullptr; }; -- 2.43.0 From 34897aceae14dc5dac2d71f4c40faa3e025d1154 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 24 Nov 2021 18:29:14 +0100 Subject: [PATCH 11/12] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index b2cc2354..aabbb129 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit b2cc2354d410b0bc0d80c481bfd37afc580e63cf +Subproject commit aabbb129a6df1d33cf10770a5ecb6336c698f0e6 -- 2.43.0 From b4479d6a7da9cf3ad87fa12d137a6c6a58935f87 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 24 Nov 2021 18:29:34 +0100 Subject: [PATCH 12/12] ccsds handler class id --- common/config/commonClassIds.h | 1 + 1 file changed, 1 insertion(+) diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 605ace3b..00b5ca25 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -22,6 +22,7 @@ enum commonClassIds: uint8_t { GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC + CCSDS_HANDLER, //PDEC COMMON_CLASS_ID_END // [EXPORT] : [END] }; -- 2.43.0