From b5d3422d90213cb5ab8f14895fad932dc6433676 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Oct 2022 19:12:04 +0200 Subject: [PATCH 01/18] add some baseline defines and config values --- linux/obc/PdecConfig.cpp | 5 +++++ linux/obc/PdecConfig.h | 4 ++++ linux/obc/PdecHandler.cpp | 8 +++++--- linux/obc/PdecHandler.h | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/linux/obc/PdecConfig.cpp b/linux/obc/PdecConfig.cpp index ac762a6c..eaa32512 100644 --- a/linux/obc/PdecConfig.cpp +++ b/linux/obc/PdecConfig.cpp @@ -31,3 +31,8 @@ uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { } return configWords[wordNo]; } + +uint32_t PdecConfig::getImrReg() { + return static_cast(enableNewFarIrq << 2) | static_cast(enableTcAbortIrq << 1) + | static_cast(enableTcNewIrq); +} diff --git a/linux/obc/PdecConfig.h b/linux/obc/PdecConfig.h index e037dd56..284af6ef 100644 --- a/linux/obc/PdecConfig.h +++ b/linux/obc/PdecConfig.h @@ -23,6 +23,7 @@ class PdecConfig { * @brief Returns the configuration word by specifying the position. */ uint32_t getConfigWord(uint8_t wordNo); + uint32_t getImrReg(); private: // TC transfer frame configuration parameters @@ -45,6 +46,9 @@ class PdecConfig { static const uint8_t CONFIG_WORDS_NUM = 2; uint32_t configWords[CONFIG_WORDS_NUM]; + bool enableTcNewIrq = true; + bool enableTcAbortIrq = true; + bool enableNewFarIrq = true; void initialize(); }; diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index c009d8a6..a04b9128 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -86,10 +86,12 @@ void PdecHandler::writePdecConfig() { *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); + // Configure interrupt mask register to enable interrupts + (*memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + // Configure all MAP IDs as invalid for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { - // TODO: adding 1 / 4 results in + 0. Check correctness - *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx + 1 / 4) = + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; } @@ -100,10 +102,10 @@ void PdecHandler::writePdecConfig() { // Write map id clock frequencies for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { - // TODO: adding 1 / 4 results in + 0. Check correctness *(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::resetFarStatFlag() { diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 57adfa9f..20a9642d 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -147,6 +147,8 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 */ + static constexpr uint32_t PDEC_PIR_OFFSET = 0xA03; + static constexpr uint32_t PDEC_IMR_OFFSET = 0xA04; static const uint32_t PDEC_FAR_OFFSET = 0xA10; static const uint32_t PDEC_CLCW_OFFSET = 0xA12; static const uint32_t PDEC_BFREE_OFFSET = 0xA24; From 278db35ae01873048c8c158b8bb02fa20bc368a8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Oct 2022 19:19:57 +0200 Subject: [PATCH 02/18] small fix --- linux/obc/PdecHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index a04b9128..2d852caf 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -87,7 +87,7 @@ void PdecHandler::writePdecConfig() { *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); // Configure interrupt mask register to enable interrupts - (*memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + *(memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); // Configure all MAP IDs as invalid for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { From 2286451039e8253830b19634c59cd7f296b00c99 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Oct 2022 14:35:47 +0200 Subject: [PATCH 03/18] split up Pdec Handler --- linux/obc/PdecConfig.cpp | 4 +- linux/obc/PdecHandler.cpp | 123 ++++++++++++++++++-------------- linux/obc/PdecHandler.h | 7 ++ mission/devices/ImtqHandler.cpp | 3 +- 4 files changed, 80 insertions(+), 57 deletions(-) diff --git a/linux/obc/PdecConfig.cpp b/linux/obc/PdecConfig.cpp index eaa32512..321e5940 100644 --- a/linux/obc/PdecConfig.cpp +++ b/linux/obc/PdecConfig.cpp @@ -33,6 +33,6 @@ uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { } uint32_t PdecConfig::getImrReg() { - return static_cast(enableNewFarIrq << 2) | static_cast(enableTcAbortIrq << 1) - | static_cast(enableTcNewIrq); + return static_cast(enableNewFarIrq << 2) | + static_cast(enableTcAbortIrq << 1) | static_cast(enableTcNewIrq); } diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 2d852caf..0f29ea3c 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -78,63 +78,16 @@ ReturnValue_t PdecHandler::initialize() { return returnvalue::OK; } -MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } - -void PdecHandler::writePdecConfig() { - PdecConfig pdecConfig; - - *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); - *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); - - // Configure interrupt mask register to enable interrupts - *(memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); - - // 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; - } - -} - -ReturnValue_t PdecHandler::resetFarStatFlag() { - uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); - if (pdecFar != FAR_RESET) { - sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." - << " Read value: 0x" << std::hex << static_cast(pdecFar) - << std::endl; - return returnvalue::FAILED; - } -#if OBSW_DEBUG_PDEC_HANDLER == 1 - sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar - << std::endl; -#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ - return returnvalue::OK; -} - -ReturnValue_t PdecHandler::releasePdec() { - ReturnValue_t result = returnvalue::OK; - result = gpioComIF->pullHigh(pdecReset); - if (result != returnvalue::OK) { - sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl; - } - return result; -} - ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { ReturnValue_t result = returnvalue::OK; + if (OP_MODE == Modes::POLLED) { + polledOperation(); + } else if (OP_MODE == Modes::IRQ) { + irqOperation(); + } +} +ReturnValue_t PdecHandler::polledOperation() { readCommandQueue(); switch (state) { @@ -164,6 +117,13 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { return returnvalue::OK; } +ReturnValue_t PdecHandler::irqOperation() { + while (true) { + readCommandQueue(); + } + return returnvalue::OK; +} + void PdecHandler::readCommandQueue(void) { CommandMessage commandMessage; ReturnValue_t result = returnvalue::FAILED; @@ -181,6 +141,61 @@ void PdecHandler::readCommandQueue(void) { } } +MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } + +void PdecHandler::writePdecConfig() { + PdecConfig pdecConfig; + + *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); + *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); + + if (OP_MODE == Modes::IRQ) { + // Configure interrupt mask register to enable interrupts + *(memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + } + + // 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; + } +} + +ReturnValue_t PdecHandler::resetFarStatFlag() { + uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); + if (pdecFar != FAR_RESET) { + sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." + << " Read value: 0x" << std::hex << static_cast(pdecFar) + << std::endl; + return returnvalue::FAILED; + } +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar + << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ + return returnvalue::OK; +} + +ReturnValue_t PdecHandler::releasePdec() { + ReturnValue_t result = returnvalue::OK; + result = gpioComIF->pullHigh(pdecReset); + if (result != returnvalue::OK) { + sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl; + } + return result; +} + bool PdecHandler::newTcReceived() { uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 20a9642d..d003bae2 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -33,6 +33,8 @@ */ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { public: + enum class Modes { POLLED, IRQ }; + /** * @brief Constructor * @param objectId Object ID of PDEC handler system object @@ -78,6 +80,8 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; + static constexpr Modes OP_MODE = Modes::POLLED; + static const ReturnValue_t ABANDONED_CLTU = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t FRAME_DIRTY = MAKE_RETURN_CODE(0xA1); static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2); @@ -234,6 +238,9 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc */ void readCommandQueue(void); + ReturnValue_t polledOperation(); + ReturnValue_t irqOperation(); + /** * @brief This functions writes the configuration parameters to the configuration * section of the PDEC. diff --git a/mission/devices/ImtqHandler.cpp b/mission/devices/ImtqHandler.cpp index d27b6f65..a0e717f8 100644 --- a/mission/devices/ImtqHandler.cpp +++ b/mission/devices/ImtqHandler.cpp @@ -321,7 +321,8 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi break; case (IMTQ::CC::PAST_AVAILABLE_RESPONSE_BYTES): { sif::warning << "IMTQHandler::scanForReply: Read 0xFF command byte, reading past available " - "bytes. Keep 1 ms delay between I2C send and read" << std::endl; + "bytes. Keep 1 ms delay between I2C send and read" + << std::endl; result = IGNORE_REPLY_DATA; break; } From 7799e3477f17241aa175605bd37d34e9a1868849 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Oct 2022 08:34:45 +0200 Subject: [PATCH 04/18] pdec handler now compiles --- linux/obc/PdecHandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 0f29ea3c..63aedbce 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -79,15 +79,15 @@ ReturnValue_t PdecHandler::initialize() { } ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { - ReturnValue_t result = returnvalue::OK; if (OP_MODE == Modes::POLLED) { - polledOperation(); + return polledOperation(); } else if (OP_MODE == Modes::IRQ) { - irqOperation(); + return irqOperation(); } } ReturnValue_t PdecHandler::polledOperation() { + ReturnValue_t result = returnvalue::OK; readCommandQueue(); switch (state) { From bc277067ed4f7959cac59ff7d51af65da035493c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Oct 2022 09:20:41 +0200 Subject: [PATCH 05/18] add PDEC IRQ uio file entry --- bsp_q7s/boardconfig/busConf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 0bd781df..2fc1963c 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -20,7 +20,8 @@ static constexpr char UART_SCEX_DEV[] = "/dev/scex"; static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio_pdec_regs"; static constexpr char UIO_PTME[] = "/dev/uio_ptme"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio_pdec_cfg_mem"; -static constexpr char UIO_PDEC_RAM[] = "/dev/pdec_ram"; +static constexpr char UIO_PDEC_RAM[] = "/dev/uio_pdec_ram"; +static constexpr char UIO_PDEC_IRQ = "/dev/uio_pdec_irq"; static constexpr int MAP_ID_PTME_CONFIG = 3; namespace uiomapids { From 95d2bc08874a28771ef0453674ac031500f058cd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Oct 2022 10:49:52 +0200 Subject: [PATCH 06/18] first IRQ impl --- bsp_q7s/boardconfig/busConf.h | 2 +- bsp_q7s/core/ObjectFactory.cpp | 7 +- linux/obc/PdecHandler.cpp | 110 ++++++++++++++++++++--- linux/obc/PdecHandler.h | 158 +++++++++++++-------------------- linux/obc/pdec.h | 59 ++++++++++++ 5 files changed, 223 insertions(+), 113 deletions(-) create mode 100644 linux/obc/pdec.h diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 2fc1963c..1db53d3e 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -21,7 +21,7 @@ static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio_pdec_regs"; static constexpr char UIO_PTME[] = "/dev/uio_ptme"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio_pdec_cfg_mem"; static constexpr char UIO_PDEC_RAM[] = "/dev/uio_pdec_ram"; -static constexpr char UIO_PDEC_IRQ = "/dev/uio_pdec_irq"; +static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq"; static constexpr int MAP_ID_PTME_CONFIG = 3; namespace uiomapids { diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 82d066c8..2294631c 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -773,8 +773,13 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { Levels::LOW); gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC"); + struct UioNames uioNames {}; + uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY; + uioNames.ramMemory = q7s::UIO_PDEC_RAM; + uioNames.registers = q7s::UIO_PDEC_REGISTERS; + uioNames.irq = q7s::UIO_PDEC_IRQ; new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, - q7s::UIO_PDEC_CONFIG_MEMORY, q7s::UIO_PDEC_RAM, q7s::UIO_PDEC_REGISTERS); + uioNames); GpioCookie* gpioRS485Chip = new GpioCookie; gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", Direction::OUT, Levels::LOW); diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 63aedbce..1530a59a 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -1,7 +1,9 @@ #include "PdecHandler.h" #include +#include #include +#include #include #include @@ -12,18 +14,21 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw_hal/linux/uio/UioMapper.h" +#include "pdec.h" + +using namespace pdec; + +// If this is ever shared, protect it with a mutex! +uint32_t PdecHandler::CURRENT_FAR = 0; PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, - LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, - std::string uioRamMemory, std::string uioRegisters) + LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names) : SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset(pdecReset), - uioConfigMemory(uioConfigMemory), - uioRamMemory(uioRamMemory), - uioRegisters(uioRegisters), - actionHelper(this, nullptr) { + actionHelper(this, nullptr), + uioNames(names) { auto mqArgs = MqArgs(objectId, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); @@ -47,22 +52,27 @@ ReturnValue_t PdecHandler::initialize() { ReturnValue_t result = returnvalue::OK; - UioMapper regMapper(uioRegisters); + UioMapper regMapper(uioNames.registers); result = regMapper.getMappedAdress(®isterBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - UioMapper configMemMapper(uioConfigMemory); + UioMapper configMemMapper(uioNames.configMemory); result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - UioMapper ramMapper(uioRamMemory); + UioMapper ramMapper(uioNames.ramMemory); result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } + if (OP_MODE == Modes::IRQ and uioNames.irq == nullptr) { + sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl; + return returnvalue::FAILED; + } + writePdecConfig(); result = releasePdec(); @@ -110,7 +120,7 @@ ReturnValue_t PdecHandler::polledOperation() { case State::WAIT_FOR_RECOVERY: break; default: - sif::debug << "PdecHandler::performOperation: Invalid state" << std::endl; + sif::error << "PdecHandler::performOperation: Invalid state" << std::endl; break; } @@ -118,8 +128,76 @@ ReturnValue_t PdecHandler::polledOperation() { } ReturnValue_t PdecHandler::irqOperation() { + ReturnValue_t result = returnvalue::OK; + int fd = open(uioNames.irq, O_RDWR); + if (fd < 0) { + sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed" + << std::endl; + return returnvalue::FAILED; + } + + struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0}; + // Used to unmask IRQ + uint32_t info = 1; + ssize_t nb = 0; + int ret = 0; + while (true) { readCommandQueue(); + switch (state) { + case State::INIT: + resetFarStatFlag(); + if (result != returnvalue::OK) { + // Requires reconfiguration and reinitialization of PDEC + triggerEvent(INVALID_FAR); + state = State::WAIT_FOR_RECOVERY; + return result; + } + state = State::RUNNING; + break; + case State::RUNNING: { + // TODO: Add poll() based IRQ handling + nb = write(fd, &info, sizeof(info)); + if (nb != static_cast(sizeof(info))) { + sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl; + close(fd); + } + + ret = poll(&fds, 1, IRQ_TIMEOUT_MS); + if (ret == 0) { + // No TCs for timeout period + checkLocks(); + } else if (ret >= 1) { + nb = read(fd, &info, sizeof(info)); + if (nb == static_cast(sizeof(info))) { + uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET); + if ((pisr & TC_NEW_MASK) == TC_NEW_MASK) { + // handle TC + handleNewTc(); + } + if ((pisr & TC_ABORT_MASK) == TC_ABORT_MASK) { + tcAbortCounter += 1; + } + if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) { + // Read FAR here + CURRENT_FAR = readFar(); + } + // Clear interrupts with dummy read + ret = *(registerBaseAddress + PDEC_PIR_OFFSET); + } + } else { + sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": " + << strerror(errno) << std::endl; + triggerEvent(POLL_ERROR_PDEC, errno); + } + break; + } + case State::WAIT_FOR_RECOVERY: + break; + default: + sif::error << "PdecHandler::performOperation: Invalid state" << std::endl; + break; + } } return returnvalue::OK; } @@ -151,7 +229,7 @@ void PdecHandler::writePdecConfig() { if (OP_MODE == Modes::IRQ) { // Configure interrupt mask register to enable interrupts - *(memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); } // Configure all MAP IDs as invalid @@ -173,17 +251,19 @@ void PdecHandler::writePdecConfig() { } ReturnValue_t PdecHandler::resetFarStatFlag() { - uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); + uint32_t pdecFar = readFar(); if (pdecFar != FAR_RESET) { sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." << " Read value: 0x" << std::hex << static_cast(pdecFar) << std::endl; + CURRENT_FAR = pdecFar; return returnvalue::FAILED; } #if OBSW_DEBUG_PDEC_HANDLER == 1 sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar << std::endl; #endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ + CURRENT_FAR = pdecFar; return returnvalue::OK; } @@ -197,12 +277,14 @@ ReturnValue_t PdecHandler::releasePdec() { } bool PdecHandler::newTcReceived() { - uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); + uint32_t pdecFar = readFar(); if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) { + CURRENT_FAR = pdecFar; return false; } if (!checkFrameAna(pdecFar)) { + CURRENT_FAR = pdecFar; return false; } return true; @@ -519,6 +601,8 @@ void PdecHandler::printPdecMon() { sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl; } +uint32_t PdecHandler::readFar() { return *(registerBaseAddress + PDEC_FAR_OFFSET); } + std::string PdecHandler::getMonStatusString(uint32_t status) { switch (status) { case TC_CHANNEL_INACTIVE: diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index d003bae2..aad3cbdf 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -13,6 +13,13 @@ #include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +struct UioNames { + const char* configMemory; + const char* ramMemory; + const char* registers; + const char* irq; +}; + /** * @brief This class controls the PDEC IP Core implemented in the programmable logic of the * Zynq-7020. All registers and memories of the PDEC IP Core are accessed via UIO @@ -33,6 +40,8 @@ */ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { public: + static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500; + enum class Modes { POLLED, IRQ }; /** @@ -45,8 +54,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc * @param uioregsiters String of uio device file same mapped to the PDEC register space */ PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, - gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory, - std::string uioRegisters); + gpioId_t pdecReset, UioNames names); virtual ~PdecHandler(); @@ -76,6 +84,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO); //! [EXPORT] : [COMMENT] Lost bit lock static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO); + static constexpr Event POLL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 7, severity::MEDIUM); private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; @@ -116,50 +125,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc // Print PDEC monitor register static const ActionId_t PRINT_PDEC_MON = 1; - static const uint8_t STAT_POSITION = 31; - static const uint8_t FRAME_ANA_POSITION = 28; - static const uint8_t IREASON_POSITION = 25; - - static const uint8_t NEW_FAR_RECEIVED = 0; - - static const uint32_t FRAME_ANA_MASK = 0x70000000; - static const uint32_t IREASON_MASK = 0x0E000000; - - static const uint32_t TC_CHANNEL_INACTIVE = 0x0; - static const uint32_t TC_CHANNEL_ACTIVE = 0x1; - static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2; - - static const uint32_t TC0_STATUS_MASK = 0x3; - static const uint32_t TC1_STATUS_MASK = 0xC; - static const uint32_t TC2_STATUS_MASK = 0x300; - static const uint32_t TC3_STATUS_MASK = 0xC00; - static const uint32_t TC4_STATUS_MASK = 0x30000; - static const uint32_t TC5_STATUS_MASK = 0xc00000; - // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) - static const uint32_t LOCK_MASK = 0xc00000; - - static const uint32_t TC0_STATUS_POS = 0; - static const uint32_t TC1_STATUS_POS = 2; - static const uint32_t TC2_STATUS_POS = 4; - static const uint32_t TC3_STATUS_POS = 6; - static const uint32_t TC4_STATUS_POS = 8; - static const uint32_t TC5_STATUS_POS = 10; - // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) - static const uint32_t LOCK_POS = 12; - - /** - * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 - * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 - */ - static constexpr uint32_t PDEC_PIR_OFFSET = 0xA03; - static constexpr uint32_t PDEC_IMR_OFFSET = 0xA04; - static const uint32_t PDEC_FAR_OFFSET = 0xA10; - static const uint32_t PDEC_CLCW_OFFSET = 0xA12; - static const uint32_t PDEC_BFREE_OFFSET = 0xA24; - static const uint32_t PDEC_BPTR_OFFSET = 0xA25; - static const uint32_t PDEC_SLEN_OFFSET = 0xA26; - static const uint32_t PDEC_MON_OFFSET = 0xA27; - #ifdef TE0720_1CFA static const int CONFIG_MEMORY_MAP_SIZE = 0x400; static const int RAM_MAP_SIZE = 0x4000; @@ -233,6 +198,53 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc enum class State : uint8_t { INIT, RUNNING, WAIT_FOR_RECOVERY }; + static uint32_t CURRENT_FAR; + + object_id_t tcDestinationId; + + AcceptsTelecommandsIF* tcDestination = nullptr; + + LinuxLibgpioIF* gpioComIF = nullptr; + + /** + * Reset signal is required to hold PDEC in reset state until the configuration has been + * written to the appropriate memory space. + * Can also be used to reboot PDEC in case of erros. + */ + gpioId_t pdecReset = gpio::NO_GPIO; + + uint32_t tcAbortCounter = 0; + + ActionHelper actionHelper; + + StorageManagerIF* tcStore = nullptr; + + MessageQueueIF* commandQueue = nullptr; + + State state = State::INIT; + + /** + * Pointer pointing to base address of the PDEC memory space. + * This address is equivalent with the base address of the section named configuration area in + * the PDEC datasheet. + */ + uint32_t* memoryBaseAddress = nullptr; + + uint32_t* ramBaseAddress = nullptr; + + // Pointer pointing to base address of register space + uint32_t* registerBaseAddress = nullptr; + + 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; + + bool carrierLock = false; + bool bitLock = false; + + UioNames uioNames; + /** * @brief Reads and handles messages stored in the commandQueue */ @@ -241,6 +253,8 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc ReturnValue_t polledOperation(); ReturnValue_t irqOperation(); + uint32_t readFar(); + /** * @brief This functions writes the configuration parameters to the configuration * section of the PDEC. @@ -352,58 +366,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc void printPdecMon(); std::string getMonStatusString(uint32_t status); - - object_id_t tcDestinationId; - - AcceptsTelecommandsIF* tcDestination = nullptr; - - LinuxLibgpioIF* gpioComIF = nullptr; - - /** - * Reset signal is required to hold PDEC in reset state until the configuration has been - * written to the appropriate memory space. - * Can also be used to reboot PDEC in case of erros. - */ - gpioId_t pdecReset = gpio::NO_GPIO; - - // UIO device file giving access to the PDEC configuration memory section - std::string uioConfigMemory; - - // UIO device file giving access to the PDEC RAM section - std::string uioRamMemory; - - // 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; - - /** - * Pointer pointing to base address of the PDEC memory space. - * This address is equivalent with the base address of the section named configuration area in - * the PDEC datasheet. - */ - uint32_t* memoryBaseAddress = nullptr; - - uint32_t* ramBaseAddress = nullptr; - - // Pointer pointing to base address of register space - uint32_t* registerBaseAddress = nullptr; - - 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; - - bool carrierLock = false; - bool bitLock = false; }; #endif /* LINUX_OBC_PDECHANDLER_H_ */ diff --git a/linux/obc/pdec.h b/linux/obc/pdec.h new file mode 100644 index 00000000..bc82d61d --- /dev/null +++ b/linux/obc/pdec.h @@ -0,0 +1,59 @@ +#ifndef LINUX_OBC_PDEC_H_ +#define LINUX_OBC_PDEC_H_ + +#include + +namespace pdec { + +static const uint8_t STAT_POSITION = 31; +static const uint8_t FRAME_ANA_POSITION = 28; +static const uint8_t IREASON_POSITION = 25; + +static const uint8_t NEW_FAR_RECEIVED = 0; + +static constexpr uint32_t NEW_FAR_MASK = 1 << 2; +static constexpr uint32_t TC_ABORT_MASK = 1 << 1; +static constexpr uint32_t TC_NEW_MASK = 1 << 0; + +static const uint32_t FRAME_ANA_MASK = 0x70000000; +static const uint32_t IREASON_MASK = 0x0E000000; + +static const uint32_t TC_CHANNEL_INACTIVE = 0x0; +static const uint32_t TC_CHANNEL_ACTIVE = 0x1; +static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2; + +static const uint32_t TC0_STATUS_MASK = 0x3; +static const uint32_t TC1_STATUS_MASK = 0xC; +static const uint32_t TC2_STATUS_MASK = 0x300; +static const uint32_t TC3_STATUS_MASK = 0xC00; +static const uint32_t TC4_STATUS_MASK = 0x30000; +static const uint32_t TC5_STATUS_MASK = 0xc00000; +// Lock register set to 1 when start sequence has been found (CLTU is beeing processed) +static const uint32_t LOCK_MASK = 0xc00000; + +static const uint32_t TC0_STATUS_POS = 0; +static const uint32_t TC1_STATUS_POS = 2; +static const uint32_t TC2_STATUS_POS = 4; +static const uint32_t TC3_STATUS_POS = 6; +static const uint32_t TC4_STATUS_POS = 8; +static const uint32_t TC5_STATUS_POS = 10; +// Lock register set to 1 when start sequence has been found (CLTU is beeing processed) +static const uint32_t LOCK_POS = 12; + +/** + * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 + * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 + */ +static constexpr uint32_t PDEC_PISR_OFFSET = 0xA02; +static constexpr uint32_t PDEC_PIR_OFFSET = 0xA03; +static constexpr uint32_t PDEC_IMR_OFFSET = 0xA04; +static const uint32_t PDEC_FAR_OFFSET = 0xA10; +static const uint32_t PDEC_CLCW_OFFSET = 0xA12; +static const uint32_t PDEC_BFREE_OFFSET = 0xA24; +static const uint32_t PDEC_BPTR_OFFSET = 0xA25; +static const uint32_t PDEC_SLEN_OFFSET = 0xA26; +static const uint32_t PDEC_MON_OFFSET = 0xA27; + +} // namespace pdec + +#endif /* LINUX_OBC_PDEC_H_ */ From 24c050765b73e10849f1c98505385cac2fbb7e8d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Oct 2022 10:51:34 +0200 Subject: [PATCH 07/18] countdown to ensure periodic lock checking --- linux/obc/PdecHandler.cpp | 5 +++++ linux/obc/PdecHandler.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 1530a59a..54f0e1ff 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -167,6 +167,7 @@ ReturnValue_t PdecHandler::irqOperation() { if (ret == 0) { // No TCs for timeout period checkLocks(); + lockCheckCd.resetTimer(); } else if (ret >= 1) { nb = read(fd, &info, sizeof(info)); if (nb == static_cast(sizeof(info))) { @@ -182,6 +183,10 @@ ReturnValue_t PdecHandler::irqOperation() { // Read FAR here CURRENT_FAR = readFar(); } + if (lockCheckCd.hasTimedOut()) { + checkLocks(); + lockCheckCd.resetTimer(); + } // Clear interrupts with dummy read ret = *(registerBaseAddress + PDEC_PIR_OFFSET); } diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index aad3cbdf..be6299fb 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -1,6 +1,8 @@ #ifndef LINUX_OBC_PDECHANDLER_H_ #define LINUX_OBC_PDECHANDLER_H_ +#include + #include "OBSWConfig.h" #include "PdecConfig.h" #include "fsfw/action/ActionHelper.h" @@ -200,6 +202,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc static uint32_t CURRENT_FAR; + Countdown lockCheckCd = Countdown(IRQ_TIMEOUT_MS); object_id_t tcDestinationId; AcceptsTelecommandsIF* tcDestination = nullptr; From 885a7b0c6a8b6f5452e2f58265c195cdb6417a54 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 31 Oct 2022 18:13:29 +0100 Subject: [PATCH 08/18] bump submodules --- fsfw | 2 +- tmtc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 226dc4d8..24612091 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 226dc4d8b742fea832861bf70d37dc48beb15dc9 +Subproject commit 24612091690f191d799f30ba38b5f750d0617fa3 diff --git a/tmtc b/tmtc index 4420bf3d..044c600b 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 4420bf3df94f26b3270dd91ac0ef80cb3f8699df +Subproject commit 044c600b1ce13d58781a8d06125619c8cc0080f9 From e5fd62a121b01ba08997ca27add1e2fdfff66b6b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 31 Oct 2022 18:45:39 +0100 Subject: [PATCH 09/18] some updates for pdec and EM syrlinks tests --- bsp_q7s/em/emObjectFactory.cpp | 7 +++++++ dummies/helpers.cpp | 4 +++- dummies/helpers.h | 1 + linux/obc/PdecHandler.cpp | 2 -- tmtc | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 13ae55d6..36a66584 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -33,6 +33,9 @@ void ObjectFactory::produce(void* args) { // level components. dummy::DummyCfg dummyCfg; dummyCfg.addCoreCtrlCfg = false; +#if OBSW_ADD_SYRLINKS == 1 + dummyCfg.addSyrlinksDummies = false; +#endif dummy::createDummies(dummyCfg); new CoreController(objects::CORE_CONTROLLER); @@ -63,6 +66,10 @@ void ObjectFactory::produce(void* args) { createImtqComponents(pwrSwitcher); #endif +#if OBSW_ADD_SYRLINKS == 1 + createSyrlinksComponents(pwrSwitcher); +#endif /* OBSW_ADD_SYRLINKS == 1 */ + #if OBSW_ADD_RW == 1 createReactionWheelComponents(gpioComIF, pwrSwitcher); #endif diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index 2b18cffd..495d6f6c 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -38,7 +38,9 @@ void dummy::createDummies(DummyCfg cfg) { new RwDummy(objects::RW4, objects::DUMMY_COM_IF, comCookieDummy); new SaDeplDummy(objects::SOLAR_ARRAY_DEPL_HANDLER); new StarTrackerDummy(objects::STAR_TRACKER, objects::DUMMY_COM_IF, comCookieDummy); - new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + if (cfg.addSyrlinksDummies) { + new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + } new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addPowerDummies) { new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); diff --git a/dummies/helpers.h b/dummies/helpers.h index 680f97c1..f509f316 100644 --- a/dummies/helpers.h +++ b/dummies/helpers.h @@ -5,6 +5,7 @@ namespace dummy { struct DummyCfg { bool addCoreCtrlCfg = true; bool addPowerDummies = true; + bool addSyrlinksDummies = true; bool addAcsBoardDummies = true; bool addSusDummies = true; bool addTempSensorDummies = true; diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 54f0e1ff..3beb18dd 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -437,7 +437,6 @@ void PdecHandler::handleNewTc() { printTC(tcLength); #endif /* OBSW_DEBUG_PDEC_HANDLER */ -#if OBSW_TC_FROM_PDEC == 1 store_address_t storeId; result = tcStore->addData(&storeId, tcSegment + 1, tcLength - 1); if (result != returnvalue::OK) { @@ -455,7 +454,6 @@ void PdecHandler::handleNewTc() { tcStore->deleteData(storeId); return; } -#endif /* OBSW_TC_FROM_PDEC == 1 */ return; } diff --git a/tmtc b/tmtc index 044c600b..f99ca2f8 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 044c600b1ce13d58781a8d06125619c8cc0080f9 +Subproject commit f99ca2f8d8df6e37f4e50073aa2dbcefff232524 From 802b8519244d0b6ed8321b7826a119958c616f01 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 10:59:21 +0100 Subject: [PATCH 10/18] bump changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2000c4f4..1c55c298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ list yields a list of all related PRs for each release. # [unreleased] +- Add IRQ mode for PDEC handler + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/310 + # [v1.15.0] 27.10.2022 - Consistent device file naming From 8297bca969511667892a9efdcee2a97f66aba46b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 15:22:05 +0100 Subject: [PATCH 11/18] small EM fix --- bsp_q7s/em/emObjectFactory.cpp | 2 +- linux/ipcore/PdecHandler.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 58b52a6e..8667154b 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -98,5 +98,5 @@ void ObjectFactory::produce(void* args) { createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), true, std::nullopt); #endif - createAcsController(); + createAcsController(true); } diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 3beb18dd..33995675 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -156,7 +156,6 @@ ReturnValue_t PdecHandler::irqOperation() { state = State::RUNNING; break; case State::RUNNING: { - // TODO: Add poll() based IRQ handling nb = write(fd, &info, sizeof(info)); if (nb != static_cast(sizeof(info))) { sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl; From a45e7d756199e544b162769e94c41dfbee98a9d4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 15:33:54 +0100 Subject: [PATCH 12/18] debug printout --- linux/ipcore/PdecHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 33995675..ff1f819d 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -167,6 +167,8 @@ ReturnValue_t PdecHandler::irqOperation() { // No TCs for timeout period checkLocks(); lockCheckCd.resetTimer(); + uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET); + sif::debug << "Current PISR: " << pisr << std::endl; } else if (ret >= 1) { nb = read(fd, &info, sizeof(info)); if (nb == static_cast(sizeof(info))) { From 3995b15ccf22a3ed457b09e40f7b378c412617e4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 15:55:40 +0100 Subject: [PATCH 13/18] bugfixes for dummies --- dummies/SusDummy.cpp | 2 +- dummies/TemperatureSensorsDummy.cpp | 2 +- fsfw | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dummies/SusDummy.cpp b/dummies/SusDummy.cpp index 2a2a1bda..4760c51e 100644 --- a/dummies/SusDummy.cpp +++ b/dummies/SusDummy.cpp @@ -6,7 +6,7 @@ #include SusDummy::SusDummy() - : ExtendedControllerBase(objects::SUS_0_N_LOC_XFYFZM_PT_XF, objects::NO_OBJECT), susSet(this) { + : ExtendedControllerBase(objects::SUS_0_N_LOC_XFYFZM_PT_XF), susSet(this) { ObjectManager::instance()->insert(objects::SUS_6_R_LOC_XFYBZM_PT_XF, this); ObjectManager::instance()->insert(objects::SUS_1_N_LOC_XBYFZM_PT_XB, this); ObjectManager::instance()->insert(objects::SUS_7_R_LOC_XBYBZM_PT_XB, this); diff --git a/dummies/TemperatureSensorsDummy.cpp b/dummies/TemperatureSensorsDummy.cpp index 49194e91..c580473a 100644 --- a/dummies/TemperatureSensorsDummy.cpp +++ b/dummies/TemperatureSensorsDummy.cpp @@ -6,7 +6,7 @@ #include TemperatureSensorsDummy::TemperatureSensorsDummy() - : ExtendedControllerBase(objects::RTD_0_IC3_PLOC_HEATSPREADER, objects::NO_OBJECT), + : ExtendedControllerBase(objects::RTD_0_IC3_PLOC_HEATSPREADER), max31865Set(this, MAX31865::MAX31865_SET_ID) { ObjectManager::instance()->insert(objects::RTD_1_IC4_PLOC_MISSIONBOARD, this); ObjectManager::instance()->insert(objects::RTD_2_IC5_4K_CAMERA, this); diff --git a/fsfw b/fsfw index 7600ed1e..e302c89f 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 7600ed1ea70ef2998739800f84722dd7cadb7552 +Subproject commit e302c89f7465dee400b75a43fd562b4ef1470c24 From 098f69b1bcce9a1ec4683c1c74c0d53d3fe6c7bb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 15:56:05 +0100 Subject: [PATCH 14/18] dummy fix --- dummies/CoreControllerDummy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dummies/CoreControllerDummy.cpp b/dummies/CoreControllerDummy.cpp index fd2e3f63..d2ed7bb8 100644 --- a/dummies/CoreControllerDummy.cpp +++ b/dummies/CoreControllerDummy.cpp @@ -7,7 +7,7 @@ #include CoreControllerDummy::CoreControllerDummy(object_id_t objectId) - : ExtendedControllerBase(objectId, objects::NO_OBJECT) {} + : ExtendedControllerBase(objectId) {} ReturnValue_t CoreControllerDummy::initialize() { static bool done = false; From ddc68669fc3c63b946f7ea4b0cd61633474ae938 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 16:08:44 +0100 Subject: [PATCH 15/18] bump deps --- fsfw | 2 +- tmtc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index e302c89f..e1d4209f 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit e302c89f7465dee400b75a43fd562b4ef1470c24 +Subproject commit e1d4209fbe06581c36dd0a1b8113dfb56e673613 diff --git a/tmtc b/tmtc index f3609b81..074eb82e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f3609b81799790578c095262f33c11add3c0b078 +Subproject commit 074eb82e78d2d0f9e0ecfbc2020cd8d0532255ba From b2e3bc7e7a0b94ddb28a80b19e139c3ea11f9371 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 16:32:00 +0100 Subject: [PATCH 16/18] some more tests --- linux/ipcore/PdecHandler.cpp | 3 +++ linux/ipcore/PdecHandler.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index ff1f819d..a1030382 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -130,6 +130,7 @@ ReturnValue_t PdecHandler::polledOperation() { ReturnValue_t PdecHandler::irqOperation() { ReturnValue_t result = returnvalue::OK; int fd = open(uioNames.irq, O_RDWR); + sif::info << uioNames.irq << std::endl; if (fd < 0) { sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed" << std::endl; @@ -141,6 +142,8 @@ ReturnValue_t PdecHandler::irqOperation() { uint32_t info = 1; ssize_t nb = 0; int ret = 0; + // Clear interrupts with dummy read before unmasking the interrupt + ret = *(registerBaseAddress + PDEC_PIR_OFFSET); while (true) { readCommandQueue(); diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index be6299fb..61b0f811 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -91,7 +91,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; - static constexpr Modes OP_MODE = Modes::POLLED; + static constexpr Modes OP_MODE = Modes::IRQ; static const ReturnValue_t ABANDONED_CLTU = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t FRAME_DIRTY = MAKE_RETURN_CODE(0xA1); From 2d821ef8df691117d51383317c5272c1cf022161 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 18:58:29 +0100 Subject: [PATCH 17/18] irq working --- dummies/CoreControllerDummy.cpp | 3 +-- dummies/SusDummy.cpp | 3 +-- linux/ipcore/PdecHandler.cpp | 24 ++++++++++-------------- linux/ipcore/PdecHandler.h | 2 +- linux/ipcore/pdec.h | 2 ++ mission/core/GenericFactory.cpp | 8 ++++---- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/dummies/CoreControllerDummy.cpp b/dummies/CoreControllerDummy.cpp index d2ed7bb8..8a027dbf 100644 --- a/dummies/CoreControllerDummy.cpp +++ b/dummies/CoreControllerDummy.cpp @@ -6,8 +6,7 @@ #include #include -CoreControllerDummy::CoreControllerDummy(object_id_t objectId) - : ExtendedControllerBase(objectId) {} +CoreControllerDummy::CoreControllerDummy(object_id_t objectId) : ExtendedControllerBase(objectId) {} ReturnValue_t CoreControllerDummy::initialize() { static bool done = false; diff --git a/dummies/SusDummy.cpp b/dummies/SusDummy.cpp index 4760c51e..6d02ba69 100644 --- a/dummies/SusDummy.cpp +++ b/dummies/SusDummy.cpp @@ -5,8 +5,7 @@ #include #include -SusDummy::SusDummy() - : ExtendedControllerBase(objects::SUS_0_N_LOC_XFYFZM_PT_XF), susSet(this) { +SusDummy::SusDummy() : ExtendedControllerBase(objects::SUS_0_N_LOC_XFYFZM_PT_XF), susSet(this) { ObjectManager::instance()->insert(objects::SUS_6_R_LOC_XFYBZM_PT_XF, this); ObjectManager::instance()->insert(objects::SUS_1_N_LOC_XBYFZM_PT_XB, this); ObjectManager::instance()->insert(objects::SUS_7_R_LOC_XBYBZM_PT_XB, this); diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index a1030382..8f5be22d 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -72,14 +72,19 @@ ReturnValue_t PdecHandler::initialize() { sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl; return returnvalue::FAILED; } - - writePdecConfig(); + PdecConfig pdecConfig; + writePdecConfigDuringReset(pdecConfig); result = releasePdec(); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } + // This configuration must be done while the PDEC is not held in reset. + if (OP_MODE == Modes::IRQ) { + // Configure interrupt mask register to enable interrupts + *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + } result = actionHelper.initialize(commandQueue); if (result != returnvalue::OK) { return result; @@ -170,8 +175,6 @@ ReturnValue_t PdecHandler::irqOperation() { // No TCs for timeout period checkLocks(); lockCheckCd.resetTimer(); - uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET); - sif::debug << "Current PISR: " << pisr << std::endl; } else if (ret >= 1) { nb = read(fd, &info, sizeof(info)); if (nb == static_cast(sizeof(info))) { @@ -230,17 +233,10 @@ void PdecHandler::readCommandQueue(void) { MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } -void PdecHandler::writePdecConfig() { - PdecConfig pdecConfig; - +void PdecHandler::writePdecConfigDuringReset(PdecConfig& pdecConfig) { *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); - if (OP_MODE == Modes::IRQ) { - // Configure interrupt mask register to enable interrupts - *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); - } - // Configure all MAP IDs as invalid for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = @@ -261,8 +257,8 @@ void PdecHandler::writePdecConfig() { ReturnValue_t PdecHandler::resetFarStatFlag() { uint32_t pdecFar = readFar(); - if (pdecFar != FAR_RESET) { - sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." + if ((pdecFar & FAR_STAT_MASK) != FAR_STAT_MASK) { + sif::warning << "PdecHandler::resetFarStatFlag: FAR register stat bit is not set." << " Read value: 0x" << std::hex << static_cast(pdecFar) << std::endl; CURRENT_FAR = pdecFar; diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 61b0f811..b7089999 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -262,7 +262,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc * @brief This functions writes the configuration parameters to the configuration * section of the PDEC. */ - void writePdecConfig(); + void writePdecConfigDuringReset(PdecConfig& config); /** * @brief Reading the FAR resets the set stat flag which signals a new TC. Without clearing diff --git a/linux/ipcore/pdec.h b/linux/ipcore/pdec.h index bc82d61d..16b0c2e6 100644 --- a/linux/ipcore/pdec.h +++ b/linux/ipcore/pdec.h @@ -15,6 +15,8 @@ static constexpr uint32_t NEW_FAR_MASK = 1 << 2; static constexpr uint32_t TC_ABORT_MASK = 1 << 1; static constexpr uint32_t TC_NEW_MASK = 1 << 0; +static constexpr uint32_t FAR_STAT_MASK = 1 << 31; + static const uint32_t FRAME_ANA_MASK = 0x70000000; static const uint32_t IREASON_MASK = 0x0E000000; diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 8f4924f1..f00c4007 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -80,14 +80,14 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun StorageManagerIF* tcStore; StorageManagerIF* tmStore; { - PoolManager::LocalPoolConfig poolCfg = {{200, 16}, {200, 32}, {150, 64}, - {100, 128}, {100, 1024}, {100, 2048}}; + PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64}, + {150, 128}, {120, 1024}, {120, 2048}}; tcStore = new PoolManager(objects::TC_STORE, poolCfg); } { - PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {300, 32}, {100, 64}, - {100, 128}, {100, 1024}, {100, 2048}}; + PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {300, 32}, {250, 64}, + {150, 128}, {120, 1024}, {120, 2048}}; tmStore = new PoolManager(objects::TM_STORE, poolCfg); } From 70092b348aeb1d2e798bc802cf0c27fd4c04d61b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 19:15:07 +0100 Subject: [PATCH 18/18] pdec handler has higher priority now --- bsp_q7s/core/InitMission.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 67dbfabb..96b2fdfc 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -131,7 +131,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.0, missedDeadlineFunc); + "PDEC_HANDLER", 75, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); if (result != returnvalue::OK) { initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);