From 23d9f56308e480fa1ef821506cfff382122058dc Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 25 Nov 2021 08:24:24 +0100 Subject: [PATCH 01/78] star tracker startup immediately --- bsp_q7s/core/ObjectFactory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index bf8a2fba..83b59d08 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -171,7 +171,8 @@ void ObjectFactory::produce(void* args) { q7s::UART_STAR_TRACKER_DEV, UartModes::NON_CANONICAL, uart::STAR_TRACKER_BAUD, StarTracker::MAX_FRAME_SIZE* 2 + 2); starTrackerCookie->setNoFixedSizeReply(); - new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie); + StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie); + starTrackerHandler->setStartUpImmediately(); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* TE7020 == 0 */ From 0b7e8fa38bafa08b77b9f4f9e77778bf06127e4c Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 26 Nov 2021 09:14:41 +0100 Subject: [PATCH 02/78] star tracker ping command --- mission/devices/StarTrackerHandler.cpp | 37 +++++++++++++++++++ mission/devices/StarTrackerHandler.h | 14 ++++++- .../StarTrackerDefinitions.h | 1 + 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index c5718f02..22a84973 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -6,6 +6,7 @@ extern "C" { #include + #include #include "common/misc.h" } @@ -55,6 +56,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi const uint8_t * commandData, size_t commandDataLen) { switch (deviceCommand) { + case (StarTracker::PING_REQUEST): { + preparePingRequest(); + return RETURN_OK; + } case (StarTracker::REQ_TEMPERATURE): { prepareTemperatureRequest(); return RETURN_OK; @@ -68,6 +73,8 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi void StarTrackerHandler::fillCommandAndReplyMap() { /** Reply lengths are unknown because of the slip encoding. Thus always maximum reply size * is specified */ + this->insertInCommandAndReplyMap(StarTracker::PING_REQUEST, 1, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 1, &temperatureSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); } @@ -106,6 +113,11 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema } switch (decodedFrame[1]) { + case (static_cast(StarTracker::PING_REQUEST)): { + *foundLen = decodedLength; + *foundId = StarTracker::PING_REQUEST; + break; + } case (static_cast(StarTracker::REQ_TEMPERATURE)): { *foundLen = decodedLength; *foundId = StarTracker::REQ_TEMPERATURE; @@ -125,6 +137,10 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch (id) { + case (StarTracker::PING_REQUEST): { + handlePingReply(); + break; + } case (StarTracker::REQ_TEMPERATURE): { handleTemperatureTm(); break; @@ -170,6 +186,16 @@ void StarTrackerHandler::slipInit() { slipInfo.prev_state = SLIP_COMPLETE; } +void StarTrackerHandler::preparePingRequest() { + uint32_t length = 0; + struct PingActionRequest pingRequest = {PING_ID}; + arc_pack_ping_action_req(&pingRequest, commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + void StarTrackerHandler::prepareTemperatureRequest() { uint32_t length = 0; arc_tm_pack_temperature_req(commandBuffer, &length); @@ -179,6 +205,17 @@ void StarTrackerHandler::prepareTemperatureRequest() { rawPacketLen = encLength; } +void StarTrackerHandler::handlePingReply() { + uint32_t pingId = 0; + size_t size = 0; + const uint8_t* buffer = decodedFrame; + SerializeAdapter::deSerialize(&pingId, &buffer, &size, SerializeIF::Endianness::BIG); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "Ping status "<< static_cast(*(decodedFrame + 2)) << std::endl; + sif::info << "Ping id "<< pingId << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ +} + void StarTrackerHandler::handleTemperatureTm() { PoolReadGuard rg(&temperatureSet); uint32_t offset = 1; diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index ee96e544..4d49064d 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -2,6 +2,7 @@ #define MISSION_DEVICES_STARTRACKERHANDLER_H_ #include +#include #include #include @@ -64,8 +65,11 @@ private: static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; //! [EXPORT] : [COMMENT] Result code of tm reply indicates an error + static const ReturnValue_t TM_REPLY_ERROR = MAKE_RETURN_CODE(0xA0); - //! P1: TM id + + // Ping request will reply ping with this ID (data field) + static const uint32_t PING_ID = 0x55; StarTracker::TemperatureSet temperatureSet; @@ -89,8 +93,16 @@ private: */ void slipInit(); + /** + * @brief Fills command buffer with data to ping the star tracker + */ + void preparePingRequest(); + /** + * @brief Fills command buffer with data to request temperature from star tracker + */ void prepareTemperatureRequest(); + void handlePingReply(); /** * @brief This function handles the telemetry reply of a temperature request. */ diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index 6c28219b..efde795e 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -21,6 +21,7 @@ enum PoolIds: lp_id_t { +static const DeviceCommandId_t PING_REQUEST = 0; static const DeviceCommandId_t REQ_TEMPERATURE = 25; static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE; From 8b97528afb9a9975ad82fafa5d7c21cb750d4d9e Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 26 Nov 2021 13:16:05 +0100 Subject: [PATCH 03/78] star tracker ping and reboot command --- mission/devices/StarTrackerHandler.cpp | 90 ++++++++++++------- mission/devices/StarTrackerHandler.h | 18 ++-- .../StarTrackerDefinitions.h | 7 +- 3 files changed, 75 insertions(+), 40 deletions(-) diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index 22a84973..ebb23033 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -25,7 +25,8 @@ StarTrackerHandler::~StarTrackerHandler() { void StarTrackerHandler::doStartUp() { #if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 - setMode(MODE_NORMAL); +// setMode(MODE_NORMAL); + setMode(_MODE_TO_ON); #else setMode(_MODE_TO_ON); #endif @@ -60,6 +61,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi preparePingRequest(); return RETURN_OK; } + case (StarTracker::REBOOT): { + prepareRebootCommand(); + return RETURN_OK; + } case (StarTracker::REQ_TEMPERATURE): { prepareTemperatureRequest(); return RETURN_OK; @@ -75,6 +80,7 @@ void StarTrackerHandler::fillCommandAndReplyMap() { * is specified */ this->insertInCommandAndReplyMap(StarTracker::PING_REQUEST, 1, nullptr, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandMap(StarTracker::REBOOT); this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 1, &temperatureSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); } @@ -136,9 +142,11 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + ReturnValue_t result = RETURN_OK; + switch (id) { case (StarTracker::PING_REQUEST): { - handlePingReply(); + result = handlePingReply(); break; } case (StarTracker::REQ_TEMPERATURE): { @@ -146,12 +154,13 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con break; } default: { - sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id" << std::endl; + sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id:" << id + << std::endl; return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; } } - return RETURN_OK; + return result; } void StarTrackerHandler::setNormalDatapoolEntriesInvalid() { @@ -165,7 +174,6 @@ uint32_t StarTrackerHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { - localDataPoolMap.emplace(StarTracker::STATUS, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::TICKS, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::TIME, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::MCU_TEMPERATURE, new PoolEntry( { 0 })); @@ -196,6 +204,16 @@ void StarTrackerHandler::preparePingRequest() { rawPacketLen = encLength; } +void StarTrackerHandler::prepareRebootCommand() { + uint32_t length = 0; + struct RebootActionRequest rebootReq; + arc_pack_reboot_action_req(&rebootReq, commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + void StarTrackerHandler::prepareTemperatureRequest() { uint32_t length = 0; arc_tm_pack_temperature_req(commandBuffer, &length); @@ -205,49 +223,59 @@ void StarTrackerHandler::prepareTemperatureRequest() { rawPacketLen = encLength; } -void StarTrackerHandler::handlePingReply() { +ReturnValue_t StarTrackerHandler::handlePingReply() { + ReturnValue_t result = RETURN_OK; uint32_t pingId = 0; - size_t size = 0; - const uint8_t* buffer = decodedFrame; - SerializeAdapter::deSerialize(&pingId, &buffer, &size, SerializeIF::Endianness::BIG); + uint8_t status = *(decodedFrame + 2); + const uint8_t* buffer = decodedFrame + 3; + size_t size = sizeof(pingId); + SerializeAdapter::deSerialize(&pingId, &buffer, &size, SerializeIF::Endianness::LITTLE); #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "Ping status "<< static_cast(*(decodedFrame + 2)) << std::endl; - sif::info << "Ping id "<< pingId << std::endl; + sif::info << "Ping status: "<< static_cast(status) << std::endl; + sif::info << "Ping id: 0x"<< std::hex << pingId << std::endl; #endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + if (status != StarTracker::STATUS_OK || pingId != PING_ID) { + result = PING_FAILED; + } + return result; } -void StarTrackerHandler::handleTemperatureTm() { +ReturnValue_t StarTrackerHandler::handleTemperatureTm() { + ReturnValue_t result = RETURN_OK; PoolReadGuard rg(&temperatureSet); - uint32_t offset = 1; - temperatureSet.status = *(decodedFrame + offset); + uint32_t offset = 2; + uint8_t status = *(decodedFrame + offset); offset += 1; - if(temperatureSet.status.value != 0) { + if(status != StarTracker::STATUS_OK) { sif::warning << "StarTrackerHandler::handleTemperatureTm: Reply error: " - << static_cast(temperatureSet.status.value) << std::endl; - triggerEvent(TM_REPLY_ERROR, temperatureSet.status.value); + << static_cast(status) << std::endl; + result = TEMPERATURE_REQUEST_FAILED; + return result; } - temperatureSet.ticks = *(decodedFrame + offset) << 24 - | *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8 - | *(decodedFrame + offset + 3); - offset += 4; - temperatureSet.time = static_cast(*(decodedFrame + offset)) << 56 - | static_cast(*(decodedFrame + offset + 1)) << 48 - | static_cast(*(decodedFrame + offset + 2)) << 40 - | static_cast(*(decodedFrame + offset + 3)) << 32 - | *(decodedFrame + offset + 4) << 24 | *(decodedFrame + offset + 5) << 16 - | *(decodedFrame + offset + 6) << 8 | *(decodedFrame + offset + 7); - offset += 8; + const uint8_t* buffer = decodedFrame + offset; + size_t size = sizeof(temperatureSet.ticks); + SerializeAdapter::deSerialize(&temperatureSet.ticks, &buffer, &size, SerializeIF::Endianness::LITTLE); + offset += size; + buffer = decodedFrame + offset; + size = sizeof(temperatureSet.time); + SerializeAdapter::deSerialize(&temperatureSet.time, &buffer, &size, SerializeIF::Endianness::LITTLE); + offset += size; temperatureSet.mcuTemperature = *(decodedFrame + offset) << 24 | *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8 | *(decodedFrame + offset + 3); - offset += 4; - temperatureSet.cmosTemperature = *(decodedFrame + offset) << 24 + offset += sizeof(temperatureSet.mcuTemperature); + temperatureSet.mcuTemperature = *(decodedFrame + offset) << 24 | *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8 | *(decodedFrame + offset + 3); -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTrackerHandler::handleTemperatureTm: Ticks: " + << temperatureSet.ticks << std::endl; + sif::info << "StarTrackerHandler::handleTemperatureTm: Time: " + << temperatureSet.time << std::endl; sif::info << "StarTrackerHandler::handleTemperatureTm: MCU Temperature: " << temperatureSet.mcuTemperature << " °C" << std::endl; sif::info << "StarTrackerHandler::handleTemperatureTm: CMOS Temperature: " << temperatureSet.mcuTemperature << " °C" << std::endl; #endif + return result; } diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index 4d49064d..329536dd 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -12,7 +12,6 @@ * @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/ * Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/ * Sagitta%201.0%20Datapack&fileid=659181 - * * @author J. Meier */ class StarTrackerHandler: public DeviceHandlerBase { @@ -64,9 +63,10 @@ private: static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; - //! [EXPORT] : [COMMENT] Result code of tm reply indicates an error - - static const ReturnValue_t TM_REPLY_ERROR = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Status in tm reply not ok + static const ReturnValue_t TEMPERATURE_REQUEST_FAILED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Ping command failed + static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1); // Ping request will reply ping with this ID (data field) static const uint32_t PING_ID = 0x55; @@ -97,16 +97,22 @@ private: * @brief Fills command buffer with data to ping the star tracker */ void preparePingRequest(); + + /** + * @brief Fills command buffer with data to reboot star tracker. + */ + void prepareRebootCommand(); + /** * @brief Fills command buffer with data to request temperature from star tracker */ void prepareTemperatureRequest(); - void handlePingReply(); + ReturnValue_t handlePingReply(); /** * @brief This function handles the telemetry reply of a temperature request. */ - void handleTemperatureTm(); + ReturnValue_t handleTemperatureTm(); }; #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index efde795e..0b30b661 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -11,8 +11,9 @@ namespace StarTracker { /** This is the address of the star tracker */ static const uint8_t ADDRESS = 33; +static const uint8_t STATUS_OK = 0; + enum PoolIds: lp_id_t { - STATUS, TICKS, TIME, MCU_TEMPERATURE, @@ -22,6 +23,7 @@ enum PoolIds: lp_id_t { static const DeviceCommandId_t PING_REQUEST = 0; +static const DeviceCommandId_t REBOOT = 7; static const DeviceCommandId_t REQ_TEMPERATURE = 25; static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE; @@ -46,8 +48,7 @@ public: StaticLocalDataSet(sid_t(objectId, TEMPERATURE_SET_ID)) { } - lp_var_t status = lp_var_t(sid.objectId, - PoolIds::STATUS, this); + // Ticks is time reference generated by interanl counter of the star tracker lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::TICKS, this); /** Unix time in microseconds */ From eb0e9c2a4193d871807257e64f1dd938b387ac72 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 26 Nov 2021 15:24:52 +0100 Subject: [PATCH 04/78] request version command --- mission/devices/StarTrackerHandler.cpp | 65 +++++++++++++++++-- mission/devices/StarTrackerHandler.h | 11 ++++ .../StarTrackerDefinitions.h | 49 ++++++++++++-- 3 files changed, 115 insertions(+), 10 deletions(-) diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index ebb23033..10805f7e 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -12,7 +12,7 @@ extern "C" { StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : - DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this) { + DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this) { if (comCookie == NULL) { sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; } @@ -61,6 +61,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi preparePingRequest(); return RETURN_OK; } + case (StarTracker::REQ_VERSION): { + prepareVersionRequest(); + return RETURN_OK; + } case (StarTracker::REBOOT): { prepareRebootCommand(); return RETURN_OK; @@ -80,6 +84,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() { * is specified */ this->insertInCommandAndReplyMap(StarTracker::PING_REQUEST, 1, nullptr, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_VERSION, 1, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandMap(StarTracker::REBOOT); this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 1, &temperatureSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); @@ -124,6 +130,11 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema *foundId = StarTracker::PING_REQUEST; break; } + case (static_cast(StarTracker::REQ_VERSION)): { + *foundLen = decodedLength; + *foundId = StarTracker::PING_REQUEST; + break; + } case (static_cast(StarTracker::REQ_TEMPERATURE)): { *foundLen = decodedLength; *foundId = StarTracker::REQ_TEMPERATURE; @@ -149,6 +160,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con result = handlePingReply(); break; } + case (StarTracker::REQ_VERSION): { + result = handleVersionTm(); + break; + } case (StarTracker::REQ_TEMPERATURE): { handleTemperatureTm(); break; @@ -174,8 +189,13 @@ uint32_t StarTrackerHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { - localDataPoolMap.emplace(StarTracker::TICKS, new PoolEntry( { 0 })); - localDataPoolMap.emplace(StarTracker::TIME, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TICKS_VERSION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_VERSION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::PROGRAM, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MAJOR, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MINOR, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TICKS_TEMPERATURE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_TEMPERATURE_SET, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::MCU_TEMPERATURE, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::CMOS_TEMPERATURE, new PoolEntry( { 0 })); @@ -204,6 +224,15 @@ void StarTrackerHandler::preparePingRequest() { rawPacketLen = encLength; } +void StarTrackerHandler::prepareVersionRequest() { + uint32_t length = 0; + arc_tm_pack_version_req(commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + void StarTrackerHandler::prepareRebootCommand() { uint32_t length = 0; struct RebootActionRequest rebootReq; @@ -240,6 +269,34 @@ ReturnValue_t StarTrackerHandler::handlePingReply() { return result; } +ReturnValue_t StarTrackerHandler::handleVersionTm() { + ReturnValue_t result = RETURN_OK; + PoolReadGuard rg(&versionSet); + uint32_t offset = 2; + uint8_t status = *(decodedFrame + offset); + offset += 1; + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleTemperatureTm: Reply error: " + << static_cast(status) << std::endl; + result = TEMPERATURE_REQUEST_FAILED; + return result; + } + versionSet.program = (*decodedFrame + offset); + offset += 1; + versionSet.major = (*decodedFrame + offset); + offset += 1; + versionSet.minor = (*decodedFrame + offset); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTrackerHandler::handleVersionTm: Program: " + << versionSet.program << std::endl; + sif::info << "StarTrackerHandler::handleVersionTm: Major: " + << versionSet.major << std::endl; + sif::info << "StarTrackerHandler::handleVersionTm: Minor: " + << versionSet.minor << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return result; +} + ReturnValue_t StarTrackerHandler::handleTemperatureTm() { ReturnValue_t result = RETURN_OK; PoolReadGuard rg(&temperatureSet); @@ -267,7 +324,7 @@ ReturnValue_t StarTrackerHandler::handleTemperatureTm() { temperatureSet.mcuTemperature = *(decodedFrame + offset) << 24 | *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8 | *(decodedFrame + offset + 3); - #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 sif::info << "StarTrackerHandler::handleTemperatureTm: Ticks: " << temperatureSet.ticks << std::endl; sif::info << "StarTrackerHandler::handleTemperatureTm: Time: " diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index 329536dd..89bd7097 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -72,6 +72,7 @@ private: static const uint32_t PING_ID = 0x55; StarTracker::TemperatureSet temperatureSet; + StarTracker::VersionSet versionSet; uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; @@ -98,6 +99,11 @@ private: */ void preparePingRequest(); + /** + * @brief Fills command buffer with data to request the version telemetry packet + */ + void prepareVersionRequest(); + /** * @brief Fills command buffer with data to reboot star tracker. */ @@ -113,6 +119,11 @@ private: * @brief This function handles the telemetry reply of a temperature request. */ ReturnValue_t handleTemperatureTm(); + + /** + * @brief This function handles the telemetry reply of a version request. + */ + ReturnValue_t handleVersionTm(); }; #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index 0b30b661..6772abfe 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -14,24 +14,32 @@ static const uint8_t ADDRESS = 33; static const uint8_t STATUS_OK = 0; enum PoolIds: lp_id_t { - TICKS, - TIME, + TICKS_VERSION_SET, + TIME_VERSION_SET, + TICKS_TEMPERATURE_SET, + TIME_TEMPERATURE_SET, MCU_TEMPERATURE, - CMOS_TEMPERATURE + CMOS_TEMPERATURE, + PROGRAM, + MAJOR, + MINOR }; static const DeviceCommandId_t PING_REQUEST = 0; +static const DeviceCommandId_t REQ_VERSION = 2; static const DeviceCommandId_t REBOOT = 7; static const DeviceCommandId_t REQ_TEMPERATURE = 25; +static const uint32_t VERSION_SET_ID = REQ_VERSION; static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE; /** Max size of unencoded frame */ static const size_t MAX_FRAME_SIZE = 1200; -static const uint8_t TEMPERATURE_SET_ENTRIES = 5; +static const uint8_t TEMPERATURE_SET_ENTRIES = 4; +static const uint8_t VERSION_SET_ENTRIES = 3; /** * @brief This dataset can be used to store the temperature of a reaction wheel. @@ -50,16 +58,45 @@ public: // Ticks is time reference generated by interanl counter of the star tracker lp_var_t ticks = lp_var_t(sid.objectId, - PoolIds::TICKS, this); + PoolIds::TICKS_TEMPERATURE_SET, this); /** Unix time in microseconds */ lp_var_t time = lp_var_t(sid.objectId, - PoolIds::TIME, this); + PoolIds::TIME_TEMPERATURE_SET, this); lp_var_t mcuTemperature = lp_var_t(sid.objectId, PoolIds::MCU_TEMPERATURE, this); lp_var_t cmosTemperature = lp_var_t(sid.objectId, PoolIds::CMOS_TEMPERATURE, this); }; +/** + * @brief Package to store version parameters + */ +class VersionSet: + public StaticLocalDataSet { +public: + + VersionSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, VERSION_SET_ID) { + } + + VersionSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, VERSION_SET_ID)) { + } + + // Ticks is time reference generated by interanl counter of the star tracker + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_VERSION_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_VERSION_SET, this); + lp_var_t program = lp_var_t(sid.objectId, + PoolIds::PROGRAM, this); + lp_var_t major = lp_var_t(sid.objectId, + PoolIds::MAJOR, this); + lp_var_t minor = lp_var_t(sid.objectId, + PoolIds::MINOR, this); +}; + } #endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */ From 5ea129d2529b11376544236ab4624c0975a6a7fa Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sat, 27 Nov 2021 19:40:52 +0100 Subject: [PATCH 05/78] star tracker solution telemetry --- mission/devices/StarTrackerHandler.cpp | 734 ++++++++++++++++-- mission/devices/StarTrackerHandler.h | 123 ++- .../StarTrackerDefinitions.h | 355 ++++++++- 3 files changed, 1137 insertions(+), 75 deletions(-) diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index 10805f7e..ce69d41d 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -2,7 +2,6 @@ #include "OBSWConfig.h" #include -#include extern "C" { #include @@ -12,7 +11,8 @@ extern "C" { StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : - DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this) { + DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this), powerSet( + this), interfaceSet(this), timeSet(this), solutionSet(this) { if (comCookie == NULL) { sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; } @@ -61,14 +61,38 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi preparePingRequest(); return RETURN_OK; } + case (StarTracker::REQ_TIME): { + prepareTimeRequest(); + return RETURN_OK; + } + case (StarTracker::BOOT): { + prepareBootCommand(); + return RETURN_OK; + } case (StarTracker::REQ_VERSION): { prepareVersionRequest(); return RETURN_OK; } + case (StarTracker::REQ_INTERFACE): { + prepareInterfaceRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_POWER): { + preparePowerRequest(); + return RETURN_OK; + } case (StarTracker::REBOOT): { prepareRebootCommand(); return RETURN_OK; } + case (StarTracker::SUBSCRIBE_TO_TM): { + prepareSubscriptionCommand(commandData); + return RETURN_OK; + } + case (StarTracker::REQ_SOLUTION): { + prepareSolutionRequest(); + return RETURN_OK; + } case (StarTracker::REQ_TEMPERATURE): { prepareTemperatureRequest(); return RETURN_OK; @@ -82,26 +106,44 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi void StarTrackerHandler::fillCommandAndReplyMap() { /** Reply lengths are unknown because of the slip encoding. Thus always maximum reply size * is specified */ - this->insertInCommandAndReplyMap(StarTracker::PING_REQUEST, 1, nullptr, + this->insertInCommandAndReplyMap(StarTracker::PING_REQUEST, 3, nullptr, StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::REQ_VERSION, 1, nullptr, + this->insertInCommandAndReplyMap(StarTracker::BOOT, 3, nullptr, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_VERSION, 3, &versionSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_TIME, 3, &timeSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_POWER, 3, &powerSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_INTERFACE, 3, &interfaceSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + // Reboot has no reply. Star tracker reboots immediately this->insertInCommandMap(StarTracker::REBOOT); - this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 1, &temperatureSet, + this->insertInCommandAndReplyMap(StarTracker::SUBSCRIBE_TO_TM, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_SOLUTION, 3, &solutionSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 3, &temperatureSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); } ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { + ReturnValue_t result = RETURN_OK; uint32_t decodedLength = 0; - - for (size_t idx = 0; idx < remainingSize; idx++) { - enum arc_dec_result decResult = arc_transport_decode_body(*(start + idx), &slipInfo, + size_t bytePos = 0; + for (bytePos = 0; bytePos < remainingSize; bytePos++) { + enum arc_dec_result decResult = arc_transport_decode_body(*(start + bytePos), &slipInfo, decodedFrame, &decodedLength); switch (decResult) { case ARC_DEC_INPROGRESS: { + if (bytePos == remainingSize - 1) { + // second doSendread() required to read whole packet + return IGNORE_FULL_PACKET; + } continue; } case ARC_DEC_ASYNC: { @@ -124,31 +166,30 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema } } - switch (decodedFrame[1]) { - case (static_cast(StarTracker::PING_REQUEST)): { - *foundLen = decodedLength; - *foundId = StarTracker::PING_REQUEST; + switch (decodedFrame[0]) { + case TMTC_ACTIONREPLY: { + *foundLen = bytePos; + result = scanForActionReply(foundId); break; } - case (static_cast(StarTracker::REQ_VERSION)): { - *foundLen = decodedLength; - *foundId = StarTracker::PING_REQUEST; + case TMTC_SETPARAMREPLY: { + *foundLen = bytePos; + result = scanForSetParameterReply(foundId); break; } - case (static_cast(StarTracker::REQ_TEMPERATURE)): { - *foundLen = decodedLength; - *foundId = StarTracker::REQ_TEMPERATURE; + case TMTC_TELEMETRYREPLYA: + case TMTC_TELEMETRYREPLY: { + *foundLen = bytePos; + result = scanForTmReply(foundId); break; } default: { - sif::debug << "StarTrackerHandler::scanForReply: Reply contains invalid reply id" - << std::endl; - return RETURN_FAILED; - break; + sif::debug << "StarTrackerHandler::scanForReply: Reply has invalid type id" << std::endl; + result = RETURN_FAILED; } } - return RETURN_OK; + return result; } ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { @@ -156,14 +197,38 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con ReturnValue_t result = RETURN_OK; switch (id) { + case (StarTracker::SUBSCRIBE_TO_TM): { + result = handleSetParamReply(); + break; + } + case (StarTracker::REQ_TIME): { + result = handleTimeTm(); + break; + } case (StarTracker::PING_REQUEST): { result = handlePingReply(); break; } + case (StarTracker::BOOT): { + result = handleActionReply(); + break; + } case (StarTracker::REQ_VERSION): { result = handleVersionTm(); break; } + case (StarTracker::REQ_INTERFACE): { + result = handleInterfaceTm(); + break; + } + case (StarTracker::REQ_POWER): { + result = handlePowerTm(); + break; + } + case (StarTracker::REQ_SOLUTION): { + handleSolutionTm(); + break; + } case (StarTracker::REQ_TEMPERATURE): { handleTemperatureTm(); break; @@ -171,13 +236,14 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con default: { sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id:" << id << std::endl; - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + result = DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; } } return result; } + void StarTrackerHandler::setNormalDatapoolEntriesInvalid() { } @@ -189,16 +255,78 @@ uint32_t StarTrackerHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { + localDataPoolMap.emplace(StarTracker::TICKS_TIME_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_TIME_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::RUN_TIME, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::UNIX_TIME, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TICKS_VERSION_SET, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::TIME_VERSION_SET, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::PROGRAM, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::MAJOR, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::MINOR, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_INTERFACE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_INTERFACE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FRAME_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CHECKSUM_ERROR_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::SET_PARAM_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::SET_PARAM_REPLY_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::PARAM_REQUEST_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::PARAM_REPLY_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::REQ_TM_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TM_REPLY_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::ACTION_REQ_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::ACTION_REPLY_COUNT, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_POWER_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_POWER_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MCU_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MCU_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_CORE_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_CORE_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_18_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_18_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_25_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_25_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_21_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_21_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_PIX_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_PIX_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_33_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_33_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_RES_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_RES_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TICKS_TEMPERATURE_SET, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::TIME_TEMPERATURE_SET, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::MCU_TEMPERATURE, new PoolEntry( { 0 })); localDataPoolMap.emplace(StarTracker::CMOS_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TICKS_SOLUTION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_SOLUTION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QW, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_CONFIDENCE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QW, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_REMOVED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::STARS_CENTROIDED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::STARS_MATCHED_DATABASE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QW, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_PERC_CLOSE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_NR_CLOSE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRUST_WORTHY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::STABLE_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::SOLUTION_STRATEGY, new PoolEntry( { 0 })); + return RETURN_OK; } @@ -206,6 +334,74 @@ size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){ return StarTracker::MAX_FRAME_SIZE; } +ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) { + switch (decodedFrame[1]) { + case (StarTracker::ID::PING): { + *foundId = StarTracker::PING_REQUEST; + break; + } + case (StarTracker::ID::BOOT): { + *foundId = StarTracker::BOOT; + break; + } + default: + sif::debug << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" + << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::scanForSetParameterReply(DeviceCommandId_t *foundId) { + switch (decodedFrame[1]) { + case (StarTracker::ID::SUBSCRIBE): { + *foundId = StarTracker::SUBSCRIBE_TO_TM; + break; + } + default: + sif::debug << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" + << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::scanForTmReply(DeviceCommandId_t *foundId) { + switch (decodedFrame[1]) { + case (StarTracker::ID::VERSION): { + *foundId = StarTracker::REQ_VERSION; + break; + } + case (StarTracker::ID::INTERFACE): { + *foundId = StarTracker::REQ_INTERFACE; + break; + } + case (StarTracker::ID::POWER): { + *foundId = StarTracker::REQ_POWER; + break; + } + case (StarTracker::ID::TEMPERATURE): { + *foundId = StarTracker::REQ_TEMPERATURE; + break; + } + case (StarTracker::ID::TIME): { + *foundId = StarTracker::REQ_TIME; + break; + } + case (StarTracker::ID::SOLUTION): { + *foundId = StarTracker::REQ_SOLUTION; + break; + } + default: { + sif::debug << "StarTrackerHandler::scanForReply: Reply contains invalid reply id" + << std::endl; + return RETURN_FAILED; + break; + } + } + return RETURN_OK; +} + void StarTrackerHandler::slipInit() { slipInfo.buffer = rxBuffer; slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE; @@ -214,6 +410,25 @@ void StarTrackerHandler::slipInit() { slipInfo.prev_state = SLIP_COMPLETE; } +void StarTrackerHandler::prepareBootCommand() { + uint32_t length = 0; + struct BootActionRequest bootRequest = {BOOT_REGION_ID}; + arc_pack_boot_action_req(&bootRequest, commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + +void StarTrackerHandler::prepareTimeRequest() { + uint32_t length = 0; + arc_tm_pack_time_req(commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + void StarTrackerHandler::preparePingRequest() { uint32_t length = 0; struct PingActionRequest pingRequest = {PING_ID}; @@ -233,6 +448,24 @@ void StarTrackerHandler::prepareVersionRequest() { rawPacketLen = encLength; } +void StarTrackerHandler::prepareInterfaceRequest() { + uint32_t length = 0; + arc_tm_pack_interface_req(commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + +void StarTrackerHandler::preparePowerRequest() { + uint32_t length = 0; + arc_tm_pack_power_req(commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + void StarTrackerHandler::prepareRebootCommand() { uint32_t length = 0; struct RebootActionRequest rebootReq; @@ -243,6 +476,42 @@ void StarTrackerHandler::prepareRebootCommand() { rawPacketLen = encLength; } +void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) { + uint32_t encLength = 0; + uint32_t length = 18; + commandBuffer[0] = TMTC_SETPARAMREQ; + commandBuffer[1] = StarTracker::ID::SUBSCRIBE; + // Fill all other fields with invalid tm id + commandBuffer[2] = *tmId; + commandBuffer[3] = 0; + commandBuffer[4] = 0; + commandBuffer[5] = 0; + commandBuffer[6] = 0; + commandBuffer[7] = 0; + commandBuffer[8] = 0; + commandBuffer[9] = 0; + commandBuffer[10] = 0; + commandBuffer[11] = 0; + commandBuffer[12] = 0; + commandBuffer[13] = 0; + commandBuffer[14] = 0; + commandBuffer[15] = 0; + commandBuffer[16] = 0; + commandBuffer[17] = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + +void StarTrackerHandler::prepareSolutionRequest() { + uint32_t length = 0; + arc_tm_pack_solution_req(commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; +} + void StarTrackerHandler::prepareTemperatureRequest() { uint32_t length = 0; arc_tm_pack_temperature_req(commandBuffer, &length); @@ -252,6 +521,29 @@ void StarTrackerHandler::prepareTemperatureRequest() { rawPacketLen = encLength; } +ReturnValue_t StarTrackerHandler::handleSetParamReply() { + uint8_t status = *(decodedFrame + STATUS_OFFSET); + if (status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleSetParamReply: Failed to execute parameter set " + " command with parameter ID" << + static_cast(*(decodedFrame + PARAMETER_ID_OFFSET)) << std::endl; + return SET_PARAM_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handleActionReply() { + uint8_t status = *(decodedFrame + STATUS_OFFSET); + if (status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleActionReply: Failed to execute action " + << " command with action ID " + << static_cast(*(decodedFrame + ACTION_ID_OFFSET)) + << " and status "<< static_cast(status) << std::endl; + return ACTION_FAILED; + } + return RETURN_OK; +} + ReturnValue_t StarTrackerHandler::handlePingReply() { ReturnValue_t result = RETURN_OK; uint32_t pingId = 0; @@ -269,70 +561,380 @@ ReturnValue_t StarTrackerHandler::handlePingReply() { return result; } +ReturnValue_t StarTrackerHandler::handleTimeTm() { + ReturnValue_t result = RETURN_OK; + PoolReadGuard rg(&timeSet); + uint32_t offset = TM_DATA_FIELD_OFFSET; + uint8_t status = 0; + uint32_t ticks = 0; + uint64_t time = 0; + getTmHeaderData(&status, &ticks, &time); + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleVersionTm: Reply error: " + << static_cast(status) << std::endl; + result = VERSION_REQ_FAILED; + return result; + } + timeSet.ticks = ticks; + timeSet.time = time; + timeSet.runTime = deserializeUint32(decodedFrame + offset); + offset += sizeof(uint32_t); + timeSet.unixTime = deserializeUint64(decodedFrame + offset); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTrackerHandler::handleTimeTm: Ticks: " + << timeSet.ticks << std::endl; + sif::info << "StarTrackerHandler::handleTimeTm: Time (time stamp): " + << timeSet.time << " us" << std::endl; + sif::info << "StarTrackerHandler::handleTimeTm: Run Time: " + << timeSet.runTime << " ms" << std::endl; + sif::info << "StarTrackerHandler::handleTimeTm: Unix Time: " + << timeSet.unixTime << " s" << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return result; +} + ReturnValue_t StarTrackerHandler::handleVersionTm() { ReturnValue_t result = RETURN_OK; PoolReadGuard rg(&versionSet); - uint32_t offset = 2; - uint8_t status = *(decodedFrame + offset); + uint32_t offset = TM_DATA_FIELD_OFFSET; + uint8_t status = 0; + uint32_t ticks = 0; + uint64_t time = 0; + getTmHeaderData(&status, &ticks, &time); + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleVersionTm: Reply error: " + << static_cast(status) << std::endl; + result = VERSION_REQ_FAILED; + return result; + } + versionSet.ticks = ticks; + versionSet.time = time; + versionSet.program = *(decodedFrame + offset); offset += 1; + versionSet.major = *(decodedFrame + offset); + offset += 1; + versionSet.minor = *(decodedFrame + offset); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTrackerHandler::handleVersionTm: Ticks: " + << versionSet.ticks << std::endl; + sif::info << "StarTrackerHandler::handleVersionTm: Unix Time: " + << versionSet.time << " us" << std::endl; + sif::info << "StarTrackerHandler::handleVersionTm: Program: " + << static_cast(versionSet.program.value) << std::endl; + sif::info << "StarTrackerHandler::handleVersionTm: Major: " + << static_cast(versionSet.major.value) << std::endl; + sif::info << "StarTrackerHandler::handleVersionTm: Minor: " + << static_cast(versionSet.minor.value) << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return result; +} + +ReturnValue_t StarTrackerHandler::handleInterfaceTm() { + ReturnValue_t result = RETURN_OK; + PoolReadGuard rg(&interfaceSet); + uint32_t offset = TM_DATA_FIELD_OFFSET; + uint8_t status = 0; + uint32_t ticks = 0; + uint64_t time = 0; + getTmHeaderData(&status, &ticks, &time); + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleInterfaceTm: Reply error: " + << static_cast(status) << std::endl; + result = INTERFACE_REQ_FAILED; + return result; + } + interfaceSet.ticks = ticks; + interfaceSet.time = time; + size_t size = sizeof(uint32_t); + interfaceSet.frameCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.checksumerrorCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.setParamCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.setParamReplyCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.paramRequestCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.paramReplyCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.tmReplyCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.actionReqCount = deserializeUint32(decodedFrame + offset); + offset += size; + interfaceSet.actionReplyCount = deserializeUint32(decodedFrame + offset); + +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTrackerHandler::handleInterfaceTm: Ticks: " + << interfaceSet.ticks << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Time: " + << interfaceSet.time << " us" << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Frame Count: " + << interfaceSet.frameCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Checksum Error Count: " + << interfaceSet.checksumerrorCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Set Param Count: " + << interfaceSet.setParamCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Set Param Reply Count: " + << interfaceSet.setParamReplyCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Param Request Count: " + << interfaceSet.paramRequestCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Param Reply Count: " + << interfaceSet.paramReplyCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Req TM Count: " + << interfaceSet.reqTmCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Telemetry Reply Count: " + << interfaceSet.tmReplyCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Action Request Count: " + << interfaceSet.actionReqCount << std::endl; + sif::info << "StarTrackerHandler::handleInterfaceTm: Action Reply Count: " + << interfaceSet.actionReplyCount << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return result; +} + +ReturnValue_t StarTrackerHandler::handlePowerTm() { + ReturnValue_t result = RETURN_OK; + PoolReadGuard rg(&powerSet); + uint32_t offset = TM_DATA_FIELD_OFFSET; + uint8_t status = 0; + uint32_t ticks = 0; + uint64_t time = 0; + getTmHeaderData(&status, &ticks, &time); + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handlePowerTm: Reply error: " + << static_cast(status) << std::endl; + result = POWER_REQ_FAILED; + return result; + } + powerSet.ticks= ticks; + powerSet.time= time; + float value = 0; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.mcuCurrent = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.mcuVoltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.fpgaCoreCurrent = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.fpgaCoreVoltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.fpga18Current = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.fpga18Voltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.fpga25Current = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.fpga25Voltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmv21Current = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmv21Voltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmvPixCurrent= value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmvPixVoltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmv33Current= value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmv33Voltage = value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmvResCurrent= value; + offset += 4; + std::memcpy(&value, decodedFrame + offset, sizeof(value)); + powerSet.cmvResVoltage = value; +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTrackerHandler::handlePowerTm: Ticks: " + << powerSet.ticks << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: Time: " + << powerSet.time << " us" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: MCU Current: " + << powerSet.mcuCurrent << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: MCU Voltage: " + << powerSet.mcuVoltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: FPGA Core current: " + << powerSet.fpgaCoreCurrent << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: FPGA Core voltage: " + << powerSet.fpgaCoreVoltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: FPGA 18 current: " + << powerSet.fpga18Current << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: FPGA 18 voltage: " + << powerSet.fpga18Voltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: FPGA 25 current: " + << powerSet.fpga25Current << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: FPGA 25 voltage: " + << powerSet.fpga25Voltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV 21 current: " + << powerSet.cmv21Current << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV 21 voltage: " + << powerSet.cmv21Voltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV Pix current: " + << powerSet.cmvPixCurrent << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV Pix voltage: " + << powerSet.cmvPixVoltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV 33 current: " + << powerSet.cmv33Current << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV 33 voltage: " + << powerSet.cmv33Voltage << " V" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV Res current: " + << powerSet.cmvResCurrent << " A" << std::endl; + sif::info << "StarTrackerHandler::handlePowerTm: CMV Res voltage: " + << powerSet.cmvResVoltage << " V" << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return result; +} + +ReturnValue_t StarTrackerHandler::handleSolutionTm() { + ReturnValue_t result = RETURN_OK; + result = solutionSet.read(MutexIF::TimeoutType::WAITING, 20); + if (result != RETURN_OK) { + return result; + } + uint32_t offset = TM_DATA_FIELD_OFFSET; + uint8_t status = 0; + uint32_t ticks = 0; + uint64_t time = 0; + getTmHeaderData(&status, &ticks, &time); if(status != StarTracker::STATUS_OK) { sif::warning << "StarTrackerHandler::handleTemperatureTm: Reply error: " << static_cast(status) << std::endl; - result = TEMPERATURE_REQUEST_FAILED; + result = TEMPERATURE_REQ_FAILED; + return result; + } + solutionSet.ticks= ticks; + solutionSet.time= time; + float word = 0; + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.caliQw = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.caliQx = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.caliQy = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.caliQz = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.trackConfidence = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.trackQw = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.trackQx = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.trackQy = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.trackQz = word; + offset += sizeof(float); + solutionSet.trackRemoved = *(decodedFrame + offset); + offset += sizeof(uint8_t); + solutionSet.starsCentroided = *(decodedFrame + offset); + offset += sizeof(uint8_t); + solutionSet.starsMatchedDatabase = *(decodedFrame + offset); + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.lisaQw = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.lisaQx = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.lisaQy = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.lisaQz = word; + offset += sizeof(float); + std::memcpy(&word, decodedFrame + offset, sizeof(float)); + solutionSet.lisaPercentageClose = word; + offset += sizeof(float); + solutionSet.lisaNrClose = *(decodedFrame + offset); + offset += sizeof(uint8_t); + solutionSet.isTrustWorthy = *(decodedFrame + offset); + offset += sizeof(uint8_t); + solutionSet.stableCount = *(decodedFrame + offset); + offset += sizeof(uint32_t); + solutionSet.stableCount = *(decodedFrame + offset); + result = solutionSet.commit(MutexIF::TimeoutType::WAITING, 20); + if (result != RETURN_OK) { return result; } - versionSet.program = (*decodedFrame + offset); - offset += 1; - versionSet.major = (*decodedFrame + offset); - offset += 1; - versionSet.minor = (*decodedFrame + offset); #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTrackerHandler::handleVersionTm: Program: " - << versionSet.program << std::endl; - sif::info << "StarTrackerHandler::handleVersionTm: Major: " - << versionSet.major << std::endl; - sif::info << "StarTrackerHandler::handleVersionTm: Minor: " - << versionSet.minor << std::endl; -#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + solutionSet.printSet(); +#endif return result; } ReturnValue_t StarTrackerHandler::handleTemperatureTm() { ReturnValue_t result = RETURN_OK; PoolReadGuard rg(&temperatureSet); - uint32_t offset = 2; - uint8_t status = *(decodedFrame + offset); - offset += 1; + uint32_t offset = TM_DATA_FIELD_OFFSET; + uint8_t status = 0; + uint32_t ticks = 0; + uint64_t time = 0; + getTmHeaderData(&status, &ticks, &time); if(status != StarTracker::STATUS_OK) { sif::warning << "StarTrackerHandler::handleTemperatureTm: Reply error: " << static_cast(status) << std::endl; - result = TEMPERATURE_REQUEST_FAILED; + result = TEMPERATURE_REQ_FAILED; return result; } - const uint8_t* buffer = decodedFrame + offset; - size_t size = sizeof(temperatureSet.ticks); - SerializeAdapter::deSerialize(&temperatureSet.ticks, &buffer, &size, SerializeIF::Endianness::LITTLE); - offset += size; - buffer = decodedFrame + offset; - size = sizeof(temperatureSet.time); - SerializeAdapter::deSerialize(&temperatureSet.time, &buffer, &size, SerializeIF::Endianness::LITTLE); - offset += size; - temperatureSet.mcuTemperature = *(decodedFrame + offset) << 24 - | *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8 - | *(decodedFrame + offset + 3); - offset += sizeof(temperatureSet.mcuTemperature); - temperatureSet.mcuTemperature = *(decodedFrame + offset) << 24 - | *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8 - | *(decodedFrame + offset + 3); + temperatureSet.ticks= ticks; + temperatureSet.time= time; + float temperature = 0; + std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); + temperatureSet.mcuTemperature = temperature; + offset += sizeof(temperature); + std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); + temperatureSet.cmosTemperature = temperature; #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTrackerHandler::handleTemperatureTm: Ticks: " - << temperatureSet.ticks << std::endl; - sif::info << "StarTrackerHandler::handleTemperatureTm: Time: " - << temperatureSet.time << std::endl; - sif::info << "StarTrackerHandler::handleTemperatureTm: MCU Temperature: " - << temperatureSet.mcuTemperature << " °C" << std::endl; - sif::info << "StarTrackerHandler::handleTemperatureTm: CMOS Temperature: " - << temperatureSet.mcuTemperature << " °C" << std::endl; + solutionSet.printSet(); #endif return result; } + +void StarTrackerHandler::getTmHeaderData(uint8_t* status, uint32_t* ticks, uint64_t* time) { + *status = *(decodedFrame + STATUS_OFFSET); + *ticks = deserializeUint32(decodedFrame + TICKS_OFFSET); + *time = deserializeUint64(decodedFrame + TIME_OFFSET); +} + +uint32_t StarTrackerHandler::deserializeUint32(uint8_t* buffer) { + uint32_t word = 0; + word = *(buffer + 3) << 24 + | *(buffer + 2) << 16 + | *(buffer + 1) << 8 + | *(buffer); + return word; +} + +uint64_t StarTrackerHandler::deserializeUint64(uint8_t* buffer) { + uint64_t word = 0; + word = static_cast(*(buffer + 7)) << 56 + | static_cast(*(buffer + 6)) << 48 + | static_cast(*(buffer + 5)) << 40 + | static_cast(*(buffer + 4)) << 32 + | static_cast(*(buffer + 3)) << 24 + | static_cast(*(buffer + 2)) << 16 + | static_cast(*(buffer + 1)) << 8 + | static_cast(*(buffer)); + return word; +} diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index 89bd7097..a4389296 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -5,6 +5,7 @@ #include #include #include +#include /** * @brief This is the device handler for the star tracker from arcsec. @@ -63,16 +64,38 @@ private: static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; - //! [EXPORT] : [COMMENT] Status in tm reply not ok - static const ReturnValue_t TEMPERATURE_REQUEST_FAILED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Status in temperature reply signals error + static const ReturnValue_t TEMPERATURE_REQ_FAILED = MAKE_RETURN_CODE(0xA0); //! [EXPORT] : [COMMENT] Ping command failed static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Status in version reply signals error + static const ReturnValue_t VERSION_REQ_FAILED = MAKE_RETURN_CODE(0xA3); + //! [EXPORT] : [COMMENT] Status in interface reply signals error + static const ReturnValue_t INTERFACE_REQ_FAILED = MAKE_RETURN_CODE(0xA4); + //! [EXPORT] : [COMMENT] Status in power reply signals error + static const ReturnValue_t POWER_REQ_FAILED = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] Status of reply to parameter set command signals error + static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA6); + //! [EXPORT] : [COMMENT] Status of reply to action command signals error + static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA7); + + static const uint8_t STATUS_OFFSET = 2; + static const uint8_t TICKS_OFFSET = 3; + static const uint8_t TIME_OFFSET = 7; + static const uint8_t TM_DATA_FIELD_OFFSET = 15; + static const uint8_t PARAMETER_ID_OFFSET = 1; + static const uint8_t ACTION_ID_OFFSET = 1; // Ping request will reply ping with this ID (data field) static const uint32_t PING_ID = 0x55; + static const uint32_t BOOT_REGION_ID = 1; StarTracker::TemperatureSet temperatureSet; StarTracker::VersionSet versionSet; + StarTracker::PowerSet powerSet; + StarTracker::InterfaceSet interfaceSet; + StarTracker::TimeSet timeSet; + StarTracker::SolutionSet solutionSet; uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; @@ -94,27 +117,86 @@ private: */ void slipInit(); + ReturnValue_t scanForActionReply(DeviceCommandId_t *foundId); + ReturnValue_t scanForSetParameterReply(DeviceCommandId_t *foundId); + ReturnValue_t scanForTmReply(DeviceCommandId_t *foundId); + /** * @brief Fills command buffer with data to ping the star tracker */ void preparePingRequest(); + /** + * @brief Fills command buffer with data to request the time telemetry. + */ + void prepareTimeRequest(); + + /** + * @brief Fills command buffer with data to boot image (works only when star tracker is + * in bootloader mode). + */ + void prepareBootCommand(); + /** * @brief Fills command buffer with data to request the version telemetry packet */ void prepareVersionRequest(); + /** + * @brief Fills the command buffer with data to request the interface telemetry packet. + */ + void prepareInterfaceRequest(); + + /** + * @brief Fills the command buffer with data to request the power telemetry packet. + */ + void preparePowerRequest(); + /** * @brief Fills command buffer with data to reboot star tracker. */ void prepareRebootCommand(); + /** + * @brief Fills command buffer with data to subscribe to a telemetry packet. + * + * @param tmId The ID of the telemetry packet to subscribe to + */ + void prepareSubscriptionCommand(const uint8_t* tmId); + + /** + * @brief Fills command buffer with data to request solution telemtry packet (contains + * attitude information) + */ + void prepareSolutionRequest(); + /** * @brief Fills command buffer with data to request temperature from star tracker */ void prepareTemperatureRequest(); + /** + * @brief Default function to handle action replies + */ + ReturnValue_t handleActionReply(); + + /** + * @brief Handles all set parameter replies + */ + ReturnValue_t handleSetParamReply(); + ReturnValue_t handlePingReply(); + + /** + * @brief Fills the time set with the data of the time request reply. + */ + ReturnValue_t handleTimeTm(); + + /** + * @brief Handles reply data of solution request. + */ + ReturnValue_t handleSolutionTm(); + /** * @brief This function handles the telemetry reply of a temperature request. */ @@ -124,6 +206,43 @@ private: * @brief This function handles the telemetry reply of a version request. */ ReturnValue_t handleVersionTm(); + + /** + * @brief Handles reply to request interface telemetry command. + */ + ReturnValue_t handleInterfaceTm(); + + /** + * @brief Handles reply to request power telemetry command. + */ + ReturnValue_t handlePowerTm(); + + /** + * @brief Extracts the header data of a received telemetry frame + */ + void getTmHeaderData(uint8_t* status, uint32_t* ticks, uint64_t* time); + + /** + * @brief This function deserializes 8 bytes into a 32 bit unsigned integer. + * + * @param buffer Pointer to buffer holding the data to deserialize + * + * @return The 32-bit unsigned integer. + * + * @note Deserialization will be performed in little endian byte order + */ + uint32_t deserializeUint32(uint8_t* buffer); + + /** + * @brief This function deserializes 8 bytes into a 64 bit unsigned integer. + * + * @param buffer Pointer to buffer holding the data to deserialize + * + * @return The 64-bit unsigned integer. + * + * @note Deserialization will be performed in little endian byte order + */ + uint64_t deserializeUint64(uint8_t* buffer); }; #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index 6772abfe..ca671d8e 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -5,6 +5,7 @@ #include #include #include "objects/systemObjectList.h" +#include namespace StarTracker { @@ -14,32 +15,117 @@ static const uint8_t ADDRESS = 33; static const uint8_t STATUS_OK = 0; enum PoolIds: lp_id_t { + TICKS_TIME_SET, + TIME_TIME_SET, + RUN_TIME, + UNIX_TIME, TICKS_VERSION_SET, TIME_VERSION_SET, + PROGRAM, + MAJOR, + MINOR, + TICKS_INTERFACE_SET, + TIME_INTERFACE_SET, + FRAME_COUNT, + CHECKSUM_ERROR_COUNT, + SET_PARAM_COUNT, + SET_PARAM_REPLY_COUNT, + PARAM_REQUEST_COUNT, + PARAM_REPLY_COUNT, + REQ_TM_COUNT, + TM_REPLY_COUNT, + ACTION_REQ_COUNT, + ACTION_REPLY_COUNT, + TICKS_POWER_SET, + TIME_POWER_SET, + MCU_CURRENT, + MCU_VOLTAGE, + FPGA_CORE_CURRENT, + FPGA_CORE_VOLTAGE, + FPGA_18_CURRENT, + FPGA_18_VOLTAGE, + FPGA_25_CURRENT, + FPGA_25_VOLTAGE, + CMV_21_CURRENT, + CMV_21_VOLTAGE, + CMV_PIX_CURRENT, + CMV_PIX_VOLTAGE, + CMV_33_CURRENT, + CMV_33_VOLTAGE, + CMV_RES_CURRENT, + CMV_RES_VOLTAGE, TICKS_TEMPERATURE_SET, TIME_TEMPERATURE_SET, MCU_TEMPERATURE, CMOS_TEMPERATURE, - PROGRAM, - MAJOR, - MINOR + + TICKS_SOLUTION_SET, + TIME_SOLUTION_SET, + CALI_QW, + CALI_QX, + CALI_QY, + CALI_QZ, + TRACK_CONFIDENCE, + TRACK_QW, + TRACK_QX, + TRACK_QY, + TRACK_QZ, + TRACK_REMOVED, + STARS_CENTROIDED, + STARS_MATCHED_DATABASE, + LISA_QW, + LISA_QX, + LISA_QY, + LISA_QZ, + LISA_PERC_CLOSE, + LISA_NR_CLOSE, + TRUST_WORTHY, + STABLE_COUNT, + SOLUTION_STRATEGY }; - - static const DeviceCommandId_t PING_REQUEST = 0; +// Boots image (works only in bootloader mode) +static const DeviceCommandId_t BOOT = 1; static const DeviceCommandId_t REQ_VERSION = 2; +static const DeviceCommandId_t REQ_INTERFACE = 3; +static const DeviceCommandId_t REQ_TIME = 4; static const DeviceCommandId_t REBOOT = 7; +static const DeviceCommandId_t REQ_POWER = 11; +static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; +static const DeviceCommandId_t REQ_SOLUTION = 24; static const DeviceCommandId_t REQ_TEMPERATURE = 25; static const uint32_t VERSION_SET_ID = REQ_VERSION; +static const uint32_t INTERFACE_SET_ID = REQ_INTERFACE; +static const uint32_t POWER_SET_ID = REQ_POWER; static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE; +static const uint32_t TIME_SET_ID = REQ_TIME; +static const uint32_t SOLUTION_SET_ID = REQ_SOLUTION; /** Max size of unencoded frame */ static const size_t MAX_FRAME_SIZE = 1200; static const uint8_t TEMPERATURE_SET_ENTRIES = 4; -static const uint8_t VERSION_SET_ENTRIES = 3; +static const uint8_t VERSION_SET_ENTRIES = 5; +static const uint8_t INTERFACE_SET_ENTRIES = 12; +static const uint8_t POWER_SET_ENTRIES = 18; +static const uint8_t TIME_SET_ENTRIES = 4; +static const uint8_t SOLUTION_SET_ENTRIES = 23; + +// Action, parameter and telemetry IDs +namespace ID { + static const uint8_t PING = 0; + static const uint8_t BOOT = 1; + static const uint8_t VERSION = 2; + static const uint8_t INTERFACE = 3; + static const uint8_t REBOOT = 7; + static const uint8_t POWER = 11; + static const uint8_t SUBSCRIBE = 18; + static const uint8_t SOLUTION = 24; + static const uint8_t TEMPERATURE = 25; + static const uint8_t TIME = 1; +} /** * @brief This dataset can be used to store the temperature of a reaction wheel. @@ -97,7 +183,262 @@ public: PoolIds::MINOR, this); }; +/** + * @brief Dataset to store the interface telemtry data. + */ +class InterfaceSet: + public StaticLocalDataSet { +public: + + InterfaceSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, REQ_INTERFACE) { + } + + InterfaceSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) { + } + + // Ticks is time reference generated by interanl counter of the star tracker + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_INTERFACE_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_INTERFACE_SET, this); + lp_var_t frameCount = lp_var_t(sid.objectId, + PoolIds::FRAME_COUNT, this); + lp_var_t checksumerrorCount = lp_var_t(sid.objectId, + PoolIds::CHECKSUM_ERROR_COUNT, this); + lp_var_t setParamCount = lp_var_t(sid.objectId, + PoolIds::SET_PARAM_COUNT, this); + lp_var_t setParamReplyCount = lp_var_t(sid.objectId, + PoolIds::SET_PARAM_REPLY_COUNT, this); + lp_var_t paramRequestCount = lp_var_t(sid.objectId, + PoolIds::PARAM_REQUEST_COUNT, this); + lp_var_t paramReplyCount = lp_var_t(sid.objectId, + PoolIds::PARAM_REPLY_COUNT, this); + lp_var_t reqTmCount = lp_var_t(sid.objectId, + PoolIds::REQ_TM_COUNT, this); + lp_var_t tmReplyCount = lp_var_t(sid.objectId, + PoolIds::TM_REPLY_COUNT, this); + lp_var_t actionReqCount = lp_var_t(sid.objectId, + PoolIds::ACTION_REQ_COUNT, this); + lp_var_t actionReplyCount = lp_var_t(sid.objectId, + PoolIds::ACTION_REPLY_COUNT, this); +}; + +/** + * @brief Dataset to store the data of the power telemetry reply. + */ +class PowerSet: + public StaticLocalDataSet { +public: + + PowerSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, REQ_INTERFACE) { + } + + PowerSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) { + } + + // Ticks is time reference generated by interanl counter of the star tracker + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_POWER_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_POWER_SET, this); + lp_var_t mcuCurrent = lp_var_t(sid.objectId, + PoolIds::MCU_CURRENT, this); + lp_var_t mcuVoltage = lp_var_t(sid.objectId, + PoolIds::MCU_VOLTAGE, this); + lp_var_t fpgaCoreCurrent = lp_var_t(sid.objectId, + PoolIds::FPGA_CORE_CURRENT, this); + lp_var_t fpgaCoreVoltage = lp_var_t(sid.objectId, + PoolIds::FPGA_CORE_VOLTAGE, this); + lp_var_t fpga18Current = lp_var_t(sid.objectId, + PoolIds::FPGA_18_CURRENT, this); + lp_var_t fpga18Voltage = lp_var_t(sid.objectId, + PoolIds::FPGA_18_VOLTAGE, this); + lp_var_t fpga25Current = lp_var_t(sid.objectId, + PoolIds::FPGA_25_CURRENT, this); + lp_var_t fpga25Voltage = lp_var_t(sid.objectId, + PoolIds::FPGA_25_VOLTAGE, this); + lp_var_t cmv21Current = lp_var_t(sid.objectId, + PoolIds::CMV_21_CURRENT, this); + lp_var_t cmv21Voltage = lp_var_t(sid.objectId, + PoolIds::CMV_21_VOLTAGE, this); + lp_var_t cmvPixCurrent = lp_var_t(sid.objectId, + PoolIds::CMV_PIX_CURRENT, this); + lp_var_t cmvPixVoltage = lp_var_t(sid.objectId, + PoolIds::CMV_PIX_VOLTAGE, this); + lp_var_t cmv33Current = lp_var_t(sid.objectId, + PoolIds::CMV_33_CURRENT, this); + lp_var_t cmv33Voltage = lp_var_t(sid.objectId, + PoolIds::CMV_33_VOLTAGE, this); + lp_var_t cmvResCurrent = lp_var_t(sid.objectId, + PoolIds::CMV_RES_CURRENT, this); + lp_var_t cmvResVoltage = lp_var_t(sid.objectId, + PoolIds::CMV_RES_VOLTAGE, this); +}; + +/** + * @brief Data set to store the time telemetry packet. + */ +class TimeSet: + public StaticLocalDataSet { +public: + + TimeSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, TIME_SET_ID) { + } + + TimeSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, TIME_SET_ID)) { + } + + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_TIME_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_TIME_SET, this); + // Number of milliseconds since processor start-up + lp_var_t runTime = lp_var_t(sid.objectId, + PoolIds::RUN_TIME, this); + // Unix time in seconds?? --> maybe typo in datasheet. Seems to be microseconds + lp_var_t unixTime = lp_var_t(sid.objectId, + PoolIds::UNIX_TIME, this); +}; + +/** + * @brief The solution dataset is the main dataset of the star tracker and contains the + * attitude information. + */ +class SolutionSet: + public StaticLocalDataSet { +public: + + SolutionSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, SOLUTION_SET_ID) { + } + + SolutionSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, SOLUTION_SET_ID)) { + } + + // Ticks timestamp + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_SOLUTION_SET, this); + /// Unix time stamp + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_SOLUTION_SET, this); + // Calibrated quaternion (takes into account the mounting quaternion), typically same as + // track q values + lp_var_t caliQw = lp_var_t(sid.objectId, + PoolIds::CALI_QW, this); + lp_var_t caliQx = lp_var_t(sid.objectId, + PoolIds::CALI_QX, this); + lp_var_t caliQy = lp_var_t(sid.objectId, + PoolIds::CALI_QY, this); + lp_var_t caliQz = lp_var_t(sid.objectId, + PoolIds::CALI_QZ, this); + // The lower this value the more confidence that the star tracker solution is correct + lp_var_t trackConfidence = lp_var_t(sid.objectId, + PoolIds::TRACK_CONFIDENCE, this); + // Estimated attitude of spacecraft + lp_var_t trackQw = lp_var_t(sid.objectId, + PoolIds::TRACK_QW, this); + lp_var_t trackQx = lp_var_t(sid.objectId, + PoolIds::TRACK_QX, this); + lp_var_t trackQy = lp_var_t(sid.objectId, + PoolIds::TRACK_QY, this); + lp_var_t trackQz = lp_var_t(sid.objectId, + PoolIds::TRACK_QZ, this); + // Number of stars removed from tracking solution + lp_var_t trackRemoved = lp_var_t(sid.objectId, + PoolIds::TRACK_REMOVED, this); + // Number of stars for which a valid centroid was found + lp_var_t starsCentroided = lp_var_t(sid.objectId, + PoolIds::STARS_CENTROIDED, this); + // Number of stars that matched to a database star + lp_var_t starsMatchedDatabase = lp_var_t(sid.objectId, + PoolIds::STARS_MATCHED_DATABASE, this); + // Result of LISA (lost in space algorithm), searches for stars without prior knowledge of + // attitude + lp_var_t lisaQw = lp_var_t(sid.objectId, + PoolIds::LISA_QW, this); + lp_var_t lisaQx = lp_var_t(sid.objectId, + PoolIds::LISA_QX, this); + lp_var_t lisaQy = lp_var_t(sid.objectId, + PoolIds::LISA_QY, this); + lp_var_t lisaQz = lp_var_t(sid.objectId, + PoolIds::LISA_QZ, this); + // Percentage of close stars in LISA solution + lp_var_t lisaPercentageClose = lp_var_t(sid.objectId, + PoolIds::LISA_PERC_CLOSE, this); + // Number of close stars in LISA solution + lp_var_t lisaNrClose = lp_var_t(sid.objectId, + PoolIds::LISA_NR_CLOSE, this); + // Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0) + lp_var_t isTrustWorthy = lp_var_t(sid.objectId, + PoolIds::TRUST_WORTHY, this); + // Number of times the validation criteria was met + lp_var_t stableCount = lp_var_t(sid.objectId, + PoolIds::STABLE_COUNT, this); + // Shows the autonomous mode used to obtain the star tracker attitude + lp_var_t solutionStrategy = lp_var_t(sid.objectId, + PoolIds::SOLUTION_STRATEGY, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "SolutionSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "SolutionSet::printSet: Time: " + << this->time << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qw: " + << this->caliQw << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qx: " + << this->caliQx << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qy: " + << this->caliQy << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qz: " + << this->caliQz << std::endl; + sif::info << "SolutionSet::printSet: Track confidence: " + << this->trackConfidence << std::endl; + sif::info << "SolutionSet::printSet: Track Qw: " + << this->trackQw << std::endl; + sif::info << "SolutionSet::printSet: Track Qx: " + << this->trackQx << std::endl; + sif::info << "SolutionSet::printSet: Track Qy: " + << this->trackQy << std::endl; + sif::info << "SolutionSet::printSet: Track Qz: " + << this->trackQz << std::endl; + sif::info << "SolutionSet::printSet: Track removed: " + << static_cast(this->trackRemoved) << std::endl; + sif::info << "SolutionSet::printSet: Number of stars centroided: " + << static_cast(this->starsCentroided) << std::endl; + sif::info << "SolutionSet::printSet: Number of stars matched database: " + << static_cast(this->starsMatchedDatabase) << std::endl; + sif::info << "SolutionSet::printSet: LISA Qw: " + << this->lisaQw << std::endl; + sif::info << "SolutionSet::printSet: LISA Qx: " + << this->lisaQx << std::endl; + sif::info << "SolutionSet::printSet: LISA Qy: " + << this->lisaQy << std::endl; + sif::info << "SolutionSet::printSet: LISA Qz: " + << this->lisaQz << std::endl; + sif::info << "SolutionSet::printSet: LISA Percentage close: " + << this->lisaPercentageClose << std::endl; + sif::info << "SolutionSet::printSet: LISA number of close stars: " + << static_cast(this->lisaNrClose) << std::endl; + sif::info << "SolutionSet::printSet: Is trust worthy: " + << static_cast(this->isTrustWorthy) << std::endl; + sif::info << "SolutionSet::printSet: Stable count: " + << this->stableCount << std::endl; + sif::info << "SolutionSet::printSet: Solution strategy: " + << static_cast(this->solutionStrategy) << std::endl; + } +}; + } #endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */ - From b84bdcc0fcb7fed25c74b3ac80447ece2338cee3 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sun, 28 Nov 2021 09:57:14 +0100 Subject: [PATCH 06/78] moved print set of temperature set and time set to dataset class --- mission/devices/StarTrackerHandler.cpp | 35 +++++++++++-------- mission/devices/StarTrackerHandler.h | 3 ++ .../StarTrackerDefinitions.h | 22 ++++++++++++ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index ce69d41d..f8c465e7 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -563,7 +563,10 @@ ReturnValue_t StarTrackerHandler::handlePingReply() { ReturnValue_t StarTrackerHandler::handleTimeTm() { ReturnValue_t result = RETURN_OK; - PoolReadGuard rg(&timeSet); + result = timeSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } uint32_t offset = TM_DATA_FIELD_OFFSET; uint8_t status = 0; uint32_t ticks = 0; @@ -580,15 +583,12 @@ ReturnValue_t StarTrackerHandler::handleTimeTm() { timeSet.runTime = deserializeUint32(decodedFrame + offset); offset += sizeof(uint32_t); timeSet.unixTime = deserializeUint64(decodedFrame + offset); + result = timeSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTrackerHandler::handleTimeTm: Ticks: " - << timeSet.ticks << std::endl; - sif::info << "StarTrackerHandler::handleTimeTm: Time (time stamp): " - << timeSet.time << " us" << std::endl; - sif::info << "StarTrackerHandler::handleTimeTm: Run Time: " - << timeSet.runTime << " ms" << std::endl; - sif::info << "StarTrackerHandler::handleTimeTm: Unix Time: " - << timeSet.unixTime << " s" << std::endl; + timeSet.printSet(); #endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ return result; } @@ -800,7 +800,7 @@ ReturnValue_t StarTrackerHandler::handlePowerTm() { ReturnValue_t StarTrackerHandler::handleSolutionTm() { ReturnValue_t result = RETURN_OK; - result = solutionSet.read(MutexIF::TimeoutType::WAITING, 20); + result = solutionSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { return result; } @@ -810,7 +810,7 @@ ReturnValue_t StarTrackerHandler::handleSolutionTm() { uint64_t time = 0; getTmHeaderData(&status, &ticks, &time); if(status != StarTracker::STATUS_OK) { - sif::warning << "StarTrackerHandler::handleTemperatureTm: Reply error: " + sif::warning << "StarTrackerHandler::handleSolutioneTm: Reply error: " << static_cast(status) << std::endl; result = TEMPERATURE_REQ_FAILED; return result; @@ -873,7 +873,7 @@ ReturnValue_t StarTrackerHandler::handleSolutionTm() { solutionSet.stableCount = *(decodedFrame + offset); offset += sizeof(uint32_t); solutionSet.stableCount = *(decodedFrame + offset); - result = solutionSet.commit(MutexIF::TimeoutType::WAITING, 20); + result = solutionSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { return result; } @@ -885,7 +885,6 @@ ReturnValue_t StarTrackerHandler::handleSolutionTm() { ReturnValue_t StarTrackerHandler::handleTemperatureTm() { ReturnValue_t result = RETURN_OK; - PoolReadGuard rg(&temperatureSet); uint32_t offset = TM_DATA_FIELD_OFFSET; uint8_t status = 0; uint32_t ticks = 0; @@ -897,6 +896,10 @@ ReturnValue_t StarTrackerHandler::handleTemperatureTm() { result = TEMPERATURE_REQ_FAILED; return result; } + result = temperatureSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } temperatureSet.ticks= ticks; temperatureSet.time= time; float temperature = 0; @@ -905,8 +908,12 @@ ReturnValue_t StarTrackerHandler::handleTemperatureTm() { offset += sizeof(temperature); std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); temperatureSet.cmosTemperature = temperature; + result = temperatureSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - solutionSet.printSet(); + temperatureSet.printSet(); #endif return result; } diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index a4389296..67b957de 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -90,6 +90,9 @@ private: static const uint32_t PING_ID = 0x55; static const uint32_t BOOT_REGION_ID = 1; + static const MutexIF::TimeoutType TIMEOUT_TYPE= MutexIF::TimeoutType::WAITING; + static const uint32_t MUTEX_TIMEOUT = 20; + StarTracker::TemperatureSet temperatureSet; StarTracker::VersionSet versionSet; StarTracker::PowerSet powerSet; diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index ca671d8e..8546f843 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -152,6 +152,17 @@ public: PoolIds::MCU_TEMPERATURE, this); lp_var_t cmosTemperature = lp_var_t(sid.objectId, PoolIds::CMOS_TEMPERATURE, this); + + void printSet() { + sif::info << "TemperatureSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "TemperatureSet::printSet: Time: " + << this->time << " us" << std::endl; + sif::info << "TemperatureSet::printSet: MCU Temperature: " + << this->mcuTemperature << " °C" << std::endl; + sif::info << "TemperatureSet::printSet: CMOS Temperature: " + << this->mcuTemperature << " °C" << std::endl; + } }; /** @@ -307,6 +318,17 @@ public: // Unix time in seconds?? --> maybe typo in datasheet. Seems to be microseconds lp_var_t unixTime = lp_var_t(sid.objectId, PoolIds::UNIX_TIME, this); + void printSet() { + PoolReadGuard rg(this); + sif::info << "TimeSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "TimeSet::printSet: Time (time stamp): " + << this->time << " us" << std::endl; + sif::info << "TimeSet::printSet: Run Time: " + << this->runTime << " ms" << std::endl; + sif::info << "TimeSet::printSet: Unix Time: " + << this->unixTime << " s" << std::endl; + } }; /** From 077913400fa2bca51ba8de5ddaf83578adad6547 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 29 Nov 2021 11:04:56 +0100 Subject: [PATCH 07/78] star tracker image helper --- bsp_q7s/core/ObjectFactory.cpp | 2 + bsp_q7s/devices/CMakeLists.txt | 1 + bsp_q7s/devices/PlocUpdater.cpp | 4 +- bsp_q7s/devices/StarTrackerImageHelper.cpp | 291 ++++++++++++++++++ bsp_q7s/devices/StarTrackerImageHelper.h | 150 +++++++++ common/config/commonClassIds.h | 1 + common/config/commonObjects.h | 3 +- common/config/commonSubsystemIds.h | 1 + linux/fsfwconfig/OBSWConfig.h.in | 3 +- .../pollingSequenceFactory.cpp | 1 + mission/devices/StarTrackerHandler.cpp | 173 +++++------ mission/devices/StarTrackerHandler.h | 27 +- .../StarTrackerDefinitions.h | 89 ++++-- 13 files changed, 632 insertions(+), 114 deletions(-) create mode 100644 bsp_q7s/devices/StarTrackerImageHelper.cpp create mode 100644 bsp_q7s/devices/StarTrackerImageHelper.h diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 83b59d08..44e4484b 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -16,6 +16,7 @@ #include "bsp_q7s/devices/PlocSupervisorHandler.h" #include "bsp_q7s/devices/PlocUpdater.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" +#include "bsp_q7s/devices/StarTrackerImageHelper.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h" @@ -173,6 +174,7 @@ void ObjectFactory::produce(void* args) { starTrackerCookie->setNoFixedSizeReply(); StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie); starTrackerHandler->setStartUpImmediately(); + new StarTrackerImageHelper(objects::STR_IMG_HELPER); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* TE7020 == 0 */ diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt index 6347b5f8..ecc6bdc1 100644 --- a/bsp_q7s/devices/CMakeLists.txt +++ b/bsp_q7s/devices/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources(${TARGET_NAME} PRIVATE PlocSupervisorHandler.cpp PlocUpdater.cpp PlocMemoryDumper.cpp + StarTrackerImageHelper.cpp ) \ No newline at end of file diff --git a/bsp_q7s/devices/PlocUpdater.cpp b/bsp_q7s/devices/PlocUpdater.cpp index 5a94495b..4771e14c 100644 --- a/bsp_q7s/devices/PlocUpdater.cpp +++ b/bsp_q7s/devices/PlocUpdater.cpp @@ -169,13 +169,13 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { // Check if file is stored on SD card and if associated SD card is mounted if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl; + sif::warning << "PlocUpdater::getImageLocation: SD card 0 not mounted" << std::endl; return SD_NOT_MOUNTED; } } else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl; + sif::warning << "PlocUpdater::getImageLocation: SD card 1 not mounted" << std::endl; return SD_NOT_MOUNTED; } } diff --git a/bsp_q7s/devices/StarTrackerImageHelper.cpp b/bsp_q7s/devices/StarTrackerImageHelper.cpp new file mode 100644 index 00000000..c225e3b9 --- /dev/null +++ b/bsp_q7s/devices/StarTrackerImageHelper.cpp @@ -0,0 +1,291 @@ +#include "fsfw/ipc/QueueFactory.h" +#include "StarTrackerImageHelper.h" + +#include +#include +#include + +StarTrackerImageHelper::StarTrackerImageHelper(object_id_t objectId) : + SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { + commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); +} + +StarTrackerImageHelper::~StarTrackerImageHelper() { +} + +ReturnValue_t StarTrackerImageHelper::initialize() { + sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "StarTrackerImageHelper::initialize: Invaldi SD Card Manager" << std::endl; + } + ReturnValue_t result = SystemObject::initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commandActionHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t StarTrackerImageHelper::performOperation(uint8_t operationCode) { + readCommandQueue(); + doStateMachine(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t StarTrackerImageHelper::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + ReturnValue_t result = EXECUTION_FINISHED; + + if (state != State::IDLE) { + return IS_BUSY; + } + + if (size > MAX_STR_IMAGE_PATH) { + return NAME_TOO_LONG; + } + + switch (actionId) { + case UPLOAD_IMAGE: + result = prepareUploadCommand(data, size); + if (result == RETURN_OK) { + result = EXECUTION_FINISHED; + } + break; + case DOWNLOAD_IMAGE: + break; + default: + return INVALID_ACTION_ID; + } + + return result; +} + +MessageQueueId_t StarTrackerImageHelper::getCommandQueue() const { + return commandQueue->getId(); +} + +MessageQueueIF* StarTrackerImageHelper::getCommandQueuePtr() { + return commandQueue; +} + +void StarTrackerImageHelper::readCommandQueue() { + CommandMessage message; + ReturnValue_t result; + + for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; + result = commandQueue->receiveMessage(&message)) { + if (result != RETURN_OK) { + continue; + } + result = actionHelper.handleActionMessage(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = commandActionHelper.handleReply(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + sif::debug << "StarTrackerImageHelper::readCommandQueue: Received inalid message" + << std::endl; + } +} + +void StarTrackerImageHelper::doStateMachine() { + switch (state) { + case State::IDLE: + break; + case State::SEND_NEXT_UPLOAD_CMD: + commandImageUpload(); + break; + case State::COMMAND_EXECUTING: + case State::UPLOAD_LAST: + break; + default: + sif::debug << "StarTrackerImageHelper::doStateMachine: Invalid state" << std::endl; + break; + } +} + +ReturnValue_t StarTrackerImageHelper::getImageLocation(const uint8_t* data, size_t size) { + + // Check if file is stored on SD card and if associated SD card is mounted + if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!isSdCardMounted(sd::SLOT_0)) { + sif::warning << "StarTrackerImageHelper::getImageLocation: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!isSdCardMounted(sd::SLOT_0)) { + sif::warning << "StarTrackerImageHelper::getImageLocation: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + else { + // Specified path in RAM filesystem + } + + imageFile = std::string(reinterpret_cast(data), size); + + // Check if file exists + if(not std::filesystem::exists(imageFile)) { + return FILE_NOT_EXISTS; + } + return RETURN_OK; +} + +bool StarTrackerImageHelper::isSdCardMounted(sd::SdCard sdCard) { + SdCardManager::SdStatePair active; + ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); + if (result != RETURN_OK) { + sif::debug << "StarTrackerImageHelper::isSdCardMounted: Failed to get SD card active state"; + return false; + } + if (sdCard == sd::SLOT_0) { + if (active.first == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else if (sdCard == sd::SLOT_1) { + if (active.second == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else { + sif::debug << "StarTrackerImageHelper::isSdCardMounted: Unknown SD card specified" << std::endl; + } + return false; +} + +ReturnValue_t StarTrackerImageHelper::prepareUploadCommand(const uint8_t* data, size_t size) { + ReturnValue_t result = RETURN_OK; + result = getImageLocation(data, size); + if (result != RETURN_OK) { + return result; + } + imageSize = std::filesystem::file_size(imageFile); + remainingCommands = imageSize / SIZE_IMAGE_PART ; + if (imageSize % SIZE_IMAGE_PART) { + remainingCommands++; + } + commandsSent = 0; + state = State::SEND_NEXT_UPLOAD_CMD; + return result; +} + +void StarTrackerImageHelper::stepSuccessfulReceived(ActionId_t actionId, + uint8_t step) { +} + +void StarTrackerImageHelper::stepFailedReceived(ActionId_t actionId, uint8_t step, + ReturnValue_t returnCode) { +} + +void StarTrackerImageHelper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { + +} + +void StarTrackerImageHelper::completionSuccessfulReceived(ActionId_t actionId) { + switch (pendingCommand) { + case (StarTracker::UPLOAD_IMAGE): + if (state == State::UPLOAD_LAST) { + triggerEvent(IMAGE_UPLOAD_FINISHED); + pendingCommand = StarTracker::NONE; + state = State::IDLE; + } + else { + state = State::SEND_NEXT_UPLOAD_CMD; + } + break; + default: + sif::debug << "StarTrackerImageHelper::completionSuccessfulReceived: Invalid pending command" + << std::endl; + state = State::IDLE; + break; + } +} + +void StarTrackerImageHelper::completionFailedReceived(ActionId_t actionId, + ReturnValue_t returnCode) { + switch(pendingCommand) { + case(StarTracker::UPLOAD_IMAGE): { + triggerEvent(IMAGE_UPLOAD_FAILED); + break; + } + default: + sif::debug << "StarTrackerImageHelper::completionFailedReceived: Invalid pending command " + << std::endl; + break; + } + state = State::IDLE; +} + +void StarTrackerImageHelper::commandImageUpload() { + ReturnValue_t result = RETURN_OK; + uint16_t dataLen = 0; + uint8_t tmpCommandBuffer[UPLOAD_COMMAND_SIZE] = {0}; + uint32_t position = commandsSent * SIZE_IMAGE_PART; + + if (not std::filesystem::exists(imageFile)) { + triggerEvent(IMAGE_FILE_NOT_EXISTS, commandsSent); + state = State::IDLE; + return; + } + + std::ifstream file(imageFile, std::ifstream::binary); + file.seekg(position, file.beg); + + if (remainingCommands == 1) { + dataLen = imageSize - file.tellg(); + } + else { + dataLen = SIZE_IMAGE_PART; + } + + size_t size = 0; + size_t maxSize = sizeof(position); + uint8_t* commandBufferPtr = tmpCommandBuffer; + uint8_t** buffer = &commandBufferPtr; + SerializeAdapter::serialize(&position, buffer, &size, maxSize, + SerializeIF::Endianness::BIG); + file.read(reinterpret_cast(tmpCommandBuffer), dataLen); + file.close(); + + result = commandActionHelper.commandAction(objects::START_TRACKER, + StarTracker::UPLOAD_IMAGE, tmpCommandBuffer - size , UPLOAD_COMMAND_SIZE); + + if (result != RETURN_OK) { + sif::warning << "StarTrackerImageHelper::commandImageUpload: Failed to send image " + << "upload command" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, StarTracker::UPLOAD_IMAGE); + state = State::IDLE; + return; + } + + remainingCommands--; + commandsSent++; + + if (remainingCommands == 0) { + state = State::UPLOAD_LAST; + } + else { + state = State::COMMAND_EXECUTING; + } + pendingCommand = StarTracker::UPLOAD_IMAGE; +} diff --git a/bsp_q7s/devices/StarTrackerImageHelper.h b/bsp_q7s/devices/StarTrackerImageHelper.h new file mode 100644 index 00000000..59dc7b83 --- /dev/null +++ b/bsp_q7s/devices/StarTrackerImageHelper.h @@ -0,0 +1,150 @@ +#ifndef MISSION_DEVICES_STARTRACKERIMAGEHELPER_H_ +#define MISSION_DEVICES_STARTRACKERIMAGEHELPER_H_ + +#include "OBSWConfig.h" +#include "mission/devices/devicedefinitions/StarTrackerDefinitions.h" +#include "fsfw/action/CommandActionHelper.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/action/HasActionsIF.h" +#include "fsfw/action/CommandsActionsIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "bsp_q7s/memory/SdCardManager.h" +#include "linux/fsfwconfig/objects/systemObjectList.h" + + +/** + * @brief An object of this class helps to download and upload images from/to the star tracker. + * + * @details The star tracker can only receive upload image commands with maximum 1024 bytes of data. + * Thus this class is used to raed the image from the file system and split the upload + * procedure into multiple steps. + * The same applies to downloading images from the star tracker (max. 1024 bytes in image + * download reply). + * + * @author J. Meier + */ +class StarTrackerImageHelper : public SystemObject, + public HasActionsIF, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public CommandsActionsIF { +public: + + static const ActionId_t UPLOAD_IMAGE = 0; + static const ActionId_t DOWNLOAD_IMAGE = 1; + + StarTrackerImageHelper(object_id_t objectId); + virtual ~StarTrackerImageHelper(); + + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size); + MessageQueueId_t getCommandQueue() const; + ReturnValue_t initialize() override; + MessageQueueIF* getCommandQueuePtr() override; + void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; + void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; + void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; + void completionSuccessfulReceived(ActionId_t actionId) override; + void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_HELPER; + + //! [EXPORT] : [COMMENT] Image helper is already executing a command + static const ReturnValue_t IMAGE_HELPER_BUSY = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Invalid path to image location + static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] SD card with image not mounted + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2); + //! [EXPORT] : [COMMENT] Specified image does not exist + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_IMAGE_HELPER; + + //! [EXPORT] : [COMMENT] Try to read image file to upload but the file does not exist. + //! P1: Refers to the upload step the reading fails + static const Event IMAGE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Failed to send command to star tracker handler + //! P1: Return value of CommandActionHelper::commandAction + //! P2: Action ID of command to send + static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] Star tracker handler replies with completion failure message to upload image command + //! P1: Upload step of the failed command execution + static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Image upload was successful + static const Event IMAGE_UPLOAD_FINISHED = MAKE_EVENT(3, severity::LOW); + + + static const uint32_t QUEUE_SIZE = config::STR_IMG_HELPER_QUEUE_SIZE; + static const size_t MAX_STR_IMAGE_PATH = 50; + static const size_t SD_PREFIX_LENGTH = 8; + // Size of one image part which can be sent per action request + static const size_t SIZE_IMAGE_PART = 1024; + // Position (uint32_t) + image data (1024 bytes) + static const size_t UPLOAD_COMMAND_SIZE = 1028; + + MessageQueueIF* commandQueue = nullptr; + + SdCardManager* sdcMan = nullptr; + + CommandActionHelper commandActionHelper; + + ActionHelper actionHelper; + + enum class State: uint8_t { + IDLE, + SEND_NEXT_UPLOAD_CMD, + UPLOAD_LAST, + COMMAND_EXECUTING + }; + + State state = State::IDLE; + + ActionId_t pendingCommand = StarTracker::NONE; + + uint32_t commandsSent = 0; + uint32_t remainingCommands = 0; + + // Path and name of active image (either upload or download image) + std::string imageFile; + // In case of upload command this variable stores the size of the image to upload + std::uintmax_t imageSize; + + void readCommandQueue(); + void doStateMachine(); + + /** + * @brief Extracts the path and name form the received command. + * + * @param data Pointer to received command + * @param size Size of the received command + * + * @details This string defines the image to upload (must be previously written to the SD card). + * In case of the download image command, this string defines the location and name of + * the image file to create. + */ + ReturnValue_t getImageLocation(const uint8_t* data, size_t size); + + /** + * @brief Prepares properties for the upload image command and changes the state to initiate + * the execution of the upload image command. + */ + ReturnValue_t prepareUploadCommand(const uint8_t* data, size_t size); + + /** + * @brief Reads part of image from file and sends upload image command to star tracker + * handler. + */ + void commandImageUpload(); + + /** + * @brief Checks whether the SD card to read from is mounted or not. + */ + bool isSdCardMounted(sd::SdCard sdCard); +}; + +#endif /* MISSION_DEVICES_STARTRACKERIMAGEHELPER_H_ */ diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 00b5ca25..b2885009 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -19,6 +19,7 @@ enum commonClassIds: uint8_t { CCSDS_IP_CORE_BRIDGE, //IPCI PTME, //PTME PLOC_UPDATER, //PLUD + STR_IMG_HELPER, //STRIMGH GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 8cf45e9a..19445dc1 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -90,7 +90,8 @@ enum commonObjects: uint32_t { START_TRACKER = 0x44130001, PLOC_UPDATER = 0x44330000, - PLOC_MEMORY_DUMPER = 0x44330001 + PLOC_MEMORY_DUMPER = 0x44330001, + STR_IMG_HELPER = 0x44330002 }; } diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 05fda61c..a6a0466d 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -18,6 +18,7 @@ enum: uint8_t { PLOC_UPDATER = 117, PLOC_MEMORY_DUMPER = 118, PDEC_HANDLER = 119, + STR_IMAGE_HELPER = 120, COMMON_SUBSYSTEM_ID_END }; } diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 663ef00b..9e2a103e 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -110,7 +110,7 @@ debugging. */ #define OBSW_DEBUG_STARTRACKER 0 #define OBSW_DEBUG_PLOC_MPSOC 0 #define OBSW_DEBUG_PLOC_SUPERVISOR 0 -#define OBSW_DEBUG_PDEC_HANDLER 0 +#define OBSW_DEBUG_PDEC_HANDLER 1 /*******************************************************************/ /** Hardcoded */ @@ -132,6 +132,7 @@ namespace config { /* Add mission configuration flags here */ static constexpr uint32_t OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE = 50; static constexpr uint32_t PLOC_UPDATER_QUEUE_SIZE = 50; +static constexpr uint32_t STR_IMG_HELPER_QUEUE_SIZE = 50; static constexpr uint8_t LIVE_TM = 0; diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 73a27116..b32ceb5f 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -588,6 +588,7 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::PLOC_UPDATER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::PLOC_MEMORY_DUMPER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::STR_IMG_HELPER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); #if OBSW_ADD_PLOC_SUPERVISOR == 1 thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index f8c465e7..0b2048c0 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -55,7 +55,7 @@ ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t * commandData, size_t commandDataLen) { - + ReturnValue_t result = RETURN_OK; switch (deviceCommand) { case (StarTracker::PING_REQUEST): { preparePingRequest(); @@ -77,6 +77,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi prepareInterfaceRequest(); return RETURN_OK; } + case (StarTracker::UPLOAD_IMAGE): { + result = prepareImageUploadCommand(commandData, commandDataLen); + return result; + } case (StarTracker::REQ_POWER): { preparePowerRequest(); return RETURN_OK; @@ -114,6 +118,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() { StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_TIME, 3, &timeSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::UPLOAD_IMAGE, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_POWER, 3, &powerSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_INTERFACE, 3, &interfaceSet, @@ -221,6 +227,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con result = handleInterfaceTm(); break; } + case (StarTracker::UPLOAD_IMAGE): { + result = handleUploadImageReply(); + break; + } case (StarTracker::REQ_POWER): { result = handlePowerTm(); break; @@ -344,6 +354,10 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) *foundId = StarTracker::BOOT; break; } + case (StarTracker::ID::UPLOAD_IMAGE): { + *foundId = StarTracker::UPLOAD_IMAGE; + break; + } default: sif::debug << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" << std::endl; @@ -457,6 +471,28 @@ void StarTrackerHandler::prepareInterfaceRequest() { rawPacketLen = encLength; } +ReturnValue_t StarTrackerHandler::prepareImageUploadCommand(const uint8_t* commandData, + size_t commandDataLen) { + if (commandDataLen != UPLOAD_COMMAND_LEN) { + return INVALID_UPLOAD_COMMAND; + } + uint32_t length = 0; + uint32_t position = deserializeUint32(commandData); + if (position > MAX_POSITION) { + return MAX_POSITION; + } + rememberUploadPosition = position; + struct UploadActionRequest uploadRequest; + uploadRequest.position = position; + std::memcpy(uploadRequest.data, commandData + 4, commandDataLen - 4); + arc_pack_upload_action_req(&uploadRequest, commandBuffer, &length); + uint32_t encLength = 0; + arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); + rawPacket = encBuffer; + rawPacketLen = encLength; + return RETURN_OK; +} + void StarTrackerHandler::preparePowerRequest() { uint32_t length = 0; arc_tm_pack_power_req(commandBuffer, &length); @@ -556,11 +592,27 @@ ReturnValue_t StarTrackerHandler::handlePingReply() { sif::info << "Ping id: 0x"<< std::hex << pingId << std::endl; #endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ if (status != StarTracker::STATUS_OK || pingId != PING_ID) { + sif::warning << "StarTrackerHandler::handlePingReply: Ping failed" << std::endl; result = PING_FAILED; } return result; } +ReturnValue_t StarTrackerHandler::handleUploadImageReply() { + ReturnValue_t result = RETURN_OK; + result = handleActionReply(); + if (result != RETURN_OK) { + return result; + } + uint32_t position = deserializeUint32(decodedFrame + ACTION_DATA_OFFSET); + if (position != rememberUploadPosition) { + sif::warning << "StarTrackerHandler::handleUploadImageReply: Invalid position" + << std::endl; + return UPLOAD_IMAGE_FAILED; + } + return result; +} + ReturnValue_t StarTrackerHandler::handleTimeTm() { ReturnValue_t result = RETURN_OK; result = timeSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); @@ -595,7 +647,6 @@ ReturnValue_t StarTrackerHandler::handleTimeTm() { ReturnValue_t StarTrackerHandler::handleVersionTm() { ReturnValue_t result = RETURN_OK; - PoolReadGuard rg(&versionSet); uint32_t offset = TM_DATA_FIELD_OFFSET; uint8_t status = 0; uint32_t ticks = 0; @@ -607,6 +658,10 @@ ReturnValue_t StarTrackerHandler::handleVersionTm() { result = VERSION_REQ_FAILED; return result; } + result = versionSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } versionSet.ticks = ticks; versionSet.time = time; versionSet.program = *(decodedFrame + offset); @@ -614,24 +669,18 @@ ReturnValue_t StarTrackerHandler::handleVersionTm() { versionSet.major = *(decodedFrame + offset); offset += 1; versionSet.minor = *(decodedFrame + offset); + result = versionSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTrackerHandler::handleVersionTm: Ticks: " - << versionSet.ticks << std::endl; - sif::info << "StarTrackerHandler::handleVersionTm: Unix Time: " - << versionSet.time << " us" << std::endl; - sif::info << "StarTrackerHandler::handleVersionTm: Program: " - << static_cast(versionSet.program.value) << std::endl; - sif::info << "StarTrackerHandler::handleVersionTm: Major: " - << static_cast(versionSet.major.value) << std::endl; - sif::info << "StarTrackerHandler::handleVersionTm: Minor: " - << static_cast(versionSet.minor.value) << std::endl; + versionSet.printSet(); #endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ return result; } ReturnValue_t StarTrackerHandler::handleInterfaceTm() { ReturnValue_t result = RETURN_OK; - PoolReadGuard rg(&interfaceSet); uint32_t offset = TM_DATA_FIELD_OFFSET; uint8_t status = 0; uint32_t ticks = 0; @@ -643,59 +692,28 @@ ReturnValue_t StarTrackerHandler::handleInterfaceTm() { result = INTERFACE_REQ_FAILED; return result; } + result = interfaceSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } interfaceSet.ticks = ticks; interfaceSet.time = time; size_t size = sizeof(uint32_t); interfaceSet.frameCount = deserializeUint32(decodedFrame + offset); offset += size; interfaceSet.checksumerrorCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.setParamCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.setParamReplyCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.paramRequestCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.paramReplyCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.tmReplyCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.actionReqCount = deserializeUint32(decodedFrame + offset); - offset += size; - interfaceSet.actionReplyCount = deserializeUint32(decodedFrame + offset); - + result = interfaceSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTrackerHandler::handleInterfaceTm: Ticks: " - << interfaceSet.ticks << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Time: " - << interfaceSet.time << " us" << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Frame Count: " - << interfaceSet.frameCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Checksum Error Count: " - << interfaceSet.checksumerrorCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Set Param Count: " - << interfaceSet.setParamCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Set Param Reply Count: " - << interfaceSet.setParamReplyCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Param Request Count: " - << interfaceSet.paramRequestCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Param Reply Count: " - << interfaceSet.paramReplyCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Req TM Count: " - << interfaceSet.reqTmCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Telemetry Reply Count: " - << interfaceSet.tmReplyCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Action Request Count: " - << interfaceSet.actionReqCount << std::endl; - sif::info << "StarTrackerHandler::handleInterfaceTm: Action Reply Count: " - << interfaceSet.actionReplyCount << std::endl; + interfaceSet.printSet(); #endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ return result; } ReturnValue_t StarTrackerHandler::handlePowerTm() { ReturnValue_t result = RETURN_OK; - PoolReadGuard rg(&powerSet); uint32_t offset = TM_DATA_FIELD_OFFSET; uint8_t status = 0; uint32_t ticks = 0; @@ -707,6 +725,10 @@ ReturnValue_t StarTrackerHandler::handlePowerTm() { result = POWER_REQ_FAILED; return result; } + result = powerSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } powerSet.ticks= ticks; powerSet.time= time; float value = 0; @@ -757,43 +779,12 @@ ReturnValue_t StarTrackerHandler::handlePowerTm() { offset += 4; std::memcpy(&value, decodedFrame + offset, sizeof(value)); powerSet.cmvResVoltage = value; + result = powerSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 - sif::info << "StarTrackerHandler::handlePowerTm: Ticks: " - << powerSet.ticks << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: Time: " - << powerSet.time << " us" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: MCU Current: " - << powerSet.mcuCurrent << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: MCU Voltage: " - << powerSet.mcuVoltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: FPGA Core current: " - << powerSet.fpgaCoreCurrent << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: FPGA Core voltage: " - << powerSet.fpgaCoreVoltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: FPGA 18 current: " - << powerSet.fpga18Current << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: FPGA 18 voltage: " - << powerSet.fpga18Voltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: FPGA 25 current: " - << powerSet.fpga25Current << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: FPGA 25 voltage: " - << powerSet.fpga25Voltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV 21 current: " - << powerSet.cmv21Current << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV 21 voltage: " - << powerSet.cmv21Voltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV Pix current: " - << powerSet.cmvPixCurrent << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV Pix voltage: " - << powerSet.cmvPixVoltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV 33 current: " - << powerSet.cmv33Current << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV 33 voltage: " - << powerSet.cmv33Voltage << " V" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV Res current: " - << powerSet.cmvResCurrent << " A" << std::endl; - sif::info << "StarTrackerHandler::handlePowerTm: CMV Res voltage: " - << powerSet.cmvResVoltage << " V" << std::endl; + powerSet.printSet(); #endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ return result; } @@ -905,7 +896,7 @@ ReturnValue_t StarTrackerHandler::handleTemperatureTm() { float temperature = 0; std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); temperatureSet.mcuTemperature = temperature; - offset += sizeof(temperature); + offset += sizeof(float); std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); temperatureSet.cmosTemperature = temperature; result = temperatureSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); @@ -924,7 +915,7 @@ void StarTrackerHandler::getTmHeaderData(uint8_t* status, uint32_t* ticks, uint6 *time = deserializeUint64(decodedFrame + TIME_OFFSET); } -uint32_t StarTrackerHandler::deserializeUint32(uint8_t* buffer) { +uint32_t StarTrackerHandler::deserializeUint32(const uint8_t* buffer) { uint32_t word = 0; word = *(buffer + 3) << 24 | *(buffer + 2) << 16 diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index 67b957de..e082cf46 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -78,13 +78,26 @@ private: static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA6); //! [EXPORT] : [COMMENT] Status of reply to action command signals error static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA7); + //! [EXPORT] : [COMMENT] Received upload image command with invalid length + static const ReturnValue_t UPLOAD_TOO_SHORT = MAKE_RETURN_CODE(0xA8); + //! [EXPORT] : [COMMENT] Received upload image command with invalid position field + static const ReturnValue_t UPLOAD_INVALID_POSITION = MAKE_RETURN_CODE(0xA8); + //! [EXPORT] : [COMMENT] Position value in upload image reply not matching sent position + static const ReturnValue_t UPLOAD_IMAGE_FAILED = MAKE_RETURN_CODE(0xA9); + //! [EXPORT] : [COMMENT] Received upload image command with invalid length + static const ReturnValue_t INVALID_UPLOAD_COMMAND = MAKE_RETURN_CODE(0xA9); + // position (uint32) + 1024 image data + static const size_t UPLOAD_COMMAND_LEN = 1028; + // Max valid position value in upload image command + static const uint16_t MAX_POSITION= 3071; static const uint8_t STATUS_OFFSET = 2; static const uint8_t TICKS_OFFSET = 3; static const uint8_t TIME_OFFSET = 7; static const uint8_t TM_DATA_FIELD_OFFSET = 15; static const uint8_t PARAMETER_ID_OFFSET = 1; static const uint8_t ACTION_ID_OFFSET = 1; + static const uint8_t ACTION_DATA_OFFSET = 3; // Ping request will reply ping with this ID (data field) static const uint32_t PING_ID = 0x55; @@ -115,6 +128,8 @@ private: InternalState internalState = InternalState::TEMPERATURE_REQUEST; + uint32_t rememberUploadPosition = 0; + /** * @brief This function initializes the serial link ip protocol struct slipInfo. */ @@ -150,6 +165,11 @@ private: */ void prepareInterfaceRequest(); + /** + * @brief Fills the command buffer with data to upload part of an image. + */ + ReturnValue_t prepareImageUploadCommand(const uint8_t* commandData, size_t commandDataLen); + /** * @brief Fills the command buffer with data to request the power telemetry packet. */ @@ -190,6 +210,11 @@ private: ReturnValue_t handlePingReply(); + /** + * @brief Handles reply to upload image command + */ + ReturnValue_t handleUploadImageReply(); + /** * @brief Fills the time set with the data of the time request reply. */ @@ -234,7 +259,7 @@ private: * * @note Deserialization will be performed in little endian byte order */ - uint32_t deserializeUint32(uint8_t* buffer); + uint32_t deserializeUint32(const uint8_t* buffer); /** * @brief This function deserializes 8 bytes into a 64 bit unsigned integer. diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index 8546f843..ef9182ff 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -91,10 +91,12 @@ static const DeviceCommandId_t REQ_VERSION = 2; static const DeviceCommandId_t REQ_INTERFACE = 3; static const DeviceCommandId_t REQ_TIME = 4; static const DeviceCommandId_t REBOOT = 7; +static const DeviceCommandId_t UPLOAD_IMAGE = 10; static const DeviceCommandId_t REQ_POWER = 11; static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; static const DeviceCommandId_t REQ_SOLUTION = 24; static const DeviceCommandId_t REQ_TEMPERATURE = 25; +static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const uint32_t VERSION_SET_ID = REQ_VERSION; static const uint32_t INTERFACE_SET_ID = REQ_INTERFACE; @@ -108,7 +110,7 @@ static const size_t MAX_FRAME_SIZE = 1200; static const uint8_t TEMPERATURE_SET_ENTRIES = 4; static const uint8_t VERSION_SET_ENTRIES = 5; -static const uint8_t INTERFACE_SET_ENTRIES = 12; +static const uint8_t INTERFACE_SET_ENTRIES = 4; static const uint8_t POWER_SET_ENTRIES = 18; static const uint8_t TIME_SET_ENTRIES = 4; static const uint8_t SOLUTION_SET_ENTRIES = 23; @@ -120,6 +122,7 @@ namespace ID { static const uint8_t VERSION = 2; static const uint8_t INTERFACE = 3; static const uint8_t REBOOT = 7; + static const uint8_t UPLOAD_IMAGE = 10; static const uint8_t POWER = 11; static const uint8_t SUBSCRIBE = 18; static const uint8_t SOLUTION = 24; @@ -161,7 +164,7 @@ public: sif::info << "TemperatureSet::printSet: MCU Temperature: " << this->mcuTemperature << " °C" << std::endl; sif::info << "TemperatureSet::printSet: CMOS Temperature: " - << this->mcuTemperature << " °C" << std::endl; + << this->cmosTemperature << " °C" << std::endl; } }; @@ -192,6 +195,20 @@ public: PoolIds::MAJOR, this); lp_var_t minor = lp_var_t(sid.objectId, PoolIds::MINOR, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "VersionSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "VersionSet::printSet: Unix Time: " + << this->time << " us" << std::endl; + sif::info << "VersionSet::printSet: Program: " + << static_cast(this->program.value) << std::endl; + sif::info << "VersionSet::printSet: Major: " + << static_cast(this->major.value) << std::endl; + sif::info << "VersionSet::printSet: Minor: " + << static_cast(this->minor.value) << std::endl; + } }; /** @@ -219,22 +236,18 @@ public: PoolIds::FRAME_COUNT, this); lp_var_t checksumerrorCount = lp_var_t(sid.objectId, PoolIds::CHECKSUM_ERROR_COUNT, this); - lp_var_t setParamCount = lp_var_t(sid.objectId, - PoolIds::SET_PARAM_COUNT, this); - lp_var_t setParamReplyCount = lp_var_t(sid.objectId, - PoolIds::SET_PARAM_REPLY_COUNT, this); - lp_var_t paramRequestCount = lp_var_t(sid.objectId, - PoolIds::PARAM_REQUEST_COUNT, this); - lp_var_t paramReplyCount = lp_var_t(sid.objectId, - PoolIds::PARAM_REPLY_COUNT, this); - lp_var_t reqTmCount = lp_var_t(sid.objectId, - PoolIds::REQ_TM_COUNT, this); - lp_var_t tmReplyCount = lp_var_t(sid.objectId, - PoolIds::TM_REPLY_COUNT, this); - lp_var_t actionReqCount = lp_var_t(sid.objectId, - PoolIds::ACTION_REQ_COUNT, this); - lp_var_t actionReplyCount = lp_var_t(sid.objectId, - PoolIds::ACTION_REPLY_COUNT, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "InterfaceSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "InterfaceSet::printSet: Time: " + << this->time << " us" << std::endl; + sif::info << "InterfaceSet::printSet: Frame Count: " + << this->frameCount << std::endl; + sif::info << "InterfaceSet::printSet: Checksum Error Count: " + << this->checksumerrorCount << std::endl; + } }; /** @@ -290,6 +303,46 @@ public: PoolIds::CMV_RES_CURRENT, this); lp_var_t cmvResVoltage = lp_var_t(sid.objectId, PoolIds::CMV_RES_VOLTAGE, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "PowerSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "PowerSet::printSet: Time: " + << this->time << " us" << std::endl; + sif::info << "PowerSet::printSet: MCU Current: " + << this->mcuCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: MCU Voltage: " + << this->mcuVoltage << " V" << std::endl; + sif::info << "PowerSet::printSet: FPGA Core current: " + << this->fpgaCoreCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: FPGA Core voltage: " + << this->fpgaCoreVoltage << " V" << std::endl; + sif::info << "PowerSet::printSet: FPGA 18 current: " + << this->fpga18Current << " A" << std::endl; + sif::info << "PowerSet::printSet: FPGA 18 voltage: " + << this->fpga18Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: FPGA 25 current: " + << this->fpga25Current << " A" << std::endl; + sif::info << "PowerSet::printSet: FPGA 25 voltage: " + << this->fpga25Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV 21 current: " + << this->cmv21Current << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV 21 voltage: " + << this->cmv21Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV Pix current: " + << this->cmvPixCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV Pix voltage: " + << this->cmvPixVoltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV 33 current: " + << this->cmv33Current << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV 33 voltage: " + << this->cmv33Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV Res current: " + << this->cmvResCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV Res voltage: " + << this->cmvResVoltage << " V" << std::endl; + } }; /** From 1affc1e1d3bd8d653ffd5a7c4e43cc33e6cdf68f Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 29 Nov 2021 15:02:14 +0100 Subject: [PATCH 08/78] str image helper, step failure handling --- bsp_q7s/devices/StarTrackerImageHelper.cpp | 26 +++++++++++++++++++--- bsp_q7s/devices/StarTrackerImageHelper.h | 9 +++++--- mission/devices/StarTrackerHandler.cpp | 13 ++++++----- mission/devices/StarTrackerHandler.h | 2 +- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/bsp_q7s/devices/StarTrackerImageHelper.cpp b/bsp_q7s/devices/StarTrackerImageHelper.cpp index c225e3b9..3fb62b99 100644 --- a/bsp_q7s/devices/StarTrackerImageHelper.cpp +++ b/bsp_q7s/devices/StarTrackerImageHelper.cpp @@ -195,10 +195,30 @@ void StarTrackerImageHelper::stepSuccessfulReceived(ActionId_t actionId, void StarTrackerImageHelper::stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) { + switch (pendingCommand) { + case (StarTracker::UPLOAD_IMAGE): + if (retries < MAX_RETRIES) { + // Repeat sending last command + commandsSent--; + remainingCommands++; + commandImageUpload(); + retries++; + state = State::COMMAND_EXECUTING; + } + else { + triggerEvent(IMAGE_UPLOAD_FAILED, returnCode, commandsSent); + retries = 0; + state = State::IDLE; + } + break; + default: + sif::debug << "StarTrackerImageHelper::completionSuccessfulReceived: Invalid pending command" + << std::endl; + break; + } } void StarTrackerImageHelper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { - } void StarTrackerImageHelper::completionSuccessfulReceived(ActionId_t actionId) { @@ -225,7 +245,7 @@ void StarTrackerImageHelper::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) { switch(pendingCommand) { case(StarTracker::UPLOAD_IMAGE): { - triggerEvent(IMAGE_UPLOAD_FAILED); + triggerEvent(IMAGE_UPLOAD_FAILED, returnCode, commandsSent); break; } default: @@ -240,7 +260,7 @@ void StarTrackerImageHelper::commandImageUpload() { ReturnValue_t result = RETURN_OK; uint16_t dataLen = 0; uint8_t tmpCommandBuffer[UPLOAD_COMMAND_SIZE] = {0}; - uint32_t position = commandsSent * SIZE_IMAGE_PART; + uint32_t position = commandsSent; if (not std::filesystem::exists(imageFile)) { triggerEvent(IMAGE_FILE_NOT_EXISTS, commandsSent); diff --git a/bsp_q7s/devices/StarTrackerImageHelper.h b/bsp_q7s/devices/StarTrackerImageHelper.h index 59dc7b83..420721dc 100644 --- a/bsp_q7s/devices/StarTrackerImageHelper.h +++ b/bsp_q7s/devices/StarTrackerImageHelper.h @@ -72,13 +72,14 @@ private: //! P1: Return value of CommandActionHelper::commandAction //! P2: Action ID of command to send static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] Star tracker handler replies with completion failure message to upload image command - //! P1: Upload step of the failed command execution + //! [EXPORT] : [COMMENT] Star tracker handler replies with completion or step failure message to upload image command + //!P1: Return code of execution/step failure message + //!P2: Failed upload step (equal to number of commands already sent) static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(2, severity::LOW); //! [EXPORT] : [COMMENT] Image upload was successful static const Event IMAGE_UPLOAD_FINISHED = MAKE_EVENT(3, severity::LOW); - + static const uint8_t MAX_RETRIES = 3; static const uint32_t QUEUE_SIZE = config::STR_IMG_HELPER_QUEUE_SIZE; static const size_t MAX_STR_IMAGE_PATH = 50; static const size_t SD_PREFIX_LENGTH = 8; @@ -108,6 +109,8 @@ private: uint32_t commandsSent = 0; uint32_t remainingCommands = 0; + // Counts retries when command was rejected by star tracker + uint8_t retries = 0; // Path and name of active image (either upload or download image) std::string imageFile; diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index 0b2048c0..ed5f5e56 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -604,12 +604,13 @@ ReturnValue_t StarTrackerHandler::handleUploadImageReply() { if (result != RETURN_OK) { return result; } - uint32_t position = deserializeUint32(decodedFrame + ACTION_DATA_OFFSET); - if (position != rememberUploadPosition) { - sif::warning << "StarTrackerHandler::handleUploadImageReply: Invalid position" - << std::endl; - return UPLOAD_IMAGE_FAILED; - } + // Position seems to be always 0 (independent of sent position) +// uint32_t position = deserializeUint32(decodedFrame + ACTION_DATA_OFFSET); +// if (position != rememberUploadPosition) { +// sif::warning << "StarTrackerHandler::handleUploadImageReply: Invalid position" +// << std::endl; +// return UPLOAD_IMAGE_FAILED; +// } return result; } diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index e082cf46..cbf05242 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -90,7 +90,7 @@ private: // position (uint32) + 1024 image data static const size_t UPLOAD_COMMAND_LEN = 1028; // Max valid position value in upload image command - static const uint16_t MAX_POSITION= 3071; + static const uint16_t MAX_POSITION= 4095; static const uint8_t STATUS_OFFSET = 2; static const uint8_t TICKS_OFFSET = 3; static const uint8_t TIME_OFFSET = 7; From 8c649b3e700aa1a1965b56a0588762669f779c60 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 30 Nov 2021 16:01:02 +0100 Subject: [PATCH 09/78] str image loader wip --- bsp_q7s/devices/PlocUpdater.cpp | 35 +----------- bsp_q7s/devices/PlocUpdater.h | 7 --- bsp_q7s/devices/StrImageLoader.cpp | 75 ++++++++++++++++++++++++++ bsp_q7s/devices/StrImageLoader.h | 56 +++++++++++++++++++ bsp_q7s/memory/SdCardManager.cpp | 30 +++++++++++ bsp_q7s/memory/SdCardManager.h | 9 ++++ common/config/commonClassIds.h | 2 +- mission/devices/StarTrackerHandler.cpp | 17 ++++-- mission/devices/StarTrackerHandler.h | 9 +++- 9 files changed, 195 insertions(+), 45 deletions(-) create mode 100644 bsp_q7s/devices/StrImageLoader.cpp create mode 100644 bsp_q7s/devices/StrImageLoader.h diff --git a/bsp_q7s/devices/PlocUpdater.cpp b/bsp_q7s/devices/PlocUpdater.cpp index 4771e14c..592a2c0d 100644 --- a/bsp_q7s/devices/PlocUpdater.cpp +++ b/bsp_q7s/devices/PlocUpdater.cpp @@ -168,13 +168,13 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { #if BOARD_TE0720 == 0 // Check if file is stored on SD card and if associated SD card is mounted if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { sif::warning << "PlocUpdater::getImageLocation: SD card 0 not mounted" << std::endl; return SD_NOT_MOUNTED; } } else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { sif::warning << "PlocUpdater::getImageLocation: SD card 1 not mounted" << std::endl; return SD_NOT_MOUNTED; } @@ -193,37 +193,6 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { return RETURN_OK; } -#if BOARD_TE0720 == 0 -bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatePair active; - ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); - if (result != RETURN_OK) { - sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; - return false; - } - if (sdCard == sd::SLOT_0) { - if (active.first == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else if (sdCard == sd::SLOT_1) { - if (active.second == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else { - sif::debug << "PlocUpdater::isSdCardMounted: Unknown SD card specified" << std::endl; - } - return false; -} -#endif /* #if BOARD_TE0720 == 0 */ - void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) { } diff --git a/bsp_q7s/devices/PlocUpdater.h b/bsp_q7s/devices/PlocUpdater.h index 50404d14..d016b9e5 100644 --- a/bsp_q7s/devices/PlocUpdater.h +++ b/bsp_q7s/devices/PlocUpdater.h @@ -174,13 +174,6 @@ private: */ void commandUpdateVerify(); -#if BOARD_TE0720 == 0 - /** - * @brief Checks whether the SD card to read from is mounted or not. - */ - bool isSdCardMounted(sd::SdCard sdCard); -#endif - void calcImageCrc(); void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet); diff --git a/bsp_q7s/devices/StrImageLoader.cpp b/bsp_q7s/devices/StrImageLoader.cpp new file mode 100644 index 00000000..803fb122 --- /dev/null +++ b/bsp_q7s/devices/StrImageLoader.cpp @@ -0,0 +1,75 @@ +#include "StrImageLoader.h" + +#include + +StrImageLoader::StrImageLoader(object_id_t objectId) { + +} + +StrImageLoader::~StrImageLoader() { +} + +ReturnValue_t StrImageLoader::initialize() { + sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "StrImageLoader::initialize: Invalid SD Card Manager" << std::endl; + } +} + +ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { + semaphore.acquire(); + while(true) { + switch(internalState) { + case InternalState::IDLE: + semaphore.acquire(); + break; + case InternalState::UPLOAD_IMAGE: + uploadImage(); + break; + case InternalState::DOWNLOAD_IMAGE: + break; + } + } +} + +void StrImageLoader::setComIF(DeviceCommunicationIF* communicationInterface_) { + communicationInterface = communicationInterface_; +} + +void StrImageLoader::setComCookie(CookieIF* comCookie_) { + comCookie = comCookie_; +} + +ReturnValue_t StrImageLoader::startImageUpload(std::string image) { + + //TODO: Use string part not data pointer + // Check if file is stored on SD card and if associated SD card is mounted + if (image.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) + == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "StrImageLoader::getImageLocation: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } else if (image.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) + == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "StrImageLoader::getImageLocation: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + + uploadImage = image; + + if(not std::filesystem::exists(uploadImage)) { + return FILE_NOT_EXISTS; + } + + internalState = InternalState::UPLOAD_IMAGE; + + semaphore.release(); +} + +ReturnValue_t StrImageLoader::uploadImage() { + +} + diff --git a/bsp_q7s/devices/StrImageLoader.h b/bsp_q7s/devices/StrImageLoader.h new file mode 100644 index 00000000..39013fe6 --- /dev/null +++ b/bsp_q7s/devices/StrImageLoader.h @@ -0,0 +1,56 @@ +#ifndef BSP_Q7S_DEVICES_STRIMAGELOADER_H_ +#define BSP_Q7S_DEVICES_STRIMAGELOADER_H_ + +#include + +#include "fsfw/osal/linux/BinarySemaphore.h" +#include "bsp_q7s/memory/SdCardManager.h" + +/** + * @brief An object of this class runs in a separate task and is responsible for uploading and + * downloading images to/from the star tracker. This is required because uploading and + * downloading via the star tracker handler takes a lot of time because each upload or + * download packet can transport a maximum of 1024 bytes. + */ +class StrImageLoader: public SystemObject, public ExecutableObjectIF { +public: + StrImageLoader(object_id_t objectId); + virtual ~StrImageLoader(); + + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + void setComIF(DeviceCommunicationIF* communicationInterface_); + void setComCookie(CookieIF* comCookie_); + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_LOADER; + + //! [EXPORT] : [COMMENT] SD card specified in path string not mounted + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); + + enum class InternalState { + IDLE, + UPLOAD_IMAGE, + DOWNLOAD_IMAGE + }; + + InternalState internalState = InternalState::IDLE; + + BinarySemaphore semaphore; + + // Absolute path and name to image to upload + std::string uploadImage; + + SdCardManager* sdcMan = nullptr; + + /** + * Communication object responsible for low level access of star tracker + * Must be set by star tracker handler + */ + DeviceCommunicationIF * communicationInterface = nullptr; +}; + +#endif /* BSP_Q7S_DEVICES_STRIMAGELOADER_H_ */ diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index ebebf854..ea16b672 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -455,3 +455,33 @@ void SdCardManager::setPrintCommandOutput(bool print) { } +bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { + SdCardManager::SdStatePair active; + ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); + if (result != RETURN_OK) { + sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state"; + return false; + } + if (sdCard == sd::SLOT_0) { + if (active.first == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else if (sdCard == sd::SLOT_1) { + if (active.second == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else { + sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl; + } + return false; +} + + diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 6f03e7f1..6e4930da 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -195,6 +195,15 @@ public: void setBlocking(bool blocking); void setPrintCommandOutput(bool print); + + /** + * @brief Checks if an SD card is mounted + * + * @param sdCard The SD crad to check + * + * @return true if mounted, otherwise false + */ + bool isSdCardMounted(sd::SdCard sdCard); private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index b2885009..a47e97d1 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -19,7 +19,7 @@ enum commonClassIds: uint8_t { CCSDS_IP_CORE_BRIDGE, //IPCI PTME, //PTME PLOC_UPDATER, //PLUD - STR_IMG_HELPER, //STRIMGH + STR_IMG_LOADER, //STRIMGL GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index ed5f5e56..f05dec71 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -10,16 +10,27 @@ extern "C" { } StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, - CookieIF * comCookie) : + CookieIF * comCookie, StrImageLoader* strImageLoader) : DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this), powerSet( - this), interfaceSet(this), timeSet(this), solutionSet(this) { - if (comCookie == NULL) { + this), interfaceSet(this), timeSet(this), solutionSet(this), strImageLoader( + strImageLoader) { + if (comCookie == nullptr) { sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; } + if (strImageLoader == nullptr) { + sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; + } slipInit(); } StarTrackerHandler::~StarTrackerHandler() { + DeviceHandlerBase::initialize(); + strImageLoader->setComIF(communicationInterface); + strImageLoader->setComCookie(comCookie); +} + +ReturnValue_t StarTrackerHandler::initialize() { + } void StarTrackerHandler::doStartUp() { diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index cbf05242..d74d6fd2 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -6,6 +6,7 @@ #include #include #include +#include /** * @brief This is the device handler for the star tracker from arcsec. @@ -28,9 +29,12 @@ public: * @param enablePin GPIO connected to the enable pin of the reaction wheels. Must be pulled * to high to enable the device. */ - StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie); + StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, + StrImageLoader* strImageLoader); virtual ~StarTrackerHandler(); + ReturnValue_t initialize() override; + protected: void doStartUp() override; void doShutDown() override; @@ -106,6 +110,9 @@ private: static const MutexIF::TimeoutType TIMEOUT_TYPE= MutexIF::TimeoutType::WAITING; static const uint32_t MUTEX_TIMEOUT = 20; + // Pointer to object responsible for uploading and downloading images to/from the star tracker + StrImageLoader* strImageLoader = nullptr; + StarTracker::TemperatureSet temperatureSet; StarTracker::VersionSet versionSet; StarTracker::PowerSet powerSet; From 77f6ac57e959698dfcf77ffbad643b93ee0a2c89 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 30 Nov 2021 16:45:33 +0100 Subject: [PATCH 10/78] some reaction wheel fixes --- bsp_q7s/callbacks/rwSpiCallback.cpp | 15 +++++++++++++-- bsp_q7s/callbacks/rwSpiCallback.h | 3 +++ bsp_q7s/core/InitMission.cpp | 2 +- mission/devices/RwHandler.h | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/callbacks/rwSpiCallback.cpp b/bsp_q7s/callbacks/rwSpiCallback.cpp index 620f63f7..ad99d505 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.cpp +++ b/bsp_q7s/callbacks/rwSpiCallback.cpp @@ -133,8 +133,15 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen closeSpi(gpioId, gpioIF, mutex); return RwHandler::SPI_READ_FAILURE; } + if(idx == 0) { + if(byteRead != FLAG_BYTE) { + sif::error << "Invalid data, expected start marker" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::NO_START_MARKER; + } + } - if (byteRead != 0x7E) { + if (byteRead != FLAG_BYTE) { break; } @@ -145,6 +152,10 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen } } +#if FSFW_HAL_SPI_WIRETAPPING == 1 + sif::info << "RW start marker detected" << std::endl; +#endif + size_t decodedFrameLen = 0; while(decodedFrameLen < replyBufferSize) { @@ -158,7 +169,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen } } - if (byteRead == 0x7E) { + if (byteRead == FLAG_BYTE) { /** Reached end of frame */ break; } diff --git a/bsp_q7s/callbacks/rwSpiCallback.h b/bsp_q7s/callbacks/rwSpiCallback.h index cc7c6cbe..8952f873 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.h +++ b/bsp_q7s/callbacks/rwSpiCallback.h @@ -8,6 +8,9 @@ namespace rwSpiCallback { +//! This is the end and start marker of the frame datalinklayer +static constexpr uint8_t FLAG_BYTE = 0x7E; + /** * @brief This is the callback function to send commands to the nano avionics reaction wheels and * receive the replies. diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 7923a2cd..81d972b1 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -22,7 +22,7 @@ ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); ServiceInterfaceStream sif::warning("WARNING"); -ServiceInterfaceStream sif::error("ERROR", false, false, true); +ServiceInterfaceStream sif::error("ERROR"); #else ServiceInterfaceStream sif::debug("DEBUG", true); ServiceInterfaceStream sif::info("INFO", true); diff --git a/mission/devices/RwHandler.h b/mission/devices/RwHandler.h index cd753be0..57895ca6 100644 --- a/mission/devices/RwHandler.h +++ b/mission/devices/RwHandler.h @@ -46,6 +46,8 @@ public: static const ReturnValue_t MISSING_END_SIGN = MAKE_RETURN_CODE(0xB4); //! [EXPORT] : [COMMENT] Reaction wheel only responds with empty frames. static const ReturnValue_t NO_REPLY = MAKE_RETURN_CODE(0xB5); + //! [EXPORT] : [COMMENT] Expected a start marker as first byte + static const ReturnValue_t NO_START_MARKER = MAKE_RETURN_CODE(0xB6); protected: void doStartUp() override; From a7ab2bb93a0f5bd77fc794f4ab364b1769baebd7 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 2 Dec 2021 08:05:33 +0100 Subject: [PATCH 11/78] str img loader wip --- bsp_q7s/devices/ArcsecDatalinkLayer.cpp | 68 ++++ bsp_q7s/devices/ArcsecDatalinkLayer.h | 84 ++++ bsp_q7s/devices/StrImageLoader.cpp | 89 +++- bsp_q7s/devices/StrImageLoader.h | 49 ++- common/config/commonObjects.h | 2 +- common/config/commonSubsystemIds.h | 2 +- mission/devices/StarTrackerHandler.cpp | 381 ++++++++++-------- mission/devices/StarTrackerHandler.h | 52 +-- .../StarTrackerDefinitions.h | 1 + mission/tmtc/CCSDSHandler.cpp | 10 +- tmtc | 2 +- 11 files changed, 526 insertions(+), 214 deletions(-) create mode 100644 bsp_q7s/devices/ArcsecDatalinkLayer.cpp create mode 100644 bsp_q7s/devices/ArcsecDatalinkLayer.h diff --git a/bsp_q7s/devices/ArcsecDatalinkLayer.cpp b/bsp_q7s/devices/ArcsecDatalinkLayer.cpp new file mode 100644 index 00000000..1f436636 --- /dev/null +++ b/bsp_q7s/devices/ArcsecDatalinkLayer.cpp @@ -0,0 +1,68 @@ +#include "ArcsecDatalinkLayer.h" + +ArcsecDatalinkLayer::ArcsecDatalinkLayer() { + slipInit(); +} + +ArcsecDatalinkLayer::~ArcsecDatalinkLayer() { +} + +void ArcsecDatalinkLayer::slipInit() { + slipInfo.buffer = rxBuffer; + slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE; + slipInfo.length = 0; + slipInfo.unescape_next = 0; + slipInfo.prev_state = SLIP_COMPLETE; +} + +ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t rawDataSize, + size_t* bytesLeft) { + size_t bytePos = 0; + for (bytePos = 0; bytePos < rawDataSize; bytePos++) { + enum arc_dec_result decResult = arc_transport_decode_body(*(rawData + bytePos), &slipInfo, + decodedFrame, &decFrameSize); + *bytesLeft = rawDataSize - bytePos; + switch (decResult) { + case ARC_DEC_INPROGRESS: { + if (bytePos == rawDataSize - 1) { + return DEC_IN_PROGRESS; + } + continue; + } + case ARC_DEC_ERROR_FRAME_SHORT: + return REPLY_TOO_SHORT; + case ARC_DEC_ERROR_CHECKSUM: + return CRC_FAILURE; + case ARC_DEC_ASYNC: + case ARC_DEC_SYNC: { + // Reset length of SLIP struct for next frame + slipInfo.length = 0; + RETURN_OK; + } + default: + sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl; + break; + } + } +} + +uint8_t ArcsecDatalinkLayer::getReplyFrameType() { + return decodedFrame[0]; +} + +const uint8_t* ArcsecDatalinkLayer::getReply() { + return &decodedFrame[1]; +} + +void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) { + arc_transport_encode_body(commandBuffer, length, encBuffer, &encFrameSize); +} + +uint8_t* ArcsecDatalinkLayer::getEncodedFrame() { + return encBuffer; +} + +uint32_t ArcsecDatalinkLayer::getEncodedLength() { + return encFrameSize; +} + diff --git a/bsp_q7s/devices/ArcsecDatalinkLayer.h b/bsp_q7s/devices/ArcsecDatalinkLayer.h new file mode 100644 index 00000000..bce1f619 --- /dev/null +++ b/bsp_q7s/devices/ArcsecDatalinkLayer.h @@ -0,0 +1,84 @@ +#ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ +#define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ + +#include "mission/devices/devicedefinitions/StarTrackerDefinitions.h" +#include "fsfw/returnvalues/HasReturnValuesIF.h" + +extern "C" { + #include "common/misc.h" +} + +/** + * @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec. + */ +class ArcsecDatalinkLayer: public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER; + + //! [EXPORT] : [COMMENT] More data required to complete frame + static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Data too short to represent a valid frame + static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Detected CRC failure in received frame + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2); + + ArcsecDatalinkLayer(); + virtual ~ArcsecDatalinkLayer(); + + /** + * @brief Applies decoding to data referenced by rawData pointer + * + * @param rawData Pointer to raw data received from star tracker + * @param rawDataSize Size of raw data stream + * @param remainingBytes Number of bytes left + */ + ReturnValue_t decodeFrame(const uint8_t* rawData, size_t rawDataSize, size_t* bytesLeft); + + /** + * @brief SLIP encodes data pointed to by data pointer. + * + * @param data Pointer to data to encode + * @param length Length of buffer to encode + */ + void encodeFrame(const uint8_t* data, uint32_t length); + + /** + * @brief Returns the frame type field of a decoded frame. + */ + uint8_t getReplyFrameType(); + + /** + * @brief Returns pointer to reply packet. + */ + const uint8_t* getReply(); + + /** + * @brief Returns size of encoded frame + */ + uint32_t getEncodedLength(); + + /** + * @brief Returns pointer to encoded frame + */ + uint8_t* getEncodedFrame(); + +private: + + // Used by arcsec slip decoding function process received data + uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; + // Decoded frame will be copied to this buffer + uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE]; + // Buffer where encoded frames will be stored + uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2]; + // Size of decoded frame + uint32_t decFrameSize = 0; + // Size of encoded frame + uint32_t encFrameSize = 0; + + slip_decode_state slipInfo; + + void slipInit(); +}; + +#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */ diff --git a/bsp_q7s/devices/StrImageLoader.cpp b/bsp_q7s/devices/StrImageLoader.cpp index 803fb122..7d4b64eb 100644 --- a/bsp_q7s/devices/StrImageLoader.cpp +++ b/bsp_q7s/devices/StrImageLoader.cpp @@ -17,15 +17,21 @@ ReturnValue_t StrImageLoader::initialize() { } ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { + ReturnValue_t result = RETURN_OK; semaphore.acquire(); while(true) { switch(internalState) { - case InternalState::IDLE: + case InternalState::IDLE: { semaphore.acquire(); break; - case InternalState::UPLOAD_IMAGE: - uploadImage(); + } + case InternalState::UPLOAD_IMAGE: { + result = uploadImage(); + if (result == RETURN_OK){ + triggerEvent(IMAGE_UPLOAD_SUCCESSFUL); + } break; + } case InternalState::DOWNLOAD_IMAGE: break; } @@ -42,7 +48,6 @@ void StrImageLoader::setComCookie(CookieIF* comCookie_) { ReturnValue_t StrImageLoader::startImageUpload(std::string image) { - //TODO: Use string part not data pointer // Check if file is stored on SD card and if associated SD card is mounted if (image.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { @@ -70,6 +75,82 @@ ReturnValue_t StrImageLoader::startImageUpload(std::string image) { } ReturnValue_t StrImageLoader::uploadImage() { + ReturnValue_t result = RETURN_OK; + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; + size_t bytesLeft = 0; + uint32_t readSize = 0; + uint32_t imageSize = 0; + struct UploadActionRequest uploadReq; + uploadReq.position = 0; + uploadReq.data = {0}; + if (not std::filesystem::exists(uploadImage)) { + triggerEvent(IMAGE_FILE_NOT_EXISTS, uploadReq.position); + state = State::IDLE; + return RETURN_FAILED; + } + + std::ifstream file(uploadImage, std::ifstream::binary); + file.seekg(0, file.end); + imageSize = file.tellg(); + file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); + + while(uploadReq.position * SIZE_IMAGE_PART < imageSize) { + result = + } + + uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART; + file.read(reinterpret_cast(uploadReq.data), remainder); + uploadReq.position++; + datalinkLayer.encodeFrame(uploadReq.data, remainder); + result = communicationInterface->sendMessage(comCookie, datalinkLayer.getEncodedFrame(), + datalinkLayer.getEncodedLength()); + if (result = RETURN_OK) { + sif::warning << "StrImageLoader::uploadImage: Failed to send upload packet" << std::endl; + triggerEvent(SENDING_UPLOAD_PACKET_FAILED, result, uploadReq.position); + return RETURN_FAILED; + } + result = ArcsecDatalinkLayer::DEC_IN_PROGRESS; + while(result == ArcsecDatalinkLayer::DEC_IN_PROGRESS) { + result = communicationInterface->requestReceiveMessage(comCookie, StarTracker::MAX_FRAME_SIZE* 2 + 2); + if (result != RETURN_OK) { + sif::warning << "StrImageLoader::uploadImage: Failed to request reply" << std::endl; + triggerEvent(UPLOAD_REQUESTING_MSG_FAILED, result, uploadReq.position); + return RETURN_FAILED; + } + result = communicationInterface->readReceivedMessage(comCookie, receivedData, + receivedDataLen); + if (result != RETURN_OK) { + sif::warning << "StrImageLoader::uploadImage: Failed to read received message" + << std::endl; + triggerEvent(UPLOAD_READING_REPLY_FAILED, result, uploadReq.position); + } + result = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft); + if (bytesLeft != 0) { + // This should never happen + triggerEvent(UPLOAD_COM_ERROR, result, uploadReq.position); + return RETURN_FAILED; + } + } + + if (remainingCommands == 1) { + dataLen = imageSize - file.tellg(); + } + else { + dataLen = SIZE_IMAGE_PART; + } + + size_t size = 0; + size_t maxSize = sizeof(position); + uint8_t* commandBufferPtr = tmpCommandBuffer; + uint8_t** buffer = &commandBufferPtr; + SerializeAdapter::serialize(&position, buffer, &size, maxSize, + SerializeIF::Endianness::BIG); + file.read(reinterpret_cast(uploadReq.data), dataLen); + file.close(); + + arc_pack_upload_action_req() + communicationInterface->requestReceiveMessage(comCookie, ) } diff --git a/bsp_q7s/devices/StrImageLoader.h b/bsp_q7s/devices/StrImageLoader.h index 39013fe6..50cdc266 100644 --- a/bsp_q7s/devices/StrImageLoader.h +++ b/bsp_q7s/devices/StrImageLoader.h @@ -5,6 +5,8 @@ #include "fsfw/osal/linux/BinarySemaphore.h" #include "bsp_q7s/memory/SdCardManager.h" +#include "bsp_q7s/devices/ArcsecDatalinkLayer.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" /** * @brief An object of this class runs in a separate task and is responsible for uploading and @@ -12,8 +14,33 @@ * downloading via the star tracker handler takes a lot of time because each upload or * download packet can transport a maximum of 1024 bytes. */ -class StrImageLoader: public SystemObject, public ExecutableObjectIF { +class StrImageLoader: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { public: + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_IMAGE_LOADER; + + //! [EXPORT] : [COMMENT] Try to upload image but specified image does not exist + static const Event IMAGE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Sending image upload packet to star tracker failed + //!P1: Return code of communication interface sendMessage function + //!P2: Position of upload packet for which the transmission failed + static const Event SENDING_UPLOAD_PACKET_FAILED = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] Communication interface requesting reply failed + //!P1: Return code of failed request + //!P1: Upload position for which the request failed + static const Event UPLOAD_REQUESTING_MSG_FAILED = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Uploading image to star tracker was successful + static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Failed to read communication interface reply data + //!P1: Return code of failed communication interface read call + //!P1: Upload position for which the read call failed + static const Event UPLOAD_READING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence + //!P1: Return code of failed communication interface read call + //!P1: Upload position for which the read call failed + static const Event UPLOAD_COM_ERROR = MAKE_EVENT(4, severity::LOW); + + StrImageLoader(object_id_t objectId); virtual ~StrImageLoader(); @@ -22,6 +49,14 @@ public: void setComIF(DeviceCommunicationIF* communicationInterface_); void setComCookie(CookieIF* comCookie_); + /** + * @brief Starts sequence to upload image to star tracker + * + * @param image Name including absolute path if to image to upload. Must be previously + * transferred to the OBC with the CFDP protocoll. + */ + ReturnValue_t startImageUpload(std::string image); + private: static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_LOADER; @@ -31,6 +66,9 @@ private: //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); + // Size of one image part which can be sent per action request + static const size_t SIZE_IMAGE_PART = 1024; + enum class InternalState { IDLE, UPLOAD_IMAGE, @@ -39,6 +77,8 @@ private: InternalState internalState = InternalState::IDLE; + ArcsecDatalinkLayer datalinkLayer; + BinarySemaphore semaphore; // Absolute path and name to image to upload @@ -51,6 +91,13 @@ private: * Must be set by star tracker handler */ DeviceCommunicationIF * communicationInterface = nullptr; + // Communication cookie. Must be set by the star tracker handler + CookieIF* comCookie = nullptr; + + /** + * @brief Performs image uploading + */ + ReturnValue_t uploadImage(); }; #endif /* BSP_Q7S_DEVICES_STRIMAGELOADER_H_ */ diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 19445dc1..610052e4 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -91,7 +91,7 @@ enum commonObjects: uint32_t { PLOC_UPDATER = 0x44330000, PLOC_MEMORY_DUMPER = 0x44330001, - STR_IMG_HELPER = 0x44330002 + STR_IMG_LOADER = 0x44330002 }; } diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index a6a0466d..2bb216a5 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -18,7 +18,7 @@ enum: uint8_t { PLOC_UPDATER = 117, PLOC_MEMORY_DUMPER = 118, PDEC_HANDLER = 119, - STR_IMAGE_HELPER = 120, + STR_IMAGE_LOADER = 120, COMMON_SUBSYSTEM_ID_END }; } diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index f05dec71..dacb8617 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -20,17 +20,83 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, if (strImageLoader == nullptr) { sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; } + eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); slipInit(); } StarTrackerHandler::~StarTrackerHandler() { - DeviceHandlerBase::initialize(); +} + +ReturnValue_t StarTrackerHandler::initialize() { + ReturnValue_t result = RETURN_OK; + result = DeviceHandlerBase::initialize(); + if (result != RETURN_OK) { + return result; + } + + EventManagerIF* manager = ObjectManager::instance()->get( + objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "StarTrackerHandler::initialize: Invalid event manager" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED;; + } + result = manager->registerListener(eventQueue->getId()); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = manager->subscribeToAllEventsFrom(eventQueue->getId(), objects::STR_IMG_LOADER); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "StarTrackerHandler::initialize: Failed to subscribe to events form image" + " loader" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + strImageLoader->setComIF(communicationInterface); strImageLoader->setComCookie(comCookie); } -ReturnValue_t StarTrackerHandler::initialize() { +ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) { + if (imageLoaderExecuting == true) { + return IMAGE_LOADER_EXECUTING; + } + // Intercept image loader commands which do not follow the common DHB communication flow + switch(actionId) { + case(StarTracker::UPLOAD_IMAGE): { + strImageLoader->startImageUpload(); + imageLoaderExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::DOWNLOAD_IMAGE): { + strImageLoader->startImageDownload(); + imageLoaderExecuting = true; + return EXECUTION_FINISHED; + } + default: + break; + } + return DeviceHandlerBase::executeAction(); +} + +void StarTrackerHandler::performOperationHook() { + EventMessage event; + for (ReturnValue_t result = eventQueue->receiveMessage(&event); + result == RETURN_OK; result = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + handleEvent(&event); + break; + default: + sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message" + << std::endl; + break; + } + } } void StarTrackerHandler::doStartUp() { @@ -89,7 +155,9 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi return RETURN_OK; } case (StarTracker::UPLOAD_IMAGE): { - result = prepareImageUploadCommand(commandData, commandDataLen); + std::string uploadImage = std::string(reinterpret_cast(commandData), + commandDataLen); + strImageLoader->startImageUpload(uploadImage); return result; } case (StarTracker::REQ_POWER): { @@ -129,8 +197,7 @@ void StarTrackerHandler::fillCommandAndReplyMap() { StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_TIME, 3, &timeSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); - this->insertInCommandAndReplyMap(StarTracker::UPLOAD_IMAGE, 3, nullptr, - StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandMap(StarTracker::UPLOAD_IMAGE); this->insertInCommandAndReplyMap(StarTracker::REQ_POWER, 3, &powerSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_INTERFACE, 3, &interfaceSet, @@ -151,52 +218,36 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema ReturnValue_t result = RETURN_OK; uint32_t decodedLength = 0; size_t bytePos = 0; - for (bytePos = 0; bytePos < remainingSize; bytePos++) { - enum arc_dec_result decResult = arc_transport_decode_body(*(start + bytePos), &slipInfo, - decodedFrame, &decodedLength); + size_t bytesLeft = 0; - switch (decResult) { - case ARC_DEC_INPROGRESS: { - if (bytePos == remainingSize - 1) { - // second doSendread() required to read whole packet - return IGNORE_FULL_PACKET; - } - continue; - } - case ARC_DEC_ASYNC: { - sif::debug << "StarTrackerHandler::scanForReply: Received asynchronous tm" << std::endl; - /** No asynchronous replies are expected as of now */ - return RETURN_FAILED; - } - case ARC_DEC_ERROR_FRAME_SHORT: - return REPLY_TOO_SHORT; - case ARC_DEC_ERROR_CHECKSUM: - return CRC_FAILURE; - case ARC_DEC_SYNC: { - /** Reset length of SLIP struct for next frame */ - slipInfo.length = 0; - break; - } - default: - sif::debug << "StarTrackerHandler::scanForReply: Unknown result code" << std::endl; - break; - } + result = dataLinkLayer.decodeFrame(start, remainingSize, &bytesLeft); + remainingSize = *bytesLeft; + switch(result) { + case ArcsecDatalinkLayer::DEC_IN_PROGRESS: { + // Need a second doSendRead pass to reaa in whole packet + return IGNORE_REPLY_DATA; + } + case RETURN_OK: { + break; + } + default: + return result; } - switch (decodedFrame[0]) { + switch (dataLinkLayer.getReplyFrameType()) { case TMTC_ACTIONREPLY: { - *foundLen = bytePos; + *foundLen = remainingsize - bytesLeft; result = scanForActionReply(foundId); break; } case TMTC_SETPARAMREPLY: { - *foundLen = bytePos; + *foundLen = remainingsize - bytesLeft; result = scanForSetParameterReply(foundId); break; } case TMTC_TELEMETRYREPLYA: case TMTC_TELEMETRYREPLY: { - *foundLen = bytePos; + *foundLen = remainingsize - bytesLeft; result = scanForTmReply(foundId); break; } @@ -238,10 +289,6 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con result = handleInterfaceTm(); break; } - case (StarTracker::UPLOAD_IMAGE): { - result = handleUploadImageReply(); - break; - } case (StarTracker::REQ_POWER): { result = handlePowerTm(); break; @@ -352,11 +399,17 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l } size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){ + // Prevent DHB from polling UART during upload command. Because UART is used by image loader + // task + if (commandId == StarTracker::UPLOAD_IMAGE) { + return 0; + } return StarTracker::MAX_FRAME_SIZE; } ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) { - switch (decodedFrame[1]) { + const uint8_t* reply = dataLinkLayer.getReply(); + switch (*reply) { case (StarTracker::ID::PING): { *foundId = StarTracker::PING_REQUEST; break; @@ -378,7 +431,8 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) } ReturnValue_t StarTrackerHandler::scanForSetParameterReply(DeviceCommandId_t *foundId) { - switch (decodedFrame[1]) { + const uint8_t* reply = dataLinkLayer.getReply(); + switch (*reply) { case (StarTracker::ID::SUBSCRIBE): { *foundId = StarTracker::SUBSCRIBE_TO_TM; break; @@ -392,7 +446,8 @@ ReturnValue_t StarTrackerHandler::scanForSetParameterReply(DeviceCommandId_t *fo } ReturnValue_t StarTrackerHandler::scanForTmReply(DeviceCommandId_t *foundId) { - switch (decodedFrame[1]) { + const uint8_t* reply = dataLinkLayer.getReply(); + switch (*reply) { case (StarTracker::ID::VERSION): { *foundId = StarTracker::REQ_VERSION; break; @@ -418,7 +473,7 @@ ReturnValue_t StarTrackerHandler::scanForTmReply(DeviceCommandId_t *foundId) { break; } default: { - sif::debug << "StarTrackerHandler::scanForReply: Reply contains invalid reply id" + sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply id" << std::endl; return RETURN_FAILED; break; @@ -427,31 +482,37 @@ ReturnValue_t StarTrackerHandler::scanForTmReply(DeviceCommandId_t *foundId) { return RETURN_OK; } -void StarTrackerHandler::slipInit() { - slipInfo.buffer = rxBuffer; - slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE; - slipInfo.length = 0; - slipInfo.unescape_next = 0; - slipInfo.prev_state = SLIP_COMPLETE; +void StarTrackerHandler::handleEvent(EventMessage* eventMessage) { + object_id_t objectId = eventMessage->getReporter(); + switch(objectId){ + case objects::STR_IMG_LOADER: { + // All events from image loader signal either that the operation was successful or that it + // failed + imageLoaderExecuting = false; + break; + } + default: + sif::debug << "StarTrackerHandler::handleEvent: Did not subscribe to this event" + << std::endl; + break; + } } void StarTrackerHandler::prepareBootCommand() { uint32_t length = 0; struct BootActionRequest bootRequest = {BOOT_REGION_ID}; arc_pack_boot_action_req(&bootRequest, commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareTimeRequest() { uint32_t length = 0; arc_tm_pack_time_req(commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::preparePingRequest() { @@ -467,64 +528,37 @@ void StarTrackerHandler::preparePingRequest() { void StarTrackerHandler::prepareVersionRequest() { uint32_t length = 0; arc_tm_pack_version_req(commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareInterfaceRequest() { uint32_t length = 0; arc_tm_pack_interface_req(commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; -} - -ReturnValue_t StarTrackerHandler::prepareImageUploadCommand(const uint8_t* commandData, - size_t commandDataLen) { - if (commandDataLen != UPLOAD_COMMAND_LEN) { - return INVALID_UPLOAD_COMMAND; - } - uint32_t length = 0; - uint32_t position = deserializeUint32(commandData); - if (position > MAX_POSITION) { - return MAX_POSITION; - } - rememberUploadPosition = position; - struct UploadActionRequest uploadRequest; - uploadRequest.position = position; - std::memcpy(uploadRequest.data, commandData + 4, commandDataLen - 4); - arc_pack_upload_action_req(&uploadRequest, commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; - return RETURN_OK; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::preparePowerRequest() { uint32_t length = 0; arc_tm_pack_power_req(commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareRebootCommand() { uint32_t length = 0; struct RebootActionRequest rebootReq; arc_pack_reboot_action_req(&rebootReq, commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) { - uint32_t encLength = 0; uint32_t length = 18; commandBuffer[0] = TMTC_SETPARAMREQ; commandBuffer[1] = StarTracker::ID::SUBSCRIBE; @@ -545,9 +579,9 @@ void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) { commandBuffer[15] = 0; commandBuffer[16] = 0; commandBuffer[17] = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareSolutionRequest() { @@ -562,29 +596,30 @@ void StarTrackerHandler::prepareSolutionRequest() { void StarTrackerHandler::prepareTemperatureRequest() { uint32_t length = 0; arc_tm_pack_temperature_req(commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } ReturnValue_t StarTrackerHandler::handleSetParamReply() { - uint8_t status = *(decodedFrame + STATUS_OFFSET); + const uint8_t* reply = dataLinkLayer.getReply(); + uint8_t status = *(reply + STATUS_OFFSET); if (status != StarTracker::STATUS_OK) { sif::warning << "StarTrackerHandler::handleSetParamReply: Failed to execute parameter set " " command with parameter ID" << - static_cast(*(decodedFrame + PARAMETER_ID_OFFSET)) << std::endl; + static_cast(*(reply + PARAMETER_ID_OFFSET)) << std::endl; return SET_PARAM_FAILED; } return RETURN_OK; } ReturnValue_t StarTrackerHandler::handleActionReply() { - uint8_t status = *(decodedFrame + STATUS_OFFSET); + const uint8_t* reply = dataLinkLayer.getReply(); + uint8_t status = *(reply + STATUS_OFFSET); if (status != StarTracker::STATUS_OK) { sif::warning << "StarTrackerHandler::handleActionReply: Failed to execute action " << " command with action ID " - << static_cast(*(decodedFrame + ACTION_ID_OFFSET)) + << static_cast(*(reply + ACTION_ID_OFFSET)) << " and status "<< static_cast(status) << std::endl; return ACTION_FAILED; } @@ -594,8 +629,9 @@ ReturnValue_t StarTrackerHandler::handleActionReply() { ReturnValue_t StarTrackerHandler::handlePingReply() { ReturnValue_t result = RETURN_OK; uint32_t pingId = 0; - uint8_t status = *(decodedFrame + 2); - const uint8_t* buffer = decodedFrame + 3; + const uint8_t* reply = dataLinkLayer.getReply(); + uint8_t status = *(reply + 2); + const uint8_t* buffer = reply + 3; size_t size = sizeof(pingId); SerializeAdapter::deSerialize(&pingId, &buffer, &size, SerializeIF::Endianness::LITTLE); #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 @@ -609,22 +645,6 @@ ReturnValue_t StarTrackerHandler::handlePingReply() { return result; } -ReturnValue_t StarTrackerHandler::handleUploadImageReply() { - ReturnValue_t result = RETURN_OK; - result = handleActionReply(); - if (result != RETURN_OK) { - return result; - } - // Position seems to be always 0 (independent of sent position) -// uint32_t position = deserializeUint32(decodedFrame + ACTION_DATA_OFFSET); -// if (position != rememberUploadPosition) { -// sif::warning << "StarTrackerHandler::handleUploadImageReply: Invalid position" -// << std::endl; -// return UPLOAD_IMAGE_FAILED; -// } - return result; -} - ReturnValue_t StarTrackerHandler::handleTimeTm() { ReturnValue_t result = RETURN_OK; result = timeSet.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); @@ -642,11 +662,12 @@ ReturnValue_t StarTrackerHandler::handleTimeTm() { result = VERSION_REQ_FAILED; return result; } + const uint8_t* reply = dataLinkLayer.getReply(); timeSet.ticks = ticks; timeSet.time = time; - timeSet.runTime = deserializeUint32(decodedFrame + offset); + timeSet.runTime = deserializeUint32(reply + offset); offset += sizeof(uint32_t); - timeSet.unixTime = deserializeUint64(decodedFrame + offset); + timeSet.unixTime = deserializeUint64(reply + offset); result = timeSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { return result; @@ -674,13 +695,14 @@ ReturnValue_t StarTrackerHandler::handleVersionTm() { if (result != RETURN_OK) { return result; } + const uint8_t* reply = dataLinkLayer.getReply(); versionSet.ticks = ticks; versionSet.time = time; - versionSet.program = *(decodedFrame + offset); + versionSet.program = *(reply + offset); offset += 1; - versionSet.major = *(decodedFrame + offset); + versionSet.major = *(reply + offset); offset += 1; - versionSet.minor = *(decodedFrame + offset); + versionSet.minor = *(reply + offset); result = versionSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { return result; @@ -708,12 +730,13 @@ ReturnValue_t StarTrackerHandler::handleInterfaceTm() { if (result != RETURN_OK) { return result; } + const uint8_t* reply = dataLinkLayer.getReply(); interfaceSet.ticks = ticks; interfaceSet.time = time; size_t size = sizeof(uint32_t); - interfaceSet.frameCount = deserializeUint32(decodedFrame + offset); + interfaceSet.frameCount = deserializeUint32(reply + offset); offset += size; - interfaceSet.checksumerrorCount = deserializeUint32(decodedFrame + offset); + interfaceSet.checksumerrorCount = deserializeUint32(reply + offset); result = interfaceSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { return result; @@ -741,55 +764,56 @@ ReturnValue_t StarTrackerHandler::handlePowerTm() { if (result != RETURN_OK) { return result; } + const uint8_t* reply = dataLinkLayer.getReply(); powerSet.ticks= ticks; powerSet.time= time; float value = 0; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.mcuCurrent = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.mcuVoltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.fpgaCoreCurrent = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.fpgaCoreVoltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.fpga18Current = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.fpga18Voltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.fpga25Current = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.fpga25Voltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmv21Current = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmv21Voltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmvPixCurrent= value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmvPixVoltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmv33Current= value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmv33Voltage = value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmvResCurrent= value; offset += 4; - std::memcpy(&value, decodedFrame + offset, sizeof(value)); + std::memcpy(&value, reply + offset, sizeof(value)); powerSet.cmvResVoltage = value; result = powerSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { @@ -818,64 +842,65 @@ ReturnValue_t StarTrackerHandler::handleSolutionTm() { result = TEMPERATURE_REQ_FAILED; return result; } + const uint8_t* reply = dataLinkLayer.getReply(); solutionSet.ticks= ticks; solutionSet.time= time; float word = 0; - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.caliQw = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.caliQx = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.caliQy = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.caliQz = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.trackConfidence = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.trackQw = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.trackQx = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.trackQy = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.trackQz = word; offset += sizeof(float); - solutionSet.trackRemoved = *(decodedFrame + offset); + solutionSet.trackRemoved = *(reply + offset); offset += sizeof(uint8_t); - solutionSet.starsCentroided = *(decodedFrame + offset); + solutionSet.starsCentroided = *(reply + offset); offset += sizeof(uint8_t); - solutionSet.starsMatchedDatabase = *(decodedFrame + offset); + solutionSet.starsMatchedDatabase = *(reply + offset); offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.lisaQw = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.lisaQx = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.lisaQy = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.lisaQz = word; offset += sizeof(float); - std::memcpy(&word, decodedFrame + offset, sizeof(float)); + std::memcpy(&word, reply + offset, sizeof(float)); solutionSet.lisaPercentageClose = word; offset += sizeof(float); - solutionSet.lisaNrClose = *(decodedFrame + offset); + solutionSet.lisaNrClose = *(reply + offset); offset += sizeof(uint8_t); - solutionSet.isTrustWorthy = *(decodedFrame + offset); + solutionSet.isTrustWorthy = *(reply + offset); offset += sizeof(uint8_t); - solutionSet.stableCount = *(decodedFrame + offset); + solutionSet.stableCount = *(reply + offset); offset += sizeof(uint32_t); - solutionSet.stableCount = *(decodedFrame + offset); + solutionSet.stableCount = *(reply + offset); result = solutionSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { return result; @@ -903,13 +928,14 @@ ReturnValue_t StarTrackerHandler::handleTemperatureTm() { if (result != RETURN_OK) { return result; } + const uint8_t* reply = dataLinkLayer.getReply(); temperatureSet.ticks= ticks; temperatureSet.time= time; float temperature = 0; - std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); + std::memcpy(&temperature, reply + offset, sizeof(temperature)); temperatureSet.mcuTemperature = temperature; offset += sizeof(float); - std::memcpy(&temperature, decodedFrame + offset, sizeof(temperature)); + std::memcpy(&temperature, reply + offset, sizeof(temperature)); temperatureSet.cmosTemperature = temperature; result = temperatureSet.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != RETURN_OK) { @@ -922,9 +948,10 @@ ReturnValue_t StarTrackerHandler::handleTemperatureTm() { } void StarTrackerHandler::getTmHeaderData(uint8_t* status, uint32_t* ticks, uint64_t* time) { - *status = *(decodedFrame + STATUS_OFFSET); - *ticks = deserializeUint32(decodedFrame + TICKS_OFFSET); - *time = deserializeUint64(decodedFrame + TIME_OFFSET); + const uint8_t* reply = dataLinkLayer.getReply(); + *status = *(reply + STATUS_OFFSET); + *ticks = deserializeUint32(reply + TICKS_OFFSET); + *time = deserializeUint64(reply + TIME_OFFSET); } uint32_t StarTrackerHandler::deserializeUint32(const uint8_t* buffer) { diff --git a/mission/devices/StarTrackerHandler.h b/mission/devices/StarTrackerHandler.h index d74d6fd2..e8aef15a 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/mission/devices/StarTrackerHandler.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include /** * @brief This is the device handler for the star tracker from arcsec. @@ -35,6 +37,15 @@ public: ReturnValue_t initialize() override; + /** + * @brief Overwrite this function from DHB to handle commands executed by the str image + * loader task. + */ + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; + + void performOperationHook() override; + protected: void doStartUp() override; void doShutDown() override; @@ -64,7 +75,9 @@ private: //! [EXPORT] : [COMMENT] Received reply is too short static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB0); //! [EXPORT] : [COMMENT] Received reply with invalid CRC - static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB0); + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB1); + //! [EXPORT] : [COMMENT] Image loader executing + static const ReturnValue_t IMAGE_LOADER_EXECUTING = MAKE_RETURN_CODE(0xB2); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; @@ -95,13 +108,13 @@ private: static const size_t UPLOAD_COMMAND_LEN = 1028; // Max valid position value in upload image command static const uint16_t MAX_POSITION= 4095; - static const uint8_t STATUS_OFFSET = 2; - static const uint8_t TICKS_OFFSET = 3; - static const uint8_t TIME_OFFSET = 7; - static const uint8_t TM_DATA_FIELD_OFFSET = 15; - static const uint8_t PARAMETER_ID_OFFSET = 1; - static const uint8_t ACTION_ID_OFFSET = 1; - static const uint8_t ACTION_DATA_OFFSET = 3; + static const uint8_t STATUS_OFFSET = 1; + static const uint8_t TICKS_OFFSET = 2; + static const uint8_t TIME_OFFSET = 6; + static const uint8_t TM_DATA_FIELD_OFFSET = 14; + static const uint8_t PARAMETER_ID_OFFSET = 0; + static const uint8_t ACTION_ID_OFFSET = 0; + static const uint8_t ACTION_DATA_OFFSET = 2; // Ping request will reply ping with this ID (data field) static const uint32_t PING_ID = 0x55; @@ -113,6 +126,10 @@ private: // Pointer to object responsible for uploading and downloading images to/from the star tracker StrImageLoader* strImageLoader = nullptr; + MessageQueueIF* eventQueue = nullptr; + + ArcsecDatalinkLayer dataLinkLayer; + StarTracker::TemperatureSet temperatureSet; StarTracker::VersionSet versionSet; StarTracker::PowerSet powerSet; @@ -121,13 +138,6 @@ private: StarTracker::SolutionSet solutionSet; uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; - uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; - uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE]; - - /** Size of buffer derived from the egse source code */ - uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2]; - - slip_decode_state slipInfo; enum class InternalState { TEMPERATURE_REQUEST @@ -135,7 +145,7 @@ private: InternalState internalState = InternalState::TEMPERATURE_REQUEST; - uint32_t rememberUploadPosition = 0; + bool imageLoaderExecuting = false; /** * @brief This function initializes the serial link ip protocol struct slipInfo. @@ -172,11 +182,6 @@ private: */ void prepareInterfaceRequest(); - /** - * @brief Fills the command buffer with data to upload part of an image. - */ - ReturnValue_t prepareImageUploadCommand(const uint8_t* commandData, size_t commandDataLen); - /** * @brief Fills the command buffer with data to request the power telemetry packet. */ @@ -217,11 +222,6 @@ private: ReturnValue_t handlePingReply(); - /** - * @brief Handles reply to upload image command - */ - ReturnValue_t handleUploadImageReply(); - /** * @brief Fills the time set with the data of the time request reply. */ diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/mission/devices/devicedefinitions/StarTrackerDefinitions.h index ef9182ff..4721957b 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/mission/devices/devicedefinitions/StarTrackerDefinitions.h @@ -91,6 +91,7 @@ static const DeviceCommandId_t REQ_VERSION = 2; static const DeviceCommandId_t REQ_INTERFACE = 3; static const DeviceCommandId_t REQ_TIME = 4; static const DeviceCommandId_t REBOOT = 7; +static const DeviceCommandId_t DOWNLOAD_IMAGE = 9; static const DeviceCommandId_t UPLOAD_IMAGE = 10; static const DeviceCommandId_t REQ_POWER = 11; static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CCSDSHandler.cpp index e0239d9a..524fe4b8 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CCSDSHandler.cpp @@ -80,15 +80,19 @@ ReturnValue_t CCSDSHandler::initialize() { EventManagerIF* manager = ObjectManager::instance()->get( objects::EVENT_MANAGER); - if (manager == nullptr) { + if (manager == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CCSDSHandler::initialize: Invalid event manager" << std::endl; #endif - return RETURN_FAILED; + return ObjectManagerIF::CHILD_INIT_FAILED; } result = manager->registerListener(eventQueue->getId()); if (result != HasReturnvaluesIF::RETURN_OK) { - return result; +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "CCSDSHandler::initialize: Failed to register CCSDS handler as event " + "listener" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED;; } result = manager->subscribeToEventRange(eventQueue->getId(), event::getEventId(PdecHandler::CARRIER_LOCK), diff --git a/tmtc b/tmtc index 1d374230..dedb2849 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1d374230b34606d8b6aa4df1335befec316a1e35 +Subproject commit dedb28497f62314498034cd87d1e2a4361b92950 From 7cc0fc640faec86af7f89319ded8b04c72f31844 Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Thu, 2 Dec 2021 11:51:22 +0100 Subject: [PATCH 12/78] pdec monitor register --- linux/obc/PdecHandler.cpp | 40 ++++++++++++++++++++++++++ linux/obc/PdecHandler.h | 59 +++++++++++++++++++++++++++++++-------- tmtc | 2 +- 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 1ac83d44..829377d0 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -484,6 +484,10 @@ uint32_t PdecHandler::getClcw() { return *(registerBaseAddress + PDEC_CLCW_OFFSET); } +uint32_t PdecHandler::getPdecMon() { + return *(registerBaseAddress + PDEC_MON_OFFSET); +} + void PdecHandler::printClcw() { uint32_t clcw = getClcw(); uint8_t type = static_cast((clcw >> 31) & 0x1); @@ -525,6 +529,39 @@ void PdecHandler::printClcw() { << "0x" << static_cast(repValue) << std::endl; } +void PdecHandler::printPdecMon() { + uint32_t pdecMon = getPdecMon(); + uint32_t tc0ChannelStatus = (pdecMon & TC0_STATUS_MASK) >> TC0_STATUS_POS; + uint32_t tc1ChannelStatus = (pdecMon & TC1_STATUS_MASK) >> TC1_STATUS_POS; + uint32_t tc2ChannelStatus = (pdecMon & TC2_STATUS_MASK) >> TC2_STATUS_POS; + uint32_t tc3ChannelStatus = (pdecMon & TC3_STATUS_MASK) >> TC3_STATUS_POS; + uint32_t tc4ChannelStatus = (pdecMon & TC4_STATUS_MASK) >> TC4_STATUS_POS; + uint32_t tc5ChannelStatus = (pdecMon & TC5_STATUS_MASK) >> TC5_STATUS_POS; + uint32_t lock = (pdecMon & LOCK_MASK) >> LOCK_POS; + sif::info << std::setw(30) << std::left << "TC0 status: " << getMonStatusString(tc0ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC1 status: " << getMonStatusString(tc1ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC2 status: " << getMonStatusString(tc2ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC3 status: " << getMonStatusString(tc3ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC4 status: " << getMonStatusString(tc4ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC5 status: " << getMonStatusString(tc5ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl; +} + +std::string PdecHandler::getMonStatusString(uint32_t status) { + switch(status) { + case TC_CHANNEL_INACTIVE: + return std::string("inactive"); + case TC_CHANNEL_ACTIVE: + return std::string("active"); + case TC_CHANNEL_TIMEDOUT: + return std::string("timed out"); + default: + sif::warning << "PdecHandler::getMonStatusString: Invalid status" << std::endl; + return std::string(); + break; + } +} + ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { @@ -532,6 +569,9 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, case PRINT_CLCW: printClcw(); return EXECUTION_FINISHED; + case PRINT_PDEC_MON: + printPdecMon(); + return EXECUTION_FINISHED; default: return COMMAND_NOT_IMPLEMENTED; } diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 8819df22..8c8e8d9b 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -61,16 +61,6 @@ public: ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) override; - /** - * brief Returns the 32-bit wide communication link control word (CLCW) - */ - uint32_t getClcw(); - - /** - * @rief Reads and prints the CLCW. Can be useful for debugging. - */ - void printClcw(); - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame @@ -119,6 +109,8 @@ private: // Action IDs static const ActionId_t PRINT_CLCW = 0; + // Print PDEC monitor register + static const ActionId_t PRINT_PDEC_MON = 1; static const uint8_t STAT_POSITION = 31; static const uint8_t FRAME_ANA_POSITION = 28; @@ -129,6 +121,28 @@ private: static const uint32_t FRAME_ANA_MASK = 0x70000000; static const uint32_t IREASON_MASK = 0x0E000000; + static const uint32_t TC_CHANNEL_INACTIVE = 0x0; + static const uint32_t TC_CHANNEL_ACTIVE = 0x1; + static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2; + + static const uint32_t TC0_STATUS_MASK = 0x3; + static const uint32_t TC1_STATUS_MASK = 0xC; + static const uint32_t TC2_STATUS_MASK = 0x300; + static const uint32_t TC3_STATUS_MASK = 0xC00; + static const uint32_t TC4_STATUS_MASK = 0x30000; + static const uint32_t TC5_STATUS_MASK = 0xc00000; + // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) + static const uint32_t LOCK_MASK = 0xc00000; + + static const uint32_t TC0_STATUS_POS = 0; + static const uint32_t TC1_STATUS_POS = 2; + static const uint32_t TC2_STATUS_POS = 4; + static const uint32_t TC3_STATUS_POS = 6; + static const uint32_t TC4_STATUS_POS = 8; + static const uint32_t TC5_STATUS_POS = 10; + // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) + static const uint32_t LOCK_POS = 12; + /** * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 @@ -138,7 +152,7 @@ private: static const uint32_t PDEC_BFREE_OFFSET = 0xA24; static const uint32_t PDEC_BPTR_OFFSET = 0xA25; static const uint32_t PDEC_SLEN_OFFSET = 0xA26; - static const uint32_t PDEC_MON = 0xA27; + static const uint32_t PDEC_MON_OFFSET = 0xA27; #if BOARD_TE0720 == 1 static const int CONFIG_MEMORY_MAP_SIZE = 0x400; @@ -330,6 +344,29 @@ private: */ uint8_t getOddParity(uint8_t number); + /** + * brief Returns the 32-bit wide communication link control word (CLCW) + */ + uint32_t getClcw(); + + /** + * @brief Returns the PDEC monitor register content + * + */ + uint32_t getPdecMon(); + + /** + * @brief Reads and prints the CLCW. Can be useful for debugging. + */ + void printClcw(); + + /** + * @brief Prints monitor register information to debug console. + */ + void printPdecMon(); + + std::string getMonStatusString(uint32_t status); + object_id_t tcDestinationId; AcceptsTelecommandsIF* tcDestination = nullptr; diff --git a/tmtc b/tmtc index 1d374230..bcec5df6 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1d374230b34606d8b6aa4df1335befec316a1e35 +Subproject commit bcec5df6e2636e3751f7a7eb103b893dc4581c10 From fac6996a15106aa2930457ab20900dba5d0c7635 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 6 Dec 2021 19:36:21 +0100 Subject: [PATCH 13/78] star tracker limits setting --- bsp_q7s/core/InitMission.cpp | 8 + bsp_q7s/core/ObjectFactory.cpp | 15 +- bsp_q7s/devices/ArcsecDatalinkLayer.cpp | 16 +- bsp_q7s/devices/ArcsecDatalinkLayer.h | 20 +- bsp_q7s/devices/CMakeLists.txt | 4 +- .../devices/StarTrackerHandler.cpp | 119 +++++- .../devices/StarTrackerHandler.h | 30 +- bsp_q7s/devices/StarTrackerImageHelper.cpp | 311 ---------------- bsp_q7s/devices/StarTrackerImageHelper.h | 153 -------- bsp_q7s/devices/StrImageLoader.cpp | 185 ++++++---- bsp_q7s/devices/StrImageLoader.h | 56 ++- .../StarTrackerDefinitions.h | 32 +- .../StarTrackerJsonCommands.h | 343 ++++++++++++++++++ bsp_q7s/memory/SdCardManager.cpp | 4 +- common/config/commonClassIds.h | 3 +- common/config/commonObjects.h | 2 +- generators/bsp_q7s_events.csv | 250 +++++++------ generators/bsp_q7s_objects.csv | 3 +- generators/events/translateEvents.cpp | 34 +- generators/objects/translateObjects.cpp | 11 +- linux/fsfwconfig/events/translateEvents.cpp | 34 +- linux/fsfwconfig/objects/translateObjects.cpp | 11 +- .../pollingSequenceFactory.cpp | 11 +- linux/obc/PdecHandler.cpp | 24 +- mission/devices/CMakeLists.txt | 1 - tmtc | 2 +- 26 files changed, 949 insertions(+), 733 deletions(-) rename {mission => bsp_q7s}/devices/StarTrackerHandler.cpp (90%) rename {mission => bsp_q7s}/devices/StarTrackerHandler.h (92%) delete mode 100644 bsp_q7s/devices/StarTrackerImageHelper.cpp delete mode 100644 bsp_q7s/devices/StarTrackerImageHelper.h rename {mission => bsp_q7s}/devices/devicedefinitions/StarTrackerDefinitions.h (93%) create mode 100644 bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 7923a2cd..9e293969 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -126,6 +126,13 @@ void initmission::initTasks() { if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER); } + + PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask( + "FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = strImgLoaderTask->addComponent(objects::STR_IMG_LOADER); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_IMG_LOADER); + } #endif /* BOARD_TE0720 */ #if OBSW_TEST_CCSDS_BRIDGE == 1 @@ -187,6 +194,7 @@ void initmission::initTasks() { #if BOARD_TE0720 == 0 fsTask->startTask(); + strImgLoaderTask->startTask(); #endif sif::info << "Tasks started.." << std::endl; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 44e4484b..f1d0dcf0 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,5 +1,7 @@ #include #include "ObjectFactory.h" + +#include "../devices/devicedefinitions/StarTrackerDefinitions.h" #include "OBSWConfig.h" #include "devConf.h" #include "ccsdsConfig.h" @@ -16,7 +18,8 @@ #include "bsp_q7s/devices/PlocSupervisorHandler.h" #include "bsp_q7s/devices/PlocUpdater.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" -#include "bsp_q7s/devices/StarTrackerImageHelper.h" +#include "bsp_q7s/devices/StrImageLoader.h" +#include "bsp_q7s/devices/StarTrackerHandler.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h" @@ -40,14 +43,12 @@ #include "mission/devices/PlocMPSoCHandler.h" #include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RwHandler.h" -#include "mission/devices/StarTrackerHandler.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "mission/devices/devicedefinitions/PlocMPSoCDefinitions.h" #include "mission/devices/devicedefinitions/RadSensorDefinitions.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" #include "mission/devices/devicedefinitions/RwDefinitions.h" -#include "mission/devices/devicedefinitions/StarTrackerDefinitions.h" #include "mission/devices/GPSHyperionHandler.h" #include "mission/tmtc/CCSDSHandler.h" #include "mission/tmtc/VirtualChannel.h" @@ -168,13 +169,15 @@ void ObjectFactory::produce(void* args) { new FileSystemHandler(objects::FILE_SYSTEM_HANDLER); #if OBSW_ADD_STAR_TRACKER == 1 - UartCookie* starTrackerCookie = new UartCookie(objects::START_TRACKER, + UartCookie* starTrackerCookie = new UartCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, UartModes::NON_CANONICAL, uart::STAR_TRACKER_BAUD, StarTracker::MAX_FRAME_SIZE* 2 + 2); starTrackerCookie->setNoFixedSizeReply(); - StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie); + StrImageLoader* strImageLoader = new StrImageLoader(objects::STR_IMG_LOADER); + StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(objects::STAR_TRACKER, + objects::UART_COM_IF, starTrackerCookie, strImageLoader); starTrackerHandler->setStartUpImmediately(); - new StarTrackerImageHelper(objects::STR_IMG_HELPER); + #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* TE7020 == 0 */ diff --git a/bsp_q7s/devices/ArcsecDatalinkLayer.cpp b/bsp_q7s/devices/ArcsecDatalinkLayer.cpp index 1f436636..4e7c9458 100644 --- a/bsp_q7s/devices/ArcsecDatalinkLayer.cpp +++ b/bsp_q7s/devices/ArcsecDatalinkLayer.cpp @@ -21,7 +21,7 @@ ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t ra for (bytePos = 0; bytePos < rawDataSize; bytePos++) { enum arc_dec_result decResult = arc_transport_decode_body(*(rawData + bytePos), &slipInfo, decodedFrame, &decFrameSize); - *bytesLeft = rawDataSize - bytePos; + *bytesLeft = rawDataSize - bytePos - 1; switch (decResult) { case ARC_DEC_INPROGRESS: { if (bytePos == rawDataSize - 1) { @@ -37,13 +37,15 @@ ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t ra case ARC_DEC_SYNC: { // Reset length of SLIP struct for next frame slipInfo.length = 0; - RETURN_OK; + return RETURN_OK; } default: sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl; break; + return RETURN_FAILED; } } + return RETURN_FAILED; } uint8_t ArcsecDatalinkLayer::getReplyFrameType() { @@ -55,7 +57,7 @@ const uint8_t* ArcsecDatalinkLayer::getReply() { } void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) { - arc_transport_encode_body(commandBuffer, length, encBuffer, &encFrameSize); + arc_transport_encode_body(data, length, encBuffer, &encFrameSize); } uint8_t* ArcsecDatalinkLayer::getEncodedFrame() { @@ -66,3 +68,11 @@ uint32_t ArcsecDatalinkLayer::getEncodedLength() { return encFrameSize; } +uint8_t ArcsecDatalinkLayer::getStatusField() { + return *(decodedFrame + STATUS_OFFSET); +} + +uint8_t ArcsecDatalinkLayer::getId() { + return *(decodedFrame + ID_OFFSET); +} + diff --git a/bsp_q7s/devices/ArcsecDatalinkLayer.h b/bsp_q7s/devices/ArcsecDatalinkLayer.h index bce1f619..58acd4b3 100644 --- a/bsp_q7s/devices/ArcsecDatalinkLayer.h +++ b/bsp_q7s/devices/ArcsecDatalinkLayer.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ #define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ -#include "mission/devices/devicedefinitions/StarTrackerDefinitions.h" +#include "devicedefinitions/StarTrackerDefinitions.h" #include "fsfw/returnvalues/HasReturnValuesIF.h" extern "C" { @@ -23,6 +23,8 @@ public: //! [EXPORT] : [COMMENT] Detected CRC failure in received frame static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2); + static const uint8_t STATUS_OK = 0; + ArcsecDatalinkLayer(); virtual ~ArcsecDatalinkLayer(); @@ -63,13 +65,27 @@ public: */ uint8_t* getEncodedFrame(); + /** + * @brief Returns status of reply + */ + uint8_t getStatusField(); + + /** + * @brief Returns ID of reply + */ + uint8_t getId(); + private: + static const uint8_t ID_OFFSET = 1; + static const uint8_t STATUS_OFFSET = 2; + // Used by arcsec slip decoding function process received data uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; // Decoded frame will be copied to this buffer uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE]; - // Buffer where encoded frames will be stored + // Buffer where encoded frames will be stored. First byte of encoded frame represents type of + // reply uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2]; // Size of decoded frame uint32_t decFrameSize = 0; diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt index ecc6bdc1..edabfa96 100644 --- a/bsp_q7s/devices/CMakeLists.txt +++ b/bsp_q7s/devices/CMakeLists.txt @@ -2,5 +2,7 @@ target_sources(${TARGET_NAME} PRIVATE PlocSupervisorHandler.cpp PlocUpdater.cpp PlocMemoryDumper.cpp - StarTrackerImageHelper.cpp + StrImageLoader.cpp + ArcsecDatalinkLayer.cpp + StarTrackerHandler.cpp ) \ No newline at end of file diff --git a/mission/devices/StarTrackerHandler.cpp b/bsp_q7s/devices/StarTrackerHandler.cpp similarity index 90% rename from mission/devices/StarTrackerHandler.cpp rename to bsp_q7s/devices/StarTrackerHandler.cpp index dacb8617..1a8b4971 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/StarTrackerHandler.cpp @@ -1,7 +1,11 @@ +#include + #include "StarTrackerHandler.h" #include "OBSWConfig.h" +#include "devicedefinitions/StarTrackerJsonCommands.h" #include +#include extern "C" { #include @@ -21,7 +25,6 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; } eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); - slipInit(); } StarTrackerHandler::~StarTrackerHandler() { @@ -43,7 +46,7 @@ ReturnValue_t StarTrackerHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED;; } result = manager->registerListener(eventQueue->getId()); - if (result != HasReturnvaluesIF::RETURN_OK) { + if (result != RETURN_OK) { return result; } result = manager->subscribeToAllEventsFrom(eventQueue->getId(), objects::STR_IMG_LOADER); @@ -57,18 +60,28 @@ ReturnValue_t StarTrackerHandler::initialize() { strImageLoader->setComIF(communicationInterface); strImageLoader->setComCookie(comCookie); + return RETURN_OK; } ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + ReturnValue_t result = RETURN_OK; + if (imageLoaderExecuting == true) { return IMAGE_LOADER_EXECUTING; } // Intercept image loader commands which do not follow the common DHB communication flow switch(actionId) { case(StarTracker::UPLOAD_IMAGE): { - strImageLoader->startImageUpload(); + if (size > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + result = strImageLoader->startImageUpload( + std::string(reinterpret_cast(data), size)); + if (result != RETURN_OK) { + return result; + } imageLoaderExecuting = true; return EXECUTION_FINISHED; } @@ -80,7 +93,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu default: break; } - return DeviceHandlerBase::executeAction(); + return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); } void StarTrackerHandler::performOperationHook() { @@ -180,6 +193,14 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi prepareTemperatureRequest(); return RETURN_OK; } + case (StarTracker::LIMITS): { + result = prepareLimitsCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::TRACKING): { + result = prepareTrackingCommand(commandData, commandDataLen); + return result; + } default: return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } @@ -210,20 +231,20 @@ void StarTrackerHandler::fillCommandAndReplyMap() { StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 3, &temperatureSet, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::LIMITS, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); } ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { ReturnValue_t result = RETURN_OK; - uint32_t decodedLength = 0; - size_t bytePos = 0; size_t bytesLeft = 0; result = dataLinkLayer.decodeFrame(start, remainingSize, &bytesLeft); - remainingSize = *bytesLeft; switch(result) { case ArcsecDatalinkLayer::DEC_IN_PROGRESS: { + remainingSize = bytesLeft; // Need a second doSendRead pass to reaa in whole packet return IGNORE_REPLY_DATA; } @@ -231,23 +252,24 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema break; } default: + remainingSize = bytesLeft; return result; } switch (dataLinkLayer.getReplyFrameType()) { case TMTC_ACTIONREPLY: { - *foundLen = remainingsize - bytesLeft; + *foundLen = remainingSize - bytesLeft; result = scanForActionReply(foundId); break; } case TMTC_SETPARAMREPLY: { - *foundLen = remainingsize - bytesLeft; + *foundLen = remainingSize - bytesLeft; result = scanForSetParameterReply(foundId); break; } case TMTC_TELEMETRYREPLYA: case TMTC_TELEMETRYREPLY: { - *foundLen = remainingsize - bytesLeft; + *foundLen = remainingSize - bytesLeft; result = scanForTmReply(foundId); break; } @@ -257,6 +279,8 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema } } + remainingSize = bytesLeft; + return result; } @@ -301,6 +325,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con handleTemperatureTm(); break; } + case (StarTracker::LIMITS): { + result = handleSetParamReply(); + break; + } default: { sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id:" << id << std::endl; @@ -407,6 +435,13 @@ size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){ return StarTracker::MAX_FRAME_SIZE; } +ReturnValue_t StarTrackerHandler::doSendReadHook() { + if(imageLoaderExecuting) { + return RETURN_FAILED; + } + return RETURN_OK; +} + ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) { const uint8_t* reply = dataLinkLayer.getReply(); switch (*reply) { @@ -423,7 +458,7 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) break; } default: - sif::debug << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" + sif::warning << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" << std::endl; return RETURN_FAILED; } @@ -437,6 +472,10 @@ ReturnValue_t StarTrackerHandler::scanForSetParameterReply(DeviceCommandId_t *fo *foundId = StarTracker::SUBSCRIBE_TO_TM; break; } + case (StarTracker::ID::LIMITS): { + *foundId = StarTracker::LIMITS; + break; + } default: sif::debug << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" << std::endl; @@ -519,10 +558,9 @@ void StarTrackerHandler::preparePingRequest() { uint32_t length = 0; struct PingActionRequest pingRequest = {PING_ID}; arc_pack_ping_action_req(&pingRequest, commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareVersionRequest() { @@ -587,10 +625,9 @@ void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) { void StarTrackerHandler::prepareSolutionRequest() { uint32_t length = 0; arc_tm_pack_solution_req(commandBuffer, &length); - uint32_t encLength = 0; - arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength); - rawPacket = encBuffer; - rawPacketLen = encLength; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); } void StarTrackerHandler::prepareTemperatureRequest() { @@ -601,6 +638,48 @@ void StarTrackerHandler::prepareTemperatureRequest() { rawPacketLen = dataLinkLayer.getEncodedLength(); } +ReturnValue_t StarTrackerHandler::prepareLimitsCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + std::string fullName(reinterpret_cast(commandData), commandDataLen); + + Limits limits; + result = limits.create(fullName, commandBuffer); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareLimitsCommand: Failed to create limits command" + << std::endl; + return result; + } + dataLinkLayer.encodeFrame(commandBuffer, Limits::COMMAND_SIZE); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::prepareTrackingCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + std::string fullName(reinterpret_cast(commandData), commandDataLen); + + Tracking tracking; + result = tracking.create(fullName, commandBuffer); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareTrackingCommand: Failed to create tracking " + " command" << std::endl; + return result; + } + dataLinkLayer.encodeFrame(commandBuffer, Tracking::COMMAND_SIZE); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + ReturnValue_t StarTrackerHandler::handleSetParamReply() { const uint8_t* reply = dataLinkLayer.getReply(); uint8_t status = *(reply + STATUS_OFFSET); @@ -963,7 +1042,7 @@ uint32_t StarTrackerHandler::deserializeUint32(const uint8_t* buffer) { return word; } -uint64_t StarTrackerHandler::deserializeUint64(uint8_t* buffer) { +uint64_t StarTrackerHandler::deserializeUint64(const uint8_t* buffer) { uint64_t word = 0; word = static_cast(*(buffer + 7)) << 56 | static_cast(*(buffer + 6)) << 48 diff --git a/mission/devices/StarTrackerHandler.h b/bsp_q7s/devices/StarTrackerHandler.h similarity index 92% rename from mission/devices/StarTrackerHandler.h rename to bsp_q7s/devices/StarTrackerHandler.h index e8aef15a..27d14a3d 100644 --- a/mission/devices/StarTrackerHandler.h +++ b/bsp_q7s/devices/StarTrackerHandler.h @@ -3,12 +3,11 @@ #include #include -#include #include #include #include #include -#include +#include /** * @brief This is the device handler for the star tracker from arcsec. @@ -68,6 +67,8 @@ protected: */ virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override; + virtual ReturnValue_t doSendReadHook() override; + private: static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER; @@ -102,7 +103,11 @@ private: //! [EXPORT] : [COMMENT] Position value in upload image reply not matching sent position static const ReturnValue_t UPLOAD_IMAGE_FAILED = MAKE_RETURN_CODE(0xA9); //! [EXPORT] : [COMMENT] Received upload image command with invalid length - static const ReturnValue_t INVALID_UPLOAD_COMMAND = MAKE_RETURN_CODE(0xA9); + static const ReturnValue_t INVALID_UPLOAD_COMMAND = MAKE_RETURN_CODE(0xAA); + //! [EXPORT] : [COMMENT] Received invalid path string. Exceeds allowed length + static const ReturnValue_t FILE_PATH_TOO_LONG = MAKE_RETURN_CODE(0xAB); + + static const size_t MAX_PATH_SIZE = 50; // position (uint32) + 1024 image data static const size_t UPLOAD_COMMAND_LEN = 1028; @@ -123,9 +128,6 @@ private: static const MutexIF::TimeoutType TIMEOUT_TYPE= MutexIF::TimeoutType::WAITING; static const uint32_t MUTEX_TIMEOUT = 20; - // Pointer to object responsible for uploading and downloading images to/from the star tracker - StrImageLoader* strImageLoader = nullptr; - MessageQueueIF* eventQueue = nullptr; ArcsecDatalinkLayer dataLinkLayer; @@ -137,6 +139,9 @@ private: StarTracker::TimeSet timeSet; StarTracker::SolutionSet solutionSet; + // Pointer to object responsible for uploading and downloading images to/from the star tracker + StrImageLoader* strImageLoader = nullptr; + uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; enum class InternalState { @@ -166,6 +171,11 @@ private: */ void prepareTimeRequest(); + /** + * @brief Handles all received event messages + */ + void handleEvent(EventMessage* eventMessage); + /** * @brief Fills command buffer with data to boot image (works only when star tracker is * in bootloader mode). @@ -210,6 +220,12 @@ private: */ void prepareTemperatureRequest(); + /** + * @brief Reads limit parameters from json file specified with commandData and prepares + * the command to apply the limits to the star tracker. + */ + ReturnValue_t prepareLimitsCommand(const uint8_t* commandData, size_t commandDataLen); + /** * @brief Default function to handle action replies */ @@ -277,7 +293,7 @@ private: * * @note Deserialization will be performed in little endian byte order */ - uint64_t deserializeUint64(uint8_t* buffer); + uint64_t deserializeUint64(const uint8_t* buffer); }; #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ diff --git a/bsp_q7s/devices/StarTrackerImageHelper.cpp b/bsp_q7s/devices/StarTrackerImageHelper.cpp deleted file mode 100644 index 3fb62b99..00000000 --- a/bsp_q7s/devices/StarTrackerImageHelper.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include "fsfw/ipc/QueueFactory.h" -#include "StarTrackerImageHelper.h" - -#include -#include -#include - -StarTrackerImageHelper::StarTrackerImageHelper(object_id_t objectId) : - SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); -} - -StarTrackerImageHelper::~StarTrackerImageHelper() { -} - -ReturnValue_t StarTrackerImageHelper::initialize() { - sdcMan = SdCardManager::instance(); - if (sdcMan == nullptr) { - sif::warning << "StarTrackerImageHelper::initialize: Invaldi SD Card Manager" << std::endl; - } - ReturnValue_t result = SystemObject::initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = commandActionHelper.initialize(); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = actionHelper.initialize(commandQueue); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t StarTrackerImageHelper::performOperation(uint8_t operationCode) { - readCommandQueue(); - doStateMachine(); - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t StarTrackerImageHelper::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - ReturnValue_t result = EXECUTION_FINISHED; - - if (state != State::IDLE) { - return IS_BUSY; - } - - if (size > MAX_STR_IMAGE_PATH) { - return NAME_TOO_LONG; - } - - switch (actionId) { - case UPLOAD_IMAGE: - result = prepareUploadCommand(data, size); - if (result == RETURN_OK) { - result = EXECUTION_FINISHED; - } - break; - case DOWNLOAD_IMAGE: - break; - default: - return INVALID_ACTION_ID; - } - - return result; -} - -MessageQueueId_t StarTrackerImageHelper::getCommandQueue() const { - return commandQueue->getId(); -} - -MessageQueueIF* StarTrackerImageHelper::getCommandQueuePtr() { - return commandQueue; -} - -void StarTrackerImageHelper::readCommandQueue() { - CommandMessage message; - ReturnValue_t result; - - for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; - result = commandQueue->receiveMessage(&message)) { - if (result != RETURN_OK) { - continue; - } - result = actionHelper.handleActionMessage(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - result = commandActionHelper.handleReply(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - - sif::debug << "StarTrackerImageHelper::readCommandQueue: Received inalid message" - << std::endl; - } -} - -void StarTrackerImageHelper::doStateMachine() { - switch (state) { - case State::IDLE: - break; - case State::SEND_NEXT_UPLOAD_CMD: - commandImageUpload(); - break; - case State::COMMAND_EXECUTING: - case State::UPLOAD_LAST: - break; - default: - sif::debug << "StarTrackerImageHelper::doStateMachine: Invalid state" << std::endl; - break; - } -} - -ReturnValue_t StarTrackerImageHelper::getImageLocation(const uint8_t* data, size_t size) { - - // Check if file is stored on SD card and if associated SD card is mounted - if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StarTrackerImageHelper::getImageLocation: SD card 0 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StarTrackerImageHelper::getImageLocation: SD card 1 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - else { - // Specified path in RAM filesystem - } - - imageFile = std::string(reinterpret_cast(data), size); - - // Check if file exists - if(not std::filesystem::exists(imageFile)) { - return FILE_NOT_EXISTS; - } - return RETURN_OK; -} - -bool StarTrackerImageHelper::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatePair active; - ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); - if (result != RETURN_OK) { - sif::debug << "StarTrackerImageHelper::isSdCardMounted: Failed to get SD card active state"; - return false; - } - if (sdCard == sd::SLOT_0) { - if (active.first == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else if (sdCard == sd::SLOT_1) { - if (active.second == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else { - sif::debug << "StarTrackerImageHelper::isSdCardMounted: Unknown SD card specified" << std::endl; - } - return false; -} - -ReturnValue_t StarTrackerImageHelper::prepareUploadCommand(const uint8_t* data, size_t size) { - ReturnValue_t result = RETURN_OK; - result = getImageLocation(data, size); - if (result != RETURN_OK) { - return result; - } - imageSize = std::filesystem::file_size(imageFile); - remainingCommands = imageSize / SIZE_IMAGE_PART ; - if (imageSize % SIZE_IMAGE_PART) { - remainingCommands++; - } - commandsSent = 0; - state = State::SEND_NEXT_UPLOAD_CMD; - return result; -} - -void StarTrackerImageHelper::stepSuccessfulReceived(ActionId_t actionId, - uint8_t step) { -} - -void StarTrackerImageHelper::stepFailedReceived(ActionId_t actionId, uint8_t step, - ReturnValue_t returnCode) { - switch (pendingCommand) { - case (StarTracker::UPLOAD_IMAGE): - if (retries < MAX_RETRIES) { - // Repeat sending last command - commandsSent--; - remainingCommands++; - commandImageUpload(); - retries++; - state = State::COMMAND_EXECUTING; - } - else { - triggerEvent(IMAGE_UPLOAD_FAILED, returnCode, commandsSent); - retries = 0; - state = State::IDLE; - } - break; - default: - sif::debug << "StarTrackerImageHelper::completionSuccessfulReceived: Invalid pending command" - << std::endl; - break; - } -} - -void StarTrackerImageHelper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { -} - -void StarTrackerImageHelper::completionSuccessfulReceived(ActionId_t actionId) { - switch (pendingCommand) { - case (StarTracker::UPLOAD_IMAGE): - if (state == State::UPLOAD_LAST) { - triggerEvent(IMAGE_UPLOAD_FINISHED); - pendingCommand = StarTracker::NONE; - state = State::IDLE; - } - else { - state = State::SEND_NEXT_UPLOAD_CMD; - } - break; - default: - sif::debug << "StarTrackerImageHelper::completionSuccessfulReceived: Invalid pending command" - << std::endl; - state = State::IDLE; - break; - } -} - -void StarTrackerImageHelper::completionFailedReceived(ActionId_t actionId, - ReturnValue_t returnCode) { - switch(pendingCommand) { - case(StarTracker::UPLOAD_IMAGE): { - triggerEvent(IMAGE_UPLOAD_FAILED, returnCode, commandsSent); - break; - } - default: - sif::debug << "StarTrackerImageHelper::completionFailedReceived: Invalid pending command " - << std::endl; - break; - } - state = State::IDLE; -} - -void StarTrackerImageHelper::commandImageUpload() { - ReturnValue_t result = RETURN_OK; - uint16_t dataLen = 0; - uint8_t tmpCommandBuffer[UPLOAD_COMMAND_SIZE] = {0}; - uint32_t position = commandsSent; - - if (not std::filesystem::exists(imageFile)) { - triggerEvent(IMAGE_FILE_NOT_EXISTS, commandsSent); - state = State::IDLE; - return; - } - - std::ifstream file(imageFile, std::ifstream::binary); - file.seekg(position, file.beg); - - if (remainingCommands == 1) { - dataLen = imageSize - file.tellg(); - } - else { - dataLen = SIZE_IMAGE_PART; - } - - size_t size = 0; - size_t maxSize = sizeof(position); - uint8_t* commandBufferPtr = tmpCommandBuffer; - uint8_t** buffer = &commandBufferPtr; - SerializeAdapter::serialize(&position, buffer, &size, maxSize, - SerializeIF::Endianness::BIG); - file.read(reinterpret_cast(tmpCommandBuffer), dataLen); - file.close(); - - result = commandActionHelper.commandAction(objects::START_TRACKER, - StarTracker::UPLOAD_IMAGE, tmpCommandBuffer - size , UPLOAD_COMMAND_SIZE); - - if (result != RETURN_OK) { - sif::warning << "StarTrackerImageHelper::commandImageUpload: Failed to send image " - << "upload command" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, StarTracker::UPLOAD_IMAGE); - state = State::IDLE; - return; - } - - remainingCommands--; - commandsSent++; - - if (remainingCommands == 0) { - state = State::UPLOAD_LAST; - } - else { - state = State::COMMAND_EXECUTING; - } - pendingCommand = StarTracker::UPLOAD_IMAGE; -} diff --git a/bsp_q7s/devices/StarTrackerImageHelper.h b/bsp_q7s/devices/StarTrackerImageHelper.h deleted file mode 100644 index 420721dc..00000000 --- a/bsp_q7s/devices/StarTrackerImageHelper.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef MISSION_DEVICES_STARTRACKERIMAGEHELPER_H_ -#define MISSION_DEVICES_STARTRACKERIMAGEHELPER_H_ - -#include "OBSWConfig.h" -#include "mission/devices/devicedefinitions/StarTrackerDefinitions.h" -#include "fsfw/action/CommandActionHelper.h" -#include "fsfw/action/ActionHelper.h" -#include "fsfw/action/HasActionsIF.h" -#include "fsfw/action/CommandsActionsIF.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "bsp_q7s/memory/SdCardManager.h" -#include "linux/fsfwconfig/objects/systemObjectList.h" - - -/** - * @brief An object of this class helps to download and upload images from/to the star tracker. - * - * @details The star tracker can only receive upload image commands with maximum 1024 bytes of data. - * Thus this class is used to raed the image from the file system and split the upload - * procedure into multiple steps. - * The same applies to downloading images from the star tracker (max. 1024 bytes in image - * download reply). - * - * @author J. Meier - */ -class StarTrackerImageHelper : public SystemObject, - public HasActionsIF, - public ExecutableObjectIF, - public HasReturnvaluesIF, - public CommandsActionsIF { -public: - - static const ActionId_t UPLOAD_IMAGE = 0; - static const ActionId_t DOWNLOAD_IMAGE = 1; - - StarTrackerImageHelper(object_id_t objectId); - virtual ~StarTrackerImageHelper(); - - ReturnValue_t performOperation(uint8_t operationCode = 0) override; - ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size); - MessageQueueId_t getCommandQueue() const; - ReturnValue_t initialize() override; - MessageQueueIF* getCommandQueuePtr() override; - void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; - void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; - void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; - void completionSuccessfulReceived(ActionId_t actionId) override; - void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; - -private: - - static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_HELPER; - - //! [EXPORT] : [COMMENT] Image helper is already executing a command - static const ReturnValue_t IMAGE_HELPER_BUSY = MAKE_RETURN_CODE(0xA0); - //! [EXPORT] : [COMMENT] Invalid path to image location - static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1); - //! [EXPORT] : [COMMENT] SD card with image not mounted - static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2); - //! [EXPORT] : [COMMENT] Specified image does not exist - static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3); - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_IMAGE_HELPER; - - //! [EXPORT] : [COMMENT] Try to read image file to upload but the file does not exist. - //! P1: Refers to the upload step the reading fails - static const Event IMAGE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); - //! [EXPORT] : [COMMENT] Failed to send command to star tracker handler - //! P1: Return value of CommandActionHelper::commandAction - //! P2: Action ID of command to send - static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] Star tracker handler replies with completion or step failure message to upload image command - //!P1: Return code of execution/step failure message - //!P2: Failed upload step (equal to number of commands already sent) - static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(2, severity::LOW); - //! [EXPORT] : [COMMENT] Image upload was successful - static const Event IMAGE_UPLOAD_FINISHED = MAKE_EVENT(3, severity::LOW); - - static const uint8_t MAX_RETRIES = 3; - static const uint32_t QUEUE_SIZE = config::STR_IMG_HELPER_QUEUE_SIZE; - static const size_t MAX_STR_IMAGE_PATH = 50; - static const size_t SD_PREFIX_LENGTH = 8; - // Size of one image part which can be sent per action request - static const size_t SIZE_IMAGE_PART = 1024; - // Position (uint32_t) + image data (1024 bytes) - static const size_t UPLOAD_COMMAND_SIZE = 1028; - - MessageQueueIF* commandQueue = nullptr; - - SdCardManager* sdcMan = nullptr; - - CommandActionHelper commandActionHelper; - - ActionHelper actionHelper; - - enum class State: uint8_t { - IDLE, - SEND_NEXT_UPLOAD_CMD, - UPLOAD_LAST, - COMMAND_EXECUTING - }; - - State state = State::IDLE; - - ActionId_t pendingCommand = StarTracker::NONE; - - uint32_t commandsSent = 0; - uint32_t remainingCommands = 0; - // Counts retries when command was rejected by star tracker - uint8_t retries = 0; - - // Path and name of active image (either upload or download image) - std::string imageFile; - // In case of upload command this variable stores the size of the image to upload - std::uintmax_t imageSize; - - void readCommandQueue(); - void doStateMachine(); - - /** - * @brief Extracts the path and name form the received command. - * - * @param data Pointer to received command - * @param size Size of the received command - * - * @details This string defines the image to upload (must be previously written to the SD card). - * In case of the download image command, this string defines the location and name of - * the image file to create. - */ - ReturnValue_t getImageLocation(const uint8_t* data, size_t size); - - /** - * @brief Prepares properties for the upload image command and changes the state to initiate - * the execution of the upload image command. - */ - ReturnValue_t prepareUploadCommand(const uint8_t* data, size_t size); - - /** - * @brief Reads part of image from file and sends upload image command to star tracker - * handler. - */ - void commandImageUpload(); - - /** - * @brief Checks whether the SD card to read from is mounted or not. - */ - bool isSdCardMounted(sd::SdCard sdCard); -}; - -#endif /* MISSION_DEVICES_STARTRACKERIMAGEHELPER_H_ */ diff --git a/bsp_q7s/devices/StrImageLoader.cpp b/bsp_q7s/devices/StrImageLoader.cpp index 7d4b64eb..9d49d8bf 100644 --- a/bsp_q7s/devices/StrImageLoader.cpp +++ b/bsp_q7s/devices/StrImageLoader.cpp @@ -1,8 +1,9 @@ #include "StrImageLoader.h" +#include #include -StrImageLoader::StrImageLoader(object_id_t objectId) { +StrImageLoader::StrImageLoader(object_id_t objectId) : SystemObject(objectId){ } @@ -13,7 +14,9 @@ ReturnValue_t StrImageLoader::initialize() { sdcMan = SdCardManager::instance(); if (sdcMan == nullptr) { sif::warning << "StrImageLoader::initialize: Invalid SD Card Manager" << std::endl; + return RETURN_FAILED; } + return RETURN_OK; } ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { @@ -26,10 +29,11 @@ ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { break; } case InternalState::UPLOAD_IMAGE: { - result = uploadImage(); + result = performImageUpload(); if (result == RETURN_OK){ triggerEvent(IMAGE_UPLOAD_SUCCESSFUL); } + internalState = InternalState::IDLE; break; } case InternalState::DOWNLOAD_IMAGE: @@ -72,85 +76,138 @@ ReturnValue_t StrImageLoader::startImageUpload(std::string image) { internalState = InternalState::UPLOAD_IMAGE; semaphore.release(); + + return RETURN_OK; } -ReturnValue_t StrImageLoader::uploadImage() { +ReturnValue_t StrImageLoader::startImageDownload() { + return RETURN_OK; +} + +ReturnValue_t StrImageLoader::performImageUpload() { ReturnValue_t result = RETURN_OK; - size_t receivedDataLen = 0; - uint8_t *receivedData = nullptr; - size_t bytesLeft = 0; - uint32_t readSize = 0; uint32_t imageSize = 0; struct UploadActionRequest uploadReq; uploadReq.position = 0; - uploadReq.data = {0}; + std::memset(&uploadReq.data, 0, sizeof(uploadReq.data)); if (not std::filesystem::exists(uploadImage)) { triggerEvent(IMAGE_FILE_NOT_EXISTS, uploadReq.position); - state = State::IDLE; + internalState = InternalState::IDLE; return RETURN_FAILED; } - std::ifstream file(uploadImage, std::ifstream::binary); + // Set position of next character to end of file input stream file.seekg(0, file.end); + // tellg returns position of character in input stream imageSize = file.tellg(); - file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); - - while(uploadReq.position * SIZE_IMAGE_PART < imageSize) { - result = - } - - uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART; - file.read(reinterpret_cast(uploadReq.data), remainder); - uploadReq.position++; - datalinkLayer.encodeFrame(uploadReq.data, remainder); - result = communicationInterface->sendMessage(comCookie, datalinkLayer.getEncodedFrame(), - datalinkLayer.getEncodedLength()); - if (result = RETURN_OK) { - sif::warning << "StrImageLoader::uploadImage: Failed to send upload packet" << std::endl; - triggerEvent(SENDING_UPLOAD_PACKET_FAILED, result, uploadReq.position); - return RETURN_FAILED; - } - result = ArcsecDatalinkLayer::DEC_IN_PROGRESS; - while(result == ArcsecDatalinkLayer::DEC_IN_PROGRESS) { - result = communicationInterface->requestReceiveMessage(comCookie, StarTracker::MAX_FRAME_SIZE* 2 + 2); - if (result != RETURN_OK) { - sif::warning << "StrImageLoader::uploadImage: Failed to request reply" << std::endl; - triggerEvent(UPLOAD_REQUESTING_MSG_FAILED, result, uploadReq.position); - return RETURN_FAILED; - } - result = communicationInterface->readReceivedMessage(comCookie, receivedData, - receivedDataLen); - if (result != RETURN_OK) { - sif::warning << "StrImageLoader::uploadImage: Failed to read received message" - << std::endl; - triggerEvent(UPLOAD_READING_REPLY_FAILED, result, uploadReq.position); - } - result = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft); - if (bytesLeft != 0) { - // This should never happen - triggerEvent(UPLOAD_COM_ERROR, result, uploadReq.position); - return RETURN_FAILED; - } - } - - if (remainingCommands == 1) { - dataLen = imageSize - file.tellg(); + // Set position of next character to beginning of file input stream + file.seekg(0, file.beg); + if (imageSize >= SIZE_IMAGE_PART) { + file.read(reinterpret_cast(uploadReq.data), SIZE_IMAGE_PART); } else { - dataLen = SIZE_IMAGE_PART; + file.read(reinterpret_cast(uploadReq.data), imageSize); } - - size_t size = 0; - size_t maxSize = sizeof(position); - uint8_t* commandBufferPtr = tmpCommandBuffer; - uint8_t** buffer = &commandBufferPtr; - SerializeAdapter::serialize(&position, buffer, &size, maxSize, - SerializeIF::Endianness::BIG); - file.read(reinterpret_cast(uploadReq.data), dataLen); + while(uploadReq.position * SIZE_IMAGE_PART < imageSize) { + result = uploadSendAndRead(&uploadReq); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkUploadReply(); + if (result != RETURN_OK) { + return result; + } + uploadReq.position++; + file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); + } + std::memset(uploadReq.data, 0, sizeof(uploadReq.data)); + uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART; + file.read(reinterpret_cast(uploadReq.data), remainder); file.close(); - - arc_pack_upload_action_req() - communicationInterface->requestReceiveMessage(comCookie, ) + uploadReq.position++; + result = uploadSendAndRead(&uploadReq); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkUploadReply(); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; } +ReturnValue_t StrImageLoader::uploadSendAndRead(struct UploadActionRequest* uploadReq) { + ReturnValue_t result = RETURN_OK; + ReturnValue_t decResult = RETURN_OK; + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; + size_t bytesLeft = 0; + uint32_t size = 0; + uint32_t missedReplies = 0; + arc_pack_upload_action_req(uploadReq, commandBuffer, &size); + datalinkLayer.encodeFrame(commandBuffer, size); + result = communicationInterface->sendMessage(comCookie, datalinkLayer.getEncodedFrame(), + datalinkLayer.getEncodedLength()); + if (result != RETURN_OK) { + sif::warning << "StrImageLoader::uploadImage: Failed to send upload packet" << std::endl; + triggerEvent(SENDING_UPLOAD_PACKET_FAILED, result, uploadReq->position); + return RETURN_FAILED; + } + decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS; + while (decResult == ArcsecDatalinkLayer::DEC_IN_PROGRESS) { + result = communicationInterface->requestReceiveMessage(comCookie, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + if (result != RETURN_OK) { + sif::warning << "StrImageLoader::uploadImage: Failed to request reply" << std::endl; + triggerEvent(UPLOAD_REQUESTING_MSG_FAILED, result, uploadReq->position); + return RETURN_FAILED; + } + result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); + if (result != RETURN_OK) { + sif::warning << "StrImageLoader::uploadImage: Failed to read received message" << std::endl; + triggerEvent(UPLOAD_READING_REPLY_FAILED, result, uploadReq->position); + return RETURN_FAILED; + } + if (receivedDataLen == 0 && missedReplies < MAX_POLLS) { + missedReplies++; + continue; + } + else if ((receivedDataLen == 0) && (missedReplies >= MAX_POLLS)) { + triggerEvent(NO_REPLY, uploadReq->position); + return RETURN_FAILED; + } + else { + missedReplies = 0; + } + decResult = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft); + if (bytesLeft != 0) { + // This should never happen + sif::warning << "StrImageLoader::uploadSendAndRead: Bytes left after decoding" << std::endl; + triggerEvent(UPLOAD_COM_ERROR, result, uploadReq->position); + return RETURN_FAILED; + } + } + if (decResult != RETURN_OK) { + triggerEvent(DEC_ERROR, decResult, uploadReq->position); + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StrImageLoader::checkUploadReply() { + uint8_t type = datalinkLayer.getReplyFrameType(); + if (type != TMTC_ACTIONREPLY) { + sif::warning << "StrImageLoader::checkUploadReply: Received invalid upload reply" + << std::endl; + triggerEvent(INVALID_TYPE_ID); + return RETURN_FAILED; + } + uint8_t status = datalinkLayer.getStatusField(); + if (status != ArcsecDatalinkLayer::STATUS_OK) { + triggerEvent(STATUS_ERROR); + sif::warning << "StrImageLoader::checkUploadReply: Status failure" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} diff --git a/bsp_q7s/devices/StrImageLoader.h b/bsp_q7s/devices/StrImageLoader.h index 50cdc266..940001a4 100644 --- a/bsp_q7s/devices/StrImageLoader.h +++ b/bsp_q7s/devices/StrImageLoader.h @@ -7,6 +7,15 @@ #include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/devices/ArcsecDatalinkLayer.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/devicehandlers/DeviceCommunicationIF.h" +#include "fsfw/devicehandlers/CookieIF.h" + +extern "C" { + #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" + #include "thirdparty/arcsec_star_tracker/client/generated/actionreq.h" +} /** * @brief An object of this class runs in a separate task and is responsible for uploading and @@ -34,16 +43,28 @@ public: //! [EXPORT] : [COMMENT] Failed to read communication interface reply data //!P1: Return code of failed communication interface read call //!P1: Upload position for which the read call failed - static const Event UPLOAD_READING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW); + static const Event UPLOAD_READING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW); //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence //!P1: Return code of failed communication interface read call //!P1: Upload position for which the read call failed - static const Event UPLOAD_COM_ERROR = MAKE_EVENT(4, severity::LOW); + static const Event UPLOAD_COM_ERROR = MAKE_EVENT(5, severity::LOW); + //! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off) + //!P1: Position of upload packet for which no reply was sent + static const Event NO_REPLY = MAKE_EVENT(6, severity::LOW); + //! [EXPORT] : [COMMENT] Received reply with invalid type ID + static const Event INVALID_TYPE_ID = MAKE_EVENT(7, severity::LOW); + //! [EXPORT] : [COMMENT] Status field in reply signals error + static const Event STATUS_ERROR = MAKE_EVENT(8, severity::LOW); + //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred + //P1: Return value of decoding function + //P2: Position of upload packet for which reply decoding failed + static const Event DEC_ERROR = MAKE_EVENT(9, severity::LOW); StrImageLoader(object_id_t objectId); virtual ~StrImageLoader(); + ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t operationCode = 0) override; void setComIF(DeviceCommunicationIF* communicationInterface_); @@ -57,6 +78,11 @@ public: */ ReturnValue_t startImageUpload(std::string image); + /** + * @brief Calling this function initiates the download of an image from the star tracker. + */ + ReturnValue_t startImageDownload(); + private: static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_LOADER; @@ -69,6 +95,8 @@ private: // Size of one image part which can be sent per action request static const size_t SIZE_IMAGE_PART = 1024; + static const uint32_t MAX_POLLS = 10000; + enum class InternalState { IDLE, UPLOAD_IMAGE, @@ -86,6 +114,8 @@ private: SdCardManager* sdcMan = nullptr; + uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; + /** * Communication object responsible for low level access of star tracker * Must be set by star tracker handler @@ -94,10 +124,30 @@ private: // Communication cookie. Must be set by the star tracker handler CookieIF* comCookie = nullptr; + // Queue id of raw data receiver + MessageQueueId_t rawDataReceiver = MessageQueueIF::NO_QUEUE; + /** * @brief Performs image uploading */ - ReturnValue_t uploadImage(); + ReturnValue_t performImageUpload(); + + /** + * @brief Sends a upload image packet and receives the action reply. + * + * @param uploadReq Pointer to upload request structure to send + * + * @return RETURN_OK if successful, otherwise RETURN_FALIED + */ + ReturnValue_t uploadSendAndRead(struct UploadActionRequest* uploadReq); + + /** + * @brief Checks the reply to an upload action request + * + * @return RETURN_OK if reply confirms success of upload packet transfer, otherwise + * REUTRN_FAILED + */ + ReturnValue_t checkUploadReply(); }; #endif /* BSP_Q7S_DEVICES_STRIMAGELOADER_H_ */ diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h similarity index 93% rename from mission/devices/devicedefinitions/StarTrackerDefinitions.h rename to bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h index 4721957b..49dd111f 100644 --- a/mission/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h @@ -97,6 +97,16 @@ static const DeviceCommandId_t REQ_POWER = 11; static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; static const DeviceCommandId_t REQ_SOLUTION = 24; static const DeviceCommandId_t REQ_TEMPERATURE = 25; +static const DeviceCommandId_t LIMITS = 40; +static const DeviceCommandId_t MONTING = 41; +static const DeviceCommandId_t CAMERA = 42; +static const DeviceCommandId_t BLOB = 43; +static const DeviceCommandId_t CENTROIDING = 44; +static const DeviceCommandId_t LISA = 45; +static const DeviceCommandId_t MACTHING = 46; +static const DeviceCommandId_t TRACKING = 47; +static const DeviceCommandId_t VALIDATION = 48; +static const DeviceCommandId_t ALGO = 49; static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const uint32_t VERSION_SET_ID = REQ_VERSION; @@ -122,6 +132,16 @@ namespace ID { static const uint8_t BOOT = 1; static const uint8_t VERSION = 2; static const uint8_t INTERFACE = 3; + static const uint8_t LIMITS = 5; + static const uint8_t MOUNTING = 6; + static const uint8_t CAMERA = 9; + static const uint8_t BLOB = 10; + static const uint8_t CENTROIDING = 11; + static const uint8_t LISA = 12; + static const uint8_t MATCHING = 13; + static const uint8_t TRACKING = 14; + static const uint8_t VALIDATION = 15; + static const uint8_t ALGO = 16; static const uint8_t REBOOT = 7; static const uint8_t UPLOAD_IMAGE = 10; static const uint8_t POWER = 11; @@ -489,11 +509,11 @@ public: sif::info << "SolutionSet::printSet: Track Qz: " << this->trackQz << std::endl; sif::info << "SolutionSet::printSet: Track removed: " - << static_cast(this->trackRemoved) << std::endl; + << static_cast(this->trackRemoved.value) << std::endl; sif::info << "SolutionSet::printSet: Number of stars centroided: " - << static_cast(this->starsCentroided) << std::endl; + << static_cast(this->starsCentroided.value) << std::endl; sif::info << "SolutionSet::printSet: Number of stars matched database: " - << static_cast(this->starsMatchedDatabase) << std::endl; + << static_cast(this->starsMatchedDatabase.value) << std::endl; sif::info << "SolutionSet::printSet: LISA Qw: " << this->lisaQw << std::endl; sif::info << "SolutionSet::printSet: LISA Qx: " @@ -505,13 +525,13 @@ public: sif::info << "SolutionSet::printSet: LISA Percentage close: " << this->lisaPercentageClose << std::endl; sif::info << "SolutionSet::printSet: LISA number of close stars: " - << static_cast(this->lisaNrClose) << std::endl; + << static_cast(this->lisaNrClose.value) << std::endl; sif::info << "SolutionSet::printSet: Is trust worthy: " - << static_cast(this->isTrustWorthy) << std::endl; + << static_cast(this->isTrustWorthy.value) << std::endl; sif::info << "SolutionSet::printSet: Stable count: " << this->stableCount << std::endl; sif::info << "SolutionSet::printSet: Solution strategy: " - << static_cast(this->solutionStrategy) << std::endl; + << static_cast(this->solutionStrategy.value) << std::endl; } }; diff --git a/bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h b/bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h new file mode 100644 index 00000000..c25e1586 --- /dev/null +++ b/bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h @@ -0,0 +1,343 @@ +#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ +#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ + +#include +#include +#include +#include + +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h" + +#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" + +using json = nlohmann::json; + +/** + * @brief This file defines a few helper classes to generate commands by means of the arcsec + * json files. + * @author J. Meier + */ + +namespace arcseckeys { + static const char PROPERTIES[] = "properties"; + static const char NAME[] = "name"; + static const char VALUE[] = "value"; + + static const char LIMITS[] = "limits"; + static const char ACTION[] = "action"; + static const char FPGA18CURRENT[] = "FPGA18Current"; + static const char FPGA25CURRENT[] = "FPGA25Current"; + static const char FPGA10CURRENT[] = "FPGA10Current"; + static const char MCUCURRENT[] = "MCUCurrent"; + static const char CMOS21CURRENT[] = "CMOS21Current"; + static const char CMOSPIXCURRENT[] = "CMOSPixCurrent"; + static const char CMOS33CURRENT[] = "CMOS33Current"; + static const char CMOSVRESCURRENT[] = "CMOSVResCurrent"; + static const char CMOS_TEMPERATURE[] = "CMOSTemperature"; + static const char MCU_TEMPERATURE[] = "MCUTemperature"; + + static const char TRACKING[] = "tracking"; + static const char THIN_LIMIT[] = "thinLimit"; + static const char OUTLIER_THRESHOLD[] = "outlierThreshold"; + static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST"; + static const char TRACKER_CHOICE[] = "trackerChoice"; +} + +class ArcsecJsonBase : public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE; + //! [EXPORT] : [COMMENT] Specified json file does not exist + static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1); + //! [EXPORT] : [COMMENT] Requested set does not exist in json file + static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2); + //! [EXPORT] : [COMMENT] Requested parameter does not exist in json file + static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3); + + /** + * @brief Constructor + * + * @param fullname Name with absolute path of json file containing the parameters to set. + */ + ArcsecJsonBase() {} + +protected: + + /** + * @brief Initializes the properties json object and the set json object + * + * @param fullname Name including absolute path to json file + * @param setName The name of the set to work on + * + * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise + * RETURN_OK + */ + ReturnValue_t init(const std::string filename,std::string setName) { + ReturnValue_t result = RETURN_OK; + if(not std::filesystem::exists(filename)) { + sif::warning << "ArcsecJsonBase::init: JSON file " << filename << " does not exist" + << std::endl; + return JSON_FILE_NOT_EXISTS; + } + createJsonObject(filename); + result = initSet(setName); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; + } + + /** + * @brief Reads the value of a parameter from a json set + * + * @param name The name of the parameter + * @param value The string representation of the read value + * + * @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS + */ + ReturnValue_t getParam(const std::string name, std::string& value) { + for (json::iterator it = set.begin(); it != set.end(); ++it) { + if ((*it)[arcseckeys::NAME] == name) { + value = (*it)[arcseckeys::VALUE]; + return RETURN_OK; + } + } + return PARAM_NOT_EXISTS; + } + + /** + * @brief This function adds a float represented as string to a buffer + * + * @param value The float in string representation to add + * @param buffer Pointer to the buffer the float will be written to + */ + void addfloat(const std::string value, uint8_t* buffer) { + float param = std::stof(value); + std::memcpy(buffer, ¶m, sizeof(param)); + } + + /** + * @brief This function adds a uint8_t represented as string to a buffer + * + * @param value The uint8_t in string representation to add + * @param buffer Pointer to the buffer the uint8_t will be written to + */ + void adduint8(const std::string value, uint8_t* buffer) { + uint8_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); + } + + /** + * @brief This function adds a uint32_t represented as string to a buffer + * + * @param value The uint32_t in string representation to add + * @param buffer Pointer to the buffer the uint32_t will be written to + */ + void adduint32(const std::string value, uint8_t* buffer) { + uint32_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); + } + + void addSetParamHeader(uint8_t* buffer, uint8_t setId) { + *buffer = static_cast(TMTC_SETPARAMREQ); + *(buffer + 1) = setId; + } + +private: + + void createJsonObject(const std::string fullname) { + json j; + std::ifstream file(fullname); + file >> j; + file.close(); + properties = j[arcseckeys::PROPERTIES]; + } + + /** + * @brief Extracts the json set object form the json file + * + * @param setName The name of the set to create the json object from + */ + ReturnValue_t initSet(std::string setName) { + for (json::iterator it = properties.begin(); it != properties.end(); ++it) { + if ((*it)["name"] == setName) { + set = (*it)["fields"]; + return RETURN_OK; + } + } + return SET_NOT_EXISTS; + } + +json properties; +json set; +}; + +/** + * @brief Generates command to set the limit parameters + * + */ +class Limits : public ArcsecJsonBase { +public: + + static const size_t COMMAND_SIZE = 43; + + Limits() {} + + /** + * @brief Fills a buffer with the tracking parameters + * + * @param fullname The name including the absolute path of the json file containing the + * limits parameters to set. + * @param buffer Pointer to the buffer the command will be written to + */ + ReturnValue_t create(std::string fullname, uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + result = init(fullname, arcseckeys::LIMITS); + if (result != RETURN_OK) { + return result; + } + result = createCommand(buffer); + return result; + } + +private: + ReturnValue_t createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::LIMITS); + offset = 2; + result = getParam(arcseckeys::ACTION, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FPGA18CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FPGA25CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FPGA10CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MCUCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS21CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOSPIXCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS33CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOSVRESCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS_TEMPERATURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MCU_TEMPERATURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; + } +}; + +/** + * @brief Generates the command to configure the tracking algorithm. + * + */ +class Tracking : public ArcsecJsonBase { +public: + + static const size_t COMMAND_SIZE = 15; + + Tracking() {} + /** + * @brief Fills a buffer with the tracking parameters + * + * @param fullname The name including the absolute path of the json file containing the + * tracking parameters to set. + * @param buffer Pointer to the buffer the command will be written to + */ + ReturnValue_t create(std::string fullname, uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + result = init(fullname, arcseckeys::TRACKING); + if (result != RETURN_OK) { + return result; + } + result = createCommand(buffer); + return result; + } + +private: + ReturnValue_t createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::TRACKING); + offset = 2; + result = getParam(arcseckeys::THIN_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OUTLIER_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OUTLIER_THRESHOLD_QUEST, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRACKER_CHOICE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + return RETURN_OK; + } + +}; + +#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */ diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index ea16b672..8a3d11f2 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -457,8 +457,8 @@ void SdCardManager::setPrintCommandOutput(bool print) { bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { SdCardManager::SdStatePair active; - ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); - if (result != RETURN_OK) { + ReturnValue_t result = this->getSdCardActiveStatus(active); + if (result != HasReturnvaluesIF::RETURN_OK) { sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state"; return false; } diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index a47e97d1..fc2bffb2 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -23,7 +23,8 @@ enum commonClassIds: uint8_t { GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC - CCSDS_HANDLER, //PDEC + CCSDS_HANDLER, //CCSDS + ARCSEC_JSON_BASE, //JSONBASE COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 610052e4..570dee84 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -87,7 +87,7 @@ enum commonObjects: uint32_t { RW3 = 0x44120249, RW4 = 0x44120350, - START_TRACKER = 0x44130001, + STAR_TRACKER = 0x44130001, PLOC_UPDATER = 0x44330000, PLOC_MEMORY_DUMPER = 0x44330001, diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 8dfa9e78..fad7c714 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -1,120 +1,130 @@ -2200;STORE_SEND_WRITE_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2201;STORE_WRITE_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2202;STORE_SEND_READ_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2203;STORE_READ_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2204;UNEXPECTED_MSG;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2205;STORING_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2206;TM_DUMP_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2207;STORE_INIT_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2208;STORE_INIT_EMPTY;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2209;STORE_CONTENT_CORRUPTED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2210;STORE_INITIALIZE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2211;INIT_DONE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2212;DUMP_FINISHED;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2213;DELETION_FINISHED;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2214;DELETION_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2600;GET_DATA_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2601;STORE_DATA_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2803;DEVICE_READING_REPLY_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2805;DEVICE_MISSED_REPLY;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2806;DEVICE_UNKNOWN_REPLY;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2807;DEVICE_UNREQUESTED_REPLY;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2809;MONITORING_LIMIT_EXCEEDED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2810;MONITORING_AMBIGUOUS;HIGH;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -4201;FUSE_CURRENT_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4202;FUSE_WENT_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4204;POWER_ABOVE_HIGH_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4205;POWER_BELOW_LOW_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4300;SWITCH_WENT_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h -5000;HEATER_ON;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5001;HEATER_OFF;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5002;HEATER_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5003;HEATER_STAYED_ON;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5004;HEATER_STAYED_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5200;TEMP_SENSOR_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5201;TEMP_SENSOR_LOW;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5202;TEMP_SENSOR_GRADIENT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5901;COMPONENT_TEMP_LOW;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5902;COMPONENT_TEMP_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5903;COMPONENT_TEMP_OOL_LOW;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5904;COMPONENT_TEMP_OOL_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5905;TEMP_NOT_IN_OP_RANGE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -7101;FDIR_CHANGED_STATE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7102;FDIR_STARTS_RECOVERY;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7201;MONITOR_CHANGED_STATE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7202;VALUE_BELOW_LOW_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7204;VALUE_OUT_OF_RANGE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7301;SWITCHING_TM_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h -7400;CHANGING_MODE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7401;MODE_INFO;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7402;FALLBACK_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7403;MODE_TRANSITION_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7404;CANT_KEEP_MODE;HIGH;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7405;OBJECT_IN_INVALID_MODE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7406;FORCING_MODE;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7407;MODE_CMD_REJECTED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7506;HEALTH_INFO;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7507;CHILD_CHANGED_HEALTH;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7508;CHILD_PROBLEMS;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7509;OVERWRITING_HEALTH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7510;TRYING_RECOVERY;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7511;RECOVERY_STEP;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7512;RECOVERY_DONE;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -8900;CLOCK_SET;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -8901;CLOCK_SET_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -9700;TEST;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/pus/Service17Test.h -10600;CHANGE_OF_SETUP_PARAMETER;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h -10900;GPIO_PULL_HIGH_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10901;GPIO_PULL_LOW_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10902;SWITCH_ALREADY_ON;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10903;SWITCH_ALREADY_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10904;MAIN_SWITCH_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -11000;MAIN_SWITCH_ON_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11001;MAIN_SWITCH_OFF_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11002;DEPLOYMENT_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11003;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11004;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11102;ACK_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11103;EXE_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11104;CRC_FAILURE_EVENT;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;/home/eive/EIVE/Robin/eive-obsw/mission/devices/RwHandler.h -11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11600;SANITIZATION_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/memory/SdCardManager.h -11700;UPDATE_FILE_NOT_EXISTS;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11701;ACTION_COMMANDING_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11800;SEND_MRAM_DUMP_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h -11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h -11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h -11901;INVALID_TC_FRAME;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h -11902;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h -11903;CARRIER_LOCK;INFO;Carrier lock detected;/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h -11904;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h +2200;STORE_SEND_WRITE_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2201;STORE_WRITE_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2202;STORE_SEND_READ_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2203;STORE_READ_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2204;UNEXPECTED_MSG;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2205;STORING_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2206;TM_DUMP_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2207;STORE_INIT_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2208;STORE_INIT_EMPTY;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2209;STORE_CONTENT_CORRUPTED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2210;STORE_INITIALIZE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2211;INIT_DONE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2212;DUMP_FINISHED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2213;DELETION_FINISHED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2214;DELETION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2600;GET_DATA_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2601;STORE_DATA_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2803;DEVICE_READING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2805;DEVICE_MISSED_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2806;DEVICE_UNKNOWN_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2807;DEVICE_UNREQUESTED_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2809;MONITORING_LIMIT_EXCEEDED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2810;MONITORING_AMBIGUOUS;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +4201;FUSE_CURRENT_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4202;FUSE_WENT_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4204;POWER_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4205;POWER_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4300;SWITCH_WENT_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h +5000;HEATER_ON;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5001;HEATER_OFF;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5002;HEATER_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5003;HEATER_STAYED_ON;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5004;HEATER_STAYED_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5200;TEMP_SENSOR_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5201;TEMP_SENSOR_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5202;TEMP_SENSOR_GRADIENT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5901;COMPONENT_TEMP_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5902;COMPONENT_TEMP_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5903;COMPONENT_TEMP_OOL_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5904;COMPONENT_TEMP_OOL_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5905;TEMP_NOT_IN_OP_RANGE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +7101;FDIR_CHANGED_STATE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7102;FDIR_STARTS_RECOVERY;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7201;MONITOR_CHANGED_STATE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7202;VALUE_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7204;VALUE_OUT_OF_RANGE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7301;SWITCHING_TM_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h +7400;CHANGING_MODE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7401;MODE_INFO;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7402;FALLBACK_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7403;MODE_TRANSITION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7404;CANT_KEEP_MODE;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7405;OBJECT_IN_INVALID_MODE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7406;FORCING_MODE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7407;MODE_CMD_REJECTED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7506;HEALTH_INFO;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7507;CHILD_CHANGED_HEALTH;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7508;CHILD_PROBLEMS;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7509;OVERWRITING_HEALTH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7510;TRYING_RECOVERY;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7511;RECOVERY_STEP;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7512;RECOVERY_DONE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +8900;CLOCK_SET;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;CLOCK_SET_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +9700;TEST;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h +10600;CHANGE_OF_SETUP_PARAMETER;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +10900;GPIO_PULL_HIGH_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h +10901;GPIO_PULL_LOW_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h +10902;SWITCH_ALREADY_ON;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h +10903;SWITCH_ALREADY_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h +10904;MAIN_SWITCH_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h +11000;MAIN_SWITCH_ON_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11001;MAIN_SWITCH_OFF_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11002;DEPLOYMENT_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11003;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11004;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11102;ACK_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11103;EXE_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11104;CRC_FAILURE_EVENT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h +11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11600;SANITIZATION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h +11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11800;SEND_MRAM_DUMP_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11901;INVALID_TC_FRAME;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +11902;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +11903;CARRIER_LOCK;INFO;Carrier lock detected;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +11904;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +12000;IMAGE_FILE_NOT_EXISTS;LOW;Try to upload image but specified image does not exist;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12001;SENDING_UPLOAD_PACKET_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12002;UPLOAD_REQUESTING_MSG_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12003;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successful;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12004;UPLOAD_READING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12005;UPLOAD_COM_ERROR;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12006;NO_REPLY;LOW;Star tracker did not send replies (maybe device is powered off)P1: Position of upload packet for which no reply was sent;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12007;INVALID_TYPE_ID;LOW;Received reply with invalid type ID;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12008;STATUS_ERROR;LOW;Status field in reply signals error;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h +12009;DEC_ERROR;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/StrImageLoader.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index fded183b..b0fe0658 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -27,7 +27,7 @@ 0x44120309;MGM_3_RM3100_HANDLER 0x44120313;GYRO_3_L3G_HANDLER 0x44120350;RW4 -0x44130001;START_TRACKER +0x44130001;STAR_TRACKER 0x44130045;GPS0_HANDLER 0x44130146;GPS1_HANDLER 0x44140014;IMTQ_HANDLER @@ -39,6 +39,7 @@ 0x443200A5;RAD_SENSOR 0x44330000;PLOC_UPDATER 0x44330001;PLOC_MEMORY_DUMPER +0x44330002;STR_IMG_LOADER 0x44330015;PLOC_MPSOC_HANDLER 0x44330016;PLOC_SUPERVISOR_HANDLER 0x444100A2;SOLAR_ARRAY_DEPL_HANDLER diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 943468c5..dea56991 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 120 translations. + * @brief Auto-generated event translation file. Contains 130 translations. * @details - * Generated on: 2021-11-25 14:09:00 + * Generated on: 2021-12-04 11:03:12 */ #include "translateEvents.h" @@ -125,6 +125,16 @@ const char *INVALID_TC_FRAME_STRING = "INVALID_TC_FRAME"; const char *INVALID_FAR_STRING = "INVALID_FAR"; const char *CARRIER_LOCK_STRING = "CARRIER_LOCK"; const char *BIT_LOCK_PDEC_STRING = "BIT_LOCK_PDEC"; +const char *IMAGE_FILE_NOT_EXISTS_STRING = "IMAGE_FILE_NOT_EXISTS"; +const char *SENDING_UPLOAD_PACKET_FAILED_STRING = "SENDING_UPLOAD_PACKET_FAILED"; +const char *UPLOAD_REQUESTING_MSG_FAILED_STRING = "UPLOAD_REQUESTING_MSG_FAILED"; +const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; +const char *UPLOAD_READING_REPLY_FAILED_STRING = "UPLOAD_READING_REPLY_FAILED"; +const char *UPLOAD_COM_ERROR_STRING = "UPLOAD_COM_ERROR"; +const char *NO_REPLY_STRING = "NO_REPLY"; +const char *INVALID_TYPE_ID_STRING = "INVALID_TYPE_ID"; +const char *STATUS_ERROR_STRING = "STATUS_ERROR"; +const char *DEC_ERROR_STRING = "DEC_ERROR"; const char * translateEvents(Event event) { switch( (event & 0xffff) ) { @@ -368,6 +378,26 @@ const char * translateEvents(Event event) { return CARRIER_LOCK_STRING; case(11904): return BIT_LOCK_PDEC_STRING; + case(12000): + return IMAGE_FILE_NOT_EXISTS_STRING; + case(12001): + return SENDING_UPLOAD_PACKET_FAILED_STRING; + case(12002): + return UPLOAD_REQUESTING_MSG_FAILED_STRING; + case(12003): + return IMAGE_UPLOAD_SUCCESSFUL_STRING; + case(12004): + return UPLOAD_READING_REPLY_FAILED_STRING; + case(12005): + return UPLOAD_COM_ERROR_STRING; + case(12006): + return NO_REPLY_STRING; + case(12007): + return INVALID_TYPE_ID_STRING; + case(12008): + return STATUS_ERROR_STRING; + case(12009): + return DEC_ERROR_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 48eb29e7..87e10da9 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2021-11-22 17:04:51 + * Contains 113 translations. + * Generated on: 2021-12-04 11:03:17 */ #include "translateObjects.h" @@ -35,7 +35,7 @@ const char *RW3_STRING = "RW3"; const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER"; const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; -const char *START_TRACKER_STRING = "START_TRACKER"; +const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS0_HANDLER_STRING = "GPS0_HANDLER"; const char *GPS1_HANDLER_STRING = "GPS1_HANDLER"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; @@ -47,6 +47,7 @@ const char *ACU_HANDLER_STRING = "ACU_HANDLER"; const char *RAD_SENSOR_STRING = "RAD_SENSOR"; const char *PLOC_UPDATER_STRING = "PLOC_UPDATER"; const char *PLOC_MEMORY_DUMPER_STRING = "PLOC_MEMORY_DUMPER"; +const char *STR_IMG_LOADER_STRING = "STR_IMG_LOADER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; @@ -180,7 +181,7 @@ const char* translateObject(object_id_t object) { case 0x44120350: return RW4_STRING; case 0x44130001: - return START_TRACKER_STRING; + return STAR_TRACKER_STRING; case 0x44130045: return GPS0_HANDLER_STRING; case 0x44130146: @@ -203,6 +204,8 @@ const char* translateObject(object_id_t object) { return PLOC_UPDATER_STRING; case 0x44330001: return PLOC_MEMORY_DUMPER_STRING; + case 0x44330002: + return STR_IMG_LOADER_STRING; case 0x44330015: return PLOC_MPSOC_HANDLER_STRING; case 0x44330016: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 943468c5..dea56991 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 120 translations. + * @brief Auto-generated event translation file. Contains 130 translations. * @details - * Generated on: 2021-11-25 14:09:00 + * Generated on: 2021-12-04 11:03:12 */ #include "translateEvents.h" @@ -125,6 +125,16 @@ const char *INVALID_TC_FRAME_STRING = "INVALID_TC_FRAME"; const char *INVALID_FAR_STRING = "INVALID_FAR"; const char *CARRIER_LOCK_STRING = "CARRIER_LOCK"; const char *BIT_LOCK_PDEC_STRING = "BIT_LOCK_PDEC"; +const char *IMAGE_FILE_NOT_EXISTS_STRING = "IMAGE_FILE_NOT_EXISTS"; +const char *SENDING_UPLOAD_PACKET_FAILED_STRING = "SENDING_UPLOAD_PACKET_FAILED"; +const char *UPLOAD_REQUESTING_MSG_FAILED_STRING = "UPLOAD_REQUESTING_MSG_FAILED"; +const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; +const char *UPLOAD_READING_REPLY_FAILED_STRING = "UPLOAD_READING_REPLY_FAILED"; +const char *UPLOAD_COM_ERROR_STRING = "UPLOAD_COM_ERROR"; +const char *NO_REPLY_STRING = "NO_REPLY"; +const char *INVALID_TYPE_ID_STRING = "INVALID_TYPE_ID"; +const char *STATUS_ERROR_STRING = "STATUS_ERROR"; +const char *DEC_ERROR_STRING = "DEC_ERROR"; const char * translateEvents(Event event) { switch( (event & 0xffff) ) { @@ -368,6 +378,26 @@ const char * translateEvents(Event event) { return CARRIER_LOCK_STRING; case(11904): return BIT_LOCK_PDEC_STRING; + case(12000): + return IMAGE_FILE_NOT_EXISTS_STRING; + case(12001): + return SENDING_UPLOAD_PACKET_FAILED_STRING; + case(12002): + return UPLOAD_REQUESTING_MSG_FAILED_STRING; + case(12003): + return IMAGE_UPLOAD_SUCCESSFUL_STRING; + case(12004): + return UPLOAD_READING_REPLY_FAILED_STRING; + case(12005): + return UPLOAD_COM_ERROR_STRING; + case(12006): + return NO_REPLY_STRING; + case(12007): + return INVALID_TYPE_ID_STRING; + case(12008): + return STATUS_ERROR_STRING; + case(12009): + return DEC_ERROR_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 48eb29e7..87e10da9 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2021-11-22 17:04:51 + * Contains 113 translations. + * Generated on: 2021-12-04 11:03:17 */ #include "translateObjects.h" @@ -35,7 +35,7 @@ const char *RW3_STRING = "RW3"; const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER"; const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; -const char *START_TRACKER_STRING = "START_TRACKER"; +const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS0_HANDLER_STRING = "GPS0_HANDLER"; const char *GPS1_HANDLER_STRING = "GPS1_HANDLER"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; @@ -47,6 +47,7 @@ const char *ACU_HANDLER_STRING = "ACU_HANDLER"; const char *RAD_SENSOR_STRING = "RAD_SENSOR"; const char *PLOC_UPDATER_STRING = "PLOC_UPDATER"; const char *PLOC_MEMORY_DUMPER_STRING = "PLOC_MEMORY_DUMPER"; +const char *STR_IMG_LOADER_STRING = "STR_IMG_LOADER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; @@ -180,7 +181,7 @@ const char* translateObject(object_id_t object) { case 0x44120350: return RW4_STRING; case 0x44130001: - return START_TRACKER_STRING; + return STAR_TRACKER_STRING; case 0x44130045: return GPS0_HANDLER_STRING; case 0x44130146: @@ -203,6 +204,8 @@ const char* translateObject(object_id_t object) { return PLOC_UPDATER_STRING; case 0x44330001: return PLOC_MEMORY_DUMPER_STRING; + case 0x44330002: + return STR_IMG_LOADER_STRING; case 0x44330015: return PLOC_MPSOC_HANDLER_STRING; case 0x44330016: diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index b32ceb5f..6d020181 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -588,7 +588,6 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::PLOC_UPDATER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::PLOC_MEMORY_DUMPER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::STR_IMG_HELPER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); #if OBSW_ADD_PLOC_SUPERVISOR == 1 thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); @@ -650,11 +649,11 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { #if OBSW_ADD_STAR_TRACKER == 1 uartPstEmpty = false; - thisSequence->addSlot(objects::START_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::START_TRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::START_TRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::START_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::START_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ); #endif if(uartPstEmpty) { diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 829377d0..aa46c23c 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -262,7 +262,7 @@ bool PdecHandler::checkFrameAna(uint32_t pdecFar) { } case(FrameAna_t::FRAME_DIRTY): { triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY); - sif::debug << "PdecHandler::checkFrameAna: Frame dirty" << std::endl; + sif::warning << "PdecHandler::checkFrameAna: Frame dirty" << std::endl; break; } case(FrameAna_t::FRAME_ILLEGAL): { @@ -314,50 +314,50 @@ void PdecHandler::handleIReason(uint32_t pdecFar, ReturnValue_t parameter1) { switch(ireason) { case(IReason_t::NO_REPORT): { triggerEvent(INVALID_TC_FRAME, parameter1, NO_REPORT); - sif::debug << "PdecHandler::handleIReason: No illegal report" << std::endl; + sif::info << "PdecHandler::handleIReason: No illegal report" << std::endl; break; } case(IReason_t::ERROR_VERSION_NUMBER): { triggerEvent(INVALID_TC_FRAME, parameter1, ERROR_VERSION_NUMBER); - sif::debug << "PdecHandler::handleIReason: Error in version number and reserved A and B " + sif::info << "PdecHandler::handleIReason: Error in version number and reserved A and B " << "fields" << std::endl; break; } case(IReason_t::ILLEGAL_COMBINATION): { triggerEvent(INVALID_TC_FRAME, parameter1, ILLEGAL_COMBINATION); - sif::debug << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control " + sif::info << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control " << "command flags" << std::endl; break; } case(IReason_t::INVALID_SC_ID): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_SC_ID); - sif::debug << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl; + sif::info << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl; break; } case(IReason_t::INVALID_VC_ID_MSB): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_MSB); - sif::debug << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match " + sif::info << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match " << std::endl; break; } case(IReason_t::INVALID_VC_ID_LSB): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_LSB); - sif::debug << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl; + sif::info << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl; break; } case(IReason_t::NS_NOT_ZERO): { triggerEvent(INVALID_TC_FRAME, parameter1, NS_NOT_ZERO); - sif::debug << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros" + sif::info << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros" << std::endl; break; } case(IReason_t::INCORRECT_BC_CC): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_BC_CC); - sif::debug << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl; + sif::info << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl; break; } default: { - sif::debug << "PdecHandler::handleIReason: Invalid reason id" << std::endl; + sif::info << "PdecHandler::handleIReason: Invalid reason id" << std::endl; break; } } @@ -373,7 +373,7 @@ void PdecHandler::handleNewTc() { } #if OBSW_DEBUG_PDEC_HANDLER == 1 unsigned int mapId = tcSegment[0] & MAP_ID_MASK; - sif::debug << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId + sif::info << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId << std::endl; printTC(tcLength); #endif /* OBSW_DEBUG_PDEC_HANDLER */ @@ -460,7 +460,7 @@ void PdecHandler::printTC(uint32_t tcLength) { tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex << static_cast(tcSegment[idx]); } - sif::debug << tcSegmentStream.str() << std::endl; + sif::info << tcSegmentStream.str() << std::endl; } uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) { diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index dd17728c..ea3fdbea 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -14,7 +14,6 @@ target_sources(${TARGET_NAME} PUBLIC RadiationSensorHandler.cpp GyroADIS16507Handler.cpp RwHandler.cpp - StarTrackerHandler.cpp ) diff --git a/tmtc b/tmtc index bcec5df6..7b01165f 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit bcec5df6e2636e3751f7a7eb103b893dc4581c10 +Subproject commit 7b01165ff937e45e052caeb550e622a8b9df6ee2 From 58c40695aedee8c9caf11700929845497e2344cc Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 7 Dec 2021 16:30:17 +0100 Subject: [PATCH 14/78] star tracker commands, tracking, mounting, camera, blob --- bsp_q7s/core/ObjectFactory.cpp | 6 +- bsp_q7s/devices/CMakeLists.txt | 7 +- .../StarTrackerJsonCommands.h | 343 ----------- .../{ => startracker}/ArcsecDatalinkLayer.cpp | 0 .../{ => startracker}/ArcsecDatalinkLayer.h | 2 +- bsp_q7s/devices/startracker/ArcsecJsonKeys.h | 81 +++ .../startracker/ArcsecJsonParamBase.cpp | 87 +++ .../devices/startracker/ArcsecJsonParamBase.h | 144 +++++ bsp_q7s/devices/startracker/CMakeLists.txt | 7 + .../StarTrackerDefinitions.h | 4 +- .../{ => startracker}/StarTrackerHandler.cpp | 130 +++-- .../{ => startracker}/StarTrackerHandler.h | 28 +- .../startracker/StarTrackerJsonCommands.cpp | 535 ++++++++++++++++++ .../startracker/StarTrackerJsonCommands.h | 128 +++++ .../{ => startracker}/StrImageLoader.cpp | 0 .../{ => startracker}/StrImageLoader.h | 3 +- 16 files changed, 1104 insertions(+), 401 deletions(-) delete mode 100644 bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h rename bsp_q7s/devices/{ => startracker}/ArcsecDatalinkLayer.cpp (100%) rename bsp_q7s/devices/{ => startracker}/ArcsecDatalinkLayer.h (98%) create mode 100644 bsp_q7s/devices/startracker/ArcsecJsonKeys.h create mode 100644 bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp create mode 100644 bsp_q7s/devices/startracker/ArcsecJsonParamBase.h create mode 100644 bsp_q7s/devices/startracker/CMakeLists.txt rename bsp_q7s/devices/{devicedefinitions => startracker}/StarTrackerDefinitions.h (99%) rename bsp_q7s/devices/{ => startracker}/StarTrackerHandler.cpp (90%) rename bsp_q7s/devices/{ => startracker}/StarTrackerHandler.h (91%) create mode 100644 bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp create mode 100644 bsp_q7s/devices/startracker/StarTrackerJsonCommands.h rename bsp_q7s/devices/{ => startracker}/StrImageLoader.cpp (100%) rename bsp_q7s/devices/{ => startracker}/StrImageLoader.h (99%) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index f1d0dcf0..ccc2ea7a 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,7 +1,7 @@ #include #include "ObjectFactory.h" -#include "../devices/devicedefinitions/StarTrackerDefinitions.h" +#include "bsp_q7s/devices/startracker/StarTrackerDefinitions.h" #include "OBSWConfig.h" #include "devConf.h" #include "ccsdsConfig.h" @@ -18,8 +18,8 @@ #include "bsp_q7s/devices/PlocSupervisorHandler.h" #include "bsp_q7s/devices/PlocUpdater.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" -#include "bsp_q7s/devices/StrImageLoader.h" -#include "bsp_q7s/devices/StarTrackerHandler.h" +#include "bsp_q7s/devices/startracker/StrImageLoader.h" +#include "bsp_q7s/devices/startracker/StarTrackerHandler.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h" diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt index edabfa96..70705e83 100644 --- a/bsp_q7s/devices/CMakeLists.txt +++ b/bsp_q7s/devices/CMakeLists.txt @@ -2,7 +2,6 @@ target_sources(${TARGET_NAME} PRIVATE PlocSupervisorHandler.cpp PlocUpdater.cpp PlocMemoryDumper.cpp - StrImageLoader.cpp - ArcsecDatalinkLayer.cpp - StarTrackerHandler.cpp -) \ No newline at end of file +) + +add_subdirectory(startracker) \ No newline at end of file diff --git a/bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h b/bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h deleted file mode 100644 index c25e1586..00000000 --- a/bsp_q7s/devices/devicedefinitions/StarTrackerJsonCommands.h +++ /dev/null @@ -1,343 +0,0 @@ -#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ -#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ - -#include -#include -#include -#include - -#include "fsfw/serviceinterface/ServiceInterface.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h" - -#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" - -using json = nlohmann::json; - -/** - * @brief This file defines a few helper classes to generate commands by means of the arcsec - * json files. - * @author J. Meier - */ - -namespace arcseckeys { - static const char PROPERTIES[] = "properties"; - static const char NAME[] = "name"; - static const char VALUE[] = "value"; - - static const char LIMITS[] = "limits"; - static const char ACTION[] = "action"; - static const char FPGA18CURRENT[] = "FPGA18Current"; - static const char FPGA25CURRENT[] = "FPGA25Current"; - static const char FPGA10CURRENT[] = "FPGA10Current"; - static const char MCUCURRENT[] = "MCUCurrent"; - static const char CMOS21CURRENT[] = "CMOS21Current"; - static const char CMOSPIXCURRENT[] = "CMOSPixCurrent"; - static const char CMOS33CURRENT[] = "CMOS33Current"; - static const char CMOSVRESCURRENT[] = "CMOSVResCurrent"; - static const char CMOS_TEMPERATURE[] = "CMOSTemperature"; - static const char MCU_TEMPERATURE[] = "MCUTemperature"; - - static const char TRACKING[] = "tracking"; - static const char THIN_LIMIT[] = "thinLimit"; - static const char OUTLIER_THRESHOLD[] = "outlierThreshold"; - static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST"; - static const char TRACKER_CHOICE[] = "trackerChoice"; -} - -class ArcsecJsonBase : public HasReturnvaluesIF { -public: - - static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE; - //! [EXPORT] : [COMMENT] Specified json file does not exist - static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1); - //! [EXPORT] : [COMMENT] Requested set does not exist in json file - static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2); - //! [EXPORT] : [COMMENT] Requested parameter does not exist in json file - static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3); - - /** - * @brief Constructor - * - * @param fullname Name with absolute path of json file containing the parameters to set. - */ - ArcsecJsonBase() {} - -protected: - - /** - * @brief Initializes the properties json object and the set json object - * - * @param fullname Name including absolute path to json file - * @param setName The name of the set to work on - * - * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise - * RETURN_OK - */ - ReturnValue_t init(const std::string filename,std::string setName) { - ReturnValue_t result = RETURN_OK; - if(not std::filesystem::exists(filename)) { - sif::warning << "ArcsecJsonBase::init: JSON file " << filename << " does not exist" - << std::endl; - return JSON_FILE_NOT_EXISTS; - } - createJsonObject(filename); - result = initSet(setName); - if (result != RETURN_OK) { - return result; - } - return RETURN_OK; - } - - /** - * @brief Reads the value of a parameter from a json set - * - * @param name The name of the parameter - * @param value The string representation of the read value - * - * @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS - */ - ReturnValue_t getParam(const std::string name, std::string& value) { - for (json::iterator it = set.begin(); it != set.end(); ++it) { - if ((*it)[arcseckeys::NAME] == name) { - value = (*it)[arcseckeys::VALUE]; - return RETURN_OK; - } - } - return PARAM_NOT_EXISTS; - } - - /** - * @brief This function adds a float represented as string to a buffer - * - * @param value The float in string representation to add - * @param buffer Pointer to the buffer the float will be written to - */ - void addfloat(const std::string value, uint8_t* buffer) { - float param = std::stof(value); - std::memcpy(buffer, ¶m, sizeof(param)); - } - - /** - * @brief This function adds a uint8_t represented as string to a buffer - * - * @param value The uint8_t in string representation to add - * @param buffer Pointer to the buffer the uint8_t will be written to - */ - void adduint8(const std::string value, uint8_t* buffer) { - uint8_t param = std::stoi(value); - std::memcpy(buffer, ¶m, sizeof(param)); - } - - /** - * @brief This function adds a uint32_t represented as string to a buffer - * - * @param value The uint32_t in string representation to add - * @param buffer Pointer to the buffer the uint32_t will be written to - */ - void adduint32(const std::string value, uint8_t* buffer) { - uint32_t param = std::stoi(value); - std::memcpy(buffer, ¶m, sizeof(param)); - } - - void addSetParamHeader(uint8_t* buffer, uint8_t setId) { - *buffer = static_cast(TMTC_SETPARAMREQ); - *(buffer + 1) = setId; - } - -private: - - void createJsonObject(const std::string fullname) { - json j; - std::ifstream file(fullname); - file >> j; - file.close(); - properties = j[arcseckeys::PROPERTIES]; - } - - /** - * @brief Extracts the json set object form the json file - * - * @param setName The name of the set to create the json object from - */ - ReturnValue_t initSet(std::string setName) { - for (json::iterator it = properties.begin(); it != properties.end(); ++it) { - if ((*it)["name"] == setName) { - set = (*it)["fields"]; - return RETURN_OK; - } - } - return SET_NOT_EXISTS; - } - -json properties; -json set; -}; - -/** - * @brief Generates command to set the limit parameters - * - */ -class Limits : public ArcsecJsonBase { -public: - - static const size_t COMMAND_SIZE = 43; - - Limits() {} - - /** - * @brief Fills a buffer with the tracking parameters - * - * @param fullname The name including the absolute path of the json file containing the - * limits parameters to set. - * @param buffer Pointer to the buffer the command will be written to - */ - ReturnValue_t create(std::string fullname, uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - result = init(fullname, arcseckeys::LIMITS); - if (result != RETURN_OK) { - return result; - } - result = createCommand(buffer); - return result; - } - -private: - ReturnValue_t createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::LIMITS); - offset = 2; - result = getParam(arcseckeys::ACTION, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::FPGA18CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FPGA25CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::FPGA10CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MCUCURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOS21CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOSPIXCURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOS33CURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOSVRESCURRENT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::CMOS_TEMPERATURE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::MCU_TEMPERATURE, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - return RETURN_OK; - } -}; - -/** - * @brief Generates the command to configure the tracking algorithm. - * - */ -class Tracking : public ArcsecJsonBase { -public: - - static const size_t COMMAND_SIZE = 15; - - Tracking() {} - /** - * @brief Fills a buffer with the tracking parameters - * - * @param fullname The name including the absolute path of the json file containing the - * tracking parameters to set. - * @param buffer Pointer to the buffer the command will be written to - */ - ReturnValue_t create(std::string fullname, uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - result = init(fullname, arcseckeys::TRACKING); - if (result != RETURN_OK) { - return result; - } - result = createCommand(buffer); - return result; - } - -private: - ReturnValue_t createCommand(uint8_t* buffer) { - ReturnValue_t result = RETURN_OK; - uint8_t offset = 0; - std::string param; - addSetParamHeader(buffer, StarTracker::ID::TRACKING); - offset = 2; - result = getParam(arcseckeys::THIN_LIMIT, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::OUTLIER_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::OUTLIER_THRESHOLD_QUEST, param); - if (result != RETURN_OK) { - return result; - } - addfloat(param, buffer + offset); - offset += sizeof(float); - result = getParam(arcseckeys::TRACKER_CHOICE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - return RETURN_OK; - } - -}; - -#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */ diff --git a/bsp_q7s/devices/ArcsecDatalinkLayer.cpp b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp similarity index 100% rename from bsp_q7s/devices/ArcsecDatalinkLayer.cpp rename to bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp diff --git a/bsp_q7s/devices/ArcsecDatalinkLayer.h b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h similarity index 98% rename from bsp_q7s/devices/ArcsecDatalinkLayer.h rename to bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h index 58acd4b3..eb5beecc 100644 --- a/bsp_q7s/devices/ArcsecDatalinkLayer.h +++ b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ #define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ -#include "devicedefinitions/StarTrackerDefinitions.h" +#include "StarTrackerDefinitions.h" #include "fsfw/returnvalues/HasReturnValuesIF.h" extern "C" { diff --git a/bsp_q7s/devices/startracker/ArcsecJsonKeys.h b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h new file mode 100644 index 00000000..58520968 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h @@ -0,0 +1,81 @@ +#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ +#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ + +/** + * @brief Keys used in JSON file of ARCSEC. + */ +namespace arcseckeys { + static const char PROPERTIES[] = "properties"; + static const char NAME[] = "name"; + static const char VALUE[] = "value"; + + static const char LIMITS[] = "limits"; + static const char ACTION[] = "action"; + static const char FPGA18CURRENT[] = "FPGA18Current"; + static const char FPGA25CURRENT[] = "FPGA25Current"; + static const char FPGA10CURRENT[] = "FPGA10Current"; + static const char MCUCURRENT[] = "MCUCurrent"; + static const char CMOS21CURRENT[] = "CMOS21Current"; + static const char CMOSPIXCURRENT[] = "CMOSPixCurrent"; + static const char CMOS33CURRENT[] = "CMOS33Current"; + static const char CMOSVRESCURRENT[] = "CMOSVResCurrent"; + static const char CMOS_TEMPERATURE[] = "CMOSTemperature"; + static const char MCU_TEMPERATURE[] = "MCUTemperature"; + + static const char MOUNTING[] = "mounting"; + static const char qw[] = "qw"; + static const char qx[] = "qx"; + static const char qy[] = "qy"; + static const char qz[] = "qz"; + + static const char CAMERA[] = "camera"; + static const char MODE[] = "mode"; + static const char FOCALLENGTH[] = "focallength"; + static const char EXPOSURE[] = "exposure"; + static const char INTERVAL[] = "interval"; + static const char OFFSET[] = "offset"; + static const char PGAGAIN[] = "PGAGain"; + static const char ADCGAIN[] = "ADCGain"; + static const char REG_1[] = "reg1"; + static const char VAL_1[] = "val1"; + static const char REG_2[] = "reg2"; + static const char VAL_2[] = "val2"; + static const char REG_3[] = "reg3"; + static const char VAL_3[] = "val3"; + static const char REG_4[] = "reg4"; + static const char VAL_4[] = "val4"; + static const char REG_5[] = "reg5"; + static const char VAL_5[] = "val5"; + static const char REG_6[] = "reg6"; + static const char VAL_6[] = "val6"; + static const char REG_7[] = "reg7"; + static const char VAL_7[] = "val7"; + static const char REG_8[] = "reg8"; + static const char VAL_8[] = "val8"; + static const char FREQ_1[] = "freq1"; + static const char FREQ_2[] = "freq2"; + + static const char BLOB[] = "blob"; + static const char MIN_VALUE[] = "minValue"; + static const char MIN_DISTANCE[] = "minDistance"; + static const char NEIGHBOUR_DISTANCE[] = "neighbourDistance"; + static const char NEIGHBOUR_BRIGHT_PIXELS[] = "neighbourBrightPixels"; + static const char MIN_TOTAL_VALUE[] = "minTotalValue"; + static const char MAX_TOTAL_VALUE[] = "maxTotalValue"; + static const char MIN_BRIGHT_NEIGHBOURS[] = "minBrightNeighbours"; + static const char MAX_BRIGHT_NEIGHBOURS[] = "maxBrightNeighbours"; + static const char MAX_PIXEL_TO_CONSIDER[] = "maxPixelsToConsider"; + static const char SIGNAL_THRESHOLD[] = "signalThreshold"; + static const char DARK_THRESHOLD[] = "darkThreshold"; + static const char ENABLE_HISTOGRAM[] = "enableHistogram"; + static const char ENABLE_CONTRAST[] = "enableContrast"; + static const char BIN_MODE[] = "binMode"; + + static const char TRACKING[] = "tracking"; + static const char THIN_LIMIT[] = "thinLimit"; + static const char OUTLIER_THRESHOLD[] = "outlierThreshold"; + static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST"; + static const char TRACKER_CHOICE[] = "trackerChoice"; +} + +#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */ diff --git a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp new file mode 100644 index 00000000..38040797 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp @@ -0,0 +1,87 @@ +#include "ArcsecJsonParamBase.h" +#include "ArcsecJsonKeys.h" + +ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {} + +ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + result = init(fullname); + if (result != RETURN_OK) { + return result; + } + result = createCommand(buffer); + return result; +} + +ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) { + for (json::iterator it = set.begin(); it != set.end(); ++it) { + if ((*it)[arcseckeys::NAME] == name) { + value = (*it)[arcseckeys::VALUE]; + return RETURN_OK; + } + } + return PARAM_NOT_EXISTS; +} + +void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) { + float param = std::stof(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) { + uint8_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) { + int16_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) { + uint16_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) { + uint32_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) { + *buffer = static_cast(TMTC_SETPARAMREQ); + *(buffer + 1) = setId; +} + +ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) { + ReturnValue_t result = RETURN_OK; + if (not std::filesystem::exists(filename)) { + sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist" + << std::endl; + return JSON_FILE_NOT_EXISTS; + } + createJsonObject(filename); + result = initSet(); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; +} + +void ArcsecJsonParamBase::createJsonObject(const std::string fullname) { + json j; + std::ifstream file(fullname); + file >> j; + file.close(); + properties = j[arcseckeys::PROPERTIES]; +} + +ReturnValue_t ArcsecJsonParamBase::initSet() { + for (json::iterator it = properties.begin(); it != properties.end(); ++it) { + if ((*it)["name"] == setName) { + set = (*it)["fields"]; + return RETURN_OK; + } + } + return SET_NOT_EXISTS; +} diff --git a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h new file mode 100644 index 00000000..dc59c6fc --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h @@ -0,0 +1,144 @@ +#ifndef BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ +#define BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ + +#include +#include +#include + +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "StarTrackerDefinitions.h" + +extern "C" { + #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" + #include "thirdparty/arcsec_star_tracker/common/genericstructs.h" +} + +using json = nlohmann::json; + +/** + * @brief Base class for creation of parameter configuration commands. Reads parameter set + * from a json file located on the filesystem and generates the appropriate command + * to apply the parameters to the star tracker software. + * + * @author J. Meier + */ +class ArcsecJsonParamBase : public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE; + //! [EXPORT] : [COMMENT] Specified json file does not exist + static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1); + //! [EXPORT] : [COMMENT] Requested set does not exist in json file + static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2); + //! [EXPORT] : [COMMENT] Requested parameter does not exist in json file + static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3); + + /** + * @brief Constructor + * + * @param fullname Name with absolute path of json file containing the parameters to set. + */ + ArcsecJsonParamBase(std::string setName); + + /** + * @brief Fills a buffer with a parameter set + * + * @param fullname The name including the absolute path of the json file containing the + * parameter set. + * @param buffer Pointer to the buffer the command will be written to + */ + ReturnValue_t create(std::string fullname, uint8_t* buffer); + + /** + * @brief Returns the size of the parameter command. + */ + virtual size_t getSize() = 0; + +protected: + + /** + * @brief Reads the value of a parameter from a json set + * + * @param name The name of the parameter + * @param value The string representation of the read value + * + * @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS + */ + ReturnValue_t getParam(const std::string name, std::string& value); + + /** + * @brief This function adds a float represented as string to a buffer + * + * @param value The float in string representation to add + * @param buffer Pointer to the buffer the float will be written to + */ + void addfloat(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a uint8_t represented as string to a buffer + * + * @param value The uint8_t in string representation to add + * @param buffer Pointer to the buffer the uint8_t will be written to + */ + void adduint8(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a int16_t represented as string to a buffer + * + * @param value The int16_t in string representation to add + * @param buffer Pointer to the buffer the int16_t will be written to + */ + void addint16(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a uint16_t represented as string to a buffer + * + * @param value The uint16_t in string representation to add + * @param buffer Pointer to the buffer the uint16_t will be written to + */ + void adduint16(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a uint32_t represented as string to a buffer + * + * @param value The uint32_t in string representation to add + * @param buffer Pointer to the buffer the uint32_t will be written to + */ + void adduint32(const std::string value, uint8_t* buffer); + + void addSetParamHeader(uint8_t* buffer, uint8_t setId); + +private: + + json properties; + json set; + std::string setName; + + /** + * @brief This function must be implemented by the derived class to define creation of a + * parameter command. + */ + virtual ReturnValue_t createCommand(uint8_t* buffer) = 0; + + /** + * @brief Initializes the properties json object and the set json object + * + * @param fullname Name including absolute path to json file + * @param setName The name of the set to work on + * + * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise + * RETURN_OK + */ + ReturnValue_t init(const std::string filename); + + void createJsonObject(const std::string fullname); + + /** + * @brief Extracts the json set object form the json file + * + * @param setName The name of the set to create the json object from + */ + ReturnValue_t initSet(); +}; + +#endif /* BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ */ diff --git a/bsp_q7s/devices/startracker/CMakeLists.txt b/bsp_q7s/devices/startracker/CMakeLists.txt new file mode 100644 index 00000000..81f0492f --- /dev/null +++ b/bsp_q7s/devices/startracker/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} PRIVATE + StarTrackerHandler.cpp + StarTrackerJsonCommands.cpp + ArcsecDatalinkLayer.cpp + ArcsecJsonParamBase.cpp + StrImageLoader.cpp +) \ No newline at end of file diff --git a/bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h similarity index 99% rename from bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h rename to bsp_q7s/devices/startracker/StarTrackerDefinitions.h index 49dd111f..6ea8d6f7 100644 --- a/bsp_q7s/devices/devicedefinitions/StarTrackerDefinitions.h +++ b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h @@ -98,12 +98,12 @@ static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; static const DeviceCommandId_t REQ_SOLUTION = 24; static const DeviceCommandId_t REQ_TEMPERATURE = 25; static const DeviceCommandId_t LIMITS = 40; -static const DeviceCommandId_t MONTING = 41; +static const DeviceCommandId_t MOUNTING = 41; static const DeviceCommandId_t CAMERA = 42; static const DeviceCommandId_t BLOB = 43; static const DeviceCommandId_t CENTROIDING = 44; static const DeviceCommandId_t LISA = 45; -static const DeviceCommandId_t MACTHING = 46; +static const DeviceCommandId_t MATCHING = 46; static const DeviceCommandId_t TRACKING = 47; static const DeviceCommandId_t VALIDATION = 48; static const DeviceCommandId_t ALGO = 49; diff --git a/bsp_q7s/devices/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp similarity index 90% rename from bsp_q7s/devices/StarTrackerHandler.cpp rename to bsp_q7s/devices/startracker/StarTrackerHandler.cpp index 1a8b4971..088bd798 100644 --- a/bsp_q7s/devices/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -2,7 +2,7 @@ #include "StarTrackerHandler.h" #include "OBSWConfig.h" -#include "devicedefinitions/StarTrackerJsonCommands.h" +#include "StarTrackerJsonCommands.h" #include #include @@ -194,11 +194,28 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi return RETURN_OK; } case (StarTracker::LIMITS): { - result = prepareLimitsCommand(commandData, commandDataLen); + Limits limits; + result = prepareParamCommand(commandData, commandDataLen, limits); + return result; + } + case (StarTracker::MOUNTING): { + Mounting mounting; + result = prepareParamCommand(commandData, commandDataLen, mounting); + return result; + } + case (StarTracker::CAMERA): { + Camera camera; + result = prepareParamCommand(commandData, commandDataLen, camera); + return result; + } + case (StarTracker::BLOB): { + Blob blob; + result = prepareParamCommand(commandData, commandDataLen, blob); return result; } case (StarTracker::TRACKING): { - result = prepareTrackingCommand(commandData, commandDataLen); + Tracking tracking; + result = prepareParamCommand(commandData, commandDataLen, tracking); return result; } default: @@ -233,6 +250,24 @@ void StarTrackerHandler::fillCommandAndReplyMap() { StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::LIMITS, 3, nullptr, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::MOUNTING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::CAMERA, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::BLOB, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::CENTROIDING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::LISA, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::MATCHING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::TRACKING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::VALIDATION, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::ALGO, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); } ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, @@ -264,7 +299,7 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema } case TMTC_SETPARAMREPLY: { *foundLen = remainingSize - bytesLeft; - result = scanForSetParameterReply(foundId); + result = scanForParameterReply(foundId); break; } case TMTC_TELEMETRYREPLYA: @@ -325,7 +360,16 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con handleTemperatureTm(); break; } - case (StarTracker::LIMITS): { + case (StarTracker::LIMITS): + case (StarTracker::MOUNTING): + case (StarTracker::CAMERA): + case (StarTracker::BLOB): + case (StarTracker::CENTROIDING): + case (StarTracker::LISA): + case (StarTracker::MATCHING): + case (StarTracker::TRACKING): + case (StarTracker::VALIDATION): + case (StarTracker::ALGO): { result = handleSetParamReply(); break; } @@ -458,14 +502,14 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) break; } default: - sif::warning << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" + sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" << std::endl; return RETURN_FAILED; } return RETURN_OK; } -ReturnValue_t StarTrackerHandler::scanForSetParameterReply(DeviceCommandId_t *foundId) { +ReturnValue_t StarTrackerHandler::scanForParameterReply(DeviceCommandId_t *foundId) { const uint8_t* reply = dataLinkLayer.getReply(); switch (*reply) { case (StarTracker::ID::SUBSCRIBE): { @@ -476,8 +520,44 @@ ReturnValue_t StarTrackerHandler::scanForSetParameterReply(DeviceCommandId_t *fo *foundId = StarTracker::LIMITS; break; } + case (StarTracker::ID::MOUNTING): { + *foundId = StarTracker::MOUNTING; + break; + } + case (StarTracker::ID::CAMERA): { + *foundId = StarTracker::CAMERA; + break; + } + case (StarTracker::ID::BLOB): { + *foundId = StarTracker::BLOB; + break; + } + case (StarTracker::ID::CENTROIDING): { + *foundId = StarTracker::CENTROIDING; + break; + } + case (StarTracker::ID::LISA): { + *foundId = StarTracker::LISA; + break; + } + case (StarTracker::ID::MATCHING): { + *foundId = StarTracker::MATCHING; + break; + } + case (StarTracker::ID::TRACKING): { + *foundId = StarTracker::TRACKING; + break; + } + case (StarTracker::ID::VALIDATION): { + *foundId = StarTracker::VALIDATION; + break; + } + case (StarTracker::ID::ALGO): { + *foundId = StarTracker::ALGO; + break; + } default: - sif::debug << "StarTrackerHandler::scanForSetParameterReply: Unknown parameter reply id" + sif::debug << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" << std::endl; return RETURN_FAILED; } @@ -638,43 +718,21 @@ void StarTrackerHandler::prepareTemperatureRequest() { rawPacketLen = dataLinkLayer.getEncodedLength(); } -ReturnValue_t StarTrackerHandler::prepareLimitsCommand(const uint8_t* commandData, - size_t commandDataLen) { +ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, + size_t commandDataLen, ArcsecJsonParamBase& paramSet) { ReturnValue_t result = RETURN_OK; if (commandDataLen > MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } std::string fullName(reinterpret_cast(commandData), commandDataLen); - Limits limits; - result = limits.create(fullName, commandBuffer); + result = paramSet.create(fullName, commandBuffer); if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareLimitsCommand: Failed to create limits command" - << std::endl; + sif::warning << "StarTrackerHandler::prepareParamCommand: Failed to create parameter " + "command" << std::endl; return result; } - dataLinkLayer.encodeFrame(commandBuffer, Limits::COMMAND_SIZE); - rawPacket = dataLinkLayer.getEncodedFrame(); - rawPacketLen = dataLinkLayer.getEncodedLength(); - return RETURN_OK; -} - -ReturnValue_t StarTrackerHandler::prepareTrackingCommand(const uint8_t* commandData, - size_t commandDataLen) { - ReturnValue_t result = RETURN_OK; - if (commandDataLen > MAX_PATH_SIZE) { - return FILE_PATH_TOO_LONG; - } - std::string fullName(reinterpret_cast(commandData), commandDataLen); - - Tracking tracking; - result = tracking.create(fullName, commandBuffer); - if (result != RETURN_OK) { - sif::warning << "StarTrackerHandler::prepareTrackingCommand: Failed to create tracking " - " command" << std::endl; - return result; - } - dataLinkLayer.encodeFrame(commandBuffer, Tracking::COMMAND_SIZE); + dataLinkLayer.encodeFrame(commandBuffer, paramSet.getSize()); rawPacket = dataLinkLayer.getEncodedFrame(); rawPacketLen = dataLinkLayer.getEncodedLength(); return RETURN_OK; diff --git a/bsp_q7s/devices/StarTrackerHandler.h b/bsp_q7s/devices/startracker/StarTrackerHandler.h similarity index 91% rename from bsp_q7s/devices/StarTrackerHandler.h rename to bsp_q7s/devices/startracker/StarTrackerHandler.h index 27d14a3d..3f3c8197 100644 --- a/bsp_q7s/devices/StarTrackerHandler.h +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.h @@ -1,13 +1,14 @@ #ifndef MISSION_DEVICES_STARTRACKERHANDLER_H_ #define MISSION_DEVICES_STARTRACKERHANDLER_H_ -#include -#include -#include +#include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "fsfw/src/fsfw/serialize/SerializeAdapter.h" +#include "thirdparty/arcsec_star_tracker/common/SLIP.h" #include -#include -#include -#include +#include "StrImageLoader.h" +#include "ArcsecDataLinkLayer.h" +#include "StarTrackerDefinitions.h" +#include "ArcsecJsonParamBase.h" /** * @brief This is the device handler for the star tracker from arcsec. @@ -158,7 +159,7 @@ private: void slipInit(); ReturnValue_t scanForActionReply(DeviceCommandId_t *foundId); - ReturnValue_t scanForSetParameterReply(DeviceCommandId_t *foundId); + ReturnValue_t scanForParameterReply(DeviceCommandId_t *foundId); ReturnValue_t scanForTmReply(DeviceCommandId_t *foundId); /** @@ -221,10 +222,17 @@ private: void prepareTemperatureRequest(); /** - * @brief Reads limit parameters from json file specified with commandData and prepares - * the command to apply the limits to the star tracker. + * @brief Reads parameters from json file specified by string in commandData and + * prepares the command to apply the parameter set to the star tracker + * + * @param commandData Contains string with file name + * @param commandDataLen Length of command + * @param paramSet The object defining the command generation + * + * @return RETURN_OK if successful, otherwise error return Value */ - ReturnValue_t prepareLimitsCommand(const uint8_t* commandData, size_t commandDataLen); + ReturnValue_t prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, + ArcsecJsonParamBase& paramSet); /** * @brief Default function to handle action replies diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp new file mode 100644 index 00000000..dd91eddf --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp @@ -0,0 +1,535 @@ +#include "StarTrackerJsonCommands.h" +#include "ArcsecJsonKeys.h" + +Limits::Limits() : ArcsecJsonParamBase(arcseckeys::LIMITS) {} + +size_t Limits::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Limits::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::LIMITS); + offset = 2; + result = getParam(arcseckeys::ACTION, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FPGA18CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FPGA25CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FPGA10CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MCUCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS21CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOSPIXCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS33CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOSVRESCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS_TEMPERATURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MCU_TEMPERATURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Tracking::Tracking() : ArcsecJsonParamBase(arcseckeys::TRACKING) {} + +size_t Tracking::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Tracking::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::TRACKING); + offset = 2; + result = getParam(arcseckeys::THIN_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OUTLIER_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OUTLIER_THRESHOLD_QUEST, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRACKER_CHOICE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + return RETURN_OK; +} + + +Mounting::Mounting() : ArcsecJsonParamBase(arcseckeys::MOUNTING) {} + +size_t Mounting::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Mounting::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::MOUNTING); + offset = 2; + result = getParam(arcseckeys::qw, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::qx, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::qy, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::qz, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Camera::Camera() : ArcsecJsonParamBase(arcseckeys::CAMERA) {} + +size_t Camera::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Camera::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::CAMERA); + offset = 2; + result = getParam(arcseckeys::MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FOCALLENGTH, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::EXPOSURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::INTERVAL, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OFFSET, param); + if (result != RETURN_OK) { + return result; + } + addint16(param, buffer + offset); + offset += sizeof(int16_t); + result = getParam(arcseckeys::PGAGAIN, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ADCGAIN, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_1, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_1, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_2, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_2, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_3, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_3, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_4, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_4, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_5, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_5, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_6, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_6, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_7, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_7, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_8, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_8, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FREQ_1, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FREQ_2, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + +Blob::Blob() : ArcsecJsonParamBase(arcseckeys::BLOB) {} + +size_t Blob::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Blob::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::BLOB); + offset = 2; + result = getParam(arcseckeys::MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_DISTANCE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NEIGHBOUR_DISTANCE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NEIGHBOUR_BRIGHT_PIXELS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_TOTAL_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_TOTAL_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MIN_BRIGHT_NEIGHBOURS, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_BRIGHT_NEIGHBOURS, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_PIXEL_TO_CONSIDER, param); + if (result != RETURN_OK) { + return result; + } + adduint32(param, buffer + offset); + offset += sizeof(uint32_t); + result = getParam(arcseckeys::SIGNAL_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::DARK_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ENABLE_HISTOGRAM, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ENABLE_CONTRAST, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::BIN_MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + return RETURN_OK; +} + +Centroiding::Centroiding() : ArcsecJsonParamBase(arcseckeys::BLOB) {} + +size_t Centroiding::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Centroiding::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::BLOB); + offset = 2; + result = getParam(arcseckeys::MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_DISTANCE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NEIGHBOUR_DISTANCE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NEIGHBOUR_BRIGHT_PIXELS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_TOTAL_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_TOTAL_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MIN_BRIGHT_NEIGHBOURS, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_BRIGHT_NEIGHBOURS, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_PIXEL_TO_CONSIDER, param); + if (result != RETURN_OK) { + return result; + } + adduint32(param, buffer + offset); + offset += sizeof(uint32_t); + result = getParam(arcseckeys::SIGNAL_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::DARK_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ENABLE_HISTOGRAM, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ENABLE_CONTRAST, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::BIN_MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + return RETURN_OK; +} diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h new file mode 100644 index 00000000..153ef8a7 --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h @@ -0,0 +1,128 @@ +#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ +#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ + +/** + * @brief This file defines a few helper classes to generate commands by means of the parameters + * defined in the arcsec json files. + * @author J. Meier + */ + +#include + +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "ArcsecJsonParamBase.h" + +/** + * @brief Generates command to set the limit parameters + * + */ +class Limits : public ArcsecJsonParamBase { +public: + + Limits(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 43; + + virtual ReturnValue_t createCommand(uint8_t* buffer) override; +}; + +/** + * @brief Generates the command to configure the tracking algorithm. + * + */ +class Tracking : public ArcsecJsonParamBase { +public: + + Tracking(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 15; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + +/** + * @brief Generates the command to set the mounting quaternion + * + */ +class Mounting : public ArcsecJsonParamBase { +public: + + Mounting(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 18; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + +/** + * @brief Generates the command to set the mounting quaternion + * + */ +class Camera : public ArcsecJsonParamBase { +public: + + Camera(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 43; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + +/** + * @brief Generates the command to configure the blob algorithm + * + */ +class Blob : public ArcsecJsonParamBase { +public: + + Blob(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 24; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + +/** + * @brief Generates the command to configure the centroiding algorithm + * + */ +class Centroiding : public ArcsecJsonParamBase { +public: + + Centroiding(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 24; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + +#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */ diff --git a/bsp_q7s/devices/StrImageLoader.cpp b/bsp_q7s/devices/startracker/StrImageLoader.cpp similarity index 100% rename from bsp_q7s/devices/StrImageLoader.cpp rename to bsp_q7s/devices/startracker/StrImageLoader.cpp diff --git a/bsp_q7s/devices/StrImageLoader.h b/bsp_q7s/devices/startracker/StrImageLoader.h similarity index 99% rename from bsp_q7s/devices/StrImageLoader.h rename to bsp_q7s/devices/startracker/StrImageLoader.h index 940001a4..e53e57d1 100644 --- a/bsp_q7s/devices/StrImageLoader.h +++ b/bsp_q7s/devices/startracker/StrImageLoader.h @@ -2,10 +2,9 @@ #define BSP_Q7S_DEVICES_STRIMAGELOADER_H_ #include - +#include "ArcsecDatalinkLayer.h" #include "fsfw/osal/linux/BinarySemaphore.h" #include "bsp_q7s/memory/SdCardManager.h" -#include "bsp_q7s/devices/ArcsecDatalinkLayer.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/tasks/ExecutableObjectIF.h" From b691a1e75d3e67046566d627187b83dddba1f681 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 8 Dec 2021 12:50:55 +0100 Subject: [PATCH 15/78] parsing of arcsec json file complete --- bsp_q7s/devices/startracker/ArcsecJsonKeys.h | 45 +++ .../startracker/StarTrackerHandler.cpp | 25 ++ .../startracker/StarTrackerJsonCommands.cpp | 335 ++++++++++++++---- .../startracker/StarTrackerJsonCommands.h | 89 ++++- 4 files changed, 416 insertions(+), 78 deletions(-) diff --git a/bsp_q7s/devices/startracker/ArcsecJsonKeys.h b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h index 58520968..2c598b43 100644 --- a/bsp_q7s/devices/startracker/ArcsecJsonKeys.h +++ b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h @@ -71,11 +71,56 @@ namespace arcseckeys { static const char ENABLE_CONTRAST[] = "enableContrast"; static const char BIN_MODE[] = "binMode"; + static const char CENTROIDING[] = "centroiding"; + static const char ENABLE_FILTER[] = "enableFilter"; + static const char MAX_QUALITY[] = "maxquality"; + static const char MIN_QUALITY[] = "minquality"; + static const char MAX_INTENSITY[] = "maxintensity"; + static const char MIN_INTENSITY[] = "minintensity"; + static const char MAX_MAGNITUDE[] = "maxmagnitude"; + static const char GAUSSIAN_CMAX[] = "gaussianCmax"; + static const char GAUSSIAN_CMIN[] = "gaussianCmin"; + static const char TRANSMATRIX_00[] = "transmatrix00"; + static const char TRANSMATRIX_01[] = "transmatrix01"; + static const char TRANSMATRIX_10[] = "transmatrix10"; + static const char TRANSMATRIX_11[] = "transmatrix11"; + + static const char LISA[] = "lisa"; + static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold"; + static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold"; + static const char FOV_WIDTH[] = "fov_width"; + static const char FOV_HEIGHT[] = "fov_height"; + static const char FLOAT_STAR_LIMIT[] = "float_star_limit"; + static const char CLOSE_STAR_LIMIT[] = "close_star_limit"; + static const char RATING_WEIGHT_CLOSE_STAR_COUNT[] = "rating_weight_close_star_count"; + static const char RATING_WEIGHT_FRACTION_CLOSE[] = "rating_weight_fraction_close"; + static const char RATING_WEIGHT_MEAN_SUM[] = "rating_weight_mean_sum"; + static const char RATING_WEIGHT_DB_STAR_COUNT[] = "rating_weight_db_star_count"; + static const char MAX_COMBINATIONS[] = "max_combinations"; + static const char NR_STARS_STOP[] = "nr_stars_stop"; + static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop"; + + static const char MATCHING[] = "matching"; + static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit"; + static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit"; + + static const char VALIDATION[] = "validation"; + static const char STABLE_COUNT[] = "stable_count"; + static const char MAX_DIFFERENCE[] = "max_difference"; + static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence"; + static const char MIN_MATCHED_STARS[] = "min_matchedStars"; + static const char TRACKING[] = "tracking"; static const char THIN_LIMIT[] = "thinLimit"; static const char OUTLIER_THRESHOLD[] = "outlierThreshold"; static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST"; static const char TRACKER_CHOICE[] = "trackerChoice"; + + static const char ALGO[] = "algo"; + static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence"; + static const char L2T_MIN_MATCHED[] = "l2t_minConfidence"; + static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence"; + static const char T2L_MIN_MATCHED[] = "t2l_minMatched"; } #endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp index 088bd798..d0a926a0 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -213,6 +213,31 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi result = prepareParamCommand(commandData, commandDataLen, blob); return result; } + case (StarTracker::CENTROIDING): { + Centroiding centroiding; + result = prepareParamCommand(commandData, commandDataLen, centroiding); + return result; + } + case (StarTracker::LISA): { + Lisa lisa; + result = prepareParamCommand(commandData, commandDataLen, lisa); + return result; + } + case (StarTracker::MATCHING): { + Matching matching; + result = prepareParamCommand(commandData, commandDataLen, matching); + return result; + } + case (StarTracker::VALIDATION): { + Validation validation; + result = prepareParamCommand(commandData, commandDataLen, validation); + return result; + } + case (StarTracker::ALGO): { + Algo algo; + result = prepareParamCommand(commandData, commandDataLen, algo); + return result; + } case (StarTracker::TRACKING): { Tracking tracking; result = prepareParamCommand(commandData, commandDataLen, tracking); diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp index dd91eddf..2c7bbf1d 100644 --- a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp @@ -324,6 +324,7 @@ ReturnValue_t Camera::createCommand(uint8_t* buffer) { return RETURN_OK; } + Blob::Blob() : ArcsecJsonParamBase(arcseckeys::BLOB) {} size_t Blob::getSize() { @@ -429,7 +430,8 @@ ReturnValue_t Blob::createCommand(uint8_t* buffer) { return RETURN_OK; } -Centroiding::Centroiding() : ArcsecJsonParamBase(arcseckeys::BLOB) {} + +Centroiding::Centroiding() : ArcsecJsonParamBase(arcseckeys::CENTROIDING) {} size_t Centroiding::getSize() { return COMMAND_SIZE; @@ -439,7 +441,247 @@ ReturnValue_t Centroiding::createCommand(uint8_t* buffer) { ReturnValue_t result = RETURN_OK; uint8_t offset = 0; std::string param; - addSetParamHeader(buffer, StarTracker::ID::BLOB); + addSetParamHeader(buffer, StarTracker::ID::CENTROIDING); + offset = 2; + result = getParam(arcseckeys::ENABLE_FILTER, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MAX_QUALITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_QUALITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MAX_INTENSITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_INTENSITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MAX_MAGNITUDE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::GAUSSIAN_CMAX, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::GAUSSIAN_CMIN, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_00, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_01, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_10, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_11, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Lisa::Lisa() : ArcsecJsonParamBase(arcseckeys::LISA) {} + +size_t Lisa::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Lisa::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::LISA); + offset = 2; + result = getParam(arcseckeys::PREFILTER_DIST_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::PREFILTER_ANGLE_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FOV_WIDTH, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FOV_HEIGHT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FLOAT_STAR_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CLOSE_STAR_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::RATING_WEIGHT_CLOSE_STAR_COUNT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::RATING_WEIGHT_FRACTION_CLOSE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::RATING_WEIGHT_DB_STAR_COUNT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MAX_COMBINATIONS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NR_STARS_STOP, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FRACTION_CLOSE_STOP, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + return RETURN_OK; +} + + +Matching::Matching() : ArcsecJsonParamBase(arcseckeys::MATCHING) {} + +size_t Matching::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Matching::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::MATCHING); + offset = 2; + result = getParam(arcseckeys::SQUARED_DISTANCE_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::SQUARED_SHIFT_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Validation::Validation() : ArcsecJsonParamBase(arcseckeys::VALIDATION) {} + +size_t Validation::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Validation::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::MATCHING); + offset = 2; + result = getParam(arcseckeys::STABLE_COUNT, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MAX_DIFFERENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_TRACKER_CONFIDENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_MATCHED_STARS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + return RETURN_OK; +} + +Algo::Algo() : ArcsecJsonParamBase(arcseckeys::ALGO) {} + +size_t Algo::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Algo::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::ALGO); offset = 2; result = getParam(arcseckeys::MODE, param); if (result != RETURN_OK) { @@ -447,89 +689,28 @@ ReturnValue_t Centroiding::createCommand(uint8_t* buffer) { } adduint8(param, buffer + offset); offset += sizeof(uint8_t); - result = getParam(arcseckeys::MIN_VALUE, param); + result = getParam(arcseckeys::L2T_MIN_CONFIDENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::L2T_MIN_MATCHED, param); if (result != RETURN_OK) { return result; } adduint8(param, buffer + offset); offset += sizeof(uint8_t); - result = getParam(arcseckeys::MIN_DISTANCE, param); + result = getParam(arcseckeys::T2L_MIN_CONFIDENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::T2L_MIN_MATCHED, param); if (result != RETURN_OK) { return result; } adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::NEIGHBOUR_DISTANCE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::NEIGHBOUR_BRIGHT_PIXELS, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::MIN_TOTAL_VALUE, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MAX_TOTAL_VALUE, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MIN_BRIGHT_NEIGHBOURS, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MAX_BRIGHT_NEIGHBOURS, param); - if (result != RETURN_OK) { - return result; - } - adduint16(param, buffer + offset); - offset += sizeof(uint16_t); - result = getParam(arcseckeys::MAX_PIXEL_TO_CONSIDER, param); - if (result != RETURN_OK) { - return result; - } - adduint32(param, buffer + offset); - offset += sizeof(uint32_t); - result = getParam(arcseckeys::SIGNAL_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::DARK_THRESHOLD, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::ENABLE_HISTOGRAM, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::ENABLE_CONTRAST, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); - result = getParam(arcseckeys::BIN_MODE, param); - if (result != RETURN_OK) { - return result; - } - adduint8(param, buffer + offset); - offset += sizeof(uint8_t); return RETURN_OK; } diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h index 153ef8a7..868c18ea 100644 --- a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h @@ -12,6 +12,7 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include "ArcsecJsonParamBase.h" + /** * @brief Generates command to set the limit parameters * @@ -30,6 +31,7 @@ private: virtual ReturnValue_t createCommand(uint8_t* buffer) override; }; + /** * @brief Generates the command to configure the tracking algorithm. * @@ -49,6 +51,7 @@ private: }; + /** * @brief Generates the command to set the mounting quaternion * @@ -68,6 +71,7 @@ private: }; + /** * @brief Generates the command to set the mounting quaternion * @@ -87,6 +91,7 @@ private: }; + /** * @brief Generates the command to configure the blob algorithm * @@ -106,6 +111,7 @@ private: }; + /** * @brief Generates the command to configure the centroiding algorithm * @@ -119,7 +125,88 @@ public: private: - static const size_t COMMAND_SIZE = 24; + static const size_t COMMAND_SIZE = 47; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the LISA (lost in space algorithm) + * + */ +class Lisa : public ArcsecJsonParamBase { +public: + + Lisa(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 48; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the matching algorithm + * + */ +class Matching : public ArcsecJsonParamBase { +public: + + Matching(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 10; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the validation parameters + * + */ +class Validation : public ArcsecJsonParamBase { +public: + + Validation(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 12; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates command to configure the mechanism of automatically switching between the + * LISA and other algorithms. + * + */ +class Algo : public ArcsecJsonParamBase { +public: + + Algo(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 13; ReturnValue_t createCommand(uint8_t* buffer) override; From 99c450933eb78d3a98070b7743bacedf69164e2d Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 8 Dec 2021 14:39:25 +0100 Subject: [PATCH 16/78] fix in validation command --- bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp index 2c7bbf1d..9c33e1c9 100644 --- a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp @@ -643,7 +643,7 @@ ReturnValue_t Validation::createCommand(uint8_t* buffer) { ReturnValue_t result = RETURN_OK; uint8_t offset = 0; std::string param; - addSetParamHeader(buffer, StarTracker::ID::MATCHING); + addSetParamHeader(buffer, StarTracker::ID::VALIDATION); offset = 2; result = getParam(arcseckeys::STABLE_COUNT, param); if (result != RETURN_OK) { From 11704ea908a13d2feaa524f303667a5bcd2e1713 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Dec 2021 14:48:29 +0100 Subject: [PATCH 17/78] enabled ACS board A side --- .../pollingSequenceFactory.cpp | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 73a27116..69982156 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -439,8 +439,8 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { #endif #if OBSW_ADD_ACS_BOARD == 1 - bool enableAside = false; - bool enableBside = true; + bool enableAside = true; + bool enableBside = false; if(enableAside) { // A side thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0, @@ -465,16 +465,16 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.3, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.6, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.75, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.85, - DeviceHandlerIF::GET_READ); +// thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0, +// DeviceHandlerIF::PERFORM_OPERATION); +// thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.3, +// DeviceHandlerIF::SEND_WRITE); +// thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.6, +// DeviceHandlerIF::GET_WRITE); +// thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.75, +// DeviceHandlerIF::SEND_READ); +// thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.85, +// DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); @@ -512,16 +512,16 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.3, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.6, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.75, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.85, - DeviceHandlerIF::GET_READ); +// thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0, +// DeviceHandlerIF::PERFORM_OPERATION); +// thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.3, +// DeviceHandlerIF::SEND_WRITE); +// thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.6, +// DeviceHandlerIF::GET_WRITE); +// thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.75, +// DeviceHandlerIF::SEND_READ); +// thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.85, +// DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); From 52d8ae5ffb94d72f43bcabd3e3776121f61f075c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Dec 2021 17:23:35 +0100 Subject: [PATCH 18/78] compiling for windows again --- CMakeLists.txt | 2 +- fsfw | 2 +- linux/devices/CMakeLists.txt | 1 + {mission => linux}/devices/StarTrackerHandler.cpp | 0 {mission => linux}/devices/StarTrackerHandler.h | 0 .../devices/devicedefinitions/StarTrackerDefinitions.h | 0 misc/eclipse/.cproject | 5 ++++- misc/eclipse/Host/eive-mingw-debug-cmake.launch | 2 +- mission/devices/CMakeLists.txt | 1 - mission/devices/RwHandler.cpp | 4 ++-- mission/devices/devicedefinitions/RwDefinitions.h | 2 +- 11 files changed, 11 insertions(+), 8 deletions(-) rename {mission => linux}/devices/StarTrackerHandler.cpp (100%) rename {mission => linux}/devices/StarTrackerHandler.h (100%) rename {mission => linux}/devices/devicedefinitions/StarTrackerDefinitions.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d76f2fb..59d9d32d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,6 +177,7 @@ endif() if(NOT EIVE_BUILD_WATCHDOG) if(NOT EIVE_BUILD_UNITTESTS) if(EIVE_ADD_LINUX_FILES) + add_subdirectory(${LIB_ARCSEC_PATH}) add_subdirectory(${LINUX_PATH}) endif() add_subdirectory(${BSP_PATH}) @@ -192,7 +193,6 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG)) add_subdirectory(${FSFW_PATH}) add_subdirectory(${MISSION_PATH}) add_subdirectory(${TEST_PATH}) - add_subdirectory(${LIB_ARCSEC_PATH}) endif() if(EIVE_BUILD_UNITTESTS) diff --git a/fsfw b/fsfw index ceb87b5a..e4999fe0 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit ceb87b5abb2992a18266328e0ea34d9af15db7af +Subproject commit e4999fe01c0446f9820ceede55be3970aa22bbad diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index 3871a6a6..6c529d8e 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources(${TARGET_NAME} PRIVATE HeaterHandler.cpp SolarArrayDeploymentHandler.cpp SusHandler.cpp + StarTrackerHandler.cpp ) diff --git a/mission/devices/StarTrackerHandler.cpp b/linux/devices/StarTrackerHandler.cpp similarity index 100% rename from mission/devices/StarTrackerHandler.cpp rename to linux/devices/StarTrackerHandler.cpp diff --git a/mission/devices/StarTrackerHandler.h b/linux/devices/StarTrackerHandler.h similarity index 100% rename from mission/devices/StarTrackerHandler.h rename to linux/devices/StarTrackerHandler.h diff --git a/mission/devices/devicedefinitions/StarTrackerDefinitions.h b/linux/devices/devicedefinitions/StarTrackerDefinitions.h similarity index 100% rename from mission/devices/devicedefinitions/StarTrackerDefinitions.h rename to linux/devices/devicedefinitions/StarTrackerDefinitions.h diff --git a/misc/eclipse/.cproject b/misc/eclipse/.cproject index 7d7c4c09..3bab5367 100644 --- a/misc/eclipse/.cproject +++ b/misc/eclipse/.cproject @@ -19,7 +19,7 @@ - +