Merge branch 'develop' into acs-ctrl-finite-check
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
Marius Eggert 2023-03-21 11:30:26 +01:00
commit a92f664770
40 changed files with 589 additions and 386 deletions

View File

@ -23,9 +23,41 @@ will consitute of a breaking change warranting a new major release:
to look into the reason of wrong outputs. To restore the reset ability, an action command has to look into the reason of wrong outputs. To restore the reset ability, an action command has
been added. been added.
## Fixed
- Fixed transition for dual power lane assemblies: When going from dual side submode to single side
submode, perform logical commanding first, similarly to when going to OFF mode.
## Changed
- Bugfixes for STR mode transitions: Booting to mode ON with submode FIRMWARE now works properly.
Furthermore, the submode in the NORMAL mode now should be 0 instead of some ON mode submode.
- Updated GYR bias values to newest measurements. This also corrects the ADIS values to always
consit of just one digit.
# [v1.38.0] 2023-03-17
eive-tmtc: v2.19.2
## Fixed
- SA deployment file handling: Use exceptionless API.
- Fix deadlock in SD card manager constructor: Double lock of preferred SD card lock.
## Added
- Failure of Safe Mode Ctrl will now trigger an event. As this can only be caused by sensors not
being in the correct mode, the assemblies should take care that this will never happen and no
additional FDIR is needed.
## Changed ## Changed
- Telemetry relevant datasets for the RWs are now set invalid and partially reset on shotdown. - Telemetry relevant datasets for the RWs are now set invalid and partially reset on shotdown.
- I2C PST now has a polling frequency of 0.4 seconds instead of 0.2 seconds.
- GS PST now has a polling frequency of 0.5 seconds instead of 1 second.
- Bump FSFW: merged upstream.
- Move BPX battery scheduling to ACS PST to avoid clashes with IMTQ scheduling / polling
# [v1.37.2] 2023-03-14 # [v1.37.2] 2023-03-14
@ -41,6 +73,8 @@ eive-tmtc: v2.19.1
## Added ## Added
- Added `EXECUTE_SHELL_CMD` action command for `CoreController` to execute arbitrary Linux commands. - Added `EXECUTE_SHELL_CMD` action command for `CoreController` to execute arbitrary Linux commands.
- Added some missing PLOC commands.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/462
- Add `PcduHandlerDummy` component. - Add `PcduHandlerDummy` component.
- Added parameter for timeout until `MEKF_INVALID_MODE_VIOLATION` event is triggered. - Added parameter for timeout until `MEKF_INVALID_MODE_VIOLATION` event is triggered.
@ -64,6 +98,17 @@ eive-tmtc: v2.19.1
- Set `OBSW_ADD_TCS_CTRL` to 1. Always add TCS controller now for both EM and FM. - Set `OBSW_ADD_TCS_CTRL` to 1. Always add TCS controller now for both EM and FM.
- generators module: Bump `fsfwgen` dependency to v0.3.1. The returnvalue CSV files are now sorted. - generators module: Bump `fsfwgen` dependency to v0.3.1. The returnvalue CSV files are now sorted.
- generators module: Always generate subsystem ID CSV files now. - generators module: Always generate subsystem ID CSV files now.
- The COM subsystem is now not commanded by the EIVE system anymore. Instead,
a separate RX_ONLY mode command will be sent at OBSW boot. After that,
commanding is done autonomously by the COM subsystem internally or by the operator. This prevents
the transmitter from going off during fallbacks to the SAFE mode, which might not always be
desired.
- Initialize switch states to a special `SWITCH_STATE_UNKNOWN` (2) variable. Return
`PowerSwitchIF::SWITCH_UNKNOWN` in switch state getter if this is the state.
- Wait 1 second before commanding SAFE mode. This ensures or at least increases the chance that
the switch states were initialized.
- Dual Lane Assemblies: The returnvalues of the dual lane power state machine FSM are not ignored
anymore.
# [v1.37.0] 2023-03-11 # [v1.37.0] 2023-03-11

View File

@ -10,8 +10,8 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 1) set(OBSW_VERSION_MAJOR 1)
set(OBSW_VERSION_MINOR 37) set(OBSW_VERSION_MINOR 38)
set(OBSW_VERSION_REVISION 2) set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE) # set(CMAKE_VERBOSE TRUE)

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 277 translations. * @brief Auto-generated event translation file. Contains 278 translations.
* @details * @details
* Generated on: 2023-03-15 09:39:13 * Generated on: 2023-03-15 10:10:04
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID"; const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION"; const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -464,6 +465,8 @@ const char *translateEvents(Event event) {
return MEKF_INVALID_INFO_STRING; return MEKF_INVALID_INFO_STRING;
case (11204): case (11204):
return MEKF_INVALID_MODE_VIOLATION_STRING; return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11205):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):

View File

@ -77,6 +77,8 @@ using gpio::Levels;
#include <mission/devices/GyrAdis1650XHandler.h> #include <mission/devices/GyrAdis1650XHandler.h>
#include <mission/devices/ImtqHandler.h> #include <mission/devices/ImtqHandler.h>
#include <mission/devices/PcduHandler.h> #include <mission/devices/PcduHandler.h>
#include <mission/devices/Pdu1Handler.h>
#include <mission/devices/Pdu2Handler.h>
#include <mission/devices/SyrlinksHandler.h> #include <mission/devices/SyrlinksHandler.h>
#include <mission/devices/devicedefinitions/rwHelpers.h> #include <mission/devices/devicedefinitions/rwHelpers.h>
#include <mission/tmtc/VirtualChannelWithQueue.h> #include <mission/tmtc/VirtualChannelWithQueue.h>
@ -105,8 +107,6 @@ using gpio::Levels;
#include "mission/devices/HeaterHandler.h" #include "mission/devices/HeaterHandler.h"
#include "mission/devices/Max31865PT1000Handler.h" #include "mission/devices/Max31865PT1000Handler.h"
#include "mission/devices/P60DockHandler.h" #include "mission/devices/P60DockHandler.h"
#include "mission/devices/PDU1Handler.h"
#include "mission/devices/PDU2Handler.h"
#include "mission/devices/PayloadPcduHandler.h" #include "mission/devices/PayloadPcduHandler.h"
#include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RadiationSensorHandler.h"
#include "mission/devices/RwHandler.h" #include "mission/devices/RwHandler.h"
@ -196,17 +196,17 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie, p60Fdir); new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie, p60Fdir);
auto pdu1Fdir = new GomspacePowerFdir(objects::PDU1_HANDLER); auto pdu1Fdir = new GomspacePowerFdir(objects::PDU1_HANDLER);
PDU1Handler* pdu1handler = Pdu1Handler* pdu1handler =
new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie, pdu1Fdir); new Pdu1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie, pdu1Fdir);
auto pdu2Fdir = new GomspacePowerFdir(objects::PDU2_HANDLER); auto pdu2Fdir = new GomspacePowerFdir(objects::PDU2_HANDLER);
PDU2Handler* pdu2handler = Pdu2Handler* pdu2handler =
new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie, pdu2Fdir); new Pdu2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie, pdu2Fdir);
auto acuFdir = new GomspacePowerFdir(objects::ACU_HANDLER); auto acuFdir = new GomspacePowerFdir(objects::ACU_HANDLER);
ACUHandler* acuhandler = ACUHandler* acuhandler =
new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie, acuFdir); new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie, acuFdir);
auto pcduHandler = new PCDUHandler(objects::PCDU_HANDLER, 50); auto pcduHandler = new PcduHandler(objects::PCDU_HANDLER, 50);
/** /**
* Setting PCDU devices to mode normal immediately after start up because PCDU is always * Setting PCDU devices to mode normal immediately after start up because PCDU is always

View File

@ -486,8 +486,8 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction
#if OBSW_ADD_I2C_TEST_CODE == 0 #if OBSW_ADD_I2C_TEST_CODE == 0
FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask( FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask(
"I2C_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); "I2C_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.4, missedDeadlineFunc);
result = pst::pstI2c(i2cPst); result = pst::pstI2cProcessingSystem(i2cPst);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {
sif::warning << "scheduling::initTasks: I2C PST is empty" << std::endl; sif::warning << "scheduling::initTasks: I2C PST is empty" << std::endl;
@ -500,7 +500,7 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction
#endif #endif
FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask( FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask(
"GS_PST_TASK", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc); "GS_PST_TASK", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc);
result = pst::pstGompaceCan(gomSpacePstTask); result = pst::pstGompaceCan(gomSpacePstTask);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {

View File

@ -37,7 +37,6 @@ SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor
sif::warning << "CoreController::sdCardInit: " sif::warning << "CoreController::sdCardInit: "
"Preferred SD card not set. Setting to 0" "Preferred SD card not set. Setting to 0"
<< std::endl; << std::endl;
setPreferredSdCard(sd::SdCard::SLOT_0);
scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sd::SdCard::SLOT_0)); scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sd::SdCard::SLOT_0));
prefSdRaw = sd::SdCard::SLOT_0; prefSdRaw = sd::SdCard::SLOT_0;

View File

@ -15,6 +15,7 @@
#include "fsfw/tasks/TaskFactory.h" #include "fsfw/tasks/TaskFactory.h"
#include "fsfw/version.h" #include "fsfw/version.h"
#include "mission/acsDefs.h" #include "mission/acsDefs.h"
#include "mission/comDefs.h"
#include "mission/system/tree/system.h" #include "mission/system/tree/system.h"
#include "q7sConfig.h" #include "q7sConfig.h"
#include "watchdog/definitions.h" #include "watchdog/definitions.h"
@ -66,6 +67,9 @@ int obsw::obsw(int argc, char* argv[]) {
// Command the EIVE system to safe mode // Command the EIVE system to safe mode
#if OBSW_COMMAND_SAFE_MODE_AT_STARTUP == 1 #if OBSW_COMMAND_SAFE_MODE_AT_STARTUP == 1
// This ensures that the PCDU switches were updated.
TaskFactory::delayTask(1000);
commandComSubsystemRxOnly();
commandEiveSystemToSafe(); commandEiveSystemToSafe();
#else #else
announceAllModes(); announceAllModes();
@ -116,7 +120,22 @@ void obsw::commandEiveSystemToSafe() {
ReturnValue_t result = ReturnValue_t result =
MessageQueueSenderIF::sendMessage(sysQueueId, &msg, MessageQueueIF::NO_QUEUE, false); MessageQueueSenderIF::sendMessage(sysQueueId, &msg, MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "Sending safe mode command to EIVE system failed" << std::endl; sif::error << "obsw: Sending safe mode command to EIVE system failed" << std::endl;
}
}
void obsw::commandComSubsystemRxOnly() {
auto* comSs = ObjectManager::instance()->get<HasModesIF>(objects::COM_SUBSYSTEM);
if (comSs == nullptr) {
sif::error << "obsw: Could not retrieve COM subsystem object" << std::endl;
return;
}
CommandMessage msg;
ModeMessage::setCmdModeMessage(msg, com::RX_ONLY, 0);
ReturnValue_t result = MessageQueueSenderIF::sendMessage(comSs->getCommandQueue(), &msg,
MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) {
sif::error << "obsw: Sending RX_ONLY mode command to COM subsystem failed" << std::endl;
} }
} }
@ -127,6 +146,6 @@ void obsw::announceAllModes() {
ReturnValue_t result = ReturnValue_t result =
MessageQueueSenderIF::sendMessage(sysQueueId, &msg, MessageQueueIF::NO_QUEUE, false); MessageQueueSenderIF::sendMessage(sysQueueId, &msg, MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "Sending safe mode command to EIVE system failed" << std::endl; sif::error << "obsw: Sending safe mode command to EIVE system failed" << std::endl;
} }
} }

View File

@ -7,6 +7,7 @@ int obsw(int argc, char* argv[]);
void bootDelayHandling(); void bootDelayHandling();
void commandEiveSystemToSafe(); void commandEiveSystemToSafe();
void commandComSubsystemRxOnly();
void announceAllModes(); void announceAllModes();
}; // namespace obsw }; // namespace obsw

2
fsfw

@ -1 +1 @@
Subproject commit cf27954a867a1c16b4e5b0fe72cd79df946ff903 Subproject commit 227524a21da755d125bcb1a5ff67bcbc452f8cf9

View File

@ -91,6 +91,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acsDefs.h 11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acsDefs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acsDefs.h 11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acsDefs.h
11204;0x2bc4;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acsDefs.h 11204;0x2bc4;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acsDefs.h
11205;0x2bc5;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acsDefs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/devices/devicedefinitions/powerDefinitions.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/devices/devicedefinitions/powerDefinitions.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
91 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH No description mission/acsDefs.h
92 11203 0x2bc3 MEKF_INVALID_INFO INFO No description mission/acsDefs.h
93 11204 0x2bc4 MEKF_INVALID_MODE_VIOLATION HIGH No description mission/acsDefs.h
94 11205 0x2bc5 SAFE_MODE_CONTROLLER_FAILURE HIGH No description mission/acsDefs.h
95 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
96 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
97 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/devices/devicedefinitions/powerDefinitions.h

View File

@ -91,6 +91,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acsDefs.h 11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acsDefs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acsDefs.h 11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acsDefs.h
11204;0x2bc4;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acsDefs.h 11204;0x2bc4;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acsDefs.h
11205;0x2bc5;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acsDefs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/devices/devicedefinitions/powerDefinitions.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/devices/devicedefinitions/powerDefinitions.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
91 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH No description mission/acsDefs.h
92 11203 0x2bc3 MEKF_INVALID_INFO INFO No description mission/acsDefs.h
93 11204 0x2bc4 MEKF_INVALID_MODE_VIOLATION HIGH No description mission/acsDefs.h
94 11205 0x2bc5 SAFE_MODE_CONTROLLER_FAILURE HIGH No description mission/acsDefs.h
95 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
96 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
97 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/devices/devicedefinitions/powerDefinitions.h

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 277 translations. * @brief Auto-generated event translation file. Contains 278 translations.
* @details * @details
* Generated on: 2023-03-15 09:39:13 * Generated on: 2023-03-15 10:10:04
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID"; const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION"; const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -464,6 +465,8 @@ const char *translateEvents(Event event) {
return MEKF_INVALID_INFO_STRING; return MEKF_INVALID_INFO_STRING;
case (11204): case (11204):
return MEKF_INVALID_MODE_VIOLATION_STRING; return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11205):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):

View File

@ -451,95 +451,99 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
cdHasTimedOut = gyro.countdown.hasTimedOut(); cdHasTimedOut = gyro.countdown.hasTimedOut();
mustPerformStartup = gyro.performStartup; mustPerformStartup = gyro.performStartup;
} }
if (mode == acs::SimpleSensorMode::NORMAL and cdHasTimedOut) { if (mode == acs::SimpleSensorMode::OFF) {
if (mustPerformStartup) { return;
uint8_t regList[6]; }
// Read configuration if (not cdHasTimedOut) {
regList[0] = adis1650x::DIAG_STAT_REG; return;
regList[1] = adis1650x::FILTER_CTRL_REG; }
regList[2] = adis1650x::RANG_MDL_REG; if (mustPerformStartup) {
regList[3] = adis1650x::MSC_CTRL_REG; uint8_t regList[6];
regList[4] = adis1650x::DEC_RATE_REG; // Read configuration
regList[5] = adis1650x::PROD_ID_REG; regList[0] = adis1650x::DIAG_STAT_REG;
size_t transferLen = regList[1] = adis1650x::FILTER_CTRL_REG;
adis1650x::prepareReadCommand(regList, sizeof(regList), cmdBuf.data(), cmdBuf.size()); regList[2] = adis1650x::RANG_MDL_REG;
result = readAdisCfg(*gyro.cookie, transferLen); regList[3] = adis1650x::MSC_CTRL_REG;
if (result != returnvalue::OK) { regList[4] = adis1650x::DEC_RATE_REG;
gyro.replyResult = result; regList[5] = adis1650x::PROD_ID_REG;
return; size_t transferLen =
} adis1650x::prepareReadCommand(regList, sizeof(regList), cmdBuf.data(), cmdBuf.size());
result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy); result = readAdisCfg(*gyro.cookie, transferLen);
if (result != returnvalue::OK or rawReply == nullptr) {
gyro.replyResult = result;
return;
}
uint16_t prodId = (rawReply[12] << 8) | rawReply[13];
if (((gyro.type == adis1650x::Type::ADIS16505) and (prodId != adis1650x::PROD_ID_16505)) or
((gyro.type == adis1650x::Type::ADIS16507) and (prodId != adis1650x::PROD_ID_16507))) {
sif::warning << "AcsPollingTask: Invalid ADIS product ID " << prodId << std::endl;
gyro.replyResult = returnvalue::FAILED;
return;
}
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
gyro.ownReply.cfgWasSet = true;
gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3];
gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5];
gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7];
gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9];
gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11];
gyro.ownReply.cfg.prodId = prodId;
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
gyro.performStartup = false;
}
// Read regular registers
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
adis1650x::BURST_READ_ENABLE.size());
std::memset(cmdBuf.data() + 2, 0, 10 * 2);
result = spiComIF.sendMessage(gyro.cookie, cmdBuf.data(), adis1650x::SENSOR_READOUT_SIZE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
gyro.replyResult = returnvalue::FAILED; gyro.replyResult = result;
return; return;
} }
result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy); result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy);
if (result != returnvalue::OK or rawReply == nullptr) { if (result != returnvalue::OK or rawReply == nullptr) {
gyro.replyResult = result;
return;
}
uint16_t prodId = (rawReply[12] << 8) | rawReply[13];
if (((gyro.type == adis1650x::Type::ADIS16505) and (prodId != adis1650x::PROD_ID_16505)) or
((gyro.type == adis1650x::Type::ADIS16507) and (prodId != adis1650x::PROD_ID_16507))) {
sif::warning << "AcsPollingTask: Invalid ADIS product ID " << prodId << std::endl;
gyro.replyResult = returnvalue::FAILED; gyro.replyResult = returnvalue::FAILED;
return; return;
} }
uint16_t checksum = (rawReply[20] << 8) | rawReply[21];
// Now verify the read checksum with the expected checksum according to datasheet p. 20
uint16_t calcChecksum = 0;
for (size_t idx = 2; idx < 20; idx++) {
calcChecksum += rawReply[idx];
}
if (checksum != calcChecksum) {
sif::warning << "AcsPollingTask: Invalid ADIS reply checksum" << std::endl;
gyro.replyResult = returnvalue::FAILED;
return;
}
auto burstMode = adis1650x::burstModeFromMscCtrl(gyro.ownReply.cfg.mscCtrlReg);
if (burstMode != adis1650x::BurstModes::BURST_16_BURST_SEL_0) {
sif::error << "GyroADIS1650XHandler::interpretDeviceReply: Analysis for select burst mode"
" not implemented!"
<< std::endl;
gyro.replyResult = returnvalue::FAILED;
return;
}
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
gyro.ownReply.dataWasSet = true; gyro.ownReply.cfgWasSet = true;
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3]; gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3];
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5]; gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5];
gyro.ownReply.data.angVelocities[1] = (rawReply[6] << 8) | rawReply[7]; gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7];
gyro.ownReply.data.angVelocities[2] = (rawReply[8] << 8) | rawReply[9]; gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9];
gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11];
gyro.ownReply.data.accelerations[0] = (rawReply[10] << 8) | rawReply[11]; gyro.ownReply.cfg.prodId = prodId;
gyro.ownReply.data.accelerations[1] = (rawReply[12] << 8) | rawReply[13]; gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
gyro.ownReply.data.accelerations[2] = (rawReply[14] << 8) | rawReply[15]; gyro.performStartup = false;
gyro.ownReply.data.temperatureRaw = (rawReply[16] << 8) | rawReply[17];
} }
// Read regular registers
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
adis1650x::BURST_READ_ENABLE.size());
std::memset(cmdBuf.data() + 2, 0, 10 * 2);
result = spiComIF.sendMessage(gyro.cookie, cmdBuf.data(), adis1650x::SENSOR_READOUT_SIZE);
if (result != returnvalue::OK) {
gyro.replyResult = returnvalue::FAILED;
return;
}
result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy);
if (result != returnvalue::OK or rawReply == nullptr) {
gyro.replyResult = returnvalue::FAILED;
return;
}
uint16_t checksum = (rawReply[20] << 8) | rawReply[21];
// Now verify the read checksum with the expected checksum according to datasheet p. 20
uint16_t calcChecksum = 0;
for (size_t idx = 2; idx < 20; idx++) {
calcChecksum += rawReply[idx];
}
if (checksum != calcChecksum) {
sif::warning << "AcsPollingTask: Invalid ADIS reply checksum" << std::endl;
gyro.replyResult = returnvalue::FAILED;
return;
}
auto burstMode = adis1650x::burstModeFromMscCtrl(gyro.ownReply.cfg.mscCtrlReg);
if (burstMode != adis1650x::BurstModes::BURST_16_BURST_SEL_0) {
sif::error << "GyroADIS1650XHandler::interpretDeviceReply: Analysis for select burst mode"
" not implemented!"
<< std::endl;
gyro.replyResult = returnvalue::FAILED;
return;
}
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
gyro.ownReply.dataWasSet = true;
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3];
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5];
gyro.ownReply.data.angVelocities[1] = (rawReply[6] << 8) | rawReply[7];
gyro.ownReply.data.angVelocities[2] = (rawReply[8] << 8) | rawReply[9];
gyro.ownReply.data.accelerations[0] = (rawReply[10] << 8) | rawReply[11];
gyro.ownReply.data.accelerations[1] = (rawReply[12] << 8) | rawReply[13];
gyro.ownReply.data.accelerations[2] = (rawReply[14] << 8) | rawReply[15];
gyro.ownReply.data.temperatureRaw = (rawReply[16] << 8) | rawReply[17];
} }
void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) { void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {

View File

@ -268,18 +268,18 @@ void StarTrackerHandler::doStartUp() {
default: default:
return; return;
} }
setMode(_MODE_TO_ON, SUBMODE_BOOTLOADER); startupState = StartupState::DONE;
internalState = InternalState::IDLE;
setMode(_MODE_TO_ON);
} }
void StarTrackerHandler::doShutDown() { void StarTrackerHandler::doShutDown() {
// If the star tracker is shutdown also stop all running processes in the image loader task // If the star tracker is shutdown also stop all running processes in the image loader task
strHelper->stopProcess(); strHelper->stopProcess();
setMode(_MODE_POWER_DOWN);
}
void StarTrackerHandler::doOffActivity() {
startupState = StartupState::IDLE;
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
startupState = StartupState::IDLE;
bootState = FwBootState::NONE;
setMode(_MODE_POWER_DOWN);
} }
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
@ -302,81 +302,103 @@ ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id
ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
switch (internalState) { switch (internalState) {
case InternalState::BOOT: case InternalState::BOOT_FIRMWARE: {
*id = startracker::BOOT; if (bootState == FwBootState::WAIT_FOR_EXECUTION or bootState == FwBootState::VERIFY_BOOT) {
bootCountdown.setTimeout(BOOT_TIMEOUT); return NOTHING_TO_SEND;
internalState = InternalState::BOOT_DELAY; }
return buildCommandFromCommand(*id, nullptr, 0); if (bootState == FwBootState::NONE) {
case InternalState::REQ_VERSION: *id = startracker::BOOT;
internalState = InternalState::VERIFY_BOOT; bootCountdown.setTimeout(BOOT_TIMEOUT);
// Again read program to check if firmware boot was successful bootState = FwBootState::BOOT_DELAY;
*id = startracker::REQ_VERSION; return buildCommandFromCommand(*id, nullptr, 0);
return buildCommandFromCommand(*id, nullptr, 0); }
case InternalState::LOGLEVEL: if (bootState == FwBootState::BOOT_DELAY) {
internalState = InternalState::WAIT_FOR_EXECUTION; if (bootCountdown.isBusy()) {
*id = startracker::LOGLEVEL; return NOTHING_TO_SEND;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), }
paramJsonFile.size()); bootState = FwBootState::REQ_VERSION;
case InternalState::LIMITS: }
internalState = InternalState::WAIT_FOR_EXECUTION; switch (bootState) {
*id = startracker::LIMITS; case (FwBootState::REQ_VERSION): {
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), bootState = FwBootState::VERIFY_BOOT;
paramJsonFile.size()); // Again read program to check if firmware boot was successful
case InternalState::TRACKING: *id = startracker::REQ_VERSION;
internalState = InternalState::WAIT_FOR_EXECUTION; return buildCommandFromCommand(*id, nullptr, 0);
*id = startracker::TRACKING; }
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), case (FwBootState::LOGLEVEL): {
paramJsonFile.size()); bootState = FwBootState::WAIT_FOR_EXECUTION;
case InternalState::MOUNTING: *id = startracker::LOGLEVEL;
internalState = InternalState::WAIT_FOR_EXECUTION; return buildCommandFromCommand(
*id = startracker::MOUNTING; *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), }
paramJsonFile.size()); case (FwBootState::LIMITS): {
case InternalState::IMAGE_PROCESSOR: bootState = FwBootState::WAIT_FOR_EXECUTION;
internalState = InternalState::WAIT_FOR_EXECUTION; *id = startracker::LIMITS;
*id = startracker::IMAGE_PROCESSOR; return buildCommandFromCommand(
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
paramJsonFile.size()); }
case InternalState::CAMERA: case (FwBootState::TRACKING): {
internalState = InternalState::WAIT_FOR_EXECUTION; bootState = FwBootState::WAIT_FOR_EXECUTION;
*id = startracker::CAMERA; *id = startracker::TRACKING;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), return buildCommandFromCommand(
paramJsonFile.size()); *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
case InternalState::CENTROIDING: }
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::MOUNTING:
*id = startracker::CENTROIDING; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::MOUNTING;
paramJsonFile.size()); return buildCommandFromCommand(
case InternalState::LISA: *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::IMAGE_PROCESSOR:
*id = startracker::LISA; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::IMAGE_PROCESSOR;
paramJsonFile.size()); return buildCommandFromCommand(
case InternalState::MATCHING: *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::CAMERA:
*id = startracker::MATCHING; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::CAMERA;
paramJsonFile.size()); return buildCommandFromCommand(
case InternalState::VALIDATION: *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::CENTROIDING:
*id = startracker::VALIDATION; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::CENTROIDING;
paramJsonFile.size()); return buildCommandFromCommand(
case InternalState::ALGO: *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::LISA:
*id = startracker::ALGO; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::LISA;
paramJsonFile.size()); return buildCommandFromCommand(
case InternalState::LOG_SUBSCRIPTION: *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::MATCHING:
*id = startracker::LOGSUBSCRIPTION; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::MATCHING;
paramJsonFile.size()); return buildCommandFromCommand(
case InternalState::DEBUG_CAMERA: *id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
internalState = InternalState::WAIT_FOR_EXECUTION; case FwBootState::VALIDATION:
*id = startracker::DEBUG_CAMERA; bootState = FwBootState::WAIT_FOR_EXECUTION;
return buildCommandFromCommand(*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), *id = startracker::VALIDATION;
paramJsonFile.size()); return buildCommandFromCommand(
*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
case FwBootState::ALGO:
bootState = FwBootState::WAIT_FOR_EXECUTION;
*id = startracker::ALGO;
return buildCommandFromCommand(
*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
case FwBootState::LOG_SUBSCRIPTION:
bootState = FwBootState::WAIT_FOR_EXECUTION;
*id = startracker::LOGSUBSCRIPTION;
return buildCommandFromCommand(
*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
case FwBootState::DEBUG_CAMERA:
bootState = FwBootState::WAIT_FOR_EXECUTION;
*id = startracker::DEBUG_CAMERA;
return buildCommandFromCommand(
*id, reinterpret_cast<const uint8_t*>(paramJsonFile.c_str()), paramJsonFile.size());
default: {
sif::error << "STR: Unexpected boot state" << (int)bootState << std::endl;
return NOTHING_TO_SEND;
}
}
}
case InternalState::BOOT_BOOTLOADER: case InternalState::BOOT_BOOTLOADER:
internalState = InternalState::BOOTLOADER_CHECK; internalState = InternalState::BOOTLOADER_CHECK;
*id = startracker::SWITCH_TO_BOOTLOADER_PROGRAM; *id = startracker::SWITCH_TO_BOOTLOADER_PROGRAM;
@ -707,6 +729,15 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
uint8_t dhbSubmode = getSubmode(); uint8_t dhbSubmode = getSubmode();
// We hide that the transition to submode firmware actually goes through the submode bootloader.
// This is because the startracker always starts in bootloader mode but we want to allow direct
// transitions to firmware mode.
if (startupState == StartupState::DONE) {
subModeFrom = SUBMODE_BOOTLOADER;
}
if (dhbSubmode == SUBMODE_NONE) {
bootFirmware(MODE_ON);
}
if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_FIRMWARE) { if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_FIRMWARE) {
bootBootloader(); bootBootloader();
} else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_FIRMWARE) { } else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_FIRMWARE) {
@ -736,19 +767,23 @@ void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFr
void StarTrackerHandler::bootFirmware(Mode_t toMode) { void StarTrackerHandler::bootFirmware(Mode_t toMode) {
switch (internalState) { switch (internalState) {
case InternalState::IDLE: case InternalState::IDLE:
internalState = InternalState::BOOT; sif::info << "STR: Booting to firmware mode" << std::endl;
internalState = InternalState::BOOT_FIRMWARE;
break; break;
case InternalState::BOOT_DELAY: case InternalState::BOOT_FIRMWARE:
if (bootCountdown.hasTimedOut()) {
internalState = InternalState::REQ_VERSION;
}
break; break;
case InternalState::FAILED_FIRMWARE_BOOT: case InternalState::FAILED_FIRMWARE_BOOT:
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
case InternalState::DONE: case InternalState::DONE:
setMode(toMode); if (toMode == MODE_NORMAL) {
setMode(toMode, 0);
} else {
setMode(toMode, SUBMODE_FIRMWARE);
}
sif::info << "STR: Firmware boot success" << std::endl;
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
startupState = StartupState::IDLE;
break; break;
default: default:
return; return;
@ -776,10 +811,11 @@ void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonF
void StarTrackerHandler::bootBootloader() { void StarTrackerHandler::bootBootloader() {
if (internalState == InternalState::IDLE) { if (internalState == InternalState::IDLE) {
internalState = InternalState::BOOT_BOOTLOADER; internalState = InternalState::BOOT_BOOTLOADER;
} else if (internalState == InternalState::BOOTING_BOOTLOADER_FAILED) { } else if (internalState == InternalState::FAILED_BOOTLOADER_BOOT) {
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
} else if (internalState == InternalState::DONE) { } else if (internalState == InternalState::DONE) {
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
startupState = StartupState::IDLE;
setMode(MODE_ON); setMode(MODE_ON);
} }
} }
@ -1934,7 +1970,7 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
if (startupState == StartupState::WAIT_CHECK_PROGRAM) { if (startupState == StartupState::WAIT_CHECK_PROGRAM) {
startupState = StartupState::DONE; startupState = StartupState::DONE;
} }
if (internalState == InternalState::VERIFY_BOOT) { if (bootState == FwBootState::VERIFY_BOOT) {
sif::warning << "StarTrackerHandler::checkProgram: Failed to boot firmware" << std::endl; sif::warning << "StarTrackerHandler::checkProgram: Failed to boot firmware" << std::endl;
// Device handler will run into timeout and fall back to transition source mode // Device handler will run into timeout and fall back to transition source mode
triggerEvent(BOOTING_FIRMWARE_FAILED_EVENT); triggerEvent(BOOTING_FIRMWARE_FAILED_EVENT);
@ -1947,11 +1983,11 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
if (startupState == StartupState::WAIT_CHECK_PROGRAM) { if (startupState == StartupState::WAIT_CHECK_PROGRAM) {
startupState = StartupState::BOOT_BOOTLOADER; startupState = StartupState::BOOT_BOOTLOADER;
} }
if (internalState == InternalState::VERIFY_BOOT) { if (bootState == FwBootState::VERIFY_BOOT) {
internalState = InternalState::LOGLEVEL; bootState = FwBootState::LOGLEVEL;
} else if (internalState == InternalState::BOOTLOADER_CHECK) { } else if (internalState == InternalState::BOOTLOADER_CHECK) {
triggerEvent(BOOTING_BOOTLOADER_FAILED_EVENT); triggerEvent(BOOTING_BOOTLOADER_FAILED_EVENT);
internalState = InternalState::BOOTING_BOOTLOADER_FAILED; internalState = InternalState::FAILED_BOOTLOADER_BOOT;
} }
break; break;
default: default:
@ -2025,54 +2061,55 @@ ReturnValue_t StarTrackerHandler::handleActionReplySet(LocalPoolDataSetBase& dat
void StarTrackerHandler::handleStartup(const uint8_t* parameterId) { void StarTrackerHandler::handleStartup(const uint8_t* parameterId) {
switch (*parameterId) { switch (*parameterId) {
case (startracker::ID::LOG_LEVEL): { case (startracker::ID::LOG_LEVEL): {
internalState = InternalState::LIMITS; bootState = FwBootState::LIMITS;
break; break;
} }
case (startracker::ID::LIMITS): { case (startracker::ID::LIMITS): {
internalState = InternalState::TRACKING; bootState = FwBootState::TRACKING;
break; break;
} }
case (startracker::ID::TRACKING): { case (startracker::ID::TRACKING): {
internalState = InternalState::MOUNTING; bootState = FwBootState::MOUNTING;
break; break;
} }
case (startracker::ID::MOUNTING): { case (startracker::ID::MOUNTING): {
internalState = InternalState::IMAGE_PROCESSOR; bootState = FwBootState::IMAGE_PROCESSOR;
break; break;
} }
case (startracker::ID::IMAGE_PROCESSOR): { case (startracker::ID::IMAGE_PROCESSOR): {
internalState = InternalState::CAMERA; bootState = FwBootState::CAMERA;
break; break;
} }
case (startracker::ID::CAMERA): { case (startracker::ID::CAMERA): {
internalState = InternalState::CENTROIDING; bootState = FwBootState::CENTROIDING;
break; break;
} }
case (startracker::ID::CENTROIDING): { case (startracker::ID::CENTROIDING): {
internalState = InternalState::LISA; bootState = FwBootState::LISA;
break; break;
} }
case (startracker::ID::LISA): { case (startracker::ID::LISA): {
internalState = InternalState::MATCHING; bootState = FwBootState::MATCHING;
break; break;
} }
case (startracker::ID::MATCHING): { case (startracker::ID::MATCHING): {
internalState = InternalState::VALIDATION; bootState = FwBootState::VALIDATION;
break; break;
} }
case (startracker::ID::VALIDATION): { case (startracker::ID::VALIDATION): {
internalState = InternalState::ALGO; bootState = FwBootState::ALGO;
break; break;
} }
case (startracker::ID::ALGO): { case (startracker::ID::ALGO): {
internalState = InternalState::LOG_SUBSCRIPTION; bootState = FwBootState::LOG_SUBSCRIPTION;
break; break;
} }
case (startracker::ID::LOG_SUBSCRIPTION): { case (startracker::ID::LOG_SUBSCRIPTION): {
internalState = InternalState::DEBUG_CAMERA; bootState = FwBootState::DEBUG_CAMERA;
break; break;
} }
case (startracker::ID::DEBUG_CAMERA): { case (startracker::ID::DEBUG_CAMERA): {
bootState = FwBootState::NONE;
internalState = InternalState::DONE; internalState = InternalState::DONE;
break; break;
} }

View File

@ -60,7 +60,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
protected: protected:
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
void doOffActivity() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
void fillCommandAndReplyMap() override; void fillCommandAndReplyMap() override;
@ -247,14 +246,31 @@ class StarTrackerHandler : public DeviceHandlerBase {
NormalState normalState = NormalState::TEMPERATURE_REQUEST; NormalState normalState = NormalState::TEMPERATURE_REQUEST;
enum class StartupState {
IDLE,
CHECK_PROGRAM,
WAIT_CHECK_PROGRAM,
BOOT_BOOTLOADER,
WAIT_JCFG,
DONE
};
StartupState startupState = StartupState::IDLE;
enum class InternalState { enum class InternalState {
IDLE, IDLE,
BOOT, BOOT_FIRMWARE,
DONE,
FAILED_FIRMWARE_BOOT,
BOOT_BOOTLOADER,
BOOTLOADER_CHECK,
FAILED_BOOTLOADER_BOOT
};
enum class FwBootState {
NONE,
BOOT_DELAY,
REQ_VERSION, REQ_VERSION,
VERIFY_BOOT, VERIFY_BOOT,
STARTUP_CHECK,
BOOT_DELAY,
FIRMWARE_CHECK,
LOGLEVEL, LOGLEVEL,
LIMITS, LIMITS,
TRACKING, TRACKING,
@ -270,26 +286,11 @@ class StarTrackerHandler : public DeviceHandlerBase {
LOG_SUBSCRIPTION, LOG_SUBSCRIPTION,
DEBUG_CAMERA, DEBUG_CAMERA,
WAIT_FOR_EXECUTION, WAIT_FOR_EXECUTION,
DONE,
FAILED_FIRMWARE_BOOT,
BOOT_BOOTLOADER,
BOOTLOADER_CHECK,
BOOTING_BOOTLOADER_FAILED
}; };
FwBootState bootState = FwBootState::NONE;
InternalState internalState = InternalState::IDLE; InternalState internalState = InternalState::IDLE;
enum class StartupState {
IDLE,
CHECK_PROGRAM,
WAIT_CHECK_PROGRAM,
BOOT_BOOTLOADER,
WAIT_JCFG,
DONE
};
StartupState startupState = StartupState::IDLE;
bool strHelperExecuting = false; bool strHelperExecuting = false;
const power::Switch_t powerSwitch = power::NO_SWITCH; const power::Switch_t powerSwitch = power::NO_SWITCH;

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 277 translations. * @brief Auto-generated event translation file. Contains 278 translations.
* @details * @details
* Generated on: 2023-03-15 09:39:13 * Generated on: 2023-03-15 10:10:04
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID"; const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION"; const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -464,6 +465,8 @@ const char *translateEvents(Event event) {
return MEKF_INVALID_INFO_STRING; return MEKF_INVALID_INFO_STRING;
case (11204): case (11204):
return MEKF_INVALID_MODE_VIOLATION_STRING; return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11205):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):

View File

@ -32,6 +32,8 @@ static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO); static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
//!< MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. //!< MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(4, severity::HIGH); static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(4, severity::HIGH);
//!< The ACS safe mode controller was not able to compute a solution and has failed.
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(5, severity::HIGH);
extern const char* getModeStr(AcsMode mode); extern const char* getModeStr(AcsMode mode);

View File

@ -181,7 +181,18 @@ void AcsController::performSafe() {
sunTargetDir, satRateSafe, &errAng, magMomMtq); sunTargetDir, satRateSafe, &errAng, magMomMtq);
} }
if (result == returnvalue::FAILED) { if (result == returnvalue::FAILED) {
// ToDo: this should never ever happen or we are dead. prob add an event at least if (not safeCtrlFailureFlag) {
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE);
safeCtrlFailureFlag = true;
}
safeCtrlFailureCounter++;
if (safeCtrlFailureCounter > 50) {
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
}
} else {
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
} }
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs, actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,

View File

@ -62,6 +62,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
uint8_t multipleRwUnavailableCounter = 0; uint8_t multipleRwUnavailableCounter = 0;
bool mekfInvalidFlag = false; bool mekfInvalidFlag = false;
uint16_t mekfInvalidCounter = 0; uint16_t mekfInvalidCounter = 0;
bool safeCtrlFailureFlag = false;
uint8_t safeCtrlFailureCounter = 0;
uint8_t resetMekfCount = 0; uint8_t resetMekfCount = 0;
bool mekfLost = false; bool mekfLost = false;

View File

@ -768,10 +768,10 @@ class AcsParameters : public HasParametersIF {
double gyr2orientationMatrix[3][3] = {{0, 0, -1}, {0, -1, 0}, {-1, 0, 0}}; double gyr2orientationMatrix[3][3] = {{0, 0, -1}, {0, -1, 0}, {-1, 0, 0}};
double gyr3orientationMatrix[3][3] = {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}; double gyr3orientationMatrix[3][3] = {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}};
double gyr0bias[3] = {0.06318149743589743, 0.4283235025641024, -0.16383500000000004}; double gyr0bias[3] = {0.0, 0.4, -0.1};
double gyr1bias[3] = {-0.12855128205128205, 1.6737307692307695, 1.031724358974359}; double gyr1bias[3] = {0.0956745283018868, 2.0854575471698116, 1.2505990566037737};
double gyr2bias[3] = {0.15039212820512823, 0.7094475589743591, -0.22298363589743594}; double gyr2bias[3] = {0.1, 0.7, -0.2};
double gyr3bias[3] = {0.0021730769230769217, -0.6655897435897435, 0.034096153846153845}; double gyr3bias[3] = {-0.10721698113207549, -0.6111650943396226, 0.1716462264150944};
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is /* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
* assumed to be equal for the same class of sensors */ * assumed to be equal for the same class of sensors */

