Merge pull request 'PTME Bandwidth Allocation Table' (#495) from ptme_bat_priority_enable into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #495
This commit is contained in:
commit
4277a98c16
@ -16,6 +16,8 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
Requires firmware update for new FPGA design where reset line is routed into the software.
|
||||
|
||||
## Added
|
||||
|
||||
- Added NaN and Inf check for the `MEKF`. If these are detected, the `AcsController` will reset
|
||||
@ -36,6 +38,13 @@ will consitute of a breaking change warranting a new major release:
|
||||
Furthermore, the submode in the NORMAL mode now should be 0 instead of some ON mode submode.
|
||||
- Updated GYR bias values to newest measurements. This also corrects the ADIS values to always
|
||||
consit of just one digit.
|
||||
- The CCSDS IP core handler now exposes a parameter to enable the priority select mode
|
||||
for the PTME core. This mode prioritizes virtual channels with a lower index, so for example
|
||||
the virtual channel (VC0) will have the highest priority, while VC3 will have the lowestg
|
||||
priority. This mode will be enabled by default for now, but can be set via the parameter IF with
|
||||
the unique parameter ID 0. The update of this mode requires a PTME reset. Therefore, it will only
|
||||
be performed when the transmitter is off to avoid weird bugs.
|
||||
- Connect and handle reset line for the PTME core in the software now.
|
||||
- Safe mode controller failure event now only triggers once per minute.
|
||||
|
||||
# [v1.38.0] 2023-03-17
|
||||
|
@ -90,6 +90,8 @@ 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";
|
||||
|
||||
static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872";
|
||||
static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872";
|
||||
static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872";
|
||||
|
@ -748,6 +748,9 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
||||
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",
|
||||
gpio::Direction::OUT, gpio::Levels::HIGH);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::PTME_RESETN, gpio);
|
||||
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
|
||||
// Creating virtual channel interfaces
|
||||
VirtualChannelIF* vc0 =
|
||||
@ -772,9 +775,14 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
||||
new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
|
||||
PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig);
|
||||
|
||||
*args.ipCoreHandler = new CcsdsIpCoreHandler(
|
||||
objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig, LINK_STATE,
|
||||
&args.gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||
PtmeGpios gpios;
|
||||
gpios.enableTxClock = gpioIds::RS485_EN_TX_CLOCK;
|
||||
gpios.enableTxData = gpioIds::RS485_EN_TX_CLOCK;
|
||||
gpios.ptmeResetn = gpioIds::PTME_RESETN;
|
||||
|
||||
*args.ipCoreHandler =
|
||||
new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig,
|
||||
LINK_STATE, &args.gpioComIF, gpios);
|
||||
// This VC will receive all live TM
|
||||
auto* vcWithQueue =
|
||||
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
|
||||
|
@ -102,6 +102,7 @@ enum gpioId_t {
|
||||
VC2_PAPB_BUSY,
|
||||
VC3_PAPB_EMPTY,
|
||||
VC3_PAPB_BUSY,
|
||||
PTME_RESETN,
|
||||
|
||||
PDEC_RESET,
|
||||
|
||||
|
@ -71,6 +71,22 @@ ReturnValue_t AxiPtmeConfig::disableTxclockInversion() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AxiPtmeConfig::enableBatPriorityBit() {
|
||||
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, true, BitPos::EN_BAT_PRIORITY);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AxiPtmeConfig::disableBatPriorityBit() {
|
||||
ReturnValue_t result = writeBit(COMMON_CONFIG_REG, false, BitPos::EN_BAT_PRIORITY);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AxiPtmeConfig::writeReg(uint32_t regOffset, uint32_t writeVal) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
result = mutex->lockMutex(timeoutType, mutexTimeout);
|
||||
|
@ -54,6 +54,9 @@ class AxiPtmeConfig : public SystemObject {
|
||||
ReturnValue_t enableTxclockInversion();
|
||||
ReturnValue_t disableTxclockInversion();
|
||||
|
||||
ReturnValue_t enableBatPriorityBit();
|
||||
ReturnValue_t disableBatPriorityBit();
|
||||
|
||||
private:
|
||||
// Address of register storing the bitrate configuration parameter
|
||||
static const uint32_t CADU_BITRATE_REG = 0x0;
|
||||
@ -61,7 +64,7 @@ class AxiPtmeConfig : public SystemObject {
|
||||
static const uint32_t COMMON_CONFIG_REG = 0x4;
|
||||
static const uint32_t ADRESS_DIVIDER = 4;
|
||||
|
||||
enum class BitPos : uint32_t { EN_TX_CLK_MANIPULATOR, INVERT_CLOCK };
|
||||
enum class BitPos : uint32_t { EN_TX_CLK_MANIPULATOR = 0, INVERT_CLOCK = 1, EN_BAT_PRIORITY = 2 };
|
||||
|
||||
std::string axiUio;
|
||||
std::string uioMap;
|
||||
|
@ -48,3 +48,11 @@ ReturnValue_t PtmeConfig::configTxManipulator(bool enable) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PtmeConfig::enableBatPriorityBit(bool enable) {
|
||||
if (enable) {
|
||||
return axiPtmeConfig->enableBatPriorityBit();
|
||||
} else {
|
||||
return axiPtmeConfig->disableBatPriorityBit();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef LINUX_OBC_PTMECONFIG_H_
|
||||
#define LINUX_OBC_PTMECONFIG_H_
|
||||
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
|
||||
#include "AxiPtmeConfig.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
@ -53,6 +55,15 @@ class PtmeConfig : public SystemObject {
|
||||
*/
|
||||
ReturnValue_t configTxManipulator(bool enable);
|
||||
|
||||
/**
|
||||
* Enable the bat priority bit in the PTME wrapper component.
|
||||
* Please note that a reset of the PTME is still required as specified in the documentation.
|
||||
* This is done by a higher level component.
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t enableBatPriorityBit(bool enable);
|
||||
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::RATE_SETTER;
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination,
|
||||
PtmeConfig& ptmeConfig, std::atomic_bool& linkState,
|
||||
GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData)
|
||||
GpioIF* gpioIF, PtmeGpios gpioIds)
|
||||
: SystemObject(objectId),
|
||||
linkState(linkState),
|
||||
tcDestination(tcDestination),
|
||||
@ -22,9 +22,8 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDesti
|
||||
actionHelper(this, nullptr),
|
||||
modeHelper(this),
|
||||
ptmeConfig(ptmeConfig),
|
||||
gpioIF(gpioIF),
|
||||
enTxClock(enTxClock),
|
||||
enTxData(enTxData) {
|
||||
ptmeGpios(gpioIds),
|
||||
gpioIF(gpioIF) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
eventQueue =
|
||||
@ -71,6 +70,12 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
if (batPriorityParam == 0) {
|
||||
disablePrioritySelectMode();
|
||||
} else {
|
||||
enablePrioritySelectMode();
|
||||
}
|
||||
|
||||
#if OBSW_SYRLINKS_SIMULATED == 1
|
||||
// Update data on rising edge
|
||||
ptmeConfig.invertTxClock(false);
|
||||
@ -111,7 +116,24 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
|
||||
ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
return returnvalue::OK;
|
||||
if ((domainId == 0) and (uniqueIdentifier == ParamId::BAT_PRIORITY)) {
|
||||
uint8_t newVal = 0;
|
||||
ReturnValue_t result = newValues->getElement(&newVal);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (newVal > 1) {
|
||||
return HasParametersIF::INVALID_VALUE;
|
||||
}
|
||||
parameterWrapper->set(batPriorityParam);
|
||||
if (mode == MODE_ON) {
|
||||
updateBatPriorityOnTxOff = true;
|
||||
} else if (mode == MODE_OFF) {
|
||||
updateBatPriorityFromParam();
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return HasParametersIF::INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
|
||||
uint32_t CcsdsIpCoreHandler::getIdentifier() const { return 0; }
|
||||
@ -184,8 +206,8 @@ void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
|
||||
|
||||
void CcsdsIpCoreHandler::enableTransmit() {
|
||||
#ifndef TE0720_1CFA
|
||||
gpioIF->pullHigh(enTxClock);
|
||||
gpioIF->pullHigh(enTxData);
|
||||
gpioIF->pullHigh(ptmeGpios.enableTxClock);
|
||||
gpioIF->pullHigh(ptmeGpios.enableTxData);
|
||||
#endif
|
||||
linkState = LINK_UP;
|
||||
}
|
||||
@ -211,14 +233,8 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
||||
auto rateHigh = [&]() {
|
||||
ReturnValue_t result = ptmeConfig.setRate(RATE_500KBPS);
|
||||
if (result == returnvalue::OK) {
|
||||
this->mode = HasModesIF::MODE_ON;
|
||||
}
|
||||
};
|
||||
auto rateLow = [&]() {
|
||||
ReturnValue_t result = ptmeConfig.setRate(RATE_100KBPS);
|
||||
auto rateSet = [&](uint32_t rate) {
|
||||
ReturnValue_t result = ptmeConfig.setRate(rate);
|
||||
if (result == returnvalue::OK) {
|
||||
this->mode = HasModesIF::MODE_ON;
|
||||
}
|
||||
@ -228,14 +244,14 @@ void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
||||
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
|
||||
com::Datarate currentDatarate = com::getCurrentDatarate();
|
||||
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
||||
rateLow();
|
||||
rateSet(RATE_100KBPS);
|
||||
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
||||
rateHigh();
|
||||
rateSet(RATE_500KBPS);
|
||||
}
|
||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
|
||||
rateHigh();
|
||||
rateSet(RATE_500KBPS);
|
||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
|
||||
rateLow();
|
||||
rateSet(RATE_100KBPS);
|
||||
}
|
||||
|
||||
} else if (mode == HasModesIF::MODE_OFF) {
|
||||
@ -250,11 +266,16 @@ void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
||||
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
|
||||
|
||||
void CcsdsIpCoreHandler::disableTransmit() {
|
||||
ptmeConfig.enableBatPriorityBit(false);
|
||||
#ifndef TE0720_1CFA
|
||||
gpioIF->pullLow(enTxClock);
|
||||
gpioIF->pullLow(enTxData);
|
||||
gpioIF->pullLow(ptmeGpios.enableTxClock);
|
||||
gpioIF->pullLow(ptmeGpios.enableTxData);
|
||||
#endif
|
||||
linkState = LINK_DOWN;
|
||||
if (updateBatPriorityOnTxOff) {
|
||||
updateBatPriorityFromParam();
|
||||
updateBatPriorityOnTxOff = false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* CcsdsIpCoreHandler::getName() const { return "CCSDS Handler"; }
|
||||
@ -270,3 +291,25 @@ ReturnValue_t CcsdsIpCoreHandler::connectModeTreeParent(HasModeTreeChildrenIF& p
|
||||
ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; }
|
||||
|
||||
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
void CcsdsIpCoreHandler::enablePrioritySelectMode() {
|
||||
ptmeConfig.enableBatPriorityBit(true);
|
||||
// Reset the PTME
|
||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::disablePrioritySelectMode() {
|
||||
ptmeConfig.enableBatPriorityBit(false);
|
||||
// Reset the PTME
|
||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
|
||||
if (batPriorityParam == 0) {
|
||||
disablePrioritySelectMode();
|
||||
} else {
|
||||
enablePrioritySelectMode();
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,25 @@
|
||||
#include "linux/ipcore/PtmeConfig.h"
|
||||
#include "mission/comDefs.h"
|
||||
|
||||
struct PtmeGpios {
|
||||
gpioId_t enableTxClock = gpio::NO_GPIO;
|
||||
gpioId_t enableTxData = gpio::NO_GPIO;
|
||||
gpioId_t ptmeResetn = gpio::NO_GPIO;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class handles the data exchange with the CCSDS IP cores implemented in the
|
||||
* programmable logic of the Q7S.
|
||||
*
|
||||
* @details After reboot default CADU bitrate is always set to 100 kbps (results in downlink rate
|
||||
* of 200 kbps due to convolutional code added by syrlinks transceiver)
|
||||
* @details
|
||||
* After reboot default CADU bitrate is always set to 100 kbps (results in downlink rate
|
||||
* of 200 kbps due to convolutional code added by syrlinks transceiver). The IP core handler exposes
|
||||
* a parameter to enable the priority selection mode for the PTME core.
|
||||
*
|
||||
* If the transmitter is on, the selection mode will be enabled when the transmitter goes off.
|
||||
* If the transmitter is off, the update of the PTME will be done immediately on a parameter update.
|
||||
* This is done because changing this parameter requires a reset of the PTME core to avoid bugs
|
||||
* while the transmitter is enabled.
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
@ -39,11 +52,12 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
public ModeTreeChildIF,
|
||||
public ModeTreeConnectionIF,
|
||||
public HasModesIF,
|
||||
// public AcceptsTelemetryIF,
|
||||
public AcceptsTelecommandsIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
enum ParamId : uint8_t { BAT_PRIORITY = 0 };
|
||||
|
||||
static const bool LINK_UP = true;
|
||||
static const bool LINK_DOWN = false;
|
||||
using VcId_t = uint8_t;
|
||||
@ -61,8 +75,7 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
* @param enTxData GPIO ID of RS485 tx data enable
|
||||
*/
|
||||
CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig,
|
||||
std::atomic_bool& linkState, GpioIF* gpioIF, gpioId_t enTxClock,
|
||||
gpioId_t enTxData);
|
||||
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds);
|
||||
|
||||
~CcsdsIpCoreHandler();
|
||||
|
||||
@ -138,15 +151,14 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE;
|
||||
|
||||
PtmeConfig& ptmeConfig;
|
||||
PtmeGpios ptmeGpios;
|
||||
// BAT priority bit on by default to enable priority selection mode for the PTME.
|
||||
uint8_t batPriorityParam = 1;
|
||||
bool updateBatPriorityOnTxOff = false;
|
||||
|
||||
GpioIF* gpioIF = nullptr;
|
||||
// GPIO to enable RS485 transceiver for TX clock
|
||||
gpioId_t enTxClock = gpio::NO_GPIO;
|
||||
// GPIO to enable RS485 transceiver for TX data signal
|
||||
gpioId_t enTxData = gpio::NO_GPIO;
|
||||
|
||||
void readCommandQueue(void);
|
||||
void handleTelemetry();
|
||||
|
||||
/**
|
||||
* @brief Forward link state to virtual channels.
|
||||
@ -163,6 +175,16 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
* RS485 transceiver chips to high.
|
||||
*/
|
||||
void disableTransmit();
|
||||
|
||||
/**
|
||||
* The following set of functions configure the mode of the PTME bandwith allocation table (BAT)
|
||||
* module. This consists of the following 2 steps:
|
||||
* 1. Update the BAT priority bit in the PTME wrapper
|
||||
* 2. Reset the PTME as specified in the datasheet.
|
||||
*/
|
||||
void enablePrioritySelectMode();
|
||||
void disablePrioritySelectMode();
|
||||
void updateBatPriorityFromParam();
|
||||
};
|
||||
|
||||
#endif /* CCSDSHANDLER_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user