#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ #include #include #include namespace PLOC { static const DeviceCommandId_t NONE = 0x0; static const DeviceCommandId_t TC_MEM_WRITE = 0x714; static const DeviceCommandId_t TC_MEM_READ = 0x715; 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_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; /** * 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) : SpacePacket(LENGTH_TC_MEM_READ - 1, true, APID_TC_MEM_READ) { 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(memAddrPtr, &memoryAddressPos, &serializedSize, sizeof(*memAddrPtr), SerializeIF::Endianness::BIG); /* Add memLen to packet data field */ this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD] = 0; this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD + 1] = 1; /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + LENGTH_TC_MEM_READ - CRC_SIZE, 0); /* Add crc to packet data field of space packet */ serializedSize = 0; uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); memcpy(this->localData.fields.buffer + CRC_OFFSET, &crc, sizeof(crc)); } 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. */ TcMemWrite(const uint32_t memAddr, const uint32_t memoryData) : SpacePacket(LENGTH_TC_MEM_WRITE - 1, true, APID_TC_MEM_WRITE) { 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(memAddrPtr, &memoryAddressPos, &serializedSize, sizeof(*memAddrPtr), SerializeIF::Endianness::BIG); /* Add memLen to packet data field */ this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD] = 0; this->localData.fields.buffer[OFFSET_MEM_LEN_FIELD + 1] = 1; /* Add memData to packet data field */ serializedSize = 0; uint8_t* memoryDataPos = this->localData.fields.buffer + OFFSET_MEM_DATA_FIELD; SerializeAdapter::serialize(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, 0); serializedSize = 0; uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; /* Add crc to packet data field of space packet */ SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); memcpy(this->localData.fields.buffer + CRC_OFFSET, &crc, sizeof(crc)); } /** 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; }; } #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ */