eive-obsw/linux/ipcore/PdecConfig.cpp

218 lines
7.0 KiB
C++
Raw Normal View History

2021-11-02 11:11:38 +01:00
#include "PdecConfig.h"
2023-02-21 14:13:46 +01:00
#include "fsfw/filesystem/HasFileSystemIF.h"
2022-01-17 15:58:27 +01:00
#include "fsfw/serviceinterface/ServiceInterface.h"
2023-02-21 14:13:46 +01:00
#include "pdecconfigdefs.h"
2021-11-02 11:11:38 +01:00
2023-02-23 15:27:24 +01:00
PdecConfig::PdecConfig()
: localParameterHandler("conf/pdecconfig.json", SdCardManager::instance()) {}
2021-11-02 11:11:38 +01:00
2022-01-17 15:58:27 +01:00
PdecConfig::~PdecConfig() {}
2021-11-02 11:11:38 +01:00
2023-02-13 11:28:27 +01:00
void PdecConfig::setMemoryBaseAddress(uint32_t* memoryBaseAddress_) {
2023-02-21 14:13:46 +01:00
memoryBaseAddress = memoryBaseAddress_;
2023-02-13 11:28:27 +01:00
}
ReturnValue_t PdecConfig::write() {
2023-02-21 14:13:46 +01:00
if (memoryBaseAddress == nullptr) {
sif::error << "PdecConfig::write: Memory base address not set" << std::endl;
return returnvalue::FAILED;
}
ReturnValue_t result = initializePersistentParameters();
if (result != returnvalue::OK) {
2023-02-23 15:27:24 +01:00
return result;
2023-02-21 14:13:46 +01:00
}
result = writeFrameHeaderFirstWord();
2023-02-21 14:13:46 +01:00
if (result != returnvalue::OK) {
2023-02-23 15:27:24 +01:00
return result;
}
result = writeFrameHeaderSecondWord();
2023-02-21 14:13:46 +01:00
if (result != returnvalue::OK) {
2023-02-23 15:27:24 +01:00
return result;
}
2023-02-21 14:13:46 +01:00
writeMapConfig();
2023-02-22 15:57:24 +01:00
return returnvalue::OK;
2023-02-21 14:13:46 +01:00
}
2023-02-13 11:28:27 +01:00
2023-02-21 14:13:46 +01:00
ReturnValue_t PdecConfig::initializePersistentParameters() {
ReturnValue_t result = localParameterHandler.initialize();
2023-02-23 15:27:24 +01:00
if (result == HasFileSystemIF::FILE_DOES_NOT_EXIST) {
result = createPersistentConfig();
if (result != returnvalue::OK) {
return result;
}
}
return result;
2023-02-21 14:13:46 +01:00
}
ReturnValue_t PdecConfig::createPersistentConfig() {
ReturnValue_t result = localParameterHandler.addParameter(
pdecconfigdefs::paramkeys::POSITIVE_WINDOW, pdecconfigdefs::defaultvalue::positiveWindow);
if (result != returnvalue::OK) {
sif::error << "PdecConfig::createPersistentConfig: Failed to set positive window" << std::endl;
return result;
}
2023-02-23 15:27:24 +01:00
result = localParameterHandler.addParameter(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW,
pdecconfigdefs::defaultvalue::negativeWindow);
2023-02-21 14:13:46 +01:00
if (result != returnvalue::OK) {
sif::error << "PdecConfig::createPersistentConfig: Failed to set negative window" << std::endl;
return result;
}
return returnvalue::OK;
2021-11-02 11:11:38 +01:00
}
uint32_t PdecConfig::getImrReg() {
2022-10-26 14:35:47 +02:00
return static_cast<uint32_t>(enableNewFarIrq << 2) |
static_cast<uint32_t>(enableTcAbortIrq << 1) | static_cast<uint32_t>(enableTcNewIrq);
}
2023-02-13 11:28:27 +01:00
ReturnValue_t PdecConfig::setPositiveWindow(uint8_t pw) {
2023-02-21 14:13:46 +01:00
if (memoryBaseAddress == nullptr) {
sif::error << "PdecConfig::setPositiveWindow: Memory base address not set" << std::endl;
return returnvalue::FAILED;
}
ReturnValue_t result =
localParameterHandler.updateParameter(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, pw);
if (result != returnvalue::OK) {
return result;
}
// Rewrite second config word which contains the positive window parameter
writeFrameHeaderSecondWord();
2023-02-21 14:13:46 +01:00
return returnvalue::OK;
2023-02-13 11:28:27 +01:00
}
ReturnValue_t PdecConfig::setNegativeWindow(uint8_t nw) {
2023-02-21 14:13:46 +01:00
if (memoryBaseAddress == nullptr) {
sif::error << "PdecConfig::setPositiveWindow: Memory base address not set" << std::endl;
return returnvalue::FAILED;
}
ReturnValue_t result =
localParameterHandler.updateParameter(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, nw);
if (result != returnvalue::OK) {
return result;
}
// Rewrite second config word which contains the negative window parameter
writeFrameHeaderSecondWord();
2023-02-21 14:13:46 +01:00
return returnvalue::OK;
2023-02-13 11:28:27 +01:00
}
2023-02-21 14:13:46 +01:00
ReturnValue_t PdecConfig::getPositiveWindow(uint8_t& positiveWindow) {
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, positiveWindow);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
2023-02-13 11:28:27 +01:00
}
2023-02-21 14:13:46 +01:00
ReturnValue_t PdecConfig::getNegativeWindow(uint8_t& negativeWindow) {
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, negativeWindow);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
2023-02-13 11:28:27 +01:00
}
ReturnValue_t PdecConfig::writeFrameHeaderFirstWord() {
uint32_t word = 0;
2023-08-14 15:06:22 +02:00
ReturnValue_t result = createFirstWord(&word);
if (result != returnvalue::OK) {
return result;
}
*(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_FIRST_CONFIG_WORD) = word;
2023-02-21 14:13:46 +01:00
return returnvalue::OK;
2023-02-13 11:28:27 +01:00
}
ReturnValue_t PdecConfig::writeFrameHeaderSecondWord() {
uint32_t word = 0;
2023-08-14 15:06:22 +02:00
ReturnValue_t result = createSecondWord(&word);
if (result != returnvalue::OK) {
return result;
}
*(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_SECOND_CONFIG_WORD) = word;
2023-02-21 14:13:46 +01:00
return returnvalue::OK;
2023-02-13 11:28:27 +01:00
}
void PdecConfig::writeMapConfig() {
2023-02-21 14:13:46 +01:00
// 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;
}
2023-02-13 11:28:27 +01:00
2023-02-21 14:13:46 +01:00
// 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;
2023-02-13 11:28:27 +01:00
2023-02-21 14:13:46 +01:00
// 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;
}
2023-02-13 11:28:27 +01:00
}
uint8_t PdecConfig::calcMapAddrEntry(uint8_t moduleId) {
uint8_t lutEntry = 0;
uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION));
lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId;
return lutEntry;
}
uint8_t PdecConfig::getOddParity(uint8_t number) {
uint8_t parityBit = 0;
uint8_t countBits = 0;
for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) {
countBits += (number >> idx) & 0x1;
}
parityBit = ~(countBits & 0x1) & 0x1;
return parityBit;
}
ReturnValue_t PdecConfig::createFirstWord(uint32_t* word) {
2023-08-14 15:06:22 +02:00
*word = 0;
*word |= (VERSION_ID << 30);
// Setting the bypass flag and the control command flag should not have any
// implication on the operation of the PDEC IP Core
*word |= (BYPASS_FLAG << 29);
*word |= (CONTROL_COMMAND_FLAG << 28);
*word |= (RESERVED_FIELD_A << 26);
*word |= (SPACECRAFT_ID << 16);
*word |= (VIRTUAL_CHANNEL << 10);
*word |= (DUMMY_BITS << 8);
uint8_t positiveWindow = 0;
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, positiveWindow);
if (result != returnvalue::OK) {
return result;
}
*word |= static_cast<uint32_t>(positiveWindow);
return returnvalue::OK;
}
ReturnValue_t PdecConfig::createSecondWord(uint32_t* word) {
2023-08-14 15:06:22 +02:00
uint8_t negativeWindow = 0;
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, negativeWindow);
if (result != returnvalue::OK) {
return result;
}
*word = 0;
*word = 0;
*word |= (static_cast<uint32_t>(negativeWindow) << 24);
*word |= (HIGH_AU_MAP_ID << 16);
*word |= (ENABLE_DERANDOMIZER << 8);
return returnvalue::OK;
}
uint32_t PdecConfig::readbackFirstWord() {
2023-08-14 15:06:22 +02:00
return *(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_FIRST_CONFIG_WORD);
}
uint32_t PdecConfig::readbackSecondWord() {
2023-08-14 15:06:22 +02:00
return *(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_SECOND_CONFIG_WORD);
}