From f2cb43a52fb91f13c20e8b30887eb33af4f207d5 Mon Sep 17 00:00:00 2001 From: Irini Kosmidou Date: Fri, 29 Apr 2022 15:46:16 +0200 Subject: [PATCH] scexDataHandler --- common/config/commonSubsystemIds.h | 1 + linux/boardtest/UartTestClass.cpp | 15 +- linux/boardtest/UartTestClass.h | 6 +- linux/devices/ScexHelper.cpp | 6 +- linux/devices/ScexHelper.h | 7 +- mission/devices/CMakeLists.txt | 1 + mission/devices/ScexDeviceHandler.cpp | 128 ++++++++++++++++++ mission/devices/ScexDeviceHandler.h | 36 +++++ .../devicedefinitions/ScexDefinitions.cpp | 33 ++++- .../devicedefinitions/ScexDefinitions.h | 33 ++++- 10 files changed, 246 insertions(+), 20 deletions(-) create mode 100644 mission/devices/ScexDeviceHandler.cpp create mode 100644 mission/devices/ScexDeviceHandler.h diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index cd692231..c19a4d0c 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -30,6 +30,7 @@ enum: uint8_t { PDU1_HANDLER = 133, PDU2_HANDLER = 134, ACU_HANDLER = 135, + SCEX_HANDLER = 136, COMMON_SUBSYSTEM_ID_END }; } diff --git a/linux/boardtest/UartTestClass.cpp b/linux/boardtest/UartTestClass.cpp index b958579a..469081cd 100644 --- a/linux/boardtest/UartTestClass.cpp +++ b/linux/boardtest/UartTestClass.cpp @@ -17,6 +17,7 @@ #include "fsfw/globalfunctions/DleEncoder.h" #include "fsfw/globalfunctions/arrayprinter.h" #include "fsfw/serviceinterface.h" +#include "mission/devices/devicedefinitions/ScexDefinitions.h" #define GPS_REPLY_WIRETAPPING 0 @@ -28,7 +29,7 @@ UartTestClass::UartTestClass(object_id_t objectId, ScexUartReader* reader) : TestTask(objectId), reader(reader) { mode = TestModes::SCEX; scexMode = ScexModes::READER_TASK; - currCmd = scex::ScexCmds::FRAM; + currCmd = scex::Cmds::FRAM; if (scexMode == ScexModes::SIMPLE) { auto encodingBuf = new std::array; DleParser::BufPair encodingBufPair{encodingBuf->data(), encodingBuf->size()}; @@ -219,7 +220,7 @@ void UartTestClass::scexPeriodic() { // helper.getTotalPacketCounter()) { nach 2min reader->finish(); if (helper.getCmd() == FRAM) { if (not fileNameSet) { - fileId = random_string(12); + fileId = random_string(6); fileName = "/tmp/scex-fram_" + fileId + ".bin"; fileNameSet = true; } @@ -235,8 +236,9 @@ void UartTestClass::scexPeriodic() { } if (finishCountdown.hasTimedOut()) { + triggerEvent(scex::EXPERIMENT_TIMEDOUT, currCmd, 0); reader->finish(); - sif::warning << "Reader countdown expired" << endl; + sif::warning << "Reader timeout" << endl; cmdDone = true; fileNameSet = false; } @@ -247,7 +249,7 @@ void UartTestClass::scexPeriodic() { sif::info << "Reader is finished" << endl; cmdDone = true; fileNameSet = false; - if (helper.getCmd() == scex::ScexCmds::PING) { + if (helper.getCmd() == scex::Cmds::PING) { cmdSent = false; fileNameSet = true; // to not generate everytime new file } @@ -344,7 +346,7 @@ void UartTestClass::scexSimplePeriodic() { << bytesRead << std::endl; } else if (bytesRead > 0) { dleParser->passData(recBuf.data(), bytesRead); - if (currCmd == ScexCmds::PING) { + if (currCmd == Cmds::PING) { cmdDone = true; cmdSent = false; } @@ -353,8 +355,7 @@ void UartTestClass::scexSimplePeriodic() { } } -int UartTestClass::prepareScexCmd(scex::ScexCmds cmd, bool tempCheck, uint8_t* cmdBuf, - size_t* len) { +int UartTestClass::prepareScexCmd(scex::Cmds cmd, bool tempCheck, uint8_t* cmdBuf, size_t* len) { using namespace scex; // Send command cmdBuf[0] = scex::createCmdByte(cmd, false); diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h index ca42a688..efe15dc1 100644 --- a/linux/boardtest/UartTestClass.h +++ b/linux/boardtest/UartTestClass.h @@ -39,7 +39,7 @@ class UartTestClass : public TestTask { void scexInit(); void scexPeriodic(); - int prepareScexCmd(scex::ScexCmds cmd, bool tempCheck, uint8_t* cmdBuf, size_t* len); + int prepareScexCmd(scex::Cmds cmd, bool tempCheck, uint8_t* cmdBuf, size_t* len); void scexSimplePeriodic(); void scexSimpleInit(); @@ -54,7 +54,7 @@ class UartTestClass : public TestTask { Countdown finishCountdown = Countdown(180 * 1000); bool cmdSent = false; bool cmdDone = false; - scex::ScexCmds currCmd = scex::ScexCmds::PING; + scex::Cmds currCmd = scex::Cmds::PING; TestModes mode = TestModes::GPS; DleEncoder dleEncoder = DleEncoder(); UartCookie* uartCookie = nullptr; @@ -67,7 +67,7 @@ class UartTestClass : public TestTask { std::array cmdBuf = {}; std::array recBuf = {}; ScexDleParser* dleParser; - scex::ScexCmds cmdHelper; + scex::Cmds cmdHelper; uint8_t recvCnt = 0; }; diff --git a/linux/devices/ScexHelper.cpp b/linux/devices/ScexHelper.cpp index ca29ff65..92a9e24a 100644 --- a/linux/devices/ScexHelper.cpp +++ b/linux/devices/ScexHelper.cpp @@ -23,7 +23,7 @@ ReturnValue_t ScexHelper::deSerialize(const uint8_t** buffer, size_t* size, } start = *buffer; cmdByteRaw = **buffer; - cmd = static_cast((cmdByteRaw >> 1) & 0b11111); + cmd = static_cast((cmdByteRaw >> 1) & 0b11111); *buffer += 1; packetCounter = **buffer; @@ -35,7 +35,7 @@ ReturnValue_t ScexHelper::deSerialize(const uint8_t** buffer, size_t* size, payloadLen = (**buffer << 8) | *(*buffer + 1); *buffer += 2; - totalPacketLen = payloadLen + HEADER_LEN + CRC_LEN; + totalPacketLen = payloadLen + scex::HEADER_LEN + scex::CRC_LEN; if (totalPacketLen >= *size) { return STREAM_TOO_SHORT; } @@ -47,7 +47,7 @@ ReturnValue_t ScexHelper::deSerialize(const uint8_t** buffer, size_t* size, return RETURN_OK; } -scex::ScexCmds ScexHelper::getCmd() const { return cmd; } +scex::Cmds ScexHelper::getCmd() const { return cmd; } uint8_t ScexHelper::getCmdByteRaw() const { return cmdByteRaw; } diff --git a/linux/devices/ScexHelper.h b/linux/devices/ScexHelper.h index a835bd0a..02908514 100644 --- a/linux/devices/ScexHelper.h +++ b/linux/devices/ScexHelper.h @@ -13,8 +13,7 @@ class ScexHelper : public HasReturnvaluesIF, public SerializeIF { public: static const ReturnValue_t INVALID_CRC = HasReturnvaluesIF::makeReturnCode(0, 2); - static constexpr uint8_t HEADER_LEN = 5; - static constexpr uint8_t CRC_LEN = 2; + ScexHelper(); ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, Endianness streamEndianness) const override; @@ -25,7 +24,7 @@ class ScexHelper : public HasReturnvaluesIF, public SerializeIF { friend std::ostream &operator<<(std::ostream &os, const ScexHelper &h); friend std::ofstream &operator<<(std::ofstream &os, const ScexHelper &h); - scex::ScexCmds getCmd() const; + scex::Cmds getCmd() const; uint8_t getCmdByteRaw() const; uint16_t getCrc() const; size_t getExpectedPacketLen() const; @@ -38,7 +37,7 @@ class ScexHelper : public HasReturnvaluesIF, public SerializeIF { const uint8_t *start = nullptr; uint16_t crc = 0; uint8_t cmdByteRaw = 0; - scex::ScexCmds cmd = scex::ScexCmds::INVALID; + scex::Cmds cmd = scex::Cmds::INVALID; int packetCounter = 0; int totalPacketCounter = 0; uint16_t payloadLen = 0; diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index fc013271..9ad299e8 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE SusHandler.cpp PayloadPcduHandler.cpp SolarArrayDeploymentHandler.cpp + ScexDeviceHandler.cpp ) add_subdirectory(devicedefinitions) diff --git a/mission/devices/ScexDeviceHandler.cpp b/mission/devices/ScexDeviceHandler.cpp new file mode 100644 index 00000000..fe948a7e --- /dev/null +++ b/mission/devices/ScexDeviceHandler.cpp @@ -0,0 +1,128 @@ +#include "ScexDeviceHandler.h" + +#include + +#include "mission/devices/devicedefinitions/ScexDefinitions.h" +#include "fsfw/globalfunctions/CRC.h" +#include + +ScexDeviceHandler::ScexDeviceHandler(object_id_t objectId, ScexUartReader& reader, CookieIF* cookie) + : DeviceHandlerBase(objectId, reader.getObjectId(),cookie), reader(reader) +{ + +} + +void ScexDeviceHandler::doStartUp() { + // mode on + setMode(MODE_ON); +} + +void ScexDeviceHandler::doShutDown() { setMode(_MODE_POWER_DOWN); } + +ReturnValue_t ScexDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { + return RETURN_OK; +} + +ReturnValue_t ScexDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + return RETURN_OK; +} + +ReturnValue_t ScexDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t* commandData, + size_t commandDataLen) { + using namespace scex; + + if (not std::find(VALID_CMDS.begin(), VALID_CMDS.end(), deviceCommand) != VALID_CMDS.end()) { + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + if (commandDataLen < 1) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } + + switch (deviceCommand) { + case (PING): { + rawPacket = cmdBuf.size(); + + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {nullptr, 0}); + return RETURN_OK; + } + case (FRAM): { + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {nullptr, 0}); + return RETURN_OK; + } + case (ION_CMD): { + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {nullptr, 0}); + return RETURN_OK; + } + case (TEMP_CMD): { + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {nullptr, 0}); + return RETURN_OK; + } + case (ONE_CELL): { + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {commandData + 1, commandData - 1}); + return RETURN_OK; + } + case (ALL_CELLS_CMD): { + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {commandData + 1, commandData - 1}); + return RETURN_OK; + } + case (EXP_STATUS_CMD): { + prepareScexCmd(deviceCommand, commandData[0], {cmdBuf.data(), cmdBuf.size()}, rawPacketLen, + {nullptr, 0}); + return RETURN_OK; + } + } + return RETURN_OK; +} + +void ScexDeviceHandler::fillCommandAndReplyMap() { + insertInCommandAndReplyMap(scex::Cmds::PING, 3); + insertInCommandAndReplyMap(scex::Cmds::ION_CMD, 3); + insertInCommandAndReplyMap(scex::Cmds::TEMP_CMD, 3); + insertInCommandAndReplyMap(scex::Cmds::EXP_STATUS_CMD, 3); + + insertInCommandMap(scex::Cmds::ALL_CELLS_CMD); + insertInCommandMap(scex::Cmds::ONE_CELL); + insertInCommandMap(scex::Cmds::FRAM); + + insertInReplyMap(scex::Cmds::ERROR_REPLY, 3); +} + +ReturnValue_t ScexDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize, + DeviceCommandId_t* foundId, size_t* foundLen) { + //helper.deSerialize(blabla); + //crc check + + *foundId = helper.getCmd(); + *foundLen = remainingSize; + + return RETURN_OK; +} + +ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { + //cmd auswertung (in file reinschreiben) + return RETURN_OK; +} + +uint32_t ScexDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { + return RETURN_OK; +} + +ReturnValue_t ScexDeviceHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { + return RETURN_OK; +} + +ReturnValue_t ScexDeviceHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + return RETURN_OK; +} + + + +void ScexDeviceHandler::modeChanged() {} diff --git a/mission/devices/ScexDeviceHandler.h b/mission/devices/ScexDeviceHandler.h new file mode 100644 index 00000000..5058ed3b --- /dev/null +++ b/mission/devices/ScexDeviceHandler.h @@ -0,0 +1,36 @@ +#ifndef MISSION_DEVICES_SCEXDEVICEHANDLER_H_ +#define MISSION_DEVICES_SCEXDEVICEHANDLER_H_ + +#include +#include +#include + +class ScexDeviceHandler : public DeviceHandlerBase { + public: + // ctor vervollständigen + ScexDeviceHandler(object_id_t objectId, ScexUartReader& reader, CookieIF* cookie); + private: + std::array cmdBuf = {}; + + // DeviceHandlerBase private function implementation + void doStartUp() override; + void doShutDown() override; + ScexHelper helper; + ScexUartReader& reader; + ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) override; + void fillCommandAndReplyMap() 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; + uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; + ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override; + + ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) override; + void modeChanged() override; +}; + +#endif /* MISSION_DEVICES_SCEXDEVICEHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/ScexDefinitions.cpp b/mission/devices/devicedefinitions/ScexDefinitions.cpp index 1e39f414..c202dd5c 100644 --- a/mission/devices/devicedefinitions/ScexDefinitions.cpp +++ b/mission/devices/devicedefinitions/ScexDefinitions.cpp @@ -1,5 +1,36 @@ #include "ScexDefinitions.h" -uint8_t scex::createCmdByte(ScexCmds cmd, bool tempCheck) { +#include + +#include + +uint8_t scex::createCmdByte(Cmds cmd, bool tempCheck) { return (IDLE_BIT_0_DEF_STATE << 7) | (IDLE_BIT_1_DEF_STATE << 6) | (cmd << 1) | tempCheck; } + +ReturnValue_t scex::prepareScexCmd(scex::Cmds cmd, bool tempCheck, + std::pair cmdBufPair, size_t& cmdLen, + std::pair usrDataPair) { + using namespace scex; + uint8_t* cmdBuf = cmdBufPair.first; + const uint8_t* userData = usrDataPair.first; + // Send command + if (cmdBuf == nullptr or (cmdBufPair.second < usrDataPair.second + HEADER_LEN + CRC_LEN) or + (usrDataPair.second > 0 and userData == nullptr)) { + cmdLen = 0; + return HasReturnvaluesIF::RETURN_FAILED; + } + cmdBuf[0] = scex::createCmdByte(cmd, tempCheck); + // These two fields are the packet counter and the total packet count. Those are 1 and 1 for each + // telecommand so far + cmdBuf[1] = 1; + cmdBuf[2] = 1; + cmdBuf[3] = (usrDataPair.second >> 8) & 0xff; + cmdBuf[4] = usrDataPair.second & 0xff; + std::memcpy(cmdBuf + HEADER_LEN, userData, usrDataPair.second); + uint16_t crc = CRC::crc16ccitt(cmdBuf, usrDataPair.second + HEADER_LEN); + cmdBuf[usrDataPair.second + HEADER_LEN] = (crc >> 8) & 0xff; + cmdBuf[usrDataPair.second + HEADER_LEN + 1] = crc & 0xff; + cmdLen = usrDataPair.second + HEADER_LEN + CRC_LEN; + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/mission/devices/devicedefinitions/ScexDefinitions.h b/mission/devices/devicedefinitions/ScexDefinitions.h index f479981e..70426085 100644 --- a/mission/devices/devicedefinitions/ScexDefinitions.h +++ b/mission/devices/devicedefinitions/ScexDefinitions.h @@ -1,17 +1,46 @@ #ifndef MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_ +#include +#include +#include + #include +#include // Definitions for the Solar Cell Experiment namespace scex { -enum ScexCmds : uint8_t { PING = 0b00111, ONE_CELL = 0b00110, FRAM = 0b00001, INVALID = 255 }; +static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SCEX_HANDLER; + +static constexpr Event MISSING_PACKET = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); + +static constexpr Event EXPERIMENT_TIMEDOUT = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); + +enum Cmds : DeviceCommandId_t { + PING = 0b00111, + ALL_CELLS_CMD = 0b00101, + ONE_CELL = 0b00110, + FRAM = 0b00001, + EXP_STATUS_CMD = 0b00010, + TEMP_CMD = 0b00011, + ION_CMD = 0b00100, + ERROR_REPLY = 0b01000, + INVALID = 255 +}; + +static const std::vector VALID_CMDS = { + PING, ALL_CELLS_CMD, ONE_CELL, FRAM, EXP_STATUS_CMD, TEMP_CMD, ION_CMD}; + +static constexpr uint8_t HEADER_LEN = 5; +static constexpr uint8_t CRC_LEN = 2; static constexpr uint8_t IDLE_BIT_0_DEF_STATE = 0; static constexpr uint8_t IDLE_BIT_1_DEF_STATE = 1; -uint8_t createCmdByte(ScexCmds cmd, bool tempCheck); +uint8_t createCmdByte(Cmds cmd, bool tempCheck); +ReturnValue_t prepareScexCmd(scex::Cmds cmd, bool tempCheck, std::pair cmdBufPair, + size_t& cmdLen, std::pair usrDataPair); } // namespace scex