eive-obsw/linux/payload/FreshMpsocHandler.cpp
Robin Mueller 96d957f7b1
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
enough of this for today
2024-04-11 13:44:35 +02:00

311 lines
12 KiB
C++

#include "FreshMpsocHandler.h"
#include "fsfw/action/CommandActionHelper.h"
#include "fsfw/devicehandlers/FreshDeviceHandlerBase.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "linux/payload/MpsocCommunication.h"
#include "linux/payload/plocSupvDefs.h"
FreshMpsocHandler::FreshMpsocHandler(DhbConfig cfg, MpsocCommunication& comInterface,
PlocMpsocSpecialComHelper* plocMPSoCHelper,
Gpio uartIsolatorSwitch, object_id_t supervisorHandler)
: FreshDeviceHandlerBase(cfg),
comInterface(comInterface),
specialComHelper(plocMPSoCHelper),
commandActionHelper(this),
uartIsolatorSwitch(uartIsolatorSwitch),
hkReport(this) {
commandActionHelperQueue = QueueFactory::instance()->createMessageQueue(10);
eventQueue = QueueFactory::instance()->createMessageQueue(10);
}
void FreshMpsocHandler::performDeviceOperation(uint8_t opCode) {
if (not transitionActive and mode == MODE_OFF) {
// Nothing to do for now.
return;
}
}
ReturnValue_t FreshMpsocHandler::handleCommandMessage(CommandMessage* message) {
return FreshDeviceHandlerBase::handleCommandMessage(message);
}
ReturnValue_t FreshMpsocHandler::initialize() {
ReturnValue_t result = FreshDeviceHandlerBase::initialize();
if (result != returnvalue::OK) {
return result;
}
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PlocMPSoCHandler::initialize: Invalid event manager" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
;
}
result = manager->registerListener(eventQueue->getId());
if (result != returnvalue::OK) {
return result;
}
result = manager->subscribeToEvent(
eventQueue->getId(), event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_WRITE_FAILED));
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->subscribeToEvent(
eventQueue->getId(),
event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_WRITE_SUCCESSFUL));
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->subscribeToEvent(
eventQueue->getId(),
event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_READ_SUCCESSFUL));
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->subscribeToEvent(
eventQueue->getId(), event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_READ_FAILED));
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
specialComHelper->setSequenceCount(&sequenceCount);
result = commandActionHelper.initialize();
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
return result;
}
// HK manager abstract functions.
LocalPoolDataSetBase* FreshMpsocHandler::getDataSetHandle(sid_t sid) {
if (sid == hkReport.getSid()) {
return &hkReport;
}
return nullptr;
}
ReturnValue_t FreshMpsocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(mpsoc::poolid::STATUS, &peStatus);
localDataPoolMap.emplace(mpsoc::poolid::MODE, &peMode);
localDataPoolMap.emplace(mpsoc::poolid::DOWNLINK_PWR_ON, &peDownlinkPwrOn);
localDataPoolMap.emplace(mpsoc::poolid::DOWNLINK_REPLY_ACTIIVE, &peDownlinkReplyActive);
localDataPoolMap.emplace(mpsoc::poolid::DOWNLINK_JESD_SYNC_STATUS, &peDownlinkJesdSyncStatus);
localDataPoolMap.emplace(mpsoc::poolid::DOWNLINK_DAC_STATUS, &peDownlinkDacStatus);
localDataPoolMap.emplace(mpsoc::poolid::CAM_STATUS, &peCameraStatus);
localDataPoolMap.emplace(mpsoc::poolid::CAM_SDI_STATUS, &peCameraSdiStatus);
localDataPoolMap.emplace(mpsoc::poolid::CAM_FPGA_TEMP, &peCameraFpgaTemp);
localDataPoolMap.emplace(mpsoc::poolid::CAM_SOC_TEMP, &peCameraSocTemp);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_TEMP, &peSysmonTemp);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCCINT, &peSysmonVccInt);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCCAUX, &peSysmonVccAux);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCCBRAM, &peSysmonVccBram);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCCPAUX, &peSysmonVccPaux);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCCPINT, &peSysmonVccPint);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCCPDRO, &peSysmonVccPdro);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_MB12V, &peSysmonMb12V);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_MB3V3, &peSysmonMb3V3);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_MB1V8, &peSysmonMb1V8);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC12V, &peSysmonVcc12V);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC5V, &peSysmonVcc5V);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC3V3, &peSysmonVcc3V3);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC3V3VA, &peSysmonVcc3V3VA);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC2V5DDR, &peSysmonVcc2V5DDR);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC1V2DDR, &peSysmonVcc1V2DDR);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC0V9, &peSysmonVcc0V9);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_VCC0V6VTT, &peSysmonVcc0V6VTT);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_SAFE_COTS_CUR, &peSysmonSafeCotsCur);
localDataPoolMap.emplace(mpsoc::poolid::SYSMON_NVM4_XO_CUR, &peSysmonNvm4XoCur);
localDataPoolMap.emplace(mpsoc::poolid::SEM_UNCORRECTABLE_ERRS, &peSemUncorrectableErrs);
localDataPoolMap.emplace(mpsoc::poolid::SEM_CORRECTABLE_ERRS, &peSemCorrectableErrs);
localDataPoolMap.emplace(mpsoc::poolid::SEM_STATUS, &peSemStatus);
localDataPoolMap.emplace(mpsoc::poolid::REBOOT_MPSOC_REQUIRED, &peRebootMpsocRequired);
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(hkReport.getSid(), false, 10.0));
return returnvalue::OK;
}
// Mode abstract functions
ReturnValue_t FreshMpsocHandler::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
return returnvalue::OK;
}
// Action override. Forward to user.
ReturnValue_t FreshMpsocHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
ReturnValue_t result = returnvalue::OK;
switch (actionId) {
case mpsoc::SET_UART_TX_TRISTATE: {
uartIsolatorSwitch.pullLow();
return EXECUTION_FINISHED;
break;
}
case mpsoc::RELEASE_UART_TX: {
uartIsolatorSwitch.pullHigh();
return EXECUTION_FINISHED;
break;
default:
break;
}
}
if (specialComHelperExecuting) {
return MPSoCReturnValuesIF::MPSOC_HELPER_EXECUTING;
}
switch (actionId) {
case mpsoc::TC_FLASH_WRITE_FULL_FILE: {
mpsoc::FlashBasePusCmd flashWritePusCmd;
result = flashWritePusCmd.extractFields(data, size);
if (result != returnvalue::OK) {
return result;
}
result = specialComHelper->startFlashWrite(flashWritePusCmd.getObcFile(),
flashWritePusCmd.getMPSoCFile());
if (result != returnvalue::OK) {
return result;
}
specialComHelperExecuting = true;
return EXECUTION_FINISHED;
}
case mpsoc::TC_FLASH_READ_FULL_FILE: {
mpsoc::FlashReadPusCmd flashReadPusCmd;
result = flashReadPusCmd.extractFields(data, size);
if (result != returnvalue::OK) {
return result;
}
result = specialComHelper->startFlashRead(flashReadPusCmd.getObcFile(),
flashReadPusCmd.getMPSoCFile(),
flashReadPusCmd.getReadSize());
if (result != returnvalue::OK) {
return result;
}
specialComHelperExecuting = true;
return EXECUTION_FINISHED;
}
case (mpsoc::OBSW_RESET_SEQ_COUNT): {
sequenceCount = 0;
return EXECUTION_FINISHED;
}
default:
break;
}
// For longer commands, do not set these.
commandIsPending = true;
cmdCountdown.resetTimer();
// TODO: Do all the stuff the form buildDeviceFromDevice blah did.
return returnvalue::OK;
}
/**
* @overload
* @param submode
*/
void FreshMpsocHandler::startTransition(Mode_t newMode, Submode_t submode) {}
ReturnValue_t FreshMpsocHandler::performDeviceOperationPreQueueHandling(uint8_t opCode) {
return returnvalue::OK;
}
void FreshMpsocHandler::handleTransitionToOn() {}
void FreshMpsocHandler::handleTransitionToOff() {}
MessageQueueIF* FreshMpsocHandler::getCommandQueuePtr() { return commandActionHelperQueue; }
void FreshMpsocHandler::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) { return; }
void FreshMpsocHandler::stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) {
switch (actionId) {
case supv::START_MPSOC: {
sif::warning << "PlocMPSoCHandler::stepFailedReceived: Failed to start MPSoC" << std::endl;
break;
}
case supv::SHUTDOWN_MPSOC: {
triggerEvent(MPSOC_SHUTDOWN_FAILED);
sif::warning << "PlocMPSoCHandler::stepFailedReceived: Failed to shutdown MPSoC" << std::endl;
break;
}
default:
sif::debug << "PlocMPSoCHandler::stepFailedReceived: Received unexpected action reply"
<< std::endl;
break;
}
powerState = PowerState::SUPV_FAILED;
}
void FreshMpsocHandler::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
return;
}
void FreshMpsocHandler::completionSuccessfulReceived(ActionId_t actionId) {
if (actionId == supv::ACK_REPORT) {
// I seriously don't know why this happens..
// sif::warning
// << "PlocMpsocHandler::completionSuccessfulReceived: Only received ACK report. Consider
// "
// "increasing the MPSoC boot timer."
// << std::endl;
} else if (actionId != supv::EXE_REPORT) {
sif::warning << "PlocMpsocHandler::completionSuccessfulReceived: Did not expect the action "
<< "ID " << actionId << std::endl;
return;
}
switch (powerState) {
case PowerState::PENDING_STARTUP: {
mpsocBootTransitionCd.resetTimer();
powerState = PowerState::DONE;
break;
}
case PowerState::PENDING_SHUTDOWN: {
powerState = PowerState::DONE;
break;
}
default: {
break;
}
}
}
void FreshMpsocHandler::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) {
handleActionCommandFailure(actionId);
}
void FreshMpsocHandler::handleActionCommandFailure(ActionId_t actionId) {
switch (actionId) {
case supv::ACK_REPORT:
case supv::EXE_REPORT:
break;
default:
sif::warning << "PlocMPSoCHandler::handleActionCommandFailure: Did not expect the action ID "
<< actionId << std::endl;
return;
}
switch (powerState) {
case PowerState::PENDING_STARTUP: {
sif::info << "PlocMPSoCHandler::handleActionCommandFailure: MPSoC boot command failed"
<< std::endl;
// This is commonly the case when the MPSoC is already operational. Thus the power state is
// set to on here
break;
}
case PowerState::PENDING_SHUTDOWN: {
// FDIR will intercept event and switch PLOC power off
triggerEvent(MPSOC_SHUTDOWN_FAILED);
sif::warning << "PlocMPSoCHandler::handleActionCommandFailure: Failed to shutdown MPSoC"
<< std::endl;
break;
}
default:
break;
}
powerState = PowerState::SUPV_FAILED;
return;
}