View File

@ -1080,12 +1080,6 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
MatrixOperations<double>::add(*cov0, *cov1, *initialCovarianceMatrix, 6, 6); MatrixOperations<double>::add(*cov0, *cov1, *initialCovarianceMatrix, 6, 6);
if (not(MathOperations<double>::checkVectorIsFinite(propagatedQuaternion, 4)) ||
not(MathOperations<double>::checkMatrixIsFinite(initialQuaternion, 6, 6))) {
updateDataSetWithoutData(mekfData, MekfStatus::NOT_FINITE);
return MEKF_NOT_FINITE;
}
updateDataSet(mekfData, MekfStatus::RUNNING, quatBJ, rotRateEst); updateDataSet(mekfData, MekfStatus::RUNNING, quatBJ, rotRateEst);
return MEKF_RUNNING; return MEKF_RUNNING;
} }
@ -1095,7 +1089,6 @@ ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::MekfData *mekfData) {
double resetCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, double resetCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}; {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
std::memcpy(initialQuaternion, resetQuaternion, 4 * sizeof(double)); std::memcpy(initialQuaternion, resetQuaternion, 4 * sizeof(double));
std::memcpy(propagatedQuaternion, resetQuaternion, 4 * sizeof(double));
std::memcpy(initialCovarianceMatrix, resetCovarianceMatrix, 6 * 6 * sizeof(double)); std::memcpy(initialCovarianceMatrix, resetCovarianceMatrix, 6 * 6 * sizeof(double));
updateDataSetWithoutData(mekfData, MekfStatus::UNINITIALIZED); updateDataSetWithoutData(mekfData, MekfStatus::UNINITIALIZED);
return MEKF_UNINITIALIZED; return MEKF_UNINITIALIZED;

View File

@ -62,7 +62,6 @@ class MultiplicativeKalmanFilter {
NO_MODEL_VECTORS = 2, NO_MODEL_VECTORS = 2,
NO_SUS_MGM_STR_DATA = 3, NO_SUS_MGM_STR_DATA = 3,
COVARIANCE_INVERSION_FAILED = 4, COVARIANCE_INVERSION_FAILED = 4,
NOT_FINITE = 5,
INITIALIZED = 10, INITIALIZED = 10,
RUNNING = 11, RUNNING = 11,
}; };
@ -75,9 +74,8 @@ class MultiplicativeKalmanFilter {
static constexpr ReturnValue_t MEKF_NO_SUS_MGM_STR_DATA = returnvalue::makeCode(IF_MEKF_ID, 5); static constexpr ReturnValue_t MEKF_NO_SUS_MGM_STR_DATA = returnvalue::makeCode(IF_MEKF_ID, 5);
static constexpr ReturnValue_t MEKF_COVARIANCE_INVERSION_FAILED = static constexpr ReturnValue_t MEKF_COVARIANCE_INVERSION_FAILED =
returnvalue::makeCode(IF_MEKF_ID, 6); returnvalue::makeCode(IF_MEKF_ID, 6);
static constexpr ReturnValue_t MEKF_NOT_FINITE = returnvalue::makeCode(IF_MEKF_ID, 7); static constexpr ReturnValue_t MEKF_INITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 7);
static constexpr ReturnValue_t MEKF_INITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 8); static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 8);
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 9);
private: private:
/*Parameters*/ /*Parameters*/

