From 699b4a0eb96db746871a5d161c418d7682ece64a Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 29 Mar 2021 14:37:52 +0200 Subject: [PATCH 01/16] ploc handler wip --- mission/devices/PlocHandler.cpp | 213 ++++++++++++++++++++++++++++++++ mission/devices/PlocHandler.h | 77 ++++++++++++ tmtc | 2 +- 3 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 mission/devices/PlocHandler.cpp create mode 100644 mission/devices/PlocHandler.h diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp new file mode 100644 index 00000000..7070b51e --- /dev/null +++ b/mission/devices/PlocHandler.cpp @@ -0,0 +1,213 @@ +#include "PlocHandler.h" + +#include +#include +#include +#include + +PlocHandler::PlocHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : + DeviceHandlerBase(objectId, comIF, comCookie), engHkDataset(this) { + if (comCookie == NULL) { + sif::error << "PlocHandler: Invalid com cookie" << std::endl; + } +} + +PlocHandler::~PlocHandler() { +} + + +void PlocHandler::doStartUp(){ + if(mode == _MODE_START_UP){ + setMode(MODE_ON); + } +} + +void PlocHandler::doShutDown(){ + +} + +ReturnValue_t PlocHandler::buildNormalDeviceCommand( + DeviceCommandId_t * id) { + *id = IMTQ::GET_ENG_HK_DATA; + return buildCommandFromCommand(*id, NULL, 0); +} + +ReturnValue_t PlocHandler::buildTransitionDeviceCommand( + DeviceCommandId_t * id){ + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PlocHandler::buildCommandFromCommand( + DeviceCommandId_t deviceCommand, const uint8_t * commandData, + size_t commandDataLen) { + switch(deviceCommand) { + case(IMTQ::GET_ENG_HK_DATA): { + commandBuffer[0] = IMTQ::CC::GET_ENG_HK_DATA; + rawPacket = commandBuffer; + return RETURN_OK; + } + case(IMTQ::START_ACTUATION_DIPOLE): { + /* IMTQ expects low byte first */ + commandBuffer[0] = IMTQ::CC::START_ACTUATION_DIPOLE; + commandBuffer[1] = *(commandData + 1); + commandBuffer[2] = *(commandData); + commandBuffer[3] = *(commandData + 3); + commandBuffer[4] = *(commandData + 2); + commandBuffer[5] = *(commandData + 5); + commandBuffer[6] = *(commandData + 4); + commandBuffer[7] = *(commandData + 7); + commandBuffer[8] = *(commandData + 6); + rawPacket = commandBuffer; + return RETURN_OK; + } + default: + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + return HasReturnvaluesIF::RETURN_FAILED; +} + +void PlocHandler::fillCommandAndReplyMap() { + this->insertInCommandAndReplyMap(IMTQ::GET_ENG_HK_DATA, 1, &engHkDataset, + IMTQ::SIZE_ENG_HK_DATA_REPLY, false, true, IMTQ::SIZE_ENG_HK_DATA_REPLY); +} + +ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, + size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { + + ReturnValue_t result = RETURN_OK; + + switch(*start) { + case(IMTQ::CC::GET_ENG_HK_DATA): + *foundLen = IMTQ::SIZE_ENG_HK_DATA_REPLY; + *foundId = IMTQ::GET_ENG_HK_DATA; + break; + default: + sif::debug << "PlocHandler::scanForReply: Reply contains invalid command code" << std::endl; + result = IGNORE_REPLY_DATA; + break; + } + + return result; +} + +ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) { + + ReturnValue_t result = RETURN_OK; + + result = parseStatusByte(packet); + + if (result != RETURN_OK) { + return result; + } + + switch (id) { + case (IMTQ::GET_ENG_HK_DATA): + fillEngHkDataset(packet); + break; + default: { + sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + } + + return RETURN_OK; +} + +ReturnValue_t PlocHandler::parseStatusByte(const uint8_t* packet) { + uint8_t cmdErrorField = *(packet + 1) & 0xF; + switch (cmdErrorField) { + case 0: + return RETURN_OK; + case 1: + return REJECTED_WITHOUT_REASON; + case 2: + return INVALID_COMMAND_CODE; + case 3: + return PARAMETER_MISSING; + case 4: + return PARAMETER_INVALID; + case 5: + return CC_UNAVAILABLE; + case 7: + return INTERNAL_PROCESSING_ERROR; + default: + sif::error << "PlocHandler::parseStatusByte: CMD Error field contains unknown error code " + << cmdErrorField << std::endl; + return CMD_ERR_UNKNOWN; + } +} + +void PlocHandler::fillEngHkDataset(const uint8_t* packet) { + uint8_t offset = 2; + engHkDataset.digitalVoltageMv = *(packet + offset + 1) | *(packet + offset); + offset += 2; + engHkDataset.analogVoltageMv = *(packet + offset + 1) | *(packet + offset); + offset += 2; + engHkDataset.digitalCurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + offset += 2; + engHkDataset.analogCurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + offset += 2; + engHkDataset.coilXcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + offset += 2; + engHkDataset.coilYcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + offset += 2; + engHkDataset.coilZcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + offset += 2; + engHkDataset.coilXTemperature = (*(packet + offset + 1) | *(packet + offset)); + offset += 2; + engHkDataset.coilYTemperature = (*(packet + offset + 1) | *(packet + offset)); + offset += 2; + engHkDataset.coilZTemperature = (*(packet + offset + 1) | *(packet + offset)); + offset += 2; + engHkDataset.mcuTemperature = (*(packet + offset + 1) | *(packet + offset)); + +#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1 + sif::info << "IMTQ digital voltage: " << engHkDataset.digitalVoltageMv << " mV" << std::endl; + sif::info << "IMTQ analog voltage: " << engHkDataset.analogVoltageMv << " mV" << std::endl; + sif::info << "IMTQ digital current: " << engHkDataset.digitalCurrentA << " A" << std::endl; + sif::info << "IMTQ analog current: " << engHkDataset.analogCurrentA << " A" << std::endl; + sif::info << "IMTQ coil X current: " << engHkDataset.coilXcurrentA << " A" << std::endl; + sif::info << "IMTQ coil Y current: " << engHkDataset.coilYcurrentA << " A" << std::endl; + sif::info << "IMTQ coil Z current: " << engHkDataset.coilZcurrentA << " A" << std::endl; + sif::info << "IMTQ coil X temperature: " << engHkDataset.coilXTemperature << " °C" + << std::endl; + sif::info << "IMTQ coil Y temperature: " << engHkDataset.coilYTemperature << " °C" + << std::endl; + sif::info << "IMTQ coil Z temperature: " << engHkDataset.coilZTemperature << " °C" + << std::endl; + sif::info << "IMTQ coil MCU temperature: " << engHkDataset.mcuTemperature << " °C" + << std::endl; +#endif +} + +void PlocHandler::setNormalDatapoolEntriesInvalid(){ + +} + +uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ + return 500; +} + +ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + + localDataPoolMap.emplace(IMTQ::DIGITAL_VOLTAGE_MV, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ANALOG_VOLTAGE_MV, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::DIGITAL_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ANALOG_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_X_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Y_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Z_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_X_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Y_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Z_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::MCU_TEMPERATURE, new PoolEntry( { 0 })); + + return HasReturnvaluesIF::RETURN_OK; +} + +void PlocHandler::setModeNormal() { + mode = MODE_NORMAL; +} + diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h new file mode 100644 index 00000000..2505f224 --- /dev/null +++ b/mission/devices/PlocHandler.h @@ -0,0 +1,77 @@ +#ifndef MISSION_DEVICES_PLOCHANDLER_H_ +#define MISSION_DEVICES_PLOCHANDLER_H_ + +#include +#include +#include + +/** + * @brief This is the device handler for the ISIS Magnetorquer iMTQ. + * + * @author J. Meier + */ +class PlocHandler: public DeviceHandlerBase { +public: + + PlocHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie); + virtual ~PlocHandler(); + + /** + * @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; + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::IMTQ_HANDLER; + + static const ReturnValue_t INVALID_COMMAND_CODE = MAKE_RETURN_CODE(0xA0); + static const ReturnValue_t PARAMETER_MISSING = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t PARAMETER_INVALID = MAKE_RETURN_CODE(0xA2); + static const ReturnValue_t CC_UNAVAILABLE = MAKE_RETURN_CODE(0xA3); + static const ReturnValue_t INTERNAL_PROCESSING_ERROR = MAKE_RETURN_CODE(0xA4); + static const ReturnValue_t REJECTED_WITHOUT_REASON = MAKE_RETURN_CODE(0xA5); + static const ReturnValue_t CMD_ERR_UNKNOWN = MAKE_RETURN_CODE(0xA6); + + + IMTQ::EngHkDataset engHkDataset; + + uint8_t commandBuffer[IMTQ::MAX_COMMAND_SIZE]; + + /** + * @brief Each reply contains a status byte giving information about a request. This function + * parses this byte and returns the associated failure message. + * + * @param packet Pointer to the received message containing the status byte. + * + * @return The return code derived from the received status byte. + */ + ReturnValue_t parseStatusByte(const uint8_t* packet); + + /** + * @brief This function fills the engineering housekeeping dataset with the received data. + + * @param packet Pointer to the received data. + * + */ + void fillEngHkDataset(const uint8_t* packet); +}; + +#endif /* MISSION_DEVICES_PLOCHANDLER_H_ */ diff --git a/tmtc b/tmtc index 80ee4208..f40b70f6 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 80ee42089e5baadd60479178417299a8c660c80a +Subproject commit f40b70f66eba176d3c36533a779e4e0ed13ae701 From 400f60c7be3987a2369a79d412a2038e6691168f Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sun, 11 Apr 2021 12:04:13 +0200 Subject: [PATCH 02/16] plocHandler wip --- README.md | 2 +- bsp_q7s/ObjectFactory.cpp | 16 ++ fsfwconfig/OBSWConfig.h | 2 +- fsfwconfig/objects/systemObjectList.h | 1 + .../pollingSequenceFactory.cpp | 5 + fsfwconfig/returnvalues/classIds.h | 1 + mission/devices/CMakeLists.txt | 1 + mission/devices/PlocHandler.cpp | 262 +++++++++++------- mission/devices/PlocHandler.h | 71 +++-- .../devicedefinitions/PlocDefinitions.h | 131 +++++++++ tmtc | 2 +- 11 files changed, 365 insertions(+), 129 deletions(-) create mode 100644 mission/devices/devicedefinitions/PlocDefinitions.h diff --git a/README.md b/README.md index f0c749be..dafbfbba 100644 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ Copying a file from Q7S to flatsat PC scp -P 22 root@192.168.133.10:/tmp/kernel-config /tmp ```` -From a windows machine files can be copied with putty tools +From a windows machine files can be copied with putty tools (note: use IPv4 address) ```` pscp -scp -P 22 eive@192.168.199.227:/example-file ```` diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 6cd3ec64..85d82a48 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -21,10 +21,12 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -327,6 +329,13 @@ void ObjectFactory::produce(){ IMTQHandler* imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie); imtqHandler->setStartUpImmediately(); + UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, + PLOC::MAX_REPLY_SIZE); + /* Testing PlocHandler on TE0720-03-1CFA */ + PlocHandler* plocHandler = new PlocHandler(objects::PLOC_HANDLER, objects::UART_COM_IF, + plocUartCookie); + plocHandler->setStartUpImmediately(); + #endif new TmTcUnixUdpBridge(objects::UDP_BRIDGE, @@ -348,5 +357,12 @@ void ObjectFactory::produce(){ heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); + + UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, + PLOC::MAX_REPLY_SIZE); + /* Testing PlocHandler on TE0720-03-1CFA */ + PlocHandler* plocHandler = new PlocHandler(objects::PLOC_HANDLER, objects::UART_COM_IF, + plocUartCookie); + plocHandler->setStartUpImmediately(); #endif } diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 73c05edb..3f5ebfca 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -19,7 +19,7 @@ debugging. */ #define OBSW_ADD_TEST_CODE 1 #define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 1 #define P60DOCK_DEBUG 0 #define PDU1_DEBUG 0 diff --git a/fsfwconfig/objects/systemObjectList.h b/fsfwconfig/objects/systemObjectList.h index c0c78a62..352c4ddc 100644 --- a/fsfwconfig/objects/systemObjectList.h +++ b/fsfwconfig/objects/systemObjectList.h @@ -52,6 +52,7 @@ namespace objects { GYRO_2_L3G_HANDLER = 0x44000013, IMTQ_HANDLER = 0x44000014, + PLOC_HANDLER = 0x44000015, /* Custom device handler */ PCDU_HANDLER = 0x44001000, diff --git a/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 43435cf3..86e3629e 100644 --- a/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -36,6 +36,7 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::RTD_IC17, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::RTD_IC18, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE); @@ -56,6 +57,7 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::RTD_IC17, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::RTD_IC18, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.4, DeviceHandlerIF::GET_WRITE); @@ -76,6 +78,7 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::RTD_IC17, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::RTD_IC18, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.6, DeviceHandlerIF::SEND_READ); @@ -96,6 +99,7 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::RTD_IC17, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::RTD_IC18, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.8, DeviceHandlerIF::GET_READ); @@ -116,6 +120,7 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::RTD_IC17, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::RTD_IC18, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { return HasReturnvaluesIF::RETURN_OK; diff --git a/fsfwconfig/returnvalues/classIds.h b/fsfwconfig/returnvalues/classIds.h index 93349596..22bb0457 100644 --- a/fsfwconfig/returnvalues/classIds.h +++ b/fsfwconfig/returnvalues/classIds.h @@ -20,6 +20,7 @@ enum { SA_DEPL_HANDLER, SYRLINKS_HANDLER, IMTQ_HANDLER, + PLOC_HANDLER }; } diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 6e8518b0..7d34aac9 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources(${TARGET_NAME} PUBLIC SyrlinksHkHandler.cpp Max31865PT1000Handler.cpp IMTQHandler.cpp + PlocHandler.cpp ) diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index 7070b51e..b88dde90 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -6,7 +6,7 @@ #include PlocHandler::PlocHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : - DeviceHandlerBase(objectId, comIF, comCookie), engHkDataset(this) { + DeviceHandlerBase(objectId, comIF, comCookie) { if (comCookie == NULL) { sif::error << "PlocHandler: Invalid com cookie" << std::endl; } @@ -28,8 +28,7 @@ void PlocHandler::doShutDown(){ ReturnValue_t PlocHandler::buildNormalDeviceCommand( DeviceCommandId_t * id) { - *id = IMTQ::GET_ENG_HK_DATA; - return buildCommandFromCommand(*id, NULL, 0); + return RETURN_OK; } ReturnValue_t PlocHandler::buildTransitionDeviceCommand( @@ -41,34 +40,37 @@ ReturnValue_t PlocHandler::buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t * commandData, size_t commandDataLen) { switch(deviceCommand) { - case(IMTQ::GET_ENG_HK_DATA): { - commandBuffer[0] = IMTQ::CC::GET_ENG_HK_DATA; - rawPacket = commandBuffer; + case(PLOC::TC_MEM_WRITE): { + 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); + PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData); + rawPacket = tcMemWrite.getWholeData(); + rawPacketLen = tcMemWrite.getFullSize(); + rememberCommandId = PLOC::TC_MEM_WRITE; return RETURN_OK; } - case(IMTQ::START_ACTUATION_DIPOLE): { - /* IMTQ expects low byte first */ - commandBuffer[0] = IMTQ::CC::START_ACTUATION_DIPOLE; - commandBuffer[1] = *(commandData + 1); - commandBuffer[2] = *(commandData); - commandBuffer[3] = *(commandData + 3); - commandBuffer[4] = *(commandData + 2); - commandBuffer[5] = *(commandData + 5); - commandBuffer[6] = *(commandData + 4); - commandBuffer[7] = *(commandData + 7); - commandBuffer[8] = *(commandData + 6); - rawPacket = commandBuffer; + case(PLOC::TC_MEM_READ): { + const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 + | *(commandData + 2) << 8 | *(commandData + 3); + PLOC::TcMemRead tcMemRead(memoryAddress); + rawPacket = tcMemRead.getWholeData(); + rawPacketLen = tcMemRead.getFullSize(); + rememberCommandId = PLOC::TC_MEM_READ; return RETURN_OK; } default: + sif::debug << "PlocHandler::buildCommandFromCommand: Command not implemented" << std::endl; return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } return HasReturnvaluesIF::RETURN_FAILED; } void PlocHandler::fillCommandAndReplyMap() { - this->insertInCommandAndReplyMap(IMTQ::GET_ENG_HK_DATA, 1, &engHkDataset, - IMTQ::SIZE_ENG_HK_DATA_REPLY, false, true, IMTQ::SIZE_ENG_HK_DATA_REPLY); + this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_ACK_REPORT); + this->insertInReplyMap(PLOC::ACK_SUCCESS, 1); + this->insertInReplyMap(PLOC::ACK_FAILURE, 1); } ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, @@ -76,34 +78,51 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, ReturnValue_t result = RETURN_OK; - switch(*start) { - case(IMTQ::CC::GET_ENG_HK_DATA): - *foundLen = IMTQ::SIZE_ENG_HK_DATA_REPLY; - *foundId = IMTQ::GET_ENG_HK_DATA; + *foundId = *(start) << 8 | *(start + 1) & APID_MASK; + + switch(*foundId) { + case(PLOC::ACK_SUCCESS): + *foundLen = PLOC::SIZE_ACK_REPORT; + break; + case(PLOC::ACK_FAILURE): + *foundLen = PLOC::SIZE_ACK_REPORT; break; default: - sif::debug << "PlocHandler::scanForReply: Reply contains invalid command code" << std::endl; + sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; result = IGNORE_REPLY_DATA; break; } + result = verifyPacket(start, foundLen); + return result; } +ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t* foundLen) { + + uint16_t receivedCrc = *(start + *foundLen - 2) << 8 | *(start + *foundlen - 1); + + if (receivedCrc != CRC::crc16ccitt(start, *foundLen, 0)) { + return CRC_FAILURE; + } + + return RETURN_OK; +} + ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { ReturnValue_t result = RETURN_OK; - result = parseStatusByte(packet); - - if (result != RETURN_OK) { - return result; - } - switch (id) { - case (IMTQ::GET_ENG_HK_DATA): - fillEngHkDataset(packet); + case (PLOC::ACK_SUCCESS): + receiveTm(); + receiveExecutionReport(); + break; + case (PLOC::ACK_FAILURE): + //TODO: Interpretation of status field in ack reply. + sif::error << "PlocHandler::interpretDeviceReply: Received ack failure reply" << std::endl; + triggerEvent(ACK_FAILURE, rememberCommandId); break; default: { sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; @@ -114,71 +133,116 @@ ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, return RETURN_OK; } -ReturnValue_t PlocHandler::parseStatusByte(const uint8_t* packet) { - uint8_t cmdErrorField = *(packet + 1) & 0xF; - switch (cmdErrorField) { - case 0: - return RETURN_OK; - case 1: - return REJECTED_WITHOUT_REASON; - case 2: - return INVALID_COMMAND_CODE; - case 3: - return PARAMETER_MISSING; - case 4: - return PARAMETER_INVALID; - case 5: - return CC_UNAVAILABLE; - case 7: - return INTERNAL_PROCESSING_ERROR; +ReturnValue_t PlocHandler::receiveTm() { + switch (rememberCommandId) { + case (PLOC::TC_MEM_WRITE): + break; + case (PLOC::TC_MEM_READ): + receiveTmMemoryReadReport(); + break; default: - sif::error << "PlocHandler::parseStatusByte: CMD Error field contains unknown error code " - << cmdErrorField << std::endl; - return CMD_ERR_UNKNOWN; + sif::debug << "PlocHandler::receiveTm: Rembered unknown command id" << std::endl; + break; } } -void PlocHandler::fillEngHkDataset(const uint8_t* packet) { - uint8_t offset = 2; - engHkDataset.digitalVoltageMv = *(packet + offset + 1) | *(packet + offset); - offset += 2; - engHkDataset.analogVoltageMv = *(packet + offset + 1) | *(packet + offset); - offset += 2; - engHkDataset.digitalCurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; - offset += 2; - engHkDataset.analogCurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; - offset += 2; - engHkDataset.coilXcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; - offset += 2; - engHkDataset.coilYcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; - offset += 2; - engHkDataset.coilZcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; - offset += 2; - engHkDataset.coilXTemperature = (*(packet + offset + 1) | *(packet + offset)); - offset += 2; - engHkDataset.coilYTemperature = (*(packet + offset + 1) | *(packet + offset)); - offset += 2; - engHkDataset.coilZTemperature = (*(packet + offset + 1) | *(packet + offset)); - offset += 2; - engHkDataset.mcuTemperature = (*(packet + offset + 1) | *(packet + offset)); +void PlocHandler::receiveExecutionReport() { -#if OBSW_VERBOSE_LEVEL >= 1 && IMTQ_DEBUG == 1 - sif::info << "IMTQ digital voltage: " << engHkDataset.digitalVoltageMv << " mV" << std::endl; - sif::info << "IMTQ analog voltage: " << engHkDataset.analogVoltageMv << " mV" << std::endl; - sif::info << "IMTQ digital current: " << engHkDataset.digitalCurrentA << " A" << std::endl; - sif::info << "IMTQ analog current: " << engHkDataset.analogCurrentA << " A" << std::endl; - sif::info << "IMTQ coil X current: " << engHkDataset.coilXcurrentA << " A" << std::endl; - sif::info << "IMTQ coil Y current: " << engHkDataset.coilYcurrentA << " A" << std::endl; - sif::info << "IMTQ coil Z current: " << engHkDataset.coilZcurrentA << " A" << std::endl; - sif::info << "IMTQ coil X temperature: " << engHkDataset.coilXTemperature << " °C" - << std::endl; - sif::info << "IMTQ coil Y temperature: " << engHkDataset.coilYTemperature << " °C" - << std::endl; - sif::info << "IMTQ coil Z temperature: " << engHkDataset.coilZTemperature << " °C" - << std::endl; - sif::info << "IMTQ coil MCU temperature: " << engHkDataset.mcuTemperature << " °C" - << std::endl; -#endif + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; + + communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); + communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); + + if(!verifyPacket(receivedData, receivedDataLen)) { + replyRawData(data, len, defaultRawReceiver); + triggerEvent(EXE_RPT_INVALID_CRC); + sif::error << "PlocHandler::receiveExecutionReport: Execution report has invalid crc" + << std::endl; + return; + } + + handleExecutionReport(receivedData, receivedDataLen); +} + +void PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { + + uint16_t apid = *(start) << 8 | *(start + 1) & APID_MASK; + + switch (apid) { + case (PLOC::APID_EXE_SUCCESS): { + return; + } + case (PLOC::APID_EXE_FAILURE): { + //TODO: Interpretation of status field in execution report + sif::error << "PlocHandler::handleExecutionReport: Received execution failure report" + << std::endl; + triggerEvent(EXE_FAILURE, rememberCommandId); + return; + } + } + return; +} + +void PlocHandler::receiveTmMemoryReadReport() { + + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; + + /* Receiving the telemetry packet */ + ReturnValue_t result = communicationInterface->requestReceiveMessage(comCookie, + PLOC::SIZE_TM_MEM_READ_REPORT); + if (result != RETURN_OK) { + sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " + << std::endl; + triggerEvent(REQUESTING_TM_READ_REPORT_FAILED, result); + return; + } + result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); + if (result != RETURN_OK) { + sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " + << std::endl; + return; + } + + uint16_t apid = *(start) << 8 | *(start + 1) & APID_MASK; + if (apid != PLOC::APID_TM_READ_REPORT) { + sif::error << "PlocHandler::receiveTmReadReport: Tm read report has invalid apid" + << std::endl; + return; + } + + if(!verifyPacket(receivedData, receivedDataLen)) { + replyRawData(data, len, defaultRawReceiver); + triggerEvent(TM_READ_RPT_INVALID_CRC); + sif::error << "PlocHandler::receiveTmReadReport: TM read report has invalid crc" + << std::endl; + return; + } + + handleDeviceTM(receivedData, receivedDataLen, PLOC::TC_MEM_READ); + +} + +void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) { + + ReturnValue_t result = RETURN_OK; + + DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); + if (iter == deviceReplyMap.end()) { + sif::debug << "PlocHandler::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, dataSet); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::handleDeviceTM: Failed to report data" << std::endl; + } } void PlocHandler::setNormalDatapoolEntriesInvalid(){ @@ -192,18 +256,6 @@ uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { - localDataPoolMap.emplace(IMTQ::DIGITAL_VOLTAGE_MV, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::ANALOG_VOLTAGE_MV, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::DIGITAL_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::ANALOG_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_X_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Y_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Z_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_X_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Y_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Z_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::MCU_TEMPERATURE, new PoolEntry( { 0 })); - return HasReturnvaluesIF::RETURN_OK; } diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index 2505f224..86e2e2dd 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -2,7 +2,7 @@ #define MISSION_DEVICES_PLOCHANDLER_H_ #include -#include +#include #include /** @@ -40,38 +40,67 @@ protected: private: - static const uint8_t INTERFACE_ID = CLASS_ID::IMTQ_HANDLER; + static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_HANDLER; - static const ReturnValue_t INVALID_COMMAND_CODE = MAKE_RETURN_CODE(0xA0); - static const ReturnValue_t PARAMETER_MISSING = MAKE_RETURN_CODE(0xA1); - static const ReturnValue_t PARAMETER_INVALID = MAKE_RETURN_CODE(0xA2); - static const ReturnValue_t CC_UNAVAILABLE = MAKE_RETURN_CODE(0xA3); - static const ReturnValue_t INTERNAL_PROCESSING_ERROR = MAKE_RETURN_CODE(0xA4); - static const ReturnValue_t REJECTED_WITHOUT_REASON = MAKE_RETURN_CODE(0xA5); - static const ReturnValue_t CMD_ERR_UNKNOWN = MAKE_RETURN_CODE(0xA6); + static const ReturnValue_t TC_ACK_FAILURE = MAKE_RETURN_CODE(0xA0); + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA1); + static const Event REQUESTING_TM_READ_REPORT_FAILED = MAKE_EVENT(0, severity::LOW); + static const Event TM_READ_RPT_INVALID_CRC = MAKE_EVENT(1, severity::LOW); + static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); + static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW); + static const Event EXE_RPT_INVALID_CRC = MAKE_EVENT(4, severity::LOW); - IMTQ::EngHkDataset engHkDataset; + static const uint16_t APID_MASK = 0x7FF; - uint8_t commandBuffer[IMTQ::MAX_COMMAND_SIZE]; + DeviceCommandId_t rememberCommandId = PLOC::NONE; + + /** + * @brief This function checks wheter a telemetry packet is expected or not. + */ + ReturnValue_t receiveTm(); /** - * @brief Each reply contains a status byte giving information about a request. This function - * parses this byte and returns the associated failure message. + * @brief This function checks the crc of the received PLOC reply. * - * @param packet Pointer to the received message containing the status byte. + * @param start Pointer to the first byte of the reply. + * @param foundLen Pointer to the length of the whole packet. * - * @return The return code derived from the received status byte. + * @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE. */ - ReturnValue_t parseStatusByte(const uint8_t* packet); + ReturnValue_t verifyPacket(const uint8_t* start, size_t* foundLen); /** - * @brief This function fills the engineering housekeeping dataset with the received data. - - * @param packet Pointer to the received data. - * + * @brief This function reads and handles the execution reply. */ - void fillEngHkDataset(const uint8_t* packet); + void receiveExecutionReport(); + + /** + * @brief This function handles the data of a execution report. + * + * @param receivedData Pointer to the received data + * @param receivedDataLen Size in bytes of the received data + */ + void handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen); + + /** + * @brief This function reads and handles the memory read report telemetry packet received + * after requesting the packet with the TC_MEM_READ command. + * + * @details In case of a valid packet the received memory content will be forwarded to the + * commanding object via an action message. + */ + void receiveTmMemoryReadReport(); + + /** + * @brief This function handles action message replies in case the telemetry has been + * requested by another object. + * + * @param data Pointer to the telemtry 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); }; #endif /* MISSION_DEVICES_PLOCHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h new file mode 100644 index 00000000..d468d0dd --- /dev/null +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -0,0 +1,131 @@ +#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ +#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ + +#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 DeviceCommandId_t ACK_SUCCESS = 0x400; + static const DeviceCommandId_t ACK_FAILURE = 0x401; + static const DeviceCommandId_t TM_READ_REPORT = 0x404; + + 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_TM_READ_REPORT = 0x404; + 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; + + /** + * @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 */ + memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(memAddrPtr)); + /* 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; + 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 */ + memcpy(this->localData.fields.buffer + CRC_OFFSET, &crc, sizeof(crc)); + } + + static const uint8_t CRC_OFFSET = 12; + static const uint8_t OFFSET_MEM_LEN_FIELD = 10; + + }; + + /** + * @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 */ + memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(memAddrPtr)); + /* 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 */ + memcpy(this->localData.fields.buffer + OFFSET_MEM_DATA_FIELD, memAddrPtr, + sizeof(memAddrPtr)); + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + LENGTH_TC_MEM_WRITE - CRC_SIZE, 0); + /* Add crc to packet data field of space packet */ + memcpy(this->localData.fields.buffer + CRC_OFFSET, &crc, sizeof(crc)); + } + + static const uint8_t OFFSET_MEM_LEN_FIELD = 10; + static const uint8_t OFFSET_MEM_DATA_FIELD = 12; + static const uint8_t CRC_OFFSET = 16; + }; + +} + + +#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ */ diff --git a/tmtc b/tmtc index f40b70f6..73105138 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f40b70f66eba176d3c36533a779e4e0ed13ae701 +Subproject commit 73105138050b5661a6cff76e1d64af40981f9c7f From 5d4c2bd5213c5965f21dc3d12d0be3b1a6b14efb Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 12 Apr 2021 10:16:59 +0200 Subject: [PATCH 03/16] plocHandler wip --- README.md | 8 ++++++- bsp_q7s/ObjectFactory.cpp | 5 ++-- fsfw_hal | 1 + fsfwconfig/OBSWConfig.h | 2 +- fsfwconfig/events/subsystemIdRanges.h | 3 ++- mission/devices/PlocHandler.cpp | 23 +++++++++---------- mission/devices/PlocHandler.h | 4 +++- .../IMTQHandlerDefinitions.h | 2 +- .../devicedefinitions/PlocDefinitions.h | 7 +++--- 9 files changed, 32 insertions(+), 23 deletions(-) create mode 160000 fsfw_hal diff --git a/README.md b/README.md index dafbfbba..73845e41 100644 --- a/README.md +++ b/README.md @@ -573,4 +573,10 @@ to install the required GPIO libraries before cloning the system root folder. When using Eclipse, there are two special build variables in the project properties → C/C++ Build → Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set the sysroot path in those variables to get any additional includes like `gpiod.h` in the -Eclipse indexer. \ No newline at end of file +Eclipse indexer. + +## Xilinx UARTLIE +Get info about ttyUL* devices +```` +cat /proc/tty/driver +```` \ No newline at end of file diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 85d82a48..fe852662 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -321,7 +321,7 @@ void ObjectFactory::produce(){ Max31865PT1000Handler* rtdIc16 = new Max31865PT1000Handler(objects::RTD_IC16, objects::SPI_COM_IF, spiRtdIc16, 0); Max31865PT1000Handler* rtdIc17 = new Max31865PT1000Handler(objects::RTD_IC17, objects::SPI_COM_IF, spiRtdIc17, 0); Max31865PT1000Handler* rtdIc18 = new Max31865PT1000Handler(objects::RTD_IC18, objects::SPI_COM_IF, spiRtdIc18, 0); - rtdIc10->setStartUpImmediately(); +// rtdIc10->setStartUpImmediately(); // rtdIc4->setStartUpImmediately(); I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE, @@ -329,9 +329,8 @@ void ObjectFactory::produce(){ IMTQHandler* imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie); imtqHandler->setStartUpImmediately(); - UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, + UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyUL3"), 115200, PLOC::MAX_REPLY_SIZE); - /* Testing PlocHandler on TE0720-03-1CFA */ PlocHandler* plocHandler = new PlocHandler(objects::PLOC_HANDLER, objects::UART_COM_IF, plocUartCookie); plocHandler->setStartUpImmediately(); diff --git a/fsfw_hal b/fsfw_hal new file mode 160000 index 00000000..14fe3257 --- /dev/null +++ b/fsfw_hal @@ -0,0 +1 @@ +Subproject commit 14fe32572d62db9d19707dc1f9bb6fecb1993b73 diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 3f5ebfca..73c05edb 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -19,7 +19,7 @@ debugging. */ #define OBSW_ADD_TEST_CODE 1 #define TEST_LIBGPIOD 0 -#define TE0720 1 +#define TE0720 0 #define P60DOCK_DEBUG 0 #define PDU1_DEBUG 0 diff --git a/fsfwconfig/events/subsystemIdRanges.h b/fsfwconfig/events/subsystemIdRanges.h index b2e9aaac..b33ee807 100644 --- a/fsfwconfig/events/subsystemIdRanges.h +++ b/fsfwconfig/events/subsystemIdRanges.h @@ -21,7 +21,8 @@ enum: uint8_t { MGM_RM3100, PCDU_HANDLER, HEATER_HANDLER, - SA_DEPL_HANDLER + SA_DEPL_HANDLER, + PLOC_HANDLER }; } diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index b88dde90..fca51b71 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -68,6 +68,7 @@ ReturnValue_t PlocHandler::buildCommandFromCommand( } void PlocHandler::fillCommandAndReplyMap() { + this->insertInCommandAndReplyMap(PLOC::TC_MEM_WRITE, 1, nullptr, PLOC::SIZE_ACK_REPORT); this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC::ACK_SUCCESS, 1); this->insertInReplyMap(PLOC::ACK_FAILURE, 1); @@ -78,7 +79,7 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, ReturnValue_t result = RETURN_OK; - *foundId = *(start) << 8 | *(start + 1) & APID_MASK; + *foundId = (*(start) << 8 | *(start + 1)) & APID_MASK; switch(*foundId) { case(PLOC::ACK_SUCCESS): @@ -100,7 +101,7 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t* foundLen) { - uint16_t receivedCrc = *(start + *foundLen - 2) << 8 | *(start + *foundlen - 1); + uint16_t receivedCrc = *(start + *foundLen - 2) << 8 | *(start + *foundLen - 1); if (receivedCrc != CRC::crc16ccitt(start, *foundLen, 0)) { return CRC_FAILURE; @@ -112,8 +113,6 @@ ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t* foundLen) ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { - ReturnValue_t result = RETURN_OK; - switch (id) { case (PLOC::ACK_SUCCESS): receiveTm(); @@ -133,7 +132,7 @@ ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, return RETURN_OK; } -ReturnValue_t PlocHandler::receiveTm() { +void PlocHandler::receiveTm() { switch (rememberCommandId) { case (PLOC::TC_MEM_WRITE): break; @@ -154,8 +153,8 @@ void PlocHandler::receiveExecutionReport() { communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); - if(!verifyPacket(receivedData, receivedDataLen)) { - replyRawData(data, len, defaultRawReceiver); + if(!verifyPacket(receivedData, &receivedDataLen)) { + replyRawData(receivedData, receivedDataLen, defaultRawReceiver); triggerEvent(EXE_RPT_INVALID_CRC); sif::error << "PlocHandler::receiveExecutionReport: Execution report has invalid crc" << std::endl; @@ -167,7 +166,7 @@ void PlocHandler::receiveExecutionReport() { void PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { - uint16_t apid = *(start) << 8 | *(start + 1) & APID_MASK; + uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; switch (apid) { case (PLOC::APID_EXE_SUCCESS): { @@ -205,15 +204,15 @@ void PlocHandler::receiveTmMemoryReadReport() { return; } - uint16_t apid = *(start) << 8 | *(start + 1) & APID_MASK; + uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; if (apid != PLOC::APID_TM_READ_REPORT) { sif::error << "PlocHandler::receiveTmReadReport: Tm read report has invalid apid" << std::endl; return; } - if(!verifyPacket(receivedData, receivedDataLen)) { - replyRawData(data, len, defaultRawReceiver); + if(!verifyPacket(receivedData, &receivedDataLen)) { + replyRawData(receivedData, receivedDataLen, defaultRawReceiver); triggerEvent(TM_READ_RPT_INVALID_CRC); sif::error << "PlocHandler::receiveTmReadReport: TM read report has invalid crc" << std::endl; @@ -239,7 +238,7 @@ void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom return; } - result = actionHelper.reportData(queueId, replyId, dataSet); + result = actionHelper.reportData(queueId, replyId, data, dataSize); if (result != RETURN_OK) { sif::debug << "PlocHandler::handleDeviceTM: Failed to report data" << std::endl; } diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index 86e2e2dd..8e3a6aa4 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -45,6 +45,8 @@ private: static const ReturnValue_t TC_ACK_FAILURE = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA1); + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_HANDLER; + static const Event REQUESTING_TM_READ_REPORT_FAILED = MAKE_EVENT(0, severity::LOW); static const Event TM_READ_RPT_INVALID_CRC = MAKE_EVENT(1, severity::LOW); static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); @@ -58,7 +60,7 @@ private: /** * @brief This function checks wheter a telemetry packet is expected or not. */ - ReturnValue_t receiveTm(); + void receiveTm(); /** * @brief This function checks the crc of the received PLOC reply. diff --git a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h index 21ad7dec..23ff8b9a 100644 --- a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h +++ b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h @@ -18,7 +18,7 @@ namespace IMTQ { static const uint8_t MAX_REPLY_SIZE = SIZE_ENG_HK_DATA_REPLY; static const uint8_t MAX_COMMAND_SIZE = 9; - static const uint8_t POOL_ENTRIES = 8; + static const uint8_t POOL_ENTRIES = 11; /** * Command code definitions. Each command or reply of an IMTQ request will begin with one of diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index d468d0dd..dbd157e5 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -21,6 +21,7 @@ namespace PLOC { * 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_EXE_SUCCESS = 0x402; static const uint16_t APID_EXE_FAILURE = 0x403; @@ -62,7 +63,7 @@ namespace PLOC { */ void fillPacketDataField(const uint32_t* memAddrPtr) { /* Add memAddr to packet data field */ - memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(memAddrPtr)); + memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(*memAddrPtr)); /* 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; @@ -107,13 +108,13 @@ namespace PLOC { */ void fillPacketDataField(const uint32_t* memAddrPtr, const uint32_t* memoryDataPtr) { /* Add memAddr to packet data field */ - memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(memAddrPtr)); + memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(*memAddrPtr)); /* 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 */ memcpy(this->localData.fields.buffer + OFFSET_MEM_DATA_FIELD, memAddrPtr, - sizeof(memAddrPtr)); + sizeof(*memAddrPtr)); uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + LENGTH_TC_MEM_WRITE - CRC_SIZE, 0); /* Add crc to packet data field of space packet */ From 0916ca87d970964f0de85f669978a8aed7b3cabe Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Thu, 15 Apr 2021 13:17:15 +0200 Subject: [PATCH 04/16] plocHandler wip --- bsp_q7s/InitMission.cpp | 16 +- bsp_q7s/ObjectFactory.cpp | 10 +- bsp_q7s/devices/HeaterHandler.cpp | 5 +- fsfwconfig/OBSWConfig.h | 2 +- .../pollingSequenceFactory.cpp | 24 ++- .../pollingsequence/pollingSequenceFactory.h | 5 + mission/devices/PlocHandler.cpp | 156 +++++++++++------- mission/devices/PlocHandler.h | 32 +++- .../devicedefinitions/PlocDefinitions.h | 53 ++++-- 9 files changed, 214 insertions(+), 89 deletions(-) diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index c776ead0..8c512c83 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -135,6 +135,8 @@ void initmission::initTasks() { initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); } +#if TE0720 == 0 + //TODO: Add handling of missed deadlines /* Polling Sequence Table Default */ FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( @@ -145,7 +147,6 @@ void initmission::initTasks() { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; } -#if TE0720 == 0 FixedTimeslotTaskIF* gomSpacePstTask = factory-> createFixedTimeslotTask("GS_PST_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc); @@ -153,6 +154,15 @@ void initmission::initTasks() { if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; } + +#else + FixedTimeslotTaskIF * pollingSequenceTableTE0720 = factory->createFixedTimeslotTask( + "PST_TASK_TE0720", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, + missedDeadlineFunc); + result = pst::pollingSequenceTE0720(pollingSequenceTableTE0720); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "InitMission::initTasks: Creating TE0720 PST failed!" << std::endl; + } #endif PeriodicTaskIF* testTask = factory->createPeriodicTask( @@ -177,8 +187,10 @@ void initmission::initTasks() { #if TE0720 == 0 gomSpacePstTask->startTask(); -#endif pollingSequenceTableTaskDefault->startTask(); +#else + pollingSequenceTableTE0720->startTask(); +#endif pusVerification->startTask(); pusEvents->startTask(); diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index fe852662..55373525 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -351,11 +351,11 @@ void ObjectFactory::produce(){ new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #elif TE0720 == 1 /* Configuration for MIO0 on TE0720-03-1CFA */ - GpiodRegular gpioConfigForDummyHeater(std::string("gpiochip0"), 0, - std::string("Heater0"), gpio::OUT, 0); - heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, - objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); +// GpiodRegular* gpio = new GpiodRegular(std::string("gpiochip0"), 0, std::string("Heater0"), +// gpio::OUT, 0); +// heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpio); +// new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, +// objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, PLOC::MAX_REPLY_SIZE); diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index 9a44c57b..3f53af2f 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -58,8 +58,9 @@ ReturnValue_t HeaterHandler::initialize() { if(mainLineSwitcherObjectId != objects::NO_OBJECT) { mainLineSwitcher = objectManager->get(mainLineSwitcherObjectId); if (mainLineSwitcher == nullptr) { - sif::error << "HeaterHandler::initialize: Main line switcher failed to fetch object" - << "from object ID." << std::endl; + sif::error + << "HeaterHandler::initialize: Failed to get main line switcher. Make sure " + << "main line switcher object is initialized." << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; } } diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 73c05edb..3f5ebfca 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -19,7 +19,7 @@ debugging. */ #define OBSW_ADD_TEST_CODE 1 #define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 1 #define P60DOCK_DEBUG 0 #define PDU1_DEBUG 0 diff --git a/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 86e3629e..51427e90 100644 --- a/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -5,13 +5,13 @@ #include #include #include +#include ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) { /* Length of a communication cycle */ uint32_t length = thisSequence->getPeriodMs(); - thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, @@ -229,3 +229,25 @@ ReturnValue_t pst::pollingSequenceAcsTest(FixedTimeslotTaskIF *thisSequence) { } return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t pst::pollingSequenceTE0720(FixedTimeslotTaskIF *thisSequence) { + uint32_t length = thisSequence->getPeriodMs(); + + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.2, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.4, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.6, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.8, + DeviceHandlerIF::GET_READ); + + if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Initialization of TE0720 PST failed" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + diff --git a/fsfwconfig/pollingsequence/pollingSequenceFactory.h b/fsfwconfig/pollingsequence/pollingSequenceFactory.h index 09dd7242..73cdc0bb 100644 --- a/fsfwconfig/pollingsequence/pollingSequenceFactory.h +++ b/fsfwconfig/pollingsequence/pollingSequenceFactory.h @@ -35,6 +35,11 @@ ReturnValue_t pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence); ReturnValue_t gomspacePstInit(FixedTimeslotTaskIF *thisSequence); ReturnValue_t pollingSequenceAcsTest(FixedTimeslotTaskIF* thisSequence); + +/** + * @brief This polling sequence will be created when the software is compiled for the TE0720. + */ +ReturnValue_t pollingSequenceTE0720(FixedTimeslotTaskIF* thisSequence); } diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index fca51b71..7300a610 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -41,24 +41,10 @@ ReturnValue_t PlocHandler::buildCommandFromCommand( size_t commandDataLen) { switch(deviceCommand) { case(PLOC::TC_MEM_WRITE): { - 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); - PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData); - rawPacket = tcMemWrite.getWholeData(); - rawPacketLen = tcMemWrite.getFullSize(); - rememberCommandId = PLOC::TC_MEM_WRITE; - return RETURN_OK; + return prepareTcMemWriteCommand(commandData, commandDataLen); } case(PLOC::TC_MEM_READ): { - const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 - | *(commandData + 2) << 8 | *(commandData + 3); - PLOC::TcMemRead tcMemRead(memoryAddress); - rawPacket = tcMemRead.getWholeData(); - rawPacketLen = tcMemRead.getFullSize(); - rememberCommandId = PLOC::TC_MEM_READ; - return RETURN_OK; + return prepareTcMemReadCommand(commandData, commandDataLen); } default: sif::debug << "PlocHandler::buildCommandFromCommand: Command not implemented" << std::endl; @@ -67,11 +53,43 @@ ReturnValue_t PlocHandler::buildCommandFromCommand( return HasReturnvaluesIF::RETURN_FAILED; } +ReturnValue_t PlocHandler::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); + PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData); + if (tcMemWrite.getFullSize() > PLOC::MAX_COMMAND_SIZE) { + sif::debug << "PlocHandler::prepareTcMemWriteCommand: Command too big" << std::endl; + return RETURN_FAILED; + } + memcpy(commandBuffer, tcMemWrite.getWholeData(), tcMemWrite.getFullSize()); + rawPacket = commandBuffer; + rawPacketLen = tcMemWrite.getFullSize(); + rememberCommandId = PLOC::TC_MEM_WRITE; + return RETURN_OK; +} + +ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData, + size_t commandDataLen) { + const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 + | *(commandData + 2) << 8 | *(commandData + 3); + PLOC::TcMemRead tcMemRead(memoryAddress); + if (tcMemRead.getFullSize() > PLOC::MAX_COMMAND_SIZE) { + sif::debug << "PlocHandler::prepareTcMemReadCommand: Command too big" << std::endl; + return RETURN_FAILED; + } + memcpy(commandBuffer, tcMemRead.getWholeData(), tcMemRead.getFullSize()); + rawPacket = commandBuffer; + rawPacketLen = tcMemRead.getFullSize(); + rememberCommandId = PLOC::TC_MEM_READ; + return RETURN_OK; +} + void PlocHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(PLOC::TC_MEM_WRITE, 1, nullptr, PLOC::SIZE_ACK_REPORT); this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_ACK_REPORT); - this->insertInReplyMap(PLOC::ACK_SUCCESS, 1); - this->insertInReplyMap(PLOC::ACK_FAILURE, 1); } ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, @@ -79,31 +97,34 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, ReturnValue_t result = RETURN_OK; - *foundId = (*(start) << 8 | *(start + 1)) & APID_MASK; + uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK; - switch(*foundId) { - case(PLOC::ACK_SUCCESS): + switch(apid) { + case(PLOC::APID_ACK_SUCCESS): *foundLen = PLOC::SIZE_ACK_REPORT; + *foundId = rememberCommandId; break; - case(PLOC::ACK_FAILURE): + case(PLOC::APID_ACK_FAILURE): *foundLen = PLOC::SIZE_ACK_REPORT; - break; + *foundId = rememberCommandId; + break; default: sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; - result = IGNORE_REPLY_DATA; + return IGNORE_REPLY_DATA; break; } - result = verifyPacket(start, foundLen); - return result; } -ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t* foundLen) { +ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) { - uint16_t receivedCrc = *(start + *foundLen - 2) << 8 | *(start + *foundLen - 1); + uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1); - if (receivedCrc != CRC::crc16ccitt(start, *foundLen, 0)) { + uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2, 0); + + if (receivedCrc != recalculatedCrc) { + sif::debug << "PlocHandler::verifyPacket: CRC failure of ACK reply" << std::endl; return CRC_FAILURE; } @@ -113,55 +134,68 @@ ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t* foundLen) ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + uint16_t apid = (*(packet) << 8 | *(packet + 1)) & APID_MASK; + + if (apid == PLOC::APID_ACK_FAILURE) { + sif::error << "PlocHandler::interpretDeviceReply: Received ACK failure reply" << std::endl; + triggerEvent(ACK_FAILURE, id); + replyRawData(packet, PLOC::SIZE_ACK_REPORT, defaultRawReceiver); + return RETURN_OK; + } + + if (verifyPacket(packet, PLOC::SIZE_ACK_REPORT) == CRC_FAILURE) { + sif::error << "PlocHandler::interpretDeviceReply: CRC failure in Ack reply" << std::endl; + replyRawData(packet, PLOC::SIZE_ACK_REPORT, defaultRawReceiver); + triggerEvent(CRC_FAILURE_IN_ACK_REPLY, id); + return RETURN_OK; + } + switch (id) { - case (PLOC::ACK_SUCCESS): - receiveTm(); - receiveExecutionReport(); - break; - case (PLOC::ACK_FAILURE): - //TODO: Interpretation of status field in ack reply. - sif::error << "PlocHandler::interpretDeviceReply: Received ack failure reply" << std::endl; - triggerEvent(ACK_FAILURE, rememberCommandId); - break; - default: { - sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } - } - - return RETURN_OK; -} - -void PlocHandler::receiveTm() { - switch (rememberCommandId) { case (PLOC::TC_MEM_WRITE): + receiveExecutionReport(); break; case (PLOC::TC_MEM_READ): receiveTmMemoryReadReport(); + receiveExecutionReport(); break; default: - sif::debug << "PlocHandler::receiveTm: Rembered unknown command id" << std::endl; - break; - } + sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + + rememberCommandId = PLOC::NONE; + return RETURN_OK; } -void PlocHandler::receiveExecutionReport() { +ReturnValue_t PlocHandler::receiveExecutionReport() { size_t receivedDataLen = 0; uint8_t *receivedData = nullptr; - communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); - communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); + ReturnValue_t result = RETURN_OK; - if(!verifyPacket(receivedData, &receivedDataLen)) { + result = communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); + if (result != RETURN_OK) { + sif::error << "PlocHandler::receiveExecutionReport: Failed to request execution report" + << std::endl; + return result; + } + result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); + if (result != RETURN_OK) { + sif::error << "PlocHandler::receiveExecutionReport: Failed to read execution report" + << std::endl; + return result; + } + + if(verifyPacket(receivedData, receivedDataLen) == CRC_FAILURE) { replyRawData(receivedData, receivedDataLen, defaultRawReceiver); triggerEvent(EXE_RPT_INVALID_CRC); sif::error << "PlocHandler::receiveExecutionReport: Execution report has invalid crc" << std::endl; - return; + return result; } - handleExecutionReport(receivedData, receivedDataLen); + result = handleExecutionReport(receivedData, receivedDataLen); } void PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { @@ -177,10 +211,10 @@ void PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t rece sif::error << "PlocHandler::handleExecutionReport: Received execution failure report" << std::endl; triggerEvent(EXE_FAILURE, rememberCommandId); - return; + return EXE_REPLY_CRC_FAILURE; } } - return; + return RETURN_OK; } void PlocHandler::receiveTmMemoryReadReport() { @@ -211,7 +245,7 @@ void PlocHandler::receiveTmMemoryReadReport() { return; } - if(!verifyPacket(receivedData, &receivedDataLen)) { + if(verifyPacket(receivedData, receivedDataLen) == CRC_FAILURE) { replyRawData(receivedData, receivedDataLen, defaultRawReceiver); triggerEvent(TM_READ_RPT_INVALID_CRC); sif::error << "PlocHandler::receiveTmReadReport: TM read report has invalid crc" diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index 8e3a6aa4..0c0bf7d8 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -44,12 +44,14 @@ private: static const ReturnValue_t TC_ACK_FAILURE = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t EXE_REPLY_CRC_FAILURE = MAKE_RETURN_CODE(0xA1); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_HANDLER; static const Event REQUESTING_TM_READ_REPORT_FAILED = MAKE_EVENT(0, severity::LOW); static const Event TM_READ_RPT_INVALID_CRC = MAKE_EVENT(1, severity::LOW); static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); + static const Event CRC_FAILURE_IN_ACK_REPLY = MAKE_EVENT(2, severity::LOW); static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW); static const Event EXE_RPT_INVALID_CRC = MAKE_EVENT(4, severity::LOW); @@ -57,10 +59,27 @@ private: DeviceCommandId_t rememberCommandId = PLOC::NONE; + uint8_t commandBuffer[PLOC::MAX_COMMAND_SIZE]; + /** - * @brief This function checks wheter a telemetry packet is expected or not. + * @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. */ - void receiveTm(); + 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. @@ -70,18 +89,21 @@ private: * * @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE. */ - ReturnValue_t verifyPacket(const uint8_t* start, size_t* foundLen); + ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen); /** * @brief This function reads and handles the execution reply. + * @param RETURN_OK if reading and handling of reply successful, otherwise failure value. */ - void receiveExecutionReport(); + ReturnValue_t receiveExecutionReport(); /** * @brief This function handles the data of a execution report. * * @param receivedData Pointer to the received data * @param receivedDataLen Size in bytes of the received data + * + * @return RETURN_OK if successful, otherwise an error code. */ void handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen); @@ -92,7 +114,7 @@ private: * @details In case of a valid packet the received memory content will be forwarded to the * commanding object via an action message. */ - void receiveTmMemoryReadReport(); + ReturnValue_t receiveTmMemoryReadReport(); /** * @brief This function handles action message replies in case the telemetry has been diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index dbd157e5..74dd3c09 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -3,15 +3,13 @@ #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 DeviceCommandId_t ACK_SUCCESS = 0x400; - static const DeviceCommandId_t ACK_FAILURE = 0x401; - static const DeviceCommandId_t TM_READ_REPORT = 0x404; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; @@ -23,6 +21,8 @@ namespace PLOC { 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; @@ -34,6 +34,7 @@ namespace PLOC { 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. @@ -44,6 +45,7 @@ namespace PLOC { */ class TcMemRead : public SpacePacket { public: + /** * @brief Constructor * @@ -63,18 +65,29 @@ namespace PLOC { */ void fillPacketDataField(const uint32_t* memAddrPtr) { /* Add memAddr to packet data field */ - memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(*memAddrPtr)); + 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 CRC_OFFSET = 12; - static const uint8_t OFFSET_MEM_LEN_FIELD = 10; + static const uint8_t OFFSET_MEM_LEN_FIELD = 4; + static const uint8_t CRC_OFFSET = 6; }; @@ -107,23 +120,39 @@ namespace PLOC { * @param memoryDataPtr Pointer to the memoryData to write */ void fillPacketDataField(const uint32_t* memAddrPtr, const uint32_t* memoryDataPtr) { + /* Add memAddr to packet data field */ - memcpy(this->localData.fields.buffer, memAddrPtr, sizeof(*memAddrPtr)); + 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 */ - memcpy(this->localData.fields.buffer + OFFSET_MEM_DATA_FIELD, memAddrPtr, - sizeof(*memAddrPtr)); + 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)); } - static const uint8_t OFFSET_MEM_LEN_FIELD = 10; - static const uint8_t OFFSET_MEM_DATA_FIELD = 12; - static const uint8_t CRC_OFFSET = 16; + /** 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; }; } From b0e8a8624a5623e5bdca97304dc2f01d9fed1d26 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Fri, 16 Apr 2021 18:59:48 +0200 Subject: [PATCH 05/16] wip --- mission/devices/PlocHandler.cpp | 4 ++-- mission/devices/devicedefinitions/PlocDefinitions.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index 7300a610..802c26e5 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -89,7 +89,7 @@ ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData, void PlocHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(PLOC::TC_MEM_WRITE, 1, nullptr, PLOC::SIZE_ACK_REPORT); - this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_ACK_REPORT); + this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_TC_MEM_READ_REPLY); } ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, @@ -198,7 +198,7 @@ ReturnValue_t PlocHandler::receiveExecutionReport() { result = handleExecutionReport(receivedData, receivedDataLen); } -void PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { +ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index 74dd3c09..89cef3da 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -15,6 +15,9 @@ namespace PLOC { static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_TM_MEM_READ_REPORT = 18; + /** Reply comprises one ack report, the telemetry packet and the execution report */ + static const uint16_t SIZE_TC_MEM_READ_REPLY = 49; + /** * SpacePacket apids of PLOC telecommands and telemetry. */ @@ -33,7 +36,7 @@ namespace PLOC { 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_REPLY_SIZE = SIZE_TC_MEM_READ_REPLY; static const size_t MAX_COMMAND_SIZE = 18; /** From 7c28b2a0bc5116b962ad8e1d0482f066b3816619 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 19 Apr 2021 17:17:22 +0200 Subject: [PATCH 06/16] changes in plocDefinitions and plocHandler --- README.md | 6 ++++++ mission/devices/PlocHandler.cpp | 13 +++++++++++++ mission/devices/devicedefinitions/PlocDefinitions.h | 8 ++++++++ 3 files changed, 27 insertions(+) diff --git a/README.md b/README.md index 73845e41..b4e5acab 100644 --- a/README.md +++ b/README.md @@ -579,4 +579,10 @@ Eclipse indexer. Get info about ttyUL* devices ```` cat /proc/tty/driver +```` + +## Useful Q7S Linux Commands +Rebooting currently running image: +```` +xsc_boot_copy -r ```` \ No newline at end of file diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index 802c26e5..38c835dc 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -106,8 +106,21 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, break; case(PLOC::APID_ACK_FAILURE): *foundLen = PLOC::SIZE_ACK_REPORT; +<<<<<<< Updated upstream *foundId = rememberCommandId; break; +======= + break; + case(PLOC::TM_READ_REPORT): + *foundLen = PLOC::SIZE_ACK_REPORT; + break; + case(PLOC::EXE_SUCCESS): + *foundLen = PLOC::SIZE_EXE_REPORT; + break; + case(PLOC::EXE_FAILURE): + *foundLen = PLOC::SIZE_EXE_REPORT; + break; +>>>>>>> Stashed changes default: sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; return IGNORE_REPLY_DATA; diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index 89cef3da..fdcae741 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -10,6 +10,14 @@ namespace PLOC { static const DeviceCommandId_t NONE = 0x0; static const DeviceCommandId_t TC_MEM_WRITE = 0x714; static const DeviceCommandId_t TC_MEM_READ = 0x715; +<<<<<<< Updated upstream +======= + static const DeviceCommandId_t ACK_SUCCESS = 0x400; + static const DeviceCommandId_t ACK_FAILURE = 0x401; + static const DeviceCommandId_t EXE_SUCCESS = 0x402; + static const DeviceCommandId_t EXE_FAILURE = 0x403; + static const DeviceCommandId_t TM_READ_REPORT = 0x404; +>>>>>>> Stashed changes static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; From a0a5c4c8aa2ab72f6365d357082cd7fe91aa04cc Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Thu, 22 Apr 2021 17:32:39 +0200 Subject: [PATCH 07/16] tc mem write and tc mem read implemented --- linux/uart/UartComIF.cpp | 3 + mission/devices/PlocHandler.cpp | 470 ++++++++++++------ mission/devices/PlocHandler.h | 91 +++- .../devicedefinitions/PlocDefinitions.h | 31 +- 4 files changed, 401 insertions(+), 194 deletions(-) diff --git a/linux/uart/UartComIF.cpp b/linux/uart/UartComIF.cpp index 79470a45..8d9a15c3 100644 --- a/linux/uart/UartComIF.cpp +++ b/linux/uart/UartComIF.cpp @@ -363,6 +363,9 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, *buffer = uartDeviceMapIter->second.replyBuffer.data(); *size = uartDeviceMapIter->second.replyLen; + /* Length is reset to 0 to prevent reading the same data twice */ + uartDeviceMapIter->second.replyLen = 0; + return RETURN_OK; } diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index 38c835dc..f1444488 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -53,6 +53,98 @@ ReturnValue_t PlocHandler::buildCommandFromCommand( return HasReturnvaluesIF::RETURN_FAILED; } +void PlocHandler::fillCommandAndReplyMap() { + this->insertInCommandMap(PLOC::TC_MEM_WRITE); + this->insertInCommandMap(PLOC::TC_MEM_READ); + this->insertInReplyMap(PLOC::ACK_REPORT, 1, nullptr, PLOC::SIZE_ACK_REPORT); + this->insertInReplyMap(PLOC::EXE_REPORT, 3, nullptr, PLOC::SIZE_EXE_REPORT); + this->insertInReplyMap(PLOC::TM_MEMORY_READ_REPORT, 2, nullptr, PLOC::SIZE_TM_MEM_READ_REPORT); +} + +ReturnValue_t PlocHandler::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::APID_ACK_SUCCESS): + *foundLen = PLOC::SIZE_ACK_REPORT; + *foundId = PLOC::ACK_REPORT; + break; + case(PLOC::APID_ACK_FAILURE): + *foundLen = PLOC::SIZE_ACK_REPORT; + *foundId = PLOC::ACK_REPORT; + break; + case(PLOC::APID_TM_MEMORY_READ_REPORT): + *foundLen = PLOC::SIZE_TM_MEM_READ_REPORT; + *foundId = PLOC::TM_MEMORY_READ_REPORT; + break; + case(PLOC::APID_EXE_SUCCESS): + *foundLen = PLOC::SIZE_EXE_REPORT; + *foundId = PLOC::EXE_REPORT; + break; + case(PLOC::APID_EXE_FAILURE): + *foundLen = PLOC::SIZE_EXE_REPORT; + *foundId = PLOC::EXE_REPORT; + break; + default: { + sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; + *foundLen = remainingSize; + result = INVALID_APID; + break; + } + } + + return result; +} + +ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) { + + ReturnValue_t result = RETURN_OK; + + switch (id) { + case PLOC::ACK_REPORT: { + result = handleAckReport(packet); + break; + } + case (PLOC::TM_MEMORY_READ_REPORT): { + result = handleMemoryReadReport(packet); + break; + } + case (PLOC::EXE_REPORT): { + result = handleExecutionReport(packet); + break; + } + default: { + sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + } + + return result; +} + +void PlocHandler::setNormalDatapoolEntriesInvalid(){ + +} + +uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ + return 500; +} + +ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + + return HasReturnvaluesIF::RETURN_OK; +} + +void PlocHandler::setModeNormal() { + mode = MODE_NORMAL; +} + ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData, size_t commandDataLen) { const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 @@ -67,7 +159,7 @@ ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData, memcpy(commandBuffer, tcMemWrite.getWholeData(), tcMemWrite.getFullSize()); rawPacket = commandBuffer; rawPacketLen = tcMemWrite.getFullSize(); - rememberCommandId = PLOC::TC_MEM_WRITE; + nextReplyId = PLOC::ACK_REPORT; return RETURN_OK; } @@ -83,53 +175,10 @@ ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData, memcpy(commandBuffer, tcMemRead.getWholeData(), tcMemRead.getFullSize()); rawPacket = commandBuffer; rawPacketLen = tcMemRead.getFullSize(); - rememberCommandId = PLOC::TC_MEM_READ; + nextReplyId = PLOC::ACK_REPORT; return RETURN_OK; } -void PlocHandler::fillCommandAndReplyMap() { - this->insertInCommandAndReplyMap(PLOC::TC_MEM_WRITE, 1, nullptr, PLOC::SIZE_ACK_REPORT); - this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_TC_MEM_READ_REPLY); -} - -ReturnValue_t PlocHandler::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::APID_ACK_SUCCESS): - *foundLen = PLOC::SIZE_ACK_REPORT; - *foundId = rememberCommandId; - break; - case(PLOC::APID_ACK_FAILURE): - *foundLen = PLOC::SIZE_ACK_REPORT; -<<<<<<< Updated upstream - *foundId = rememberCommandId; - break; -======= - break; - case(PLOC::TM_READ_REPORT): - *foundLen = PLOC::SIZE_ACK_REPORT; - break; - case(PLOC::EXE_SUCCESS): - *foundLen = PLOC::SIZE_EXE_REPORT; - break; - case(PLOC::EXE_FAILURE): - *foundLen = PLOC::SIZE_EXE_REPORT; - break; ->>>>>>> Stashed changes - default: - sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; - return IGNORE_REPLY_DATA; - break; - } - - return result; -} - ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) { uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1); @@ -137,137 +186,202 @@ ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) { uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2, 0); if (receivedCrc != recalculatedCrc) { - sif::debug << "PlocHandler::verifyPacket: CRC failure of ACK reply" << std::endl; return CRC_FAILURE; } return RETURN_OK; } -ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) { - - uint16_t apid = (*(packet) << 8 | *(packet + 1)) & APID_MASK; - - if (apid == PLOC::APID_ACK_FAILURE) { - sif::error << "PlocHandler::interpretDeviceReply: Received ACK failure reply" << std::endl; - triggerEvent(ACK_FAILURE, id); - replyRawData(packet, PLOC::SIZE_ACK_REPORT, defaultRawReceiver); - return RETURN_OK; - } - - if (verifyPacket(packet, PLOC::SIZE_ACK_REPORT) == CRC_FAILURE) { - sif::error << "PlocHandler::interpretDeviceReply: CRC failure in Ack reply" << std::endl; - replyRawData(packet, PLOC::SIZE_ACK_REPORT, defaultRawReceiver); - triggerEvent(CRC_FAILURE_IN_ACK_REPLY, id); - return RETURN_OK; - } - - switch (id) { - case (PLOC::TC_MEM_WRITE): - receiveExecutionReport(); - break; - case (PLOC::TC_MEM_READ): - receiveTmMemoryReadReport(); - receiveExecutionReport(); - break; - default: - sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } - - rememberCommandId = PLOC::NONE; - return RETURN_OK; -} - -ReturnValue_t PlocHandler::receiveExecutionReport() { - - size_t receivedDataLen = 0; - uint8_t *receivedData = nullptr; +ReturnValue_t PlocHandler::handleAckReport(const uint8_t* data) { ReturnValue_t result = RETURN_OK; - result = communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to request execution report" - << std::endl; - return result; - } - result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to read execution report" - << std::endl; - return result; + result = verifyPacket(data, PLOC::SIZE_ACK_REPORT); + if(result == CRC_FAILURE) { + sif::error << "PlocHandler::handleAckReport: CRC failure" << std::endl; + nextReplyId = PLOC::NONE; + replyRawReplyIfnotWiretapped(data, PLOC::SIZE_ACK_REPORT); + triggerEvent(CRC_FAILURE_EVENT); + sendFailureReport(PLOC::ACK_REPORT, CRC_FAILURE); + disableAllReplies(); + return IGNORE_REPLY_DATA; } - if(verifyPacket(receivedData, receivedDataLen) == CRC_FAILURE) { - replyRawData(receivedData, receivedDataLen, defaultRawReceiver); - triggerEvent(EXE_RPT_INVALID_CRC); - sif::error << "PlocHandler::receiveExecutionReport: Execution report has invalid crc" - << std::endl; - return result; - } + uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; - result = handleExecutionReport(receivedData, receivedDataLen); + switch(apid) { + case PLOC::APID_ACK_FAILURE: { + //TODO: Interpretation of status field in acknowledgment report + sif::debug << "PlocHandler::handleAckReport: Received Ack failure report" << std::endl; + DeviceCommandId_t commandId = getPendingCommand(); + if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { + triggerEvent(ACK_FAILURE, commandId); + } + sendFailureReport(PLOC::ACK_REPORT, RECEIVED_ACK_FAILURE); + disableAllReplies(); + nextReplyId = PLOC::NONE; + result = IGNORE_REPLY_DATA; + break; + } + case PLOC::APID_ACK_SUCCESS: { + setNextReplyId(); + break; + } + default: { + sif::debug << "PlocHandler::handleAckReport: Invalid APID in Ack report" << std::endl; + result = RETURN_FAILED; + break; + } + } + + return result; } -ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { +ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* data) { - uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; + ReturnValue_t result = RETURN_OK; + + result = verifyPacket(data, PLOC::SIZE_EXE_REPORT); + if(result == CRC_FAILURE) { + sif::error << "PlocHandler::handleExecutionReport: CRC failure" << std::endl; + nextReplyId = PLOC::NONE; + return result; + } + + uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; switch (apid) { case (PLOC::APID_EXE_SUCCESS): { - return; + break; } case (PLOC::APID_EXE_FAILURE): { //TODO: Interpretation of status field in execution report sif::error << "PlocHandler::handleExecutionReport: Received execution failure report" << std::endl; - triggerEvent(EXE_FAILURE, rememberCommandId); - return EXE_REPLY_CRC_FAILURE; + DeviceCommandId_t commandId = getPendingCommand(); + if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { + triggerEvent(EXE_FAILURE, commandId); + } + else { + sif::debug << "PlocHandler::handleExecutionReport: Unknown command id" << std::endl; + } + sendFailureReport(PLOC::EXE_REPORT, RECEIVED_EXE_FAILURE); + disableExeReportReply(); + result = IGNORE_REPLY_DATA; + break; + } + default: { + sif::error << "PlocHandler::handleExecutionReport: Unknown APID" << std::endl; + result = RETURN_FAILED; + break; } } + + nextReplyId = PLOC::NONE; + + return result; +} + +ReturnValue_t PlocHandler::handleMemoryReadReport(const uint8_t* data) { + + ReturnValue_t result = RETURN_OK; + + result = verifyPacket(data, PLOC::SIZE_TM_MEM_READ_REPORT); + + if(result == CRC_FAILURE) { + sif::error << "PlocHandler::handleMemoryReadReport: Memory read report has invalid crc" + << std::endl; + } + /** Send data to commanding queue */ + handleDeviceTM(data + PLOC::DATA_FIELD_OFFSET, PLOC::SIZE_MEM_READ_REPORT_DATA, + PLOC::TM_MEMORY_READ_REPORT); + + nextReplyId = PLOC::EXE_REPORT; + + return result; +} + +ReturnValue_t PlocHandler::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::TC_MEM_WRITE: + enabledReplies = 2; + break; + case PLOC::TC_MEM_READ: { + enabledReplies = 3; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC::TM_MEMORY_READ_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " + << PLOC::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl; + } + break; + } + default: + sif::debug << "PlocHandler::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::ACK_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " << PLOC::ACK_REPORT + << " not in replyMap" << std::endl; + } + + result = DeviceHandlerBase::enableReplyInReplyMap(command, + enabledReplies, true, PLOC::EXE_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " << PLOC::EXE_REPORT + << " not in replyMap" << std::endl; + } + return RETURN_OK; } -void PlocHandler::receiveTmMemoryReadReport() { - - size_t receivedDataLen = 0; - uint8_t *receivedData = nullptr; - - /* Receiving the telemetry packet */ - ReturnValue_t result = communicationInterface->requestReceiveMessage(comCookie, - PLOC::SIZE_TM_MEM_READ_REPORT); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " - << std::endl; - triggerEvent(REQUESTING_TM_READ_REPORT_FAILED, result); - return; +void PlocHandler::setNextReplyId() { + switch(getPendingCommand()) { + case PLOC::TC_MEM_READ: + nextReplyId = PLOC::TM_MEMORY_READ_REPORT; + break; + default: + /* If no telemetry is expected the next reply is always the execution report */ + nextReplyId = PLOC::EXE_REPORT; + break; } - result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); - if (result != RETURN_OK) { - sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " - << std::endl; - return; +} +size_t PlocHandler::getNextReplyLength(DeviceCommandId_t commandId){ + + size_t replyLen = 0; + + if (nextReplyId == PLOC::NONE) { + return replyLen; } - uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; - if (apid != PLOC::APID_TM_READ_REPORT) { - sif::error << "PlocHandler::receiveTmReadReport: Tm read report has invalid apid" - << std::endl; - return; + 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 << "PlocHandler::getNextReplyLength: No entry for reply with reply id " + << std::hex << nextReplyId << " in deviceReplyMap" << std::endl; } - if(verifyPacket(receivedData, receivedDataLen) == CRC_FAILURE) { - replyRawData(receivedData, receivedDataLen, defaultRawReceiver); - triggerEvent(TM_READ_RPT_INVALID_CRC); - sif::error << "PlocHandler::receiveTmReadReport: TM read report has invalid crc" - << std::endl; - return; - } - - handleDeviceTM(receivedData, receivedDataLen, PLOC::TC_MEM_READ); - + return replyLen; } void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) { @@ -291,21 +405,67 @@ void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom } } -void PlocHandler::setNormalDatapoolEntriesInvalid(){ +void PlocHandler::disableAllReplies() { + DeviceReplyMap::iterator iter; + + /* Disable ack reply */ + iter = deviceReplyMap.find(PLOC::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::TC_MEM_WRITE: + break; + case PLOC::TC_MEM_READ: { + iter = deviceReplyMap.find(PLOC::TM_MEMORY_READ_REPORT); + info = &(iter->second); + info->delayCycles = 0; + info->command = deviceCommandMap.end(); + break; + } + default: { + sif::debug << "PlocHandler::disableAllReplies: Unknown command id" << commandId + << std::endl; + break; + } + } + + /* We must always disable the execution report reply here */ + disableExeReportReply(); } -uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ - return 500; +void PlocHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) { + + DeviceReplyIter iter = deviceReplyMap.find(replyId); + + if (iter == deviceReplyMap.end()) { + sif::debug << "PlocHandler::sendFailureReport: Reply not in reply map" << std::endl; + return; + } + + DeviceCommandInfo* info = &(iter->second.command->second); + + if (info == nullptr) { + sif::debug << "PlocHandler::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; } -ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { - - return HasReturnvaluesIF::RETURN_OK; +void PlocHandler::disableExeReportReply() { + DeviceReplyIter iter = deviceReplyMap.find(PLOC::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; } - -void PlocHandler::setModeNormal() { - mode = MODE_NORMAL; -} - diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index 0c0bf7d8..b241c838 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -6,7 +6,10 @@ #include /** - * @brief This is the device handler for the ISIS Magnetorquer iMTQ. + * @brief This is the device handler for the PLOC. + * + * @details The PLOC uses the space packet protocol for communication. On each command the PLOC + * answers at least with one acknowledgment and one execution report. * * @author J. Meier */ @@ -37,30 +40,38 @@ protected: 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_HANDLER; - static const ReturnValue_t TC_ACK_FAILURE = MAKE_RETURN_CODE(0xA0); - static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA1); - static const ReturnValue_t EXE_REPLY_CRC_FAILURE = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0); //!> Space Packet received from PLOC has invalid CRC + static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1); //!> Received ACK failure reply from PLOC + static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2); //!> Received execution failure reply from PLOC + static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3); //!> Received space packet with invalid APID from PLOC static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_HANDLER; - static const Event REQUESTING_TM_READ_REPORT_FAILED = MAKE_EVENT(0, severity::LOW); - static const Event TM_READ_RPT_INVALID_CRC = MAKE_EVENT(1, severity::LOW); - static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); - static const Event CRC_FAILURE_IN_ACK_REPLY = MAKE_EVENT(2, severity::LOW); - static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW); - static const Event EXE_RPT_INVALID_CRC = MAKE_EVENT(4, severity::LOW); + static const Event MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); //!> PLOC crc failure in telemetry packet + static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); //!> PLOC receive acknowledgment failure report + static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW); //!> PLOC receive execution failure report + static const Event CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW); //!> PLOC reply has invalid crc static const uint16_t APID_MASK = 0x7FF; - DeviceCommandId_t rememberCommandId = PLOC::NONE; - uint8_t commandBuffer[PLOC::MAX_COMMAND_SIZE]; + /** + * 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::NONE; + /** * @brief This function fills the commandBuffer to initiate the write memory command. * @@ -92,39 +103,71 @@ private: ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen); /** - * @brief This function reads and handles the execution reply. - * @param RETURN_OK if reading and handling of reply successful, otherwise failure value. + * @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 receiveExecutionReport(); + ReturnValue_t handleAckReport(const uint8_t* data); /** * @brief This function handles the data of a execution report. * - * @param receivedData Pointer to the received data - * @param receivedDataLen Size in bytes of the received data + * @param data Pointer to the received data packet. * * @return RETURN_OK if successful, otherwise an error code. */ - void handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen); + ReturnValue_t handleExecutionReport(const uint8_t* data); /** - * @brief This function reads and handles the memory read report telemetry packet received - * after requesting the packet with the TC_MEM_READ command. + * @brief This function handles the memory read report. * - * @details In case of a valid packet the received memory content will be forwarded to the - * commanding object via an action message. + * @param data Pointer to the data buffer holding the memory read report. + * + * @return RETURN_OK if successful, otherwise an error code. */ - ReturnValue_t receiveTmMemoryReadReport(); + 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 telemtry data. + * @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(); }; #endif /* MISSION_DEVICES_PLOCHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index fdcae741..b7378a8a 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -8,35 +8,36 @@ namespace PLOC { static const DeviceCommandId_t NONE = 0x0; - static const DeviceCommandId_t TC_MEM_WRITE = 0x714; - static const DeviceCommandId_t TC_MEM_READ = 0x715; -<<<<<<< Updated upstream -======= - static const DeviceCommandId_t ACK_SUCCESS = 0x400; - static const DeviceCommandId_t ACK_FAILURE = 0x401; - static const DeviceCommandId_t EXE_SUCCESS = 0x402; - static const DeviceCommandId_t EXE_FAILURE = 0x403; - static const DeviceCommandId_t TM_READ_REPORT = 0x404; ->>>>>>> Stashed changes + 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; - /** Reply comprises one ack report, the telemetry packet and the execution report */ - static const uint16_t SIZE_TC_MEM_READ_REPLY = 49; - /** * 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_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. @@ -44,7 +45,7 @@ namespace PLOC { 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_TC_MEM_READ_REPLY; + static const size_t MAX_REPLY_SIZE = SIZE_TM_MEM_READ_REPORT; static const size_t MAX_COMMAND_SIZE = 18; /** From 2e28016281996fa4923085b063815f6e0f0f4883 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sat, 24 Apr 2021 12:46:08 +0200 Subject: [PATCH 08/16] readme update --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index b4e5acab..12239b49 100644 --- a/README.md +++ b/README.md @@ -581,6 +581,13 @@ Get info about ttyUL* devices cat /proc/tty/driver ```` +## I2C +Getting information about I2C device +```` +ls /sys/class/i2c-dev/i2c-0/device/device/driver +```` +This shows the memory mapping of /dev/i2c-0 + ## Useful Q7S Linux Commands Rebooting currently running image: ```` From e4a715e24c0543a7d953a0169e931b72c3f545d9 Mon Sep 17 00:00:00 2001 From: Martin Zietz Date: Sat, 24 Apr 2021 14:22:22 +0200 Subject: [PATCH 09/16] ploc build for q7s --- bsp_q7s/ObjectFactory.cpp | 1 - fsfw | 2 +- fsfw_hal | 2 +- fsfwconfig/OBSWConfig.h | 2 +- tmtc | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 55373525..ca61442f 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -45,7 +45,6 @@ #include #include #include -#include #include #include diff --git a/fsfw b/fsfw index 42720e6f..18a9729c 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 42720e6f7d64bdd9a1ac0cea5846c9a8cedea0ff +Subproject commit 18a9729c75875f8bee674f03dd93a5eeeb657a66 diff --git a/fsfw_hal b/fsfw_hal index 14fe3257..7a3190e5 160000 --- a/fsfw_hal +++ b/fsfw_hal @@ -1 +1 @@ -Subproject commit 14fe32572d62db9d19707dc1f9bb6fecb1993b73 +Subproject commit 7a3190e5b6980ad2addc5e8a76d21994b542f0e0 diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 3f5ebfca..73c05edb 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -19,7 +19,7 @@ debugging. */ #define OBSW_ADD_TEST_CODE 1 #define TEST_LIBGPIOD 0 -#define TE0720 1 +#define TE0720 0 #define P60DOCK_DEBUG 0 #define PDU1_DEBUG 0 diff --git a/tmtc b/tmtc index 73105138..79e897b0 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 73105138050b5661a6cff76e1d64af40981f9c7f +Subproject commit 79e897b0353acacf0f986f22f57e9cd8cf30a0da From d877887826032187d606dfbc8827d07c0a018a3f Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sun, 25 Apr 2021 12:47:41 +0200 Subject: [PATCH 10/16] imqt wip --- mission/devices/IMTQHandler.cpp | 61 +++++++++++++++++++-------------- mission/devices/IMTQHandler.h | 1 + 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/mission/devices/IMTQHandler.cpp b/mission/devices/IMTQHandler.cpp index 0c1b1d1e..59f6dd46 100644 --- a/mission/devices/IMTQHandler.cpp +++ b/mission/devices/IMTQHandler.cpp @@ -117,6 +117,41 @@ ReturnValue_t IMTQHandler::interpretDeviceReply(DeviceCommandId_t id, return RETURN_OK; } +void IMTQHandler::setNormalDatapoolEntriesInvalid(){ + +} + +uint32_t IMTQHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ + return 500; +} + +ReturnValue_t IMTQHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + + localDataPoolMap.emplace(IMTQ::DIGITAL_VOLTAGE_MV, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ANALOG_VOLTAGE_MV, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::DIGITAL_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ANALOG_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_X_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Y_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Z_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_X_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Y_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Z_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::MCU_TEMPERATURE, new PoolEntry( { 0 })); + + return HasReturnvaluesIF::RETURN_OK; +} + +size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId){ + DeviceReplyIter iter = deviceReplyMap.find(commandId); + if(iter != deviceReplyMap.end()) { + return iter->second.replyLen; + }else{ + return 0; + } +} + ReturnValue_t IMTQHandler::parseStatusByte(const uint8_t* packet) { uint8_t cmdErrorField = *(packet + 1) & 0xF; switch (cmdErrorField) { @@ -184,32 +219,6 @@ void IMTQHandler::fillEngHkDataset(const uint8_t* packet) { #endif } -void IMTQHandler::setNormalDatapoolEntriesInvalid(){ - -} - -uint32_t IMTQHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ - return 500; -} - -ReturnValue_t IMTQHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { - - localDataPoolMap.emplace(IMTQ::DIGITAL_VOLTAGE_MV, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::ANALOG_VOLTAGE_MV, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::DIGITAL_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::ANALOG_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_X_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Y_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Z_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_X_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Y_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Z_TEMPERATURE, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::MCU_TEMPERATURE, new PoolEntry( { 0 })); - - return HasReturnvaluesIF::RETURN_OK; -} - void IMTQHandler::setModeNormal() { mode = MODE_NORMAL; } diff --git a/mission/devices/IMTQHandler.h b/mission/devices/IMTQHandler.h index 2e2a7612..21ba770f 100644 --- a/mission/devices/IMTQHandler.h +++ b/mission/devices/IMTQHandler.h @@ -37,6 +37,7 @@ protected: uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; + virtual size_t getNextReplyLength(DeviceCommandId_t commandId) override; private: From 191f4b6d0c296980dac641693bd8e1812172c904 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sun, 25 Apr 2021 15:53:44 +0200 Subject: [PATCH 11/16] get commanded dipole wip --- .../pollingSequenceFactory.cpp | 3 +- mission/devices/IMTQHandler.cpp | 93 ++++++++++++++----- mission/devices/IMTQHandler.h | 1 - .../IMTQHandlerDefinitions.h | 4 + tmtc | 2 +- 5 files changed, 78 insertions(+), 25 deletions(-) diff --git a/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 02e6b625..f7422786 100644 --- a/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -85,9 +85,10 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::RTD_IC16, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::RTD_IC17, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::RTD_IC18, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); #endif /* Q7S_ADD_RTD_DEVICES */ + thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.6, DeviceHandlerIF::SEND_READ); diff --git a/mission/devices/IMTQHandler.cpp b/mission/devices/IMTQHandler.cpp index 59f6dd46..80cc1550 100644 --- a/mission/devices/IMTQHandler.cpp +++ b/mission/devices/IMTQHandler.cpp @@ -42,25 +42,31 @@ ReturnValue_t IMTQHandler::buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t * commandData, size_t commandDataLen) { switch(deviceCommand) { + case(IMTQ::START_ACTUATION_DIPOLE): { + /* IMTQ expects low byte first */ + commandBuffer[0] = IMTQ::CC::START_ACTUATION_DIPOLE; + commandBuffer[1] = *(commandData + 1); + commandBuffer[2] = *(commandData); + commandBuffer[3] = *(commandData + 3); + commandBuffer[4] = *(commandData + 2); + commandBuffer[5] = *(commandData + 5); + commandBuffer[6] = *(commandData + 4); + commandBuffer[7] = *(commandData + 7); + commandBuffer[8] = *(commandData + 6); + rawPacket = commandBuffer; + rawPacketLen = 9; + return RETURN_OK; + } case(IMTQ::GET_ENG_HK_DATA): { commandBuffer[0] = IMTQ::CC::GET_ENG_HK_DATA; rawPacket = commandBuffer; rawPacketLen = 1; return RETURN_OK; } - case(IMTQ::START_ACTUATION_DIPOLE): { - /* IMTQ expects low byte first */ - commandBuffer[0] = IMTQ::CC::START_ACTUATION_DIPOLE; - commandBuffer[1] = *(commandData + 1); - commandBuffer[2] = *(commandData); - commandBuffer[3] = *(commandData + 3); - commandBuffer[4] = *(commandData + 2); - commandBuffer[5] = *(commandData + 5); - commandBuffer[6] = *(commandData + 4); - commandBuffer[7] = *(commandData + 7); - commandBuffer[8] = *(commandData + 6); + case(IMTQ::GET_COMMANDED_DIPOLE): { + commandBuffer[0] = IMTQ::CC::GET_COMMANDED_DIPOLE; rawPacket = commandBuffer; - rawPacketLen = 9; + rawPacketLen = 1; return RETURN_OK; } default: @@ -70,8 +76,12 @@ ReturnValue_t IMTQHandler::buildCommandFromCommand( } void IMTQHandler::fillCommandAndReplyMap() { + this->insertInCommandAndReplyMap(IMTQ::START_ACTUATION_DIPOLE, 1, nullptr, + IMTQ::SIZE_STATUS_REPLY); this->insertInCommandAndReplyMap(IMTQ::GET_ENG_HK_DATA, 1, &engHkDataset, - IMTQ::SIZE_ENG_HK_DATA_REPLY, false, true, IMTQ::SIZE_ENG_HK_DATA_REPLY); + IMTQ::SIZE_ENG_HK_DATA_REPLY); + this->insertInCommandAndReplyMap(IMTQ::GET_COMMANDED_DIPOLE, 1, nullptr, + IMTQ::SIZE_ENG_HK_DATA_REPLY); } ReturnValue_t IMTQHandler::scanForReply(const uint8_t *start, @@ -80,10 +90,18 @@ ReturnValue_t IMTQHandler::scanForReply(const uint8_t *start, ReturnValue_t result = RETURN_OK; switch(*start) { + case(IMTQ::CC::START_ACTUATION_DIPOLE): + *foundLen = IMTQ::SIZE_STATUS_REPLY; + *foundId = IMTQ::START_ACTUATION_DIPOLE; + break; case(IMTQ::CC::GET_ENG_HK_DATA): *foundLen = IMTQ::SIZE_ENG_HK_DATA_REPLY; *foundId = IMTQ::GET_ENG_HK_DATA; break; + case(IMTQ::CC::GET_COMMANDED_DIPOLE): + *foundLen = IMTQ::SIZE_GET_COMMANDED_DIPOLE_REPLY; + *foundId = IMTQ::GET_COMMANDED_DIPOLE; + break; default: sif::debug << "IMTQHandler::scanForReply: Reply contains invalid command code" << std::endl; result = IGNORE_REPLY_DATA; @@ -105,9 +123,15 @@ ReturnValue_t IMTQHandler::interpretDeviceReply(DeviceCommandId_t id, } switch (id) { + case (IMTQ::START_ACTUATION_DIPOLE): + // Replies only the status byte which is already handled with parseStatusByte + break; case (IMTQ::GET_ENG_HK_DATA): fillEngHkDataset(packet); break; + case (IMTQ::GET_COMMANDED_DIPOLE): + handleGetCommandedDipoleReply(packet); + break; default: { sif::debug << "IMTQHandler::interpretDeviceReply: Unknown device reply id" << std::endl; return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; @@ -143,31 +167,29 @@ ReturnValue_t IMTQHandler::initializeLocalDataPool(localpool::DataPool& localDat return HasReturnvaluesIF::RETURN_OK; } -size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId){ - DeviceReplyIter iter = deviceReplyMap.find(commandId); - if(iter != deviceReplyMap.end()) { - return iter->second.replyLen; - }else{ - return 0; - } -} - ReturnValue_t IMTQHandler::parseStatusByte(const uint8_t* packet) { uint8_t cmdErrorField = *(packet + 1) & 0xF; switch (cmdErrorField) { case 0: return RETURN_OK; case 1: + sif::error << "IMTQHandler::parseStatusByte: Command rejected without reason" << std::endl; return REJECTED_WITHOUT_REASON; case 2: + sif::error << "IMTQHandler::parseStatusByte: Command has invalid command code" << std::endl; return INVALID_COMMAND_CODE; case 3: + sif::error << "IMTQHandler::parseStatusByte: Command has missing parameter" << std::endl; return PARAMETER_MISSING; case 4: + sif::error << "IMTQHandler::parseStatusByte: Command has invalid parameter" << std::endl; return PARAMETER_INVALID; case 5: + sif::error << "IMTQHandler::parseStatusByte: CC unavailable" << std::endl; return CC_UNAVAILABLE; case 7: + sif::error << "IMTQHandler::parseStatusByte: IMQT replied internal processing error" + << std::endl; return INTERNAL_PROCESSING_ERROR; default: sif::error << "IMTQHandler::parseStatusByte: CMD Error field contains unknown error code " @@ -223,3 +245,30 @@ void IMTQHandler::setModeNormal() { mode = MODE_NORMAL; } + + +void IMTQHandler::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 result; + } + + DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); + if (iter == deviceReplyMap.end()) { + sif::debug << "IMTQHandler::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 << "IMTQHandler::handleDeviceTM: Failed to report data" << std::endl; + } +} diff --git a/mission/devices/IMTQHandler.h b/mission/devices/IMTQHandler.h index 21ba770f..2e2a7612 100644 --- a/mission/devices/IMTQHandler.h +++ b/mission/devices/IMTQHandler.h @@ -37,7 +37,6 @@ protected: uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; - virtual size_t getNextReplyLength(DeviceCommandId_t commandId) override; private: diff --git a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h index 23ff8b9a..60bd511e 100644 --- a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h +++ b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h @@ -6,6 +6,7 @@ namespace IMTQ { static const DeviceCommandId_t NONE = 0x0; static const DeviceCommandId_t GET_ENG_HK_DATA = 0x1; static const DeviceCommandId_t START_ACTUATION_DIPOLE = 0x2; + static const DeviceCommandId_t GET_COMMANDED_DIPOLE = 0x3; static const uint8_t GET_TEMP_REPLY_SIZE = 2; static const uint8_t CFGR_CMD_SIZE = 3; @@ -13,7 +14,9 @@ namespace IMTQ { static const uint32_t ENG_HK_DATA_SET_ID = GET_ENG_HK_DATA; static const uint8_t SIZE_ENG_HK_COMMAND = 1; + static const uint8_t SIZE_STATUS_REPLY = 2; static const uint8_t SIZE_ENG_HK_DATA_REPLY = 24; + static const uint8_t SIZE_GET_COMMANDED_DIPOLE_REPLY = 8; static const uint8_t MAX_REPLY_SIZE = SIZE_ENG_HK_DATA_REPLY; static const uint8_t MAX_COMMAND_SIZE = 9; @@ -28,6 +31,7 @@ namespace IMTQ { static const uint8_t START_ACTUATION_DIPOLE = 0x6; static const uint8_t SOFTWARE_RESET = 0xAA; static const uint8_t GET_ENG_HK_DATA = 0x4A; + static const uint8_t GET_COMMANDED_DIPOLE = 0x46; }; enum IMTQPoolIds: lp_id_t { diff --git a/tmtc b/tmtc index 986f88e2..3e466f06 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 986f88e2908c6bc555a279b53f11e82d9a8a851c +Subproject commit 3e466f06ef7737f2f1bab8c3d68feb633da76dbc From 986ee977216d4f015ea572b1b61bc994777b5223 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Sun, 25 Apr 2021 15:54:48 +0200 Subject: [PATCH 12/16] added wiretapping mode check in handleDeviceTm of PlocHandler --- fsfw | 2 +- fsfw_hal | 2 +- mission/devices/PlocHandler.cpp | 5 +++++ thirdparty/etl | 2 +- tmtc | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fsfw b/fsfw index 42720e6f..e7d24563 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 42720e6f7d64bdd9a1ac0cea5846c9a8cedea0ff +Subproject commit e7d245635047439ca4b5a46d05bf58437a5aa33a diff --git a/fsfw_hal b/fsfw_hal index 14fe3257..a85c0146 160000 --- a/fsfw_hal +++ b/fsfw_hal @@ -1 +1 @@ -Subproject commit 14fe32572d62db9d19707dc1f9bb6fecb1993b73 +Subproject commit a85c01465bc8687773676f05c5e7eb8af54b25ff diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index f1444488..5b106477 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -388,6 +388,11 @@ void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom ReturnValue_t result = RETURN_OK; + if (wiretappingMode == RAW) { + /* Data already sent in doGetRead() */ + return result; + } + DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); if (iter == deviceReplyMap.end()) { sif::debug << "PlocHandler::handleDeviceTM: Unknown reply id" << std::endl; diff --git a/thirdparty/etl b/thirdparty/etl index ae06e641..c308dc42 160000 --- a/thirdparty/etl +++ b/thirdparty/etl @@ -1 +1 @@ -Subproject commit ae06e6417702b770c49289c9e7162cb3f4a5a217 +Subproject commit c308dc427b7a34e54f33860fb2e244564b2740b4 diff --git a/tmtc b/tmtc index 73105138..3e466f06 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 73105138050b5661a6cff76e1d64af40981f9c7f +Subproject commit 3e466f06ef7737f2f1bab8c3d68feb633da76dbc From ad48d5888dc5d41d7ab08160dc42feae2381ba57 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 26 Apr 2021 07:56:02 +0200 Subject: [PATCH 13/16] imqt base functions --- mission/devices/IMTQHandler.cpp | 199 +++++++++++++++--- mission/devices/IMTQHandler.h | 41 ++++ .../IMTQHandlerDefinitions.h | 112 ++++++++-- tmtc | 2 +- 4 files changed, 304 insertions(+), 50 deletions(-) diff --git a/mission/devices/IMTQHandler.cpp b/mission/devices/IMTQHandler.cpp index 80cc1550..f3d1880a 100644 --- a/mission/devices/IMTQHandler.cpp +++ b/mission/devices/IMTQHandler.cpp @@ -6,7 +6,8 @@ #include IMTQHandler::IMTQHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : - DeviceHandlerBase(objectId, comIF, comCookie), engHkDataset(this) { + DeviceHandlerBase(objectId, comIF, comCookie), engHkDataset(this), calMtmMeasurementSet( + this), rawMtmMeasurementSet(this) { if (comCookie == NULL) { sif::error << "IMTQHandler: Invalid com cookie" << std::endl; } @@ -29,7 +30,28 @@ void IMTQHandler::doShutDown(){ ReturnValue_t IMTQHandler::buildNormalDeviceCommand( DeviceCommandId_t * id) { - *id = IMTQ::GET_ENG_HK_DATA; + switch (communicationStep) { + case CommunicationStep::GET_ENG_HK_DATA: + *id = IMTQ::GET_ENG_HK_DATA; + communicationStep = CommunicationStep::START_MTM_MEASUREMENT; + break; + case CommunicationStep::START_MTM_MEASUREMENT: + *id = IMTQ::START_MTM_MEASUREMENT; + communicationStep = CommunicationStep::GET_CAL_MTM_MEASUREMENT; + break; + case CommunicationStep::GET_CAL_MTM_MEASUREMENT: + *id = IMTQ::GET_CAL_MTM_MEASUREMENT; + communicationStep = CommunicationStep::GET_RAW_MTM_MEASUREMENT; + break; + case CommunicationStep::GET_RAW_MTM_MEASUREMENT: + *id = IMTQ::GET_RAW_MTM_MEASUREMENT; + communicationStep = CommunicationStep::GET_ENG_HK_DATA; + break; + default: + sif::debug << "IMTQHandler::buildNormalDeviceCommand: Invalid communication step" + << std::endl; + break; + } return buildCommandFromCommand(*id, NULL, 0); } @@ -69,6 +91,24 @@ ReturnValue_t IMTQHandler::buildCommandFromCommand( rawPacketLen = 1; return RETURN_OK; } + case(IMTQ::START_MTM_MEASUREMENT): { + commandBuffer[0] = IMTQ::CC::START_MTM_MEASUREMENT; + rawPacket = commandBuffer; + rawPacketLen = 1; + return RETURN_OK; + } + case(IMTQ::GET_CAL_MTM_MEASUREMENT): { + commandBuffer[0] = IMTQ::CC::GET_CAL_MTM_MEASUREMENT; + rawPacket = commandBuffer; + rawPacketLen = 1; + return RETURN_OK; + } + case(IMTQ::GET_RAW_MTM_MEASUREMENT): { + commandBuffer[0] = IMTQ::CC::GET_RAW_MTM_MEASUREMENT; + rawPacket = commandBuffer; + rawPacketLen = 1; + return RETURN_OK; + } default: return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } @@ -81,7 +121,13 @@ void IMTQHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(IMTQ::GET_ENG_HK_DATA, 1, &engHkDataset, IMTQ::SIZE_ENG_HK_DATA_REPLY); this->insertInCommandAndReplyMap(IMTQ::GET_COMMANDED_DIPOLE, 1, nullptr, - IMTQ::SIZE_ENG_HK_DATA_REPLY); + IMTQ::SIZE_GET_COMMANDED_DIPOLE_REPLY); + this->insertInCommandAndReplyMap(IMTQ::START_MTM_MEASUREMENT, 1, nullptr, + IMTQ::SIZE_STATUS_REPLY); + this->insertInCommandAndReplyMap(IMTQ::GET_CAL_MTM_MEASUREMENT, 1, &calMtmMeasurementSet, + IMTQ::SIZE_GET_CAL_MTM_MEASUREMENT); + this->insertInCommandAndReplyMap(IMTQ::GET_RAW_MTM_MEASUREMENT, 1, &rawMtmMeasurementSet, + IMTQ::SIZE_GET_RAW_MTM_MEASUREMENT); } ReturnValue_t IMTQHandler::scanForReply(const uint8_t *start, @@ -94,6 +140,10 @@ ReturnValue_t IMTQHandler::scanForReply(const uint8_t *start, *foundLen = IMTQ::SIZE_STATUS_REPLY; *foundId = IMTQ::START_ACTUATION_DIPOLE; break; + case(IMTQ::CC::START_MTM_MEASUREMENT): + *foundLen = IMTQ::SIZE_STATUS_REPLY; + *foundId = IMTQ::START_MTM_MEASUREMENT; + break; case(IMTQ::CC::GET_ENG_HK_DATA): *foundLen = IMTQ::SIZE_ENG_HK_DATA_REPLY; *foundId = IMTQ::GET_ENG_HK_DATA; @@ -102,6 +152,14 @@ ReturnValue_t IMTQHandler::scanForReply(const uint8_t *start, *foundLen = IMTQ::SIZE_GET_COMMANDED_DIPOLE_REPLY; *foundId = IMTQ::GET_COMMANDED_DIPOLE; break; + case(IMTQ::CC::GET_CAL_MTM_MEASUREMENT): + *foundLen = IMTQ::SIZE_GET_CAL_MTM_MEASUREMENT; + *foundId = IMTQ::GET_CAL_MTM_MEASUREMENT; + break; + case(IMTQ::CC::GET_RAW_MTM_MEASUREMENT): + *foundLen = IMTQ::SIZE_GET_RAW_MTM_MEASUREMENT; + *foundId = IMTQ::GET_RAW_MTM_MEASUREMENT; + break; default: sif::debug << "IMTQHandler::scanForReply: Reply contains invalid command code" << std::endl; result = IGNORE_REPLY_DATA; @@ -124,7 +182,8 @@ ReturnValue_t IMTQHandler::interpretDeviceReply(DeviceCommandId_t id, switch (id) { case (IMTQ::START_ACTUATION_DIPOLE): - // Replies only the status byte which is already handled with parseStatusByte + case (IMTQ::START_MTM_MEASUREMENT): + /* Replies only the status byte which is already handled with parseStatusByte */ break; case (IMTQ::GET_ENG_HK_DATA): fillEngHkDataset(packet); @@ -132,6 +191,12 @@ ReturnValue_t IMTQHandler::interpretDeviceReply(DeviceCommandId_t id, case (IMTQ::GET_COMMANDED_DIPOLE): handleGetCommandedDipoleReply(packet); break; + case (IMTQ::GET_CAL_MTM_MEASUREMENT): + fillCalibratedMtmDataset(packet); + break; + case (IMTQ::GET_RAW_MTM_MEASUREMENT): + fillRawMtmDataset(packet); + break; default: { sif::debug << "IMTQHandler::interpretDeviceReply: Unknown device reply id" << std::endl; return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; @@ -152,18 +217,31 @@ uint32_t IMTQHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ ReturnValue_t IMTQHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { + /** Entries of engineering housekeeping dataset */ localDataPoolMap.emplace(IMTQ::DIGITAL_VOLTAGE_MV, new PoolEntry( { 0 })); localDataPoolMap.emplace(IMTQ::ANALOG_VOLTAGE_MV, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::DIGITAL_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::ANALOG_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_X_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Y_CURRENT_A, new PoolEntry( { 0 })); - localDataPoolMap.emplace(IMTQ::COIL_Z_CURRENT_A, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::DIGITAL_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ANALOG_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_X_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Y_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::COIL_Z_CURRENT, new PoolEntry( { 0 })); localDataPoolMap.emplace(IMTQ::COIL_X_TEMPERATURE, new PoolEntry( { 0 })); localDataPoolMap.emplace(IMTQ::COIL_Y_TEMPERATURE, new PoolEntry( { 0 })); localDataPoolMap.emplace(IMTQ::COIL_Z_TEMPERATURE, new PoolEntry( { 0 })); localDataPoolMap.emplace(IMTQ::MCU_TEMPERATURE, new PoolEntry( { 0 })); + /** Entries of calibrated MTM measurement dataset */ + localDataPoolMap.emplace(IMTQ::MTM_CAL_X, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::MTM_CAL_Y, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::MTM_CAL_Z, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ACTUATION_CAL_STATUS, new PoolEntry( { 0 })); + + /** Entries of raw MTM measurement dataset */ + localDataPoolMap.emplace(IMTQ::MTM_RAW_X, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::MTM_RAW_Y, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::MTM_RAW_Z, new PoolEntry( { 0 })); + localDataPoolMap.emplace(IMTQ::ACTUATION_RAW_STATUS, new PoolEntry( { 0 })); + return HasReturnvaluesIF::RETURN_OK; } @@ -200,36 +278,36 @@ ReturnValue_t IMTQHandler::parseStatusByte(const uint8_t* packet) { void IMTQHandler::fillEngHkDataset(const uint8_t* packet) { uint8_t offset = 2; - engHkDataset.digitalVoltageMv = *(packet + offset + 1) | *(packet + offset); + engHkDataset.digitalVoltageMv = *(packet + offset + 1) << 8 | *(packet + offset); offset += 2; - engHkDataset.analogVoltageMv = *(packet + offset + 1) | *(packet + offset); + engHkDataset.analogVoltageMv = *(packet + offset + 1) << 8 | *(packet + offset); offset += 2; - engHkDataset.digitalCurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + engHkDataset.digitalCurrentmA = (*(packet + offset + 1) << 8 | *(packet + offset)) * 0.1; offset += 2; - engHkDataset.analogCurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + engHkDataset.analogCurrentmA = (*(packet + offset + 1) << 8 | *(packet + offset)) * 0.1; offset += 2; - engHkDataset.coilXcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + engHkDataset.coilXCurrentmA = (*(packet + offset + 1) << 8 | *(packet + offset)) * 0.1; offset += 2; - engHkDataset.coilYcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + engHkDataset.coilYCurrentmA = (*(packet + offset + 1) << 8 | *(packet + offset)) * 0.1; offset += 2; - engHkDataset.coilZcurrentA = (*(packet + offset + 1) | *(packet + offset)) * 0.0001; + engHkDataset.coilZCurrentmA = (*(packet + offset + 1) << 8 | *(packet + offset)) * 0.1; offset += 2; - engHkDataset.coilXTemperature = (*(packet + offset + 1) | *(packet + offset)); + engHkDataset.coilXTemperature = (*(packet + offset + 1) << 8 | *(packet + offset)); offset += 2; - engHkDataset.coilYTemperature = (*(packet + offset + 1) | *(packet + offset)); + engHkDataset.coilYTemperature = (*(packet + offset + 1) << 8 | *(packet + offset)); offset += 2; - engHkDataset.coilZTemperature = (*(packet + offset + 1) | *(packet + offset)); + engHkDataset.coilZTemperature = (*(packet + offset + 1) << 8 | *(packet + offset)); offset += 2; - engHkDataset.mcuTemperature = (*(packet + offset + 1) | *(packet + offset)); + engHkDataset.mcuTemperature = (*(packet + offset + 1) << 8 | *(packet + offset)); #if OBSW_VERBOSE_LEVEL >= 1 && IMQT_DEBUG == 1 sif::info << "IMTQ digital voltage: " << engHkDataset.digitalVoltageMv << " mV" << std::endl; sif::info << "IMTQ analog voltage: " << engHkDataset.analogVoltageMv << " mV" << std::endl; - sif::info << "IMTQ digital current: " << engHkDataset.digitalCurrentA << " A" << std::endl; - sif::info << "IMTQ analog current: " << engHkDataset.analogCurrentA << " A" << std::endl; - sif::info << "IMTQ coil X current: " << engHkDataset.coilXcurrentA << " A" << std::endl; - sif::info << "IMTQ coil Y current: " << engHkDataset.coilYcurrentA << " A" << std::endl; - sif::info << "IMTQ coil Z current: " << engHkDataset.coilZcurrentA << " A" << std::endl; + sif::info << "IMTQ digital current: " << engHkDataset.digitalCurrentmA << " mA" << std::endl; + sif::info << "IMTQ analog current: " << engHkDataset.analogCurrentmA << " mA" << std::endl; + sif::info << "IMTQ coil X current: " << engHkDataset.coilXCurrentmA << " mA" << std::endl; + sif::info << "IMTQ coil Y current: " << engHkDataset.coilYCurrentmA << " mA" << std::endl; + sif::info << "IMTQ coil Z current: " << engHkDataset.coilZCurrentmA << " mA" << std::endl; sif::info << "IMTQ coil X temperature: " << engHkDataset.coilXTemperature << " °C" << std::endl; sif::info << "IMTQ coil Y temperature: " << engHkDataset.coilYTemperature << " °C" @@ -245,15 +323,11 @@ void IMTQHandler::setModeNormal() { mode = MODE_NORMAL; } - - void IMTQHandler::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 result; + return; } DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); @@ -267,8 +341,71 @@ void IMTQHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom return; } - result = actionHelper.reportData(queueId, replyId, data, dataSize); + ReturnValue_t result = actionHelper.reportData(queueId, replyId, data, dataSize); if (result != RETURN_OK) { sif::debug << "IMTQHandler::handleDeviceTM: Failed to report data" << std::endl; + return; } } + +void IMTQHandler::handleGetCommandedDipoleReply(const uint8_t* packet) { + uint8_t tmData[6]; + /* Switching endianess of received dipole values */ + tmData[0] = *(packet + 3); + tmData[1] = *(packet + 2); + tmData[2] = *(packet + 5); + tmData[3] = *(packet + 4); + tmData[4] = *(packet + 7); + tmData[5] = *(packet + 6); + handleDeviceTM(tmData, sizeof(tmData), IMTQ::GET_COMMANDED_DIPOLE); +} + +void IMTQHandler::fillCalibratedMtmDataset(const uint8_t* packet) { + int8_t offset = 2; + calMtmMeasurementSet.mtmXnT = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 + | *(packet + offset + 1) << 8 | *(packet + offset); + offset += 4; + calMtmMeasurementSet.mtmYnT = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 + | *(packet + offset + 1) << 8 | *(packet + offset); + offset += 4; + calMtmMeasurementSet.mtmZnT = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 + | *(packet + offset + 1) << 8 | *(packet + offset); + offset += 4; + calMtmMeasurementSet.coilActuationStatus = (*(packet + offset + 3) << 24) + | (*(packet + offset + 2) << 16) | (*(packet + offset + 1) << 8) | (*(packet + offset)); +#if OBSW_VERBOSE_LEVEL >= 1 && IMQT_DEBUG == 1 + sif::info << "IMTQ calibrated MTM measurement X: " << calMtmMeasurementSet.mtmXnT << " nT" + << std::endl; + sif::info << "IMTQ calibrated MTM measurement Y: " << calMtmMeasurementSet.mtmYnT << " nT" + << std::endl; + sif::info << "IMTQ calibrated MTM measurement Z: " << calMtmMeasurementSet.mtmZnT << " nT" + << std::endl; + sif::info << "IMTQ coil actuation status during MTM measurement: " + << (unsigned int) calMtmMeasurementSet.coilActuationStatus.value << std::endl; +#endif +} + +void IMTQHandler::fillRawMtmDataset(const uint8_t* packet) { + int8_t offset = 2; + rawMtmMeasurementSet.mtmXnT = (*(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 + | *(packet + offset + 1) << 8 | *(packet + offset)) * 7.5; + offset += 4; + rawMtmMeasurementSet.mtmYnT = (*(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 + | *(packet + offset + 1) << 8 | *(packet + offset)) * 7.5; + offset += 4; + rawMtmMeasurementSet.mtmZnT = (*(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 + | *(packet + offset + 1) << 8 | *(packet + offset)) * 7.5; + offset += 4; + rawMtmMeasurementSet.coilActuationStatus = (*(packet + offset + 3) << 24) + | (*(packet + offset + 2) << 16) | (*(packet + offset + 1) << 8) | (*(packet + offset)); +#if OBSW_VERBOSE_LEVEL >= 1 && IMQT_DEBUG == 1 + sif::info << "IMTQ raw MTM measurement X: " << rawMtmMeasurementSet.mtmXnT << " nT" + << std::endl; + sif::info << "IMTQ raw MTM measurement Y: " << rawMtmMeasurementSet.mtmYnT << " nT" + << std::endl; + sif::info << "IMTQ raw MTM measurement Z: " << rawMtmMeasurementSet.mtmZnT << " nT" + << std::endl; + sif::info << "IMTQ coil actuation status during MTM measurement: " + << (unsigned int) rawMtmMeasurementSet.coilActuationStatus.value << std::endl; +#endif +} diff --git a/mission/devices/IMTQHandler.h b/mission/devices/IMTQHandler.h index 2e2a7612..be680560 100644 --- a/mission/devices/IMTQHandler.h +++ b/mission/devices/IMTQHandler.h @@ -52,9 +52,20 @@ private: IMTQ::EngHkDataset engHkDataset; + IMTQ::CalibratedMtmMeasurementSet calMtmMeasurementSet; + IMTQ::RawMtmMeasurementSet rawMtmMeasurementSet; uint8_t commandBuffer[IMTQ::MAX_COMMAND_SIZE]; + enum class CommunicationStep { + GET_ENG_HK_DATA, + START_MTM_MEASUREMENT, + GET_CAL_MTM_MEASUREMENT, + GET_RAW_MTM_MEASUREMENT + }; + + CommunicationStep communicationStep = CommunicationStep::GET_ENG_HK_DATA; + /** * @brief Each reply contains a status byte giving information about a request. This function * parses this byte and returns the associated failure message. @@ -72,6 +83,36 @@ private: * */ void fillEngHkDataset(const uint8_t* packet); + + /** + * @brief This function sends a command reply to the requesting queue. + * + * @param data Pointer to the data to send. + * @param dataSize Size of the data to send. + * @param relplyId Reply id which will be inserted at the beginning of the action message. + */ + void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId); + + /** + * @brief This function handles the reply containing the commanded dipole. + * + * @param packet Pointer to the reply data. + */ + void handleGetCommandedDipoleReply(const uint8_t* packet); + + /** + * @brief This function parses the reply containing the calibrated MTM measurement and writes + * the values to the appropriate dataset. + * @param packet Pointer to the reply data. + */ + void fillCalibratedMtmDataset(const uint8_t* packet); + + /** + * @brief This function copies the raw MTM measurements to the MTM raw dataset. + * @param packet Pointer to the reply data requested with the GET_RAW_MTM_MEASUREMENTS + * command. + */ + void fillRawMtmDataset(const uint8_t* packet); }; #endif /* MISSION_DEVICES_IMTQHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h index 60bd511e..23b5982a 100644 --- a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h +++ b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h @@ -7,49 +7,71 @@ namespace IMTQ { static const DeviceCommandId_t GET_ENG_HK_DATA = 0x1; static const DeviceCommandId_t START_ACTUATION_DIPOLE = 0x2; static const DeviceCommandId_t GET_COMMANDED_DIPOLE = 0x3; + /** Generates new measurement of the magnetic field */ + static const DeviceCommandId_t START_MTM_MEASUREMENT = 0x4; + /** Requests the calibrated magnetometer measurement */ + static const DeviceCommandId_t GET_CAL_MTM_MEASUREMENT = 0x5; + /** Requests the raw values measured by the built-in MTM XEN1210 */ + static const DeviceCommandId_t GET_RAW_MTM_MEASUREMENT = 0x6; static const uint8_t GET_TEMP_REPLY_SIZE = 2; static const uint8_t CFGR_CMD_SIZE = 3; static const uint8_t POINTER_REG_SIZE = 1; static const uint32_t ENG_HK_DATA_SET_ID = GET_ENG_HK_DATA; + static const uint32_t CAL_MTM_SET = GET_CAL_MTM_MEASUREMENT; + static const uint8_t SIZE_ENG_HK_COMMAND = 1; static const uint8_t SIZE_STATUS_REPLY = 2; static const uint8_t SIZE_ENG_HK_DATA_REPLY = 24; static const uint8_t SIZE_GET_COMMANDED_DIPOLE_REPLY = 8; + static const uint8_t SIZE_GET_CAL_MTM_MEASUREMENT = 15; + static const uint8_t SIZE_GET_RAW_MTM_MEASUREMENT = 15; static const uint8_t MAX_REPLY_SIZE = SIZE_ENG_HK_DATA_REPLY; static const uint8_t MAX_COMMAND_SIZE = 9; - static const uint8_t POOL_ENTRIES = 11; + static const uint8_t ENG_HK_SET_POOL_ENTRIES = 11; + static const uint8_t CAL_MTM_POOL_ENTRIES = 4; /** * Command code definitions. Each command or reply of an IMTQ request will begin with one of * the following command codes. */ namespace CC { + static const uint8_t START_MTM_MEASUREMENT = 0x4; static const uint8_t START_ACTUATION_DIPOLE = 0x6; static const uint8_t SOFTWARE_RESET = 0xAA; static const uint8_t GET_ENG_HK_DATA = 0x4A; static const uint8_t GET_COMMANDED_DIPOLE = 0x46; + static const uint8_t GET_RAW_MTM_MEASUREMENT = 0x42; + static const uint8_t GET_CAL_MTM_MEASUREMENT = 0x43; }; enum IMTQPoolIds: lp_id_t { DIGITAL_VOLTAGE_MV, ANALOG_VOLTAGE_MV, - DIGITAL_CURRENT_A, - ANALOG_CURRENT_A, - COIL_X_CURRENT_A, - COIL_Y_CURRENT_A, - COIL_Z_CURRENT_A, + DIGITAL_CURRENT, + ANALOG_CURRENT, + COIL_X_CURRENT, + COIL_Y_CURRENT, + COIL_Z_CURRENT, COIL_X_TEMPERATURE, COIL_Y_TEMPERATURE, COIL_Z_TEMPERATURE, - MCU_TEMPERATURE + MCU_TEMPERATURE, + MTM_CAL_X, + MTM_CAL_Y, + MTM_CAL_Z, + ACTUATION_CAL_STATUS, + MTM_RAW_X, + MTM_RAW_Y, + MTM_RAW_Z, + ACTUATION_RAW_STATUS }; class EngHkDataset: - public StaticLocalDataSet { + public StaticLocalDataSet { public: EngHkDataset(HasLocalDataPoolIF* owner): @@ -64,16 +86,16 @@ public: DIGITAL_VOLTAGE_MV, this); lp_var_t analogVoltageMv = lp_var_t(sid.objectId, ANALOG_VOLTAGE_MV, this); - lp_var_t digitalCurrentA = lp_var_t(sid.objectId, - DIGITAL_CURRENT_A, this); - lp_var_t analogCurrentA = lp_var_t(sid.objectId, - ANALOG_CURRENT_A, this); - lp_var_t coilXcurrentA = lp_var_t(sid.objectId, - COIL_X_CURRENT_A, this); - lp_var_t coilYcurrentA = lp_var_t(sid.objectId, - COIL_Y_CURRENT_A, this); - lp_var_t coilZcurrentA = lp_var_t(sid.objectId, - COIL_Z_CURRENT_A, this); + lp_var_t digitalCurrentmA = lp_var_t(sid.objectId, + DIGITAL_CURRENT, this); + lp_var_t analogCurrentmA = lp_var_t(sid.objectId, + ANALOG_CURRENT, this); + lp_var_t coilXCurrentmA = lp_var_t(sid.objectId, + COIL_X_CURRENT, this); + lp_var_t coilYCurrentmA = lp_var_t(sid.objectId, + COIL_Y_CURRENT, this); + lp_var_t coilZCurrentmA = lp_var_t(sid.objectId, + COIL_Z_CURRENT, this); /** All temperatures in [°C] */ lp_var_t coilXTemperature = lp_var_t(sid.objectId, COIL_X_TEMPERATURE, this); @@ -85,6 +107,60 @@ public: MCU_TEMPERATURE, this); }; +/** + * @brief This dataset holds the raw MTM measurements. + */ +class CalibratedMtmMeasurementSet: + public StaticLocalDataSet { +public: + + CalibratedMtmMeasurementSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, CAL_MTM_SET) { + } + + CalibratedMtmMeasurementSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, CAL_MTM_SET)) { + } + + /** The unit of all measurements is nT */ + lp_var_t mtmXnT = lp_var_t(sid.objectId, + MTM_CAL_X, this); + lp_var_t mtmYnT = lp_var_t(sid.objectId, + MTM_CAL_Y, this); + lp_var_t mtmZnT = lp_var_t(sid.objectId, + MTM_CAL_Z, this); + /** 1 if coils were actuating during measurement otherwise 0 */ + lp_var_t coilActuationStatus = lp_var_t(sid.objectId, + ACTUATION_CAL_STATUS, this); +}; + +/** + * @brief This dataset holds the last calibrated MTM measurement. + */ +class RawMtmMeasurementSet: + public StaticLocalDataSet { +public: + + RawMtmMeasurementSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, CAL_MTM_SET) { + } + + RawMtmMeasurementSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, CAL_MTM_SET)) { + } + + /** The unit of all measurements is nT */ + lp_var_t mtmXnT = lp_var_t(sid.objectId, + MTM_RAW_X, this); + lp_var_t mtmYnT = lp_var_t(sid.objectId, + MTM_RAW_Y, this); + lp_var_t mtmZnT = lp_var_t(sid.objectId, + MTM_RAW_Z, this); + /** 1 if coils were actuating during measurement otherwise 0 */ + lp_var_t coilActuationStatus = lp_var_t(sid.objectId, + ACTUATION_RAW_STATUS, this); +}; + /** * @brief This class can be used to ease the generation of an action message commanding the * IMTQHandler to configure the magnettorquer with the desired dipoles. diff --git a/tmtc b/tmtc index 3e466f06..4d2b7a61 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3e466f06ef7737f2f1bab8c3d68feb633da76dbc +Subproject commit 4d2b7a61509a41e67cf62ecaa2864bba3acd9ef4 From cdde3e29a8a807dae6cedc62324f6f94cbe444b8 Mon Sep 17 00:00:00 2001 From: IRS Cleanroom Laptop Date: Mon, 26 Apr 2021 11:28:19 +0200 Subject: [PATCH 14/16] corrections in plocHandler, endianness --- .../Q7S/win_path_helper_xilinx_tools.sh | 10 +++++-- fsfw_hal | 2 +- mission/devices/PlocHandler.cpp | 19 ++++++++++-- mission/devices/PlocHandler.h | 5 ++++ .../devicedefinitions/PlocDefinitions.h | 29 +++++++++---------- tmtc | 2 +- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh b/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh index c9bcc54a..d0a24dba 100644 --- a/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh +++ b/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh @@ -1,5 +1,9 @@ #!/bin/sh -export PATH=$PATH:"/c/Xilinx/SDK/2018.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" -export CROSS_COMPILE="arm-linux-gnueabihf" +export PATH=/c/Users/integration/Documents/EIVE/gcc-arm-linux-gnueabi/bin:${PATH} +export CROSS_COMPILE=arm-linux-gnueabihf -export Q7S_SYSROOT="/c/Xilinx/SDK/2018.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc" +export CMAKE_ASM_COMPILER=arm-linux-gnueabihf-as +export CMAKE_C_COMPILER=arm-linux-gnueabihf-gcc +export CMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ + +export Q7S_SYSROOT=/c/Users/integration/Documents/EIVE/cortexa9hf-neon-xiphos-linux-gnueabi diff --git a/fsfw_hal b/fsfw_hal index 7a3190e5..c47d3996 160000 --- a/fsfw_hal +++ b/fsfw_hal @@ -1 +1 @@ -Subproject commit 7a3190e5b6980ad2addc5e8a76d21994b542f0e0 +Subproject commit c47d39964fcdc08f6ab93a5e6b6e3b63d4a21abb diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index f1444488..427eac4c 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -151,7 +151,10 @@ ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData, | *(commandData + 2) << 8 | *(commandData + 3); const uint32_t memoryData = *(commandData + 4) << 24 | *(commandData + 5) << 16 | *(commandData + 6) << 8 | *(commandData + 7); - PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData); + if (subsequenceCount != 0) { + subsequenceCount++; + } + PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData, subsequenceCount); if (tcMemWrite.getFullSize() > PLOC::MAX_COMMAND_SIZE) { sif::debug << "PlocHandler::prepareTcMemWriteCommand: Command too big" << std::endl; return RETURN_FAILED; @@ -167,7 +170,10 @@ ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData, size_t commandDataLen) { const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 | *(commandData + 3); - PLOC::TcMemRead tcMemRead(memoryAddress); + if (subsequenceCount != 0) { + subsequenceCount++; + } + PLOC::TcMemRead tcMemRead(memoryAddress, subsequenceCount); if (tcMemRead.getFullSize() > PLOC::MAX_COMMAND_SIZE) { sif::debug << "PlocHandler::prepareTcMemReadCommand: Command too big" << std::endl; return RETURN_FAILED; @@ -176,6 +182,7 @@ ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData, rawPacket = commandBuffer; rawPacketLen = tcMemRead.getFullSize(); nextReplyId = PLOC::ACK_REPORT; + return RETURN_OK; } @@ -183,7 +190,7 @@ ReturnValue_t PlocHandler::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, 0); + uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2); if (receivedCrc != recalculatedCrc) { return CRC_FAILURE; @@ -221,10 +228,12 @@ ReturnValue_t PlocHandler::handleAckReport(const uint8_t* data) { disableAllReplies(); nextReplyId = PLOC::NONE; result = IGNORE_REPLY_DATA; + subsequenceCount = ((*(data + 2) & 0x3F) << 8) | *(data + 3); break; } case PLOC::APID_ACK_SUCCESS: { setNextReplyId(); + subsequenceCount = ((*(data + 2) & 0x3F) << 8) | *(data + 3); break; } default: { @@ -252,6 +261,7 @@ ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* data) { switch (apid) { case (PLOC::APID_EXE_SUCCESS): { + subsequenceCount = ((*(data + 2) & 0x3F) << 8) | *(data + 3); break; } case (PLOC::APID_EXE_FAILURE): { @@ -268,6 +278,7 @@ ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* data) { sendFailureReport(PLOC::EXE_REPORT, RECEIVED_EXE_FAILURE); disableExeReportReply(); result = IGNORE_REPLY_DATA; + subsequenceCount = ((*(data + 2) & 0x3F) << 8) | *(data + 3); break; } default: { @@ -298,6 +309,8 @@ ReturnValue_t PlocHandler::handleMemoryReadReport(const uint8_t* data) { nextReplyId = PLOC::EXE_REPORT; + subsequenceCount = ((*(data + 2) & 0x3F) << 8) | *(data + 3); + return result; } diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index b241c838..fcb423d3 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -65,6 +65,11 @@ private: uint8_t commandBuffer[PLOC::MAX_COMMAND_SIZE]; + /** + * This object counts takes the subsequence count of the PLOC space packets. + */ + uint16_t subsequenceCount = 0; + /** * 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 diff --git a/mission/devices/devicedefinitions/PlocDefinitions.h b/mission/devices/devicedefinitions/PlocDefinitions.h index b7378a8a..f5add451 100644 --- a/mission/devices/devicedefinitions/PlocDefinitions.h +++ b/mission/devices/devicedefinitions/PlocDefinitions.h @@ -63,10 +63,10 @@ namespace PLOC { * * @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); - } + TcMemRead(const uint32_t memAddr, uint16_t sequenceCount) : + SpacePacket(LENGTH_TC_MEM_READ - 1, true, APID_TC_MEM_READ, sequenceCount) { + fillPacketDataField(&memAddr); + } private: @@ -80,22 +80,21 @@ namespace PLOC { size_t serializedSize = 0; uint8_t* memoryAddressPos = this->localData.fields.buffer; SerializeAdapter::serialize(memAddrPtr, &memoryAddressPos, &serializedSize, - sizeof(*memAddrPtr), SerializeIF::Endianness::BIG); + sizeof(*memAddrPtr), SerializeIF::Endianness::LITTLE); /* 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; + 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, 0); + 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(&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; @@ -117,9 +116,10 @@ namespace PLOC { * * @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) : - SpacePacket(LENGTH_TC_MEM_WRITE - 1, true, APID_TC_MEM_WRITE) { + 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); } @@ -140,8 +140,8 @@ namespace PLOC { 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; + 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; @@ -151,14 +151,13 @@ namespace PLOC { /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + LENGTH_TC_MEM_WRITE - CRC_SIZE, 0); + 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(&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 */ diff --git a/tmtc b/tmtc index 79e897b0..b464648f 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 79e897b0353acacf0f986f22f57e9cd8cf30a0da +Subproject commit b464648f53b8b9b41f1ee00c94c095c55ee673e1 From 4e8a6b65ec7cf1e199fbf3b16f03dff4cebd6f8e Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 26 Apr 2021 14:25:23 +0200 Subject: [PATCH 15/16] self test wip --- mission/devices/IMTQHandler.cpp | 5 +++++ mission/devices/IMTQHandler.h | 1 + mission/devices/devicedefinitions/IMTQHandlerDefinitions.h | 1 + 3 files changed, 7 insertions(+) diff --git a/mission/devices/IMTQHandler.cpp b/mission/devices/IMTQHandler.cpp index f3d1880a..0e92a6c1 100644 --- a/mission/devices/IMTQHandler.cpp +++ b/mission/devices/IMTQHandler.cpp @@ -21,6 +21,7 @@ void IMTQHandler::doStartUp(){ if(mode == _MODE_START_UP){ //TODO: Set to MODE_ON again setMode(MODE_NORMAL); + communicationStep = CommunicationStep::SELT_TEST; } } @@ -31,6 +32,10 @@ void IMTQHandler::doShutDown(){ ReturnValue_t IMTQHandler::buildNormalDeviceCommand( DeviceCommandId_t * id) { switch (communicationStep) { + case CommunicationStep::SELF_TEST: + *id = IMTQ::SELF_TEST; + communicationStep = CommunicationStep::GET_ENG_HK_DATA; + break; case CommunicationStep::GET_ENG_HK_DATA: *id = IMTQ::GET_ENG_HK_DATA; communicationStep = CommunicationStep::START_MTM_MEASUREMENT; diff --git a/mission/devices/IMTQHandler.h b/mission/devices/IMTQHandler.h index be680560..e162c1c6 100644 --- a/mission/devices/IMTQHandler.h +++ b/mission/devices/IMTQHandler.h @@ -58,6 +58,7 @@ private: uint8_t commandBuffer[IMTQ::MAX_COMMAND_SIZE]; enum class CommunicationStep { + SELF_TEST, GET_ENG_HK_DATA, START_MTM_MEASUREMENT, GET_CAL_MTM_MEASUREMENT, diff --git a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h index 23b5982a..0cbbb04e 100644 --- a/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h +++ b/mission/devices/devicedefinitions/IMTQHandlerDefinitions.h @@ -13,6 +13,7 @@ namespace IMTQ { static const DeviceCommandId_t GET_CAL_MTM_MEASUREMENT = 0x5; /** Requests the raw values measured by the built-in MTM XEN1210 */ static const DeviceCommandId_t GET_RAW_MTM_MEASUREMENT = 0x6; + static const DeviceCommandId_t SELF_TEST = 0x7; static const uint8_t GET_TEMP_REPLY_SIZE = 2; static const uint8_t CFGR_CMD_SIZE = 3; From ea2b1fbda487e5ca6f5d32660475ea59f73b0e02 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Tue, 27 Apr 2021 17:34:50 +0200 Subject: [PATCH 16/16] basic structure for ILH PLOC control --- bsp_q7s/ObjectFactory.cpp | 15 +++++++++------ fsfwconfig/OBSWConfig.h | 3 ++- mission/devices/PlocHandler.cpp | 17 ++++++++++------- mission/devices/PlocHandler.h | 20 ++++++++++++-------- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 9102f79e..0815b81d 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -433,12 +433,6 @@ void ObjectFactory::produce(){ gpioCookie->addGpio(gpioIds::TEST_ID_0, gpioConfigMio0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #elif TE0720 == 1 - /* Configuration for MIO0 on TE0720-03-1CFA */ - GpiodRegular* heaterGpio = new GpiodRegular(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); - GpioCookie* gpioCookie = new GpioCookie; - gpioCookie->addGpio(gpioIds::HEATER_0, heaterGpio); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, - pcduSwitches::TCS_BOARD_8V_HEATER_IN); UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, PLOC::MAX_REPLY_SIZE); @@ -448,6 +442,15 @@ void ObjectFactory::produce(){ plocHandler->setStartUpImmediately(); #endif +#if TE0720 == 1 && TE0720_HEATER_TEST == 1 + /* Configuration for MIO0 on TE0720-03-1CFA */ + GpiodRegular* heaterGpio = new GpiodRegular(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); + GpioCookie* gpioCookie = new GpioCookie; + gpioCookie->addGpio(gpioIds::HEATER_0, heaterGpio); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, + pcduSwitches::TCS_BOARD_8V_HEATER_IN); +#endif + #if Q7S_ADD_SPI_TEST == 1 new SpiTestClass(objects::SPI_TEST, gpioComIF); #endif diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index f3f7cda3..c1a6c313 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -21,7 +21,8 @@ debugging. */ #define OBSW_ADD_TEST_CODE 1 #define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 1 +#define TE0720_HEATER_TEST 0 #define P60DOCK_DEBUG 0 #define PDU1_DEBUG 0 diff --git a/mission/devices/PlocHandler.cpp b/mission/devices/PlocHandler.cpp index d8ed395e..b0660ba0 100644 --- a/mission/devices/PlocHandler.cpp +++ b/mission/devices/PlocHandler.cpp @@ -156,6 +156,7 @@ ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData, | *(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::TcMemWrite tcMemWrite(memoryAddress, memoryData, packetSequenceCount); if (tcMemWrite.getFullSize() > PLOC::MAX_COMMAND_SIZE) { sif::debug << "PlocHandler::prepareTcMemWriteCommand: Command too big" << std::endl; @@ -172,6 +173,7 @@ ReturnValue_t PlocHandler::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::TcMemRead tcMemRead(memoryAddress, packetSequenceCount); if (tcMemRead.getFullSize() > PLOC::MAX_COMMAND_SIZE) { sif::debug << "PlocHandler::prepareTcMemReadCommand: Command too big" << std::endl; @@ -482,14 +484,15 @@ void PlocHandler::disableExeReportReply() { } ReturnValue_t PlocHandler::checkPacketSequenceCount(const uint8_t* data) { - uint16_t receivedSequenceCount = *(data + 2) << 8 | *(data + 3) & PACKET_SEQUENCE_COUNT_MASK; - if (receivedSequenceCount != ((packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK)) { - sif::debug << "PlocHandler::checkPacketSequenceCount: Packet sequence count mismatch" + 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 + << "PlocHandler::checkPacketSequenceCount: Packet sequence count mismatch. " << std::endl; - /** The packet sequence count is corrected here to match the sequence count of the PLOC */ - packetSequenceCount = (receivedSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK; - return SUBSEQUENCE_COUNT_FAILURE; + sif::debug << "Received sequence count: " << receivedSequenceCount << ". OBSW sequence " + << "count: " << expectedPacketSequenceCount << std::endl; } - packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK; + packetSequenceCount = receivedSequenceCount; return RETURN_OK; } diff --git a/mission/devices/PlocHandler.h b/mission/devices/PlocHandler.h index 1b529484..06965d0f 100644 --- a/mission/devices/PlocHandler.h +++ b/mission/devices/PlocHandler.h @@ -8,8 +8,8 @@ /** * @brief This is the device handler for the PLOC. * - * @details The PLOC uses the space packet protocol for communication. On each command the PLOC - * answers at least with one acknowledgment and one execution report. + * @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. * * @author J. Meier */ @@ -53,7 +53,6 @@ private: static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1); //!> Received ACK failure reply from PLOC static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2); //!> Received execution failure reply from PLOC static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3); //!> Received space packet with invalid APID from PLOC - static const ReturnValue_t SUBSEQUENCE_COUNT_FAILURE = MAKE_RETURN_CODE(0xA4); //!> The packet sequence count does not match the expected packet sequence count. There may be one packet lost. static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_HANDLER; @@ -63,7 +62,7 @@ private: static const Event CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW); //!> PLOC reply has invalid crc static const uint16_t APID_MASK = 0x7FF; - static const unit16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF; + static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF; uint8_t commandBuffer[PLOC::MAX_COMMAND_SIZE]; @@ -184,14 +183,19 @@ private: void disableExeReportReply(); /** - * @brief This function checks the subsequence count of a received space packet to detect - * lost packets. + * @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, else SUBSEQUENCE_COUNT_FAILURE + * @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 checkSubsequenceCount(const uint8_t* data); + ReturnValue_t checkPacketSequenceCount(const uint8_t* data); }; #endif /* MISSION_DEVICES_PLOCHANDLER_H_ */