From 60c99fdbfb3f0d79033de583495a76cf356edc0c Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 13 Feb 2023 11:28:27 +0100 Subject: [PATCH] local parameter handler wip --- bsp_q7s/core/ObjectFactory.cpp | 6 + bsp_q7s/core/ObjectFactory.h | 2 + bsp_q7s/fmObjectFactory.cpp | 2 + bsp_q7s/memory/CMakeLists.txt | 2 +- bsp_q7s/memory/LocalParameterHandler.cpp | 22 +++ bsp_q7s/memory/LocalParameterHandler.h | 66 +++++++++ linux/ipcore/PdecConfig.cpp | 139 ++++++++++++++---- linux/ipcore/PdecConfig.h | 91 +++++++++++- linux/ipcore/PdecHandler.cpp | 107 +++++++------- linux/ipcore/PdecHandler.h | 58 ++++---- mission/config/configfile.h | 9 ++ mission/system/objects/ComSubsystem.h | 1 + mission/utility/GlobalConfigFileDefinitions.h | 2 + mission/utility/GlobalConfigHandler.cpp | 47 +++--- mission/utility/GlobalConfigHandler.h | 15 +- 15 files changed, 417 insertions(+), 152 deletions(-) create mode 100644 bsp_q7s/memory/LocalParameterHandler.cpp create mode 100644 bsp_q7s/memory/LocalParameterHandler.h create mode 100644 mission/config/configfile.h diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 1fb9efed..47ca4e18 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -51,6 +51,8 @@ #include "mission/system/tree/comModeTree.h" #include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/tcsModeTree.h" +#include "mission/utility/GlobalConfigHandler.h" +#include "mission/config/configfile.h" #include "tmtc/pusIds.h" #if OBSW_TEST_LIBGPIOD == 1 #include "linux/boardtest/LibgpiodTest.h" @@ -966,3 +968,7 @@ void ObjectFactory::testAcsBrdAss(AcsBoardAssembly* acsAss) { sif::warning << "Sending mode command failed" << std::endl; } } + +void ObjectFactory::createGlobalConfigHandler() { + new GlobalConfigHandler(objects::GLOBAL_JSON_CFG, configfile::sdrelative); +} diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index c55e8452..853fd9ce 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -48,6 +48,8 @@ void createTestComponents(LinuxLibgpioIF* gpioComIF); void testAcsBrdAss(AcsBoardAssembly* assAss); +void createGlobalConfigHandler(); + }; // namespace ObjectFactory #endif /* BSP_Q7S_OBJECTFACTORY_H_ */ diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 44b53225..40d2454e 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -86,6 +86,8 @@ void ObjectFactory::produce(void* args) { createTestComponents(gpioComIF); #endif /* OBSW_ADD_TEST_CODE == 1 */ + createGlobalConfigHandler(); + createMiscComponents(); createThermalController(); createAcsController(true); diff --git a/bsp_q7s/memory/CMakeLists.txt b/bsp_q7s/memory/CMakeLists.txt index 06909a0a..4ff840c8 100644 --- a/bsp_q7s/memory/CMakeLists.txt +++ b/bsp_q7s/memory/CMakeLists.txt @@ -1 +1 @@ -target_sources(${OBSW_NAME} PRIVATE scratchApi.cpp) +target_sources(${OBSW_NAME} PRIVATE scratchApi.cpp LocalParameterHandler.cpp) diff --git a/bsp_q7s/memory/LocalParameterHandler.cpp b/bsp_q7s/memory/LocalParameterHandler.cpp new file mode 100644 index 00000000..03a5ba82 --- /dev/null +++ b/bsp_q7s/memory/LocalParameterHandler.cpp @@ -0,0 +1,22 @@ +#include "LocalParameterHandler.h" +#include + +LocalParameterHandler::LocalParameterHandler(std::string sdRelativeName, SdCardMountedIF* sdcMan) + : sdRelativeName(sdRelativeName), sdcMan(sdcMan) {} + +LocalParameterHandler::~LocalParameterHandler() { +} + +ReturnValue_t LocalParameterHandler::initialize() { + std::string mountPrefix = sdcMan->getCurrentMountPrefix(); + std::string fullname = mountPrefix + "/" + sdRelativeName; + setFullName(fullname); + ReturnValue_t result = readJsonFile(); + if (result != returnvalue::OK) { + sif::warning << "LocalParameterHandler::initialize: Failed to read json file" + << getFullName() << std::endl; + return result; + } + return returnvalue::OK; +} + diff --git a/bsp_q7s/memory/LocalParameterHandler.h b/bsp_q7s/memory/LocalParameterHandler.h new file mode 100644 index 00000000..57d646cb --- /dev/null +++ b/bsp_q7s/memory/LocalParameterHandler.h @@ -0,0 +1,66 @@ +#ifndef BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_ +#define BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_ + +#include + +#include +#include + +/** + * @brief Class to handle persistent parameters + * + * @details Use the insertValue function to add parameters + */ +class LocalParameterHandler : public NVMParameterBase { + public: + /** + * @brief Constructor + * + * @param sdRelativeName Absolute name of json file relative to mount + * directory of SD card. E.g. conf/example.json + * @param sdcMan Pointer to SD card manager + */ + LocalParameterHandler(std::string sdRelativeName, SdCardMountedIF* sdcMan); + virtual ~LocalParameterHandler(); + + /** + * @brief Will initialize the local parameter handler + * + * @return OK if successful, otherwise error return value + */ + ReturnValue_t initialize(); + + /** + * @brief Function to add parameter to json file + * + * @param key The string to identify the parameter + * @param value The value to set for this parameter + * + * @return OK if successful, otherwise error return value + * + * @details The function will add the parameter only if it is not already + * present in the json file + */ + template ReturnValue_t addParameter(std::string key, T value); + + private: + + // Name relative to mount point of SD card where parameters will be stored + std::string sdRelativeName; + + SdCardMountedIF* sdcMan; +}; + +template inline ReturnValue_t LocalParameterHandler::addParameter(std::string key, T value) { + ReturnValue_t result = insertValue(key, value); + if (result != returnvalue::OK) { + return result; + } + result = writeJsonFile(); + if (result != returnvalue::OK) { + return result; + } + return returnvalue::OK; +} + +#endif /* BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_ */ diff --git a/linux/ipcore/PdecConfig.cpp b/linux/ipcore/PdecConfig.cpp index 21de4610..152ea320 100644 --- a/linux/ipcore/PdecConfig.cpp +++ b/linux/ipcore/PdecConfig.cpp @@ -2,41 +2,126 @@ #include "fsfw/serviceinterface/ServiceInterface.h" -PdecConfig::PdecConfig() { initialize(); } +PdecConfig::PdecConfig() + : localParameterHandler("conf/pdecconfig", SdCardManager::instance()) { +} PdecConfig::~PdecConfig() {} -void PdecConfig::initialize() { - uint32_t word = 0; - word |= (VERSION_ID << 30); - - // Setting the bypass flag and the control command flag should not have any - // implication on the operation of the PDEC IP Core - word |= (BYPASS_FLAG << 29); - word |= (CONTROL_COMMAND_FLAG << 28); - - word |= (RESERVED_FIELD_A << 26); - word |= (SPACECRAFT_ID << 16); - word |= (VIRTUAL_CHANNEL << 10); - word |= (DUMMY_BITS << 8); - word |= POSITIVE_WINDOW; - configWords[0] = word; - word = 0; - word |= (NEGATIVE_WINDOW << 24); - word |= (HIGH_AU_MAP_ID << 16); - word |= (ENABLE_DERANDOMIZER << 8); - configWords[1] = word; +void PdecConfig::setMemoryBaseAddress(uint32_t* memoryBaseAddress_) { + memoryBaseAddress = memoryBaseAddress_; } -uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { - if (wordNo >= CONFIG_WORDS_NUM) { - sif::error << "PdecConfig::getConfigWord: Invalid word number" << std::endl; - return 0; - } - return configWords[wordNo]; +ReturnValue_t PdecConfig::write() { + if (memoryBaseAddress == nullptr) { + sif::error << "PdecConfig::write: Memory base address not set" << std::endl; + return returnvalue::FAILED; + } + + writeFrameHeaderFirstOctet(); + writeFrameHeaderSecondOctet(); + writeMapConfig(); + return returnvalue::FAILED; } uint32_t PdecConfig::getImrReg() { return static_cast(enableNewFarIrq << 2) | static_cast(enableTcAbortIrq << 1) | static_cast(enableTcNewIrq); } + +ReturnValue_t PdecConfig::setPositiveWindow(uint8_t pw) { + if (memoryBaseAddress == nullptr) { + sif::error << "PdecConfig::setPositiveWindow: Memory base address not set" + << std::endl; + return returnvalue::FAILED; + } + positiveWindow = pw; + // Rewrite second config word which contains the positive window parameter + writeFrameHeaderSecondOctet(); + return returnvalue::OK; +} + +ReturnValue_t PdecConfig::setNegativeWindow(uint8_t nw) { + if (memoryBaseAddress == nullptr) { + sif::error << "PdecConfig::setPositiveWindow: Memory base address not set" + << std::endl; + return returnvalue::FAILED; + } + negativeWindow = nw; + // Rewrite second config word which contains the negative window parameter + writeFrameHeaderSecondOctet(); + return returnvalue::OK; +} + +uint8_t PdecConfig::getPositiveWindow() { + return positiveWindow; +} + +uint8_t PdecConfig::getNegativeWindow() { + return negativeWindow; +} + +void PdecConfig::writeFrameHeaderFirstOctet() { + uint32_t word = 0; + word |= (VERSION_ID << 30); + + // Setting the bypass flag and the control command flag should not have any + // implication on the operation of the PDEC IP Core + word |= (BYPASS_FLAG << 29); + word |= (CONTROL_COMMAND_FLAG << 28); + + word |= (RESERVED_FIELD_A << 26); + word |= (SPACECRAFT_ID << 16); + word |= (VIRTUAL_CHANNEL << 10); + word |= (DUMMY_BITS << 8); + word |= positiveWindow; + *(memoryBaseAddress + FRAME_HEADER_OFFSET) = word; +} + +void PdecConfig::writeFrameHeaderSecondOctet() { + uint32_t word = 0; + word = 0; + word |= (negativeWindow << 24); + word |= (HIGH_AU_MAP_ID << 16); + word |= (ENABLE_DERANDOMIZER << 8); + *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = word; +} + +void PdecConfig::writeMapConfig() { + // Configure all MAP IDs as invalid + for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = + NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; + } + + // All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory) + uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = + (NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm; + + // Write map id clock frequencies + for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { + *(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = + MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ; + } +} + +uint8_t PdecConfig::calcMapAddrEntry(uint8_t moduleId) { + uint8_t lutEntry = 0; + uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION)); + lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId; + return lutEntry; +} + +uint8_t PdecConfig::getOddParity(uint8_t number) { + uint8_t parityBit = 0; + uint8_t countBits = 0; + for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) { + countBits += (number >> idx) & 0x1; + } + parityBit = ~(countBits & 0x1) & 0x1; + return parityBit; +} + + + diff --git a/linux/ipcore/PdecConfig.h b/linux/ipcore/PdecConfig.h index 3d909581..0b665c6c 100644 --- a/linux/ipcore/PdecConfig.h +++ b/linux/ipcore/PdecConfig.h @@ -3,28 +3,51 @@ #include +#include "bsp_q7s/memory/LocalParameterHandler.h" +#include "bsp_q7s/fs/SdCardManager.h" #include "fsfw/returnvalues/returnvalue.h" +#include "pdec.h" /** * @brief This class generates the configuration words for the configuration memory of the PDEC * IP Cores. * - * @details Fields are initialized according to pecification in PDEC datasheet section 6.11.3.1 + * @details Fields are initialized according to specification in PDEC datasheet section 6.11.3.1 * PROM usage. * * @author J. Meier */ class PdecConfig { public: + /** + * @brief Constructor + */ PdecConfig(); virtual ~PdecConfig(); /** - * @brief Returns the configuration word by specifying the position. + * @brief Sets the memory base address pointer + */ + void setMemoryBaseAddress(uint32_t* memoryBaseAddress_); + + /** + * @brief Will write the config to the PDEC configuration memory. New config + * becomes active after resetting PDEC. + */ + ReturnValue_t write(); + + /** + * @brief Returns the value to write to the interrupt mask register. This + * value defines which interrupts should be enabled/disabled. */ - uint32_t getConfigWord(uint8_t wordNo); uint32_t getImrReg(); + ReturnValue_t setPositiveWindow(uint8_t pw); + ReturnValue_t setNegativeWindow(uint8_t nw); + + uint8_t getPositiveWindow(); + uint8_t getNegativeWindow(); + private: // TC transfer frame configuration parameters static const uint8_t VERSION_ID = 0; @@ -36,21 +59,73 @@ class PdecConfig { static const uint8_t RESERVED_FIELD_A = 0; static const uint16_t SPACECRAFT_ID = 0x3DC; static const uint16_t DUMMY_BITS = 0; - // Parameters to control the FARM for AD frames - // Set here for future use - static const uint8_t POSITIVE_WINDOW = 10; - static const uint8_t NEGATIVE_WINDOW = 151; static const uint8_t HIGH_AU_MAP_ID = 0xF; static const uint8_t ENABLE_DERANDOMIZER = 1; static const uint8_t CONFIG_WORDS_NUM = 2; + // 0x200 / 4 = 0x80 + static const uint32_t FRAME_HEADER_OFFSET = 0x80; + + static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0; + static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90; + // MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be + // discarded + static const uint8_t MAP_CLK_FREQ = 2; + + static const uint8_t MAX_MAP_ADDR = 63; + // Writing this to the map address in the look up table will invalidate a MAP ID. + static const uint8_t NO_DESTINATION = 0; + static const uint8_t VALID_POSITION = 6; + static const uint8_t PARITY_POSITION = 7; + + /** + * TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in + * the PDEC memory. + */ + static const uint8_t PM_BUFFER = 7; + + uint32_t* memoryBaseAddress = nullptr; + + // Pointer to object providing access to persistent configuration parameters + LocalParameterHandler localParameterHandler; + uint32_t configWords[CONFIG_WORDS_NUM]; bool enableTcNewIrq = true; bool enableTcAbortIrq = true; bool enableNewFarIrq = true; - void initialize(); + NVMParameterBase persistenParams; + + // Parameters to control the FARM for AD frames + // Set here for future use + uint8_t positiveWindow = 10; + uint8_t negativeWindow = 151; + + void writeFrameHeaderFirstOctet(); + void writeFrameHeaderSecondOctet(); + void writeMapConfig(); + + /** + * @brief This function calculates the entry for the configuration of the MAP ID routing. + * + * @param mapAddr The MAP ID to configure + * @param moduleId The destination module where all TCs with the map id mapAddr will be routed + * to. + * + * @details The PDEC has different modules where the TCs can be routed to. A lookup table is + * used which links the MAP ID field to the destination module. The entry for this + * lookup table is created by this function and must be stored in the configuration + * memory region of the PDEC. The entry has a specific format + */ + uint8_t calcMapAddrEntry(uint8_t moduleId); + + /** + * @brief This functions calculates the odd parity of the bits in number. + * + * @param number The number from which to calculate the odd parity. + */ + uint8_t getOddParity(uint8_t number); }; #endif /* LINUX_OBC_PDECCONFIG_H_ */ diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 57d59841..3d1b9d58 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -22,13 +22,15 @@ using namespace pdec; uint32_t PdecHandler::CURRENT_FAR = 0; PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, - LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names) + LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names, + object_id_t globalConfigHandlerId) : SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset(pdecReset), actionHelper(this, nullptr), - uioNames(names) { + uioNames(names), + globalConfigHandlerId(globalConfigHandlerId) { auto mqArgs = MqArgs(objectId, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); @@ -61,6 +63,8 @@ ReturnValue_t PdecHandler::initialize() { result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; + } else { + pdecConfig.setMemoryBaseAddress(memoryBaseAddress); } UioMapper ramMapper(uioNames.ramMemory); result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE); @@ -72,8 +76,19 @@ ReturnValue_t PdecHandler::initialize() { sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl; return returnvalue::FAILED; } - PdecConfig pdecConfig; - writePdecConfigDuringReset(pdecConfig); + + globalConfigHandler = ObjectManager::instance()->get(objects::GLOBAL_JSON_CFG); + if (globalConfigHandler == nullptr) { + sif::error << "PdecHandler::initialize: Invalid global config handler" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + pdecConfig.setGlobalConfigHandler(globalConfigHandler); + result = pdecConfig.write(); + if (result != returnvalue::OK) { + sif::error << "PdecHandler::initialize: Failed to write PDEC config" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } result = releasePdec(); if (result != returnvalue::OK) { @@ -233,26 +248,45 @@ void PdecHandler::readCommandQueue(void) { MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } -void PdecHandler::writePdecConfigDuringReset(PdecConfig& pdecConfig) { - *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); - *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); - - // Configure all MAP IDs as invalid - for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { - *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = - NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; +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; + case PRINT_PDEC_MON: + printPdecMon(); + return EXECUTION_FINISHED; + default: + return COMMAND_NOT_IMPLEMENTED; } +} - // All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory) - uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); - *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = - (NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm; - - // Write map id clock frequencies - for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { - *(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = - MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ; +ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, uint16_t startAtIndex) { + if ((domainId == 0) and (uniqueIdentifier == ParameterId::POSITIVE_WINDOW)) { + uint8_t newVal = 0; + ReturnValue_t result = newValues->getElement(&newVal); + if (result != returnvalue::OK) { + return result; + } + parameterWrapper->set(); + com::setCurrentDatarate(static_cast(newVal)); + return returnvalue::OK; + } else if ((domainId == 0) and + (uniqueIdentifier == static_cast(com::ParameterId::TRANSMITTER_TIMEOUT))) { + uint8_t newVal = 0; + ReturnValue_t result = newValues->getElement(&newVal); + if (result != returnvalue::OK) { + return result; + } + parameterWrapper->set(transmitterTimeout); + transmitterTimeout = newVal; + transmitterCountdown.setTimeout(transmitterTimeout); + return returnvalue::OK; } + return returnvalue::OK; } ReturnValue_t PdecHandler::resetFarStatFlag() { @@ -518,23 +552,6 @@ void PdecHandler::printTC(uint32_t tcLength) { sif::info << tcSegmentStream.str() << std::endl; } -uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) { - uint8_t lutEntry = 0; - uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION)); - lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId; - return lutEntry; -} - -uint8_t PdecHandler::getOddParity(uint8_t number) { - uint8_t parityBit = 0; - uint8_t countBits = 0; - for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) { - countBits += (number >> idx) & 0x1; - } - parityBit = ~(countBits & 0x1) & 0x1; - return parityBit; -} - uint32_t PdecHandler::getClcw() { return *(registerBaseAddress + PDEC_CLCW_OFFSET); } uint32_t PdecHandler::getPdecMon() { return *(registerBaseAddress + PDEC_MON_OFFSET); } @@ -620,17 +637,3 @@ std::string PdecHandler::getMonStatusString(uint32_t status) { break; } } - -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; - case PRINT_PDEC_MON: - printPdecMon(); - return EXECUTION_FINISHED; - default: - return COMMAND_NOT_IMPLEMENTED; - } -} diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 6ebd9ce6..8664e732 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -8,6 +8,8 @@ #include "eive/definitions.h" #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" +#include "fsfw/parameters/HasParametersIF.h" +#include "fsfw/parameters/ParameterHelper.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/returnvalues/returnvalue.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -15,6 +17,7 @@ #include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "mission/utility/GlobalConfigHandler.h" struct UioNames { const char* configMemory; @@ -41,7 +44,10 @@ struct UioNames { * * @author J. Meier */ -class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { +class PdecHandler : public SystemObject, + public ExecutableObjectIF, + public HasActionsIF, + public HasParametersIF { public: static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500; @@ -55,9 +61,10 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc * @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC. * @param uioConfigMemory String of uio device file same mapped to the PDEC memory space * @param uioregsiters String of uio device file same mapped to the PDEC register space + * @param globalConfigHandler Object ID of global config file handler */ PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, - gpioId_t pdecReset, UioNames names); + gpioId_t pdecReset, UioNames names, object_id_t globalConfigHandlerId); virtual ~PdecHandler(); @@ -70,6 +77,10 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) override; + ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, + uint16_t startAtIndex) override; + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame @@ -138,9 +149,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc static const int REGISTER_MAP_SIZE = 0x4000; #endif /* BOARD_TE0720 == 1 */ - // 0x200 / 4 = 0x80 - static const uint32_t FRAME_HEADER_OFFSET = 0x80; - static const size_t MAX_TC_SEGMENT_SIZE = 1017; static const uint8_t MAP_ID_MASK = 0x3F; @@ -150,15 +158,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc 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; - - static const uint8_t MAX_MAP_ADDR = 63; - // Writing this to the map address in the look up table will invalidate a MAP ID. - static const uint8_t NO_DESTINATION = 0; - static const uint8_t VALID_POSITION = 6; - static const uint8_t PARITY_POSITION = 7; - // Expected value stored in FAR register after reset static const uint32_t FAR_RESET = 0x7FE0; @@ -167,15 +166,13 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc 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. - */ - static const uint8_t PM_BUFFER = 7; - - // MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be - // discarded - static const uint8_t MAP_CLK_FREQ = 2; + class ParameterId { + public: + // ID of the parameter to update the positive window of AD frames + static const uint8_t POSITIVE_WINDOW = 0; + // ID of the parameter to update the negative window of AD frames + static const uint8_t NEGATIVE_WINDOW = 1; + }; enum class FrameAna_t : uint8_t { ABANDONED_CLTU, @@ -249,6 +246,15 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc UioNames uioNames; + // Object ID of global config file handler + object_id_t globalConfigHandlerId; + + ParameterHelper paramHelper; + + GlobalConfigHandler* globalConfigHandler = nullptr; + + PdecConfig pdecConfig; + /** * @brief Reads and handles messages stored in the commandQueue */ @@ -341,12 +347,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc */ uint8_t calcMapAddrEntry(uint8_t moduleId); - /** - * @brief This functions calculates the odd parity of the bits in number. - * - * @param number The number from which to calculate the odd parity. - */ - uint8_t getOddParity(uint8_t number); /** * brief Returns the 32-bit wide communication link control word (CLCW) diff --git a/mission/config/configfile.h b/mission/config/configfile.h new file mode 100644 index 00000000..eb8fb0a5 --- /dev/null +++ b/mission/config/configfile.h @@ -0,0 +1,9 @@ +#ifndef MISSION_CONFIG_CONFIGFILE_H_ +#define MISSION_CONFIG_CONFIGFILE_H_ + +namespace configfile { + // Name of global config file relative to currently mounted SD card + static const char sdrelative[] = "config/global_config.json"; +} + +#endif /* MISSION_CONFIG_CONFIGFILE_H_ */ diff --git a/mission/system/objects/ComSubsystem.h b/mission/system/objects/ComSubsystem.h index ac8cc60f..b1bbeed9 100644 --- a/mission/system/objects/ComSubsystem.h +++ b/mission/system/objects/ComSubsystem.h @@ -50,6 +50,7 @@ class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF { // Maximum time after which the transmitter will be turned of. This is a // protection mechanism due prevent the syrlinks from overheating uint32_t transmitterTimeout = 0; + ParameterHelper paramHelper; MessageQueueIF* eventQueue = nullptr; diff --git a/mission/utility/GlobalConfigFileDefinitions.h b/mission/utility/GlobalConfigFileDefinitions.h index 2e7d133a..2c9b6b66 100644 --- a/mission/utility/GlobalConfigFileDefinitions.h +++ b/mission/utility/GlobalConfigFileDefinitions.h @@ -15,6 +15,8 @@ enum ParamIds : uint8_t { PARAM0 = 0, PARAM1 = 1, PARAM2 = 2, + PDEC_PW = 3, + PDEC_NW = 4 }; #endif /* MISSION_UTILITY_GLOBALCONFIGFILEDEFINITIONS_H_ */ diff --git a/mission/utility/GlobalConfigHandler.cpp b/mission/utility/GlobalConfigHandler.cpp index bb4b3d7d..ffd1963b 100644 --- a/mission/utility/GlobalConfigHandler.cpp +++ b/mission/utility/GlobalConfigHandler.cpp @@ -23,23 +23,24 @@ GlobalConfigHandler::GlobalConfigHandler(object_id_t objectId, std::string confi CONFIG_LOCK = MutexFactory::instance()->createMutex(); } } + ReturnValue_t GlobalConfigHandler::initialize() { ReturnValue_t result = SystemObject::initialize(); if (result != returnvalue::OK) { #if OBSW_VERBOSE_LEVEL >= 1 - sif::info << "GlobalConfigHandler::initialize: SystemObject::initialize() failed with " + sif::info << "GlobalConfigHandler::initialize: SystemObject::initialize failed with " << result << std::endl; #endif return result; } - result = ReadConfigFile(); + result = readConfigFile(); if (result != returnvalue::OK) { #if OBSW_VERBOSE_LEVEL >= 1 sif::info << "GlobalConfigHandler::initialize: Creating JSON file at " << getFullName() << std::endl; #endif - result = ResetConfigFile(); + result = resetConfigFile(); if (result != returnvalue::OK) { return result; } @@ -63,6 +64,7 @@ ReturnValue_t GlobalConfigHandler::lockConfigFile() { result = CONFIG_LOCK->lockMutex(MutexIF::TimeoutType::WAITING, 10); return result; } + ReturnValue_t GlobalConfigHandler::unlockConfigFile() { ReturnValue_t result = returnvalue::OK; result = CONFIG_LOCK->unlockMutex(); @@ -70,34 +72,21 @@ ReturnValue_t GlobalConfigHandler::unlockConfigFile() { } template -ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, T data) { +ReturnValue_t GlobalConfigHandler::setConfigFileValue(std::string paramName, T data) { ReturnValue_t result = returnvalue::OK; ReturnValue_t resultSet = returnvalue::OK; result = lockConfigFile(); if (result != returnvalue::OK) { #if OBSW_VERBOSE_LEVEL >= 1 - sif::info << "GlobalConfigHandler::setConfigFileValue lock mutex failed with " << result + sif::info << "GlobalConfigHandler::setConfigFileValue: Lock mutex failed with " << result << std::endl; #endif return result; } - std::string paramString; - paramString = PARAM_KEY_MAP[paramID]; - - // Check if key exists in map before setting value. No check is done in setValue! Somehow - // PARAM_KEY_MAP.count(paramID) == 0 does not work - if (paramString.empty() == true) { -#if OBSW_VERBOSE_LEVEL >= 1 - sif::info << "GlobalConfigHandler::setConfigFileValue ParamId " << PARAM_KEY_MAP[paramID] - << " not found!" << std::endl; -#endif - triggerEvent(SET_CONFIGFILEVALUE_FAILED, 1, 0); - return returnvalue::FAILED; - } - - resultSet = setValue(PARAM_KEY_MAP[paramID], data); + // If value exists it is updated otherwise a new entry will be created + resultSet = insertValue(paramName, data); if (resultSet != returnvalue::OK) { triggerEvent(SET_CONFIGFILEVALUE_FAILED, 0, 0); #if OBSW_VERBOSE_LEVEL >= 1 @@ -117,6 +106,7 @@ ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, T data) return resultSet; } + template ReturnValue_t GlobalConfigHandler::getConfigFileValue(ParamIds paramID, T& data) { ReturnValue_t result = returnvalue::OK; @@ -161,8 +151,10 @@ ReturnValue_t GlobalConfigHandler::resetConfigFileValues() { #endif return result; } - insertValue(PARAM_KEY_MAP[PARAM0], PARAM0_DEFAULT); - insertValue(PARAM_KEY_MAP[PARAM1], PARAM1_DEFAULT); + + for(const auto& keyMap: PARAM_KEY_MAP) { + insertValue(keyMap.second, PARAM0_DEFAULT); + } result = unlockConfigFile(); if (result != returnvalue::OK) { @@ -174,7 +166,8 @@ ReturnValue_t GlobalConfigHandler::resetConfigFileValues() { } return result; } -ReturnValue_t GlobalConfigHandler::WriteConfigFile() { + +ReturnValue_t GlobalConfigHandler::writeConfigFile() { ReturnValue_t result = returnvalue::OK; ReturnValue_t resultWrite = returnvalue::OK; result = lockConfigFile(); @@ -205,7 +198,8 @@ ReturnValue_t GlobalConfigHandler::WriteConfigFile() { } return resultWrite; } -ReturnValue_t GlobalConfigHandler::ReadConfigFile() { + +ReturnValue_t GlobalConfigHandler::readConfigFile() { ReturnValue_t result = returnvalue::OK; ReturnValue_t resultRead = returnvalue::OK; result = lockConfigFile(); @@ -237,7 +231,8 @@ ReturnValue_t GlobalConfigHandler::ReadConfigFile() { return resultRead; } -ReturnValue_t GlobalConfigHandler::ResetConfigFile() { + +ReturnValue_t GlobalConfigHandler::resetConfigFile() { ReturnValue_t result = returnvalue::OK; result = resetConfigFileValues(); if (result != returnvalue::OK) { @@ -253,7 +248,7 @@ ReturnValue_t GlobalConfigHandler::ResetConfigFile() { ReturnValue_t GlobalConfigHandler::setConfigFileName(std::string configFileName) { ReturnValue_t result = returnvalue::OK; setFullName(configFileName); - result = ResetConfigFile(); + result = resetConfigFile(); return result; } std::string GlobalConfigHandler::getConfigFileName() { return getFullName(); } diff --git a/mission/utility/GlobalConfigHandler.h b/mission/utility/GlobalConfigHandler.h index 80e141c6..1a2fe07f 100644 --- a/mission/utility/GlobalConfigHandler.h +++ b/mission/utility/GlobalConfigHandler.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -24,10 +25,6 @@ #include "fsfw/parameters/ParameterHelper.h" #include "mission/memory/NVMParameterBase.h" -static std::map PARAM_KEY_MAP = { - {PARAM0, "Parameter0"}, - {PARAM1, "Parameter1"}, -}; /* * Idea: This class is intended to be used as a subclass for the Core Controller. * Its tasks is managing a configuration JSON file containing config values important for various @@ -54,12 +51,12 @@ class GlobalConfigHandler : public SystemObject, ReturnValue_t initialize(); template - ReturnValue_t setConfigFileValue(ParamIds paramID, T data); + ReturnValue_t setConfigFileValue(std::string paramName, T data); template - ReturnValue_t getConfigFileValue(ParamIds paramID, T& data); + ReturnValue_t getConfigFileValue(std::string paramName, T& data); - ReturnValue_t ResetConfigFile(); - ReturnValue_t WriteConfigFile(); + ReturnValue_t resetConfigFile(); + ReturnValue_t writeConfigFile(); std::string getConfigFileName(); private: @@ -71,7 +68,7 @@ class GlobalConfigHandler : public SystemObject, ReturnValue_t setConfigFileName(std::string configFileName); - ReturnValue_t ReadConfigFile(); + ReturnValue_t readConfigFile(); MessageQueueIF* commandQueue; };