View File

@ -404,26 +404,6 @@ class MathOperations {
std::memcpy(inverse, identity, sizeof(identity)); std::memcpy(inverse, identity, sizeof(identity));
return 0; // successful inversion return 0; // successful inversion
} }
static bool checkVectorIsFinite(const T1 *inputVector, uint8_t size) {
for (uint8_t i = 0; i < size; i++) {
if (not isfinite(inputVector[i])) {
return false;
}
}
return true;
}
static bool checkMatrixIsFinite(const T1 *inputMatrix, uint8_t rows, uint8_t cols) {
for (uint8_t col = 0; col < cols; col++) {
for (uint8_t row = 0; row < rows; row++) {
if (not isfinite(inputMatrix[row * cols + cols])) {
return false;
}
}
}
return true;
}
}; };
#endif /* ACS_MATH_MATHOPERATIONS_H_ */ #endif /* ACS_MATH_MATHOPERATIONS_H_ */

View File

@ -112,8 +112,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
} }
{ {
PoolManager::LocalPoolConfig poolCfg = {{600, 32}, {400, 64}, {400, 128}, {300, 512}, PoolManager::LocalPoolConfig poolCfg = {{600, 32}, {400, 64}, {400, 128},
{250, 1024}, {150, 2048}}; {300, 512}, {250, 1024}, {150, 2048}};
*tmStore = new PoolManager(objects::TM_STORE, poolCfg); *tmStore = new PoolManager(objects::TM_STORE, poolCfg);
} }
@ -254,8 +254,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
pus::PUS_SERVICE_20); pus::PUS_SERVICE_20);
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID, new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID,
pus::PUS_SERVICE_200, 8); pus::PUS_SERVICE_200, 8);
HealthServiceCfg healthCfg(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID, *healthTable, HealthServiceCfg healthCfg(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID,
20); objects::HEALTH_TABLE, 20);
new CServiceHealthCommanding(healthCfg); new CServiceHealthCommanding(healthCfg);
#if OBSW_ADD_CFDP_COMPONENTS == 1 #if OBSW_ADD_CFDP_COMPONENTS == 1

