diff --git a/CHANGELOG.md b/CHANGELOG.md index d4fa7a22..5c151397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,10 +34,12 @@ will consitute of a breaking change warranting a new major release: on the same system. - Add ACS board for EM by default now. - Add support for MPSoC HK packet. +- Add support for MPSoC Flash Directory Content Report. - Dynamically enable and disable HK packets for MPSoC on `ON` and `OFF` commands. - Add support for MPSoC Flash Directory Content Report. - Larger allowed path and file sizes for STR and PLOC MPSoC modules. - More robust MPSoC flash read and write command data handling. +- Increase frequency of payload handlers from 0.8 seconds to 0.5 seconds. ## Added @@ -51,6 +53,13 @@ will consitute of a breaking change warranting a new major release: 16505 type. - Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP funnel. +- PLOC Supervisor handler now has a power switcher assigned to make PLOC power switching work + without an additional PCDU power switch command. +- The PLOC Supervisor handler now waits for the replies to the `SET_TIME` command to verify working + communication. +- The PLOC MPSoC now waits 10 cycles before going to on. These wait cycles are necessary because + the MPSoC is not ready to process commands without this additional boot time. +- Fixed correction for `GPS Altitude` in case the sensor data is out of the expected bonds. # [v2.0.5] 2023-05-11 diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 12e9177f..8fcace4e 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -644,6 +644,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF), power::PDU1_CH6_PLOC_12V, *supvHelper); + supvHandler->setPowerSwitcher(&pwrSwitch); supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM); #endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ static_cast(consumer); diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index f2cd8229..5866ce8c 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -366,7 +366,7 @@ void scheduling::initTasks() { #endif /* OBSW_ADD_PLOC_SUPERVISOR */ PeriodicTaskIF* plTask = factory->createPeriodicTask( - "PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc, &RR_SCHEDULING); + "PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING); plTask->addComponent(objects::CAM_SWITCHER); scheduling::addMpsocSupvHandlers(plTask); scheduling::scheduleScexDev(plTask); diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 0311a468..36863b89 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -52,12 +52,12 @@ void ObjectFactory::produce(void* args) { // level components. dummy::DummyCfg dummyCfg; dummyCfg.addCoreCtrlCfg = false; + dummyCfg.addCamSwitcherDummy = false; #if OBSW_ADD_SYRLINKS == 1 dummyCfg.addSyrlinksDummies = false; #endif #if OBSW_ADD_PLOC_SUPERVISOR == 1 || OBSW_ADD_PLOC_MPSOC == 1 dummyCfg.addPlocDummies = false; - dummyCfg.addCamSwitcherDummy = false; #endif #if OBSW_ADD_GOMSPACE_PCDU == 1 dummyCfg.addPowerDummies = false; diff --git a/linux/payload/PlocMpsocHandler.cpp b/linux/payload/PlocMpsocHandler.cpp index 3462859b..0c2ce279 100644 --- a/linux/payload/PlocMpsocHandler.cpp +++ b/linux/payload/PlocMpsocHandler.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -104,6 +105,7 @@ void PlocMPSoCHandler::performOperationHook() { ReturnValue_t PlocMPSoCHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result = returnvalue::OK; + commandIsPending = true; switch (actionId) { case mpsoc::SET_UART_TX_TRISTATE: { uartIsolatorSwitch.pullLow(); @@ -165,32 +167,47 @@ ReturnValue_t PlocMPSoCHandler::executeAction(ActionId_t actionId, MessageQueueI } void PlocMPSoCHandler::doStartUp() { + if (startupState == StartupState::IDLE) { + startupState = StartupState::HW_INIT; + } + if (startupState == StartupState::HW_INIT) { #ifdef XIPHOS_Q7S #if not OBSW_MPSOC_JTAG_BOOT == 1 - switch (powerState) { - case PowerState::OFF: - commandActionHelper.commandAction(supervisorHandler, supv::START_MPSOC); - powerState = PowerState::BOOTING; - break; - case PowerState::ON: - hkReport.setReportingEnabled(true); - setMode(_MODE_TO_ON); - uartIsolatorSwitch.pullHigh(); - break; - default: - break; - } + switch (powerState) { + case PowerState::OFF: + commandActionHelper.commandAction(supervisorHandler, supv::START_MPSOC); + powerState = PowerState::BOOTING; + return; + case PowerState::ON: + uartIsolatorSwitch.pullHigh(); + startupState = StartupState::WAIT_CYCLES; + break; + default: + return; + } #else - powerState = PowerState::ON; - hkReport.setReportingEnabled(true); - setMode(_MODE_TO_ON); - uartIsolatorSwitch.pullHigh(); + uartIsolatorSwitch.pullHigh(); + startupState = StartupState::WAIT_CYCLES; #endif /* not MSPOC_JTAG_BOOT == 1 */ #else - powerState = PowerState::ON; - hkReport.setReportingEnabled(true); - setMode(_MODE_TO_ON); + startupState = StartupState::WAIT_CYCLES; + powerState = PowerState::ON; #endif /* XIPHOS_Q7S */ + } + // Need to wait, MPSoC still not booted properly, requesting HK without these wait cycles does + // not work, no replies.. + if (startupState == StartupState::WAIT_CYCLES) { + waitCycles++; + if (waitCycles >= 8) { + startupState = StartupState::DONE; + waitCycles = 0; + } + } + if (startupState == StartupState::DONE) { + setMode(_MODE_TO_ON); + hkReport.setReportingEnabled(true); + startupState = StartupState::IDLE; + } } void PlocMPSoCHandler::doShutDown() { @@ -218,11 +235,16 @@ void PlocMPSoCHandler::doShutDown() { powerState = PowerState::OFF; #endif #endif + startupState = StartupState::IDLE; } ReturnValue_t PlocMPSoCHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { - *id = mpsoc::TC_GET_HK_REPORT; - return buildCommandFromCommand(*id, nullptr, 0); + if (not commandIsPending) { + *id = mpsoc::TC_GET_HK_REPORT; + commandIsPending = true; + return buildCommandFromCommand(*id, nullptr, 0); + } + return NOTHING_TO_SEND; } ReturnValue_t PlocMPSoCHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { @@ -345,9 +367,9 @@ void PlocMPSoCHandler::fillCommandAndReplyMap() { this->insertInReplyMap(mpsoc::ACK_REPORT, 3, nullptr, mpsoc::SIZE_ACK_REPORT); this->insertInReplyMap(mpsoc::EXE_REPORT, 3, nullptr, mpsoc::SIZE_EXE_REPORT); this->insertInReplyMap(mpsoc::TM_MEMORY_READ_REPORT, 2, nullptr, mpsoc::SIZE_TM_MEM_READ_REPORT); - this->insertInReplyMap(mpsoc::TM_GET_HK_REPORT, 2, nullptr, mpsoc::SIZE_TM_HK_REPORT); + this->insertInReplyMap(mpsoc::TM_GET_HK_REPORT, 5, nullptr, mpsoc::SIZE_TM_HK_REPORT); this->insertInReplyMap(mpsoc::TM_CAM_CMD_RPT, 2, nullptr, mpsoc::SP_MAX_SIZE); - this->insertInReplyMap(mpsoc::TM_FLASH_DIRECTORY_CONTENT, 2, nullptr, 0); + this->insertInReplyMap(mpsoc::TM_FLASH_DIRECTORY_CONTENT, 2, nullptr, mpsoc::SP_MAX_SIZE); } ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remainingSize, @@ -403,13 +425,14 @@ ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remain *foundId = mpsoc::EXE_REPORT; break; default: { - sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid apid" << std::endl; + sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid APID 0x" << std::hex + << std::setfill('0') << std::setw(2) << apid << std::dec << std::endl; *foundLen = remainingSize; return MPSoCReturnValuesIF::INVALID_APID; } } - uint16_t recvSeqCnt = (*(start + 2) << 8 | *(start + 3)) & PACKET_SEQUENCE_COUNT_MASK; + uint16_t recvSeqCnt = ((*(start + 2) << 8) | *(start + 3)) & PACKET_SEQUENCE_COUNT_MASK; if (recvSeqCnt != sequenceCount) { triggerEvent(MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH, sequenceCount, recvSeqCnt); sequenceCount = recvSeqCnt; @@ -469,13 +492,14 @@ void PlocMPSoCHandler::setNormalDatapoolEntriesInvalid() { hkReport.setValidity(false, true); } -uint32_t PlocMPSoCHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 5000; } +uint32_t PlocMPSoCHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 10000; } ReturnValue_t PlocMPSoCHandler::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); @@ -493,6 +517,7 @@ ReturnValue_t PlocMPSoCHandler::initializeLocalDataPool(localpool::DataPool& loc 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); @@ -611,13 +636,12 @@ ReturnValue_t PlocMPSoCHandler::prepareTcDownlinkPwrOff() { } ReturnValue_t PlocMPSoCHandler::prepareTcGetHkReport() { - ReturnValue_t result = returnvalue::OK; - mpsoc::TcGetHkReport tcDownlinkPwrOff(spParams, sequenceCount); - result = tcDownlinkPwrOff.buildPacket(); + mpsoc::TcGetHkReport tcGetHkReport(spParams, sequenceCount); + ReturnValue_t result = tcGetHkReport.buildPacket(); if (result != returnvalue::OK) { return result; } - finishTcPrep(tcDownlinkPwrOff.getFullPacketLen()); + finishTcPrep(tcGetHkReport.getFullPacketLen()); return returnvalue::OK; } @@ -793,8 +817,23 @@ ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) { uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK; + auto cmdDoneHandler = [&](bool success) { + if (normalCmdPending) { + normalCmdPending = false; + } + commandIsPending = false; + auto commandIter = deviceCommandMap.find(getPendingCommand()); + if (commandIter != deviceCommandMap.end()) { + commandIter->second.isExecuting = false; + if (commandIter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) { + actionHelper.finish(success, commandIter->second.sendReplyTo, getPendingCommand(), result); + } + } + disableAllReplies(); + }; switch (apid) { case (mpsoc::apid::EXE_SUCCESS): { + cmdDoneHandler(true); break; } case (mpsoc::apid::EXE_FAILURE): { @@ -810,8 +849,8 @@ ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) { } printStatus(data); sendFailureReport(mpsoc::EXE_REPORT, MPSoCReturnValuesIF::RECEIVED_EXE_FAILURE); - disableExeReportReply(); result = IGNORE_REPLY_DATA; + cmdDoneHandler(false); break; } default: { @@ -1159,6 +1198,14 @@ void PlocMPSoCHandler::setNextReplyId() { case mpsoc::TC_MEM_READ: nextReplyId = mpsoc::TM_MEMORY_READ_REPORT; break; + case mpsoc::TC_FLASH_GET_DIRECTORY_CONTENT: { + nextReplyId = mpsoc::TM_FLASH_DIRECTORY_CONTENT; + break; + } + case mpsoc::TC_GET_HK_REPORT: { + nextReplyId = mpsoc::TM_GET_HK_REPORT; + break; + } default: /* If no telemetry is expected the next reply is always the execution report */ nextReplyId = mpsoc::EXE_REPORT; @@ -1387,12 +1434,12 @@ void PlocMPSoCHandler::disableExeReportReply() { } void PlocMPSoCHandler::printStatus(const uint8_t* data) { - uint16_t status = *(data + STATUS_OFFSET) << 8 | *(data + STATUS_OFFSET + 1); + uint16_t status = (*(data + STATUS_OFFSET) << 8) | *(data + STATUS_OFFSET + 1); sif::info << "Verification report status: " << getStatusString(status) << std::endl; } uint16_t PlocMPSoCHandler::getStatus(const uint8_t* data) { - return *(data + STATUS_OFFSET) << 8 | *(data + STATUS_OFFSET + 1); + return (*(data + STATUS_OFFSET) << 8) | *(data + STATUS_OFFSET + 1); } void PlocMPSoCHandler::handleActionCommandFailure(ActionId_t actionId) { diff --git a/linux/payload/PlocMpsocHandler.h b/linux/payload/PlocMpsocHandler.h index a6a866ef..a6af8156 100644 --- a/linux/payload/PlocMpsocHandler.h +++ b/linux/payload/PlocMpsocHandler.h @@ -108,6 +108,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF { mpsoc::HkReport hkReport; + bool normalCmdPending = false; MessageQueueIF* eventQueue = nullptr; MessageQueueIF* commandActionHelperQueue = nullptr; @@ -117,7 +118,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF { SpacePacketCreator creator; ploc::SpTcParams spParams = ploc::SpTcParams(creator); - PoolEntry peStatus = PoolEntry(); + PoolEntry peStatus = PoolEntry(); PoolEntry peMode = PoolEntry(); PoolEntry peDownlinkPwrOn = PoolEntry(); PoolEntry peDownlinkReplyActive = PoolEntry(); @@ -168,6 +169,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF { // Used to block incoming commands when MPSoC helper class is currently executing a command bool plocMPSoCHelperExecuting = false; + bool commandIsPending = false; struct TmMemReadReport { static const uint8_t FIX_SIZE = 14; @@ -183,7 +185,9 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF { size_t foundPacketLen = 0; TelemetryBuffer tmBuffer; + uint32_t waitCycles = 0; + enum class StartupState { IDLE, HW_INIT, WAIT_CYCLES, DONE } startupState = StartupState::IDLE; enum class PowerState { OFF, BOOTING, SHUTDOWN, ON }; PowerState powerState = PowerState::OFF; diff --git a/linux/payload/PlocSupervisorHandler.cpp b/linux/payload/PlocSupervisorHandler.cpp index 06a4cf07..682b8020 100644 --- a/linux/payload/PlocSupervisorHandler.cpp +++ b/linux/payload/PlocSupervisorHandler.cpp @@ -151,7 +151,7 @@ void PlocSupervisorHandler::doStartUp() { } } } - if (startupState == StartupState::SET_TIME_EXECUTING) { + if (startupState == StartupState::TIME_WAS_SET) { startupState = StartupState::ON; } if (startupState == StartupState::ON) { @@ -176,7 +176,7 @@ ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* ReturnValue_t PlocSupervisorHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { if (startupState == StartupState::SET_TIME) { *id = supv::SET_TIME_REF; - startupState = StartupState::SET_TIME_EXECUTING; + startupState = StartupState::WAIT_FOR_TIME_REPLY; return buildCommandFromCommand(*id, nullptr, 0); } return NOTHING_TO_SEND; @@ -1909,6 +1909,10 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionRepor case supv::SET_TIME_REF: { // We could only allow proper bootup when the time was set successfully, but // this makes debugging difficult. + + if (startupState == StartupState::WAIT_FOR_TIME_REPLY) { + startupState = StartupState::TIME_WAS_SET; + } break; } default: diff --git a/linux/payload/PlocSupervisorHandler.h b/linux/payload/PlocSupervisorHandler.h index 78c20205..3e5ac2a0 100644 --- a/linux/payload/PlocSupervisorHandler.h +++ b/linux/payload/PlocSupervisorHandler.h @@ -99,7 +99,14 @@ class PlocSupervisorHandler : public DeviceHandlerBase { static const uint32_t MRAM_DUMP_TIMEOUT = 60000; // 4 s static const uint32_t BOOT_TIMEOUT = 4000; - enum class StartupState : uint8_t { OFF, BOOTING, SET_TIME, SET_TIME_EXECUTING, ON }; + enum class StartupState : uint8_t { + OFF, + BOOTING, + SET_TIME, + WAIT_FOR_TIME_REPLY, + TIME_WAS_SET, + ON + }; static constexpr bool SET_TIME_DURING_BOOT = true; diff --git a/linux/payload/plocMpscoDefs.h b/linux/payload/plocMpscoDefs.h index d7bfa028..3d74fe0d 100644 --- a/linux/payload/plocMpscoDefs.h +++ b/linux/payload/plocMpscoDefs.h @@ -85,7 +85,6 @@ static const DeviceCommandId_t TC_FLASH_GET_DIRECTORY_CONTENT = 28; static const DeviceCommandId_t TM_FLASH_DIRECTORY_CONTENT = 29; static constexpr DeviceCommandId_t TC_FLASH_READ_FULL_FILE = 30; - // Will reset the sequence count of the OBSW static const DeviceCommandId_t OBSW_RESET_SEQ_COUNT = 50; @@ -128,7 +127,10 @@ static const uint16_t ACK_FAILURE = 0x401; static const uint16_t EXE_SUCCESS = 0x402; static const uint16_t EXE_FAILURE = 0x403; static const uint16_t TM_MEMORY_READ_REPORT = 0x404; +<<<<<<< HEAD static const uint16_t TM_FLASH_READ_REPORT = 0x405; +======= +>>>>>>> origin/v2.1.0-dev static constexpr uint16_t TM_FLASH_DIRECTORY_CONTENT = 0x406; static const uint16_t TM_CAM_CMD_RPT = 0x407; static constexpr uint16_t TM_HK_GET_REPORT = 0x408; @@ -660,9 +662,6 @@ class TcDownlinkPwrOn : public TcBase { } }; -/** - * @brief Class to build replay stop space packet. - */ class TcGetHkReport : public TcBase { public: TcGetHkReport(ploc::SpTcParams params, uint16_t sequenceCount) @@ -676,12 +675,21 @@ class TcGetDirContent : public TcBase { ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) { ReturnValue_t result = returnvalue::OK; +<<<<<<< HEAD spParams.setFullPayloadLen(commandDataLen + sizeof(NULL_TERMINATOR) + CRC_SIZE); +======= + // Yeah it needs to be 256.. even if the path is shorter. + spParams.setFullPayloadLen(256 + CRC_SIZE); +>>>>>>> origin/v2.1.0-dev if (result != returnvalue::OK) { return result; } std::memcpy(payloadStart, commandData, commandDataLen); +<<<<<<< HEAD *(payloadStart + commandDataLen) = NULL_TERMINATOR; +======= + payloadStart[255] = '\0'; +>>>>>>> origin/v2.1.0-dev return result; } }; @@ -987,8 +995,7 @@ class HkReport : public StaticLocalDataSet<36> { lp_var_t(sid.objectId, mpsoc::poolid::SEM_UNCORRECTABLE_ERRS, this); lp_var_t semCorrectableErrs = lp_var_t(sid.objectId, mpsoc::poolid::SEM_CORRECTABLE_ERRS, this); - lp_var_t semStatus = - lp_var_t(sid.objectId, mpsoc::poolid::SEM_CORRECTABLE_ERRS, this); + lp_var_t semStatus = lp_var_t(sid.objectId, mpsoc::poolid::SEM_STATUS, this); lp_var_t rebootMpsocRequired = lp_var_t(sid.objectId, mpsoc::poolid::REBOOT_MPSOC_REQUIRED, this); }; diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index 4cc15a16..b106baaa 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -573,7 +573,7 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong // Altitude FDIR if (gpsAltitude > gpsParameters->maximumFdirAltitude || - gpsAltitude < gpsParameters->maximumFdirAltitude) { + gpsAltitude < gpsParameters->minimumFdirAltitude) { altitude = gpsParameters->fdirAltitude; } else { altitude = gpsAltitude; diff --git a/tmtc b/tmtc index 13fd9a7d..dd3e4c64 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 13fd9a7d84645535496e9ff2855118e5d0b59916 +Subproject commit dd3e4c649b687ea6b9444389439f3f2d5a558ad2