fixed merge conflicts
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
||||
target_sources(${OBSW_NAME} PRIVATE
|
||||
GPSHyperionLinuxController.cpp
|
||||
)
|
||||
target_sources(${OBSW_NAME} PRIVATE GPSHyperionLinuxController.cpp)
|
||||
endif()
|
||||
|
||||
target_sources(${OBSW_NAME} PRIVATE Max31865RtdLowlevelHandler.cpp)
|
||||
|
||||
add_subdirectory(ploc)
|
||||
add_subdirectory(startracker)
|
||||
|
@ -57,12 +57,12 @@ ReturnValue_t GPSHyperionLinuxController::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
switch (actionId) {
|
||||
case (GpsHyperion::TRIGGER_RESET_PIN): {
|
||||
case (GpsHyperion::TRIGGER_RESET_PIN_GNSS): {
|
||||
if (resetCallback != nullptr) {
|
||||
PoolReadGuard pg(&gpsSet);
|
||||
// Set HK entries invalid
|
||||
gpsSet.setValidity(false, true);
|
||||
resetCallback(resetCallbackArgs);
|
||||
resetCallback(data, size, resetCallbackArgs);
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
|
@ -30,7 +30,7 @@ class GPSHyperionLinuxController : public ExtendedControllerBase {
|
||||
bool debugHyperionGps = false);
|
||||
virtual ~GPSHyperionLinuxController();
|
||||
|
||||
using gpioResetFunction_t = ReturnValue_t (*)(void* args);
|
||||
using gpioResetFunction_t = ReturnValue_t (*)(const uint8_t* actionData, size_t len, void* args);
|
||||
|
||||
void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void* args);
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
|
465
linux/devices/Max31865RtdLowlevelHandler.cpp
Normal file
465
linux/devices/Max31865RtdLowlevelHandler.cpp
Normal file
@ -0,0 +1,465 @@
|
||||
#include "Max31865RtdLowlevelHandler.h"
|
||||
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <fsfw_hal/linux/spi/ManualCsLockGuard.h>
|
||||
|
||||
#define OBSW_RTD_AUTO_MODE 1
|
||||
|
||||
#if OBSW_RTD_AUTO_MODE == 1
|
||||
static constexpr uint8_t BASE_CFG = (MAX31865::Bias::ON << MAX31865::CfgBitPos::BIAS_SEL) |
|
||||
(MAX31865::Wires::FOUR_WIRE << MAX31865::CfgBitPos::WIRE_SEL) |
|
||||
(MAX31865::ConvMode::AUTO << MAX31865::CfgBitPos::CONV_MODE);
|
||||
#else
|
||||
static constexpr uint8_t BASE_CFG =
|
||||
(MAX31865::Bias::OFF << MAX31865::CfgBitPos::BIAS_SEL) |
|
||||
(MAX31865::Wires::FOUR_WIRE << MAX31865::CfgBitPos::WIRE_SEL) |
|
||||
(MAX31865::ConvMode::NORM_OFF << MAX31865::CfgBitPos::CONV_MODE);
|
||||
#endif
|
||||
|
||||
Max31865RtdReader::Max31865RtdReader(object_id_t objectId, SpiComIF* lowLevelComIF, GpioIF* gpioIF)
|
||||
: SystemObject(objectId), rtds(EiveMax31855::NUM_RTDS), comIF(lowLevelComIF), gpioIF(gpioIF) {
|
||||
readerMutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::performOperation(uint8_t operationCode) {
|
||||
using namespace MAX31865;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
static_cast<void>(result);
|
||||
// Stopwatch watch;
|
||||
if (periodicInitHandling()) {
|
||||
#if OBSW_RTD_AUTO_MODE == 0
|
||||
// 10 ms delay for VBIAS startup
|
||||
TaskFactory::delayTask(10);
|
||||
#endif
|
||||
} else {
|
||||
// No devices usable (e.g. TCS board off)
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
#if OBSW_RTD_AUTO_MODE == 0
|
||||
result = periodicReadReqHandling();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
// After requesting, 65 milliseconds delay required
|
||||
TaskFactory::delayTask(65);
|
||||
#endif
|
||||
|
||||
return periodicReadHandling();
|
||||
}
|
||||
|
||||
bool Max31865RtdReader::rtdIsActive(uint8_t idx) {
|
||||
if (rtds[idx]->on and rtds[idx]->active and rtds[idx]->configured) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Max31865RtdReader::periodicInitHandling() {
|
||||
using namespace MAX31865;
|
||||
MutexGuard mg(readerMutex);
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (mg.getLockResult() != RETURN_OK) {
|
||||
sif::warning << "Max31865RtdReader::periodicInitHandling: Mutex lock failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& rtd : rtds) {
|
||||
if (rtd == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if ((rtd->on or rtd->active) and not rtd->configured and rtd->cd.hasTimedOut()) {
|
||||
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
|
||||
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
|
||||
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
|
||||
break;
|
||||
}
|
||||
result = writeCfgReg(rtd->spiCookie, BASE_CFG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
handleSpiError(rtd, result, "writeCfgReg");
|
||||
}
|
||||
if (rtd->writeLowThreshold) {
|
||||
result = writeLowThreshold(rtd->spiCookie, rtd->lowThreshold);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
handleSpiError(rtd, result, "writeLowThreshold");
|
||||
}
|
||||
}
|
||||
if (rtd->writeHighThreshold) {
|
||||
result = writeHighThreshold(rtd->spiCookie, rtd->highThreshold);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
handleSpiError(rtd, result, "writeHighThreshold");
|
||||
}
|
||||
}
|
||||
result = clearFaultStatus(rtd->spiCookie);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
handleSpiError(rtd, result, "clearFaultStatus");
|
||||
}
|
||||
rtd->configured = true;
|
||||
rtd->db.configured = true;
|
||||
if (rtd->active) {
|
||||
rtd->db.active = true;
|
||||
}
|
||||
}
|
||||
if (rtd->active and rtd->configured and not rtd->db.active) {
|
||||
rtd->db.active = true;
|
||||
}
|
||||
}
|
||||
bool someRtdUsable = false;
|
||||
for (auto& rtd : rtds) {
|
||||
if (rtd == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (rtdIsActive(rtd->idx)) {
|
||||
#if OBSW_RTD_AUTO_MODE == 0
|
||||
result = writeBiasSel(Bias::ON, rtd->spiCookie, BASE_CFG);
|
||||
#endif
|
||||
someRtdUsable = true;
|
||||
}
|
||||
}
|
||||
return someRtdUsable;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::periodicReadReqHandling() {
|
||||
using namespace MAX31865;
|
||||
MutexGuard mg(readerMutex);
|
||||
if (mg.getLockResult() != RETURN_OK) {
|
||||
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
// Now request one shot config for all active RTDs
|
||||
for (auto& rtd : rtds) {
|
||||
if (rtd == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (rtdIsActive(rtd->idx)) {
|
||||
ReturnValue_t result = writeCfgReg(rtd->spiCookie, BASE_CFG | (1 << CfgBitPos::ONE_SHOT));
|
||||
if (result != RETURN_OK) {
|
||||
handleSpiError(rtd, result, "writeCfgReg");
|
||||
// Release mutex ASAP
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::periodicReadHandling() {
|
||||
using namespace MAX31865;
|
||||
auto result = RETURN_OK;
|
||||
MutexGuard mg(readerMutex);
|
||||
if (mg.getLockResult() != RETURN_OK) {
|
||||
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
// Now read the RTD values
|
||||
for (auto& rtd : rtds) {
|
||||
if (rtd == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (rtdIsActive(rtd->idx)) {
|
||||
uint16_t rtdVal = 0;
|
||||
bool faultBitSet = false;
|
||||
result = readRtdVal(rtd->spiCookie, rtdVal, faultBitSet);
|
||||
if (result != RETURN_OK) {
|
||||
handleSpiError(rtd, result, "readRtdVal");
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (faultBitSet) {
|
||||
rtd->db.faultBitSet = faultBitSet;
|
||||
}
|
||||
rtd->db.adcCode = rtdVal;
|
||||
}
|
||||
}
|
||||
#if OBSW_RTD_AUTO_MODE == 0
|
||||
for (auto& rtd : rtds) {
|
||||
if (rtd == nullptr) {
|
||||
continue;
|
||||
}
|
||||
// Even if a device was made inactive, turn off the bias here. If it was turned off, not
|
||||
// necessary anymore..
|
||||
if (rtd->on) {
|
||||
result = writeBiasSel(Bias::OFF, rtd->spiCookie, BASE_CFG);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::initializeInterface(CookieIF* cookie) {
|
||||
if (cookie == nullptr) {
|
||||
throw std::invalid_argument("Invalid MAX31865 Reader Cookie");
|
||||
}
|
||||
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
|
||||
ReturnValue_t result = comIF->initializeInterface(rtdCookie->spiCookie);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (rtdCookie->idx > EiveMax31855::NUM_RTDS) {
|
||||
throw std::invalid_argument("Invalid RTD index");
|
||||
}
|
||||
rtds[rtdCookie->idx] = rtdCookie;
|
||||
MutexGuard mg(readerMutex);
|
||||
if (dbLen == 0) {
|
||||
dbLen = rtdCookie->db.getSerializedSize();
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
size_t sendLen) {
|
||||
if (cookie == nullptr) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
// Empty command.. don't fail for now
|
||||
if (sendLen < 1) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
MutexGuard mg(readerMutex);
|
||||
if (mg.getLockResult() != RETURN_OK) {
|
||||
sif::warning << "Max31865RtdReader::sendMessage: Mutex lock failed" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
|
||||
uint8_t cmdRaw = sendData[0];
|
||||
if (cmdRaw > EiveMax31855::RtdCommands::NUM_CMDS) {
|
||||
sif::warning << "Max31865RtdReader::sendMessage: Invalid command" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
auto thresholdHandler = [](Max31865ReaderCookie* rtdCookie, const uint8_t* sendData) {
|
||||
rtdCookie->lowThreshold = (sendData[1] << 8) | sendData[2];
|
||||
rtdCookie->highThreshold = (sendData[3] << 8) | sendData[4];
|
||||
rtdCookie->writeLowThreshold = true;
|
||||
rtdCookie->writeHighThreshold = true;
|
||||
};
|
||||
|
||||
auto cmd = static_cast<EiveMax31855::RtdCommands>(sendData[0]);
|
||||
switch (cmd) {
|
||||
case (EiveMax31855::RtdCommands::ON): {
|
||||
if (not rtdCookie->on) {
|
||||
rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS);
|
||||
rtdCookie->cd.resetTimer();
|
||||
rtdCookie->on = true;
|
||||
rtdCookie->active = false;
|
||||
rtdCookie->configured = false;
|
||||
if (sendLen == 5) {
|
||||
thresholdHandler(rtdCookie, sendData);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (EiveMax31855::RtdCommands::ACTIVE): {
|
||||
if (not rtdCookie->on) {
|
||||
rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS);
|
||||
rtdCookie->cd.resetTimer();
|
||||
rtdCookie->on = true;
|
||||
rtdCookie->active = true;
|
||||
rtdCookie->configured = false;
|
||||
} else {
|
||||
rtdCookie->active = true;
|
||||
}
|
||||
if (sendLen == 5) {
|
||||
thresholdHandler(rtdCookie, sendData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (EiveMax31855::RtdCommands::OFF): {
|
||||
rtdCookie->on = false;
|
||||
rtdCookie->active = false;
|
||||
rtdCookie->configured = false;
|
||||
break;
|
||||
}
|
||||
case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): {
|
||||
if (sendLen == 3) {
|
||||
rtdCookie->highThreshold = (sendData[1] << 8) | sendData[2];
|
||||
rtdCookie->writeHighThreshold = true;
|
||||
} else {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (EiveMax31855::RtdCommands::LOW_THRESHOLD): {
|
||||
if (sendLen == 3) {
|
||||
rtdCookie->lowThreshold = (sendData[1] << 8) | sendData[2];
|
||||
rtdCookie->writeLowThreshold = true;
|
||||
} else {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (EiveMax31855::RtdCommands::CFG):
|
||||
default: {
|
||||
// TODO: Only implement if needed
|
||||
break;
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::getSendSuccess(CookieIF* cookie) { return RETURN_OK; }
|
||||
|
||||
ReturnValue_t Max31865RtdReader::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
size_t* size) {
|
||||
MutexGuard mg(readerMutex);
|
||||
if (mg.getLockResult() != RETURN_OK) {
|
||||
// TODO: Emit warning
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
|
||||
uint8_t* exchangePtr = rtdCookie->exchangeBuf.data();
|
||||
size_t serLen = 0;
|
||||
auto result = rtdCookie->db.serialize(&exchangePtr, &serLen, rtdCookie->exchangeBuf.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
if (result != RETURN_OK) {
|
||||
// TODO: Emit warning
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
*buffer = reinterpret_cast<uint8_t*>(rtdCookie->exchangeBuf.data());
|
||||
*size = serLen;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::writeCfgReg(SpiCookie* cookie, uint8_t cfg) {
|
||||
using namespace MAX31865;
|
||||
return writeNToReg(cookie, CONFIG, 1, &cfg, nullptr);
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie,
|
||||
uint8_t baseCfg) {
|
||||
using namespace MAX31865;
|
||||
if (bias == MAX31865::Bias::OFF) {
|
||||
baseCfg &= ~(1 << CfgBitPos::BIAS_SEL);
|
||||
} else {
|
||||
baseCfg |= (1 << CfgBitPos::BIAS_SEL);
|
||||
}
|
||||
return writeCfgReg(cookie, baseCfg);
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::clearFaultStatus(SpiCookie* cookie) {
|
||||
using namespace MAX31865;
|
||||
// Read back the current configuration to avoid overwriting it when clearing te fault status
|
||||
uint8_t currentCfg = 0;
|
||||
auto result = readCfgReg(cookie, currentCfg);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
// Clear bytes 5, 3 and 2 which need to be 0
|
||||
currentCfg &= ~0x2C;
|
||||
currentCfg |= (1 << CfgBitPos::FAULT_STATUS_CLEAR);
|
||||
return writeCfgReg(cookie, currentCfg);
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::readCfgReg(SpiCookie* cookie, uint8_t& cfg) {
|
||||
using namespace MAX31865;
|
||||
uint8_t* replyPtr = nullptr;
|
||||
auto result = readNFromReg(cookie, CONFIG, 1, &replyPtr);
|
||||
if (result == RETURN_OK) {
|
||||
cfg = replyPtr[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::writeLowThreshold(SpiCookie* cookie, uint16_t val) {
|
||||
using namespace MAX31865;
|
||||
uint8_t cmd[2] = {static_cast<uint8_t>((val >> 8) & 0xff), static_cast<uint8_t>(val & 0xff)};
|
||||
return writeNToReg(cookie, LOW_THRESHOLD, 2, cmd, nullptr);
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::writeHighThreshold(SpiCookie* cookie, uint16_t val) {
|
||||
using namespace MAX31865;
|
||||
uint8_t cmd[2] = {static_cast<uint8_t>((val >> 8) & 0xff), static_cast<uint8_t>(val & 0xff)};
|
||||
return writeNToReg(cookie, HIGH_THRESHOLD, 2, cmd, nullptr);
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::readLowThreshold(SpiCookie* cookie, uint16_t& lowThreshold) {
|
||||
using namespace MAX31865;
|
||||
uint8_t* replyPtr = nullptr;
|
||||
auto result = readNFromReg(cookie, LOW_THRESHOLD, 2, &replyPtr);
|
||||
if (result == RETURN_OK) {
|
||||
lowThreshold = (replyPtr[0] << 8) | replyPtr[1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::readHighThreshold(SpiCookie* cookie, uint16_t& highThreshold) {
|
||||
using namespace MAX31865;
|
||||
uint8_t* replyPtr = nullptr;
|
||||
auto result = readNFromReg(cookie, HIGH_THRESHOLD, 2, &replyPtr);
|
||||
if (result == RETURN_OK) {
|
||||
highThreshold = (replyPtr[0] << 8) | replyPtr[1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::writeNToReg(SpiCookie* cookie, uint8_t reg, size_t n, uint8_t* cmd,
|
||||
uint8_t** reply) {
|
||||
using namespace MAX31865;
|
||||
if (n > cmdBuf.size() - 1) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
cmdBuf[0] = reg | WRITE_BIT;
|
||||
for (size_t idx = 0; idx < n; idx++) {
|
||||
cmdBuf[idx + 1] = cmd[idx];
|
||||
}
|
||||
return comIF->sendMessage(cookie, cmdBuf.data(), n + 1);
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet) {
|
||||
using namespace MAX31865;
|
||||
uint8_t* replyPtr = nullptr;
|
||||
auto result = readNFromReg(cookie, RTD, 2, &replyPtr);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (replyPtr[1] & 0b0000'0001) {
|
||||
faultBitSet = true;
|
||||
}
|
||||
// Shift 1 to the right to remove fault bit
|
||||
val = ((replyPtr[0] << 8) | replyPtr[1]) >> 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::readNFromReg(SpiCookie* cookie, uint8_t reg, size_t n,
|
||||
uint8_t** reply) {
|
||||
using namespace MAX31865;
|
||||
if (n > 4) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
// Clear write bit in any case
|
||||
reg &= ~WRITE_BIT;
|
||||
cmdBuf[0] = reg;
|
||||
std::memset(cmdBuf.data() + 1, 0, n);
|
||||
ReturnValue_t result = comIF->sendMessage(cookie, cmdBuf.data(), n + 1);
|
||||
if (result != RETURN_OK) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
size_t dummyLen = 0;
|
||||
uint8_t* replyPtr = nullptr;
|
||||
result = comIF->readReceivedMessage(cookie, &replyPtr, &dummyLen);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (reply != nullptr) {
|
||||
*reply = replyPtr + 1;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result,
|
||||
const char* ctx) {
|
||||
cookie->db.spiErrorCount.value += 1;
|
||||
sif::warning << "Max31865RtdReader::handleSpiError: " << ctx << " | Failed with result " << result
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Max31865RtdReader::initialize() {
|
||||
csLock = comIF->getCsMutex();
|
||||
return SystemObject::initialize();
|
||||
}
|
87
linux/devices/Max31865RtdLowlevelHandler.h
Normal file
87
linux/devices/Max31865RtdLowlevelHandler.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef LINUX_DEVICES_MAX31865RTDREADER_H_
|
||||
#define LINUX_DEVICES_MAX31865RTDREADER_H_
|
||||
|
||||
#include <fsfw/ipc/MutexIF.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceCommunicationIF.h"
|
||||
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||
|
||||
struct Max31865ReaderCookie : public CookieIF {
|
||||
Max31865ReaderCookie(){};
|
||||
Max31865ReaderCookie(object_id_t handlerId_, uint8_t idx_, const std::string& locString_,
|
||||
SpiCookie* spiCookie_)
|
||||
: idx(idx_), handlerId(handlerId_), locString(locString_), spiCookie(spiCookie_) {}
|
||||
|
||||
uint8_t idx = 0;
|
||||
object_id_t handlerId = objects::NO_OBJECT;
|
||||
|
||||
std::string locString = "";
|
||||
std::array<uint8_t, 12> exchangeBuf{};
|
||||
Countdown cd = Countdown(MAX31865::WARMUP_MS);
|
||||
|
||||
bool on = false;
|
||||
bool configured = false;
|
||||
bool active = false;
|
||||
bool writeLowThreshold = false;
|
||||
bool writeHighThreshold = false;
|
||||
uint16_t lowThreshold = 0;
|
||||
uint16_t highThreshold = 0;
|
||||
SpiCookie* spiCookie = nullptr;
|
||||
|
||||
// Exchange data buffer struct
|
||||
EiveMax31855::ReadOutStruct db;
|
||||
};
|
||||
|
||||
class Max31865RtdReader : public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public DeviceCommunicationIF {
|
||||
public:
|
||||
Max31865RtdReader(object_id_t objectId, SpiComIF* lowLevelComIF, GpioIF* gpioIF);
|
||||
|
||||
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
std::vector<Max31865ReaderCookie*> rtds;
|
||||
std::array<uint8_t, 4> cmdBuf = {};
|
||||
size_t dbLen = 0;
|
||||
MutexIF* readerMutex;
|
||||
|
||||
SpiComIF* comIF;
|
||||
GpioIF* gpioIF;
|
||||
MutexIF::TimeoutType csTimeoutType = MutexIF::TimeoutType::BLOCKING;
|
||||
uint32_t csTimeoutMs = 0;
|
||||
MutexIF* csLock = nullptr;
|
||||
|
||||
bool periodicInitHandling();
|
||||
ReturnValue_t periodicReadReqHandling();
|
||||
ReturnValue_t periodicReadHandling();
|
||||
|
||||
bool rtdIsActive(uint8_t idx);
|
||||
ReturnValue_t writeCfgReg(SpiCookie* cookie, uint8_t cfg);
|
||||
ReturnValue_t writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie, uint8_t baseCfg);
|
||||
ReturnValue_t readCfgReg(SpiCookie* cookie, uint8_t& cfg);
|
||||
ReturnValue_t readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet);
|
||||
ReturnValue_t writeLowThreshold(SpiCookie* cookie, uint16_t val);
|
||||
ReturnValue_t writeHighThreshold(SpiCookie* cookie, uint16_t val);
|
||||
ReturnValue_t readLowThreshold(SpiCookie* cookie, uint16_t& val);
|
||||
ReturnValue_t readHighThreshold(SpiCookie* cookie, uint16_t& val);
|
||||
ReturnValue_t clearFaultStatus(SpiCookie* cookie);
|
||||
|
||||
ReturnValue_t readNFromReg(SpiCookie* cookie, uint8_t reg, size_t n, uint8_t** reply);
|
||||
ReturnValue_t writeNToReg(SpiCookie* cookie, uint8_t reg, size_t n, uint8_t* cmd,
|
||||
uint8_t** reply);
|
||||
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
ReturnValue_t getSendSuccess(CookieIF* cookie) override;
|
||||
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||
|
||||
ReturnValue_t handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result, const char* ctx);
|
||||
};
|
||||
|
||||
#endif /* LINUX_DEVICES_MAX31865RTDREADER_H_ */
|
@ -100,6 +100,33 @@ static const uint16_t TC_WRITE_SEQ_EXECUTION_DELAY = 80;
|
||||
// Requires approx. 2 seconds for execution. 8 => 4 seconds
|
||||
static const uint16_t TC_DOWNLINK_PWR_ON_EXECUTION_DELAY = 8;
|
||||
|
||||
namespace status_code {
|
||||
static const uint16_t UNKNOWN_APID = 0x5DD;
|
||||
static const uint16_t INCORRECT_LENGTH = 0x5DE;
|
||||
static const uint16_t INCORRECT_CRC = 0x5DF;
|
||||
static const uint16_t INCORRECT_PKT_SEQ_CNT = 0x5E0;
|
||||
static const uint16_t TC_NOT_ALLOWED_IN_MODE = 0x5E1;
|
||||
static const uint16_t TC_EXEUTION_DISABLED = 0x5E2;
|
||||
static const uint16_t FLASH_MOUNT_FAILED = 0x5E3;
|
||||
static const uint16_t FLASH_FILE_ALREADY_CLOSED = 0x5E4;
|
||||
static const uint16_t FLASH_FILE_OPEN_FAILED = 0x5E5;
|
||||
static const uint16_t FLASH_FILE_ALREDY_OPEN = 0x5E6;
|
||||
static const uint16_t FLASH_FILE_NOT_OPEN = 0x5E7;
|
||||
static const uint16_t FLASH_UNMOUNT_FAILED = 0x5E8;
|
||||
static const uint16_t HEAP_ALLOCATION_FAILED = 0x5E9;
|
||||
static const uint16_t INVALID_PARAMETER = 0x5EA;
|
||||
static const uint16_t NOT_INITIALIZED = 0x5EB;
|
||||
static const uint16_t REBOOT_IMMINENT = 0x5EC;
|
||||
static const uint16_t CORRUPT_DATA = 0x5ED;
|
||||
static const uint16_t FLASH_CORRECTABLE_MISMATCH = 0x5EE;
|
||||
static const uint16_t FLASH_UNCORRECTABLE_MISMATCH = 0x5EF;
|
||||
static const uint16_t RESERVED_0 = 0x5F0;
|
||||
static const uint16_t RESERVED_1 = 0x5F1;
|
||||
static const uint16_t RESERVED_2 = 0x5F2;
|
||||
static const uint16_t RESERVED_3 = 0x5F3;
|
||||
static const uint16_t RESERVED_4 = 0x5F4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abstract base class for TC space packet of MPSoC.
|
||||
*/
|
||||
@ -656,9 +683,13 @@ class TcCamcmdSend : public TcBase {
|
||||
if (commandDataLen > MAX_DATA_LENGTH) {
|
||||
return INVALID_LENGTH;
|
||||
}
|
||||
std::memcpy(this->getPacketData(), commandData, commandDataLen);
|
||||
*(this->getPacketData() + commandDataLen) = CARRIAGE_RETURN;
|
||||
uint16_t trueLength = commandDataLen + sizeof(CARRIAGE_RETURN) + CRC_SIZE;
|
||||
uint16_t dataLen = static_cast<uint16_t>(commandDataLen + sizeof(CARRIAGE_RETURN));
|
||||
size_t size = sizeof(dataLen);
|
||||
SerializeAdapter::serialize(&dataLen, this->getPacketData(), &size, sizeof(dataLen),
|
||||
SerializeIF::Endianness::BIG);
|
||||
std::memcpy(this->getPacketData() + sizeof(dataLen), commandData, commandDataLen);
|
||||
*(this->getPacketData() + sizeof(dataLen) + commandDataLen) = CARRIAGE_RETURN;
|
||||
uint16_t trueLength = sizeof(dataLen) + commandDataLen + sizeof(CARRIAGE_RETURN) + CRC_SIZE;
|
||||
this->setPacketDataLength(trueLength - 1);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ static const DeviceCommandId_t LOGGING_SET_TOPIC = 56;
|
||||
static const DeviceCommandId_t REQUEST_ADC_REPORT = 57;
|
||||
static const DeviceCommandId_t RESET_PL = 58;
|
||||
static const DeviceCommandId_t ENABLE_NVMS = 59;
|
||||
static const DeviceCommandId_t CONTINUE_UPDATE = 60;
|
||||
|
||||
/** Reply IDs */
|
||||
static const DeviceCommandId_t ACK_REPORT = 100;
|
||||
@ -309,6 +310,9 @@ class ApidOnlyPacket : public SpacePacket {
|
||||
*/
|
||||
class MPSoCBootSelect : public SpacePacket {
|
||||
public:
|
||||
static const uint8_t NVM0 = 0;
|
||||
static const uint8_t NVM1 = 1;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
@ -316,8 +320,10 @@ class MPSoCBootSelect : public SpacePacket {
|
||||
* @param bp0 Partition pin 0
|
||||
* @param bp1 Partition pin 1
|
||||
* @param bp2 Partition pin 2
|
||||
*
|
||||
* @note Selection of partitions is currently not supported.
|
||||
*/
|
||||
MPSoCBootSelect(uint8_t mem, uint8_t bp0, uint8_t bp1, uint8_t bp2)
|
||||
MPSoCBootSelect(uint8_t mem = 0, uint8_t bp0 = 0, uint8_t bp1 = 0, uint8_t bp2 = 0)
|
||||
: SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE, DEFAULT_SEQUENCE_COUNT),
|
||||
mem(mem),
|
||||
bp0(bp0),
|
||||
@ -1460,7 +1466,9 @@ class ExecutionReport : public VerificationReport {
|
||||
OUT_OF_RANGE = 0x103,
|
||||
OUT_OF_HEAP_MEMORY = 0x104,
|
||||
INVALID_STATE_TRANSITION = 0x105,
|
||||
MPSOC_BOOT_FAILED = 0x106,
|
||||
MPSOC_ALREADY_BOOTING = 0x106,
|
||||
MPSOC_ALREADY_OPERATIONAL = 0x107,
|
||||
MPSOC_BOOT_FAILED = 0x108,
|
||||
SP_NOT_AVAILABLE = 0x200,
|
||||
SP_DATA_INSUFFICIENT = 0x201,
|
||||
SP_MEMORY_ID_INVALID = 0x202,
|
||||
@ -1594,6 +1602,14 @@ class ExecutionReport : public VerificationReport {
|
||||
sif::warning << STATUS_PRINTOUT_PREFIX << "Invalid state transition" << std::endl;
|
||||
break;
|
||||
}
|
||||
case StatusCode::MPSOC_ALREADY_BOOTING: {
|
||||
sif::warning << STATUS_PRINTOUT_PREFIX << "MPSoC already booting" << std::endl;
|
||||
break;
|
||||
}
|
||||
case StatusCode::MPSOC_ALREADY_OPERATIONAL: {
|
||||
sif::warning << STATUS_PRINTOUT_PREFIX << "MPSoC already operational" << std::endl;
|
||||
break;
|
||||
}
|
||||
case StatusCode::MPSOC_BOOT_FAILED: {
|
||||
sif::warning << STATUS_PRINTOUT_PREFIX << "MPSoC boot failed" << std::endl;
|
||||
break;
|
||||
|
@ -1,7 +1,4 @@
|
||||
target_sources(${OBSW_NAME} PRIVATE
|
||||
PlocSupervisorHandler.cpp
|
||||
PlocMemoryDumper.cpp
|
||||
PlocMPSoCHandler.cpp
|
||||
PlocMPSoCHelper.cpp
|
||||
PlocSupvHelper.cpp
|
||||
)
|
||||
target_sources(
|
||||
${OBSW_NAME}
|
||||
PRIVATE PlocSupervisorHandler.cpp PlocMemoryDumper.cpp PlocMPSoCHandler.cpp
|
||||
PlocMPSoCHelper.cpp PlocSupvHelper.cpp)
|
||||
|
@ -589,14 +589,14 @@ ReturnValue_t PlocMPSoCHandler::handleAckReport(const uint8_t* data) {
|
||||
|
||||
switch (apid) {
|
||||
case mpsoc::apid::ACK_FAILURE: {
|
||||
// TODO: Interpretation of status field in acknowledgment report
|
||||
sif::debug << "PlocMPSoCHandler::handleAckReport: Received Ack failure report" << std::endl;
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
uint16_t status = getStatus(data);
|
||||
printStatus(data);
|
||||
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
|
||||
triggerEvent(ACK_FAILURE, commandId, status);
|
||||
}
|
||||
sendFailureReport(mpsoc::ACK_REPORT, MPSoCReturnValuesIF::RECEIVED_ACK_FAILURE);
|
||||
sendFailureReport(mpsoc::ACK_REPORT, status);
|
||||
disableAllReplies();
|
||||
nextReplyId = mpsoc::NONE;
|
||||
result = IGNORE_REPLY_DATA;
|
||||
@ -683,17 +683,17 @@ ReturnValue_t PlocMPSoCHandler::handleCamCmdRpt(const uint8_t* data) {
|
||||
if (result == MPSoCReturnValuesIF::CRC_FAILURE) {
|
||||
sif::warning << "PlocMPSoCHandler::handleCamCmdRpt: CRC failure" << std::endl;
|
||||
}
|
||||
const uint8_t* dataFieldPtr = data + mpsoc::SPACE_PACKET_HEADER_SIZE;
|
||||
const uint8_t* dataFieldPtr = data + mpsoc::SPACE_PACKET_HEADER_SIZE + sizeof(uint16_t);
|
||||
std::string camCmdRptMsg(
|
||||
reinterpret_cast<const char*>(dataFieldPtr),
|
||||
tmCamCmdRpt.rememberSpacePacketSize - mpsoc::SPACE_PACKET_HEADER_SIZE - 3);
|
||||
tmCamCmdRpt.rememberSpacePacketSize - mpsoc::SPACE_PACKET_HEADER_SIZE - sizeof(uint16_t) - 3);
|
||||
#if OBSW_DEBUG_PLOC_MPSOC == 1
|
||||
uint8_t ackValue = *(packet.getPacketData() + packet.getPacketDataLength() - 2);
|
||||
sif::info << "PlocMPSoCHandler: CamCmdRpt message: " << camCmdRptMsg << std::endl;
|
||||
sif::info << "PlocMPSoCHandler: CamCmdRpt Ack value: 0x" << std::hex
|
||||
<< static_cast<unsigned int>(ackValue) << std::endl;
|
||||
#endif /* OBSW_DEBUG_PLOC_MPSOC == 1 */
|
||||
handleDeviceTM(packet.getPacketData(), packet.getPacketDataLength() - 1, mpsoc::TM_CAM_CMD_RPT);
|
||||
handleDeviceTM(packet.getPacketData() + sizeof(uint16_t), packet.getPacketDataLength() - 1, mpsoc::TM_CAM_CMD_RPT);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -994,7 +994,7 @@ void PlocMPSoCHandler::disableExeReportReply() {
|
||||
|
||||
void PlocMPSoCHandler::printStatus(const uint8_t* data) {
|
||||
uint16_t status = *(data + STATUS_OFFSET) << 8 | *(data + STATUS_OFFSET + 1);
|
||||
sif::info << "Verification report status: 0x" << std::hex << status << std::endl;
|
||||
sif::info << "Verification report status: " << getStatusString(status) << std::endl;
|
||||
}
|
||||
|
||||
uint16_t PlocMPSoCHandler::getStatus(const uint8_t* data) {
|
||||
@ -1033,3 +1033,79 @@ void PlocMPSoCHandler::handleActionCommandFailure(ActionId_t actionId) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::string PlocMPSoCHandler::getStatusString(uint16_t status) {
|
||||
switch(status) {
|
||||
case(mpsoc::status_code::UNKNOWN_APID): {
|
||||
return "Unknown APID";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::INCORRECT_LENGTH): {
|
||||
return "Incorrect length";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::INCORRECT_CRC): {
|
||||
return "Incorrect crc";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::INCORRECT_PKT_SEQ_CNT): {
|
||||
return "Incorrect packet sequence count";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::TC_NOT_ALLOWED_IN_MODE): {
|
||||
return "TC not allowed in this mode";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::TC_EXEUTION_DISABLED): {
|
||||
return "TC execution disabled";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::FLASH_MOUNT_FAILED): {
|
||||
return "Flash mount failed";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::FLASH_FILE_ALREADY_CLOSED): {
|
||||
return "Flash file already closed";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::FLASH_FILE_NOT_OPEN): {
|
||||
return "Flash file not open";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::FLASH_UNMOUNT_FAILED): {
|
||||
return "Flash unmount failed";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::HEAP_ALLOCATION_FAILED): {
|
||||
return "Heap allocation failed";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::INVALID_PARAMETER): {
|
||||
return "Invalid parameter";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::NOT_INITIALIZED): {
|
||||
return "Not initialized";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::REBOOT_IMMINENT): {
|
||||
return "Reboot imminent";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::CORRUPT_DATA): {
|
||||
return "Corrupt data";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::FLASH_CORRECTABLE_MISMATCH): {
|
||||
return "Flash correctable mismatch";
|
||||
break;
|
||||
}
|
||||
case(mpsoc::status_code::FLASH_UNCORRECTABLE_MISMATCH): {
|
||||
return "Flash uncorrectable mismatch";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -108,7 +108,11 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
MessageQueueIF* commandActionHelperQueue = nullptr;
|
||||
|
||||
SourceSequenceCounter sequenceCount;
|
||||
// Initiate the sequence count with the maximum value. It is incremented before
|
||||
// a packet is sent, so the first value will be 0 accordingly using
|
||||
// the wrap around of the counter.
|
||||
SourceSequenceCounter sequenceCount =
|
||||
SourceSequenceCounter(SpacePacketBase::LIMIT_SEQUENCE_COUNT - 1);
|
||||
|
||||
uint8_t commandBuffer[mpsoc::MAX_COMMAND_SIZE];
|
||||
|
||||
@ -259,6 +263,8 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
||||
uint16_t getStatus(const uint8_t* data);
|
||||
|
||||
void handleActionCommandFailure(ActionId_t actionId);
|
||||
|
||||
std::string getStatusString(uint16_t status);
|
||||
};
|
||||
|
||||
#endif /* BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ */
|
||||
|
@ -118,6 +118,11 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId,
|
||||
plocSupvHelperExecuting = true;
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case CONTINUE_UPDATE: {
|
||||
supvHelper->initiateUpdateContinuation();
|
||||
plocSupvHelperExecuting = true;
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case LOGGING_REQUEST_EVENT_BUFFERS: {
|
||||
if (size > config::MAX_PATH_SIZE) {
|
||||
return SupvReturnValuesIF::FILENAME_TOO_LONG;
|
||||
@ -137,7 +142,8 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId,
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::doStartUp() {
|
||||
switch (startupState) {
|
||||
if (setTimeDuringStartup) {
|
||||
switch (startupState) {
|
||||
case StartupState::OFF: {
|
||||
bootTimeout.resetTimer();
|
||||
startupState = StartupState::BOOTING;
|
||||
@ -158,6 +164,9 @@ void PlocSupervisorHandler::doStartUp() {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::doShutDown() {
|
||||
@ -436,8 +445,9 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
|
||||
&mramDumpTimeout);
|
||||
this->insertInCommandAndReplyMap(CONSECUTIVE_MRAM_DUMP, 0, nullptr, 0, false, false,
|
||||
CONSECUTIVE_MRAM_DUMP, &mramDumpTimeout);
|
||||
this->insertInReplyMap(ACK_REPORT, 3, nullptr, SIZE_ACK_REPORT);
|
||||
this->insertInReplyMap(EXE_REPORT, 0, nullptr, SIZE_EXE_REPORT, false, &executionTimeout);
|
||||
this->insertInReplyMap(ACK_REPORT, 3, nullptr, SIZE_ACK_REPORT, false,
|
||||
&acknowledgementReportTimeout);
|
||||
this->insertInReplyMap(EXE_REPORT, 0, nullptr, SIZE_EXE_REPORT, false, &executionReportTimeout);
|
||||
this->insertInReplyMap(HK_REPORT, 3, &hkset, SIZE_HK_REPORT);
|
||||
this->insertInReplyMap(BOOT_STATUS_REPORT, 3, &bootStatusReport, SIZE_BOOT_STATUS_REPORT);
|
||||
this->insertInReplyMap(LATCHUP_REPORT, 3, &latchupStatusReport, SIZE_LATCHUP_STATUS_REPORT);
|
||||
@ -572,14 +582,14 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
setExecutionTimeout(command->first);
|
||||
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, EXE_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " << EXE_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
setExecutionTimeout(command->first);
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
@ -814,7 +824,9 @@ void PlocSupervisorHandler::handleEvent(EventMessage* eventMessage) {
|
||||
// After execution of update procedure, PLOC is in a state where it draws approx. 700 mA of
|
||||
// current. To leave this state the shutdown MPSoC command must be sent here.
|
||||
if (event == PlocSupvHelper::SUPV_UPDATE_FAILED ||
|
||||
event == PlocSupvHelper::SUPV_UPDATE_SUCCESSFUL) {
|
||||
event == PlocSupvHelper::SUPV_UPDATE_SUCCESSFUL ||
|
||||
event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_FAILED ||
|
||||
event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_SUCCESSFUL) {
|
||||
result = this->executeAction(supv::SHUTDOWN_MPSOC, NO_COMMANDER, nullptr, 0);
|
||||
if (result != RETURN_OK) {
|
||||
triggerEvent(SUPV_MPSOC_SHUWDOWN_BUILD_FAILED);
|
||||
@ -837,13 +849,13 @@ void PlocSupervisorHandler::setExecutionTimeout(DeviceCommandId_t command) {
|
||||
switch (command) {
|
||||
case FIRST_MRAM_DUMP:
|
||||
case CONSECUTIVE_MRAM_DUMP:
|
||||
executionTimeout.setTimeout(MRAM_DUMP_EXECUTION_TIMEOUT);
|
||||
executionReportTimeout.setTimeout(MRAM_DUMP_EXECUTION_TIMEOUT);
|
||||
break;
|
||||
case COPY_ADC_DATA_TO_MRAM:
|
||||
executionTimeout.setTimeout(COPY_ADC_TO_MRAM_TIMEOUT);
|
||||
executionReportTimeout.setTimeout(COPY_ADC_TO_MRAM_TIMEOUT);
|
||||
break;
|
||||
default:
|
||||
executionTimeout.setTimeout(EXECUTION_DEFAULT_TIMEOUT);
|
||||
executionReportTimeout.setTimeout(EXECUTION_DEFAULT_TIMEOUT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -957,6 +969,7 @@ ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) {
|
||||
|
||||
if (result == SupvReturnValuesIF::CRC_FAILURE) {
|
||||
sif::error << "PlocSupervisorHandler::handleHkReport: Hk report has invalid crc" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t offset = supv::DATA_FIELD_OFFSET;
|
||||
@ -1062,8 +1075,9 @@ ReturnValue_t PlocSupervisorHandler::handleBootStatusReport(const uint8_t* data)
|
||||
nextReplyId = supv::EXE_REPORT;
|
||||
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
sif::info << "PlocSupervisorHandler::handleBootStatusReport: SoC State (0 - off, 1 - booting, 3 "
|
||||
"- operating, 4 - Shutdown): "
|
||||
sif::info << "PlocSupervisorHandler::handleBootStatusReport: SoC State (0 - off, 1 - booting, 2 "
|
||||
"- Update, 3 "
|
||||
"- operating, 4 - Shutdown, 5 - Reset): "
|
||||
<< static_cast<unsigned int>(bootStatusReport.socState.value) << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleBootStatusReport: Power Cycles: "
|
||||
<< static_cast<unsigned int>(bootStatusReport.powerCycles.value) << std::endl;
|
||||
|
@ -83,6 +83,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
static const uint8_t SIZE_NULL_TERMINATOR = 1;
|
||||
// 5 s
|
||||
static const uint32_t EXECUTION_DEFAULT_TIMEOUT = 5000;
|
||||
// 70 S
|
||||
static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 70000;
|
||||
// 60 s
|
||||
static const uint32_t MRAM_DUMP_EXECUTION_TIMEOUT = 60000;
|
||||
// 70 s
|
||||
@ -93,6 +95,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
static const uint32_t BOOT_TIMEOUT = 2000;
|
||||
enum class StartupState : uint8_t { OFF, BOOTING, SET_TIME, SET_TIME_EXECUTING, ON };
|
||||
|
||||
bool setTimeDuringStartup = false;
|
||||
|
||||
StartupState startupState = StartupState::OFF;
|
||||
|
||||
uint8_t commandBuffer[supv::MAX_COMMAND_SIZE];
|
||||
@ -141,7 +145,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
// Supervisor helper class currently executing a command
|
||||
bool plocSupvHelperExecuting = false;
|
||||
|
||||
Countdown executionTimeout = Countdown(EXECUTION_DEFAULT_TIMEOUT, false);
|
||||
Countdown executionReportTimeout = Countdown(EXECUTION_DEFAULT_TIMEOUT, false);
|
||||
Countdown acknowledgementReportTimeout = Countdown(ACKNOWLEDGE_DEFAULT_TIMEOUT, false);
|
||||
// Vorago nees some time to boot properly
|
||||
Countdown bootTimeout = Countdown(BOOT_TIMEOUT);
|
||||
Countdown mramDumpTimeout = Countdown(MRAM_DUMP_TIMEOUT);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
#include "fsfw/tasks/TaskFactory.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
#include "mission/utility/Filenaming.h"
|
||||
#include "mission/utility/ProgressPrinter.h"
|
||||
@ -51,6 +52,18 @@ ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) {
|
||||
internalState = InternalState::IDLE;
|
||||
break;
|
||||
}
|
||||
case InternalState::CONTINUE_UPDATE: {
|
||||
result = continueUpdate();
|
||||
if (result == RETURN_OK) {
|
||||
triggerEvent(SUPV_CONTINUE_UPDATE_SUCCESSFUL, result);
|
||||
} else if (result == PROCESS_TERMINATED) {
|
||||
// Event already triggered
|
||||
} else {
|
||||
triggerEvent(SUPV_CONTINUE_UPDATE_FAILED, result);
|
||||
}
|
||||
internalState = InternalState::IDLE;
|
||||
break;
|
||||
}
|
||||
case InternalState::REQUEST_EVENT_BUFFER: {
|
||||
result = performEventBufferRequest();
|
||||
if (result == RETURN_OK) {
|
||||
@ -109,12 +122,21 @@ ReturnValue_t PlocSupvHelper::startUpdate(std::string file, uint8_t memoryId,
|
||||
update.length = getFileSize(update.file);
|
||||
update.memoryId = memoryId;
|
||||
update.startAddress = startAddress;
|
||||
update.remainingSize = update.length;
|
||||
update.bytesWritten = 0;
|
||||
update.packetNum = 1;
|
||||
update.sequenceCount = 1;
|
||||
internalState = InternalState::UPDATE;
|
||||
uartComIF->flushUartTxAndRxBuf(comCookie);
|
||||
semaphore.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
void PlocSupvHelper::initiateUpdateContinuation() {
|
||||
internalState = InternalState::CONTINUE_UPDATE;
|
||||
semaphore.release();
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::startEventbBufferRequest(std::string path) {
|
||||
#ifdef XIPHOS_Q7S
|
||||
ReturnValue_t result = FilesystemHelper::checkPath(path);
|
||||
@ -140,6 +162,10 @@ ReturnValue_t PlocSupvHelper::performUpdate() {
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = selectMemory();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = prepareUpdate();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
@ -148,62 +174,88 @@ ReturnValue_t PlocSupvHelper::performUpdate() {
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = writeUpdatePackets();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = handleCheckMemoryCommand();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::continueUpdate() {
|
||||
ReturnValue_t result = prepareUpdate();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = writeUpdatePackets();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = handleCheckMemoryCommand();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::writeUpdatePackets() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
ProgressPrinter progressPrinter("Supervisor update", update.length,
|
||||
ProgressPrinter::HALF_PERCENT);
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
uint8_t tempData[supv::WriteMemory::CHUNK_MAX];
|
||||
std::ifstream file(update.file, std::ifstream::binary);
|
||||
size_t remainingSize = update.length;
|
||||
uint16_t dataLength = 0;
|
||||
size_t bytesWritten = 0;
|
||||
uint16_t sequenceCount = 1;
|
||||
supv::SequenceFlags seqFlags = supv::SequenceFlags::FIRST_PKT;
|
||||
while (remainingSize > 0) {
|
||||
supv::SequenceFlags seqFlags;
|
||||
while (update.remainingSize > 0) {
|
||||
if (terminate) {
|
||||
terminate = false;
|
||||
triggerEvent(TERMINATED_UPDATE_PROCEDURE);
|
||||
return PROCESS_TERMINATED;
|
||||
}
|
||||
if (remainingSize > supv::WriteMemory::CHUNK_MAX) {
|
||||
if (update.remainingSize > supv::WriteMemory::CHUNK_MAX) {
|
||||
dataLength = supv::WriteMemory::CHUNK_MAX;
|
||||
} else {
|
||||
dataLength = static_cast<uint16_t>(remainingSize);
|
||||
dataLength = static_cast<uint16_t>(update.remainingSize);
|
||||
}
|
||||
if (file.is_open()) {
|
||||
file.seekg(bytesWritten, file.beg);
|
||||
file.seekg(update.bytesWritten, file.beg);
|
||||
file.read(reinterpret_cast<char*>(tempData), dataLength);
|
||||
if (!file) {
|
||||
sif::warning << "PlocSupvHelper::performUpdate: Read only " << file.gcount() << " of "
|
||||
<< dataLength << " bytes" << std::endl;
|
||||
sif::info << "PlocSupvHelper::performUpdate: Failed when trying to read byte "
|
||||
<< bytesWritten << std::endl;
|
||||
<< update.bytesWritten << std::endl;
|
||||
}
|
||||
remainingSize -= dataLength;
|
||||
} else {
|
||||
return FILE_CLOSED_ACCIDENTALLY;
|
||||
}
|
||||
if (bytesWritten == 0) {
|
||||
if (update.bytesWritten == 0) {
|
||||
seqFlags = supv::SequenceFlags::FIRST_PKT;
|
||||
} else if (remainingSize == 0) {
|
||||
} else if (update.remainingSize == 0) {
|
||||
seqFlags = supv::SequenceFlags::LAST_PKT;
|
||||
} else {
|
||||
seqFlags = supv::SequenceFlags::CONTINUED_PKT;
|
||||
}
|
||||
supv::WriteMemory packet(seqFlags, sequenceCount++, update.memoryId,
|
||||
update.startAddress + bytesWritten, dataLength, tempData);
|
||||
supv::WriteMemory packet(seqFlags, update.sequenceCount++, update.memoryId,
|
||||
update.startAddress + update.bytesWritten, dataLength, tempData);
|
||||
result = handlePacketTransmission(packet);
|
||||
if (result != RETURN_OK) {
|
||||
update.sequenceCount--;
|
||||
triggerEvent(WRITE_MEMORY_FAILED, update.packetNum);
|
||||
return result;
|
||||
}
|
||||
bytesWritten += dataLength;
|
||||
update.remainingSize -= dataLength;
|
||||
update.packetNum += 1;
|
||||
update.bytesWritten += dataLength;
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
progressPrinter.print(bytesWritten);
|
||||
progressPrinter.print(update.bytesWritten);
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
}
|
||||
result = handleCheckMemoryCommand();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -230,10 +282,20 @@ ReturnValue_t PlocSupvHelper::performEventBufferRequest() {
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::selectMemory() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
supv::MPSoCBootSelect packet(update.memoryId);
|
||||
result = handlePacketTransmission(packet);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::prepareUpdate() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
supv::ApidOnlyPacket packet(supv::APID_PREPARE_UPDATE);
|
||||
result = handlePacketTransmission(packet);
|
||||
result = handlePacketTransmission(packet, PREPARE_UPDATE_EXECUTION_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
@ -342,8 +404,8 @@ ReturnValue_t PlocSupvHelper::handleTmReception(supv::TmPacket* tmPacket, size_t
|
||||
}
|
||||
}
|
||||
if (remainingBytes != 0) {
|
||||
sif::warning << "PlocSupvHelper::handleTmReception: Failed to read " << remainingBytes
|
||||
<< " bytes" << std::endl;
|
||||
sif::warning << "PlocSupvHelper::handleTmReception: Failed to read " << std::dec
|
||||
<< remainingBytes << " bytes" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
result = tmPacket->checkCrc();
|
||||
@ -372,6 +434,8 @@ ReturnValue_t PlocSupvHelper::receive(uint8_t* data, size_t* readBytes, size_t r
|
||||
}
|
||||
if (*readBytes > 0) {
|
||||
std::memcpy(data, buffer, *readBytes);
|
||||
} else {
|
||||
TaskFactory::delayTask(40);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -28,56 +28,63 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
static const Event SUPV_UPDATE_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] update successful
|
||||
static const Event SUPV_UPDATE_SUCCESSFUL = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Continue update command failed
|
||||
static const Event SUPV_CONTINUE_UPDATE_FAILED = MAKE_EVENT(2, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Continue update command successful
|
||||
static const Event SUPV_CONTINUE_UPDATE_SUCCESSFUL = MAKE_EVENT(3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Terminated update procedure by command
|
||||
static const Event TERMINATED_UPDATE_PROCEDURE = MAKE_EVENT(2, severity::LOW);
|
||||
static const Event TERMINATED_UPDATE_PROCEDURE = MAKE_EVENT(4, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Requesting event buffer was successful
|
||||
static const Event SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL = MAKE_EVENT(3, severity::LOW);
|
||||
static const Event SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL = MAKE_EVENT(5, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Requesting event buffer failed
|
||||
static const Event SUPV_EVENT_BUFFER_REQUEST_FAILED = MAKE_EVENT(4, severity::LOW);
|
||||
static const Event SUPV_EVENT_BUFFER_REQUEST_FAILED = MAKE_EVENT(6, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Terminated event buffer request by command
|
||||
//! P1: Number of packets read before process was terminated
|
||||
static const Event SUPV_EVENT_BUFFER_REQUEST_TERMINATED = MAKE_EVENT(5, severity::LOW);
|
||||
static const Event SUPV_EVENT_BUFFER_REQUEST_TERMINATED = MAKE_EVENT(7, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Communication interface returned failure when trying to send the command
|
||||
//! to the supervisor
|
||||
//! P1: Return value returned by the communication interface sendMessage function
|
||||
//! P2: Internal state of supervisor helper
|
||||
static const Event SUPV_SENDING_COMMAND_FAILED = MAKE_EVENT(6, severity::LOW);
|
||||
static const Event SUPV_SENDING_COMMAND_FAILED = MAKE_EVENT(8, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Request receive message of communication interface failed
|
||||
//! P1: Return value returned by the communication interface requestReceiveMessage function
|
||||
//! P2: Internal state of supervisor helper
|
||||
static const Event SUPV_HELPER_REQUESTING_REPLY_FAILED = MAKE_EVENT(7, severity::LOW);
|
||||
static const Event SUPV_HELPER_REQUESTING_REPLY_FAILED = MAKE_EVENT(9, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Reading receive message of communication interface failed
|
||||
//! P1: Return value returned by the communication interface readingReceivedMessage function
|
||||
//! P2: Internal state of supervisor helper
|
||||
static const Event SUPV_HELPER_READING_REPLY_FAILED = MAKE_EVENT(8, severity::LOW);
|
||||
static const Event SUPV_HELPER_READING_REPLY_FAILED = MAKE_EVENT(10, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Did not receive acknowledgement report
|
||||
//! P1: Number of bytes missing
|
||||
//! P2: Internal state of MPSoC helper
|
||||
static const Event SUPV_MISSING_ACK = MAKE_EVENT(9, severity::LOW);
|
||||
static const Event SUPV_MISSING_ACK = MAKE_EVENT(11, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor did not receive execution report
|
||||
//! P1: Number of bytes missing
|
||||
//! P2: Internal state of supervisor helper
|
||||
static const Event SUPV_MISSING_EXE = MAKE_EVENT(10, severity::LOW);
|
||||
static const Event SUPV_MISSING_EXE = MAKE_EVENT(12, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor received acknowledgment failure report
|
||||
//! P1: Internal state of supervisor helper
|
||||
static const Event SUPV_ACK_FAILURE_REPORT = MAKE_EVENT(11, severity::LOW);
|
||||
static const Event SUPV_ACK_FAILURE_REPORT = MAKE_EVENT(13, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Execution report failure
|
||||
//! P1:
|
||||
static const Event SUPV_EXE_FAILURE_REPORT = MAKE_EVENT(12, severity::LOW);
|
||||
static const Event SUPV_EXE_FAILURE_REPORT = MAKE_EVENT(14, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor expected acknowledgment report but received space packet with
|
||||
//! other apid P1: Apid of received space packet P2: Internal state of supervisor helper
|
||||
static const Event SUPV_ACK_INVALID_APID = MAKE_EVENT(13, severity::LOW);
|
||||
static const Event SUPV_ACK_INVALID_APID = MAKE_EVENT(15, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor helper expected execution report but received space packet
|
||||
//! with other apid P1: Apid of received space packet P2: Internal state of supervisor helper
|
||||
static const Event SUPV_EXE_INVALID_APID = MAKE_EVENT(14, severity::LOW);
|
||||
static const Event SUPV_EXE_INVALID_APID = MAKE_EVENT(16, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Failed to receive acknowledgment report
|
||||
//! P1: Return value
|
||||
//! P2: Apid of command for which the reception of the acknowledgment report failed
|
||||
static const Event ACK_RECEPTION_FAILURE = MAKE_EVENT(15, severity::LOW);
|
||||
static const Event ACK_RECEPTION_FAILURE = MAKE_EVENT(17, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Failed to receive execution report
|
||||
//! P1: Return value
|
||||
//! P2: Apid of command for which the reception of the execution report failed
|
||||
static const Event EXE_RECEPTION_FAILURE = MAKE_EVENT(16, severity::LOW);
|
||||
static const Event EXE_RECEPTION_FAILURE = MAKE_EVENT(18, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Update procedure failed when sending packet with number P1
|
||||
//! P1: Packet number for which the memory write command fails
|
||||
static const Event WRITE_MEMORY_FAILED = MAKE_EVENT(19, severity::LOW);
|
||||
|
||||
PlocSupvHelper(object_id_t objectId);
|
||||
virtual ~PlocSupvHelper();
|
||||
@ -99,6 +106,11 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
*/
|
||||
ReturnValue_t startUpdate(std::string file, uint8_t memoryId, uint32_t startAddress);
|
||||
|
||||
/**
|
||||
* @brief This initiate the continuation of a failed update.
|
||||
*/
|
||||
void initiateUpdateContinuation();
|
||||
|
||||
/**
|
||||
* @brief Calling this function will initiate the procedure to request the event buffer
|
||||
*/
|
||||
@ -128,6 +140,7 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
static const size_t SIZE_EVENT_BUFFER_FULL_PACKET = 1024;
|
||||
static const size_t SIZE_EVENT_BUFFER_LAST_PACKET = 200;
|
||||
static const uint32_t CRC_EXECUTION_TIMEOUT = 60000;
|
||||
static const uint32_t PREPARE_UPDATE_EXECUTION_REPORT = 2000;
|
||||
|
||||
struct Update {
|
||||
uint8_t memoryId;
|
||||
@ -137,6 +150,10 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
// Size of update
|
||||
uint32_t length;
|
||||
uint32_t crc;
|
||||
size_t remainingSize;
|
||||
size_t bytesWritten;
|
||||
uint32_t packetNum;
|
||||
uint16_t sequenceCount;
|
||||
};
|
||||
|
||||
struct Update update;
|
||||
@ -150,7 +167,7 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
|
||||
EventBufferRequest eventBufferReq;
|
||||
|
||||
enum class InternalState { IDLE, UPDATE, REQUEST_EVENT_BUFFER };
|
||||
enum class InternalState { IDLE, UPDATE, CONTINUE_UPDATE, REQUEST_EVENT_BUFFER };
|
||||
|
||||
InternalState internalState = InternalState::IDLE;
|
||||
|
||||
@ -175,9 +192,11 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
uint16_t rememberApid = 0;
|
||||
|
||||
ReturnValue_t performUpdate();
|
||||
ReturnValue_t continueUpdate();
|
||||
ReturnValue_t writeUpdatePackets();
|
||||
ReturnValue_t performEventBufferRequest();
|
||||
ReturnValue_t handlePacketTransmission(SpacePacket& packet,
|
||||
uint32_t timeoutExecutionReport = 1000);
|
||||
uint32_t timeoutExecutionReport = 60000);
|
||||
ReturnValue_t sendCommand(SpacePacket& packet);
|
||||
/**
|
||||
* @brief Function which reads form the communication interface
|
||||
@ -195,9 +214,13 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
* @param tmPacket Pointer to space packet where received data will be written to
|
||||
* @param reaminingBytes Number of bytes to read in the space packet
|
||||
* @param timeout Receive timeout in milliseconds
|
||||
*
|
||||
* @note It can take up to 70 seconds until the supervisor replies with an acknowledgment
|
||||
* failure report.
|
||||
*/
|
||||
ReturnValue_t handleTmReception(supv::TmPacket* tmPacket, size_t remainingBytes,
|
||||
uint32_t timeout = 1000);
|
||||
uint32_t timeout = 70000);
|
||||
ReturnValue_t selectMemory();
|
||||
ReturnValue_t prepareUpdate();
|
||||
ReturnValue_t eraseMemory();
|
||||
// Calculates CRC over image. Will be used for verification after update writing has
|
||||
|
@ -1,7 +1,4 @@
|
||||
target_sources(${OBSW_NAME} PRIVATE
|
||||
StarTrackerHandler.cpp
|
||||
StarTrackerJsonCommands.cpp
|
||||
ArcsecDatalinkLayer.cpp
|
||||
ArcsecJsonParamBase.cpp
|
||||
StrHelper.cpp
|
||||
)
|
||||
target_sources(
|
||||
${OBSW_NAME}
|
||||
PRIVATE StarTrackerHandler.cpp StarTrackerJsonCommands.cpp
|
||||
ArcsecDatalinkLayer.cpp ArcsecJsonParamBase.cpp StrHelper.cpp)
|
||||
|
Reference in New Issue
Block a user