#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ #include #include #include #include #include #include namespace PLOC_SPV { /** Command IDs */ static const DeviceCommandId_t NONE = 0; static const DeviceCommandId_t GET_HK_REPORT = 1; static const DeviceCommandId_t RESTART_MPSOC = 2; static const DeviceCommandId_t START_MPSOC = 3; static const DeviceCommandId_t SHUTDOWN_MPSOC = 4; static const DeviceCommandId_t SEL_MPSOC_BOOT_IMAGE = 5; static const DeviceCommandId_t SET_BOOT_TIMEOUT = 6; static const DeviceCommandId_t SET_MAX_RESTART_TRIES = 7; static const DeviceCommandId_t RESET_MPSOC = 8; static const DeviceCommandId_t SET_TIME_REF = 9; static const DeviceCommandId_t DISABLE_PERIOIC_HK_TRANSMISSION = 10; static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; /** Notifies the supervisor that a new update is available for the MPSoC */ static const DeviceCommandId_t UPDATE_AVAILABLE = 12; static const DeviceCommandId_t WATCHDOGS_ENABLE = 13; static const DeviceCommandId_t WATCHDOGS_CONFIG_TIMEOUT = 14; static const DeviceCommandId_t ENABLE_LATCHUP_ALERT = 15; static const DeviceCommandId_t DISABLE_LATCHUP_ALERT = 16; static const DeviceCommandId_t AUTO_CALIBRATE_ALERT = 17; static const DeviceCommandId_t SET_ALERT_LIMIT = 18; static const DeviceCommandId_t SET_ALERT_IRQ_FILTER = 19; static const DeviceCommandId_t SET_ADC_SWEEP_PERIOD = 20; static const DeviceCommandId_t SET_ADC_ENABLED_CHANNELS = 21; static const DeviceCommandId_t SET_ADC_WINDOW_AND_STRIDE = 22; static const DeviceCommandId_t SET_ADC_THRESHOLD = 23; static const DeviceCommandId_t GET_LATCHUP_STATUS_REPORT = 24; static const DeviceCommandId_t COPY_ADC_DATA_TO_MRAM = 25; static const DeviceCommandId_t ENABLE_NVMS = 26; static const DeviceCommandId_t SELECT_NVM = 27; static const DeviceCommandId_t RUN_AUTO_EM_TESTS = 28; static const DeviceCommandId_t WIPE_MRAM = 29; static const DeviceCommandId_t DUMP_MRAM = 30; static const DeviceCommandId_t SET_DBG_VERBOSITY = 31; static const DeviceCommandId_t CAN_LOOPBACK_TEST = 32; static const DeviceCommandId_t PRINT_CPU_STATS = 33; static const DeviceCommandId_t SET_GPIO = 34; static const DeviceCommandId_t READ_GPIO = 35; static const DeviceCommandId_t RESTART_SUPERVISOR = 36; static const DeviceCommandId_t FACTORY_RESET_CLEAR_ALL = 37; static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40; static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41; static const DeviceCommandId_t UPDATE_VERIFY = 42; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; static const DeviceCommandId_t EXE_REPORT = 51; static const DeviceCommandId_t HK_REPORT = 52; static const DeviceCommandId_t BOOT_STATUS_REPORT = 53; static const DeviceCommandId_t LATCHUP_REPORT = 54; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_HK_REPORT = 48; static const uint16_t SIZE_BOOT_STATUS_REPORT = 22; static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 51; /** * SpacePacket apids of telemetry packets */ static const uint16_t APID_ACK_SUCCESS = 0x200; static const uint16_t APID_ACK_FAILURE = 0x201; static const uint16_t APID_EXE_SUCCESS = 0x202; static const uint16_t APID_EXE_FAILURE = 0x203; static const uint16_t APID_HK_REPORT = 0x204; static const uint16_t APID_BOOT_STATUS_REPORT = 0x205; static const uint16_t APID_UPDATE_STATUS_REPORT = 0x206; static const uint16_t APID_WDG_STATUS_REPORT = 0x207; static const uint16_t APID_LATCHUP_STATUS_REPORT = 0x208; static const uint16_t APID_SOC_SYSMON = 0x209; static const uint16_t APID_MRAM_DUMP_TM = 0x20A; static const uint16_t APID_SRAM = 0x20B; static const uint16_t APID_NOR_DATA = 0x20C; static const uint16_t APID_DATA_LOGGER_DATA = 0x20D; /** * APIDs of telecommand packets */ static const uint16_t APID_RESTART_MPSOC = 0xA0; static const uint16_t APID_START_MPSOC = 0xA1; static const uint16_t APID_SHUTWOWN_MPSOC = 0xA2; static const uint16_t APID_SEL_MPSOC_BOOT_IMAGE = 0xA3; static const uint16_t APID_SET_BOOT_TIMEOUT = 0xA4; static const uint16_t APID_SET_MAX_RESTART_TRIES = 0xA5; static const uint16_t APID_RESET_MPSOC = 0xA6; static const uint16_t APID_GET_BOOT_STATUS_RPT = 0xA8; static const uint16_t APID_UPDATE_AVAILABLE = 0xB0; static const uint16_t APID_UPDATE_IMAGE_DATA = 0xB1; static const uint16_t APID_UPDATE_VERIFY = 0xB2; static const uint16_t APID_WTD_ENABLE = 0xC0; static const uint16_t APID_WTD_CONFIG_TIMEOUT = 0xC1; static const uint16_t APID_SET_TIME_REF = 0xC2; static const uint16_t APID_DISABLE_HK = 0xC3; static const uint16_t APID_ENABLE_LATCHUP_ALERT = 0xD0; static const uint16_t APID_DISABLE_LATCHUP_ALERT = 0xD1; static const uint16_t APID_AUTO_CALIBRATE_ALERT = 0xD2; static const uint16_t APID_SET_ALERT_LIMIT = 0xD3; static const uint16_t APID_SET_ALERT_IRQ_FILTER = 0xD4; static const uint16_t APID_SET_ADC_SWEEP_PERIOD = 0xD5; static const uint16_t APID_SET_ADC_ENABLED_CHANNELS = 0xD6; static const uint16_t APID_SET_ADC_WINDOW_AND_STRIDE = 0xD7; static const uint16_t APID_SET_ADC_THRESHOLD = 0xD8; static const uint16_t APID_GET_LATCHUP_STATUS_REPORT = 0xD9; static const uint16_t APID_COPY_ADC_DATA_TO_MRAM = 0xDA; static const uint16_t APID_ENABLE_NVMS = 0xF0; static const uint16_t APID_SELECT_NVM = 0xF1; static const uint16_t APID_RUN_AUTO_EM_TESTS = 0xF2; static const uint16_t APID_WIPE_MRAM = 0xF3; static const uint16_t APID_DUMP_MRAM = 0xF4; static const uint16_t APID_SET_DBG_VERBOSITY = 0xF5; static const uint16_t APID_CAN_LOOPBACK_TEST = 0xF6; static const uint16_t APID_PRINT_CPU_STATS = 0xF8; static const uint16_t APID_SET_GPIO = 0xF9; static const uint16_t APID_READ_GPIO = 0xFA; static const uint16_t APID_RESTART_SUPERVISOR = 0xFB; static const uint16_t APID_FACTORY_RESET = 0xFC; static const uint16_t APID_REQUEST_LOGGING_DATA = 0xFD; static const uint16_t APID_GET_HK_REPORT = 0xC6; static const uint16_t APID_MASK = 0x3FF; static const uint16_t SEQUENCE_COUNT_MASK = 0xFFF; /** Offset from first byte in Space packet to first byte of data field */ static const uint8_t DATA_FIELD_OFFSET = 6; /** * 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_EMPTY_TC = 2; // Only CRC will be transported with the data field /** This is the maximum length of a space packet as defined by the TAS ICD */ static const size_t MAX_COMMAND_SIZE = 1024; static const size_t MAX_DATA_CAPACITY = 1016; /** This is the maximum size of a space packet for the supervisor */ static const size_t MAX_PACKET_SIZE = 1024; static const uint8_t SPACE_PACKET_HEADER_LENGTH = 6; enum class SequenceFlags: uint8_t { CONTINUED_PKT = 0b00, FIRST_PKT = 0b01, LAST_PKT = 0b10, STANDALONE_PKT = 0b11 }; enum PoolIds : lp_id_t { NUM_TMS, TEMP_PS, TEMP_PL, SOC_STATE, NVM0_1_STATE, NVM3_STATE, MISSION_IO_STATE, FMC_STATE, NUM_TCS, TEMP_SUP, UPTIME, CPULOAD, AVAILABLEHEAP, BOOT_SIGNAL, RESET_COUNTER, BOOT_AFTER_MS, BOOT_TIMEOUT_MS, ACTIVE_NVM, BP0_STATE, BP1_STATE, BP2_STATE, LATCHUP_ID, CNT0, CNT1, CNT2, CNT3, CNT4, CNT5, CNT6, LATCHUP_RPT_TIME_SEC, LATCHUP_RPT_TIME_MIN, LATCHUP_RPT_TIME_HOUR, LATCHUP_RPT_TIME_DAY, LATCHUP_RPT_TIME_MON, LATCHUP_RPT_TIME_YEAR, LATCHUP_RPT_TIME_MSEC, LATCHUP_RPT_TIME_USEC, }; static const uint8_t HK_SET_ENTRIES = 13; static const uint8_t BOOT_REPORT_SET_ENTRIES = 8; static const uint8_t LATCHUP_RPT_SET_ENTRIES = 15; static const uint32_t HK_SET_ID = HK_REPORT; static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT; static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT; /** * @brief With this class a space packet can be created which does not contain any data. */ class EmptyPacket: public SpacePacket { public: /** * @brief Constructor * * @param apid The APID to set in the space packet. * * @note Sequence count of empty packet is always 1. */ EmptyPacket(uint16_t apid) : SpacePacket(LENGTH_EMPTY_TC - 1, true, apid, 1) { calcCrc(); } private: /** * @brief CRC calculation which involves only the header in an empty packet */ void calcCrc() { /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader)); /* Add crc to packet data field of space packet */ size_t serializedSize = 0; uint8_t* crcPos = this->localData.fields.buffer; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class can be used to generate the space packet selecting the boot image of * of the MPSoC. */ class MPSoCBootSelect: public SpacePacket { public: /** * @brief Constructor * * @param mem The memory to boot from: NVM0 (0), NVM1 (1) * @param bp0 Partition pin 0 * @param bp1 Partition pin 1 * @param bp2 Partition pin 2 */ MPSoCBootSelect(uint8_t mem, uint8_t bp0, uint8_t bp1, uint8_t bp2) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE, DEFAULT_SEQUENCE_COUNT), mem(mem), bp0(bp0), bp1(bp1), bp2(bp2) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 6; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint8_t MEM_OFFSET = 0; static const uint8_t BP0_OFFSET = 1; static const uint8_t BP1_OFFSET = 2; static const uint8_t BP2_OFFSET = 3; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t mem = 0; uint8_t bp0 = 0; uint8_t bp1 = 0; uint8_t bp2 = 0; void initPacket() { uint8_t* data_field_start = this->localData.fields.buffer; std::memcpy(data_field_start + MEM_OFFSET, &mem, sizeof(mem)); std::memcpy(data_field_start + BP0_OFFSET, &bp0, sizeof(bp0)); std::memcpy(data_field_start + BP1_OFFSET, &bp1, sizeof(bp1)); std::memcpy(data_field_start + BP2_OFFSET, &bp2, sizeof(bp2)); /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); /* Add crc to packet data field of space packet */ size_t serializedSize = 0; uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class generates the space packet to update the time of the PLOC supervisor. */ class SetTimeRef: public SpacePacket { public: SetTimeRef(Clock::TimeOfDay_t* time) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_TIME_REF, DEFAULT_SEQUENCE_COUNT) { initPacket(time); } private: static const uint16_t DATA_FIELD_LENGTH = 34; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; void initPacket(Clock::TimeOfDay_t* time) { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&time->second, &data_field_ptr, &serializedSize, sizeof(time->second), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&time->minute, &data_field_ptr, &serializedSize, sizeof(time->minute), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&time->hour, &data_field_ptr, &serializedSize, sizeof(time->hour), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&time->day, &data_field_ptr, &serializedSize, sizeof(time->day), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&time->month, &data_field_ptr, &serializedSize, sizeof(time->month), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&time->year, &data_field_ptr, &serializedSize, sizeof(time->year), SerializeIF::Endianness::BIG); serializedSize = 0; uint32_t milliseconds = time->usecond / 1000; SerializeAdapter::serialize(&milliseconds, &data_field_ptr, &serializedSize, sizeof(milliseconds), SerializeIF::Endianness::BIG); serializedSize = 0; uint32_t isSet = 0xFFFFFFFF; SerializeAdapter::serialize(&isSet, &data_field_ptr, &serializedSize, sizeof(isSet), SerializeIF::Endianness::BIG); serializedSize = 0; /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); SerializeAdapter::serialize(&crc, &data_field_ptr, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class can be used to generate the set boot timout command. */ class SetBootTimeout: public SpacePacket { public: /** * @brief Constructor * * @param timeout The boot timeout in milliseconds. */ SetBootTimeout(uint32_t timeout) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_BOOT_TIMEOUT, 1), timeout(timeout) { initPacket(); } private: uint32_t timeout = 0; /** boot timeout value (uint32_t) and crc (uint16_t) */ static const uint16_t DATA_FIELD_LENGTH = 6; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&timeout, &data_field_ptr, &serializedSize, sizeof(timeout), SerializeIF::Endianness::BIG); /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); /* Add crc to packet data field of space packet */ serializedSize = 0; SerializeAdapter::serialize(&crc, &data_field_ptr, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class can be used to generate the space packet to set the maximum boot tries. */ class SetRestartTries: public SpacePacket { public: /** * @brief Constructor * * @param restartTries Maximum restart tries to set. */ SetRestartTries(uint8_t restartTries) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_MAX_RESTART_TRIES, 1), restartTries( restartTries) { initPacket(); } private: uint8_t restartTries = 0; /** Restart tries value (uint8_t) and crc (uint16_t) */ static const uint16_t DATA_FIELD_LENGTH = 3; void initPacket() { uint8_t* data_field_ptr = this->localData.fields.buffer; *data_field_ptr = restartTries; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); size_t serializedSize = 0; uint8_t* crcPtr = data_field_ptr + 1; SerializeAdapter::serialize(&crc, &crcPtr, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the command to notify the supervisor that a new update for the * MPSoC is available. */ class UpdateAvailable: public SpacePacket { public: /** * @brief Constructor * * @param imageSelect * @param imagePartition * @param imageSize * @param imageCrc * @param numberOfPackets */ UpdateAvailable(uint8_t imageSelect, uint8_t imagePartition, uint32_t imageSize, uint32_t imageCrc, uint32_t numberOfPackets) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_UPDATE_AVAILABLE, DEFAULT_SEQUENCE_COUNT), imageSelect(imageSelect), imagePartition( imagePartition), imageSize(imageSize), imageCrc(imageCrc), numberOfPackets( numberOfPackets) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 16; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t imageSelect = 0; uint8_t imagePartition = 0; uint32_t imageSize = 0; uint32_t imageCrc = 0; uint32_t numberOfPackets = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&imageSelect, &data_field_ptr, &serializedSize, sizeof(imageSelect), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&imagePartition, &data_field_ptr, &serializedSize, sizeof(imagePartition), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, sizeof(imageSize), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, sizeof(imageCrc), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&numberOfPackets, &data_field_ptr, &serializedSize, sizeof(numberOfPackets), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief With this class the space packet can be generated to disable to periodic transmission * of housekeeping data. Normally, this will be disabled by default. However, adding this * command can be useful for debugging. */ class DisablePeriodicHkTransmission: public SpacePacket { public: /** * @brief Constructor */ DisablePeriodicHkTransmission() : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_DISABLE_HK, 1) { initPacket(); } private: uint8_t disableHk = 0; /** Restart tries value (uint8_t) and crc (uint16_t) */ static const uint16_t DATA_FIELD_LENGTH = 3; void initPacket() { uint8_t* data_field_ptr = this->localData.fields.buffer; *data_field_ptr = disableHk; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); size_t serializedSize = 0; uint8_t* crcPtr = data_field_ptr + 1; SerializeAdapter::serialize(&crc, &crcPtr, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the command to enable the watchdogs of the PLOC. */ class WatchdogsEnable: public SpacePacket { public: /** * @brief Constructor * * @param watchdogPs Enables processing system watchdog * @param watchdogPl Enables programmable logic wathdog * @param watchdogInt */ WatchdogsEnable(uint8_t watchdogPs, uint8_t watchdogPl, uint8_t watchdogInt) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_WTD_ENABLE, DEFAULT_SEQUENCE_COUNT), watchdogPs(watchdogPs), watchdogPl(watchdogPl), watchdogInt(watchdogInt) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 5; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t watchdogPs = 0; uint8_t watchdogPl = 0; uint8_t watchdogInt = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&watchdogPs, &data_field_ptr, &serializedSize, sizeof(watchdogPs), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&watchdogPl, &data_field_ptr, &serializedSize, sizeof(watchdogPl), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&watchdogInt, &data_field_ptr, &serializedSize, sizeof(watchdogInt), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the command to set the timeout of one of the three watchdogs (PS, * PL, INT) */ class WatchdogsConfigTimeout: public SpacePacket { public: /** * @brief Constructor * * @param watchdogPs Selects the watchdog to configure (0 - PS, 1 - PL, 2 - INT) * @param timeout The timeout to set */ WatchdogsConfigTimeout(uint8_t watchdog, uint32_t timeout) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_WTD_CONFIG_TIMEOUT, DEFAULT_SEQUENCE_COUNT), watchdog(watchdog), timeout(timeout) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 7; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t watchdog = 0; uint32_t timeout = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&watchdog, &data_field_ptr, &serializedSize, sizeof(watchdog), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&timeout, &data_field_ptr, &serializedSize, sizeof(timeout), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the command to enable of disable the latchup alert. * * @details There are 7 different latchup alerts. */ class LatchupAlert: public SpacePacket { public: /** * @brief Constructor * * @param state true - enable, false - disable * @param latchupId Identifies the latchup to enable/disable (0 - 0.85V, 1 - 1.8V, 2 - MISC, * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) */ LatchupAlert(bool state, uint8_t latchupId) : SpacePacket(DATA_FIELD_LENGTH - 1, true), latchupId(latchupId) { if (state) { this->setAPID(APID_ENABLE_LATCHUP_ALERT); } else { this->setAPID(APID_DISABLE_LATCHUP_ALERT); } this->setPacketSequenceCount(DEFAULT_SEQUENCE_COUNT); initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 3; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t latchupId = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, sizeof(latchupId), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the command to calibrate a certain latchup alert. */ class AutoCalibrateAlert: public SpacePacket { public: /** * @brief Constructor * * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) * @param mg */ AutoCalibrateAlert(uint8_t latchupId, uint32_t mg) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_AUTO_CALIBRATE_ALERT, DEFAULT_SEQUENCE_COUNT), latchupId(latchupId), mg(mg) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 7; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t latchupId = 0; uint32_t mg = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, sizeof(latchupId), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&mg, &data_field_ptr, &serializedSize, sizeof(mg), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; class SetAlertlimit: public SpacePacket { public: /** * @brief Constructor * * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) * @param dutycycle */ SetAlertlimit(uint8_t latchupId, uint32_t dutycycle) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ALERT_LIMIT, DEFAULT_SEQUENCE_COUNT), latchupId(latchupId), dutycycle(dutycycle) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 7; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t latchupId = 0; uint32_t dutycycle = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, sizeof(latchupId), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&dutycycle, &data_field_ptr, &serializedSize, sizeof(dutycycle), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; class SetAlertIrqFilter: public SpacePacket { public: /** * @brief Constructor * * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) * @param tp * @param div */ SetAlertIrqFilter(uint8_t latchupId, uint8_t tp, uint8_t div) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ALERT_IRQ_FILTER, DEFAULT_SEQUENCE_COUNT), tp(tp), div(div) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 5; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t latchupId = 0; uint8_t tp = 0; uint8_t div = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, sizeof(latchupId), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&tp, &data_field_ptr, &serializedSize, sizeof(tp), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&div, &data_field_ptr, &serializedSize, sizeof(div), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to set the sweep period of the ADC. */ class SetAdcSweepPeriod: public SpacePacket { public: /** * @brief Constructor * * @param sweepPeriod Sweep period in us. minimum is 21 us */ SetAdcSweepPeriod(uint32_t sweepPeriod) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_SWEEP_PERIOD, DEFAULT_SEQUENCE_COUNT), sweepPeriod(sweepPeriod) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 6; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint32_t sweepPeriod = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&sweepPeriod, &data_field_ptr, &serializedSize, sizeof(sweepPeriod), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to enable or disable ADC channels. */ class SetAdcEnabledChannels: public SpacePacket { public: /** * @brief Constructor * * @param ch Defines channels to be enabled or disabled. */ SetAdcEnabledChannels(uint16_t ch) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_ENABLED_CHANNELS, DEFAULT_SEQUENCE_COUNT), ch(ch) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 4; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint16_t ch = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&ch, &data_field_ptr, &serializedSize, sizeof(ch), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to configures the window size and striding step of * the moving average filter applied to the ADC readings. */ class SetAdcWindowAndStride: public SpacePacket { public: /** * @brief Constructor * * @param windowSize * @param stridingStepSize */ SetAdcWindowAndStride(uint16_t windowSize, uint16_t stridingStepSize) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_WINDOW_AND_STRIDE, DEFAULT_SEQUENCE_COUNT), windowSize(windowSize), stridingStepSize( stridingStepSize) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 6; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint16_t windowSize = 0; uint16_t stridingStepSize = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&windowSize, &data_field_ptr, &serializedSize, sizeof(windowSize), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&stridingStepSize, &data_field_ptr, &serializedSize, sizeof(stridingStepSize), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to set the ADC trigger threshold. */ class SetAdcThreshold: public SpacePacket { public: /** * @brief Constructor * * @param threshold */ SetAdcThreshold(uint32_t threshold) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_THRESHOLD, DEFAULT_SEQUENCE_COUNT), threshold(threshold) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 6; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint32_t threshold = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&threshold, &data_field_ptr, &serializedSize, sizeof(threshold), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to select between NVM 0 and NVM 1. */ class SelectNvm: public SpacePacket { public: /** * @brief Constructor * * @param mem 0 - select NVM0, 1 - select NVM1. */ SelectNvm(uint8_t mem) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SELECT_NVM, DEFAULT_SEQUENCE_COUNT), mem(mem) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 3; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t mem = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&mem, &data_field_ptr, &serializedSize, sizeof(mem), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to power the NVMs on or off. */ class EnableNvms: public SpacePacket { public: /** * @brief Constructor * * @param n01 Set to one to power NVM0 and NVM1 on. 0 powers off memory. * @param n3 Set to one to power NVM3 on. 0 powers off the memory. */ EnableNvms(uint8_t n01, uint8_t n3) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_ENABLE_NVMS, DEFAULT_SEQUENCE_COUNT), n01(n01), n3(n3) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 4; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t n01 = 0; uint8_t n3 = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&n01, &data_field_ptr, &serializedSize, sizeof(n01), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&n3, &data_field_ptr, &serializedSize, sizeof(n3), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to run auto EM tests. */ class RunAutoEmTests: public SpacePacket { public: /** * @brief Constructor * * @param test 1 - complete EM test, 2 - Short test (only memory readback NVM0,1,3) */ RunAutoEmTests(uint8_t test) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_RUN_AUTO_EM_TESTS, DEFAULT_SEQUENCE_COUNT), test(test) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 3; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t test = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&test, &data_field_ptr, &serializedSize, sizeof(test), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet causing the supervisor to print the CPU load to * the debug output. */ class PrintCpuStats: public SpacePacket { public: /** * @brief Constructor * * @param en Print is enabled if en != 0 */ PrintCpuStats(uint8_t en) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_PRINT_CPU_STATS, DEFAULT_SEQUENCE_COUNT), en(en) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 3; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t en = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&en, &data_field_ptr, &serializedSize, sizeof(en), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to set the print verbosity in the supervisor * software. */ class SetDbgVerbosity: public SpacePacket { public: /** * @brief Constructor * * @param vb 0: None, 1: Error, 2: Warn, 3: Info */ SetDbgVerbosity(uint8_t vb) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_DBG_VERBOSITY, DEFAULT_SEQUENCE_COUNT), vb(vb) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 3; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t vb = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&vb, &data_field_ptr, &serializedSize, sizeof(vb), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to wipe or dump parts of the MRAM. */ class MramCmd: public SpacePacket { public: enum class MramAction { WIPE, DUMP }; /** * @brief Constructor * * @param start Start address of the MRAM section to wipe or dump * @param stop End address of the MRAM section to wipe or dump * @param action Dump or wipe MRAM * * @note The content at the stop address is excluded from the dump or wipe operation. */ MramCmd(uint32_t start, uint32_t stop, MramAction action) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_IDLE_PACKET, DEFAULT_SEQUENCE_COUNT), start(start), stop(stop) { if(action == MramAction::WIPE) { this->setAPID(APID_WIPE_MRAM); } else if (action == MramAction::DUMP) { this->setAPID(APID_DUMP_MRAM); } else { sif::debug << "WipeMram: Invalid action specified"; } initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 8; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint32_t start = 0; uint32_t stop = 0; void initPacket() { uint8_t concatBuffer[6]; concatBuffer[0] = static_cast(start >> 16); concatBuffer[1] = static_cast(start >> 8); concatBuffer[2] = static_cast(start); concatBuffer[3] = static_cast(stop >> 16); concatBuffer[4] = static_cast(stop >> 8); concatBuffer[5] = static_cast(stop); uint8_t* data_field_ptr = this->localData.fields.buffer; std::memcpy(data_field_ptr, concatBuffer, sizeof(concatBuffer)); size_t serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet change the state of a GPIO. This command is only * required for ground testing. */ class SetGpio: public SpacePacket { public: /** * @brief Constructor * * @param port * @param pin * @param val */ SetGpio(uint8_t port, uint8_t pin, uint8_t val) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_GPIO, DEFAULT_SEQUENCE_COUNT), port(port), pin(pin), val(val) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 5; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t port = 0; uint8_t pin = 0; uint8_t val = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, sizeof(port), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, sizeof(pin), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&val, &data_field_ptr, &serializedSize, sizeof(val), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet causing the supervisor print the state of a GPIO * to the debug output. */ class ReadGpio: public SpacePacket { public: /** * @brief Constructor * * @param port * @param pin */ ReadGpio(uint8_t port, uint8_t pin) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_READ_GPIO, DEFAULT_SEQUENCE_COUNT), port(port), pin(pin) { initPacket(); } private: static const uint16_t DATA_FIELD_LENGTH = 4; static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; uint8_t port = 0; uint8_t pin = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, sizeof(port), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, sizeof(pin), SerializeIF::Endianness::BIG); serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet to perform the factory reset. The op parameter is * optional. * * @details: Without OP: All MRAM entries will be cleared. * OP = 0x01: Only the mirror entries will be wiped. * OP = 0x02: Only the circular entries will be wiped. */ class FactoryReset: public SpacePacket { public: enum class Op { CLEAR_ALL, MIRROR_ENTRIES, CIRCULAR_ENTRIES }; /** * @brief Constructor * * @param op */ FactoryReset(Op op) : SpacePacket(0, true, APID_FACTORY_RESET, DEFAULT_SEQUENCE_COUNT), op(op) { initPacket(); } private: uint16_t packetLen = 1; // only CRC in data field static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; uint8_t crcOffset = 0; Op op = Op::CLEAR_ALL; void initPacket() { uint8_t* data_field_ptr = this->localData.fields.buffer; switch(op) { case Op::MIRROR_ENTRIES: *data_field_ptr = 1; packetLen = 2; crcOffset = 1; break; case Op::CIRCULAR_ENTRIES: *data_field_ptr = 2; packetLen = 2; crcOffset = 1; break; default: break; } this->setPacketDataLength(packetLen); size_t serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + packetLen - 1); uint8_t* crcPos = this->localData.fields.buffer + crcOffset; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; class SupvTcSpacePacket : public SpacePacket { public: SupvTcSpacePacket(size_t payloadDataLen, uint16_t apid) : SpacePacket(payloadDataLen + 1, true, apid, DEFAULT_SEQUENCE_COUNT), payloadDataLen(payloadDataLen) { } void makeCrc() { size_t serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + payloadDataLen); uint8_t* crcPos = this->localData.fields.buffer + payloadDataLen; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } private: // The sequence count of most of the TC packets for the supervisor is 1. static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; // The size of the payload data (data field without crc size) size_t payloadDataLen = 0; }; /** * @brief This class can be used to package the update available or update verify command. */ class UpdateInfo: public SupvTcSpacePacket { public: /** * @brief Constructor * * @param apid Packet can be used to generate the update available and the update verify * packet. Thus the APID must be specified here. * @param memory The memory to apply the update (NVM0 - 0, NVM1 - 1) * @param partition The partition to update (A - 0, B - 1) * @param imageSize The size of the update image * param numPackets The number of space packets required to transfer all data. */ UpdateInfo(uint16_t apid, uint8_t memory, uint8_t partition, uint32_t imageSize, uint32_t imageCrc, uint32_t numPackets) : SupvTcSpacePacket(PAYLOAD_LENGTH, apid), memory(memory), partition(partition), imageSize( imageSize), numPackets(numPackets) { initPacket(); makeCrc(); } private: static const uint16_t PAYLOAD_LENGTH = 14; // length without CRC field uint8_t memory = 0; uint8_t partition = 0; uint32_t imageSize = 0; uint32_t imageCrc = 0; uint32_t numPackets = 0; void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; SerializeAdapter::serialize(&memory, &data_field_ptr, &serializedSize, sizeof(memory), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&partition, &data_field_ptr, &serializedSize, sizeof(partition), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, sizeof(imageSize), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, sizeof(imageCrc), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&numPackets, &data_field_ptr, &serializedSize, sizeof(numPackets), SerializeIF::Endianness::BIG); } }; /** * @brief This class packages the space packet transporting a part of an MPSoC update. */ class UpdatePacket: public SupvTcSpacePacket { public: /** * @brief Constructor * * @param payloadLength Update data length (data field length without CRC) */ UpdatePacket(uint16_t payloadLength) : SupvTcSpacePacket(payloadLength, APID_UPDATE_IMAGE_DATA) { } /** * @brief Returns the pointer to the beginning of the data field. */ uint8_t* getDataFieldPointer() { return this->localData.fields.buffer; } }; /** * @brief This dataset stores the boot status report of the supervisor. */ class BootStatusReport: public StaticLocalDataSet { public: BootStatusReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { } BootStatusReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { } /** Information about boot status of MPSoC */ lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); /** Time the MPSoC needs for last boot */ lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); /** The currently set boot timeout */ lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); /** States of the boot partition pins */ lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); }; /** * @brief This dataset stores the housekeeping data of the supervisor. */ class HkSet: public StaticLocalDataSet { public: HkSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, HK_SET_ID) { } HkSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, HK_SET_ID)) { } lp_var_t tempPs = lp_var_t(sid.objectId, PoolIds::TEMP_PS, this); lp_var_t tempPl = lp_var_t(sid.objectId, PoolIds::TEMP_PS, this); lp_var_t tempSup = lp_var_t(sid.objectId, PoolIds::TEMP_SUP, this); lp_var_t uptime = lp_var_t(sid.objectId, PoolIds::UPTIME, this); lp_var_t cpuLoad = lp_var_t(sid.objectId, PoolIds::CPULOAD, this); lp_var_t availableHeap = lp_var_t(sid.objectId, PoolIds::AVAILABLEHEAP, this); lp_var_t numTcs = lp_var_t(sid.objectId, PoolIds::NUM_TCS, this); lp_var_t numTms = lp_var_t(sid.objectId, PoolIds::NUM_TMS, this); lp_var_t socState = lp_var_t(sid.objectId, PoolIds::SOC_STATE, this); lp_var_t nvm0_1_state = lp_var_t(sid.objectId, PoolIds::NVM0_1_STATE, this); lp_var_t nvm3_state = lp_var_t(sid.objectId, PoolIds::NVM3_STATE, this); lp_var_t missionIoState = lp_var_t(sid.objectId, PoolIds::MISSION_IO_STATE, this); lp_var_t fmcState = lp_var_t(sid.objectId, PoolIds::FMC_STATE, this); }; /** * @brief This dataset stores the last requested latchup status report. */ class LatchupStatusReport: public StaticLocalDataSet { public: LatchupStatusReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, LATCHUP_RPT_ID) { } LatchupStatusReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, LATCHUP_RPT_ID)) { } lp_var_t id = lp_var_t(sid.objectId, PoolIds::LATCHUP_ID, this); lp_var_t cnt0 = lp_var_t(sid.objectId, PoolIds::CNT0, this); lp_var_t cnt1 = lp_var_t(sid.objectId, PoolIds::CNT1, this); lp_var_t cnt2 = lp_var_t(sid.objectId, PoolIds::CNT2, this); lp_var_t cnt3 = lp_var_t(sid.objectId, PoolIds::CNT3, this); lp_var_t cnt4 = lp_var_t(sid.objectId, PoolIds::CNT4, this); lp_var_t cnt5 = lp_var_t(sid.objectId, PoolIds::CNT5, this); lp_var_t cnt6 = lp_var_t(sid.objectId, PoolIds::CNT6, this); lp_var_t timeSec = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_SEC, this); lp_var_t timeMin = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MIN, this); lp_var_t timeHour = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_HOUR, this); lp_var_t timeDay = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_DAY, this); lp_var_t timeMon = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MON, this); lp_var_t timeYear = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_YEAR, this); lp_var_t timeMsec = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MSEC, this); }; } #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ */