Merge remote-tracking branch 'origin/develop' into mueller/plpcdu-refactoring
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good

This commit is contained in:
2022-03-29 15:40:02 +02:00
84 changed files with 3529 additions and 1500 deletions

View File

@ -111,6 +111,9 @@ void ObjectFactory::produceGenericObjects() {
tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID});
sif::info << "Created TCP server for TMTC commanding with listener port "
<< tcpServer->getTcpPort() << std::endl;
#if TCP_SERVER_WIRETAPPING == 1
tcpServer->enableWiretapping(true);
#endif /* TCP_SERVER_WIRETAPPING == 1 */
#endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */
tmtcBridge->setMaxNumberOfPacketsStored(70);
#endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */

View File

@ -11,7 +11,6 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE
Max31865PT1000Handler.cpp
IMTQHandler.cpp
HeaterHandler.cpp
PlocMPSoCHandler.cpp
RadiationSensorHandler.cpp
GyroADIS1650XHandler.cpp
RwHandler.cpp

View File

@ -419,7 +419,7 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8]}));
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_RW,
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH2_RW_5V]}));
#if BOARD_TE0720 == 1
#ifdef TE0720_1CFA
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>({1}));
#else
localDataPoolMap.emplace(

View File

@ -306,7 +306,7 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool(localpool::DataPool &localDat
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_Q7S, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_RW, new PoolEntry<uint8_t>({0}));
#if BOARD_TE0720 == 1
#ifdef TE0720_1CFA
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>({1}));
#else
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>({0}));

View File

@ -493,6 +493,8 @@ void PayloadPcduHandler::checkAdcValues() {
}
params.getValue(PARAM_KEY_MAP[HPA_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_HPA], upperBound, I_HPA_OUT_OF_BOUNDS)) {
sif::warning << "PayloadPcduHandler::checkCurrent: I HPA exceeded limit: Measured "
<< adcSet.processed[I_HPA] << " mA" << std::endl;
return;
}
}

View File

