I2C reboot procedure for EIVE system #578

Merged
muellerr merged 17 commits from feature_i2c_reboot_procedure into develop 2023-04-07 11:07:05 +02:00
3 changed files with 76 additions and 58 deletions
Showing only changes of commit 9020014245 - Show all commits

View File

@ -2,6 +2,7 @@
#include <fsfw/storagemanager/LocalPool.h>
#include <fsfw/storagemanager/PoolManager.h>
#include <mission/power/gsDefs.h>
#include <mission/system/EiveSystem.h>
#include "OBSWConfig.h"
#include "bsp_q7s/core/CoreController.h"
@ -13,7 +14,7 @@
#include "linux/ObjectFactory.h"
#include "linux/callbacks/gpioCallbacks.h"
#include "mission/genericFactory.h"
#include "mission/system/tree/system.h"
#include "mission/system/systemTree.h"
#include "mission/tmtc/tmFilters.h"
void ObjectFactory::produce(void* args) {
@ -45,6 +46,8 @@ void ObjectFactory::produce(void* args) {
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
satsystem::EIVE_SYSTEM.setPowerSwitcher(pwrSwitcher);
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
#if OBSW_ADD_RAD_SENSORS == 1

View File

@ -54,7 +54,6 @@ void EiveSystem::announceMode(bool recursive) {
}
void EiveSystem::performChildOperation() {
ReturnValue_t result;
Subsystem::performChildOperation();
handleEventMessages();
if (not isInTransition and performSafeRecovery) {
@ -62,60 +61,7 @@ void EiveSystem::performChildOperation() {
performSafeRecovery = false;
return;
}
if (not isInTransition and performI2cReboot) {
if (i2cRebootState == I2cRebootState::SYSTEM_MODE_BOOT) {
startTransition(satsystem::Mode::BOOT, 0);
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT;
i2cRebootCountdown.resetTimer();
} else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT) {
if (mode == satsystem::Mode::BOOT) {
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_OFF);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
CommandMessage msg;
ActionMessage::setCommand(&msg, BpxBattery::REBOOT, store_address_t());
result = commandQueue->sendMessage(bpxBattQueueId, &msg);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_ON;
}
if (i2cRebootCountdown.hasTimedOut()) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
performI2cReboot = false;
}
} else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_ON) {
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_ON);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
i2cRebootState = I2cRebootState::SYSTEM_MODE_SAFE;
} else if (i2cRebootState == I2cRebootState::SYSTEM_MODE_SAFE) {
if (powerSwitcher->getSwitchState(power::Switches::P60_DOCK_3V3_STACK) ==
PowerSwitchIF::SWITCH_ON) {
// This should always be accepted
commandSelfToSafe();
i2cRebootState = I2cRebootState::NONE;
performI2cReboot = false;
actionHelper.finish(true, actionCommandedBy, EXECUTE_I2C_REBOOT);
}
}
// Timeout handling for the internal procedure.
if (i2cRebootState != I2cRebootState::NONE and i2cRebootCountdown.hasTimedOut()) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_ON);
// This should always be accepted
commandSelfToSafe();
}
}
i2cRecoveryLogic();
}
ReturnValue_t EiveSystem::initialize() {
@ -198,6 +144,71 @@ ReturnValue_t EiveSystem::executeAction(ActionId_t actionId, MessageQueueId_t co
return returnvalue::OK;
}
void EiveSystem::setPowerSwitcher(PowerSwitchIF* pwrSwitcher) {}
void EiveSystem::setPowerSwitcher(PowerSwitchIF* pwrSwitcher) { this->powerSwitcher = pwrSwitcher; }
void EiveSystem::i2cRecoveryLogic() {
ReturnValue_t result;
if (alreadyTriedI2cRecovery and i2cRecoveryClearCountdown.hasTimedOut()) {
alreadyTriedI2cRecovery = false;
}
if (not isInTransition and performI2cReboot) {
if (i2cRebootState == I2cRebootState::SYSTEM_MODE_BOOT) {
startTransition(satsystem::Mode::BOOT, 0);
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT;
i2cRebootCountdown.resetTimer();
} else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT) {
if (mode == satsystem::Mode::BOOT) {
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_OFF);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
CommandMessage msg;
ActionMessage::setCommand(&msg, BpxBattery::REBOOT, store_address_t());
result = commandQueue->sendMessage(bpxBattQueueId, &msg);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_ON;
}
if (i2cRebootCountdown.hasTimedOut()) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
performI2cReboot = false;
}
} else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_ON) {
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_ON);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
i2cRebootState = I2cRebootState::SYSTEM_MODE_SAFE;
} else if (i2cRebootState == I2cRebootState::SYSTEM_MODE_SAFE) {
if (powerSwitcher->getSwitchState(power::Switches::P60_DOCK_3V3_STACK) ==
PowerSwitchIF::SWITCH_ON) {
// This should always be accepted
commandSelfToSafe();
i2cRebootState = I2cRebootState::NONE;
alreadyTriedI2cRecovery = true;
i2cRecoveryClearCountdown.resetTimer();
performI2cReboot = false;
actionHelper.finish(true, actionCommandedBy, EXECUTE_I2C_REBOOT);
}
}
// Timeout handling for the internal procedure.
if (i2cRebootState != I2cRebootState::NONE and i2cRebootCountdown.hasTimedOut()) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_ON);
alreadyTriedI2cRecovery = true;
i2cRecoveryClearCountdown.resetTimer();
// This should always be accepted
commandSelfToSafe();
}
}
}
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }

View File

@ -27,18 +27,22 @@ class EiveSystem : public Subsystem, public HasActionsIF {
MessageQueueIF* eventQueue = nullptr;
bool performSafeRecovery = false;
bool performI2cReboot = false;
bool alreadyTriedI2cRecovery = false;
ActionHelper actionHelper;
PowerSwitchIF* powerSwitcher = nullptr;
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE;
Countdown i2cRebootCountdown = Countdown(10000);
// After 1 minute, clear the flag to avoid full reboots on I2C issues.
Countdown i2cRecoveryClearCountdown = Countdown(60000);
ReturnValue_t initialize() override;
void performChildOperation() override;
void announceMode(bool recursive) override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
void i2cRecoveryLogic();
void handleEventMessages();
void commandSelfToSafe();
};