I2C reboot procedure for EIVE system #578
@ -2,6 +2,7 @@
|
|||||||
#include <fsfw/storagemanager/LocalPool.h>
|
#include <fsfw/storagemanager/LocalPool.h>
|
||||||
#include <fsfw/storagemanager/PoolManager.h>
|
#include <fsfw/storagemanager/PoolManager.h>
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
|
#include <mission/system/EiveSystem.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/core/CoreController.h"
|
#include "bsp_q7s/core/CoreController.h"
|
||||||
@ -13,7 +14,7 @@
|
|||||||
#include "linux/ObjectFactory.h"
|
#include "linux/ObjectFactory.h"
|
||||||
#include "linux/callbacks/gpioCallbacks.h"
|
#include "linux/callbacks/gpioCallbacks.h"
|
||||||
#include "mission/genericFactory.h"
|
#include "mission/genericFactory.h"
|
||||||
#include "mission/system/tree/system.h"
|
#include "mission/system/systemTree.h"
|
||||||
#include "mission/tmtc/tmFilters.h"
|
#include "mission/tmtc/tmFilters.h"
|
||||||
|
|
||||||
void ObjectFactory::produce(void* args) {
|
void ObjectFactory::produce(void* args) {
|
||||||
@ -45,6 +46,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
|
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
|
||||||
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
||||||
|
satsystem::EIVE_SYSTEM.setPowerSwitcher(pwrSwitcher);
|
||||||
|
|
||||||
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
||||||
|
|
||||||
#if OBSW_ADD_RAD_SENSORS == 1
|
#if OBSW_ADD_RAD_SENSORS == 1
|
||||||
|
@ -54,7 +54,6 @@ void EiveSystem::announceMode(bool recursive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EiveSystem::performChildOperation() {
|
void EiveSystem::performChildOperation() {
|
||||||
ReturnValue_t result;
|
|
||||||
Subsystem::performChildOperation();
|
Subsystem::performChildOperation();
|
||||||
handleEventMessages();
|
handleEventMessages();
|
||||||
if (not isInTransition and performSafeRecovery) {
|
if (not isInTransition and performSafeRecovery) {
|
||||||
@ -62,60 +61,7 @@ void EiveSystem::performChildOperation() {
|
|||||||
performSafeRecovery = false;
|
performSafeRecovery = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (not isInTransition and performI2cReboot) {
|
i2cRecoveryLogic();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t EiveSystem::initialize() {
|
ReturnValue_t EiveSystem::initialize() {
|
||||||
@ -198,6 +144,71 @@ ReturnValue_t EiveSystem::executeAction(ActionId_t actionId, MessageQueueId_t co
|
|||||||
return returnvalue::OK;
|
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); }
|
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }
|
||||||
|
@ -27,18 +27,22 @@ class EiveSystem : public Subsystem, public HasActionsIF {
|
|||||||
MessageQueueIF* eventQueue = nullptr;
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
bool performSafeRecovery = false;
|
bool performSafeRecovery = false;
|
||||||
bool performI2cReboot = false;
|
bool performI2cReboot = false;
|
||||||
|
bool alreadyTriedI2cRecovery = false;
|
||||||
|
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
PowerSwitchIF* powerSwitcher = nullptr;
|
PowerSwitchIF* powerSwitcher = nullptr;
|
||||||
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
|
||||||
MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE;
|
||||||
Countdown i2cRebootCountdown = Countdown(10000);
|
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;
|
ReturnValue_t initialize() override;
|
||||||
void performChildOperation() override;
|
void performChildOperation() override;
|
||||||
void announceMode(bool recursive) override;
|
void announceMode(bool recursive) override;
|
||||||
|
|
||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) override;
|
const uint8_t* data, size_t size) override;
|
||||||
|
void i2cRecoveryLogic();
|
||||||
void handleEventMessages();
|
void handleEventMessages();
|
||||||
void commandSelfToSafe();
|
void commandSelfToSafe();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user