@ -1,473 +0,0 @@
#include "PlocMPSoCHandler.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/CRC.h>
#include "OBSWConfig.h"
PlocMPSoCHandler::PlocMPSoCHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie)
: DeviceHandlerBase(objectId, comIF, comCookie) {
if (comCookie == NULL) {
sif::error << "PlocMPSoCHandler: Invalid com cookie" << std::endl;
}
}
PlocMPSoCHandler::~PlocMPSoCHandler() {}
void PlocMPSoCHandler::doStartUp() {
if (mode == _MODE_START_UP) {
setMode(MODE_ON);
}
}
void PlocMPSoCHandler::doShutDown() { setMode(_MODE_POWER_DOWN); }
ReturnValue_t PlocMPSoCHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
switch (deviceCommand) {
case (PLOC_MPSOC::TC_MEM_WRITE): {
return prepareTcMemWriteCommand(commandData, commandDataLen);
}
case (PLOC_MPSOC::TC_MEM_READ): {
return prepareTcMemReadCommand(commandData, commandDataLen);
}
default:
sif::debug << "PlocMPSoCHandler::buildCommandFromCommand: Command not implemented"
<< std::endl;
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
void PlocMPSoCHandler::fillCommandAndReplyMap() {
this->insertInCommandMap(PLOC_MPSOC::TC_MEM_WRITE);
this->insertInCommandMap(PLOC_MPSOC::TC_MEM_READ);
this->insertInReplyMap(PLOC_MPSOC::ACK_REPORT, 1, nullptr, PLOC_MPSOC::SIZE_ACK_REPORT);
this->insertInReplyMap(PLOC_MPSOC::EXE_REPORT, 3, nullptr, PLOC_MPSOC::SIZE_EXE_REPORT);
this->insertInReplyMap(PLOC_MPSOC::TM_MEMORY_READ_REPORT, 2, nullptr,
PLOC_MPSOC::SIZE_TM_MEM_READ_REPORT);
}
ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
ReturnValue_t result = RETURN_OK;
uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK;
switch (apid) {
case (PLOC_MPSOC::APID_ACK_SUCCESS):
*foundLen = PLOC_MPSOC::SIZE_ACK_REPORT;
*foundId = PLOC_MPSOC::ACK_REPORT;
break;
case (PLOC_MPSOC::APID_ACK_FAILURE):
*foundLen = PLOC_MPSOC::SIZE_ACK_REPORT;
*foundId = PLOC_MPSOC::ACK_REPORT;
break;
case (PLOC_MPSOC::APID_TM_MEMORY_READ_REPORT):
*foundLen = PLOC_MPSOC::SIZE_TM_MEM_READ_REPORT;
*foundId = PLOC_MPSOC::TM_MEMORY_READ_REPORT;
break;
case (PLOC_MPSOC::APID_EXE_SUCCESS):
*foundLen = PLOC_MPSOC::SIZE_EXE_REPORT;
*foundId = PLOC_MPSOC::EXE_REPORT;
break;
case (PLOC_MPSOC::APID_EXE_FAILURE):
*foundLen = PLOC_MPSOC::SIZE_EXE_REPORT;
*foundId = PLOC_MPSOC::EXE_REPORT;
break;
default: {
sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid apid" << std::endl;
*foundLen = remainingSize;
return INVALID_APID;
}
}
/**
* This should normally never fail. However, this function is also responsible for incrementing
* the packet sequence count why it is called here.
*/
result = checkPacketSequenceCount(start);
return result;
}
ReturnValue_t PlocMPSoCHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
ReturnValue_t result = RETURN_OK;
switch (id) {
case PLOC_MPSOC::ACK_REPORT: {
result = handleAckReport(packet);
break;
}
case (PLOC_MPSOC::TM_MEMORY_READ_REPORT): {
result = handleMemoryReadReport(packet);
break;
}
case (PLOC_MPSOC::EXE_REPORT): {
result = handleExecutionReport(packet);
break;
}
default: {
sif::debug << "PlocMPSoCHandler::interpretDeviceReply: Unknown device reply id" << std::endl;
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
}
return result;
}
void PlocMPSoCHandler::setNormalDatapoolEntriesInvalid() {}
uint32_t PlocMPSoCHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
ReturnValue_t PlocMPSoCHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
return HasReturnvaluesIF::RETURN_OK;
}
void PlocMPSoCHandler::setModeNormal() { mode = MODE_NORMAL; }
ReturnValue_t PlocMPSoCHandler::prepareTcMemWriteCommand(const uint8_t* commandData,
size_t commandDataLen) {
const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 |
*(commandData + 2) << 8 | *(commandData + 3);
const uint32_t memoryData = *(commandData + 4) << 24 | *(commandData + 5) << 16 |
*(commandData + 6) << 8 | *(commandData + 7);
packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK;
PLOC_MPSOC::TcMemWrite tcMemWrite(memoryAddress, memoryData, packetSequenceCount);
if (tcMemWrite.getFullSize() > PLOC_MPSOC::MAX_COMMAND_SIZE) {
sif::debug << "PlocMPSoCHandler::prepareTcMemWriteCommand: Command too big" << std::endl;
return RETURN_FAILED;
}
memcpy(commandBuffer, tcMemWrite.getWholeData(), tcMemWrite.getFullSize());
rawPacket = commandBuffer;
rawPacketLen = tcMemWrite.getFullSize();
nextReplyId = PLOC_MPSOC::ACK_REPORT;
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::prepareTcMemReadCommand(const uint8_t* commandData,
size_t commandDataLen) {
const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 |
*(commandData + 2) << 8 | *(commandData + 3);
packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK;
PLOC_MPSOC::TcMemRead tcMemRead(memoryAddress, packetSequenceCount);
if (tcMemRead.getFullSize() > PLOC_MPSOC::MAX_COMMAND_SIZE) {
sif::debug << "PlocMPSoCHandler::prepareTcMemReadCommand: Command too big" << std::endl;
return RETURN_FAILED;
}
memcpy(commandBuffer, tcMemRead.getWholeData(), tcMemRead.getFullSize());
rawPacket = commandBuffer;
rawPacketLen = tcMemRead.getFullSize();
nextReplyId = PLOC_MPSOC::ACK_REPORT;
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1);
uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2);
if (receivedCrc != recalculatedCrc) {
return CRC_FAILURE;
}
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::handleAckReport(const uint8_t* data) {
ReturnValue_t result = RETURN_OK;
result = verifyPacket(data, PLOC_MPSOC::SIZE_ACK_REPORT);
if (result == CRC_FAILURE) {
sif::error << "PlocMPSoCHandler::handleAckReport: CRC failure" << std::endl;
nextReplyId = PLOC_MPSOC::NONE;
replyRawReplyIfnotWiretapped(data, PLOC_MPSOC::SIZE_ACK_REPORT);
triggerEvent(CRC_FAILURE_EVENT);
sendFailureReport(PLOC_MPSOC::ACK_REPORT, CRC_FAILURE);
disableAllReplies();
return IGNORE_REPLY_DATA;
}
uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK;
switch (apid) {
case PLOC_MPSOC::APID_ACK_FAILURE: {
// TODO: Interpretation of status field in acknowledgment report
sif::debug << "PlocMPSoCHandler::handleAckReport: Received Ack failure report" << std::endl;
DeviceCommandId_t commandId = getPendingCommand();
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
triggerEvent(ACK_FAILURE, commandId);
}
sendFailureReport(PLOC_MPSOC::ACK_REPORT, RECEIVED_ACK_FAILURE);
disableAllReplies();
nextReplyId = PLOC_MPSOC::NONE;
result = IGNORE_REPLY_DATA;
break;
}
case PLOC_MPSOC::APID_ACK_SUCCESS: {
setNextReplyId();
break;
}
default: {
sif::debug << "PlocMPSoCHandler::handleAckReport: Invalid APID in Ack report" << std::endl;
result = RETURN_FAILED;
break;
}
}
return result;
}
ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) {
ReturnValue_t result = RETURN_OK;
result = verifyPacket(data, PLOC_MPSOC::SIZE_EXE_REPORT);
if (result == CRC_FAILURE) {
sif::error << "PlocMPSoCHandler::handleExecutionReport: CRC failure" << std::endl;
nextReplyId = PLOC_MPSOC::NONE;
return result;
}
uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK;
switch (apid) {
case (PLOC_MPSOC::APID_EXE_SUCCESS): {
break;
}
case (PLOC_MPSOC::APID_EXE_FAILURE): {
// TODO: Interpretation of status field in execution report
sif::error << "PlocMPSoCHandler::handleExecutionReport: Received execution failure report"
<< std::endl;
DeviceCommandId_t commandId = getPendingCommand();
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
triggerEvent(EXE_FAILURE, commandId);
} else {
sif::debug << "PlocMPSoCHandler::handleExecutionReport: Unknown command id" << std::endl;
}
sendFailureReport(PLOC_MPSOC::EXE_REPORT, RECEIVED_EXE_FAILURE);
disableExeReportReply();
result = IGNORE_REPLY_DATA;
break;
}
default: {
sif::error << "PlocMPSoCHandler::handleExecutionReport: Unknown APID" << std::endl;
result = RETURN_FAILED;
break;
}
}
nextReplyId = PLOC_MPSOC::NONE;
return result;
}
ReturnValue_t PlocMPSoCHandler::handleMemoryReadReport(const uint8_t* data) {
ReturnValue_t result = RETURN_OK;
result = verifyPacket(data, PLOC_MPSOC::SIZE_TM_MEM_READ_REPORT);
if (result == CRC_FAILURE) {
sif::error << "PlocMPSoCHandler::handleMemoryReadReport: Memory read report has invalid crc"
<< std::endl;
}
/** Send data to commanding queue */
handleDeviceTM(data + PLOC_MPSOC::DATA_FIELD_OFFSET, PLOC_MPSOC::SIZE_MEM_READ_REPORT_DATA,
PLOC_MPSOC::TM_MEMORY_READ_REPORT);
nextReplyId = PLOC_MPSOC::EXE_REPORT;
return result;
}
ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command,
uint8_t expectedReplies, bool useAlternateId,
DeviceCommandId_t alternateReplyID) {
ReturnValue_t result = RETURN_OK;
uint8_t enabledReplies = 0;
switch (command->first) {
case PLOC_MPSOC::TC_MEM_WRITE:
enabledReplies = 2;
break;
case PLOC_MPSOC::TC_MEM_READ: {
enabledReplies = 3;
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
PLOC_MPSOC::TM_MEMORY_READ_REPORT);
if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< PLOC_MPSOC::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl;
}
break;
}
default:
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
break;
}
/**
* Every command causes at least one acknowledgment and one execution report. Therefore both
* replies will be enabled here.
*/
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
PLOC_MPSOC::ACK_REPORT);
if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< PLOC_MPSOC::ACK_REPORT << " not in replyMap" << std::endl;
}
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
PLOC_MPSOC::EXE_REPORT);
if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< PLOC_MPSOC::EXE_REPORT << " not in replyMap" << std::endl;
}
return RETURN_OK;
}
void PlocMPSoCHandler::setNextReplyId() {
switch (getPendingCommand()) {
case PLOC_MPSOC::TC_MEM_READ:
nextReplyId = PLOC_MPSOC::TM_MEMORY_READ_REPORT;
break;
default:
/* If no telemetry is expected the next reply is always the execution report */
nextReplyId = PLOC_MPSOC::EXE_REPORT;
break;
}
}
size_t PlocMPSoCHandler::getNextReplyLength(DeviceCommandId_t commandId) {
size_t replyLen = 0;
if (nextReplyId == PLOC_MPSOC::NONE) {
return replyLen;
}
DeviceReplyIter iter = deviceReplyMap.find(nextReplyId);
if (iter != deviceReplyMap.end()) {
if (iter->second.delayCycles == 0) {
/* Reply inactive */
return replyLen;
}
replyLen = iter->second.replyLen;
} else {
sif::debug << "PlocMPSoCHandler::getNextReplyLength: No entry for reply with reply id "
<< std::hex << nextReplyId << " in deviceReplyMap" << std::endl;
}
return replyLen;
}
void PlocMPSoCHandler::handleDeviceTM(const uint8_t* data, size_t dataSize,
DeviceCommandId_t replyId) {
ReturnValue_t result = RETURN_OK;
if (wiretappingMode == RAW) {
/* Data already sent in doGetRead() */
return;
}
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
if (iter == deviceReplyMap.end()) {
sif::debug << "PlocMPSoCHandler::handleDeviceTM: Unknown reply id" << std::endl;
return;
}
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
if (queueId == NO_COMMANDER) {
return;
}
result = actionHelper.reportData(queueId, replyId, data, dataSize);
if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::handleDeviceTM: Failed to report data" << std::endl;
}
}
void PlocMPSoCHandler::disableAllReplies() {
DeviceReplyMap::iterator iter;
/* Disable ack reply */
iter = deviceReplyMap.find(PLOC_MPSOC::ACK_REPORT);
DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0;
info->command = deviceCommandMap.end();
DeviceCommandId_t commandId = getPendingCommand();
/* If the command expects a telemetry packet the appropriate tm reply will be disabled here */
switch (commandId) {
case PLOC_MPSOC::TC_MEM_WRITE:
break;
case PLOC_MPSOC::TC_MEM_READ: {
iter = deviceReplyMap.find(PLOC_MPSOC::TM_MEMORY_READ_REPORT);
info = &(iter->second);
info->delayCycles = 0;
info->command = deviceCommandMap.end();
break;
}
default: {
sif::debug << "PlocMPSoCHandler::disableAllReplies: Unknown command id" << commandId
<< std::endl;
break;
}
}
/* We must always disable the execution report reply here */
disableExeReportReply();
}
void PlocMPSoCHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) {
DeviceReplyIter iter = deviceReplyMap.find(replyId);
if (iter == deviceReplyMap.end()) {
sif::debug << "PlocMPSoCHandler::sendFailureReport: Reply not in reply map" << std::endl;
return;
}
DeviceCommandInfo* info = &(iter->second.command->second);
if (info == nullptr) {
sif::debug << "PlocMPSoCHandler::sendFailureReport: Reply has no active command" << std::endl;
return;
}
if (info->sendReplyTo != NO_COMMANDER) {
actionHelper.finish(false, info->sendReplyTo, iter->first, status);
}
info->isExecuting = false;
}
void PlocMPSoCHandler::disableExeReportReply() {
DeviceReplyIter iter = deviceReplyMap.find(PLOC_MPSOC::EXE_REPORT);
DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0;
info->command = deviceCommandMap.end();
/* Expected replies is set to one here. The value will set to 0 in replyToReply() */
info->command->second.expectedReplies = 0;
}
ReturnValue_t PlocMPSoCHandler::checkPacketSequenceCount(const uint8_t* data) {
uint16_t receivedSequenceCount = (*(data + 2) << 8 | *(data + 3)) & PACKET_SEQUENCE_COUNT_MASK;
uint16_t expectedPacketSequenceCount = ((packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK);
if (receivedSequenceCount != expectedPacketSequenceCount) {
sif::debug << "PlocMPSoCHandler::checkPacketSequenceCount: Packet sequence count mismatch. "
<< std::endl;
sif::debug << "Received sequence count: " << receivedSequenceCount << ". OBSW sequence "
<< "count: " << expectedPacketSequenceCount << std::endl;
}
packetSequenceCount = receivedSequenceCount;
return RETURN_OK;
}

View File

@ -1,212 +0,0 @@
#ifndef MISSION_DEVICES_PLOCMPSOCHANDLER_H_
#define MISSION_DEVICES_PLOCMPSOCHANDLER_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/devices/devicedefinitions/PlocMPSoCDefinitions.h>
#include <cstring>
/**
* @brief This is the device handler for the MPSoC which is programmed by the ILH of the
* university of stuttgart.
*
* @details
* The PLOC uses the space packet protocol for communication. To each command the PLOC
* answers with at least one acknowledgment and one execution report.
* Flight manual:
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_Commands
* ILH ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
* Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960
* @author J. Meier
*/
class PlocMPSoCHandler : public DeviceHandlerBase {
public:
PlocMPSoCHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie);
virtual ~PlocMPSoCHandler();
/**
* @brief Sets mode to MODE_NORMAL. Can be used for debugging.
*/
void setModeNormal();
protected:
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
void fillCommandAndReplyMap() override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
size_t* foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
void setNormalDatapoolEntriesInvalid() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command,
uint8_t expectedReplies = 1, bool useAlternateId = false,
DeviceCommandId_t alternateReplyID = 0) override;
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HANDLER;
//! Space Packet received from PLOC has invalid CRC
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
//! Received ACK failure reply from PLOC
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
//! Received execution failure reply from PLOC
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
//! Received space packet with invalid APID from PLOC
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER;
//! PLOC crc failure in telemetry packet
static const Event MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
//! PLOC receive acknowledgment failure report
static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
//! PLOC receive execution failure report
static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW);
//! PLOC reply has invalid crc
static const Event CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW);
static const uint16_t APID_MASK = 0x7FF;
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
uint8_t commandBuffer[PLOC_MPSOC::MAX_COMMAND_SIZE];
/**
* @brief This object is incremented each time a packet is sent or received. By checking the
* packet sequence count of a received packet, no packets can be lost without noticing
* it. Only the least significant 14 bits represent the packet sequence count in a
* space packet. Thus the maximum value amounts to 16383 (0x3FFF).
* @note Normally this should never happen because the PLOC replies are always sent in a
* fixed order. However, the PLOC software checks this value and will return an ACK
* failure report in case the sequence count is not incremented with each transferred
* space packet.
*/
uint16_t packetSequenceCount = 0x3FFF;
/**
* This variable is used to store the id of the next reply to receive. This is necessary
* because the PLOC sends as reply to each command at least one acknowledgment and execution
* report.
*/
DeviceCommandId_t nextReplyId = PLOC_MPSOC::NONE;
/**
* @brief This function fills the commandBuffer to initiate the write memory command.
*
* @param commandData Pointer to action command data.
* @param commanDataLen Size of command data in bytes.
*
* @return RETURN_OK if successful, else RETURN_FAILURE.
*/
ReturnValue_t prepareTcMemWriteCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief This function fills the commandBuffer to initiate the write reads command.
*
* @param commandData Pointer to action command data.
* @param commanDataLen Size of command data in bytes.
*
* @return RETURN_OK if successful, else RETURN_FAILURE.
*/
ReturnValue_t prepareTcMemReadCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief This function checks the crc of the received PLOC reply.
*
* @param start Pointer to the first byte of the reply.
* @param foundLen Pointer to the length of the whole packet.
*
* @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE.
*/
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
/**
* @brief This function handles the acknowledgment report.
*
* @param data Pointer to the data holding the acknowledgment report.
*
* @return RETURN_OK if successful, otherwise an error code.
*/
ReturnValue_t handleAckReport(const uint8_t* data);
/**
* @brief This function handles the data of a execution report.
*
* @param data Pointer to the received data packet.
*
* @return RETURN_OK if successful, otherwise an error code.
*/
ReturnValue_t handleExecutionReport(const uint8_t* data);
/**
* @brief This function handles the memory read report.
*
* @param data Pointer to the data buffer holding the memory read report.
*
* @return RETURN_OK if successful, otherwise an error code.
*/
ReturnValue_t handleMemoryReadReport(const uint8_t* data);
/**
* @brief Depending on the current active command, this function sets the reply id of the
* next reply after a successful acknowledgment report has been received. This is
* required by the function getNextReplyLength() to identify the length of the next
* reply to read.
*/
void setNextReplyId();
/**
* @brief This function handles action message replies in case the telemetry has been
* requested by another object.
*
* @param data Pointer to the telemetry data.
* @param dataSize Size of telemetry in bytes.
* @param replyId Id of the reply. This will be added to the ActionMessage.
*/
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
/**
* @brief In case an acknowledgment failure reply has been received this function disables
* all previously enabled commands and resets the exepected replies variable of an
* active command.
*/
void disableAllReplies();
/**
* @brief This function sends a failure report if the active action was commanded by an other
* object.
*
* @param replyId The id of the reply which signals a failure.
* @param status A status byte which gives information about the failure type.
*/
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status);
/**
* @brief This function disables the execution report reply. Within this function also the
* the variable expectedReplies of an active command will be set to 0.
*/
void disableExeReportReply();
/**
* @brief This function checks and increments the packet sequence count of a received space
* packet.
*
* @param data Pointer to a space packet.
*
* @return RETURN_OK if successful
*
* @details There should be never a case in which a wrong packet sequence count is received
* because the communication scheme between PLOC and OBC always follows a strict
* procedure. Thus this function mainly serves for debugging purposes to detected an
* invalid handling of the packet sequence count.
*/
ReturnValue_t checkPacketSequenceCount(const uint8_t* data);
};
#endif /* MISSION_DEVICES_PLOCMPSOCHANDLER_H_ */

View File

@ -30,12 +30,7 @@ void RwHandler::doStartUp() {
if (gpioComIF->pullHigh(enableGpio) != RETURN_OK) {
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to high";
}
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
setMode(MODE_NORMAL);
#else
setMode(_MODE_TO_ON);
#endif
}
void RwHandler::doShutDown() {
@ -472,52 +467,52 @@ void RwHandler::handleGetTelemetryReply(const uint8_t* packet) {
tmDataset.spiTotalNumOfErrors = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 |
*(packet + offset + 1) << 8 | *(packet + offset);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleTemperatureReply: Last reset status: "
sif::info << "RwHandler::handleGetTelemetryReply: Last reset status: "
<< static_cast<unsigned int>(tmDataset.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleTemperatureReply: MCU temperature: " << tmDataset.mcuTemperature
sif::info << "RwHandler::handleGetTelemetryReply: MCU temperature: " << tmDataset.mcuTemperature
<< std::endl;
sif::info << "RwHandler::handleTemperatureReply: Pressure sensor temperature: "
sif::info << "RwHandler::handleGetTelemetryReply: Pressure sensor temperature: "
<< tmDataset.pressureSensorTemperature << std::endl;
sif::info << "RwHandler::handleTemperatureReply: Pressure " << tmDataset.pressure << std::endl;
sif::info << "RwHandler::handleTemperatureReply: State: "
sif::info << "RwHandler::handleGetTelemetryReply: Pressure " << tmDataset.pressure << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: State: "
<< static_cast<unsigned int>(tmDataset.rwState.value) << std::endl;
sif::info << "RwHandler::handleTemperatureReply: CLC mode: "
sif::info << "RwHandler::handleGetTelemetryReply: CLC mode: "
<< static_cast<unsigned int>(tmDataset.rwClcMode.value) << std::endl;
sif::info << "RwHandler::handleTemperatureReply: Current speed: " << tmDataset.rwCurrSpeed
sif::info << "RwHandler::handleGetTelemetryReply: Current speed: " << tmDataset.rwCurrSpeed
<< std::endl;
sif::info << "RwHandler::handleTemperatureReply: Reference speed: " << tmDataset.rwRefSpeed
sif::info << "RwHandler::handleGetTelemetryReply: Reference speed: " << tmDataset.rwRefSpeed
<< std::endl;
sif::info << "RwHandler::handleTemperatureReply: Number of invalid CRC packets: "
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid CRC packets: "
<< tmDataset.numOfInvalidCrcPackets << std::endl;
sif::info << "RwHandler::handleTemperatureReply: Number of invalid length packets: "
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid length packets: "
<< tmDataset.numOfInvalidLenPackets << std::endl;
sif::info << "RwHandler::handleTemperatureReply: Number of invalid command packets: "
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid command packets: "
<< tmDataset.numOfInvalidCmdPackets << std::endl;
sif::info << "RwHandler::handleTemperatureReply: Number of command executed replies: "
sif::info << "RwHandler::handleGetTelemetryReply: Number of command executed replies: "
<< tmDataset.numOfCmdExecutedReplies << std::endl;
sif::info << "RwHandler::handleTemperatureReply: Number of command replies: "
sif::info << "RwHandler::handleGetTelemetryReply: Number of command replies: "
<< tmDataset.numOfCmdReplies << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of bytes written: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of bytes written: "
<< tmDataset.uartNumOfBytesWritten << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of bytes read: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of bytes read: "
<< tmDataset.uartNumOfBytesRead << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of parity errors: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of parity errors: "
<< tmDataset.uartNumOfParityErrors << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of noise errors: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of noise errors: "
<< tmDataset.uartNumOfNoiseErrors << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of frame errors: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of frame errors: "
<< tmDataset.uartNumOfFrameErrors << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of register overrun errors: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of register overrun errors: "
<< tmDataset.uartNumOfRegisterOverrunErrors << std::endl;
sif::info << "RwHandler::handleTemperatureReply: UART number of total errors: "
sif::info << "RwHandler::handleGetTelemetryReply: UART number of total errors: "
<< tmDataset.uartTotalNumOfErrors << std::endl;
sif::info << "RwHandler::handleTemperatureReply: SPI number of bytes written: "
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of bytes written: "
<< tmDataset.spiNumOfBytesWritten << std::endl;
sif::info << "RwHandler::handleTemperatureReply: SPI number of bytes read: "
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of bytes read: "
<< tmDataset.spiNumOfBytesRead << std::endl;
sif::info << "RwHandler::handleTemperatureReply: SPI number of register overrun errors: "
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of register overrun errors: "
<< tmDataset.spiNumOfRegisterOverrunErrors << std::endl;
sif::info << "RwHandler::handleTemperatureReply: SPI number of register total errors: "
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of register total errors: "
<< tmDataset.spiTotalNumOfErrors << std::endl;
#endif
}

View File

@ -1,166 +0,0 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
#include <fsfw/globalfunctions/CRC.h>
#include <fsfw/serialize/SerializeAdapter.h>
#include <fsfw/tmtcpacket/SpacePacket.h>
namespace PLOC_MPSOC {
static const DeviceCommandId_t NONE = 0x0;
static const DeviceCommandId_t TC_MEM_WRITE = 0x1;
static const DeviceCommandId_t TC_MEM_READ = 0x2;
static const DeviceCommandId_t ACK_REPORT = 0x3;
static const DeviceCommandId_t EXE_REPORT = 0x5;
static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 0x6;
static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_TM_MEM_READ_REPORT = 18;
/**
* SpacePacket apids of PLOC telecommands and telemetry.
*/
static const uint16_t APID_TC_MEM_WRITE = 0x714;
static const uint16_t APID_TC_MEM_READ = 0x715;
static const uint16_t APID_TM_MEMORY_READ_REPORT = 0x404;
static const uint16_t APID_ACK_SUCCESS = 0x400;
static const uint16_t APID_ACK_FAILURE = 0x401;
static const uint16_t APID_EXE_SUCCESS = 0x402;
static const uint16_t APID_EXE_FAILURE = 0x403;
/** Offset from first byte in Space packet to first byte of data field */
static const uint8_t DATA_FIELD_OFFSET = 6;
/**
* The size of payload data which will be forwarded to the requesting object. e.g. PUS Service
* 8.
*/
static const uint8_t SIZE_MEM_READ_REPORT_DATA = 10;
/**
* PLOC space packet length for fixed size packets. This is the size of the whole packet data
* field. For the length field in the space packet this size will be substracted by one.
*/
static const uint16_t LENGTH_TC_MEM_WRITE = 12;
static const uint16_t LENGTH_TC_MEM_READ = 8;
static const size_t MAX_REPLY_SIZE = SIZE_TM_MEM_READ_REPORT;
static const size_t MAX_COMMAND_SIZE = 18;
/**
* @brief This class helps to build the memory read command for the PLOC.
*
* @details The last two bytes of the packet data field contain a CRC calculated over the whole
* space packet. This is the CRC-16-CCITT as specified in
* ECSS-E-ST-70-41C Telemetry and telecommand packet utilization.
*/
class TcMemRead : public SpacePacket {
public:
/**
* @brief Constructor
*
* @param memAddr The memory address to read from.
*/
TcMemRead(const uint32_t memAddr, uint16_t sequenceCount)
: SpacePacket(LENGTH_TC_MEM_READ - 1, true, APID_TC_MEM_READ, sequenceCount) {
fillPacketDataField(&memAddr);
}
private:
/**
* @brief This function builds the packet data field for the mem read command.
*
* @param memAddrPtr Pointer to the memory address to read from.
*/
void fillPacketDataField(const uint32_t* memAddrPtr) {
/* Add memAddr to packet data field */
size_t serializedSize = 0;
uint8_t* memoryAddressPos = this->localData.fields.buffer;
SerializeAdapter::serialize<uint32_t>(memAddrPtr, &memoryAddressPos, &serializedSize,
sizeof(*memAddrPtr), SerializeIF::Endianness::LITTLE);
/* Add memLen to packet data field */
this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD] = 1;
this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD + 1] = 0;
/* Calculate crc */
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
sizeof(CCSDSPrimaryHeader) + LENGTH_TC_MEM_READ - CRC_SIZE);
/* Add crc to packet data field of space packet */
serializedSize = 0;
uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET;
SerializeAdapter::serialize<uint16_t>(&crc, &crcPos, &serializedSize, sizeof(crc),
SerializeIF::Endianness::BIG);
}
static const uint8_t OFFSET_MEM_LEN_FIELD = 4;
static const uint8_t CRC_OFFSET = 6;
};
/**
* @brief This class helps to generate the space packet to write to a memory address within
* the PLOC.
* @details The last two bytes of the packet data field contain a CRC calculated over the whole
* space packet. This is the CRC-16-CCITT as specified in
* ECSS-E-ST-70-41C Telemetry and telecommand packet utilization.
*/
class TcMemWrite : public SpacePacket {
public:
/**
* @brief Constructor
*
* @param memAddr The PLOC memory address where to write to.
* @param memoryData The data to write to the specified memory address.
* @param sequenceCount The subsequence count. Must be incremented with each new packet.
*/
TcMemWrite(const uint32_t memAddr, const uint32_t memoryData, uint16_t sequenceCount)
: SpacePacket(LENGTH_TC_MEM_WRITE - 1, true, APID_TC_MEM_WRITE, sequenceCount) {
fillPacketDataField(&memAddr, &memoryData);
}
private:
/**
* @brief This function builds the packet data field for the mem write command.
*
* @param memAddrPtr Pointer to the PLOC memory address where to write to.
* @param memoryDataPtr Pointer to the memoryData to write
*/
void fillPacketDataField(const uint32_t* memAddrPtr, const uint32_t* memoryDataPtr) {
/* Add memAddr to packet data field */
size_t serializedSize = 0;
uint8_t* memoryAddressPos = this->localData.fields.buffer;
SerializeAdapter::serialize<uint32_t>(memAddrPtr, &memoryAddressPos, &serializedSize,
sizeof(*memAddrPtr), SerializeIF::Endianness::BIG);
/* Add memLen to packet data field */
this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD] = 1;
this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD + 1] = 0;
/* Add memData to packet data field */
serializedSize = 0;
uint8_t* memoryDataPos = this->localData.fields.buffer + OFFSET_MEM_DATA_FIELD;
SerializeAdapter::serialize<uint32_t>(memoryDataPtr, &memoryDataPos, &serializedSize,
sizeof(*memoryDataPtr), SerializeIF::Endianness::BIG);
/* Calculate crc */
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
sizeof(CCSDSPrimaryHeader) + LENGTH_TC_MEM_WRITE - CRC_SIZE);
serializedSize = 0;
uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET;
/* Add crc to packet data field of space packet */
SerializeAdapter::serialize<uint16_t>(&crc, &crcPos, &serializedSize, sizeof(crc),
SerializeIF::Endianness::BIG);
}
/** Offsets from base address of packet data field */
static const uint8_t OFFSET_MEM_LEN_FIELD = 4;
static const uint8_t OFFSET_MEM_DATA_FIELD = 6;
static const uint8_t CRC_OFFSET = 10;
};
} // namespace PLOC_MPSOC
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */

View File

@ -162,7 +162,7 @@ static constexpr double DFT_MPA_I_UPPER_BOUND = 650.0;
static constexpr double DFT_HPA_U_LOWER_BOUND = 9.4;
static constexpr double DFT_HPA_U_UPPER_BOUND = 11.0;
static constexpr double DFT_HPA_I_UPPER_BOUND = 3000.0;
static constexpr double DFT_HPA_I_UPPER_BOUND = 3800.0;
// Wait time in floating point seconds
static constexpr double DFT_SSR_TO_DRO_WAIT_TIME = 5.0;

View File

@ -313,7 +313,7 @@ void CCSDSHandler::enableTransmit() {
return;
}
transmitterCountdown.setTimeout(TRANSMITTER_TIMEOUT);
#if BOARD_TE0720 == 0
#ifdef TE0720_1CFA
gpioIF->pullHigh(enTxClock);
gpioIF->pullHigh(enTxData);
#endif /* BOARD_TE0720 == 0 */
@ -332,7 +332,7 @@ void CCSDSHandler::checkTxTimer() {
}
void CCSDSHandler::disableTransmit() {
#if BOARD_TE0720 == 0
#ifdef TE0720_1CFA
gpioIF->pullLow(enTxClock);
gpioIF->pullLow(enTxData);
#endif /* BOARD_TE0720 == 0 */