From 709661ff6730b4d4228acd4a145d5946b8bea03f Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 3 Nov 2021 18:19:36 +0100 Subject: [PATCH] pdec handler print tc --- bsp_q7s/boardconfig/busConf.h | 3 +- bsp_q7s/core/ObjectFactory.cpp | 3 +- linux/obc/PdecConfig.cpp | 3 + linux/obc/PdecConfig.h | 2 + linux/obc/PdecHandler.cpp | 117 ++++++++++++++++++++++++--------- linux/obc/PdecHandler.h | 47 ++++++++++--- 6 files changed, 132 insertions(+), 43 deletions(-) diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 75618e7a..e68a1f19 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -17,7 +17,8 @@ static constexpr char UART_GNSS_0_DEV[] = "/dev/ttyUL0"; static constexpr char UART_GNSS_1_DEV[] = "/dev/ttyUL2"; static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0"; -static constexpr char UIO_PDEC_MEMORY[] = "/dev/uio2"; +static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2"; +static constexpr char UIO_PDEC_RAM[] = "/dev/uio3"; namespace gpioNames { static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select"; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index b86b29f8..a64a1493 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -961,7 +961,8 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { gpioComIF->addGpios(gpioCookiePdec); new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, - std::string(q7s::UIO_PDEC_MEMORY), std::string(q7s::UIO_PDEC_REGISTERS)); + std::string(q7s::UIO_PDEC_CONFIG_MEMORY), std::string(q7s::UIO_PDEC_RAM), + std::string(q7s::UIO_PDEC_REGISTERS)); #if BOARD_TE0720 == 0 GpioCookie* gpioRS485Chip = new GpioCookie; diff --git a/linux/obc/PdecConfig.cpp b/linux/obc/PdecConfig.cpp index 6e5e3a91..bb2ffb13 100644 --- a/linux/obc/PdecConfig.cpp +++ b/linux/obc/PdecConfig.cpp @@ -22,6 +22,9 @@ void PdecConfig::initialize() { configWords[0] = word; word = 0; word |= (NEGATIVE_WINDOW << 24); + word |= (HIGH_AU_MAP_ID << 16); + word |= (ENABLE_DERANDOMIZER << 8); + configWords[1] = word; } uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { diff --git a/linux/obc/PdecConfig.h b/linux/obc/PdecConfig.h index d1159bf2..46cd5097 100644 --- a/linux/obc/PdecConfig.h +++ b/linux/obc/PdecConfig.h @@ -39,6 +39,8 @@ private: // 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; diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index df6e967f..0a49f94a 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -10,10 +11,11 @@ #include "fsfw/objectmanager/ObjectManager.h" PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, - LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioMemory, - std::string uioRegisters) : + LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, + std::string uioRamMemory, std::string uioRegisters) : SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset( - pdecReset), uioMemory(uioMemory), uioRegisters(uioRegisters) { + pdecReset), uioConfigMemory(uioConfigMemory), uioRamMemory(uioRamMemory), uioRegisters( + uioRegisters) { } @@ -43,7 +45,12 @@ ReturnValue_t PdecHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = getMemoryBaseAddress(); + result = getConfigMemoryBaseAddress(); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + result = getRamBaseAddress(); if (result != RETURN_OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -76,45 +83,62 @@ ReturnValue_t PdecHandler::getRegisterAddress() { return RETURN_OK; } -ReturnValue_t PdecHandler::getMemoryBaseAddress() { - int fd = open(uioMemory.c_str(), O_RDWR); +ReturnValue_t PdecHandler::getConfigMemoryBaseAddress() { + int fd = open(uioConfigMemory.c_str(), O_RDWR); if (fd < 1) { - sif::warning << "PdecHandler::getMemoryBaseAddress: Invalid UIO device file" << std::endl; + sif::warning << "PdecHandler::getConfigMemoryBaseAddress: Invalid UIO device file" << std::endl; return RETURN_FAILED; } - memoryBaseAddress = static_cast(mmap(NULL, MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ, + memoryBaseAddress = static_cast(mmap(NULL, CONFIG_MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0)); if (memoryBaseAddress == MAP_FAILED) { - sif::error << "PdecHandler::getMemoryBaseAddress: Failed to map uio address" << std::endl; + sif::error << "PdecHandler::getConfigMemoryBaseAddress: Failed to map uio address" << std::endl; return RETURN_FAILED; } return RETURN_OK; } +ReturnValue_t PdecHandler::getRamBaseAddress() { + int fd = open(uioRamMemory.c_str(), O_RDWR); + + ramBaseAddress = static_cast(mmap(NULL, RAM_MAP_SIZE, PROT_WRITE | PROT_READ, + MAP_SHARED, fd, 0)); + + if (ramBaseAddress == MAP_FAILED) { + sif::error << "PdecHandler::getRamBaseAddress: Failed to map RAM base address" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + void PdecHandler::writePdecConfig() { PdecConfig pdecConfig; - *memoryBaseAddress = pdecConfig.getConfigWord(0); - *(memoryBaseAddress + 1) = pdecConfig.getConfigWord(1); + *(memoryBaseAddress + FRAME_HEADER_OFFSET)= pdecConfig.getConfigWord(0); + *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); -// uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); // 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 + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx + 1 / 4) = NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; -// *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = routeToPm << 24 -// | routeToPm << 16 | routeToPm << 8 | routeToPm; } // 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 + 1) = NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 + *(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() { @@ -173,9 +197,6 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { bool PdecHandler::newTcReceived() { uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); - sif::debug << "PdecHandler::newTcReceived: pdecFar 0x" << std::hex - << static_cast(pdecFar) << std::endl; - if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) { return false; } @@ -303,11 +324,12 @@ void PdecHandler::handleNewTc() { if (result != RETURN_OK) { return; } -#if OBSW_DEBUG_PDEC == 1 +#if OBSW_DEBUG_PDEC_HANDLER == 1 unsigned int mapId = tcSegment[0] & MAP_ID_MASK; sif::debug << "PdecHandler::handleNewTc: Received TC segment with map ID" << mapId << std::endl; -#endif /* OBSW_DEBUG_PDEC */ + printTC(tcLength); +#endif /* OBSW_DEBUG_PDEC_HANDLER */ store_address_t storeId; result = tcStore->addData(&storeId, tcSegment + 1, tcLength - 1); @@ -331,18 +353,17 @@ void PdecHandler::handleNewTc() { } ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) { - uint32_t tcOffset = *(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_BASE_ADDRESS; + uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4; -#if OBSW_DEBUG_PDEC == 1 - sif::debug << "PdecHandler::readTc: TC offset: " << std::hex << tcOffset << std::endl; -#endif /* OBSW_DEBUG_PDEC */ +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER */ - uint32_t* tcPtr = reinterpret_cast(*(registerBaseAddress + tcOffset) / 4); tcLength = *(registerBaseAddress + PDEC_SLEN_OFFSET); -#if OBSW_DEBUG_PDEC == 1 - sif::debug << "PdecHandler::readTc: TC length: " << tcLength << std::endl; -#endif /* OBSW_DEBUG_PDEC */ +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::readTc: TC segment length: " << std::dec << tcLength << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER */ if (tcLength > MAX_TC_SEGMENT_SIZE) { sif::warning << "PdecHandler::handleNewTc: Read invalid TC length from PDEC register" @@ -352,9 +373,31 @@ ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) { uint32_t idx = 0; uint32_t tcData = 0; - for (idx = 0; idx < tcLength; idx = idx + 4) { - tcData = *(tcPtr + idx); - std::memcpy(tcSegment + idx, &tcData, sizeof(tcData)); + for (idx = 0; idx <= tcLength; idx = idx + 4) { + tcData = *(ramBaseAddress + tcOffset + idx / 4); + if (idx == 0) { + tcSegment[idx] = static_cast((tcData >> 16) & 0xFF); + tcSegment[idx + 1] = static_cast((tcData >> 8) & 0xFF); + tcSegment[idx + 2] = static_cast(tcData & 0xFF); + } + else if (tcLength - idx + 1 == 3) { + tcSegment[idx - 1] = static_cast((tcData >> 16) & 0xFF); + tcSegment[idx] = static_cast((tcData >> 8) & 0xFF); + tcSegment[idx + 1] = static_cast(tcData & 0xFF); + } + else if (tcLength - idx + 1 == 2) { + tcSegment[idx - 1] = static_cast((tcData >> 8) & 0xFF); + tcSegment[idx + 1] = static_cast(tcData & 0xFF); + } + else if (tcLength - idx + 1 == 1) { + tcSegment[idx - 1] = static_cast(tcData & 0xFF); + } + else { + tcSegment[idx - 1] = static_cast((tcData >> 24) & 0xFF); + tcSegment[idx] = static_cast((tcData >> 16) & 0xFF); + tcSegment[idx + 1] = static_cast((tcData >> 8) & 0xFF); + tcSegment[idx + 2] = static_cast(tcData & 0xFF); + } } // Backend buffer is handled back to PDEC3 @@ -363,6 +406,16 @@ ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) { return RETURN_OK; } +void PdecHandler::printTC(uint32_t tcLength) { + std::stringstream tcSegmentStream; + tcSegmentStream << "TC segment data: 0x"; + for (uint32_t idx = 0; idx < tcLength; idx++) { + tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex + << static_cast(tcSegment[idx]); + } + sif::debug << tcSegmentStream.str() << std::endl; +} + uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) { uint8_t lutEntry = 0; uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION)); diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 7f7d1420..10e57afc 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -37,11 +37,12 @@ public: * @param tcDestinationId Object ID of object responsible for processing TCs. * @param gpioComIF Pointer to GPIO interace responsible for driving GPIOs. * @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC. - * @param uioMemory String of uio device file same mapped to the PDEC memory space + * @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 */ PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, - gpioId_t pdecReset, std::string uioMemory, std::string uioRegisters); + gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory, + std::string uioRegisters); virtual ~PdecHandler(); @@ -104,14 +105,19 @@ private: static const uint32_t PDEC_BPTR_OFFSET = 0xA25; static const uint32_t PDEC_SLEN_OFFSET = 0xA26; - static const int MEMORY_MAP_SIZE = 0xF42400; + static const int CONFIG_MEMORY_MAP_SIZE = 0x400; + static const int RAM_MAP_SIZE = 0x4000; static const int REGISTER_MAP_SIZE = 0x10000; + // 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; - static const uint32_t PHYSICAL_BASE_ADDRESS = 0x30000000; + static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000; 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. @@ -122,11 +128,17 @@ private: // Expected value stored in FAR register after reset static const uint32_t FAR_RESET = 0x7FE0; + static const uint32_t TC_SEGMENT_LEN = 1017; + /** * TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in * the PDEC memory. */ - static const uint32_t PM_BUFFER = 7; + 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; enum class FrameAna_t: uint8_t { ABANDONED_CLTU, @@ -166,7 +178,14 @@ private: * @brief Opens UIO device assigned to the base address of the PDEC memory space and maps the * physical address into the virtual address space. */ - ReturnValue_t getMemoryBaseAddress(); + ReturnValue_t getConfigMemoryBaseAddress(); + + /** + * @brief Opens UIO device assigned to the RAM section of the PDEC IP core memory map. + * + * @details A received TC segment will be written to this memory area. + */ + ReturnValue_t getRamBaseAddress(); /** * @brief This functions writes the configuration parameters to the configuration @@ -225,6 +244,11 @@ private: */ ReturnValue_t readTc(uint32_t& tcLength); + /** + * @brief Prints the tc segment data + */ + void printTC(uint32_t tcLength); + /** * @brief This function calculates the entry for the configuration of the MAP ID routing. * @@ -259,8 +283,11 @@ private: */ gpioId_t pdecReset = gpio::NO_GPIO; - // UIO device file giving access to the PDEC memory space - std::string uioMemory; + // 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; @@ -276,12 +303,14 @@ private: */ 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[1017]; + uint8_t tcSegment[TC_SEGMENT_LEN]; }; #endif /* LINUX_OBC_PDECHANDLER_H_ */