diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f9bd66f..86948c4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,15 +18,30 @@ will consitute of a breaking change warranting a new major release: ## Added -- CFDP source handler, which allows file downlink using the standardized - CFDP interface. -- Proper back pressure handling for the CFDP handler, where the `LiveTmTask` is able to throttle - the CFDP handler. - Added a new safety mechanism where the ProASIC scratch buffer can be used to trigger an auto-boot to another image. The auto-boot is currently implemented as a one-shot mechanism: The key-value pair which triggers the auto-boot will be removed from the scratch buffer. See more information [here](https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/OBC_Auto_Switch_Image) +# [v7.2.0] 2023-10-27 + +- `eive-tmtc` v5.10.1 + +## Added + +- STR: Added new TM sets: Blob, Blobs, MatchedCentroids, Contrast, AutoBlob, Centroid, Centroids +- STR: Added new mechanism where the secondary TM which is polled can now be a set instead of + being temperature only. An API is exposed which allows to add a data set to that set of secondary + telemetry, reset it back to temperature only, and read the whole set. This allows more debugging + capability. +- CFDP source handler, which allows file downlink using the standardized + CFDP interface. +- Proper back pressure handling for the CFDP handler, where the `LiveTmTask` is able to throttle + the CFDP handler. +- Added CFDP fault handler events. +- The EIVE system will command the payload OFF explicitely again when receiving the + `power::POWER_LEVEL_CRITICAL` event. + ## Fixed - If the PTME is driven in a way where it fills faster than it can be emptied, the interface @@ -39,6 +54,21 @@ will consitute of a breaking change warranting a new major release: - PL Enable set of the power controller is now set to invalid properly if the power controller is not in normal mode. - MPSoC debug mode. +- Possible bugfix for PL PCDU parameter JSON handling which might not have been initialized + properly from the JSON file. + +## Changed + +- Swapped RTD 9 (PLOC HPA Sensor) and RTD 11 (PLOC MPA Sensor) chip select definitions. It is + strongly suspected the cables for those devices were swapped during integration. This is probably + the easiest way to fix the issue without the need to tweak ground or other OBSW or controller + code. +- Added a 3 second delay in the EIVE system between commanding all PL components except the SUPV, + and the SUPV itself OFF when the power level becomes low or critical. +- SUS FDIR should now trigger less events. The finish event is now only triggered once the + SUS has been working properly for a minute again. It will then display the number of periods + during which the SUS was not working as well as the maximum amount of invalid messages. +- Updated battery internal resistance to new value # [v7.1.0] 2023-10-11 diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e85d35..cbfd7815 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 7) -set(OBSW_VERSION_MINOR 1) +set(OBSW_VERSION_MINOR 2) set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 7c04e9f5..099a4c7a 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 314 translations. + * @brief Auto-generated event translation file. Contains 315 translations. * @details - * Generated on: 2023-10-13 15:23:30 + * Generated on: 2023-10-27 14:24:05 */ #include "translateEvents.h" @@ -319,6 +319,7 @@ const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED"; const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED"; const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START"; const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY"; +const char *FAULT_HANDLER_TRIGGERED_STRING = "FAULT_HANDLER_TRIGGERED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -950,6 +951,8 @@ const char *translateEvents(Event event) { return TEMPERATURE_ALL_ONES_START_STRING; case (14501): return TEMPERATURE_ALL_ONES_RECOVERY_STRING; + case (14600): + return FAULT_HANDLER_TRIGGERED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 5cb8e295..1fa48c9a 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 174 translations. - * Generated on: 2023-10-13 15:23:30 + * Contains 175 translations. + * Generated on: 2023-10-27 14:24:05 */ #include "translateObjects.h" @@ -161,6 +161,7 @@ const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL"; const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL"; const char *CFDP_HANDLER_STRING = "CFDP_HANDLER"; const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR"; +const char *CFDP_FAULT_HANDLER_STRING = "CFDP_FAULT_HANDLER"; const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; @@ -493,6 +494,8 @@ const char *translateObject(object_id_t object) { return CFDP_HANDLER_STRING; case 0x73000206: return CFDP_DISTRIBUTOR_STRING; + case 0x73000207: + return CFDP_FAULT_HANDLER_STRING; case 0x73010000: return EIVE_SYSTEM_STRING; case 0x73010001: diff --git a/common/config/devices/addresses.h b/common/config/devices/addresses.h index c1e65314..e1598574 100644 --- a/common/config/devices/addresses.h +++ b/common/config/devices/addresses.h @@ -54,6 +54,9 @@ enum I2cAddress : address_t { }; enum spiAddresses : address_t { + RTD_IC_0, + RTD_IC_1, + RTD_IC_2, RTD_IC_3, RTD_IC_4, RTD_IC_5, @@ -67,9 +70,6 @@ enum spiAddresses : address_t { RTD_IC_13, RTD_IC_14, RTD_IC_15, - RTD_IC_16, - RTD_IC_17, - RTD_IC_18, RW1, RW2, RW3, diff --git a/common/config/devices/gpioIds.h b/common/config/devices/gpioIds.h index bed82142..2cab2c32 100644 --- a/common/config/devices/gpioIds.h +++ b/common/config/devices/gpioIds.h @@ -37,6 +37,9 @@ enum gpioId_t { TEST_ID_0, TEST_ID_1, + RTD_IC_0, + RTD_IC_1, + RTD_IC_2, RTD_IC_3, RTD_IC_4, RTD_IC_5, @@ -50,9 +53,6 @@ enum gpioId_t { RTD_IC_13, RTD_IC_14, RTD_IC_15, - RTD_IC_16, - RTD_IC_17, - RTD_IC_18, CS_SUS_0, CS_SUS_1, diff --git a/common/config/eive/eventSubsystemIds.h b/common/config/eive/eventSubsystemIds.h index 84ac42d5..370a00b8 100644 --- a/common/config/eive/eventSubsystemIds.h +++ b/common/config/eive/eventSubsystemIds.h @@ -41,6 +41,7 @@ enum : uint8_t { PERSISTENT_TM_STORE = 143, SYRLINKS_COM = 144, SUS_HANDLER = 145, + CFDP_APP = 146, COMMON_SUBSYSTEM_ID_END }; diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index d6b15b8d..c7e56715 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -166,6 +166,7 @@ enum commonObjects : uint32_t { CFDP_TM_FUNNEL = 0x73000102, CFDP_HANDLER = 0x73000205, CFDP_DISTRIBUTOR = 0x73000206, + CFDP_FAULT_HANDLER = 0x73000207, MISC_TM_STORE = 0x73020001, OK_TM_STORE = 0x73020002, NOT_OK_TM_STORE = 0x73020003, diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index 24e48628..de7416f5 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -312,4 +312,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h -14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h +14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values for a prolonged time again, resetting all counters. P1: Number of periods with invalid messages. P2: Maximum invalid message counter.;mission/acs/SusHandler.h +14600;0x3908;FAULT_HANDLER_TRIGGERED;LOW;P1: CFDP fault handler code. P2: CFDP condition code.;mission/cfdp/defs.h diff --git a/generators/bsp_hosted_objects.csv b/generators/bsp_hosted_objects.csv index 689a58f2..254d093a 100644 --- a/generators/bsp_hosted_objects.csv +++ b/generators/bsp_hosted_objects.csv @@ -153,6 +153,7 @@ 0x73000102;CFDP_TM_FUNNEL 0x73000205;CFDP_HANDLER 0x73000206;CFDP_DISTRIBUTOR +0x73000207;CFDP_FAULT_HANDLER 0x73010000;EIVE_SYSTEM 0x73010001;ACS_SUBSYSTEM 0x73010002;PL_SUBSYSTEM diff --git a/generators/bsp_hosted_subsystems.csv b/generators/bsp_hosted_subsystems.csv index c9c90629..36828fda 100644 --- a/generators/bsp_hosted_subsystems.csv +++ b/generators/bsp_hosted_subsystems.csv @@ -61,3 +61,4 @@ 143;PERSISTENT_TM_STORE 144;SYRLINKS_COM 145;SUS_HANDLER +146;CFDP_APP diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 24e48628..de7416f5 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -312,4 +312,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h -14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h +14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values for a prolonged time again, resetting all counters. P1: Number of periods with invalid messages. P2: Maximum invalid message counter.;mission/acs/SusHandler.h +14600;0x3908;FAULT_HANDLER_TRIGGERED;LOW;P1: CFDP fault handler code. P2: CFDP condition code.;mission/cfdp/defs.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 10cfed26..1ada26dd 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -158,6 +158,7 @@ 0x73000102;CFDP_TM_FUNNEL 0x73000205;CFDP_HANDLER 0x73000206;CFDP_DISTRIBUTOR +0x73000207;CFDP_FAULT_HANDLER 0x73010000;EIVE_SYSTEM 0x73010001;ACS_SUBSYSTEM 0x73010002;PL_SUBSYSTEM diff --git a/generators/bsp_q7s_subsystems.csv b/generators/bsp_q7s_subsystems.csv index c9c90629..36828fda 100644 --- a/generators/bsp_q7s_subsystems.csv +++ b/generators/bsp_q7s_subsystems.csv @@ -61,3 +61,4 @@ 143;PERSISTENT_TM_STORE 144;SYRLINKS_COM 145;SUS_HANDLER +146;CFDP_APP diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 7c04e9f5..099a4c7a 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 314 translations. + * @brief Auto-generated event translation file. Contains 315 translations. * @details - * Generated on: 2023-10-13 15:23:30 + * Generated on: 2023-10-27 14:24:05 */ #include "translateEvents.h" @@ -319,6 +319,7 @@ const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED"; const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED"; const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START"; const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY"; +const char *FAULT_HANDLER_TRIGGERED_STRING = "FAULT_HANDLER_TRIGGERED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -950,6 +951,8 @@ const char *translateEvents(Event event) { return TEMPERATURE_ALL_ONES_START_STRING; case (14501): return TEMPERATURE_ALL_ONES_RECOVERY_STRING; + case (14600): + return FAULT_HANDLER_TRIGGERED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 5b99d6f0..5cc157c2 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 178 translations. - * Generated on: 2023-10-13 15:23:30 + * Contains 179 translations. + * Generated on: 2023-10-27 14:24:05 */ #include "translateObjects.h" @@ -166,6 +166,7 @@ const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL"; const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL"; const char *CFDP_HANDLER_STRING = "CFDP_HANDLER"; const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR"; +const char *CFDP_FAULT_HANDLER_STRING = "CFDP_FAULT_HANDLER"; const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; @@ -507,6 +508,8 @@ const char *translateObject(object_id_t object) { return CFDP_HANDLER_STRING; case 0x73000206: return CFDP_DISTRIBUTOR_STRING; + case 0x73000207: + return CFDP_FAULT_HANDLER_STRING; case 0x73010000: return EIVE_SYSTEM_STRING; case 0x73010001: diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index cb3e043b..756dc0af 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -206,74 +206,78 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_0, gpioRtdIc0); GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_1, gpioRtdIc1); GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_2, gpioRtdIc2); GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc3); GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc4); GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc5); GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc6); GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc7); GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc8); GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc9); GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc10); GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc11); GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc12); GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc13); GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc14); GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", Direction::OUT, Levels::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); - rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15); + rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc15); gpioChecker(gpioComIF->addGpios(rtdGpioCookie), "RTDs"); #if OBSW_ADD_RTD_DEVICES == 1 using namespace EiveMax31855; + // ! NOTE ! + // The chip selects for device 9 and 11 are swapped here. It is strongly suspected the cables + // for those devices were swapped during integration. This is probably the easiest way to + // fix the issue. std::array, NUM_RTDS> cookieArgs = {{ + {addresses::RTD_IC_0, gpioIds::RTD_IC_0}, + {addresses::RTD_IC_1, gpioIds::RTD_IC_1}, + {addresses::RTD_IC_2, gpioIds::RTD_IC_2}, {addresses::RTD_IC_3, gpioIds::RTD_IC_3}, {addresses::RTD_IC_4, gpioIds::RTD_IC_4}, {addresses::RTD_IC_5, gpioIds::RTD_IC_5}, {addresses::RTD_IC_6, gpioIds::RTD_IC_6}, {addresses::RTD_IC_7, gpioIds::RTD_IC_7}, {addresses::RTD_IC_8, gpioIds::RTD_IC_8}, - {addresses::RTD_IC_9, gpioIds::RTD_IC_9}, - {addresses::RTD_IC_10, gpioIds::RTD_IC_10}, {addresses::RTD_IC_11, gpioIds::RTD_IC_11}, + {addresses::RTD_IC_10, gpioIds::RTD_IC_10}, + {addresses::RTD_IC_9, gpioIds::RTD_IC_9}, {addresses::RTD_IC_12, gpioIds::RTD_IC_12}, {addresses::RTD_IC_13, gpioIds::RTD_IC_13}, {addresses::RTD_IC_14, gpioIds::RTD_IC_14}, {addresses::RTD_IC_15, gpioIds::RTD_IC_15}, - {addresses::RTD_IC_16, gpioIds::RTD_IC_16}, - {addresses::RTD_IC_17, gpioIds::RTD_IC_17}, - {addresses::RTD_IC_18, gpioIds::RTD_IC_18}, }}; // HSPD: Heatspreader diff --git a/linux/callbacks/gpioCallbacks.cpp b/linux/callbacks/gpioCallbacks.cpp index 969aada0..4c05bac3 100644 --- a/linux/callbacks/gpioCallbacks.cpp +++ b/linux/callbacks/gpioCallbacks.cpp @@ -21,6 +21,18 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp if (value == gpio::Levels::HIGH) { switch (gpioId) { + case (gpioIds::RTD_IC_0): { + disableDecoderTcsIc1(gpioIF); + break; + } + case (gpioIds::RTD_IC_1): { + disableDecoderTcsIc1(gpioIF); + break; + } + case (gpioIds::RTD_IC_2): { + disableDecoderTcsIc1(gpioIF); + break; + } case (gpioIds::RTD_IC_3): { disableDecoderTcsIc1(gpioIF); break; @@ -42,15 +54,15 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp break; } case (gpioIds::RTD_IC_8): { - disableDecoderTcsIc1(gpioIF); + disableDecoderTcsIc2(gpioIF); break; } case (gpioIds::RTD_IC_9): { - disableDecoderTcsIc1(gpioIF); + disableDecoderTcsIc2(gpioIF); break; } case (gpioIds::RTD_IC_10): { - disableDecoderTcsIc1(gpioIF); + disableDecoderTcsIc2(gpioIF); break; } case (gpioIds::RTD_IC_11): { @@ -73,18 +85,6 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp disableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_16): { - disableDecoderTcsIc2(gpioIF); - break; - } - case (gpioIds::RTD_IC_17): { - disableDecoderTcsIc2(gpioIF); - break; - } - case (gpioIds::RTD_IC_18): { - disableDecoderTcsIc2(gpioIF); - break; - } case (gpioIds::CS_SUS_0): { disableDecoderInterfaceBoardIc1(gpioIF); break; @@ -154,82 +154,82 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp } } else if (value == gpio::Levels::LOW) { switch (gpioId) { - case (gpioIds::RTD_IC_3): { + case (gpioIds::RTD_IC_0): { selectY7(gpioIF); enableDecoderTcsIc1(gpioIF); break; } + case (gpioIds::RTD_IC_1): { + selectY6(gpioIF); + enableDecoderTcsIc1(gpioIF); + break; + } + case (gpioIds::RTD_IC_2): { + selectY5(gpioIF); + enableDecoderTcsIc1(gpioIF); + break; + } + case (gpioIds::RTD_IC_3): { + selectY4(gpioIF); + enableDecoderTcsIc1(gpioIF); + break; + } case (gpioIds::RTD_IC_4): { - selectY6(gpioIF); + selectY3(gpioIF); enableDecoderTcsIc1(gpioIF); break; } case (gpioIds::RTD_IC_5): { - selectY5(gpioIF); + selectY2(gpioIF); enableDecoderTcsIc1(gpioIF); break; } case (gpioIds::RTD_IC_6): { - selectY4(gpioIF); + selectY1(gpioIF); enableDecoderTcsIc1(gpioIF); break; } case (gpioIds::RTD_IC_7): { - selectY3(gpioIF); - enableDecoderTcsIc1(gpioIF); - break; - } - case (gpioIds::RTD_IC_8): { - selectY2(gpioIF); - enableDecoderTcsIc1(gpioIF); - break; - } - case (gpioIds::RTD_IC_9): { - selectY1(gpioIF); - enableDecoderTcsIc1(gpioIF); - break; - } - case (gpioIds::RTD_IC_10): { selectY0(gpioIF); enableDecoderTcsIc1(gpioIF); break; } - case (gpioIds::RTD_IC_11): { + case (gpioIds::RTD_IC_8): { selectY7(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_12): { + case (gpioIds::RTD_IC_9): { selectY6(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_13): { + case (gpioIds::RTD_IC_10): { selectY5(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_14): { + case (gpioIds::RTD_IC_11): { selectY4(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_15): { + case (gpioIds::RTD_IC_12): { selectY3(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_16): { + case (gpioIds::RTD_IC_13): { selectY2(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_17): { + case (gpioIds::RTD_IC_14): { selectY1(gpioIF); enableDecoderTcsIc2(gpioIF); break; } - case (gpioIds::RTD_IC_18): { + case (gpioIds::RTD_IC_15): { selectY0(gpioIF); enableDecoderTcsIc2(gpioIF); break; diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 7c04e9f5..099a4c7a 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 314 translations. + * @brief Auto-generated event translation file. Contains 315 translations. * @details - * Generated on: 2023-10-13 15:23:30 + * Generated on: 2023-10-27 14:24:05 */ #include "translateEvents.h" @@ -319,6 +319,7 @@ const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED"; const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED"; const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START"; const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY"; +const char *FAULT_HANDLER_TRIGGERED_STRING = "FAULT_HANDLER_TRIGGERED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -950,6 +951,8 @@ const char *translateEvents(Event event) { return TEMPERATURE_ALL_ONES_START_STRING; case (14501): return TEMPERATURE_ALL_ONES_RECOVERY_STRING; + case (14600): + return FAULT_HANDLER_TRIGGERED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 5b99d6f0..5cc157c2 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 178 translations. - * Generated on: 2023-10-13 15:23:30 + * Contains 179 translations. + * Generated on: 2023-10-27 14:24:05 */ #include "translateObjects.h" @@ -166,6 +166,7 @@ const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL"; const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL"; const char *CFDP_HANDLER_STRING = "CFDP_HANDLER"; const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR"; +const char *CFDP_FAULT_HANDLER_STRING = "CFDP_FAULT_HANDLER"; const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; @@ -507,6 +508,8 @@ const char *translateObject(object_id_t object) { return CFDP_HANDLER_STRING; case 0x73000206: return CFDP_DISTRIBUTOR_STRING; + case 0x73000207: + return CFDP_FAULT_HANDLER_STRING; case 0x73010000: return EIVE_SYSTEM_STRING; case 0x73010001: diff --git a/mission/acs/SusHandler.cpp b/mission/acs/SusHandler.cpp index 4b9778e5..193bdb5c 100644 --- a/mission/acs/SusHandler.cpp +++ b/mission/acs/SusHandler.cpp @@ -97,7 +97,7 @@ ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8 // appear sometimes for the SUS device: Allow invalid message up to a certain threshold // before triggering FDIR reactions. if (reply->tempRaw == 0xfff and not waitingForRecovery) { - if (invalidMsgCounter == 0) { + if (invalidMsgCounter == 0 and invalidMsgPeriodCounter == 0) { triggerEvent(TEMPERATURE_ALL_ONES_START); } else if (invalidMsgCounter == susMax1227::MAX_INVALID_MSG_COUNT) { triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT); @@ -110,8 +110,17 @@ ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8 return returnvalue::OK; } if (invalidMsgCounter > 0) { - triggerEvent(TEMPERATURE_ALL_ONES_RECOVERY, invalidMsgCounter); + invalidMsgPeriodCounter++; + if (invalidMsgCounter > invalidMsgCounterMax) { + invalidMsgCounterMax = invalidMsgCounter; + } invalidMsgCounter = 0; + invalidMsgCountdown.resetTimer(); + } + if (invalidMsgCountdown.hasTimedOut() and invalidMsgPeriodCounter > 0) { + triggerEvent(TEMPERATURE_ALL_ONES_RECOVERY, invalidMsgPeriodCounter, invalidMsgCounterMax); + invalidMsgPeriodCounter = 0; + invalidMsgCounterMax = 0; } dataset.setValidity(true, true); dataset.tempC = max1227::getTemperature(reply->tempRaw); diff --git a/mission/acs/SusHandler.h b/mission/acs/SusHandler.h index 88e2b163..43c49dcb 100644 --- a/mission/acs/SusHandler.h +++ b/mission/acs/SusHandler.h @@ -20,8 +20,9 @@ class SusHandler : public DeviceHandlerBase { //! [EXPORT] : [COMMENT] Detected invalid values, starting invalid message counting static constexpr Event TEMPERATURE_ALL_ONES_START = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); - //! [EXPORT] : [COMMENT] Detected valid values again, resetting invalid message counter. - //! P1: Invalid message counter. + //! [EXPORT] : [COMMENT] Detected valid values for a prolonged time again, resetting all counters. + //! P1: Number of periods with invalid messages. + //! P2: Maximum invalid message counter. static constexpr Event TEMPERATURE_ALL_ONES_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); @@ -54,8 +55,13 @@ class SusHandler : public DeviceHandlerBase { susMax1227::SusDataset dataset; acs::SusRequest request{}; uint8_t susIdx; + + // After 1 minute, trigger the event for the invalid messages. + Countdown invalidMsgCountdown = Countdown(60000); bool waitingForRecovery = true; uint32_t invalidMsgCounter = 0; + uint32_t invalidMsgCounterMax = 0; + uint32_t invalidMsgPeriodCounter = 0; uint32_t transitionDelay = 1000; bool goToNormalMode = false; diff --git a/mission/acs/str/StarTrackerHandler.cpp b/mission/acs/str/StarTrackerHandler.cpp index a6091d7c..541301f1 100644 --- a/mission/acs/str/StarTrackerHandler.cpp +++ b/mission/acs/str/StarTrackerHandler.cpp @@ -49,6 +49,13 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, subscriptionSet(this), logSubscriptionSet(this), debugCameraSet(this), + autoBlobSet(this), + matchedCentroidsSet(this), + blobSet(this), + blobsSet(this), + centroidSet(this), + centroidsSet(this), + contrastSet(this), strHelper(strHelper), paramJsonFile(jsonFileStr), powerSwitch(powerSwitch) { @@ -59,6 +66,8 @@ 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); + additionalRequestedTm.emplace(startracker::REQ_TEMPERATURE); + currentSecondaryTmIter = additionalRequestedTm.begin(); } StarTrackerHandler::~StarTrackerHandler() {} @@ -165,6 +174,35 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu ReturnValue_t result = returnvalue::OK; switch (actionId) { + case (startracker::ADD_SECONDARY_TM_TO_NORMAL_MODE): { + if (size < 4) { + return HasActionsIF::INVALID_PARAMETERS; + } + DeviceCommandId_t idToAdd; + result = + SerializeAdapter::deSerialize(&idToAdd, data, &size, SerializeIF::Endianness::NETWORK); + if (result != returnvalue::OK) { + return result; + } + addSecondaryTmForNormalMode(idToAdd); + return EXECUTION_FINISHED; + } + case (startracker::RESET_SECONDARY_TM_SET): { + resetSecondaryTmSet(); + return EXECUTION_FINISHED; + } + case (startracker::READ_SECONDARY_TM_SET): { + std::vector dataVec(additionalRequestedTm.size() * 4); + unsigned idx = 0; + size_t serLen = 0; + for (const auto& cmd : additionalRequestedTm) { + SerializeAdapter::serialize(&cmd, dataVec.data() + idx * 4, &serLen, dataVec.size(), + SerializeIF::Endianness::NETWORK); + idx++; + } + actionHelper.reportData(commandedBy, actionId, dataVec.data(), dataVec.size()); + return EXECUTION_FINISHED; + } case (startracker::STOP_IMAGE_LOADER): { strHelper->stopProcess(); return EXECUTION_FINISHED; @@ -306,13 +344,20 @@ ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id return NOTHING_TO_SEND; } switch (normalState) { - case NormalState::TEMPERATURE_REQUEST: - *id = startracker::REQ_TEMPERATURE; + case NormalState::SECONDARY_REQUEST: + if (additionalRequestedTm.size() == 0) { + break; + } + *id = *currentSecondaryTmIter; + currentSecondaryTmIter++; + if (currentSecondaryTmIter == additionalRequestedTm.end()) { + currentSecondaryTmIter = additionalRequestedTm.begin(); + } normalState = NormalState::SOLUTION_REQUEST; break; case NormalState::SOLUTION_REQUEST: *id = startracker::REQ_SOLUTION; - normalState = NormalState::TEMPERATURE_REQUEST; + normalState = NormalState::SECONDARY_REQUEST; break; default: sif::debug << "StarTrackerHandler::buildNormalDeviceCommand: Invalid normal step" @@ -472,6 +517,18 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi prepareTimeRequest(); return returnvalue::OK; } + case (startracker::REQ_CENTROID): { + prepareRequestCentroidTm(); + return returnvalue::OK; + } + case (startracker::REQ_CENTROIDS): { + prepareRequestCentroidsTm(); + return returnvalue::OK; + } + case (startracker::REQ_CONTRAST): { + prepareRequestContrastTm(); + return returnvalue::OK; + } case (startracker::BOOT): { prepareBootCommand(); return returnvalue::OK; @@ -607,6 +664,22 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi result = prepareRequestLisaParams(); return result; } + case (startracker::REQ_MATCHED_CENTROIDS): { + result = prepareRequestMatchedCentroidsTm(); + return result; + } + case (startracker::REQ_BLOB): { + result = prepareRequestBlobTm(); + return result; + } + case (startracker::REQ_BLOBS): { + result = prepareRequestBlobsTm(); + return result; + } + case (startracker::REQ_AUTO_BLOB): { + result = prepareRequestAutoBlobTm(); + return returnvalue::OK; + } case (startracker::REQ_MATCHING): { result = prepareRequestMatchingParams(); return result; @@ -729,6 +802,20 @@ void StarTrackerHandler::fillCommandAndReplyMap() { startracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(startracker::REQ_DEBUG_CAMERA, 3, &debugCameraSet, startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_AUTO_BLOB, 3, &autoBlobSet, + startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_MATCHED_CENTROIDS, 3, &matchedCentroidsSet, + startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_BLOB, 3, &blobSet, + startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_BLOBS, 3, &blobsSet, + startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_CENTROID, 3, ¢roidSet, + startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_CENTROIDS, 3, ¢roidsSet, + startracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(startracker::REQ_CONTRAST, 3, &contrastSet, + startracker::MAX_FRAME_SIZE * 2 + 2); } ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { @@ -860,6 +947,74 @@ void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonF JCFG_DONE = true; } +ReturnValue_t StarTrackerHandler::statusFieldCheck(const uint8_t* rawFrame) { + uint8_t status = startracker::getStatusField(rawFrame); + if (status != startracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleTm: Reply error: " + << static_cast(status) << std::endl; + return REPLY_ERROR; + } + return returnvalue::OK; +} + +void StarTrackerHandler::addSecondaryTmForNormalMode(DeviceCommandId_t cmd) { + additionalRequestedTm.emplace(cmd); +} + +void StarTrackerHandler::resetSecondaryTmSet() { + additionalRequestedTm.clear(); + additionalRequestedTm.emplace(startracker::REQ_TEMPERATURE); + currentSecondaryTmIter = additionalRequestedTm.begin(); + { + PoolReadGuard pg(&autoBlobSet); + if (pg.getReadResult() == returnvalue::OK) { + autoBlobSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(&matchedCentroidsSet); + if (pg.getReadResult() == returnvalue::OK) { + matchedCentroidsSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(&blobSet); + if (pg.getReadResult() == returnvalue::OK) { + blobSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(&blobsSet); + if (pg.getReadResult() == returnvalue::OK) { + blobsSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(¢roidSet); + if (pg.getReadResult() == returnvalue::OK) { + centroidSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(&contrastSet); + if (pg.getReadResult() == returnvalue::OK) { + contrastSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(¢roidsSet); + if (pg.getReadResult() == returnvalue::OK) { + centroidsSet.setValidity(false, true); + } + } + { + PoolReadGuard pg(&histogramSet); + if (pg.getReadResult() == returnvalue::OK) { + histogramSet.setValidity(false, true); + } + } +} + void StarTrackerHandler::bootBootloader() { if (internalState == InternalState::IDLE) { internalState = InternalState::BOOT_BOOTLOADER; @@ -896,24 +1051,24 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t* start, size_t rema } case TMTC_ACTIONREPLY: { *foundLen = remainingSize; + fullPacketLen = remainingSize; return scanForActionReply(startracker::getId(start), foundId); - break; } case TMTC_SETPARAMREPLY: { *foundLen = remainingSize; + fullPacketLen = remainingSize; return scanForSetParameterReply(startracker::getId(start), foundId); - break; } case TMTC_PARAMREPLY: { *foundLen = remainingSize; + fullPacketLen = remainingSize; return scanForGetParameterReply(startracker::getId(start), foundId); - break; } case TMTC_TELEMETRYREPLYA: case TMTC_TELEMETRYREPLY: { *foundLen = remainingSize; + fullPacketLen = remainingSize; return scanForTmReply(startracker::getId(start), foundId); - break; } default: { sif::debug << "StarTrackerHandler::scanForReply: Reply has invalid type id" << std::endl; @@ -933,7 +1088,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, break; } case (startracker::REQ_TIME): { - result = handleTm(packet, timeSet, startracker::TimeSet::SIZE, "REQ_TIME"); + result = handleTm(packet, timeSet, "REQ_TIME"); break; } case (startracker::PING_REQUEST): { @@ -948,7 +1103,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, break; } case (startracker::REQ_VERSION): { - result = handleTm(packet, versionSet, startracker::VersionSet::SIZE, "REQ_VERSION"); + result = handleTm(packet, versionSet, "REQ_VERSION"); if (result != returnvalue::OK) { return result; } @@ -959,23 +1114,51 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, break; } case (startracker::REQ_INTERFACE): { - result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE, "REQ_INTERFACE"); + result = handleTm(packet, interfaceSet, "REQ_INTERFACE"); break; } case (startracker::REQ_POWER): { - result = handleTm(packet, powerSet, startracker::PowerSet::SIZE, "REQ_POWER"); + result = handleTm(packet, powerSet, "REQ_POWER"); break; } case (startracker::REQ_SOLUTION): { - result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE, "REQ_SOLUTION"); + result = handleTm(packet, solutionSet, "REQ_SOLUTION"); + break; + } + case (startracker::REQ_CONTRAST): { + result = handleTm(packet, contrastSet, "REQ_CONTRAST"); + break; + } + case (startracker::REQ_AUTO_BLOB): { + result = handleAutoBlobTm(packet); + break; + } + case (startracker::REQ_MATCHED_CENTROIDS): { + result = handleMatchedCentroidTm(packet); + break; + } + case (startracker::REQ_BLOB): { + result = handleBlobTm(packet); + break; + } + case (startracker::REQ_BLOBS): { + result = handleBlobsTm(packet); + break; + } + case (startracker::REQ_CENTROID): { + result = handleCentroidTm(packet); + break; + } + case (startracker::REQ_CENTROIDS): { + result = handleCentroidsTm(packet); break; } case (startracker::REQ_TEMPERATURE): { - result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE, "REQ_TEMP"); + result = handleTm(packet, temperatureSet, "REQ_TEMP"); break; } case (startracker::REQ_HISTOGRAM): { - result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE, "REQ_HISTO"); + result = handleTm(packet, histogramSet, "REQ_HISTO"); break; } case (startracker::SUBSCRIPTION): @@ -1329,6 +1512,56 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l localDataPoolMap.emplace(startracker::CHKSUM, new PoolEntry({0})); + localDataPoolMap.emplace(startracker::TICKS_AUTO_BLOB, new PoolEntry()); + localDataPoolMap.emplace(startracker::TIME_AUTO_BLOB, new PoolEntry()); + localDataPoolMap.emplace(startracker::AUTO_BLOB_THRESHOLD, new PoolEntry()); + + localDataPoolMap.emplace(startracker::PoolIds::NUM_MATCHED_CENTROIDS, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_STAR_IDS, + new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_X_COORDS, + new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_Y_COORDS, + new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_X_ERRORS, + new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_Y_ERRORS, + new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::TICKS_MATCHED_CENTROIDS, + new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::TIME_MATCHED_CENTROIDS, new PoolEntry()); + + localDataPoolMap.emplace(startracker::PoolIds::BLOB_TICKS, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOB_TIME, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOB_COUNT, new PoolEntry()); + + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_TICKS, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_TIME, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_COUNT, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_COUNT_USED, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_NR_4LINES_SKIPPED, + new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_X_COORDS, new PoolEntry(8)); + localDataPoolMap.emplace(startracker::PoolIds::BLOBS_Y_COORDS, new PoolEntry(8)); + + localDataPoolMap.emplace(startracker::PoolIds::CENTROID_TICKS, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CENTROID_TIME, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CENTROID_COUNT, new PoolEntry()); + + localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_TICKS, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_TIME, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_COUNT, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_X_COORDS, new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_Y_COORDS, new PoolEntry(16)); + localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_MAGNITUDES, new PoolEntry(16)); + + localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_TICKS, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_TIME, new PoolEntry()); + localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_A, new PoolEntry(9)); + localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_B, new PoolEntry(9)); + localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_C, new PoolEntry(9)); + localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_D, new PoolEntry(9)); + poolManager.subscribeForDiagPeriodicPacket( subdp::DiagnosticsHkPeriodicParams(temperatureSet.getSid(), false, 10.0)); poolManager.subscribeForRegularPeriodicPacket( @@ -1343,6 +1576,20 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l subdp::RegularHkPeriodicParams(histogramSet.getSid(), false, 10.0)); poolManager.subscribeForRegularPeriodicPacket( subdp::RegularHkPeriodicParams(lisaSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(autoBlobSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(matchedCentroidsSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(blobSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(blobsSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(centroidSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(centroidsSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(contrastSet.getSid(), false, 10.0)); return returnvalue::OK; } @@ -1584,8 +1831,36 @@ ReturnValue_t StarTrackerHandler::scanForTmReply(uint8_t replyId, DeviceCommandI *foundId = startracker::REQ_SOLUTION; break; } + case (startracker::ID::BLOB): { + *foundId = startracker::REQ_BLOB; + break; + } + case (startracker::ID::BLOBS): { + *foundId = startracker::REQ_BLOBS; + break; + } + case (startracker::ID::CENTROID): { + *foundId = startracker::REQ_CENTROID; + break; + } + case (startracker::ID::CENTROIDS): { + *foundId = startracker::REQ_CENTROIDS; + break; + } + case (startracker::ID::AUTO_BLOB): { + *foundId = startracker::REQ_AUTO_BLOB; + break; + } + case (startracker::ID::MATCHED_CENTROIDS): { + *foundId = startracker::REQ_MATCHED_CENTROIDS; + break; + } + case (startracker::ID::CONTRAST): { + *foundId = startracker::REQ_CONTRAST; + break; + } default: { - sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply id: " + sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply ID: " << static_cast(replyId) << std::endl; return returnvalue::FAILED; break; @@ -1760,6 +2035,62 @@ void StarTrackerHandler::prepareHistogramRequest() { rawPacketLen = length; } +ReturnValue_t StarTrackerHandler::prepareRequestAutoBlobTm() { + uint32_t length = 0; + arc_tm_pack_autoblob_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::prepareRequestMatchedCentroidsTm() { + uint32_t length = 0; + arc_tm_pack_matchedcentroids_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::prepareRequestBlobTm() { + uint32_t length = 0; + arc_tm_pack_blob_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::prepareRequestBlobsTm() { + uint32_t length = 0; + arc_tm_pack_blobs_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::prepareRequestCentroidTm() { + uint32_t length = 0; + arc_tm_pack_centroid_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::prepareRequestCentroidsTm() { + uint32_t length = 0; + arc_tm_pack_centroids_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::prepareRequestContrastTm() { + uint32_t length = 0; + arc_tm_pack_contrast_req(commandBuffer, &length); + rawPacket = commandBuffer; + rawPacketLen = length; + return returnvalue::OK; +} + ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, ArcsecJsonParamBase& paramSet, @@ -2038,13 +2369,10 @@ ReturnValue_t StarTrackerHandler::checkProgram() { } ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, - size_t size, const char* context) { - ReturnValue_t result = returnvalue::OK; - uint8_t status = startracker::getStatusField(rawFrame); - if (status != startracker::STATUS_OK) { - sif::warning << "StarTrackerHandler::handleTm: Reply error: " - << static_cast(status) << std::endl; - return REPLY_ERROR; + const char* context) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; } result = dataset.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); if (result != returnvalue::OK) { @@ -2052,10 +2380,11 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat } const uint8_t* reply = rawFrame + TICKS_OFFSET; dataset.setValidityBufferGeneration(false); - result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE); + size_t sizeLeft = fullPacketLen; + result = dataset.deSerialize(&reply, &sizeLeft, SerializeIF::Endianness::LITTLE); if (result != returnvalue::OK) { - sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context - << std::endl; + sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context << ": 0x" + << std::hex << std::setw(4) << result << std::dec << std::endl; } dataset.setValidityBufferGeneration(true); dataset.setValidity(true, true); @@ -2069,6 +2398,262 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat return result; } +ReturnValue_t StarTrackerHandler::handleAutoBlobTm(const uint8_t* rawFrame) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; + } + rawFrame += TICKS_OFFSET; + size_t remainingLen = fullPacketLen; + PoolReadGuard pg(&autoBlobSet); + result = pg.getReadResult(); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&autoBlobSet.ticks, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&autoBlobSet.timeUs, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&autoBlobSet.threshold, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + autoBlobSet.setValidity(true, true); + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::handleMatchedCentroidTm(const uint8_t* rawFrame) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; + } + rawFrame += TICKS_OFFSET; + size_t remainingLen = fullPacketLen; + PoolReadGuard pg(&matchedCentroidsSet); + result = pg.getReadResult(); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.ticks, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.timeUs, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.numberOfMatchedCentroids, &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + + if (result != returnvalue::OK) { + return result; + } + // Yeah, we serialize it like that because I can't model anything with that local datapool crap. + for (unsigned idx = 0; idx < 16; idx++) { + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.starIds[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.xCoords[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.yCoords[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.xErrors[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&matchedCentroidsSet.yErrors[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + } + matchedCentroidsSet.setValidity(true, true); + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::handleBlobTm(const uint8_t* rawFrame) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; + } + rawFrame += TICKS_OFFSET; + size_t remainingLen = fullPacketLen; + PoolReadGuard pg(&blobsSet); + result = pg.getReadResult(); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobSet.ticks, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobSet.timeUs, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobSet.blobCount, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + blobSet.setValidity(true, true); + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::handleBlobsTm(const uint8_t* rawFrame) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; + } + rawFrame += TICKS_OFFSET; + size_t remainingLen = fullPacketLen; + PoolReadGuard pg(&blobsSet); + result = pg.getReadResult(); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobsSet.ticks, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobsSet.timeUs, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobsSet.blobsCount, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobsSet.blobsCountUsed, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobsSet.nr4LinesSkipped, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + for (unsigned idx = 0; idx < 8; idx++) { + result = SerializeAdapter::deSerialize(&blobsSet.xCoords[idx], &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(&blobsSet.yCoords[idx], &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + } + blobsSet.setValidity(true, true); + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::handleCentroidTm(const uint8_t* rawFrame) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; + } + rawFrame += TICKS_OFFSET; + size_t remainingLen = fullPacketLen; + PoolReadGuard pg(¢roidsSet); + result = pg.getReadResult(); + if (result != returnvalue::OK) { + return result; + } + + result = SerializeAdapter::deSerialize(¢roidSet.ticks, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(¢roidSet.timeUs, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(¢roidSet.centroidCount, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + centroidSet.setValidity(true, true); + return returnvalue::OK; +} + +ReturnValue_t StarTrackerHandler::handleCentroidsTm(const uint8_t* rawFrame) { + ReturnValue_t result = statusFieldCheck(rawFrame); + if (result != returnvalue::OK) { + return result; + } + rawFrame += TICKS_OFFSET; + size_t remainingLen = fullPacketLen; + PoolReadGuard pg(¢roidsSet); + result = pg.getReadResult(); + if (result != returnvalue::OK) { + return result; + } + + result = SerializeAdapter::deSerialize(¢roidsSet.ticksCentroidsTm, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(¢roidsSet.timeUsCentroidsTm, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(¢roidsSet.centroidsCount, &rawFrame, &remainingLen, + SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + for (unsigned idx = 0; idx < 16; idx++) { + result = SerializeAdapter::deSerialize(¢roidsSet.centroidsXCoords[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(¢roidsSet.centroidsYCoords[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + result = SerializeAdapter::deSerialize(¢roidsSet.centroidsMagnitudes[idx], &rawFrame, + &remainingLen, SerializeIF::Endianness::LITTLE); + if (result != returnvalue::OK) { + return result; + } + } + centroidsSet.setValidity(true, true); + return returnvalue::OK; +} + ReturnValue_t StarTrackerHandler::handleActionReplySet(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size) { ReturnValue_t result = returnvalue::OK; @@ -2204,10 +2789,17 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) { case startracker::REQ_SUBSCRIPTION: case startracker::REQ_LOG_SUBSCRIPTION: case startracker::REQ_DEBUG_CAMERA: + case startracker::REQ_MATCHED_CENTROIDS: + case startracker::REQ_BLOB: + case startracker::REQ_BLOBS: + case startracker::REQ_CENTROID: + case startracker::REQ_CENTROIDS: + case startracker::REQ_CONTRAST: { if (getMode() == MODE_ON and getSubmode() != startracker::Program::FIRMWARE) { return STARTRACKER_NOT_RUNNING_FIRMWARE; } break; + } case startracker::FIRMWARE_UPDATE: case startracker::FLASH_READ: if (getMode() != MODE_ON or getSubmode() != startracker::Program::BOOTLOADER) { diff --git a/mission/acs/str/StarTrackerHandler.h b/mission/acs/str/StarTrackerHandler.h index 1e790695..3bfdc8fd 100644 --- a/mission/acs/str/StarTrackerHandler.h +++ b/mission/acs/str/StarTrackerHandler.h @@ -8,6 +8,7 @@ #include #include +#include #include #include "OBSWConfig.h" @@ -151,6 +152,7 @@ class StarTrackerHandler : public DeviceHandlerBase { static const uint8_t PARAMS_OFFSET = 2; static const uint8_t TICKS_OFFSET = 3; static const uint8_t TIME_OFFSET = 7; + static const uint8_t TM_PARAM_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; @@ -204,6 +206,13 @@ class StarTrackerHandler : public DeviceHandlerBase { startracker::SubscriptionSet subscriptionSet; startracker::LogSubscriptionSet logSubscriptionSet; startracker::DebugCameraSet debugCameraSet; + startracker::AutoBlobSet autoBlobSet; + startracker::MatchedCentroidsSet matchedCentroidsSet; + startracker::BlobSet blobSet; + startracker::BlobsSet blobsSet; + startracker::CentroidSet centroidSet; + startracker::CentroidsSet centroidsSet; + startracker::ContrastSet contrastSet; // Pointer to object responsible for uploading and downloading images to/from the star tracker StrComHandler* strHelper = nullptr; @@ -239,9 +248,9 @@ class StarTrackerHandler : public DeviceHandlerBase { std::string paramJsonFile; - enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST }; + enum class NormalState { SECONDARY_REQUEST, SOLUTION_REQUEST }; - NormalState normalState = NormalState::TEMPERATURE_REQUEST; + NormalState normalState = NormalState::SECONDARY_REQUEST; enum class StartupState { IDLE, @@ -297,6 +306,11 @@ class StarTrackerHandler : public DeviceHandlerBase { const power::Switch_t powerSwitch = power::NO_SWITCH; + size_t fullPacketLen = 0; + + std::set additionalRequestedTm{}; + std::set::iterator currentSecondaryTmIter; + /** * @brief Handles internal state */ @@ -345,6 +359,18 @@ class StarTrackerHandler : public DeviceHandlerBase { */ ReturnValue_t executeFlashReadCommand(const uint8_t* commandData, size_t commandDataLen); + /** + * Add a TM request to the list of telemetry which will be polled in the secondary step of + * the device communication. + * @param cmd + */ + void addSecondaryTmForNormalMode(DeviceCommandId_t cmd); + + /** + * Reset the secondary set, which will only contain a TEMPERATURE set request after the reset. + */ + void resetSecondaryTmSet(); + /** * @brief Fills command buffer with data to boot image (works only when star tracker is * in bootloader mode). @@ -429,6 +455,13 @@ class StarTrackerHandler : public DeviceHandlerBase { ReturnValue_t prepareRequestCentroidingParams(); ReturnValue_t prepareRequestLisaParams(); ReturnValue_t prepareRequestMatchingParams(); + ReturnValue_t prepareRequestAutoBlobTm(); + ReturnValue_t prepareRequestMatchedCentroidsTm(); + ReturnValue_t prepareRequestBlobTm(); + ReturnValue_t prepareRequestBlobsTm(); + ReturnValue_t prepareRequestCentroidTm(); + ReturnValue_t prepareRequestCentroidsTm(); + ReturnValue_t prepareRequestContrastTm(); ReturnValue_t prepareRequestTrackingParams(); ReturnValue_t prepareRequestValidationParams(); ReturnValue_t prepareRequestAlgoParams(); @@ -477,6 +510,7 @@ class StarTrackerHandler : public DeviceHandlerBase { */ void handleStartup(uint8_t tmType, uint8_t parameterId); + ReturnValue_t statusFieldCheck(const uint8_t* rawFrame); /** * @brief Handles telemtry replies and fills the appropriate dataset * @@ -485,9 +519,16 @@ class StarTrackerHandler : public DeviceHandlerBase { * * @return returnvalue::OK if successful, otherwise error return value */ - ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size, + ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, const char* context); + ReturnValue_t handleAutoBlobTm(const uint8_t* rawFrame); + ReturnValue_t handleMatchedCentroidTm(const uint8_t* rawFrame); + ReturnValue_t handleBlobTm(const uint8_t* rawFrame); + ReturnValue_t handleBlobsTm(const uint8_t* rawFrame); + ReturnValue_t handleCentroidTm(const uint8_t* rawFrame); + ReturnValue_t handleCentroidsTm(const uint8_t* rawFrame); + /** * @brief Checks if star tracker is in valid mode for executing the received command. * diff --git a/mission/acs/str/strHelpers.h b/mission/acs/str/strHelpers.h index c6336186..808d6060 100644 --- a/mission/acs/str/strHelpers.h +++ b/mission/acs/str/strHelpers.h @@ -272,7 +272,50 @@ enum PoolIds : lp_id_t { LOG_SUBSCRIPTION_LEVEL2, LOG_SUBSCRIPTION_MODULE2, DEBUG_CAMERA_TIMING, - DEBUG_CAMERA_TEST + DEBUG_CAMERA_TEST, + + TICKS_AUTO_BLOB, + TIME_AUTO_BLOB, + AUTO_BLOB_THRESHOLD, + + TICKS_MATCHED_CENTROIDS, + TIME_MATCHED_CENTROIDS, + NUM_MATCHED_CENTROIDS, + MATCHED_CENTROIDS_STAR_IDS, + MATCHED_CENTROIDS_X_COORDS, + MATCHED_CENTROIDS_Y_COORDS, + MATCHED_CENTROIDS_X_ERRORS, + MATCHED_CENTROIDS_Y_ERRORS, + + BLOB_TICKS, + BLOB_TIME, + BLOB_COUNT, + + BLOBS_TICKS, + BLOBS_TIME, + BLOBS_COUNT, + BLOBS_COUNT_USED, + BLOBS_NR_4LINES_SKIPPED, + BLOBS_X_COORDS, + BLOBS_Y_COORDS, + + CENTROID_TICKS, + CENTROID_TIME, + CENTROID_COUNT, + + CENTROIDS_TICKS, + CENTROIDS_TIME, + CENTROIDS_COUNT, + CENTROIDS_X_COORDS, + CENTROIDS_Y_COORDS, + CENTROIDS_MAGNITUDES, + + CONTRAST_TICKS, + CONTRAST_TIME, + CONTRAST_A, + CONTRAST_B, + CONTRAST_C, + CONTRAST_D, }; static const DeviceCommandId_t PING_REQUEST = 0; @@ -291,6 +334,7 @@ static const DeviceCommandId_t IMAGE_PROCESSOR = 19; static const DeviceCommandId_t REQ_SOLUTION = 24; static const DeviceCommandId_t REQ_TEMPERATURE = 25; static const DeviceCommandId_t REQ_HISTOGRAM = 28; +static constexpr DeviceCommandId_t REQ_CONTRAST = 29; static const DeviceCommandId_t LIMITS = 40; static const DeviceCommandId_t MOUNTING = 41; static const DeviceCommandId_t CAMERA = 42; @@ -328,6 +372,15 @@ static const DeviceCommandId_t DISABLE_TIMESTAMP_GENERATION = 85; static const DeviceCommandId_t ENABLE_TIMESTAMP_GENERATION = 86; static constexpr DeviceCommandId_t SET_TIME_FROM_SYS_TIME = 87; static constexpr DeviceCommandId_t AUTO_THRESHOLD = 88; +static constexpr DeviceCommandId_t REQ_AUTO_BLOB = 89; +static constexpr DeviceCommandId_t REQ_MATCHED_CENTROIDS = 90; +static constexpr DeviceCommandId_t REQ_BLOB = 91; +static constexpr DeviceCommandId_t REQ_BLOBS = 92; +static constexpr DeviceCommandId_t REQ_CENTROID = 93; +static constexpr DeviceCommandId_t REQ_CENTROIDS = 94; +static constexpr DeviceCommandId_t ADD_SECONDARY_TM_TO_NORMAL_MODE = 95; +static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96; +static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97; static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const uint32_t VERSION_SET_ID = REQ_VERSION; @@ -352,6 +405,13 @@ static const uint32_t ALGO_SET_ID = REQ_ALGO; static const uint32_t SUBSCRIPTION_SET_ID = REQ_SUBSCRIPTION; static const uint32_t LOG_SUBSCRIPTION_SET_ID = REQ_LOG_SUBSCRIPTION; static const uint32_t DEBUG_CAMERA_SET_ID = REQ_DEBUG_CAMERA; +static const uint32_t AUTO_BLOB_SET_ID = REQ_AUTO_BLOB; +static const uint32_t MATCHED_CENTROIDS_SET_ID = REQ_MATCHED_CENTROIDS; +static const uint32_t BLOB_SET_ID = REQ_BLOB; +static const uint32_t BLOBS_SET_ID = REQ_BLOBS; +static const uint32_t CENTROID_SET_ID = REQ_CENTROID; +static const uint32_t CENTROIDS_SET_ID = REQ_CENTROIDS; +static const uint32_t CONTRAST_SET_ID = REQ_CONTRAST; /** Max size of unencoded frame */ static const size_t MAX_FRAME_SIZE = 1200; @@ -412,6 +472,12 @@ static const uint8_t LOG_LEVEL = 3; static const uint8_t LOG_SUBSCRIPTION = 19; static const uint8_t DEBUG_CAMERA = 20; static const uint8_t AUTO_THRESHOLD = 23; +static constexpr uint8_t BLOB = 25; +static constexpr uint8_t BLOBS = 36; +static constexpr uint8_t CENTROID = 26; +static constexpr uint8_t CENTROIDS = 37; +static constexpr uint8_t AUTO_BLOB = 39; +static constexpr uint8_t MATCHED_CENTROIDS = 40; } // namespace ID namespace Program { @@ -474,8 +540,6 @@ static const uint32_t FLASH_REGION_SIZE = 0x20000; */ class TemperatureSet : public StaticLocalDataSet { public: - static const size_t SIZE = 24; - TemperatureSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, TEMPERATURE_SET_ID) {} TemperatureSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, TEMPERATURE_SET_ID)) {} @@ -505,8 +569,6 @@ class TemperatureSet : public StaticLocalDataSet { */ class VersionSet : public StaticLocalDataSet { public: - static const size_t SIZE = 15; - VersionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, VERSION_SET_ID) {} VersionSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, VERSION_SET_ID)) {} @@ -536,8 +598,6 @@ class VersionSet : public StaticLocalDataSet { */ class InterfaceSet : public StaticLocalDataSet { public: - static const size_t SIZE = 20; - InterfaceSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, REQ_INTERFACE) {} InterfaceSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) {} @@ -565,8 +625,6 @@ class InterfaceSet : public StaticLocalDataSet { */ class PowerSet : public StaticLocalDataSet { public: - static const size_t SIZE = 76; - PowerSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, REQ_INTERFACE) {} PowerSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) {} @@ -630,8 +688,6 @@ class PowerSet : public StaticLocalDataSet { */ class TimeSet : public StaticLocalDataSet { public: - static const size_t SIZE = 24; - TimeSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, TIME_SET_ID) {} TimeSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, TIME_SET_ID)) {} @@ -658,15 +714,13 @@ class TimeSet : public StaticLocalDataSet { */ class SolutionSet : public StaticLocalDataSet { public: - static const size_t SIZE = 79; - 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 + // Unix time stamp lp_var_t timeUs = lp_var_t(sid.objectId, PoolIds::TIME_SOLUTION_SET, this); // Calibrated quaternion (takes into account the mounting quaternion), typically same as // track q values @@ -1381,6 +1435,123 @@ class ValidationSet : public StaticLocalDataSet { } }; +class AutoBlobSet : public StaticLocalDataSet<3> { + public: + AutoBlobSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, AUTO_BLOB_SET_ID) {} + // Ticks timestamp + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::TICKS_AUTO_BLOB, this); + // Unix time stamp + lp_var_t timeUs = lp_var_t(sid.objectId, PoolIds::TIME_AUTO_BLOB, this); + lp_var_t threshold = lp_var_t(sid.objectId, PoolIds::AUTO_BLOB_THRESHOLD, this); + + private: +}; + +class MatchedCentroidsSet : public StaticLocalDataSet<20> { + public: + MatchedCentroidsSet(HasLocalDataPoolIF* owner) + : StaticLocalDataSet(owner, MATCHED_CENTROIDS_SET_ID) {} + MatchedCentroidsSet(object_id_t objectId) + : StaticLocalDataSet(sid_t(objectId, MATCHED_CENTROIDS_SET_ID)) {} + // Ticks timestamp + lp_var_t ticks = + lp_var_t(sid.objectId, PoolIds::TICKS_MATCHED_CENTROIDS, this); + // Unix time stamp + lp_var_t timeUs = + lp_var_t(sid.objectId, PoolIds::TIME_MATCHED_CENTROIDS, this); + lp_var_t numberOfMatchedCentroids = + lp_var_t(sid.objectId, PoolIds::NUM_MATCHED_CENTROIDS, this); + lp_vec_t starIds = + lp_vec_t(sid.objectId, PoolIds::MATCHED_CENTROIDS_STAR_IDS, this); + lp_vec_t xCoords = + lp_vec_t(sid.objectId, PoolIds::MATCHED_CENTROIDS_X_COORDS, this); + lp_vec_t yCoords = + lp_vec_t(sid.objectId, PoolIds::MATCHED_CENTROIDS_Y_COORDS, this); + lp_vec_t xErrors = + lp_vec_t(sid.objectId, PoolIds::MATCHED_CENTROIDS_X_ERRORS, this); + lp_vec_t yErrors = + lp_vec_t(sid.objectId, PoolIds::MATCHED_CENTROIDS_Y_ERRORS, this); + + private: +}; + +class BlobSet : public StaticLocalDataSet<5> { + public: + BlobSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, BLOB_SET_ID) {} + // The blob count received from the Blob Telemetry Set (ID 25) + // Ticks timestamp + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::BLOB_TICKS, this); + // Unix time stamp + lp_var_t timeUs = lp_var_t(sid.objectId, PoolIds::BLOB_TIME, this); + lp_var_t blobCount = lp_var_t(sid.objectId, PoolIds::BLOB_COUNT, this); +}; + +class BlobsSet : public StaticLocalDataSet<10> { + public: + BlobsSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, BLOBS_SET_ID) {} + // Ticks timestamp + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::BLOBS_TICKS, this); + // Unix time stamp + lp_var_t timeUs = lp_var_t(sid.objectId, PoolIds::BLOBS_TIME, this); + lp_var_t blobsCount = lp_var_t(sid.objectId, PoolIds::BLOBS_COUNT, this); + lp_var_t blobsCountUsed = + lp_var_t(sid.objectId, PoolIds::BLOBS_COUNT_USED, this); + lp_var_t nr4LinesSkipped = + lp_var_t(sid.objectId, PoolIds::BLOBS_NR_4LINES_SKIPPED, this); + lp_vec_t xCoords = + lp_vec_t(sid.objectId, PoolIds::BLOBS_X_COORDS, this); + lp_vec_t yCoords = + lp_vec_t(sid.objectId, PoolIds::BLOBS_Y_COORDS, this); +}; + +class CentroidSet : public StaticLocalDataSet<5> { + public: + CentroidSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CENTROID_SET_ID) {} + + // Data received from the Centroid Telemetry Set (ID 26) + // Ticks timestamp + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::CENTROID_TICKS, this); + // Unix time stamp + lp_var_t timeUs = lp_var_t(sid.objectId, PoolIds::CENTROID_TIME, this); + // The centroid count received from the Centroid Telemetry Set (ID 26) + lp_var_t centroidCount = + lp_var_t(sid.objectId, PoolIds::CENTROID_COUNT, this); +}; + +class CentroidsSet : public StaticLocalDataSet<10> { + public: + CentroidsSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CENTROIDS_SET_ID) {} + + // Data received from the Centroids Telemetry Set (ID 37) + lp_var_t ticksCentroidsTm = + lp_var_t(sid.objectId, PoolIds::CENTROIDS_TICKS, this); + // Unix time stamp + lp_var_t timeUsCentroidsTm = + lp_var_t(sid.objectId, PoolIds::CENTROIDS_TIME, this); + lp_var_t centroidsCount = + lp_var_t(sid.objectId, PoolIds::CENTROIDS_COUNT, this); + lp_vec_t centroidsXCoords = + lp_vec_t(sid.objectId, PoolIds::CENTROIDS_X_COORDS, this); + lp_vec_t centroidsYCoords = + lp_vec_t(sid.objectId, PoolIds::CENTROIDS_Y_COORDS, this); + lp_vec_t centroidsMagnitudes = + lp_vec_t(sid.objectId, PoolIds::CENTROIDS_MAGNITUDES, this); +}; + +class ContrastSet : public StaticLocalDataSet<8> { + public: + ContrastSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CONTRAST_SET_ID) {} + + // Data received from the Centroids Telemetry Set (ID 29) + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::CONTRAST_TICKS, this); + // Unix time stamp + lp_var_t timeUs = lp_var_t(sid.objectId, PoolIds::CONTRAST_TIME, this); + lp_vec_t contrastA = lp_vec_t(sid.objectId, PoolIds::CONTRAST_A, this); + lp_vec_t contrastB = lp_vec_t(sid.objectId, PoolIds::CONTRAST_B, this); + lp_vec_t contrastC = lp_vec_t(sid.objectId, PoolIds::CONTRAST_C, this); + lp_vec_t contrastD = lp_vec_t(sid.objectId, PoolIds::CONTRAST_D, this); +}; + /** * @brief Will store the requested algo parameters */ diff --git a/mission/cfdp/CfdpFaultHandler.h b/mission/cfdp/CfdpFaultHandler.h index 565606c6..09ba0847 100644 --- a/mission/cfdp/CfdpFaultHandler.h +++ b/mission/cfdp/CfdpFaultHandler.h @@ -1,28 +1,35 @@ #ifndef MISSION_CFDP_CFDPFAULTHANDLER_H_ #define MISSION_CFDP_CFDPFAULTHANDLER_H_ +#include "defs.h" #include "fsfw/cfdp.h" namespace cfdp { -class EiveFaultHandler : public cfdp::FaultHandlerBase { +class EiveFaultHandler : public cfdp::FaultHandlerBase, public SystemObject { public: + EiveFaultHandler(object_id_t objectId) : SystemObject(objectId) {} + void noticeOfSuspensionCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override { sif::warning << "Notice of suspension detected for transaction " << id << " with condition code: " << cfdp::getConditionCodeString(code) << std::endl; + triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::NOTICE_OF_SUSPENSION, code); } void noticeOfCancellationCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override { sif::warning << "Notice of suspension detected for transaction " << id << " with condition code: " << cfdp::getConditionCodeString(code) << std::endl; + triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::NOTICE_OF_CANCELLATION, code); } void abandonCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override { sif::warning << "Transaction " << id << " was abandoned, condition code : " << cfdp::getConditionCodeString(code) << std::endl; + triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::ABANDON_TRANSACTION, code); } void ignoreCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override { sif::warning << "Fault ignored for transaction " << id << ", condition code: " << cfdp::getConditionCodeString(code) << std::endl; + triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::IGNORE_ERROR, code); } }; diff --git a/mission/cfdp/defs.h b/mission/cfdp/defs.h new file mode 100644 index 00000000..249bec04 --- /dev/null +++ b/mission/cfdp/defs.h @@ -0,0 +1,16 @@ +#ifndef MISSION_CFDP_DEFS_H_ +#define MISSION_CFDP_DEFS_H_ + +#include "eive/eventSubsystemIds.h" +#include "fsfw/events/Event.h" + +namespace cfdp { + +static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CFDP_APP; + +//! [EXPORT] : [COMMENT] P1: CFDP fault handler code. P2: CFDP condition code. +static constexpr Event FAULT_HANDLER_TRIGGERED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); + +} // namespace cfdp + +#endif /* MISSION_CFDP_DEFS_H_ */ diff --git a/mission/controller/PowerController.h b/mission/controller/PowerController.h index 1f27616d..b7c3d1a0 100644 --- a/mission/controller/PowerController.h +++ b/mission/controller/PowerController.h @@ -53,13 +53,13 @@ class PowerController : public ExtendedControllerBase, public ReceivesParameterM ReturnValue_t calculateCoulombCounterChargeUpperThreshold(); // Parameters - float batteryInternalResistance = 70.0 / 2.0 / 1000.0; // [Ohm] - float batteryMaximumCapacity = 2.6 * 2; // [Ah] - float coulombCounterVoltageUpperThreshold = 16.2; // [V] - double maxAllowedTimeDiff = 1.5; // [s] - float payloadOpLimitOn = 0.90; // [%] - float payloadOpLimitLow = 0.75; // [%] - float higherModesLimit = 0.6; // [%] + float batteryInternalResistance = 0.06798200367; // [Ohm] + float batteryMaximumCapacity = 2.6 * 2; // [Ah] + float coulombCounterVoltageUpperThreshold = 16.2; // [V] + double maxAllowedTimeDiff = 1.5; // [s] + float payloadOpLimitOn = 0.90; // [%] + float payloadOpLimitLow = 0.75; // [%] + float higherModesLimit = 0.6; // [%] // OCV Look-up-Table {[Ah],[V]} static constexpr uint8_t LOOK_UP_TABLE_MAX_IDX = 99; diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 25b59f9b..47cb1a5f 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -86,7 +86,6 @@ EntityId REMOTE_CFDP_ID(UnsignedByteField(config::EIVE_GROUND_CFDP_ENT RemoteEntityCfg GROUND_REMOTE_CFG(REMOTE_CFDP_ID); OneRemoteConfigProvider REMOTE_CFG_PROVIDER(GROUND_REMOTE_CFG); HostFilesystem HOST_FS; -EiveFaultHandler EIVE_FAULT_HANDLER; } // namespace cfdp @@ -290,7 +289,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun cfdp::EntityId localId(apid); GROUND_REMOTE_CFG.defaultChecksum = cfdp::ChecksumType::CRC_32; GROUND_REMOTE_CFG.maxFileSegmentLen = config::CFDP_MAX_FILE_SEGMENT_LEN; - CfdpHandlerCfg cfdpCfg(localId, indicationCfg, *eiveUserHandler, EIVE_FAULT_HANDLER, PACKET_LIST, + auto eiveFaultHandler = new EiveFaultHandler(objects::CFDP_FAULT_HANDLER); + CfdpHandlerCfg cfdpCfg(localId, indicationCfg, *eiveUserHandler, *eiveFaultHandler, PACKET_LIST, LOST_SEGMENTS, REMOTE_CFG_PROVIDER); auto* cfdpHandler = new CfdpHandler(params, cfdpCfg, signals::CFDP_CHANNEL_THROTTLE_SIGNAL); // All CFDP packets arrive wrapped inside CCSDS space packets diff --git a/mission/payload/PayloadPcduHandler.cpp b/mission/payload/PayloadPcduHandler.cpp index bda15b20..b3b71aea 100644 --- a/mission/payload/PayloadPcduHandler.cpp +++ b/mission/payload/PayloadPcduHandler.cpp @@ -395,7 +395,6 @@ void PayloadPcduHandler::quickTransitionBackToOff(bool startTransitionToOff, boo void PayloadPcduHandler::checkAdcValues() { using namespace plpcdu; - checkJsonFileInit(); adcSet.processed[U_BAT_DIV_6] = static_cast(adcSet.channels[0]) * VOLTAGE_DIV / MAX122X_BIT * MAX122X_VREF; adcSet.processed[U_NEG_V_FB] = @@ -529,6 +528,10 @@ void PayloadPcduHandler::checkJsonFileInit() { params.initialize(sdcMan->getCurrentMountPrefix()); jsonFileInitComplete = true; } + } else { + if (not sdcMan->isSdCardUsable(std::nullopt)) { + jsonFileInitComplete = false; + } } } @@ -564,6 +567,13 @@ bool PayloadPcduHandler::checkCurrent(float val, float upperBound, Event event) return true; } +ReturnValue_t PayloadPcduHandler::initialize() { + checkJsonFileInit(); + return DeviceHandlerBase::initialize(); +} + +void PayloadPcduHandler::performOperationHook() { checkJsonFileInit(); } + ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, uint32_t* msToReachTheMode) { if (commandedMode != MODE_OFF) { diff --git a/mission/payload/PayloadPcduHandler.h b/mission/payload/PayloadPcduHandler.h index a4574f53..d48d0f89 100644 --- a/mission/payload/PayloadPcduHandler.h +++ b/mission/payload/PayloadPcduHandler.h @@ -67,7 +67,9 @@ class PayloadPcduHandler : public DeviceHandlerBase { SdCardMountedIF* sdcMan, Stack5VHandler& stackHandler, bool periodicPrintout); void setToGoToNormalModeImmediately(bool enable); + void performOperationHook() override; void enablePeriodicPrintout(bool enable, uint8_t divider); + ReturnValue_t initialize() override; #ifdef XIPHOS_Q7S static ReturnValue_t extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie, diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index 0df0fc95..cd450502 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -70,6 +70,9 @@ void EiveSystem::performChildOperation() { } pdecRecoveryLogic(); i2cRecoveryLogic(); + if (forcePlOffState != ForcePlOffState::NONE) { + forceOffPayload(); + } } ReturnValue_t EiveSystem::initialize() { @@ -203,10 +206,14 @@ void EiveSystem::handleEventMessages() { break; } case power::POWER_LEVEL_LOW: { - forceOffPayload(); + forcePlOffState = ForcePlOffState::FORCE_ALL_EXCEPT_SUPV_OFF; break; } - case power::POWER_LEVEL_CRITICAL: + case power::POWER_LEVEL_CRITICAL: { + // Force payload off in any case. It really should not be on when the power level + // becomes critical, but better be safe than sorry.. + forcePlOffState = ForcePlOffState::FORCE_ALL_EXCEPT_SUPV_OFF; + // Also set the STR assembly to faulty, which should cause a fallback to SAFE mode. CommandMessage msg; HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY); ReturnValue_t result = MessageQueueSenderIF::sendMessage( @@ -216,6 +223,7 @@ void EiveSystem::handleEventMessages() { << std::endl; } break; + } } break; default: @@ -403,37 +411,45 @@ void EiveSystem::pdecRecoveryLogic() { void EiveSystem::forceOffPayload() { CommandMessage msg; + ReturnValue_t result; // set PL to faulty HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY); - ReturnValue_t result = commandQueue->sendMessage(plPcduQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PL PCDU failed" << std::endl; + if (forcePlOffState == ForcePlOffState::FORCE_ALL_EXCEPT_SUPV_OFF) { + result = commandQueue->sendMessage(plocMpsocQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PLOC MPSOC failed" << std::endl; + } + result = commandQueue->sendMessage(cameraQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PL CAM failed" << std::endl; + } + result = commandQueue->sendMessage(scexQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to SCEX failed" << std::endl; + } + result = commandQueue->sendMessage(radSensorQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to RAD SENSOR failed" << std::endl; + } + result = commandQueue->sendMessage(plPcduQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PL PCDU failed" << std::endl; + } + forcePlOffState = ForcePlOffState::WAITING; + supvOffDelay.resetTimer(); } - result = commandQueue->sendMessage(plocMpsocQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PLOC MPSOC failed" << std::endl; + if (forcePlOffState == ForcePlOffState::WAITING and supvOffDelay.hasTimedOut()) { + forcePlOffState = ForcePlOffState::FORCE_SUPV_OFF; } - result = commandQueue->sendMessage(plocSupervisorQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PLOC SUPERVISOR failed" << std::endl; - } - - result = commandQueue->sendMessage(cameraQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to PL CAM failed" << std::endl; - } - - result = commandQueue->sendMessage(scexQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to SCEX failed" << std::endl; - } - - result = commandQueue->sendMessage(radSensorQueueId, &msg); - if (result != returnvalue::OK) { - sif::error << "EIVE System: Sending FAULTY command to RAD SENSOR failed" << std::endl; + if (forcePlOffState == ForcePlOffState::FORCE_SUPV_OFF) { + result = commandQueue->sendMessage(plocSupervisorQueueId, &msg); + if (result != returnvalue::OK) { + sif::error << "EIVE System: Sending FAULTY command to PLOC SUPERVISOR failed" << std::endl; + } + forcePlOffState = ForcePlOffState::NONE; } } diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index 78f8bdc9..fed5791a 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -22,6 +22,12 @@ class EiveSystem : public Subsystem, public HasActionsIF { [[nodiscard]] MessageQueueId_t getCommandQueue() const override; private: + enum class ForcePlOffState { + NONE, + FORCE_ALL_EXCEPT_SUPV_OFF, + WAITING, + FORCE_SUPV_OFF + } forcePlOffState = ForcePlOffState::NONE; enum class I2cRebootState { NONE, SYSTEM_MODE_BOOT, @@ -37,6 +43,7 @@ class EiveSystem : public Subsystem, public HasActionsIF { bool alreadyTriedI2cRecovery = false; uint8_t frameDirtyErrorCounter = 0; + Countdown supvOffDelay = Countdown(3000); Countdown frameDirtyCheckCd = Countdown(10000); // If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that // only a full reboot will fix the issue. diff --git a/tmtc b/tmtc index 728b7c64..92fe9d92 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 728b7c647cf826d0dd751126935c1cb559aa16ee +Subproject commit 92fe9d92def31d2f9d1c8cefe0ce4f244bcd1702