meier/pdec #110

Merged
muellerr merged 10 commits from meier/pdec into develop 2021-11-19 12:49:37 +01:00
6 changed files with 132 additions and 43 deletions
Showing only changes of commit 709661ff67 - Show all commits

View File

@ -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";

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -1,4 +1,5 @@
#include <cstring>
#include <sstream>
#include <sys/mman.h>
#include <fcntl.h>
@ -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<uint32_t*>(mmap(NULL, MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ,
memoryBaseAddress = static_cast<uint32_t*>(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<uint32_t*>(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<unsigned int>(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<uint32_t*>(*(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<uint8_t>((tcData >> 16) & 0xFF);
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
tcSegment[idx + 2] = static_cast<uint8_t>(tcData & 0xFF);
}
else if (tcLength - idx + 1 == 3) {
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
tcSegment[idx] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
tcSegment[idx + 1] = static_cast<uint8_t>(tcData & 0xFF);
}
else if (tcLength - idx + 1 == 2) {
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
tcSegment[idx + 1] = static_cast<uint8_t>(tcData & 0xFF);
}
else if (tcLength - idx + 1 == 1) {
tcSegment[idx - 1] = static_cast<uint8_t>(tcData & 0xFF);
}
else {
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
tcSegment[idx + 2] = static_cast<uint8_t>(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;
Review

Maybe we can use arrayprinter::print() from globalfunctions here?

Maybe we can use arrayprinter::print() from `globalfunctions` here?
Review

Yes, we can also use the array printer function for this,

Yes, we can also use the array printer function for this,
tcSegmentStream << "TC segment data: 0x";
for (uint32_t idx = 0; idx < tcLength; idx++) {
tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex
<< static_cast<unsigned int>(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));

View File

@ -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_ */