WIP: PTME: Separate registers for VCs #636

Closed
muellerr wants to merge 4 commits from ptme-separate-regs-for-vcs-2 into v4.0.0-dev
6 changed files with 79 additions and 27 deletions
Showing only changes of commit 00e98a2fd6 - Show all commits

View File

@ -23,6 +23,7 @@ TODO: New firmware package version.
## Changed
- Removed PTME busy/ready signals. Those were not used anyway because register reads are used now.
- Update PTME config register code: Each VC now has its own configuration register.
## Fixed
@ -59,7 +60,6 @@ TODO: New firmware package version.
# [v2.0.5] 2023-05-11
- The dual lane assembly transition failed handler started new transitions towards the current mode
instead of the target mode. This means that if the dual lane assembly never reached the initial
submode (e.g. mode normal and submode dual side), it will transition back to the current mode,

View File

@ -32,7 +32,7 @@ ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) {
sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to lock mutex" << std::endl;
return returnvalue::FAILED;
}
*(baseAddress + CADU_BITRATE_REG) = static_cast<uint32_t>(rateVal);
*(baseAddress + ADDR_CADU_BITRATE_REG) = static_cast<uint32_t>(rateVal);
result = mutex->unlockMutex();
if (result != returnvalue::OK) {
sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to unlock mutex" << std::endl;
@ -42,27 +42,27 @@ ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) {
}
void AxiPtmeConfig::enableTxclockManipulator() {
writeBit(COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR);
writeBit(ADDR_COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR);
}
void AxiPtmeConfig::disableTxclockManipulator() {
writeBit(COMMON_CONFIG_REG, false, BitPos::EN_TX_CLK_MANIPULATOR);
writeBit(ADDR_COMMON_CONFIG_REG, false, BitPos::EN_TX_CLK_MANIPULATOR);
}
void AxiPtmeConfig::enableTxclockInversion() {
writeBit(COMMON_CONFIG_REG, true, BitPos::INVERT_CLOCK);
writeBit(ADDR_COMMON_CONFIG_REG, true, BitPos::INVERT_CLOCK);
}
void AxiPtmeConfig::disableTxclockInversion() {
writeBit(COMMON_CONFIG_REG, false, BitPos::INVERT_CLOCK);
writeBit(ADDR_COMMON_CONFIG_REG, false, BitPos::INVERT_CLOCK);
}
void AxiPtmeConfig::enableBatPriorityBit() {
writeBit(COMMON_CONFIG_REG, true, BitPos::EN_BAT_PRIORITY);
writeBit(ADDR_COMMON_CONFIG_REG, true, BitPos::EN_BAT_PRIORITY);
}
void AxiPtmeConfig::disableBatPriorityBit() {
writeBit(COMMON_CONFIG_REG, false, BitPos::EN_BAT_PRIORITY);
writeBit(ADDR_COMMON_CONFIG_REG, false, BitPos::EN_BAT_PRIORITY);
}
void AxiPtmeConfig::writeReg(uint32_t regOffset, uint32_t writeVal) {
@ -75,21 +75,62 @@ uint32_t AxiPtmeConfig::readReg(uint32_t regOffset) {
return *(baseAddress + regOffset / ADRESS_DIVIDER);
}
void AxiPtmeConfig::writePollThreshold(AxiPtmeConfig::IdlePollThreshold pollThreshold) {
uint32_t regVal = readCommonCfgReg();
void AxiPtmeConfig::writePollThreshold(uint8_t vcIdx,
AxiPtmeConfig::IdlePollThreshold pollThreshold) {
uint32_t regVal = readVcCfgReg(vcIdx);
// Clear bits first
regVal &= ~(0b111 << 3);
regVal |= (static_cast<uint8_t>(pollThreshold) << 3);
writeCommonCfgReg(regVal);
regVal &= ~(0b111 << 13);
regVal |= (static_cast<uint8_t>(pollThreshold) << 13);
writeVcCfgReg(vcIdx, regVal);
}
AxiPtmeConfig::IdlePollThreshold AxiPtmeConfig::readPollThreshold() {
uint32_t regVal = readCommonCfgReg();
return static_cast<AxiPtmeConfig::IdlePollThreshold>((regVal >> 3) & 0b111);
AxiPtmeConfig::IdlePollThreshold AxiPtmeConfig::readPollThreshold(uint8_t vcIdx) {
uint32_t regVal = readVcCfgReg(vcIdx);
return static_cast<AxiPtmeConfig::IdlePollThreshold>((regVal >> 13) & 0b111);
}
void AxiPtmeConfig::writeCommonCfgReg(uint32_t value) { writeReg(COMMON_CONFIG_REG, value); }
uint32_t AxiPtmeConfig::readCommonCfgReg() { return readReg(COMMON_CONFIG_REG); }
void AxiPtmeConfig::writeCommonCfgReg(uint32_t value) { writeReg(ADDR_COMMON_CONFIG_REG, value); }
uint32_t AxiPtmeConfig::readCommonCfgReg() { return readReg(ADDR_COMMON_CONFIG_REG); }
uint32_t AxiPtmeConfig::readVcCfgReg(uint8_t vcIdx) {
switch (vcIdx) {
case (0): {
return readReg(ADDR_VC0_REG);
}
case (1): {
return readReg(ADDR_VC1_REG);
}
case (2): {
return readReg(ADDR_VC2_REG);
}
case (3): {
return readReg(ADDR_VC3_REG);
}
}
return 0;
}
void AxiPtmeConfig::writeVcCfgReg(uint8_t vcIdx, uint32_t reg) {
switch (vcIdx) {
case (0): {
writeReg(ADDR_VC0_REG, reg);
break;
}
case (1): {
writeReg(ADDR_VC1_REG, reg);
break;
}
case (2): {
writeReg(ADDR_VC2_REG, reg);
break;
}
case (3): {
writeReg(ADDR_VC3_REG, reg);
break;
}
}
}
void AxiPtmeConfig::writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos) {
uint32_t readVal = readReg(regOffset);

View File

@ -67,14 +67,20 @@ class AxiPtmeConfig : public SystemObject {
void enableBatPriorityBit();
void disableBatPriorityBit();
void writePollThreshold(IdlePollThreshold pollThreshold);
IdlePollThreshold readPollThreshold();
void writePollThreshold(uint8_t vcIdx, IdlePollThreshold pollThreshold);
IdlePollThreshold readPollThreshold(uint8_t vcIdx);
private:
// Address of register storing the bitrate configuration parameter
static const uint32_t CADU_BITRATE_REG = 0x0;
static const uint32_t ADDR_CADU_BITRATE_REG = 0;
// Address of register storing common configuration parameters
static const uint32_t COMMON_CONFIG_REG = 0x4;
static const uint32_t ADDR_COMMON_CONFIG_REG = 4;
static const uint32_t ADDR_FRAME_LENGTH_REG = 8;
static const uint32_t ADDR_VC0_REG = 12;
static const uint32_t ADDR_VC1_REG = 16;
static const uint32_t ADDR_VC2_REG = 20;
static const uint32_t ADDR_VC3_REG = 24;
static const uint32_t ADRESS_DIVIDER = 4;
enum class BitPos : uint32_t { EN_TX_CLK_MANIPULATOR = 0, INVERT_CLOCK = 1, EN_BAT_PRIORITY = 2 };
@ -106,6 +112,9 @@ class AxiPtmeConfig : public SystemObject {
uint32_t readCommonCfgReg();
void writeCommonCfgReg(uint32_t value);
uint32_t readVcCfgReg(uint8_t vcIdx);
void writeVcCfgReg(uint8_t vcIdx, uint32_t reg);
/**
* @brief Sets one bit in a register
*

View File

@ -50,6 +50,8 @@ void PtmeConfig::enableBatPriorityBit(bool enable) {
}
}
void PtmeConfig::setPollThreshold(AxiPtmeConfig::IdlePollThreshold pollThreshold) {
axiPtmeConfig->writePollThreshold(pollThreshold);
void PtmeConfig::setAllPollThresholds(AxiPtmeConfig::IdlePollThreshold pollThreshold) {
for (uint8_t idx = 0; idx < 4; idx++) {
axiPtmeConfig->writePollThreshold(idx, pollThreshold);
}
}

View File

@ -64,7 +64,7 @@ class PtmeConfig : public SystemObject {
*/
void enableBatPriorityBit(bool enable);
void setPollThreshold(AxiPtmeConfig::IdlePollThreshold pollThreshold);
void setAllPollThresholds(AxiPtmeConfig::IdlePollThreshold pollThreshold);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::RATE_SETTER;

View File

@ -76,7 +76,7 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
// This also pulls the PTME out of reset state.
updateBatPriorityFromParam();
ptmeConfig.setPollThreshold(
ptmeConfig.setAllPollThresholds(
static_cast<AxiPtmeConfig::IdlePollThreshold>(params.pollThresholdParam));
resetPtme();
ptmeLocked = false;
@ -322,7 +322,7 @@ void CcsdsIpCoreHandler::performPtmeUpdateWhenApplicable() {
doResetPtme = true;
}
if (updateContext.updatePollThreshold) {
ptmeConfig.setPollThreshold(
ptmeConfig.setAllPollThresholds(
static_cast<AxiPtmeConfig::IdlePollThreshold>(params.pollThresholdParam));
updateContext.updatePollThreshold = false;
doResetPtme = true;