diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 909e4891..4dcb2a16 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -124,6 +124,18 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( case(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT): { result = prepareWatchdogsConfigTimeoutCmd(commandData); break; + } + case(PLOC_SPV::ENABLE_LATCHUP_ALERT): { + result = prepareLatchupConfigCmd(commandData, deviceCommand); + break; + } + case(PLOC_SPV::DISABLE_LATCHUP_ALERT): { + result = prepareLatchupConfigCmd(commandData, deviceCommand); + break; + } + case(PLOC_SPV::AUTO_CALIBRATE_ALERT): { + result = prepareAutoCalibrateAlertCmd(commandData); + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -157,6 +169,9 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::UPDATE_AVAILABLE); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_ENABLE); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT); + this->insertInCommandMap(PLOC_SPV::ENABLE_LATCHUP_ALERT); + this->insertInCommandMap(PLOC_SPV::DISABLE_LATCHUP_ALERT); + this->insertInCommandMap(PLOC_SPV::APID_AUTO_CALIBRATE_ALERT); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -545,6 +560,9 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::UPDATE_AVAILABLE: case PLOC_SPV::WATCHDOGS_ENABLE: case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: + case PLOC_SPV::ENABLE_LATCHUP_ALERT: + case PLOC_SPV::DISABLE_LATCHUP_ALERT: + case PLOC_SPV::AUTO_CALIBRATE_ALERT: enabledReplies = 2; break; default: @@ -639,19 +657,13 @@ void PlocSupervisorHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, void PlocSupervisorHandler::prepareEmptyCmd(uint16_t apid) { PLOC_SPV::EmptyPacket packet(apid); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareSelBootImageCmd(const uint8_t * commandData) { PLOC_SPV::MPSoCBootSelect packet(*commandData, *(commandData + 1), *(commandData + 2), *(commandData + 3)); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() { @@ -663,38 +675,26 @@ ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() { return GET_TIME_FAILURE; } PLOC_SPV::SetTimeRef packet(&time); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); return RETURN_OK; } void PlocSupervisorHandler::prepareDisableHk() { PLOC_SPV::DisablePeriodicHkTransmission packet; - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareSetBootTimeoutCmd(const uint8_t * commandData) { uint32_t timeout = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 | *(commandData + 3); PLOC_SPV::SetBootTimeout packet(timeout); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t * commandData) { uint8_t restartTries = *(commandData); PLOC_SPV::SetRestartTries packet(restartTries); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandData) { @@ -714,10 +714,7 @@ void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandDat PLOC_SPV::UpdateAvailable packet(imageSelect, imagePartition, imageSize, imageCrc, numberOfPackets); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandData) { @@ -728,10 +725,7 @@ void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandDat offset += 1; uint8_t watchdogInt = *(commandData + offset); PLOC_SPV::WatchdogsEnable packet(watchdogPs, watchdogPl, watchdogInt); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } ReturnValue_t PlocSupervisorHandler::prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData) { @@ -747,13 +741,59 @@ ReturnValue_t PlocSupervisorHandler::prepareWatchdogsConfigTimeoutCmd(const uint return INVALID_WATCHDOG_TIMEOUT; } PLOC_SPV::WatchdogsConfigTimeout packet(watchdog, timeout); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); return RETURN_OK; } +ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* commandData, + DeviceCommandId_t deviceCommand) { + ReturnValue_t result = RETURN_OK; + uint8_t latchupId = *commandData; + if (latchupId > 6) { + return INVALID_LATCHUP_ID; + } + switch (deviceCommand) { + case (PLOC_SPV::ENABLE_LATCHUP_ALERT): { + PLOC_SPV::LatchupAlert packet(true, latchupId); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + break; + } + case (PLOC_SPV::DISABLE_LATCHUP_ALERT): { + PLOC_SPV::LatchupAlert packet(false, latchupId); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + break; + } + default: { + sif::debug << "PlocSupervisorHandler::prepareLatchupConfigCmd: Invalid command id" + << std::endl; + result = RETURN_FAILED; + break; + } + } + return result; +} + +ReturnValue_t PlocSupervisorHandler::prepareAutoCalibrateAlertCmd(const uint8_t* commandData) { + uint8_t offset = 0; + uint8_t latchupId = *commandData; + offset += 1; + uint32_t mg = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + if (latchupId > 6) { + return INVALID_LATCHUP_ID; + } + PLOC_SPV::AutoCalibrateAlert packet(latchupId, mg); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; +} + +void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { + memcpy(commandBuffer, packetData, fullSize); + rawPacket = commandBuffer; + rawPacketLen = fullSize; + nextReplyId = PLOC_SPV::ACK_REPORT; +} + void PlocSupervisorHandler::disableAllReplies() { DeviceReplyMap::iterator iter; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 3136a5df..bbbbf25e 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -67,6 +67,8 @@ private: static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6); //! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms. static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA6); + //! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID + static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA7); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -215,6 +217,16 @@ private: */ ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData); + ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData, + DeviceCommandId_t deviceCommand); + ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData); + + + /** + * @brief Copies the content of a space packet to the command buffer. + */ + void packetToOutBuffer(uint8_t* packetData, size_t fullSize); + /** * @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 diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 5cfd026e..28349dab 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -25,6 +25,9 @@ static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; 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; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -73,6 +76,30 @@ 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; @@ -539,6 +566,101 @@ private: } }; +/** + * @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); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */