eive-obsw/bsp_q7s/devices/devicedefinitions/PlocMPSoCDefinitions.h
2022-01-06 18:05:21 +01:00

350 lines
11 KiB
C++

#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
#include <fsfw/tmtcpacket/SpacePacket.h>
#include <fsfw/globalfunctions/CRC.h>
#include <fsfw/serialize/SerializeAdapter.h>
#include <bsp_q7s/devices/ploc/PlocMPSoCHandler.h>
namespace mpsoc {
static const DeviceCommandId_t NONE = 0;
static const DeviceCommandId_t TC_MEM_WRITE = 1;
static const DeviceCommandId_t TC_MEM_READ = 2;
static const DeviceCommandId_t ACK_REPORT = 3;
static const DeviceCommandId_t EXE_REPORT = 5;
static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 6;
static const DeviceCommandId_t TC_FLASHFOPEN = 7;
static const DeviceCommandId_t TC_FLASHFCLOSE = 8;
static const DeviceCommandId_t TC_FLASHWRITE = 9;
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.
*/
namespace apid {
static const uint16_t TC_MEM_WRITE = 0x114;
static const uint16_t TC_MEM_READ = 0x115;
static const uint16_t TC_FLASHWRITE = 0x117;
static const uint16_t TC_FLASHFOPEN = 0x119;
static const uint16_t TC_FLASHFCLOSE = 0x11A;
static const uint16_t TM_MEMORY_READ_REPORT = 0x404;
static const uint16_t ACK_SUCCESS = 0x400;
static const uint16_t ACK_FAILURE = 0x401;
static const uint16_t EXE_SUCCESS = 0x402;
static const uint16_t 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;
static const size_t MAX_FILENAME_SIZE = 256;
/**
* 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 = SpacePacket::PACKET_MAX_SIZE;
static const size_t MAX_COMMAND_SIZE = SpacePacket::PACKET_MAX_SIZE;
static const size_t MAX_DATA_SIZE = 1016;
/**
* @breif Abstract base class for TC space packet of MPSoC.
*/
class TcBase : public SpacePacket, public HasReturnvaluesIF {
public:
// Initial length field of space packet. Will always be updated when packet is created.
static const uint16_t INIT_LENGTH = 1;
static const uint8_t INTERFACE_ID = CLASS_ID::MPSOC_CMD;
//! [EXPORT] : [COMMENT] Received command with invalid length
static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xA0);
/**
* @brief Constructor
*
* @param sequenceCount Sequence count of space packet which will be incremented with each
* sent and received packet.s
*/
TcBase(uint16_t apid, uint16_t sequenceCount) :
SpacePacket(INIT_LENGTH, true, apid, sequenceCount) {
}
/**
* @brief Function to initialitze the space packet
*
* @param commandData Pointer to command specific data
* @param commandDataLen Length of command data
*
* @return RETURN_OK if packet creation was successful, otherwise error return value
*/
ReturnValue_t createPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
result = initPacket(commandData, commandDataLen);
if (result != RETURN_OK) {
return result;
}
result = addCrc();
if (result != RETURN_OK) {
return result;
}
return result;
}
protected:
/**
* @brief Must be overwritten by the child class to define the command specific parameters
*
* @param commandData Pointer to received command data
* @param commandDataLen Length of received command data
*/
virtual ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) = 0;
private:
/**
* @brief Calculates and adds the CRC
*/
ReturnValue_t addCrc() {
ReturnValue_t result = RETURN_OK;
size_t serializedSize = 0;
uint32_t full_size = getFullSize();
uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE);
result = SerializeAdapter::serialize<uint16_t>(&crc,
this->localData.byteStream + full_size - CRC_SIZE, &serializedSize, sizeof(crc),
SerializeIF::Endianness::BIG);
if (result != RETURN_OK) {
sif::debug << "TcBase::addCrc: Failed to serialize crc field" << std::endl;
}
return result;
}
};
/**
* @brief Class for handling tm replies of the PLOC MPSoC.
*/
class TmPacket : public SpacePacket, public HasReturnvaluesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::MPSOC_CMD;
//! [EXPORT] : [COMMENT] CRC check of received packet failed
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
/**
* @brief Constructor creates idle packet and sets length field to maximum allowed size.
*/
TmPacket() : SpacePacket(PACKET_MAX_SIZE) {
}
ReturnValue_t checkCrc() {
uint8_t crcPtr = this->getPacketData() + this->getPacketDataLength() - 1;
uint16_t receivedCrc = *(crcPtr) << 8 | *(crcPtr + 1);
uint16_t recalculatedCrc = CRC::crc16ccitt(this->localData.byteStream, this->getFullSize());
if (recalculatedCrc != this->ge) {
return CRC_FAILURE;
}
return RETURN_OK;
}
};
/**
* @brief This class helps to build the memory read command for the PLOC.
*/
class TcMemRead: public TcBase {
public:
/**
* @brief Constructor
*/
TcMemRead(uint16_t sequenceCount) :
TcBase(apid::TC_MEM_READ, sequenceCount) {
this->setPacketDataLength(PACKET_LENGTH);
}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, MEM_ADDRESS_SIZE);
std::memcpy(this->localData.fields.buffer + MEM_ADDRESS_SIZE,
commandData + MEM_ADDRESS_SIZE, MEM_LEN_SIZE);
return result;
}
private:
static const size_t COMMAND_LENGTH = 6;
static const size_t MEM_ADDRESS_SIZE = 4;
static const size_t MEM_LEN_SIZE = 2;
static const uint16_t PACKET_LENGTH = 7;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_LENGTH){
return INVALID_LENGTH;
}
return RETURN_OK;
}
};
/**
* @brief This class helps to generate the space packet to write data to a memory address within
* the PLOC.
*/
class TcMemWrite: public TcBase {
public:
/**
* @brief Constructor
*/
TcMemWrite(uint16_t sequenceCount) : TcBase(apid::TC_MEM_WRITE, sequenceCount) {
this->setPacketDataLength(PACKET_LENGTH);
}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, MEM_ADDRESS_SIZE);
std::memcpy(this->localData.fields.buffer + MEM_ADDRESS_SIZE,
commandData + MEM_ADDRESS_SIZE, MEM_DATA_SIZE);
return result;
}
private:
static const size_t COMMAND_LENGTH = 8;
static const uint16_t PACKET_LENGTH = 9;
static const size_t MEM_ADDRESS_SIZE = 4;
static const size_t MEM_DATA_SIZE = 4;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_LENGTH) {
return INVALID_LENGTH;
}
return RETURN_OK;
}
};
/**
* @brief Class to help creation of flash fopen command.
*/
class FlashFopen : public TcBase {
public:
FlashFopen(uint16_t sequenceCount) :
TcBase(apid::TC_FLASHFOPEN, sequenceCount) {
}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != RETURN_OK) {
return result;
}
std::string filename = std::string(reinterpret_cast<const char*>(commandData), commandDataLen - 1);
accessMode = *(commandData + commandDataLen);
uint16_t truePacketLen = filename.size() + sizeof(accessMode) + CRC_SIZE;
this->setPacketDataLength(truePacketLen - 1);
std::memcpy(this->getPacketData(), filename.c_str(),
truePacketLen - CRC_SIZE - sizeof(accessMode));
std::memcpy(this->getPacketData() + truePacketLen - CRC_SIZE, &accessMode,
sizeof(accessMode));
return RETURN_OK;
}
private:
uint8_t accessMode = 0;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen > MAX_FILENAME_SIZE + sizeof(accessMode)) {
return INVALID_LENGTH;
}
return RETURN_OK;
}
};
/**
* @brief Class to help creation of flash fclose command.
*/
class FlashFclose : public TcBase {
public:
FlashFclose(uint16_t sequenceCount) :
TcBase(apid::TC_FLASHFCLOSE, sequenceCount) {
}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != RETURN_OK) {
return result;
}
std::string filename = std::string(reinterpret_cast<const char*>(commandData), commandDataLen - 1);
uint16_t truePacketLen = filename.size() + CRC_SIZE;
this->setPacketDataLength(truePacketLen - 1);
std::memcpy(this->getPacketData(), filename.c_str(),
truePacketLen - CRC_SIZE);
return RETURN_OK;
}
private:
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen > MAX_FILENAME_SIZE) {
return INVALID_LENGTH;
}
return RETURN_OK;
}
};
/**
* @brief Class to build flash write space packet.
*/
class FlashWrite : public TcBase {
public:
FlashWrite(uint16_t sequenceCount) :
TcBase(apid::TC_FLASHWRITE, sequenceCount) {
}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen > MAX_DATA_SIZE) {
sif::debug << "FlashWrite::initPacket: Command data too big" << std::endl;
return RETURN_FAILED;
}
std::memcpy(this->getPacketData(), commandData, commandDataLen);
this->setPacketDataLength(static_cast<uint16_t>(commandDataLen + CRC_SIZE - 1));
return RETURN_OK;
}
};
}
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */