transmit enable and timeout
This commit is contained in:
parent
ec7568337c
commit
345ccf5392
@ -110,7 +110,7 @@ void initmission::initTasks() {
|
||||
// If a command has not been read before the next one arrives, the old command will be
|
||||
// overwritten by the PDEC.
|
||||
PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask(
|
||||
"PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.6, missedDeadlineFunc);
|
||||
"PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
|
||||
result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
|
||||
|
@ -951,7 +951,8 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) {
|
||||
TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(gpioIds::BIT_RATE_SEL, gpioComIF);
|
||||
|
||||
CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME,
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF);
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF, gpioComIF,
|
||||
gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||
|
||||
VirtualChannel* vc = nullptr;
|
||||
vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE);
|
||||
|
@ -78,6 +78,7 @@
|
||||
0x50000701;PAPB_VC1
|
||||
0x50000702;PAPB_VC2
|
||||
0x50000703;PAPB_VC3
|
||||
0x50000704;PDEC_HANDLER
|
||||
0x50000800;CCSDS_HANDLER
|
||||
0x51000500;PUS_SERVICE_6
|
||||
0x53000000;FSFW_OBJECTS_START
|
||||
|
|
@ -37,7 +37,7 @@ debugging. */
|
||||
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
||||
#define OBSW_TM_TO_PTME 1
|
||||
// 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 OBSW_ENABLE_TIMERS 1
|
||||
#define OBSW_ADD_STAR_TRACKER 0
|
||||
|
@ -196,6 +196,7 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
||||
if (newTcReceived()) {
|
||||
handleNewTc();
|
||||
}
|
||||
checkLocks();
|
||||
break;
|
||||
case State::WAIT_FOR_RECOVERY:
|
||||
break;
|
||||
@ -237,6 +238,19 @@ bool PdecHandler::newTcReceived() {
|
||||
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 frameValid = false;
|
||||
FrameAna_t frameAna = static_cast<FrameAna_t>((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION);
|
||||
|
@ -71,6 +71,19 @@ public:
|
||||
*/
|
||||
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:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
||||
@ -102,15 +115,6 @@ private:
|
||||
//! Invalid BC control command
|
||||
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
||||
|
||||
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);
|
||||
|
||||
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||
|
||||
// Action IDs
|
||||
@ -172,6 +176,9 @@ private:
|
||||
|
||||
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
|
||||
* the PDEC memory.
|
||||
@ -260,6 +267,12 @@ private:
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -362,6 +375,9 @@ private:
|
||||
uint32_t pdecFar = 0;
|
||||
|
||||
uint8_t tcSegment[TC_SEGMENT_LEN];
|
||||
|
||||
// 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_ */
|
||||
|
@ -1,24 +1,32 @@
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/events/EventManagerIF.h"
|
||||
|
||||
#include <linux/obc/PdecHandler.h>
|
||||
|
||||
#include "CCSDSHandler.h"
|
||||
|
||||
CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
|
||||
TxRateSetterIF* txRateSetterIF) :
|
||||
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData) :
|
||||
SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this), actionHelper(
|
||||
this, nullptr), txRateSetterIF(txRateSetterIF) {
|
||||
this, nullptr), txRateSetterIF(txRateSetterIF), gpioIF(gpioIF), enTxClock(
|
||||
enTxClock), enTxData(enTxData) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 2);
|
||||
}
|
||||
|
||||
CCSDSHandler::~CCSDSHandler() {
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) {
|
||||
checkEvents();
|
||||
readCommandQueue();
|
||||
handleTelemetry();
|
||||
handleTelecommands();
|
||||
checkTxTimer();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
@ -71,6 +79,27 @@ ReturnValue_t CCSDSHandler::initialize() {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -157,13 +186,113 @@ ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||
|
||||
switch(actionId) {
|
||||
case SET_LOW_RATE:
|
||||
case SET_LOW_RATE: {
|
||||
txRateSetterIF->setRate(BitRates::RATE_400KHZ);
|
||||
return EXECUTION_FINISHED;
|
||||
case SET_HIGH_RATE:
|
||||
}
|
||||
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->pullLow(enTxClock);
|
||||
gpioIF->pullLow(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->pullHigh(enTxClock);
|
||||
gpioIF->pullHigh(enTxData);
|
||||
#endif /* BOARD_TE0720 == 0 */
|
||||
linkState = DOWN;
|
||||
forwardLinkstate();
|
||||
}
|
||||
|
@ -10,7 +10,11 @@
|
||||
#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 <unordered_map>
|
||||
|
||||
@ -39,9 +43,12 @@ public:
|
||||
* @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,
|
||||
TxRateSetterIF* txRateSetterIF);
|
||||
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData);
|
||||
|
||||
~CCSDSHandler();
|
||||
|
||||
@ -76,10 +83,19 @@ private:
|
||||
|
||||
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);
|
||||
|
||||
// syrlinks must not be transmitting more than 15 minutes (according to datasheet)
|
||||
// static const uint32_t TRANSMITTER_TIMEOUT = 900000; //900000 ms = 15 min
|
||||
static const uint32_t TRANSMITTER_TIMEOUT = 10000; //900000 ms = 15 min
|
||||
|
||||
static const bool UP = true;
|
||||
static const bool DOWN = false;
|
||||
|
||||
using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannel*>;
|
||||
using VirtualChannelMapIter = VirtualChannelMap::iterator;
|
||||
|
||||
@ -91,6 +107,7 @@ private:
|
||||
object_id_t tcDestination;
|
||||
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
|
||||
ParameterHelper parameterHelper;
|
||||
|
||||
@ -100,9 +117,48 @@ private:
|
||||
|
||||
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 handleTelemetry();
|
||||
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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user