meier/txRateSetting #111
@ -66,7 +66,10 @@ namespace gpioNames {
|
|||||||
static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3";
|
static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3";
|
||||||
static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872";
|
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_TX_DATA[] = "tx_data_enable_ltc2872";
|
||||||
|
static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872";
|
||||||
|
static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872";
|
||||||
static constexpr char PDEC_RESET[] = "pdec_reset";
|
static constexpr char PDEC_RESET[] = "pdec_reset";
|
||||||
|
static constexpr char BIT_RATE_SEL[] = "bit_rate_sel";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ void initmission::initTasks() {
|
|||||||
// If a command has not been read before the next one arrives, the old command will be
|
// If a command has not been read before the next one arrives, the old command will be
|
||||||
// overwritten by the PDEC.
|
// overwritten by the PDEC.
|
||||||
PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask(
|
PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask(
|
||||||
"PDEC_HANDLER", 10, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
"PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc);
|
||||||
result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER);
|
result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
|
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
|
||||||
|
@ -79,6 +79,8 @@
|
|||||||
#include <linux/obc/PdecHandler.h>
|
#include <linux/obc/PdecHandler.h>
|
||||||
#include <linux/obc/PapbVcInterface.h>
|
#include <linux/obc/PapbVcInterface.h>
|
||||||
#include <linux/obc/PtmeConfig.h>
|
#include <linux/obc/PtmeConfig.h>
|
||||||
|
#include <linux/obc/PtmeRateSetter.h>
|
||||||
|
#include <linux/obc/TxRateSetterIF.h>
|
||||||
|
|
||||||
ResetArgs resetArgsGnss0;
|
ResetArgs resetArgsGnss0;
|
||||||
ResetArgs resetArgsGnss1;
|
ResetArgs resetArgsGnss1;
|
||||||
@ -937,8 +939,20 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) {
|
|||||||
ptme->addVcInterface(ccsds::VC2, vc2);
|
ptme->addVcInterface(ccsds::VC2, vc2);
|
||||||
ptme->addVcInterface(ccsds::VC3, vc3);
|
ptme->addVcInterface(ccsds::VC3, vc3);
|
||||||
|
|
||||||
|
GpioCookie* gpioCookieRateSetter = new GpioCookie;
|
||||||
|
consumer.str("");
|
||||||
|
consumer << "ptme rate setter";
|
||||||
|
// Init to low -> default bit rate is low bit rate (200 kbps in downlink with syrlinks)
|
||||||
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::BIT_RATE_SEL, consumer.str(), gpio::OUT,
|
||||||
|
gpio::LOW);
|
||||||
|
gpioCookieRateSetter->addGpio(gpioIds::BIT_RATE_SEL, gpio);
|
||||||
|
gpioComIF->addGpios(gpioCookieRateSetter);
|
||||||
|
|
||||||
|
TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(gpioIds::BIT_RATE_SEL, gpioComIF);
|
||||||
|
|
||||||
CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME,
|
CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME,
|
||||||
objects::CCSDS_PACKET_DISTRIBUTOR);
|
objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF, gpioComIF,
|
||||||
|
gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||||
|
|
||||||
VirtualChannel* vc = nullptr;
|
VirtualChannel* vc = nullptr;
|
||||||
vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE);
|
vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE);
|
||||||
@ -967,12 +981,20 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) {
|
|||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
GpioCookie* gpioRS485Chip = new GpioCookie;
|
GpioCookie* gpioRS485Chip = new GpioCookie;
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
|
||||||
gpio::Direction::OUT, gpio::HIGH);
|
gpio::Direction::OUT, gpio::LOW);
|
||||||
gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio);
|
gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio);
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver",
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver",
|
||||||
gpio::Direction::OUT, gpio::HIGH);
|
gpio::Direction::OUT, gpio::LOW);
|
||||||
gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio);
|
gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio);
|
||||||
|
|
||||||
|
// Default configuration enables RX channels (RXEN = LOW)
|
||||||
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver",
|
||||||
|
gpio::Direction::OUT, gpio::LOW);
|
||||||
|
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio);
|
||||||
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver",
|
||||||
|
gpio::Direction::OUT, gpio::LOW);
|
||||||
|
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio);
|
||||||
|
|
||||||
gpioComIF->addGpios(gpioRS485Chip);
|
gpioComIF->addGpios(gpioRS485Chip);
|
||||||
#endif /* BOARD_TE0720 == 0 */
|
#endif /* BOARD_TE0720 == 0 */
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ enum commonClassIds: uint8_t {
|
|||||||
GOM_SPACE_HANDLER, //GOMS
|
GOM_SPACE_HANDLER, //GOMS
|
||||||
PLOC_MEMORY_DUMPER, //PLMEMDUMP
|
PLOC_MEMORY_DUMPER, //PLMEMDUMP
|
||||||
PDEC_HANDLER, //PDEC
|
PDEC_HANDLER, //PDEC
|
||||||
|
CCSDS_HANDLER, //PDEC
|
||||||
COMMON_CLASS_ID_END // [EXPORT] : [END]
|
COMMON_CLASS_ID_END // [EXPORT] : [END]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
0x50000701;PAPB_VC1
|
0x50000701;PAPB_VC1
|
||||||
0x50000702;PAPB_VC2
|
0x50000702;PAPB_VC2
|
||||||
0x50000703;PAPB_VC3
|
0x50000703;PAPB_VC3
|
||||||
|
0x50000704;PDEC_HANDLER
|
||||||
0x50000800;CCSDS_HANDLER
|
0x50000800;CCSDS_HANDLER
|
||||||
0x51000500;PUS_SERVICE_6
|
0x51000500;PUS_SERVICE_6
|
||||||
0x53000000;FSFW_OBJECTS_START
|
0x53000000;FSFW_OBJECTS_START
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 106 translations.
|
* @brief Auto-generated event translation file. Contains 106 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2021-10-31 17:56:40
|
* Generated on: 2021-11-22 17:04:42
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 111 translations.
|
* Contains 112 translations.
|
||||||
* Generated on: 2021-10-13 15:54:21
|
* Generated on: 2021-11-22 17:04:51
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
@ -86,6 +86,7 @@ const char *PAPB_VC0_STRING = "PAPB_VC0";
|
|||||||
const char *PAPB_VC1_STRING = "PAPB_VC1";
|
const char *PAPB_VC1_STRING = "PAPB_VC1";
|
||||||
const char *PAPB_VC2_STRING = "PAPB_VC2";
|
const char *PAPB_VC2_STRING = "PAPB_VC2";
|
||||||
const char *PAPB_VC3_STRING = "PAPB_VC3";
|
const char *PAPB_VC3_STRING = "PAPB_VC3";
|
||||||
|
const char *PDEC_HANDLER_STRING = "PDEC_HANDLER";
|
||||||
const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER";
|
const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER";
|
||||||
const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6";
|
const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6";
|
||||||
const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START";
|
const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START";
|
||||||
@ -280,6 +281,8 @@ const char* translateObject(object_id_t object) {
|
|||||||
return PAPB_VC2_STRING;
|
return PAPB_VC2_STRING;
|
||||||
case 0x50000703:
|
case 0x50000703:
|
||||||
return PAPB_VC3_STRING;
|
return PAPB_VC3_STRING;
|
||||||
|
case 0x50000704:
|
||||||
|
return PDEC_HANDLER_STRING;
|
||||||
case 0x50000800:
|
case 0x50000800:
|
||||||
return CCSDS_HANDLER_STRING;
|
return CCSDS_HANDLER_STRING;
|
||||||
case 0x51000500:
|
case 0x51000500:
|
||||||
|
@ -37,7 +37,9 @@ debugging. */
|
|||||||
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
||||||
#define OBSW_TM_TO_PTME 1
|
#define OBSW_TM_TO_PTME 1
|
||||||
// Set to 1 if telecommands are received via the PDEC IP Core
|
// Set to 1 if telecommands are received via the PDEC IP Core
|
||||||
#define OBSW_TC_FROM_PDEC 0
|
#define OBSW_TC_FROM_PDEC 1
|
||||||
|
|
||||||
|
#define TMTC_TEST_SETUP 1
|
||||||
|
|
||||||
#define OBSW_ENABLE_TIMERS 1
|
#define OBSW_ENABLE_TIMERS 1
|
||||||
#define OBSW_ADD_STAR_TRACKER 0
|
#define OBSW_ADD_STAR_TRACKER 0
|
||||||
@ -92,7 +94,6 @@ debugging. */
|
|||||||
#define OBSW_TEST_TE7020_HEATER 0
|
#define OBSW_TEST_TE7020_HEATER 0
|
||||||
#define OBSW_TEST_GPIO_OPEN_BY_LABEL 0
|
#define OBSW_TEST_GPIO_OPEN_BY_LABEL 0
|
||||||
#define OBSW_TEST_GPIO_OPEN_BY_LINE_NAME 0
|
#define OBSW_TEST_GPIO_OPEN_BY_LINE_NAME 0
|
||||||
#define OBSW_LINK_IS_UP 1
|
|
||||||
|
|
||||||
#define OBSW_DEBUG_P60DOCK 0
|
#define OBSW_DEBUG_P60DOCK 0
|
||||||
#define OBSW_DEBUG_PDU1 0
|
#define OBSW_DEBUG_PDU1 0
|
||||||
@ -109,7 +110,7 @@ debugging. */
|
|||||||
#define OBSW_DEBUG_STARTRACKER 0
|
#define OBSW_DEBUG_STARTRACKER 0
|
||||||
#define OBSW_DEBUG_PLOC_MPSOC 0
|
#define OBSW_DEBUG_PLOC_MPSOC 0
|
||||||
#define OBSW_DEBUG_PLOC_SUPERVISOR 0
|
#define OBSW_DEBUG_PLOC_SUPERVISOR 0
|
||||||
#define OBSW_DEBUG_PDEC_HANDLER 0
|
#define OBSW_DEBUG_PDEC_HANDLER 1
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/** Hardcoded */
|
/** Hardcoded */
|
||||||
|
@ -104,7 +104,11 @@ enum gpioId_t {
|
|||||||
|
|
||||||
|
|
||||||
RS485_EN_TX_DATA,
|
RS485_EN_TX_DATA,
|
||||||
RS485_EN_TX_CLOCK
|
RS485_EN_TX_CLOCK,
|
||||||
|
RS485_EN_RX_DATA,
|
||||||
|
RS485_EN_RX_CLOCK,
|
||||||
|
|
||||||
|
BIT_RATE_SEL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 106 translations.
|
* @brief Auto-generated event translation file. Contains 106 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2021-10-31 17:56:40
|
* Generated on: 2021-11-22 17:04:42
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 111 translations.
|
* Contains 112 translations.
|
||||||
* Generated on: 2021-10-13 15:54:21
|
* Generated on: 2021-11-22 17:04:51
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
@ -86,6 +86,7 @@ const char *PAPB_VC0_STRING = "PAPB_VC0";
|
|||||||
const char *PAPB_VC1_STRING = "PAPB_VC1";
|
const char *PAPB_VC1_STRING = "PAPB_VC1";
|
||||||
const char *PAPB_VC2_STRING = "PAPB_VC2";
|
const char *PAPB_VC2_STRING = "PAPB_VC2";
|
||||||
const char *PAPB_VC3_STRING = "PAPB_VC3";
|
const char *PAPB_VC3_STRING = "PAPB_VC3";
|
||||||
|
const char *PDEC_HANDLER_STRING = "PDEC_HANDLER";
|
||||||
const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER";
|
const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER";
|
||||||
const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6";
|
const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6";
|
||||||
const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START";
|
const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START";
|
||||||
@ -280,6 +281,8 @@ const char* translateObject(object_id_t object) {
|
|||||||
return PAPB_VC2_STRING;
|
return PAPB_VC2_STRING;
|
||||||
case 0x50000703:
|
case 0x50000703:
|
||||||
return PAPB_VC3_STRING;
|
return PAPB_VC3_STRING;
|
||||||
|
case 0x50000704:
|
||||||
|
return PDEC_HANDLER_STRING;
|
||||||
case 0x50000800:
|
case 0x50000800:
|
||||||
return CCSDS_HANDLER_STRING;
|
return CCSDS_HANDLER_STRING;
|
||||||
case 0x51000500:
|
case 0x51000500:
|
||||||
|
@ -3,6 +3,7 @@ target_sources(${TARGET_NAME} PUBLIC
|
|||||||
Ptme.cpp
|
Ptme.cpp
|
||||||
PdecHandler.cpp
|
PdecHandler.cpp
|
||||||
PdecConfig.cpp
|
PdecConfig.cpp
|
||||||
|
PtmeRateSetter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,14 +9,16 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
|
|
||||||
|
|
||||||
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
|
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
|
||||||
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory,
|
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory,
|
||||||
std::string uioRamMemory, std::string uioRegisters) :
|
std::string uioRamMemory, std::string uioRegisters) :
|
||||||
SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset(
|
SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset(
|
||||||
pdecReset), uioConfigMemory(uioConfigMemory), uioRamMemory(uioRamMemory), uioRegisters(
|
pdecReset), uioConfigMemory(uioConfigMemory), uioRamMemory(uioRamMemory), uioRegisters(
|
||||||
uioRegisters) {
|
uioRegisters), actionHelper(this, nullptr) {
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PdecHandler::~PdecHandler() {
|
PdecHandler::~PdecHandler() {
|
||||||
@ -62,9 +64,18 @@ ReturnValue_t PdecHandler::initialize() {
|
|||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = actionHelper.initialize(commandQueue);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t PdecHandler::getCommandQueue() const {
|
||||||
|
return commandQueue->getId();
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::getRegisterAddress() {
|
ReturnValue_t PdecHandler::getRegisterAddress() {
|
||||||
int fd = open(uioRegisters.c_str(), O_RDWR);
|
int fd = open(uioRegisters.c_str(), O_RDWR);
|
||||||
if (fd < 1) {
|
if (fd < 1) {
|
||||||
@ -168,6 +179,8 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
|||||||
|
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
|
readCommandQueue();
|
||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case State::INIT:
|
case State::INIT:
|
||||||
resetFarStatFlag();
|
resetFarStatFlag();
|
||||||
@ -183,7 +196,7 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
|||||||
if (newTcReceived()) {
|
if (newTcReceived()) {
|
||||||
handleNewTc();
|
handleNewTc();
|
||||||
}
|
}
|
||||||
getClcw();
|
checkLocks();
|
||||||
break;
|
break;
|
||||||
case State::WAIT_FOR_RECOVERY:
|
case State::WAIT_FOR_RECOVERY:
|
||||||
break;
|
break;
|
||||||
@ -195,6 +208,24 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
|||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdecHandler::readCommandQueue(void) {
|
||||||
|
CommandMessage commandMessage;
|
||||||
|
ReturnValue_t result = RETURN_FAILED;
|
||||||
|
|
||||||
|
result = commandQueue->receiveMessage(&commandMessage);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
result = actionHelper.handleActionMessage(&commandMessage);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CommandMessage reply;
|
||||||
|
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND,
|
||||||
|
commandMessage.getCommand());
|
||||||
|
commandQueue->reply(&reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PdecHandler::newTcReceived() {
|
bool PdecHandler::newTcReceived() {
|
||||||
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET);
|
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET);
|
||||||
|
|
||||||
@ -207,6 +238,19 @@ bool PdecHandler::newTcReceived() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdecHandler::checkLocks() {
|
||||||
|
uint32_t clcw = getClcw();
|
||||||
|
if (!(clcw & NO_RF_MASK) && (lastClcw & NO_RF_MASK)) {
|
||||||
|
// Rf available changed from 0 to 1
|
||||||
|
triggerEvent(CARRIER_LOCK);
|
||||||
|
}
|
||||||
|
if (!(clcw & NO_BITLOCK_MASK) && (lastClcw & NO_BITLOCK_MASK)) {
|
||||||
|
// Bit lock changed from 0 to 1
|
||||||
|
triggerEvent(BIT_LOCK);
|
||||||
|
}
|
||||||
|
lastClcw = clcw;
|
||||||
|
}
|
||||||
|
|
||||||
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
||||||
bool frameValid = false;
|
bool frameValid = false;
|
||||||
FrameAna_t frameAna = static_cast<FrameAna_t>((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION);
|
FrameAna_t frameAna = static_cast<FrameAna_t>((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION);
|
||||||
@ -434,21 +478,12 @@ uint8_t PdecHandler::getOddParity(uint8_t number) {
|
|||||||
return parityBit;
|
return parityBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdecHandler::getClcw() {
|
uint32_t PdecHandler::getClcw() {
|
||||||
|
return *(registerBaseAddress + PDEC_CLCW_OFFSET);
|
||||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
|
||||||
uint32_t clcw = *(registerBaseAddress + PDEC_CLCW_OFFSET);
|
|
||||||
if (debugDivider == 10) {
|
|
||||||
printClcw(clcw);
|
|
||||||
debugDivider = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debugDivider++;
|
|
||||||
#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdecHandler::printClcw(uint32_t clcw) {
|
void PdecHandler::printClcw() {
|
||||||
|
uint32_t clcw = getClcw();
|
||||||
uint8_t type = static_cast<uint8_t>((clcw >> 31) & 0x1);
|
uint8_t type = static_cast<uint8_t>((clcw >> 31) & 0x1);
|
||||||
uint8_t versionNo = static_cast<uint8_t>((clcw >> 29) & 0x3);
|
uint8_t versionNo = static_cast<uint8_t>((clcw >> 29) & 0x3);
|
||||||
uint8_t status = static_cast<uint8_t>((clcw >> 26) & 0x7);
|
uint8_t status = static_cast<uint8_t>((clcw >> 26) & 0x7);
|
||||||
@ -487,3 +522,15 @@ void PdecHandler::printClcw(uint32_t clcw) {
|
|||||||
sif::info << std::setw(30) << std::left << "CLCW rep value: " << std::hex
|
sif::info << std::setw(30) << std::left << "CLCW rep value: " << std::hex
|
||||||
<< "0x" << static_cast<unsigned int>(repValue) << std::endl;
|
<< "0x" << static_cast<unsigned int>(repValue) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||||
|
switch(actionId) {
|
||||||
|
case PRINT_CLCW:
|
||||||
|
printClcw();
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
default:
|
||||||
|
return COMMAND_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
|
#include "fsfw/action/ActionHelper.h"
|
||||||
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class controls the PDEC IP Core implemented in the programmable logic of the
|
* @brief This class controls the PDEC IP Core implemented in the programmable logic of the
|
||||||
@ -29,7 +31,10 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
|
class PdecHandler : public SystemObject,
|
||||||
|
public ExecutableObjectIF,
|
||||||
|
public HasReturnvaluesIF,
|
||||||
|
public HasActionsIF {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -51,6 +56,34 @@ public:
|
|||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
MessageQueueId_t getCommandQueue() const;
|
||||||
|
|
||||||
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* brief Returns the 32-bit wide communication link control word (CLCW)
|
||||||
|
*/
|
||||||
|
uint32_t getClcw();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @rief Reads and prints the CLCW. Can be useful for debugging.
|
||||||
|
*/
|
||||||
|
void printClcw();
|
||||||
|
|
||||||
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
||||||
|
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
||||||
|
//! P2: When frame declared illegal this parameter this parameter gives information about the reason (IReason field of the PDEC_FAR register)
|
||||||
|
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
||||||
|
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Carrier lock detected
|
||||||
|
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
||||||
|
static const Event BIT_LOCK = MAKE_EVENT(4, severity::INFO);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
||||||
@ -63,6 +96,9 @@ private:
|
|||||||
static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4);
|
static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4);
|
||||||
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||||
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
||||||
|
|
||||||
static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6);
|
static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6);
|
||||||
//! Error in version number and reserved A and B fields
|
//! Error in version number and reserved A and B fields
|
||||||
static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7);
|
static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7);
|
||||||
@ -79,14 +115,10 @@ private:
|
|||||||
//! Invalid BC control command
|
//! Invalid BC control command
|
||||||
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
// Action IDs
|
||||||
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
static const ActionId_t PRINT_CLCW = 0;
|
||||||
//! P2: When frame declared illegal this parameter this parameter gives information about the reason (IReason field of the PDEC_FAR register)
|
|
||||||
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
|
||||||
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
|
||||||
|
|
||||||
static const uint8_t STAT_POSITION = 31;
|
static const uint8_t STAT_POSITION = 31;
|
||||||
static const uint8_t FRAME_ANA_POSITION = 28;
|
static const uint8_t FRAME_ANA_POSITION = 28;
|
||||||
@ -124,7 +156,12 @@ private:
|
|||||||
static const size_t MAX_TC_SEGMENT_SIZE = 1017;
|
static const size_t MAX_TC_SEGMENT_SIZE = 1017;
|
||||||
static const uint8_t MAP_ID_MASK = 0x3F;
|
static const uint8_t MAP_ID_MASK = 0x3F;
|
||||||
|
|
||||||
|
#if BOARD_TE0720 == 1
|
||||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
|
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
|
||||||
|
#else
|
||||||
|
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
|
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
|
||||||
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
|
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
|
||||||
|
|
||||||
@ -139,6 +176,9 @@ private:
|
|||||||
|
|
||||||
static const uint32_t TC_SEGMENT_LEN = 1017;
|
static const uint32_t TC_SEGMENT_LEN = 1017;
|
||||||
|
|
||||||
|
static const uint32_t NO_RF_MASK = 0x8000;
|
||||||
|
static const uint32_t NO_BITLOCK_MASK = 0x4000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in
|
* TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in
|
||||||
* the PDEC memory.
|
* the PDEC memory.
|
||||||
@ -177,6 +217,11 @@ private:
|
|||||||
WAIT_FOR_RECOVERY
|
WAIT_FOR_RECOVERY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads and handles messages stored in the commandQueue
|
||||||
|
*/
|
||||||
|
void readCommandQueue(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC
|
* @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC
|
||||||
* registers. The register base address will be mapped into the virtual address space.
|
* registers. The register base address will be mapped into the virtual address space.
|
||||||
@ -222,6 +267,12 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool newTcReceived();
|
bool newTcReceived();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
||||||
|
* event.
|
||||||
|
*/
|
||||||
|
void checkLocks();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Analyzes the FramAna field (frame analysis data) of a FAR report.
|
* @brief Analyzes the FramAna field (frame analysis data) of a FAR report.
|
||||||
*
|
*
|
||||||
@ -279,9 +330,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
uint8_t getOddParity(uint8_t number);
|
uint8_t getOddParity(uint8_t number);
|
||||||
|
|
||||||
void getClcw();
|
|
||||||
void printClcw(uint32_t clcw);
|
|
||||||
|
|
||||||
object_id_t tcDestinationId;
|
object_id_t tcDestinationId;
|
||||||
|
|
||||||
AcceptsTelecommandsIF* tcDestination = nullptr;
|
AcceptsTelecommandsIF* tcDestination = nullptr;
|
||||||
@ -304,8 +352,12 @@ private:
|
|||||||
// UIO device file giving access to the PDEC register space
|
// UIO device file giving access to the PDEC register space
|
||||||
std::string uioRegisters;
|
std::string uioRegisters;
|
||||||
|
|
||||||
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
StorageManagerIF* tcStore = nullptr;
|
StorageManagerIF* tcStore = nullptr;
|
||||||
|
|
||||||
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
|
|
||||||
State state = State::INIT;
|
State state = State::INIT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,7 +376,8 @@ private:
|
|||||||
|
|
||||||
uint8_t tcSegment[TC_SEGMENT_LEN];
|
uint8_t tcSegment[TC_SEGMENT_LEN];
|
||||||
|
|
||||||
uint8_t debugDivider = 0;
|
// Used to check carrier and bit lock changes (default set to no rf and no bitlock)
|
||||||
|
uint32_t lastClcw = 0xC000;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_OBC_PDECHANDLER_H_ */
|
#endif /* LINUX_OBC_PDECHANDLER_H_ */
|
||||||
|
27
linux/obc/PtmeRateSetter.cpp
Normal file
27
linux/obc/PtmeRateSetter.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "PtmeRateSetter.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
|
PtmeRateSetter::PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif) :
|
||||||
|
bitrateSel(bitrateSel), gpioif(gpioif) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PtmeRateSetter::~PtmeRateSetter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PtmeRateSetter::setRate(BitRates rate) {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
switch(rate) {
|
||||||
|
case RATE_2000KHZ:
|
||||||
|
result = gpioif->pullHigh(bitrateSel);
|
||||||
|
break;
|
||||||
|
case RATE_400KHZ:
|
||||||
|
result = gpioif->pullLow(bitrateSel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::debug << "PtmeRateSetter::setRate: Invalid rate" << std::endl;
|
||||||
|
result = HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
40
linux/obc/PtmeRateSetter.h
Normal file
40
linux/obc/PtmeRateSetter.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef LINUX_OBC_PTMERATESETTER_H_
|
||||||
|
#define LINUX_OBC_PTMERATESETTER_H_
|
||||||
|
|
||||||
|
#include "TxRateSetterIF.h"
|
||||||
|
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||||
|
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Class to set the downlink bit rate by using the cadu_rate_switcher implemented in
|
||||||
|
* the programmable logic.
|
||||||
|
*
|
||||||
|
* @details The cadu_rate_switcher module sets the input rate to the syrlinks transceiver either
|
||||||
|
* to 2000 kHz (bitrateSel = 1) or 400 kHz (bitrate = 0).
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class PtmeRateSetter: public TxRateSetterIF {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* @param bitrateSel GPIO ID of the GPIO connected to the bitrate_sel input of the
|
||||||
|
* cadu_rate_switcher.
|
||||||
|
* @param gpioif GPIO interface to drive the bitrateSel GPIO
|
||||||
|
*/
|
||||||
|
PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif);
|
||||||
|
virtual ~PtmeRateSetter();
|
||||||
|
|
||||||
|
virtual ReturnValue_t setRate(BitRates rate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
gpioId_t bitrateSel = gpio::NO_GPIO;
|
||||||
|
|
||||||
|
GpioIF* gpioif = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LINUX_OBC_PTMERATESETTER_H_ */
|
25
linux/obc/TxRateSetterIF.h
Normal file
25
linux/obc/TxRateSetterIF.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef LINUX_OBC_TXRATESETTERIF_H_
|
||||||
|
#define LINUX_OBC_TXRATESETTERIF_H_
|
||||||
|
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
|
enum BitRates : uint32_t {
|
||||||
|
RATE_2000KHZ,
|
||||||
|
RATE_400KHZ
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Abstract class for objects implementing the functionality to switch the
|
||||||
|
* downlink bit rate.
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class TxRateSetterIF {
|
||||||
|
public:
|
||||||
|
TxRateSetterIF() {};
|
||||||
|
virtual ~TxRateSetterIF() {};
|
||||||
|
|
||||||
|
virtual ReturnValue_t setRate(BitRates bitRate) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LINUX_OBC_TXRATESETTERIF_H_ */
|
@ -2,21 +2,30 @@
|
|||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
|
#include "fsfw/events/EventManagerIF.h"
|
||||||
|
|
||||||
|
#include <linux/obc/PdecHandler.h>
|
||||||
|
|
||||||
#include "CCSDSHandler.h"
|
#include "CCSDSHandler.h"
|
||||||
|
|
||||||
CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination) :
|
CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
|
||||||
SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this) {
|
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData) :
|
||||||
|
SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this), actionHelper(
|
||||||
|
this, nullptr), txRateSetterIF(txRateSetterIF), gpioIF(gpioIF), enTxClock(
|
||||||
|
enTxClock), enTxData(enTxData) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||||
|
eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCSDSHandler::~CCSDSHandler() {
|
CCSDSHandler::~CCSDSHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) {
|
ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) {
|
||||||
|
checkEvents();
|
||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
handleTelemetry();
|
handleTelemetry();
|
||||||
handleTelecommands();
|
handleTelecommands();
|
||||||
|
checkTxTimer();
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +64,11 @@ ReturnValue_t CCSDSHandler::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = actionHelper.initialize(commandQueue);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
VirtualChannelMapIter iter;
|
VirtualChannelMapIter iter;
|
||||||
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||||
result = iter->second->initialize();
|
result = iter->second->initialize();
|
||||||
@ -64,6 +78,27 @@ ReturnValue_t CCSDSHandler::initialize() {
|
|||||||
iter->second->setPtmeObject(ptme);
|
iter->second->setPtmeObject(ptme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(
|
||||||
|
objects::EVENT_MANAGER);
|
||||||
|
if (manager == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "CCSDSHandler::initialize: Invalid event manager" << std::endl;
|
||||||
|
#endif
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
result = manager->registerListener(eventQueue->getId());
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = manager->subscribeToEventRange(eventQueue->getId(),
|
||||||
|
event::getEventId(PdecHandler::CARRIER_LOCK), event::getEventId(PdecHandler::BIT_LOCK));
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "CCSDSHandler::initialize: Failed to subscribe to events from PDEC "
|
||||||
|
"handler" << std::endl;
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,10 +112,15 @@ void CCSDSHandler::readCommandQueue(void) {
|
|||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
result = actionHelper.handleActionMessage(&commandMessage);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND,
|
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND,
|
||||||
commandMessage.getCommand());
|
commandMessage.getCommand());
|
||||||
commandQueue->reply(&reply);
|
commandQueue->reply(&reply);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,3 +180,119 @@ MessageQueueId_t CCSDSHandler::getRequestQueue() {
|
|||||||
// Forward packets directly to TC distributor
|
// Forward packets directly to TC distributor
|
||||||
return tcDistributorQueueId;
|
return tcDistributorQueueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||||
|
|
||||||
|
switch(actionId) {
|
||||||
|
case SET_LOW_RATE: {
|
||||||
|
txRateSetterIF->setRate(BitRates::RATE_400KHZ);
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case SET_HIGH_RATE: {
|
||||||
|
txRateSetterIF->setRate(BitRates::RATE_2000KHZ);
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case EN_TRANSMITTER: {
|
||||||
|
enableTransmit();
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case DIS_TRANSMITTER: {
|
||||||
|
disableTransmit();
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return COMMAND_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::checkEvents() {
|
||||||
|
EventMessage event;
|
||||||
|
for (ReturnValue_t result = eventQueue->receiveMessage(&event);
|
||||||
|
result == RETURN_OK; result = eventQueue->receiveMessage(&event)) {
|
||||||
|
switch (event.getMessageId()) {
|
||||||
|
case EventMessage::EVENT_MESSAGE:
|
||||||
|
handleEvent(&event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CCSDSHandler::handleEvent(EventMessage* eventMessage) {
|
||||||
|
Event event = eventMessage->getEvent();
|
||||||
|
switch(event){
|
||||||
|
case PdecHandler::BIT_LOCK: {
|
||||||
|
handleBitLockEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PdecHandler::CARRIER_LOCK: {
|
||||||
|
handleCarrierLockEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sif::debug << "CCSDSHandler::handleEvent: Did not subscribe to this event"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::handleBitLockEvent() {
|
||||||
|
if(transmitterCountdown.isBusy()) {
|
||||||
|
// Transmitter already enabled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
enableTransmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::handleCarrierLockEvent() {
|
||||||
|
if (!enableTxWhenCarrierLock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
enableTransmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::forwardLinkstate() {
|
||||||
|
VirtualChannelMapIter iter;
|
||||||
|
for(iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||||
|
iter->second->setLinkState(linkState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::enableTransmit() {
|
||||||
|
if(transmitterCountdown.isBusy()) {
|
||||||
|
// Transmitter already enabled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
transmitterCountdown.setTimeout(TRANSMITTER_TIMEOUT);
|
||||||
|
#if BOARD_TE0720 == 0
|
||||||
|
gpioIF->pullHigh(enTxClock);
|
||||||
|
gpioIF->pullHigh(enTxData);
|
||||||
|
#endif /* BOARD_TE0720 == 0 */
|
||||||
|
linkState = UP;
|
||||||
|
// Set link state of all virtual channels to link up
|
||||||
|
forwardLinkstate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::checkTxTimer() {
|
||||||
|
if(linkState == DOWN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (transmitterCountdown.hasTimedOut()) {
|
||||||
|
disableTransmit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCSDSHandler::disableTransmit() {
|
||||||
|
#if BOARD_TE0720 == 0
|
||||||
|
gpioIF->pullLow(enTxClock);
|
||||||
|
gpioIF->pullLow(enTxData);
|
||||||
|
#endif /* BOARD_TE0720 == 0 */
|
||||||
|
linkState = DOWN;
|
||||||
|
forwardLinkstate();
|
||||||
|
transmitterCountdown.setTimeout(0);
|
||||||
|
}
|
||||||
|
@ -8,6 +8,13 @@
|
|||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
#include "fsfw/parameters/ParameterHelper.h"
|
#include "fsfw/parameters/ParameterHelper.h"
|
||||||
|
#include "fsfw/action/ActionHelper.h"
|
||||||
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
|
#include "fsfw/timemanager/Countdown.h"
|
||||||
|
#include "fsfw/events/EventMessage.h"
|
||||||
|
#include "linux/obc/TxRateSetterIF.h"
|
||||||
|
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||||
|
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||||
#include "VirtualChannel.h"
|
#include "VirtualChannel.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@ -22,7 +29,8 @@ class CCSDSHandler: public SystemObject,
|
|||||||
public AcceptsTelemetryIF,
|
public AcceptsTelemetryIF,
|
||||||
public AcceptsTelecommandsIF,
|
public AcceptsTelecommandsIF,
|
||||||
public HasReturnvaluesIF,
|
public HasReturnvaluesIF,
|
||||||
public ReceivesParameterMessagesIF {
|
public ReceivesParameterMessagesIF,
|
||||||
|
public HasActionsIF {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using VcId_t = uint8_t;
|
using VcId_t = uint8_t;
|
||||||
@ -33,8 +41,14 @@ public:
|
|||||||
* @param objectId Object ID of the CCSDS handler
|
* @param objectId Object ID of the CCSDS handler
|
||||||
* @param ptmeId Object ID of the PTME object providing access to the PTME IP Core.
|
* @param ptmeId Object ID of the PTME object providing access to the PTME IP Core.
|
||||||
* @param tcDestination Object ID of object handling received TC space packets
|
* @param tcDestination Object ID of object handling received TC space packets
|
||||||
|
* @param txRateSetter Object providing the functionality to switch the input bitrate of
|
||||||
|
* the S-Band transceiver.
|
||||||
|
* @param gpioIF Required to enable TX data and TX clock RS485 transceiver chips.
|
||||||
|
* @param enTxClock GPIO ID of RS485 tx clock enable
|
||||||
|
* @param enTxData GPIO ID of RS485 tx data enable
|
||||||
*/
|
*/
|
||||||
CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination);
|
CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
|
||||||
|
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData);
|
||||||
|
|
||||||
~CCSDSHandler();
|
~CCSDSHandler();
|
||||||
|
|
||||||
@ -58,10 +72,34 @@ public:
|
|||||||
uint16_t getIdentifier() override;
|
uint16_t getIdentifier() override;
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() override;
|
||||||
|
|
||||||
|
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER;
|
||||||
|
|
||||||
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||||
|
|
||||||
|
static const ActionId_t SET_LOW_RATE = 0;
|
||||||
|
static const ActionId_t SET_HIGH_RATE = 1;
|
||||||
|
static const ActionId_t EN_TRANSMITTER = 2;
|
||||||
|
static const ActionId_t DIS_TRANSMITTER = 3;
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||||
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
||||||
|
|
||||||
|
#if TMTC_TEST_SETUP == 0
|
||||||
|
// syrlinks must not be transmitting more than 15 minutes (according to datasheet)
|
||||||
|
static const uint32_t TRANSMITTER_TIMEOUT = 900000; //900000 ms = 15 min
|
||||||
|
#else
|
||||||
|
// Set to high value when not sending via syrlinks
|
||||||
|
static const uint32_t TRANSMITTER_TIMEOUT = 86400000; // 1 day
|
||||||
|
#endif /* TMTC_TEST_SETUP == 0 */
|
||||||
|
|
||||||
|
static const bool UP = true;
|
||||||
|
static const bool DOWN = false;
|
||||||
|
|
||||||
using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannel*>;
|
using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannel*>;
|
||||||
using VirtualChannelMapIter = VirtualChannelMap::iterator;
|
using VirtualChannelMapIter = VirtualChannelMap::iterator;
|
||||||
|
|
||||||
@ -73,14 +111,58 @@ private:
|
|||||||
object_id_t tcDestination;
|
object_id_t tcDestination;
|
||||||
|
|
||||||
MessageQueueIF* commandQueue = nullptr;
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
|
|
||||||
ParameterHelper parameterHelper;
|
ParameterHelper parameterHelper;
|
||||||
|
|
||||||
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
MessageQueueId_t tcDistributorQueueId;
|
MessageQueueId_t tcDistributorQueueId;
|
||||||
|
|
||||||
|
TxRateSetterIF* txRateSetterIF = nullptr;
|
||||||
|
|
||||||
|
GpioIF* gpioIF = nullptr;
|
||||||
|
gpioId_t enTxClock = gpio::NO_GPIO;
|
||||||
|
gpioId_t enTxData = gpio::NO_GPIO;
|
||||||
|
|
||||||
|
// Countdown to disable transmitter after 15 minutes
|
||||||
|
Countdown transmitterCountdown;
|
||||||
|
|
||||||
|
// When true transmitting is started as soon as carrier lock has been detected
|
||||||
|
bool enableTxWhenCarrierLock = false;
|
||||||
|
|
||||||
|
bool linkState = DOWN;
|
||||||
|
|
||||||
void readCommandQueue(void);
|
void readCommandQueue(void);
|
||||||
void handleTelemetry();
|
void handleTelemetry();
|
||||||
void handleTelecommands();
|
void handleTelecommands();
|
||||||
|
void checkEvents();
|
||||||
|
void handleEvent(EventMessage* eventMessage);
|
||||||
|
|
||||||
|
void handleBitLockEvent();
|
||||||
|
void handleCarrierLockEvent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Forward link state to virtual channels.
|
||||||
|
*/
|
||||||
|
void forwardLinkstate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts transmit timer and enables transmitter.
|
||||||
|
*/
|
||||||
|
void enableTransmit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks Tx timer for timeout and disables RS485 tx clock and tx data in case
|
||||||
|
* timer has expired.
|
||||||
|
*/
|
||||||
|
void checkTxTimer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the
|
||||||
|
* RS485 transceiver chips to high.
|
||||||
|
*/
|
||||||
|
void disableTransmit();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CCSDSHANDLER_H_ */
|
#endif /* CCSDSHANDLER_H_ */
|
||||||
|
@ -64,6 +64,6 @@ void VirtualChannel::setPtmeObject(PtmeIF* ptme_) {
|
|||||||
ptme = ptme_;
|
ptme = ptme_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualChannel::setLinkState(bool linkIsUp) {
|
void VirtualChannel::setLinkState(bool linkIsUp_) {
|
||||||
linkIsUp = linkIsUp;
|
linkIsUp = linkIsUp_;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ class VirtualChannel: public AcceptsTelemetryIF, public HasReturnvaluesIF {
|
|||||||
* @brief Can be used by the owner to set the link state. Packets will be discarded if link
|
* @brief Can be used by the owner to set the link state. Packets will be discarded if link
|
||||||
* to ground station is down.
|
* to ground station is down.
|
||||||
*/
|
*/
|
||||||
void setLinkState(bool linkIsUp);
|
void setLinkState(bool linkIsUp_);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -46,11 +46,7 @@ private:
|
|||||||
MessageQueueIF* tmQueue = nullptr;
|
MessageQueueIF* tmQueue = nullptr;
|
||||||
uint8_t vcId;
|
uint8_t vcId;
|
||||||
|
|
||||||
#if OBSW_LINK_IS_UP == 1
|
|
||||||
bool linkIsUp = true;
|
|
||||||
#else
|
|
||||||
bool linkIsUp = false;
|
bool linkIsUp = false;
|
||||||
#endif /* OBSW_LINK_IS_UP == 1 */
|
|
||||||
|
|
||||||
StorageManagerIF* tmStore = nullptr;
|
StorageManagerIF* tmStore = nullptr;
|
||||||
};
|
};
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit b2cc2354d410b0bc0d80c481bfd37afc580e63cf
|
Subproject commit aabbb129a6df1d33cf10770a5ecb6336c698f0e6
|
Loading…
Reference in New Issue
Block a user