View File

@ -36,31 +36,25 @@ ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) {
// I don't think this needs to be in a PST because linux takes care of bus serialization, but // I don't think this needs to be in a PST because linux takes care of bus serialization, but
// keep it like this for now, it works // keep it like this for now, it works
ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { ReturnValue_t pst::pstI2cProcessingSystem(FixedTimeslotTaskIF *thisSequence) {
// Length of a communication cycle // Length of a communication cycle
uint32_t length = thisSequence->getPeriodMs(); uint32_t length = thisSequence->getPeriodMs();
static_cast<void>(length); static_cast<void>(length);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.2,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.2, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.3, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.3, DeviceHandlerIF::GET_READ);
// These are actually part of another bus, but this works, so keep it like this for now // These are actually part of another bus, but this works, so keep it like this for now
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.4, thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.2,
DeviceHandlerIF::PERFORM_OPERATION); DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.4, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.2, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.45, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.3, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.45, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_0, length * 0.3, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.5, thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.4,
DeviceHandlerIF::PERFORM_OPERATION); DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.5, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.4, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.5, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.55, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.5, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.55, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_TCS_1, length * 0.5, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.6, thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.6,
DeviceHandlerIF::PERFORM_OPERATION); DeviceHandlerIF::PERFORM_OPERATION);
@ -68,10 +62,9 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) {
DeviceHandlerIF::SEND_WRITE); DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.6, thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.6,
DeviceHandlerIF::GET_WRITE); DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.65, thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.7,
DeviceHandlerIF::SEND_READ); DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.65, thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_0, length * 0.7, DeviceHandlerIF::GET_READ);
DeviceHandlerIF::GET_READ);
// damaged // damaged
/* /*
thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_1, length * 0.4, thisSequence->addSlot(objects::TMP1075_HANDLER_PLPCDU_1, length * 0.4,
@ -90,10 +83,9 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) {
DeviceHandlerIF::SEND_WRITE); DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_IF_BOARD, length * 0.8, thisSequence->addSlot(objects::TMP1075_HANDLER_IF_BOARD, length * 0.8,
DeviceHandlerIF::GET_WRITE); DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_IF_BOARD, length * 0.85, thisSequence->addSlot(objects::TMP1075_HANDLER_IF_BOARD, length * 0.9,
DeviceHandlerIF::SEND_READ); DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_IF_BOARD, length * 0.85, thisSequence->addSlot(objects::TMP1075_HANDLER_IF_BOARD, length * 0.9, DeviceHandlerIF::GET_READ);
DeviceHandlerIF::GET_READ);
static_cast<void>(length); static_cast<void>(length);
return thisSequence->checkSequence(); return thisSequence->checkSequence();
} }
@ -562,6 +554,16 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
DeviceHandlerIF::SEND_READ); DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * config::spiSched::SCHED_BLOCK_8_PERIOD, thisSequence->addSlot(objects::PLPCDU_HANDLER, length * config::spiSched::SCHED_BLOCK_8_PERIOD,
DeviceHandlerIF::GET_READ); DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * config::spiSched::SCHED_BLOCK_8_PERIOD,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * config::spiSched::SCHED_BLOCK_8_PERIOD,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * config::spiSched::SCHED_BLOCK_8_PERIOD,
DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * config::spiSched::SCHED_BLOCK_9_PERIOD,
DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * config::spiSched::SCHED_BLOCK_9_PERIOD,
DeviceHandlerIF::GET_READ);
#if OBSW_ADD_RAD_SENSORS == 1 #if OBSW_ADD_RAD_SENSORS == 1
/* Radiation sensor */ /* Radiation sensor */

View File

