From 6c39e7dd0c78dc822f9ed9e47be20902c8be06a3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jun 2023 17:08:39 +0200 Subject: [PATCH 01/12] and go back to newest version here --- bsp_q7s/boardconfig/busConf.h | 4 - bsp_q7s/core/ObjectFactory.cpp | 29 ++--- common/config/devices/gpioIds.h | 4 - linux/ipcore/PapbVcInterface.cpp | 120 ++++---------------- linux/ipcore/PapbVcInterface.h | 10 +- mission/com/PersistentLogTmStoreTask.cpp | 6 - mission/com/PersistentSingleTmStoreTask.cpp | 6 - 7 files changed, 32 insertions(+), 147 deletions(-) diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 6a3e0d9e..146386c4 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -85,13 +85,9 @@ static constexpr char EN_RW_4[] = "enable_rw_4"; static constexpr char RAD_SENSOR_CHIP_SELECT[] = "rad_sensor_chip_select"; static constexpr char ENABLE_RADFET[] = "enable_radfet"; -static constexpr char PAPB_BUSY_SIGNAL_VC0[] = "papb_busy_signal_vc0"; static constexpr char PAPB_EMPTY_SIGNAL_VC0[] = "papb_empty_signal_vc0"; -static constexpr char PAPB_BUSY_SIGNAL_VC1[] = "papb_busy_signal_vc1"; static constexpr char PAPB_EMPTY_SIGNAL_VC1[] = "papb_empty_signal_vc1"; -static constexpr char PAPB_BUSY_SIGNAL_VC2[] = "papb_busy_signal_vc2"; static constexpr char PAPB_EMPTY_SIGNAL_VC2[] = "papb_empty_signal_vc2"; -static constexpr char PAPB_BUSY_SIGNAL_VC3[] = "papb_busy_signal_vc3"; static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3"; static constexpr char PTME_RESETN[] = "ptme_resetn"; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index af568553..35d30c1a 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -731,20 +731,12 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { // GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core GpioCookie* gpioCookiePtmeIp = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, "PAPB VC0"); - gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, "PAPB VC0"); gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, "PAPB VC1"); - gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, "PAPB VC1"); gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, "PAPB VC2"); - gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, "PAPB VC2"); gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, "PAPB VC3"); - gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3"); gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::PTME_RESETN, "PTME RESETN", @@ -753,19 +745,14 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs"); // Creating virtual channel interfaces - VirtualChannelIF* vc0 = - new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, - q7s::UIO_PTME, q7s::uiomapids::PTME_VC0); - VirtualChannelIF* vc1 = - new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, - q7s::UIO_PTME, q7s::uiomapids::PTME_VC1); - VirtualChannelIF* vc2 = - new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY, - q7s::UIO_PTME, q7s::uiomapids::PTME_VC2); - VirtualChannelIF* vc3 = - new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY, - q7s::UIO_PTME, q7s::uiomapids::PTME_VC3); - + VirtualChannelIF* vc0 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_EMPTY, + q7s::UIO_PTME, q7s::uiomapids::PTME_VC0); + VirtualChannelIF* vc1 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_EMPTY, + q7s::UIO_PTME, q7s::uiomapids::PTME_VC1); + VirtualChannelIF* vc2 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_EMPTY, + q7s::UIO_PTME, q7s::uiomapids::PTME_VC2); + VirtualChannelIF* vc3 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_EMPTY, + q7s::UIO_PTME, q7s::uiomapids::PTME_VC3); // Creating ptme object and adding virtual channel interfaces Ptme* ptme = new Ptme(objects::PTME); ptme->addVcInterface(ccsds::VC0, vc0); diff --git a/common/config/devices/gpioIds.h b/common/config/devices/gpioIds.h index ac193bd2..bed82142 100644 --- a/common/config/devices/gpioIds.h +++ b/common/config/devices/gpioIds.h @@ -96,13 +96,9 @@ enum gpioId_t { SPI_MUX, VC0_PAPB_EMPTY, - VC0_PAPB_BUSY, VC1_PAPB_EMPTY, - VC1_PAPB_BUSY, VC2_PAPB_EMPTY, - VC2_PAPB_BUSY, VC3_PAPB_EMPTY, - VC3_PAPB_BUSY, PTME_RESETN, PDEC_RESET, diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 60968cc6..404f3653 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -7,20 +7,16 @@ #include "fsfw/serviceinterface/ServiceInterface.h" -PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, - gpioId_t papbEmptyId, std::string uioFile, int mapNum) - : gpioComIF(gpioComIF), - papbBusyId(papbBusyId), - papbEmptyId(papbEmptyId), - uioFile(std::move(uioFile)), - mapNum(mapNum) {} +PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId, + std::string uioFile, int mapNum) + : gpioComIF(gpioComIF), papbEmptyId(papbEmptyId), uioFile(std::move(uioFile)), mapNum(mapNum) {} PapbVcInterface::~PapbVcInterface() {} ReturnValue_t PapbVcInterface::initialize() { UioMapper uioMapper(uioFile, mapNum); ReturnValue_t result = uioMapper.getMappedAdress(const_cast(&vcBaseReg), - UioMapper::Permissions::WRITE_ONLY); + UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return result; } @@ -32,63 +28,16 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { if (size < 4) { return returnvalue::FAILED; } - if (pollInterfaceReadiness(0, true) == returnvalue::OK) { + if (pollReadyForPacket()) { startPacketTransfer(ByteWidthCfg::ONE); } else { return DirectTmSinkIF::IS_BUSY; } - // TODO: This should work but does not.. :( - // size_t idx = 0; - // while (idx < size) { - // - // nanosleep(&BETWEEN_POLL_DELAY, &remDelay); - // if ((size - idx) < 4) { - // *vcBaseReg = CONFIG_DATA_INPUT | (size - idx - 1); - // usleep(1); - // } - // if (pollPapbBusySignal(2) == returnvalue::OK) { - // // vcBaseReg + DATA_REG_OFFSET + 3 = static_cast(data + idx); - // // vcBaseReg + DATA_REG_OFFSET + 2 = static_cast(data + idx + 1); - // // vcBaseReg + DATA_REG_OFFSET + 1 = static_cast(data + idx + 2); - // // vcBaseReg + DATA_REG_OFFSET = static_cast(data + idx + 3); - // - // // std::memcpy((vcBaseReg + DATA_REG_OFFSET), data + idx , nextWriteSize); - // *(vcBaseReg + DATA_REG_OFFSET) = *reinterpret_cast(data + idx); - // //uint8_t* byteReg = reinterpret_cast(vcBaseReg + DATA_REG_OFFSET); - // - // //byteReg[0] = data[idx]; - // //byteReg[1] = data[idx]; - // } else { - // abortPacketTransfer(); - // return returnvalue::FAILED; - // } - // // TODO: Change this after the bugfix. Right now, the PAPB ignores the content of the byte - // // width configuration.5 - // // It's okay to increment by a larger amount for the last segment here, loop will be over - // // in any case. - // idx += 4; - // } for (size_t idx = 0; idx < size; idx++) { - // This delay is super-important, DO NOT REMOVE! - // Polling the GPIO or the config register too often messes up the scheduler. - // TODO: Maybe this should not be done like this. It would be better if there was a custom - // FPGA module which can accept packets and then takes care of dumping that packet into - // the PTME. DMA would be an ideal solution for this. - nanosleep(&BETWEEN_POLL_DELAY, &remDelay); - if (pollInterfaceReadiness(2, false) == returnvalue::OK) { - *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); - } else { - abortPacketTransfer(); - return returnvalue::FAILED; - } - } - nanosleep(&BETWEEN_POLL_DELAY, &remDelay); - if (pollInterfaceReadiness(2, false) == returnvalue::OK) { - completePacketTransfer(); - } else { - abortPacketTransfer(); - return returnvalue::FAILED; + // if (pollInterfaceReadiness(2, false) == returnvalue::OK) { + *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } + completePacketTransfer(); return returnvalue::OK; } @@ -98,60 +47,33 @@ void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) { void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } -ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries, - bool checkReadyState) const { - uint32_t busyIdx = 0; - nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS; - - while (true) { - // Check if PAPB interface is ready to receive data. Use the configuration register for this. - // Bit 5, see PTME ptme_001_01-0-7-r2 Table 31. - uint32_t reg = *vcBaseReg; - bool busy = (reg >> 5) & 0b1; - bool ready = (reg >> 6) & 0b1; - if (not busy) { - return returnvalue::OK; - } - if (checkReadyState and not ready) { - return PAPB_BUSY; - } - - busyIdx++; - if (busyIdx >= maxPollRetries) { - return PAPB_BUSY; - } - - // Ignore signal handling here for now. - nanosleep(&nextDelay, &remDelay); - // Adaptive delay. - if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { - nextDelay.tv_nsec *= 2; - } - } - return returnvalue::OK; +bool PapbVcInterface::pollReadyForPacket() const { + // Check if PAPB interface is ready to receive data. Use the configuration register for this. + // Bit 5, see PTME ptme_001_01-0-7-r2 Table 31. + uint32_t reg = *vcBaseReg; + // bool busy = (reg >> 5) & 0b1; + return (reg >> 6) & 0b1; } -void PapbVcInterface::isVcInterfaceBufferEmpty() { +bool PapbVcInterface::isVcInterfaceBufferEmpty() { ReturnValue_t result = returnvalue::OK; gpio::Levels papbEmptyState = gpio::Levels::HIGH; result = gpioComIF->readGpio(papbEmptyId, papbEmptyState); if (result != returnvalue::OK) { - sif::warning << "PapbVcInterface::isVcInterfaceBufferEmpty: Failed to read papb empty signal" - << std::endl; - return; + sif::error << "PapbVcInterface::isVcInterfaceBufferEmpty: Failed to read papb empty signal" + << std::endl; + return true; } if (papbEmptyState == gpio::Levels::HIGH) { - sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Buffer is empty" << std::endl; - } else { - sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Buffer is not empty" << std::endl; + return true; } - return; + return false; } -bool PapbVcInterface::isBusy() const { return pollInterfaceReadiness(0, true) == PAPB_BUSY; } +bool PapbVcInterface::isBusy() const { return not pollReadyForPacket(); } void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); } diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index e54def5d..ba6063b5 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -30,8 +30,7 @@ class PapbVcInterface : public VirtualChannelIF { * @param uioFile UIO file providing access to the PAPB bus * @param mapNum Map number of UIO map associated with this virtual channel */ - PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, gpioId_t papbEmptyId, - std::string uioFile, int mapNum); + PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId, std::string uioFile, int mapNum); virtual ~PapbVcInterface(); bool isBusy() const override; @@ -83,9 +82,6 @@ class PapbVcInterface : public VirtualChannelIF { static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; LinuxLibgpioIF* gpioComIF = nullptr; - - /** Pulled to low when virtual channel not ready to receive data */ - gpioId_t papbBusyId = gpio::NO_GPIO; /** High when external buffer memory of virtual channel is empty */ gpioId_t papbEmptyId = gpio::NO_GPIO; @@ -120,13 +116,13 @@ class PapbVcInterface : public VirtualChannelIF { * * @return returnvalue::OK when ready to receive data else PAPB_BUSY. */ - inline ReturnValue_t pollInterfaceReadiness(uint32_t maxPollRetries, bool checkReadyState) const; + inline bool pollReadyForPacket() const; /** * @brief This function can be used for debugging to check whether there are packets in * the packet buffer of the virtual channel or not. */ - void isVcInterfaceBufferEmpty(); + bool isVcInterfaceBufferEmpty(); /** * @brief This function sends a complete telemetry transfer frame data field (1105 bytes) diff --git a/mission/com/PersistentLogTmStoreTask.cpp b/mission/com/PersistentLogTmStoreTask.cpp index 77f2bb7d..28545457 100644 --- a/mission/com/PersistentLogTmStoreTask.cpp +++ b/mission/com/PersistentLogTmStoreTask.cpp @@ -42,13 +42,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { if (not someonesBusy) { TaskFactory::delayTask(100); } else if (vcBusyDuringDump) { - // TODO: Might not be necessary - sif::debug << "VC busy, delaying" << std::endl; TaskFactory::delayTask(10); - } else { - // TODO: Would be best to remove this, but not delaying here can lead to evil issues. - // Polling the PAPB of the PTME core too often leads to scheuduling issues. - TaskFactory::delayTask(2); } } } diff --git a/mission/com/PersistentSingleTmStoreTask.cpp b/mission/com/PersistentSingleTmStoreTask.cpp index 1b77365b..d6f43289 100644 --- a/mission/com/PersistentSingleTmStoreTask.cpp +++ b/mission/com/PersistentSingleTmStoreTask.cpp @@ -24,13 +24,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { if (not busy) { TaskFactory::delayTask(100); } else if (dumpContext.vcBusyDuringDump) { - sif::debug << "VC busy, delaying" << std::endl; - // TODO: Might not be necessary TaskFactory::delayTask(10); - } else { - // TODO: Would be best to remove this, but not delaying here can lead to evil issues. - // Polling the PAPB of the PTME core too often leads to scheuduling issues. - TaskFactory::delayTask(2); } } } -- 2.43.0 From 27f77799a6e9614fc13857635bb06c388e2406e5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jun 2023 17:33:17 +0200 Subject: [PATCH 02/12] bump major version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d391877c..60412e93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ # ############################################################################## cmake_minimum_required(VERSION 3.13) -set(OBSW_VERSION_MAJOR 5) +set(OBSW_VERSION_MAJOR 6) set(OBSW_VERSION_MINOR 0) set(OBSW_VERSION_REVISION 0) -- 2.43.0 From c881b36630b28a37c5f3164cc62b6fea82f01217 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jun 2023 15:28:27 +0200 Subject: [PATCH 03/12] prevent warning --- linux/ipcore/AxiPtmeConfig.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/linux/ipcore/AxiPtmeConfig.cpp b/linux/ipcore/AxiPtmeConfig.cpp index d3d5662a..7f044c79 100644 --- a/linux/ipcore/AxiPtmeConfig.cpp +++ b/linux/ipcore/AxiPtmeConfig.cpp @@ -26,8 +26,7 @@ ReturnValue_t AxiPtmeConfig::initialize() { } ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) { - ReturnValue_t result = returnvalue::OK; - result = mutex->lockMutex(timeoutType, mutexTimeout); + ReturnValue_t result = mutex->lockMutex(timeoutType, mutexTimeout); if (result != returnvalue::OK) { sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to lock mutex" << std::endl; return returnvalue::FAILED; @@ -42,7 +41,6 @@ ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) { } uint8_t AxiPtmeConfig::readCaduRateReg() { - ReturnValue_t result = returnvalue::OK; MutexGuard mg(mutex); return static_cast(*(baseAddress + CADU_BITRATE_REG)); } -- 2.43.0 From 9dfdf388225f7cbc9d5e7faf4085b42aff570cf1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jun 2023 17:20:10 +0200 Subject: [PATCH 04/12] important bugfix for live channel --- linux/ipcore/PapbVcInterface.cpp | 1 - mission/com/LiveTmTask.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 404f3653..98cb1b41 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -34,7 +34,6 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - // if (pollInterfaceReadiness(2, false) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } completePacketTransfer(); diff --git a/mission/com/LiveTmTask.cpp b/mission/com/LiveTmTask.cpp index d09c6ced..b3358789 100644 --- a/mission/com/LiveTmTask.cpp +++ b/mission/com/LiveTmTask.cpp @@ -20,7 +20,7 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) { readCommandQueue(); while (true) { bool performWriteOp = true; - if (mode == MODE_OFF or ptmeLocked) { + if (ptmeLocked) { performWriteOp = false; } -- 2.43.0 From b57283101b9501c88ae1d87f5de0e37e7f5163f3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jun 2023 17:20:10 +0200 Subject: [PATCH 05/12] important bugfix for live channel --- mission/com/LiveTmTask.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mission/com/LiveTmTask.cpp b/mission/com/LiveTmTask.cpp index d09c6ced..39648c15 100644 --- a/mission/com/LiveTmTask.cpp +++ b/mission/com/LiveTmTask.cpp @@ -19,13 +19,8 @@ LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunne ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) { readCommandQueue(); while (true) { - bool performWriteOp = true; - if (mode == MODE_OFF or ptmeLocked) { - performWriteOp = false; - } - // The funnel tasks are scheduled here directly as well. - ReturnValue_t result = channel.handleNextTm(performWriteOp); + ReturnValue_t result = channel.handleNextTm(!ptmeLocked); if (result == DirectTmSinkIF::IS_BUSY) { sif::error << "Lost live TM, PAPB busy" << std::endl; } -- 2.43.0 From 25da1316535cdc053ee96bc2036e5a082f50ccfe Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 00:33:58 +0200 Subject: [PATCH 06/12] seems to work well --- linux/ipcore/PapbVcInterface.cpp | 27 ++++++++++++++++++++++++++- linux/ipcore/PapbVcInterface.h | 3 +++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 98cb1b41..5dcb4519 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -33,9 +33,21 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { } else { return DirectTmSinkIF::IS_BUSY; } + if (not pollReadyForOctet(MAX_BUSY_POLLS)) { + abortPacketTransfer(); + return returnvalue::FAILED; + } for (size_t idx = 0; idx < size; idx++) { + if (not pollReadyForOctet(MAX_BUSY_POLLS)) { + abortPacketTransfer(); + return returnvalue::FAILED; + } *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } + if (not pollReadyForOctet(MAX_BUSY_POLLS)) { + abortPacketTransfer(); + return returnvalue::FAILED; + } completePacketTransfer(); return returnvalue::OK; } @@ -50,7 +62,6 @@ bool PapbVcInterface::pollReadyForPacket() const { // Check if PAPB interface is ready to receive data. Use the configuration register for this. // Bit 5, see PTME ptme_001_01-0-7-r2 Table 31. uint32_t reg = *vcBaseReg; - // bool busy = (reg >> 5) & 0b1; return (reg >> 6) & 0b1; } @@ -76,6 +87,20 @@ bool PapbVcInterface::isBusy() const { return not pollReadyForPacket(); } void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); } +inline bool PapbVcInterface::pollReadyForOctet(uint32_t maxCycles) const { + uint32_t reg; + uint32_t idx = 0; + while (idx < maxCycles) { + reg = *vcBaseReg; + // Busy bit. + if (not((reg >> 5) & 0b1)) { + return true; + } + idx++; + } + return false; +} + ReturnValue_t PapbVcInterface::sendTestFrame() { /** Size of one complete transfer frame data field amounts to 1105 bytes */ uint8_t testPacket[1105]; diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index ba6063b5..9c6734e8 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -80,6 +80,7 @@ class PapbVcInterface : public VirtualChannelIF { static constexpr long int FIRST_DELAY_PAPB_POLLING_NS = 10; static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; + static constexpr uint32_t MAX_BUSY_POLLS = 100000; LinuxLibgpioIF* gpioComIF = nullptr; /** High when external buffer memory of virtual channel is empty */ @@ -118,6 +119,8 @@ class PapbVcInterface : public VirtualChannelIF { */ inline bool pollReadyForPacket() const; + inline bool pollReadyForOctet(uint32_t maxCycles) const; + /** * @brief This function can be used for debugging to check whether there are packets in * the packet buffer of the virtual channel or not. -- 2.43.0 From 03e772246f1a5211f815ac8691da86d36b8b32e4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 00:35:06 +0200 Subject: [PATCH 07/12] less cycles.. --- linux/ipcore/PapbVcInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 9c6734e8..b5160748 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -80,7 +80,7 @@ class PapbVcInterface : public VirtualChannelIF { static constexpr long int FIRST_DELAY_PAPB_POLLING_NS = 10; static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; - static constexpr uint32_t MAX_BUSY_POLLS = 100000; + static constexpr uint32_t MAX_BUSY_POLLS = 1000; LinuxLibgpioIF* gpioComIF = nullptr; /** High when external buffer memory of virtual channel is empty */ -- 2.43.0 From 2173d890475d3e685ebc2d5e0454268c6228b1e8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 08:54:34 +0200 Subject: [PATCH 08/12] changelog --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fda0e54..95a4d7d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,12 @@ will consitute of a breaking change warranting a new major release: - Important bugfixes for PTME. See `q7s-package` CHANGELOG. -# [v5.1.0] to be released +## Fixed + +- For the live channel (VC0), telemetry was still only dumped if the transmitter is active. + Please note that this fix will lead to crashes for FW version v4. + +# [v5.1.0] 2023-06-28 - `eive-tmtc` version v5.1.0 -- 2.43.0 From 4f5903227e92ce01b0654e7291966b9848a835c6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 08:54:58 +0200 Subject: [PATCH 09/12] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a4d7d0..9e74bdd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ will consitute of a breaking change warranting a new major release: ## Fixed - For the live channel (VC0), telemetry was still only dumped if the transmitter is active. - Please note that this fix will lead to crashes for FW version v4. + Please note that this fix will lead to crashes for FW versions below v3.2. # [v5.1.0] 2023-06-28 -- 2.43.0 From 04d24e74b1b1e00277f71e2c788f00ac657ee4b5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 15:01:54 +0200 Subject: [PATCH 10/12] q7s-package version specification --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77281df0..2b3ef9f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ will consitute of a breaking change warranting a new major release: # [v6.0.0] to be released +- `q7s-package` version v3.2.0 - Important bugfixes for PTME. See `q7s-package` CHANGELOG. ## Fixed -- 2.43.0 From 4fc999e10226cf93653ab9e6dd2bb47e801707c1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 15:03:45 +0200 Subject: [PATCH 11/12] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5881296..116649da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,11 @@ will consitute of a breaking change warranting a new major release: - Important bugfixes for PTME. See `q7s-package` CHANGELOG. +## Changed + +- Added back PTME busy bit polling. This is necessary due to changes to the AXI APB interface + to the PTME core. + # [v5.2.0] 2023-06-29 ## Fixed -- 2.43.0 From 56ea9af615e97dfc22c1113f52f94d701dcbef0c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jun 2023 15:06:25 +0200 Subject: [PATCH 12/12] add documentation of initial delay --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6b06283c..ce57c33f 100644 --- a/README.md +++ b/README.md @@ -964,6 +964,12 @@ used by other software components to read the current chip and copy. This is a configuration scripts which runs after the Network Time Protocol has run. This script currently sets the static IP address `192.168.133.10` and starts the `can` interface. +## Initial boot delay + +You can create a file named `boot_delays_secs.txt` inside the home folder to delay the OBSW boot +for 6 seconds if the file is empty of for the number of seconds specified inside the file. This +can be helpful if something inside the OBSW leads to an immediate crash of the OBC. + ## PCDU Connect to serial console of P60 Dock -- 2.43.0