@ -51,7 +51,7 @@ ReturnValue_t pstSyrlinks(FixedTimeslotTaskIF* thisSequence);
ReturnValue_t pstTcsAndAcs(FixedTimeslotTaskIF* thisSequence, AcsPstCfg cfg); ReturnValue_t pstTcsAndAcs(FixedTimeslotTaskIF* thisSequence, AcsPstCfg cfg);
ReturnValue_t pstI2c(FixedTimeslotTaskIF* thisSequence); ReturnValue_t pstI2cProcessingSystem(FixedTimeslotTaskIF* thisSequence);
/** /**
* Generic test PST * Generic test PST

View File

@ -5,8 +5,8 @@ target_sources(
Tmp1075Handler.cpp Tmp1075Handler.cpp
PcduHandler.cpp PcduHandler.cpp
P60DockHandler.cpp P60DockHandler.cpp
PDU1Handler.cpp Pdu1Handler.cpp
PDU2Handler.cpp Pdu2Handler.cpp
ACUHandler.cpp ACUHandler.cpp
SyrlinksHandler.cpp SyrlinksHandler.cpp
Max31865PT1000Handler.cpp Max31865PT1000Handler.cpp

View File

@ -65,10 +65,7 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_
} }
case (InternalState::SHUTDOWN): { case (InternalState::SHUTDOWN): {
*id = adis1650x::REQUEST; *id = adis1650x::REQUEST;
acs::Adis1650XRequest *request = reinterpret_cast<acs::Adis1650XRequest *>(cmdBuf.data()); return preparePeriodicRequest(acs::SimpleSensorMode::OFF);
request->mode = acs::SimpleSensorMode::OFF;
request->type = adisType;
return returnvalue::OK;
} }
default: { default: {
return NOTHING_TO_SEND; return NOTHING_TO_SEND;

View File

@ -7,7 +7,7 @@
#include <mission/devices/PcduHandler.h> #include <mission/devices/PcduHandler.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h> #include <mission/devices/devicedefinitions/GomSpacePackets.h>
PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) PcduHandler::PcduHandler(object_id_t setObjectId, size_t cmdQueueSize)
: SystemObject(setObjectId), : SystemObject(setObjectId),
poolManager(this, nullptr), poolManager(this, nullptr),
p60CoreHk(objects::P60DOCK_HANDLER), p60CoreHk(objects::P60DOCK_HANDLER),
@ -19,11 +19,12 @@ PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize)
commandQueue = QueueFactory::instance()->createMessageQueue( commandQueue = QueueFactory::instance()->createMessageQueue(
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
pwrLock = MutexFactory::instance()->createMutex(); pwrLock = MutexFactory::instance()->createMutex();
std::memset(switchStates, SWITCH_STATE_UNKNOWN, sizeof(switchStates));
} }
PCDUHandler::~PCDUHandler() {} PcduHandler::~PcduHandler() {}
ReturnValue_t PCDUHandler::performOperation(uint8_t counter) { ReturnValue_t PcduHandler::performOperation(uint8_t counter) {
if (counter == DeviceHandlerIF::PERFORM_OPERATION) { if (counter == DeviceHandlerIF::PERFORM_OPERATION) {
readCommandQueue(); readCommandQueue();
} }
@ -51,7 +52,7 @@ ReturnValue_t PCDUHandler::performOperation(uint8_t counter) {
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PCDUHandler::initialize() { ReturnValue_t PcduHandler::initialize() {
ReturnValue_t result; ReturnValue_t result;
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE); IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
@ -99,7 +100,7 @@ ReturnValue_t PCDUHandler::initialize() {
return returnvalue::OK; return returnvalue::OK;
} }
void PCDUHandler::initializeSwitchStates() { void PcduHandler::initializeSwitchStates() {
using namespace pcdu; using namespace pcdu;
try { try {
for (uint8_t idx = 0; idx < NUMBER_OF_SWITCHES; idx++) { for (uint8_t idx = 0; idx < NUMBER_OF_SWITCHES; idx++) {
@ -116,7 +117,7 @@ void PCDUHandler::initializeSwitchStates() {
} }
} }
void PCDUHandler::readCommandQueue() { void PcduHandler::readCommandQueue() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
CommandMessage command; CommandMessage command;
@ -129,9 +130,9 @@ void PCDUHandler::readCommandQueue() {
} }
} }
MessageQueueId_t PCDUHandler::getCommandQueue() const { return commandQueue->getId(); } MessageQueueId_t PcduHandler::getCommandQueue() const { return commandQueue->getId(); }
void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) { void PcduHandler::handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) {
if (sid == sid_t(objects::PDU2_HANDLER, static_cast<uint32_t>(P60System::SetIds::CORE))) { if (sid == sid_t(objects::PDU2_HANDLER, static_cast<uint32_t>(P60System::SetIds::CORE))) {
updateHkTableDataset(storeId, &pdu2CoreHk, &timeStampPdu2HkDataset); updateHkTableDataset(storeId, &pdu2CoreHk, &timeStampPdu2HkDataset);
updatePdu2SwitchStates(); updatePdu2SwitchStates();
@ -143,7 +144,7 @@ void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId, bool*
} }
} }
void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSetBase* dataset, void PcduHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSetBase* dataset,
CCSDSTime::CDS_short* datasetTimeStamp) { CCSDSTime::CDS_short* datasetTimeStamp) {
ReturnValue_t result; ReturnValue_t result;
@ -169,7 +170,7 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet
} }
} }
void PCDUHandler::updatePdu2SwitchStates() { void PcduHandler::updatePdu2SwitchStates() {
using namespace pcdu; using namespace pcdu;
using namespace PDU2; using namespace PDU2;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2; GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2;
@ -206,7 +207,7 @@ void PCDUHandler::updatePdu2SwitchStates() {
} }
} }
void PCDUHandler::updatePdu1SwitchStates() { void PcduHandler::updatePdu1SwitchStates() {
using namespace pcdu; using namespace pcdu;
using namespace PDU1; using namespace PDU1;
PoolReadGuard rg0(&switcherSet); PoolReadGuard rg0(&switcherSet);
@ -243,9 +244,9 @@ void PCDUHandler::updatePdu1SwitchStates() {
} }
} }
LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; } LocalDataPoolManager* PcduHandler::getHkManagerHandle() { return &poolManager; }
ReturnValue_t PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) { ReturnValue_t PcduHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) {
using namespace pcdu; using namespace pcdu;
ReturnValue_t result; ReturnValue_t result;
uint16_t memoryAddress = 0; uint16_t memoryAddress = 0;
@ -395,9 +396,9 @@ ReturnValue_t PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onO
return result; return result;
} }
ReturnValue_t PCDUHandler::sendFuseOnCommand(uint8_t fuseNr) { return returnvalue::OK; } ReturnValue_t PcduHandler::sendFuseOnCommand(uint8_t fuseNr) { return returnvalue::OK; }
ReturnValue_t PCDUHandler::getSwitchState(uint8_t switchNr) const { ReturnValue_t PcduHandler::getSwitchState(uint8_t switchNr) const {
if (switchNr >= pcdu::NUMBER_OF_SWITCHES) { if (switchNr >= pcdu::NUMBER_OF_SWITCHES) {
sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl; sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
@ -407,6 +408,9 @@ ReturnValue_t PCDUHandler::getSwitchState(uint8_t switchNr) const {
MutexGuard mg(pwrLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(pwrLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
currentState = switchStates[switchNr]; currentState = switchStates[switchNr];
} }
if (currentState == SWITCH_STATE_UNKNOWN) {
return PowerSwitchIF::SWITCH_UNKNOWN;
}
if (currentState == 1) { if (currentState == 1) {
return PowerSwitchIF::SWITCH_ON; return PowerSwitchIF::SWITCH_ON;
} else { } else {
@ -414,13 +418,13 @@ ReturnValue_t PCDUHandler::getSwitchState(uint8_t switchNr) const {
} }
} }
ReturnValue_t PCDUHandler::getFuseState(uint8_t fuseNr) const { return returnvalue::OK; } ReturnValue_t PcduHandler::getFuseState(uint8_t fuseNr) const { return returnvalue::OK; }
uint32_t PCDUHandler::getSwitchDelayMs(void) const { return 20000; } uint32_t PcduHandler::getSwitchDelayMs(void) const { return 20000; }
object_id_t PCDUHandler::getObjectId() const { return SystemObject::getObjectId(); } object_id_t PcduHandler::getObjectId() const { return SystemObject::getObjectId(); }
ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, ReturnValue_t PcduHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) { LocalDataPoolManager& poolManager) {
using namespace pcdu; using namespace pcdu;
localDataPoolMap.emplace(PoolIds::PDU1_SWITCHES, &pdu1Switches); localDataPoolMap.emplace(PoolIds::PDU1_SWITCHES, &pdu1Switches);
@ -431,7 +435,7 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PCDUHandler::initializeAfterTaskCreation() { ReturnValue_t PcduHandler::initializeAfterTaskCreation() {
if (executingTask != nullptr) { if (executingTask != nullptr) {
pstIntervalMs = executingTask->getPeriodMs(); pstIntervalMs = executingTask->getPeriodMs();
} }
@ -442,11 +446,11 @@ ReturnValue_t PCDUHandler::initializeAfterTaskCreation() {
return returnvalue::OK; return returnvalue::OK;
} }
uint32_t PCDUHandler::getPeriodicOperationFrequency() const { return pstIntervalMs; } uint32_t PcduHandler::getPeriodicOperationFrequency() const { return pstIntervalMs; }
void PCDUHandler::setTaskIF(PeriodicTaskIF* task) { executingTask = task; } void PcduHandler::setTaskIF(PeriodicTaskIF* task) { executingTask = task; }
LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) { LocalPoolDataSetBase* PcduHandler::getDataSetHandle(sid_t sid) {
if (sid == switcherSet.getSid()) { if (sid == switcherSet.getSid()) {
return &switcherSet; return &switcherSet;
} else { } else {
@ -455,7 +459,7 @@ LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) {
} }
} }
void PCDUHandler::checkAndUpdatePduSwitch(GOMSPACE::Pdu pdu, pcdu::Switches switchIdx, void PcduHandler::checkAndUpdatePduSwitch(GOMSPACE::Pdu pdu, pcdu::Switches switchIdx,
uint8_t setValue) { uint8_t setValue) {
using namespace pcdu; using namespace pcdu;
if (switchStates[switchIdx] != setValue) { if (switchStates[switchIdx] != setValue) {

View File

@ -20,13 +20,13 @@
* This is necessary because the FSFW manages all power related functionalities via one * This is necessary because the FSFW manages all power related functionalities via one
* power object. This includes for example switching on and off of devices. * power object. This includes for example switching on and off of devices.
*/ */
class PCDUHandler : public PowerSwitchIF, class PcduHandler : public PowerSwitchIF,
public HasLocalDataPoolIF, public HasLocalDataPoolIF,
public SystemObject, public SystemObject,
public ExecutableObjectIF { public ExecutableObjectIF {
public: public:
PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize = 20); PcduHandler(object_id_t setObjectId, size_t cmdQueueSize = 20);
virtual ~PCDUHandler(); virtual ~PcduHandler();
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
virtual ReturnValue_t performOperation(uint8_t counter) override; virtual ReturnValue_t performOperation(uint8_t counter) override;
@ -35,7 +35,11 @@ class PCDUHandler : public PowerSwitchIF,
virtual ReturnValue_t sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override; virtual ReturnValue_t sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override;
virtual ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override; virtual ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
virtual ReturnValue_t getSwitchState(uint8_t switchNr) const override; /**
* @param switchNr
* @return returnvalue::FAILED if the switch state has not been updated yet.
*/
ReturnValue_t getSwitchState(uint8_t switchNr) const override;
virtual ReturnValue_t getFuseState(uint8_t fuseNr) const override; virtual ReturnValue_t getFuseState(uint8_t fuseNr) const override;
virtual uint32_t getSwitchDelayMs(void) const override; virtual uint32_t getSwitchDelayMs(void) const override;
virtual object_id_t getObjectId() const override; virtual object_id_t getObjectId() const override;
@ -84,6 +88,7 @@ class PCDUHandler : public PowerSwitchIF,
/** The timeStamp of the current pdu1HkTableDataset */ /** The timeStamp of the current pdu1HkTableDataset */
CCSDSTime::CDS_short timeStampPdu1HkDataset; CCSDSTime::CDS_short timeStampPdu1HkDataset;
uint8_t SWITCH_STATE_UNKNOWN = 2;
uint8_t switchStates[pcdu::NUMBER_OF_SWITCHES]; uint8_t switchStates[pcdu::NUMBER_OF_SWITCHES];
/** /**
* Pointer to the IPCStore. * Pointer to the IPCStore.

View File

@ -1,11 +1,10 @@
#include "PDU1Handler.h"
#include <fsfw/datapool/PoolReadGuard.h> #include <fsfw/datapool/PoolReadGuard.h>
#include <mission/devices/Pdu1Handler.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h> #include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include "devices/powerSwitcherList.h" #include "devices/powerSwitcherList.h"
PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie, Pdu1Handler::Pdu1Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir) FailureIsolationBase *customFdir)
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir), : GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
coreHk(this), coreHk(this),
@ -13,23 +12,23 @@ PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF *comC
initPduConfigTable(); initPduConfigTable();
} }
PDU1Handler::~PDU1Handler() {} Pdu1Handler::~Pdu1Handler() {}
ReturnValue_t PDU1Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t Pdu1Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE; *id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0); return buildCommandFromCommand(*id, NULL, 0);
} }
void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { void Pdu1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
parseHkTableReply(packet); parseHkTableReply(packet);
} }
void PDU1Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) { void Pdu1Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) {
this->channelSwitchHook = hook; this->channelSwitchHook = hook;
this->hookArgs = args; this->hookArgs = args;
} }
ReturnValue_t PDU1Handler::setParamCallback(SetParamMessageUnpacker &unpacker, ReturnValue_t Pdu1Handler::setParamCallback(SetParamMessageUnpacker &unpacker,
bool afterExecution) { bool afterExecution) {
using namespace PDU1; using namespace PDU1;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1; GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1;
@ -79,15 +78,15 @@ ReturnValue_t PDU1Handler::setParamCallback(SetParamMessageUnpacker &unpacker,
return returnvalue::OK; return returnvalue::OK;
} }
void PDU1Handler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) { void Pdu1Handler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) {
handleDeviceTm(packet, PDU::CONFIG_TABLE_SIZE, id); handleDeviceTm(packet, PDU::CONFIG_TABLE_SIZE, id);
} }
void PDU1Handler::parseHkTableReply(const uint8_t *packet) { void Pdu1Handler::parseHkTableReply(const uint8_t *packet) {
GomspaceDeviceHandler::parsePduHkTable(coreHk, auxHk, packet); GomspaceDeviceHandler::parsePduHkTable(coreHk, auxHk, packet);
} }
ReturnValue_t PDU1Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, ReturnValue_t Pdu1Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) { LocalDataPoolManager &poolManager) {
initializePduPool(localDataPoolMap, poolManager, pcdu::INIT_SWITCHES_PDU1); initializePduPool(localDataPoolMap, poolManager, pcdu::INIT_SWITCHES_PDU1);
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
@ -97,7 +96,7 @@ ReturnValue_t PDU1Handler::initializeLocalDataPool(localpool::DataPool &localDat
return returnvalue::OK; return returnvalue::OK;
} }
LocalPoolDataSetBase *PDU1Handler::getDataSetHandle(sid_t sid) { LocalPoolDataSetBase *Pdu1Handler::getDataSetHandle(sid_t sid) {
if (sid == coreHk.getSid()) { if (sid == coreHk.getSid()) {
return &coreHk; return &coreHk;
} else if (sid == auxHk.getSid()) { } else if (sid == auxHk.getSid()) {
@ -106,7 +105,7 @@ LocalPoolDataSetBase *PDU1Handler::getDataSetHandle(sid_t sid) {
return nullptr; return nullptr;
} }
ReturnValue_t PDU1Handler::printStatus(DeviceCommandId_t cmd) { ReturnValue_t Pdu1Handler::printStatus(DeviceCommandId_t cmd) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
switch (cmd) { switch (cmd) {
case (GOMSPACE::PRINT_SWITCH_V_I): { case (GOMSPACE::PRINT_SWITCH_V_I): {
@ -137,7 +136,7 @@ ReturnValue_t PDU1Handler::printStatus(DeviceCommandId_t cmd) {
return result; return result;
} }
void PDU1Handler::printHkTableSwitchVI() { void Pdu1Handler::printHkTableSwitchVI() {
using namespace PDU1; using namespace PDU1;
sif::info << "PDU1 Info: " << std::endl; sif::info << "PDU1 Info: " << std::endl;
sif::info << "Boot Cause: " << auxHk.bootcause << " | Boot Count: " << std::setw(4) << std::right sif::info << "Boot Cause: " << auxHk.bootcause << " | Boot Count: " << std::setw(4) << std::right
@ -163,7 +162,7 @@ void PDU1Handler::printHkTableSwitchVI() {
printerHelper("Syrlinks", Channels::SYRLINKS); printerHelper("Syrlinks", Channels::SYRLINKS);
} }
void PDU1Handler::printHkTableLatchups() { void Pdu1Handler::printHkTableLatchups() {
using namespace PDU1; using namespace PDU1;
sif::info << "PDU1 Latchup Information" << std::endl; sif::info << "PDU1 Latchup Information" << std::endl;
auto printerHelper = [&](std::string channelStr, Channels idx) { auto printerHelper = [&](std::string channelStr, Channels idx) {

View File

@ -19,11 +19,11 @@
* ACS 3.3V for Side A group, channel 7 * ACS 3.3V for Side A group, channel 7
* Unoccupied, 5V, channel 8 * Unoccupied, 5V, channel 8
*/ */
class PDU1Handler : public GomspaceDeviceHandler { class Pdu1Handler : public GomspaceDeviceHandler {
public: public:
PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, Pdu1Handler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
FailureIsolationBase* customFdir); FailureIsolationBase* customFdir);
virtual ~PDU1Handler(); virtual ~Pdu1Handler();
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;

View File

@ -1,11 +1,10 @@
#include "PDU2Handler.h"
#include <fsfw/datapool/PoolReadGuard.h> #include <fsfw/datapool/PoolReadGuard.h>
#include <mission/devices/Pdu2Handler.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h> #include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include "devices/powerSwitcherList.h" #include "devices/powerSwitcherList.h"
PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie, Pdu2Handler::Pdu2Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir) FailureIsolationBase *customFdir)
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir), : GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
coreHk(this), coreHk(this),
@ -13,27 +12,27 @@ PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF *comC
initPduConfigTable(); initPduConfigTable();
} }
PDU2Handler::~PDU2Handler() {} Pdu2Handler::~Pdu2Handler() {}
ReturnValue_t PDU2Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t Pdu2Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE; *id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0); return buildCommandFromCommand(*id, NULL, 0);
} }
void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { void Pdu2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
parseHkTableReply(packet); parseHkTableReply(packet);
} }
void PDU2Handler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) { void Pdu2Handler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) {
handleDeviceTm(packet, PDU::CONFIG_TABLE_SIZE, id); handleDeviceTm(packet, PDU::CONFIG_TABLE_SIZE, id);
} }
void PDU2Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) { void Pdu2Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) {
this->channelSwitchHook = hook; this->channelSwitchHook = hook;
this->hookArgs = args; this->hookArgs = args;
} }
LocalPoolDataSetBase *PDU2Handler::getDataSetHandle(sid_t sid) { LocalPoolDataSetBase *Pdu2Handler::getDataSetHandle(sid_t sid) {
if (sid == coreHk.getSid()) { if (sid == coreHk.getSid()) {
return &coreHk; return &coreHk;
} else if (sid == auxHk.getSid()) { } else if (sid == auxHk.getSid()) {
@ -42,11 +41,11 @@ LocalPoolDataSetBase *PDU2Handler::getDataSetHandle(sid_t sid) {
return nullptr; return nullptr;
} }
void PDU2Handler::parseHkTableReply(const uint8_t *packet) { void Pdu2Handler::parseHkTableReply(const uint8_t *packet) {
GomspaceDeviceHandler::parsePduHkTable(coreHk, auxHk, packet); GomspaceDeviceHandler::parsePduHkTable(coreHk, auxHk, packet);
} }
ReturnValue_t PDU2Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, ReturnValue_t Pdu2Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) { LocalDataPoolManager &poolManager) {
initializePduPool(localDataPoolMap, poolManager, pcdu::INIT_SWITCHES_PDU2); initializePduPool(localDataPoolMap, poolManager, pcdu::INIT_SWITCHES_PDU2);
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
@ -56,7 +55,7 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool(localpool::DataPool &localDat
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PDU2Handler::printStatus(DeviceCommandId_t cmd) { ReturnValue_t Pdu2Handler::printStatus(DeviceCommandId_t cmd) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
switch (cmd) { switch (cmd) {
case (GOMSPACE::PRINT_SWITCH_V_I): { case (GOMSPACE::PRINT_SWITCH_V_I): {
@ -87,7 +86,7 @@ ReturnValue_t PDU2Handler::printStatus(DeviceCommandId_t cmd) {
return result; return result;
} }
void PDU2Handler::printHkTableSwitchVI() { void Pdu2Handler::printHkTableSwitchVI() {
using namespace PDU2; using namespace PDU2;
sif::info << "PDU2 Info:" << std::endl; sif::info << "PDU2 Info:" << std::endl;
sif::info << "Boot Cause: " << auxHk.bootcause << " | Boot Count: " << std::setw(4) << std::right sif::info << "Boot Cause: " << auxHk.bootcause << " | Boot Count: " << std::setw(4) << std::right
@ -111,7 +110,7 @@ void PDU2Handler::printHkTableSwitchVI() {
printerHelper("Payload Camera", Channels::PAYLOAD_CAMERA); printerHelper("Payload Camera", Channels::PAYLOAD_CAMERA);
} }
void PDU2Handler::printHkTableLatchups() { void Pdu2Handler::printHkTableLatchups() {
using namespace PDU2; using namespace PDU2;
sif::info << "PDU2 Latchup Information" << std::endl; sif::info << "PDU2 Latchup Information" << std::endl;
auto printerHelper = [&](std::string channelStr, Channels idx) { auto printerHelper = [&](std::string channelStr, Channels idx) {
@ -129,7 +128,7 @@ void PDU2Handler::printHkTableLatchups() {
printerHelper("Payload Camera", Channels::PAYLOAD_CAMERA); printerHelper("Payload Camera", Channels::PAYLOAD_CAMERA);
} }
ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, ReturnValue_t Pdu2Handler::setParamCallback(SetParamMessageUnpacker &unpacker,
bool afterExecution) { bool afterExecution) {
using namespace PDU2; using namespace PDU2;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2; GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2;

View File

@ -19,11 +19,11 @@
* ACS Board (Gyro, MGMs, GPS), 3.3V channel 7 * ACS Board (Gyro, MGMs, GPS), 3.3V channel 7
* Payload Camera, 8V, channel 8 * Payload Camera, 8V, channel 8
*/ */
class PDU2Handler : public GomspaceDeviceHandler { class Pdu2Handler : public GomspaceDeviceHandler {
public: public:
PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, Pdu2Handler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
FailureIsolationBase* customFdir); FailureIsolationBase* customFdir);
virtual ~PDU2Handler(); virtual ~Pdu2Handler();
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;

View File

@ -157,10 +157,14 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa
return returnvalue::OK; return returnvalue::OK;
} }
bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const char* filename, bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const char* infoFile,
bool dryRun) { bool dryRun) {
using namespace std; using namespace std;
ifstream file(filename); std::error_code e;
ifstream file(infoFile);
if (file.bad()) {
return false;
}
string line; string line;
string word; string word;
unsigned int lineNum = 0; unsigned int lineNum = 0;
@ -211,14 +215,14 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const
stateSwitch = true; stateSwitch = true;
} }
}; };
if ((secsSinceBoot > FIRST_BURN_START_TIME) and (secsSinceBoot < FIRST_BURN_END_TIME)) { if ((secsSinceBoot >= FIRST_BURN_START_TIME) and (secsSinceBoot < FIRST_BURN_END_TIME)) {
switchCheck(AutonomousDeplState::FIRST_BURN); switchCheck(AutonomousDeplState::FIRST_BURN);
} else if ((secsSinceBoot > WAIT_START_TIME) and (secsSinceBoot < WAIT_END_TIME)) { } else if ((secsSinceBoot >= WAIT_START_TIME) and (secsSinceBoot < WAIT_END_TIME)) {
switchCheck(AutonomousDeplState::WAIT); switchCheck(AutonomousDeplState::WAIT);
} else if ((secsSinceBoot > SECOND_BURN_START_TIME) and } else if ((secsSinceBoot >= SECOND_BURN_START_TIME) and
(secsSinceBoot < SECOND_BURN_END_TIME)) { (secsSinceBoot < SECOND_BURN_END_TIME)) {
switchCheck(AutonomousDeplState::SECOND_BURN); switchCheck(AutonomousDeplState::SECOND_BURN);
} else if (secsSinceBoot > SECOND_BURN_END_TIME) { } else if (secsSinceBoot >= SECOND_BURN_END_TIME) {
switchCheck(AutonomousDeplState::DONE); switchCheck(AutonomousDeplState::DONE);
} }
} }
@ -240,15 +244,18 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const
} }
} }
if (deplState == AutonomousDeplState::DONE) { if (deplState == AutonomousDeplState::DONE) {
remove(filename); std::filesystem::remove(infoFile, e);
if (sdCard == sd::SdCard::SLOT_0) { if (sdCard == sd::SdCard::SLOT_0) {
remove(SD_0_DEPL_FILE); std::filesystem::remove(SD_0_DEPL_FILE, e);
} else { } else {
remove(SD_1_DEPL_FILE); std::filesystem::remove(SD_1_DEPL_FILE, e);
} }
triggerEvent(AUTONOMOUS_DEPLOYMENT_COMPLETED); triggerEvent(AUTONOMOUS_DEPLOYMENT_COMPLETED);
} else { } else {
std::ofstream of(filename); std::ofstream of(infoFile);
if (of.bad()) {
return false;
}
of << "phase: "; of << "phase: ";
if (deplState == AutonomousDeplState::INIT) { if (deplState == AutonomousDeplState::INIT) {
of << PHASE_INIT_STR << "\n"; of << PHASE_INIT_STR << "\n";

11
mission/sysDefs.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef MISSION_SYSDEFS_H_
#define MISSION_SYSDEFS_H_
#include "acsDefs.h"
namespace satsystem {
enum Mode : Mode_t { BOOT = 5, SAFE = acs::AcsMode::SAFE, PTG_IDLE = acs::AcsMode::PTG_IDLE };
}
#endif /* MISSION_SYSDEFS_H_ */

View File

@ -19,7 +19,10 @@ DualLaneAssemblyBase::DualLaneAssemblyBase(object_id_t objectId, PowerSwitchIF*
void DualLaneAssemblyBase::performChildOperation() { void DualLaneAssemblyBase::performChildOperation() {
using namespace duallane; using namespace duallane;
if (pwrStateMachine.active()) { if (pwrStateMachine.active()) {
pwrStateMachineWrapper(); ReturnValue_t result = pwrStateMachineWrapper();
if (result != returnvalue::OK) {
handleModeTransitionFailed(result);
}
} }
// Only perform the regular child operation if the power state machine is not active. // Only perform the regular child operation if the power state machine is not active.
// It does not make any sense to command device modes while the power switcher is busy // It does not make any sense to command device modes while the power switcher is busy
@ -31,10 +34,17 @@ void DualLaneAssemblyBase::performChildOperation() {
} }
void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
// doStartTransition(mode, submode);
using namespace duallane; using namespace duallane;
pwrStateMachine.reset(); pwrStateMachine.reset();
if (mode != MODE_OFF) { if (mode != MODE_OFF) {
// Special exception: A transition from dual side to single mode must be handled like
// going OFF.
if ((this->mode == MODE_ON or this->mode == DeviceHandlerIF::MODE_NORMAL) and
this->submode == DUAL_MODE and submode != DUAL_MODE) {
dualToSingleSideTransition = true;
AssemblyBase::startTransition(mode, submode);
return;
}
// If anything other than MODE_OFF is commanded, perform power state machine first // If anything other than MODE_OFF is commanded, perform power state machine first
// Cache the target modes, required by power state machine // Cache the target modes, required by power state machine
pwrStateMachine.start(mode, submode); pwrStateMachine.start(mode, submode);
@ -72,9 +82,13 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() {
// Will be called for transitions to MODE_OFF, where everything is done after power switching // Will be called for transitions to MODE_OFF, where everything is done after power switching
finishModeOp(); finishModeOp();
} else if (opCode == OpCodes::TO_NOT_OFF_DONE) { } else if (opCode == OpCodes::TO_NOT_OFF_DONE) {
// Will be called for transitions from MODE_OFF to anything else, where the mode still has if (dualToSingleSideTransition) {
// to be commanded after power switching finishModeOp();
AssemblyBase::startTransition(targetMode, targetSubmode); } else {
// Will be called for transitions from MODE_OFF to anything else, where the mode still has
// to be commanded after power switching
AssemblyBase::startTransition(targetMode, targetSubmode);
}
} else if (opCode == OpCodes::TIMEOUT_OCCURED) { } else if (opCode == OpCodes::TIMEOUT_OCCURED) {
if (powerRetryCounter == 0) { if (powerRetryCounter == 0) {
powerRetryCounter++; powerRetryCounter++;
@ -112,8 +126,16 @@ void DualLaneAssemblyBase::handleModeReached() {
pwrStateMachine.start(targetMode, targetSubmode); pwrStateMachine.start(targetMode, targetSubmode);
// Now we can switch off the power. After that, the AssemblyBase::handleModeReached function // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function
// will be called // will be called
// Ignore failures for now.
pwrStateMachineWrapper(); pwrStateMachineWrapper();
} else { } else {
// For dual to single side transition, devices should be logically off, but the switch
// handling still needs to be done.
if (dualToSingleSideTransition) {
pwrStateMachine.start(targetMode, targetSubmode);
pwrStateMachineWrapper();
return;
}
finishModeOp(); finishModeOp();
} }
} }
@ -225,6 +247,7 @@ void DualLaneAssemblyBase::finishModeOp() {
pwrStateMachine.reset(); pwrStateMachine.reset();
powerRetryCounter = 0; powerRetryCounter = 0;
tryingOtherSide = false; tryingOtherSide = false;
dualToSingleSideTransition = false;
dualModeErrorSwitch = true; dualModeErrorSwitch = true;
} }

View File

@ -31,6 +31,7 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
uint8_t powerRetryCounter = 0; uint8_t powerRetryCounter = 0;
bool tryingOtherSide = false; bool tryingOtherSide = false;
bool dualModeErrorSwitch = true; bool dualModeErrorSwitch = true;
bool dualToSingleSideTransition = false;
duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE;
enum RecoveryCustomStates { enum RecoveryCustomStates {

View File

@ -3,6 +3,7 @@
#include <fsfw/devicehandlers/DeviceHandlerIF.h> #include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/subsystem/Subsystem.h> #include <fsfw/subsystem/Subsystem.h>
#include <mission/acsDefs.h> #include <mission/acsDefs.h>
#include <mission/sysDefs.h>
#include "acsModeTree.h" #include "acsModeTree.h"
#include "comModeTree.h" #include "comModeTree.h"
@ -16,6 +17,7 @@ namespace {
// Alias for checker function // Alias for checker function
const auto check = subsystem::checkInsert; const auto check = subsystem::checkInsert;
void buildBootSequence(Subsystem& ss, ModeListEntry& eh);
void buildSafeSequence(Subsystem& ss, ModeListEntry& eh); void buildSafeSequence(Subsystem& ss, ModeListEntry& eh);
void buildIdleSequence(Subsystem& ss, ModeListEntry& eh); void buildIdleSequence(Subsystem& ss, ModeListEntry& eh);
} // namespace } // namespace
@ -33,29 +35,36 @@ void satsystem::init() {
auto& comSubsystem = com::init(); auto& comSubsystem = com::init();
comSubsystem.connectModeTreeParent(EIVE_SYSTEM); comSubsystem.connectModeTreeParent(EIVE_SYSTEM);
ModeListEntry entry; ModeListEntry entry;
buildBootSequence(EIVE_SYSTEM, entry);
buildSafeSequence(EIVE_SYSTEM, entry); buildSafeSequence(EIVE_SYSTEM, entry);
buildIdleSequence(EIVE_SYSTEM, entry); buildIdleSequence(EIVE_SYSTEM, entry);
EIVE_SYSTEM.setInitialMode(HasModesIF::MODE_OFF, 0); EIVE_SYSTEM.setInitialMode(satsystem::Mode::BOOT, 0);
} }
EiveSystem satsystem::EIVE_SYSTEM = EiveSystem(objects::EIVE_SYSTEM, 12, 24); EiveSystem satsystem::EIVE_SYSTEM = EiveSystem(objects::EIVE_SYSTEM, 12, 24);
auto EIVE_SEQUENCE_SAFE = std::make_pair(acs::AcsMode::SAFE, FixedArrayList<ModeListEntry, 5>()); auto EIVE_SEQUENCE_BOOT = std::make_pair(satsystem::Mode::BOOT, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_BOOT_TGT =
std::make_pair((satsystem::Mode::BOOT << 24) | 1, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_BOOT_TRANS_0 =
std::make_pair((satsystem::Mode::BOOT << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto EIVE_SEQUENCE_SAFE = std::make_pair(satsystem::Mode::SAFE, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_SAFE_TGT = auto EIVE_TABLE_SAFE_TGT =
std::make_pair((acs::AcsMode::SAFE << 24) | 1, FixedArrayList<ModeListEntry, 5>()); std::make_pair((satsystem::Mode::SAFE << 24) | 1, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_SAFE_TRANS_0 = auto EIVE_TABLE_SAFE_TRANS_0 =
std::make_pair((acs::AcsMode::SAFE << 24) | 2, FixedArrayList<ModeListEntry, 5>()); std::make_pair((satsystem::Mode::SAFE << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_SAFE_TRANS_1 = auto EIVE_TABLE_SAFE_TRANS_1 =
std::make_pair((acs::AcsMode::SAFE << 24) | 3, FixedArrayList<ModeListEntry, 5>()); std::make_pair((satsystem::Mode::SAFE << 24) | 3, FixedArrayList<ModeListEntry, 5>());
auto EIVE_SEQUENCE_IDLE = auto EIVE_SEQUENCE_IDLE =
std::make_pair(acs::AcsMode::PTG_IDLE, FixedArrayList<ModeListEntry, 5>()); std::make_pair(satsystem::Mode::PTG_IDLE, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_IDLE_TGT = auto EIVE_TABLE_IDLE_TGT =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 1, FixedArrayList<ModeListEntry, 5>()); std::make_pair((satsystem::Mode::PTG_IDLE << 24) | 1, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_IDLE_TRANS_0 = auto EIVE_TABLE_IDLE_TRANS_0 =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 2, FixedArrayList<ModeListEntry, 5>()); std::make_pair((satsystem::Mode::PTG_IDLE << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_IDLE_TRANS_1 = auto EIVE_TABLE_IDLE_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 3, FixedArrayList<ModeListEntry, 5>()); std::make_pair((satsystem::Mode::PTG_IDLE << 24) | 3, FixedArrayList<ModeListEntry, 5>());
namespace { namespace {
@ -89,7 +98,6 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
// Build SAFE transition 0. // Build SAFE transition 0.
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second); iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second);
iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_SAFE_TRANS_0.second);
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TRANS_0.second); iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TRANS_0.second);
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TRANS_0.second, true); iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TRANS_0.second, true);
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_0.first, &EIVE_TABLE_SAFE_TRANS_0.second)), check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_0.first, &EIVE_TABLE_SAFE_TRANS_0.second)),
@ -140,4 +148,48 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
ctxc); ctxc);
} }
void buildBootSequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::buildBootSequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table,
bool allowAllSubmodes = false) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
if (allowAllSubmodes) {
eh.allowAllSubmodes();
}
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::OFF, 0, EIVE_TABLE_BOOT_TGT.second, true);
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TGT.second);
iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_BOOT_TGT.second);
iht(objects::TCS_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TGT.second);
check(ss.addTable(TableEntry(EIVE_TABLE_BOOT_TGT.first, &EIVE_TABLE_BOOT_TGT.second)), ctxc);
// Build SAFE transition 0.
iht(objects::TCS_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TRANS_0.second);
iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_BOOT_TRANS_0.second);
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TRANS_0.second);
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::OFF, 0, EIVE_TABLE_BOOT_TRANS_0.second, true);
check(ss.addTable(TableEntry(EIVE_TABLE_BOOT_TRANS_0.first, &EIVE_TABLE_BOOT_TRANS_0.second)),
ctxc);
// Build Safe sequence
ihs(EIVE_SEQUENCE_BOOT.second, EIVE_TABLE_BOOT_TGT.first, 0, false);
ihs(EIVE_SEQUENCE_BOOT.second, EIVE_TABLE_BOOT_TRANS_0.first, 0, false);
check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_BOOT.first, &EIVE_SEQUENCE_BOOT.second,
EIVE_SEQUENCE_SAFE.first)),
ctxc);
}
} // namespace } // namespace

2
tmtc

@ -1 +1 @@
Subproject commit 4f48c25bf757b6c056072049fe5965da890b4f5b Subproject commit e5a09e148b45d0380dc6d9a1a88002bab4b0376c