diff --git a/CHANGELOG.md b/CHANGELOG.md index 2128a01d..3626825b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,12 @@ list yields a list of all related PRs for each release. ## Added +- PUS11 TC scheduler + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/259 +- Regular reboot command + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/242 +- Commands for individual RTD devices + PR: https://egit.irs.uni-stuttgart.de/eive/eive-tmtc/pulls/84 - `RwAssembly` added to system components. Assembly works in principle, issues making 4 consecutives RWs communicate at once.. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/224 @@ -27,6 +33,11 @@ list yields a list of all related PRs for each release. username appended at the end is created as a side-product now PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/248 +## Fixed + +- `q7s-cp.py` bugfix + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/256 + ### Heater - Adds `HealthIF` to heaters. Heaters are own system object with queues now which allows to set them faulty. diff --git a/CMakeLists.txt b/CMakeLists.txt index eb44bd41..ef87352e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,8 @@ include(EiveHelpers) option(EIVE_ADD_ETL_LIB "Add ETL library" ON) option(EIVE_ADD_JSON_LIB "Add JSON library" ON) +set(OBSW_MAX_SCHEDULED_TCS 500) + if(EIVE_Q7S_EM) set(OBSW_Q7S_EM 1 diff --git a/bsp_hosted/fsfwconfig/tmtc/apid.h b/bsp_hosted/fsfwconfig/tmtc/apid.h deleted file mode 100644 index 9d5c9ed5..00000000 --- a/bsp_hosted/fsfwconfig/tmtc/apid.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FSFWCONFIG_TMTC_APID_H_ -#define FSFWCONFIG_TMTC_APID_H_ - -#include - -/** - * Application Process Definition: entity, uniquely identified by an - * application process ID (APID), capable of generating telemetry source - * packets and receiving telecommand packets - * - * SOURCE APID: 0x73 / 115 / s - * APID is a 11 bit number - */ -namespace apid { -static const uint16_t EIVE_OBSW = 0x65; -} - -#endif /* FSFWCONFIG_TMTC_APID_H_ */ diff --git a/bsp_linux_board/InitMission.h b/bsp_linux_board/InitMission.h index f14135dd..6e38fc94 100644 --- a/bsp_linux_board/InitMission.h +++ b/bsp_linux_board/InitMission.h @@ -3,7 +3,7 @@ #include -#include "fsfw/tasks/Typedef.h" +#include "fsfw/tasks/definitions.h" class PeriodicTaskIF; class TaskFactory; diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 93a7e96a..47f80936 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -67,7 +67,7 @@ void ObjectFactory::produce(void* args) { GpioCookie* gpioCookie = nullptr; static_cast(gpioCookie); - SpiComIF* spiComIF = new SpiComIF(objects::SPI_COM_IF, gpioIF); + SpiComIF* spiComIF = new SpiComIF(objects::SPI_MAIN_COM_IF, spi::DEV, gpioIF); static_cast(spiComIF); auto pwrSwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0); static_cast(pwrSwitcher); @@ -116,73 +116,72 @@ void ObjectFactory::createRpiAcsBoard(GpioIF* gpioIF, std::string spiDev) { gpio::Direction::OUT, gpio::Levels::HIGH); gpioIF->addGpios(gpioCookie); SpiCookie* spiCookie = - new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, - MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, MGMLIS3MDL::MAX_BUFFER_SIZE, + spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); auto mgmLis3Handler = - new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, 0); mgmLis3Handler->setStartUpImmediately(); #if OBSW_TEST_ACS == 1 mgmLis3Handler->setToGoToNormalMode(true); #endif spiCookie = - new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev, - RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, RM3100::MAX_BUFFER_SIZE, + spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); auto mgmRm3100Handler = - new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, 0); mgmRm3100Handler->setStartUpImmediately(); #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setToGoToNormalMode(true); #endif spiCookie = - new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev, - MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, MGMLIS3MDL::MAX_BUFFER_SIZE, + spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); mgmLis3Handler = - new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, 0); mgmLis3Handler->setStartUpImmediately(); #if OBSW_TEST_ACS == 1 mgmLis3Handler->setToGoToNormalMode(true); #endif spiCookie = - new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev, - RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, RM3100::MAX_BUFFER_SIZE, + spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); mgmRm3100Handler = - new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, 0); mgmRm3100Handler->setStartUpImmediately(); #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setToGoToNormalMode(true); #endif spiCookie = - new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, - ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie, ADIS1650X::Type::ADIS16505); - adisHandler->setStartUpImmediately(); - spiCookie = - new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE, + new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + auto adisHandler = + new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, + ADIS1650X::Type::ADIS16505); + adisHandler->setStartUpImmediately(); + spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, L3GD20H::MAX_BUFFER_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); auto gyroL3gHandler = - new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, 0); gyroL3gHandler->setStartUpImmediately(); #if OBSW_TEST_ACS == 1 gyroL3gHandler->setToGoToNormalMode(true); #endif spiCookie = - new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, - ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); - adisHandler = new GyroADIS1650XHandler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, + new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, ADIS1650X::MAXIMUM_REPLY_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + adisHandler = new GyroADIS1650XHandler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, ADIS1650X::Type::ADIS16505); adisHandler->setStartUpImmediately(); - spiCookie = - new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE, - spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + spiCookie = new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, L3GD20H::MAX_BUFFER_SIZE, + spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); gyroL3gHandler = - new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, 0); + new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie, 0); gyroL3gHandler->setStartUpImmediately(); #if OBSW_TEST_ACS == 1 gyroL3gHandler->setToGoToNormalMode(true); diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index e8cc5bd2..fffa4a2a 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -4,6 +4,8 @@ namespace q7s { static constexpr char SPI_DEFAULT_DEV[] = "/dev/spi-main"; +static constexpr uint32_t SPI_MAIN_BUS_LOCK_TIMEOUT = 50; + static constexpr char SPI_RW_DEV[] = "/dev/spi-rw"; static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-eive"; diff --git a/bsp_q7s/callbacks/gnssCallback.cpp b/bsp_q7s/callbacks/gnssCallback.cpp index d5dbc3b0..7e854b6d 100644 --- a/bsp_q7s/callbacks/gnssCallback.cpp +++ b/bsp_q7s/callbacks/gnssCallback.cpp @@ -1,9 +1,14 @@ #include "gnssCallback.h" #include "devices/gpioIds.h" +#include "fsfw/action/HasActionsIF.h" #include "fsfw/tasks/TaskFactory.h" -ReturnValue_t gps::triggerGpioResetPin(void* args) { +ReturnValue_t gps::triggerGpioResetPin(const uint8_t* actionData, size_t len, void* args) { + // At least one byte which denotes which GPS to reset is required + if (len < 1 or actionData == nullptr) { + return HasActionsIF::INVALID_PARAMETERS; + } ResetArgs* resetArgs = reinterpret_cast(args); if (args == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; @@ -12,11 +17,10 @@ ReturnValue_t gps::triggerGpioResetPin(void* args) { return HasReturnvaluesIF::RETURN_FAILED; } gpioId_t gpioId; - if (resetArgs->gnss1) { - gpioId = gpioIds::GNSS_1_NRESET; - - } else { + if (actionData[0] == 0) { gpioId = gpioIds::GNSS_0_NRESET; + } else { + gpioId = gpioIds::GNSS_1_NRESET; } resetArgs->gpioComIF->pullLow(gpioId); TaskFactory::delayTask(resetArgs->waitPeriodMs); diff --git a/bsp_q7s/callbacks/gnssCallback.h b/bsp_q7s/callbacks/gnssCallback.h index 3e769899..cd69f5a6 100644 --- a/bsp_q7s/callbacks/gnssCallback.h +++ b/bsp_q7s/callbacks/gnssCallback.h @@ -5,14 +5,13 @@ #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" struct ResetArgs { - bool gnss1 = false; LinuxLibgpioIF* gpioComIF = nullptr; uint32_t waitPeriodMs = 100; }; namespace gps { -ReturnValue_t triggerGpioResetPin(void* args); +ReturnValue_t triggerGpioResetPin(const uint8_t* actionData, size_t len, void* args); } diff --git a/bsp_q7s/callbacks/rwSpiCallback.cpp b/bsp_q7s/callbacks/rwSpiCallback.cpp index 0d845fb8..0fd2c512 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.cpp +++ b/bsp_q7s/callbacks/rwSpiCallback.cpp @@ -44,8 +44,8 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen GpioIF* gpioIF = comIf->getGpioInterface(); MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; uint32_t timeoutMs = 0; - cookie->getMutexParams(timeoutType, timeoutMs); MutexIF* mutex = comIf->getCsMutex(); + cookie->getMutexParams(timeoutType, timeoutMs); if (mutex == nullptr or gpioIF == nullptr) { sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5419e7a9..e387aa71 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -56,6 +56,7 @@ CoreController::CoreController(object_id_t objectId) } catch (const std::filesystem::filesystem_error &e) { sif::error << "CoreController::CoreController: Failed with exception " << e.what() << std::endl; } + sdCardCheckCd.timeOut(); eventQueue = QueueFactory::instance()->createMessageQueue(5, EventMessage::MAX_MESSAGE_SIZE); } @@ -77,6 +78,10 @@ void CoreController::performControlOperation() { performWatchdogControlOperation(); sdStateMachine(); performMountedSdCardOperations(); + if (sdCardCheckCd.hasTimedOut()) { + performSdCardCheck(); + sdCardCheckCd.resetTimer(); + } readHkData(); opDivider5.checkAndIncrement(); opDivider10.checkAndIncrement(); @@ -134,6 +139,9 @@ ReturnValue_t CoreController::initialize() { ReturnValue_t CoreController::initializeAfterTaskCreation() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + sdInfo.pref = sdcMan->getPreferredSdCard(); + sdcMan->setActiveSdCard(sdInfo.pref); + currMntPrefix = sdcMan->getCurrentMountPrefix(); if (BLOCKING_SD_INIT) { ReturnValue_t result = initSdCardBlocking(); if (result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) { @@ -165,7 +173,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ if (size < 1) { return HasActionsIF::INVALID_PARAMETERS; } - std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE; // Disable the reboot file mechanism parseRebootFile(path, rebootFile); if (data[0] == 0) { @@ -205,15 +213,20 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ if (size < 1) { return HasActionsIF::INVALID_PARAMETERS; } - std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE; // Disable the reboot file mechanism parseRebootFile(path, rebootFile); rebootFile.maxCount = data[0]; rewriteRebootFile(rebootFile); return HasActionsIF::EXECUTION_FINISHED; } + case (XSC_REBOOT_OBC): { + // Warning: This function will never return, because it reboots the system + return actionXscReboot(data, size); + } case (REBOOT_OBC): { - return actionPerformReboot(data, size); + // Warning: This function will never return, because it reboots the system + return actionReboot(data, size); } default: { return HasActionsIF::INVALID_ACTION_ID; @@ -237,13 +250,12 @@ ReturnValue_t CoreController::initSdCardBlocking() { return HasReturnvaluesIF::RETURN_OK; #else - result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); + result = sdcMan->getSdCardsStatus(sdInfo.currentState); if (result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - determinePreferredSdCard(); updateSdInfoOther(); sif::info << "Cold redundant SD card configuration, preferred SD card: " << static_cast(sdInfo.pref) << std::endl; @@ -324,8 +336,8 @@ ReturnValue_t CoreController::sdStateMachine() { if (sdInfo.state == SdStates::SET_STATE_SELF) { if (not sdInfo.commandExecuted) { - result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); - determinePreferredSdCard(); + result = sdcMan->getSdCardsStatus(sdInfo.currentState); + sdInfo.pref = sdcMan->getPreferredSdCard(); updateSdInfoOther(); if (sdInfo.pref != sd::SdCard::SLOT_0 and sdInfo.pref != sd::SdCard::SLOT_1) { sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl; @@ -468,7 +480,7 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.state = SdStates::IDLE; sdInfo.cycleCount = 0; sdcMan->setBlocking(false); - sdcMan->getSdCardActiveStatus(sdInfo.currentState); + sdcMan->getSdCardsStatus(sdInfo.currentState); if (not sdInfo.initFinished) { updateSdInfoOther(); sdInfo.initFinished = true; @@ -845,25 +857,18 @@ void CoreController::initPrint() { #endif } -ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t size) { +ReturnValue_t CoreController::actionXscReboot(const uint8_t *data, size_t size) { if (size < 1) { return HasActionsIF::INVALID_PARAMETERS; } bool rebootSameBootCopy = data[0]; - bool protOpPerformed; + bool protOpPerformed = false; + SdCardManager::instance()->setBlocking(true); if (rebootSameBootCopy) { #if OBSW_VERBOSE_LEVEL >= 1 sif::info << "CoreController::actionPerformReboot: Rebooting on current image" << std::endl; #endif - // Attempt graceful shutdown by unmounting and switching off SD cards - SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0); - SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1); - // If any boot copies are unprotected - ReturnValue_t retval = setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true, - protOpPerformed, false); - if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { - sif::info << "Running slot was writeprotected before reboot" << std::endl; - } + gracefulShutdownTasks(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, protOpPerformed); int result = std::system("xsc_boot_copy -r"); if (result != 0) { utility::handleSystemError(result, "CoreController::executeAction"); @@ -885,12 +890,8 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si auto tgtChip = static_cast(data[1]); auto tgtCopy = static_cast(data[2]); - ReturnValue_t retval = - setBootCopyProtection(static_cast(data[1]), static_cast(data[2]), true, - protOpPerformed, false); - if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { - sif::info << "Target slot was writeprotected before reboot" << std::endl; - } + // This function can not really fail + gracefulShutdownTasks(tgtChip, tgtCopy, protOpPerformed); switch (tgtChip) { case (xsc::Chip::CHIP_0): { @@ -931,27 +932,32 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si return HasReturnvaluesIF::RETURN_FAILED; } -CoreController::~CoreController() {} - -void CoreController::determinePreferredSdCard() { - if (sdInfo.pref == sd::SdCard::NONE) { - ReturnValue_t result = sdcMan->getPreferredSdCard(sdInfo.pref); - if (result != HasReturnvaluesIF::RETURN_OK) { - if (result == scratch::KEY_NOT_FOUND) { - sif::warning << "CoreController::sdCardInit: " - "Preferred SD card not set. Setting to 0" - << std::endl; - sdcMan->setPreferredSdCard(sd::SdCard::SLOT_0); - sdInfo.pref = sd::SdCard::SLOT_0; - } else { - sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" - "information from the scratch buffer" - << std::endl; - } - } - } +ReturnValue_t CoreController::actionReboot(const uint8_t *data, size_t size) { + bool protOpPerformed = false; + gracefulShutdownTasks(xsc::Chip::CHIP_0, xsc::Copy::COPY_0, protOpPerformed); + std::system("reboot"); + return RETURN_OK; } +ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy copy, + bool &protOpPerformed) { + sdcMan->setBlocking(true); + // Attempt graceful shutdown by unmounting and switching off SD cards + sdcMan->switchOffSdCard(sd::SdCard::SLOT_0); + sdcMan->switchOffSdCard(sd::SdCard::SLOT_1); + // If any boot copies are unprotected + ReturnValue_t result = setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true, + protOpPerformed, false); + if (result == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { + // TODO: Would be nice to notify operator. But we can't use the filesystem anymore + // and a reboot is imminent. Use scratch buffer? + sif::info << "Running slot was writeprotected before reboot" << std::endl; + } + return result; +} + +CoreController::~CoreController() {} + void CoreController::updateSdInfoOther() { if (sdInfo.pref == sd::SdCard::SLOT_0) { sdInfo.prefChar = "0"; @@ -1235,24 +1241,73 @@ void CoreController::performWatchdogControlOperation() { } void CoreController::performMountedSdCardOperations() { - currMntPrefix = sdcMan->getCurrentMountPrefix(); - if (doPerformMountedSdCardOps) { - bool sdCardMounted = false; - sdCardMounted = sdcMan->isSdCardMounted(sdInfo.pref); - if (sdCardMounted) { - std::string path = currMntPrefix + "/" + CONF_FOLDER; - if (not std::filesystem::exists(path)) { - std::filesystem::create_directory(path); + auto mountedSdCardOp = [&](bool &mntSwitch, sd::SdCard sdCard, std::string mntPoint) { + if (mntSwitch) { + bool sdCardMounted = sdcMan->isSdCardMounted(sdCard); + if (sdCardMounted and not performOneShotSdCardOpsSwitch) { + std::ostringstream path; + path << mntPoint << "/" << CONF_FOLDER; + if (not std::filesystem::exists(path.str())) { + std::filesystem::create_directory(path.str()); + } + initVersionFile(); + initClockFromTimeFile(); + performRebootFileHandling(false); + performOneShotSdCardOpsSwitch = true; } - initVersionFile(); - initClockFromTimeFile(); - performRebootFileHandling(false); - doPerformMountedSdCardOps = false; + mntSwitch = false; } + }; + if (sdInfo.pref == sd::SdCard::SLOT_1) { + mountedSdCardOp(sdInfo.mountSwitch.second, sd::SdCard::SLOT_1, SdCardManager::SD_1_MOUNT_POINT); + mountedSdCardOp(sdInfo.mountSwitch.first, sd::SdCard::SLOT_0, SdCardManager::SD_0_MOUNT_POINT); + } else { + mountedSdCardOp(sdInfo.mountSwitch.first, sd::SdCard::SLOT_0, SdCardManager::SD_0_MOUNT_POINT); + mountedSdCardOp(sdInfo.mountSwitch.second, sd::SdCard::SLOT_1, SdCardManager::SD_1_MOUNT_POINT); } timeFileHandler(); } +ReturnValue_t CoreController::performSdCardCheck() { + bool mountedReadOnly = false; + SdCardManager::SdStatePair active; + sdcMan->getSdCardsStatus(active); + auto sdCardCheck = [&](sd::SdCard sdCard) { + ReturnValue_t result = sdcMan->isSdCardMountedReadOnly(sdCard, mountedReadOnly); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "CoreController::performSdCardCheck: Could not check " + "read-only mount state" + << std::endl; + mountedReadOnly = true; + } + if (mountedReadOnly) { + int linuxErrno = 0; + result = sdcMan->performFsck(sdCard, true, linuxErrno); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "CoreController::performSdCardCheck: fsck command on SD Card " + << static_cast(sdCard) << " failed with code " << linuxErrno << " | " + << strerror(linuxErrno); + } + result = sdcMan->remountReadWrite(sdCard); + if (result == HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::performSdCardCheck: Remounted SD Card " + << static_cast(sdCard) << " read-write"; + } else { + sif::error << "CoreController::performSdCardCheck: Remounting SD Card " + << static_cast(sdCard) << " read-write failed"; + } + } + }; + if (active.first == sd::SdState::MOUNTED) { + sdCardCheck(sd::SdCard::SLOT_0); + } + if (active.second == sd::SdState::MOUNTED) { + sdCardCheck(sd::SdCard::SLOT_1); + } + + return RETURN_OK; +} + void CoreController::performRebootFileHandling(bool recreateFile) { using namespace std; std::string path = currMntPrefix + REBOOT_FILE; @@ -1678,7 +1733,7 @@ void CoreController::rewriteRebootFile(RebootFile file) { } void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) { - std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + std::string path = currMntPrefix + REBOOT_FILE; // Disable the reboot file mechanism parseRebootFile(path, rebootFile); if (tgtChip == xsc::CHIP_0) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index fb4f02b0..2ebdd4ec 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -67,8 +67,11 @@ class CoreController : public ExtendedControllerBase { static constexpr ActionId_t SWITCH_IMG_LOCK = 7; static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8; - static constexpr ActionId_t REBOOT_OBC = 32; + //! Reboot using the xsc_boot_copy command + static constexpr ActionId_t XSC_REBOOT_OBC = 32; static constexpr ActionId_t MOUNT_OTHER_COPY = 33; + //! Reboot using the reboot command + static constexpr ActionId_t REBOOT_OBC = 34; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; @@ -159,11 +162,12 @@ class CoreController : public ExtendedControllerBase { struct SdInfo { sd::SdCard pref = sd::SdCard::NONE; - sd::SdState prefState = sd::SdState::OFF; sd::SdCard other = sd::SdCard::NONE; + sd::SdState prefState = sd::SdState::OFF; sd::SdState otherState = sd::SdState::OFF; std::string prefChar = "0"; std::string otherChar = "1"; + std::pair mountSwitch = {true, true}; SdStates state = SdStates::START; // Used to track whether a command was executed bool commandExecuted = true; @@ -179,7 +183,7 @@ class CoreController : public ExtendedControllerBase { } sdInfo; RebootFile rebootFile = {}; std::string currMntPrefix; - bool doPerformMountedSdCardOps = true; + bool performOneShotSdCardOpsSwitch = true; /** * Index 0: Chip 0 Copy 0 @@ -195,12 +199,14 @@ class CoreController : public ExtendedControllerBase { ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; + Countdown sdCardCheckCd = Countdown(120000); LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode); void performMountedSdCardOperations(); ReturnValue_t initVersionFile(); ReturnValue_t initClockFromTimeFile(); + ReturnValue_t performSdCardCheck(); ReturnValue_t timeFileHandler(); ReturnValue_t initBootCopy(); ReturnValue_t initWatchdogFifo(); @@ -214,14 +220,16 @@ class CoreController : public ExtendedControllerBase { ReturnValue_t sdColdRedundantBlockingInit(); void currentStateSetter(sd::SdCard sdCard, sd::SdState newState); - void determinePreferredSdCard(); void executeNextExternalSdCommand(); void checkExternalSdCommandStatus(); void performRebootFileHandling(bool recreateFile); ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size); - ReturnValue_t actionPerformReboot(const uint8_t* data, size_t size); + ReturnValue_t actionXscReboot(const uint8_t* data, size_t size); + ReturnValue_t actionReboot(const uint8_t* data, size_t size); + + ReturnValue_t gracefulShutdownTasks(xsc::Chip chip, xsc::Copy copy, bool& protOpPerformed); void performWatchdogControlOperation(); diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 8913789b..52ecd30f 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -1,5 +1,7 @@ #include "bsp_q7s/core/InitMission.h" +#include + #include #include @@ -13,6 +15,7 @@ #include "fsfw/tasks/FixedTimeslotTaskIF.h" #include "fsfw/tasks/PeriodicTaskIF.h" #include "fsfw/tasks/TaskFactory.h" +#include "mission/devices/devicedefinitions/Max31865Definitions.h" #include "mission/utility/InitMission.h" #include "pollingsequence/pollingSequenceFactory.h" @@ -123,7 +126,7 @@ void initmission::initTasks() { #if OBSW_ADD_ACS_HANDLERS == 1 PeriodicTaskIF* acsTask = factory->createPeriodicTask( - "ACS_CTRL", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + "ACS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); result = acsTask->addComponent(objects::GPS_CONTROLLER); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER); @@ -145,19 +148,49 @@ void initmission::initTasks() { initmission::printAddObjectError("RW_ASS", objects::RW_ASS); } #endif - #if OBSW_ADD_SUS_BOARD_ASS == 1 result = sysTask->addComponent(objects::SUS_BOARD_ASS); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS); } #endif + #if OBSW_ADD_RTD_DEVICES == 1 - result = sysTask->addComponent(objects::TCS_BOARD_ASS); + PeriodicTaskIF* tcsPollingTask = factory->createPeriodicTask( + "TCS_POLLING_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.5, missedDeadlineFunc); + result = tcsPollingTask->addComponent(objects::SPI_RTD_COM_IF); if (result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("TCS_BOARD_ASS", objects::TCS_BOARD_ASS); + initmission::printAddObjectError("SPI_RTD_POLLING", objects::SPI_RTD_COM_IF); } -#endif /* OBSW_ADD_RTD_DEVICES == 1 */ + PeriodicTaskIF* tcsTask = factory->createPeriodicTask( + "TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + std::array rtdIds = { + objects::RTD_0_IC3_PLOC_HEATSPREADER, + objects::RTD_1_IC4_PLOC_MISSIONBOARD, + objects::RTD_2_IC5_4K_CAMERA, + objects::RTD_3_IC6_DAC_HEATSPREADER, + objects::RTD_4_IC7_STARTRACKER, + objects::RTD_5_IC8_RW1_MX_MY, + objects::RTD_6_IC9_DRO, + objects::RTD_7_IC10_SCEX, + objects::RTD_8_IC11_X8, + objects::RTD_9_IC12_HPA, + objects::RTD_10_IC13_PL_TX, + objects::RTD_11_IC14_MPA, + objects::RTD_12_IC15_ACU, + objects::RTD_13_IC16_PLPCDU_HEATSPREADER, + objects::RTD_14_IC17_TCS_BOARD, + objects::RTD_15_IC18_IMTQ, + }; + tcsTask->addComponent(objects::TCS_BOARD_ASS); + for (const auto& rtd : rtdIds) { + tcsTask->addComponent(rtd, DeviceHandlerIF::PERFORM_OPERATION); + tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_WRITE); + tcsTask->addComponent(rtd, DeviceHandlerIF::GET_WRITE); + tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ); + tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ); + } +#endif /* OBSW_ADD_RTD_DEVICES */ // FS task, task interval does not matter because it runs in permanent loop, priority low // because it is a non-essential background task @@ -256,10 +289,12 @@ void initmission::initTasks() { #if OBSW_ADD_ACS_HANDLERS == 1 acsTask->startTask(); -#endif -#if OBSW_ADD_RTD_DEVICES == 1 +#endif /* OBSW_ADD_ACS_HANDLERS == 1 */ sysTask->startTask(); -#endif +#if OBSW_ADD_RTD_DEVICES == 1 + tcsPollingTask->startTask(); + tcsTask->startTask(); +#endif /* OBSW_ADD_RTD_DEVICES == 1 */ #if OBSW_ADD_PLOC_SUPERVISOR == 1 supvHelperTask->startTask(); #endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ @@ -393,13 +428,22 @@ void initmission::createPusTasks(TaskFactory& factory, PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + + result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_3", objects::PUS_SERVICE_3_HOUSEKEEPING); + } result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_11_TC_SCHEDULER); if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Object add component failed" << std::endl; + initmission::printAddObjectError("PUS_11", objects::PUS_SERVICE_11_TC_SCHEDULER); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -409,10 +453,6 @@ void initmission::createPusTasks(TaskFactory& factory, if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_201", objects::PUS_SERVICE_201_HEALTH); } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); - if (result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); - } taskVec.push_back(pusMedPrio); PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( diff --git a/bsp_q7s/core/InitMission.h b/bsp_q7s/core/InitMission.h index 5c509b79..e0b1d8f2 100644 --- a/bsp_q7s/core/InitMission.h +++ b/bsp_q7s/core/InitMission.h @@ -3,7 +3,7 @@ #include -#include "fsfw/tasks/Typedef.h" +#include "fsfw/tasks/definitions.h" class PeriodicTaskIF; class TaskFactory; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 1715fa63..dbef1841 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -93,8 +93,7 @@ #include "mission/tmtc/VirtualChannel.h" #include "mission/utility/TmFunnel.h" -ResetArgs resetArgsGnss0; -ResetArgs resetArgsGnss1; +ResetArgs RESET_ARGS_GNSS; void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; @@ -103,9 +102,13 @@ void Factory::setStaticFrameworkObjectIds() { CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; +#if OBSW_Q7S_EM == 1 + DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; +#else DeviceHandlerBase::powerSwitcherId = objects::PCDU_HANDLER; - // DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; -#if OBSW_TM_TO_PTME == 1 +#endif /* OBSW_Q7S_EM == 1 */ + + #if OBSW_TM_TO_PTME == 1 TmFunnel::downlinkDestination = objects::CCSDS_HANDLER; #else TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; @@ -214,6 +217,7 @@ void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) { SpiCookie* spiCookieRadSensor = new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, RAD_SENSOR::READ_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED); + spiCookieRadSensor->setMutexParams(MutexIF::TimeoutType::WAITING, spi::RAD_SENSOR_CS_TIMEOUT); auto radSensor = new RadiationSensorHandler(objects::RAD_SENSOR, objects::SPI_MAIN_COM_IF, spiCookieRadSensor, gpioComIF); static_cast(radSensor); @@ -461,15 +465,11 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_DEBUG_GPS == 1 debugGps = true; #endif - resetArgsGnss1.gnss1 = true; - resetArgsGnss1.gpioComIF = gpioComIF; - resetArgsGnss1.waitPeriodMs = 100; - resetArgsGnss0.gnss1 = false; - resetArgsGnss0.gpioComIF = gpioComIF; - resetArgsGnss0.waitPeriodMs = 100; - auto gpsHandler0 = + RESET_ARGS_GNSS.gpioComIF = gpioComIF; + RESET_ARGS_GNSS.waitPeriodMs = 100; + auto gpsCtrl = new GPSHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); - gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); + gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS); AcsBoardHelper acsBoardHelper = AcsBoardHelper( objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER, diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index d4500e0b..9301f6d3 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -1,4 +1,5 @@ #include + #include "OBSWConfig.h" #include "bsp_q7s/core/CoreController.h" #include "bsp_q7s/core/ObjectFactory.h" @@ -37,9 +38,13 @@ void ObjectFactory::produce(void* args) { createSolarArrayDeploymentComponents(); createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher); #if OBSW_ADD_SYRLINKS == 1 +#if OBSW_Q7S_EM == 1 + createSyrlinksComponents(nullptr); +#else createSyrlinksComponents(pwrSwitcher); +#endif /* OBSW_Q7S_EM == 1 */ #endif /* OBSW_ADD_SYRLINKS == 1 */ - createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher); + createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF); createPayloadComponents(gpioComIF); #if OBSW_ADD_MGT == 1 diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 638edcd5..00e7bbd9 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -38,7 +38,7 @@ void ObjectFactory::produce(void* args) { #if OBSW_ADD_SYRLINKS == 1 createSyrlinksComponents(pwrSwitcher); #endif /* OBSW_ADD_SYRLINKS == 1 */ - createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher); + createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF); createPayloadComponents(gpioComIF); #if OBSW_ADD_MGT == 1 diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 7a4a791c..33849fbe 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -70,9 +70,8 @@ void FileSystemHandler::fileSystemHandlerLoop() { void FileSystemHandler::fileSystemCheckup() { SdCardManager::SdStatePair statusPair; - sdcMan->getSdCardActiveStatus(statusPair); - sd::SdCard preferredSdCard; - sdcMan->getPreferredSdCard(preferredSdCard); + sdcMan->getSdCardsStatus(statusPair); + sd::SdCard preferredSdCard = sdcMan->getPreferredSdCard(); if ((preferredSdCard == sd::SdCard::SLOT_0) and (statusPair.first == sd::SdState::MOUNTED)) { currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; } else if ((preferredSdCard == sd::SdCard::SLOT_1) and @@ -109,11 +108,7 @@ ReturnValue_t FileSystemHandler::initialize() { << std::endl; } sdcMan = SdCardManager::instance(); - sd::SdCard preferredSdCard; - ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + sd::SdCard preferredSdCard = sdcMan->getPreferredSdCard(); if (preferredSdCard == sd::SdCard::SLOT_0) { currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; } else if (preferredSdCard == sd::SdCard::SLOT_1) { diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 4ca11787..cfd4f490 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -16,23 +16,51 @@ #include "linux/utility/utility.h" #include "scratchApi.h" -SdCardManager* SdCardManager::factoryInstance = nullptr; +SdCardManager* SdCardManager::INSTANCE = nullptr; SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) { mutex = MutexFactory::instance()->createMutex(); + ReturnValue_t result = mutex->lockMutex(); + if (result != RETURN_OK) { + sif::error << "SdCardManager::SdCardManager: Mutex lock failed" << std::endl; + } + uint8_t prefSdRaw = 0; + result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw); + result = mutex->unlockMutex(); + if (result != RETURN_OK) { + sif::error << "SdCardManager::SdCardManager: Mutex unlock failed" << std::endl; + } + + if (result != HasReturnvaluesIF::RETURN_OK) { + if (result == scratch::KEY_NOT_FOUND) { + sif::warning << "CoreController::sdCardInit: " + "Preferred SD card not set. Setting to 0" + << std::endl; + setPreferredSdCard(sd::SdCard::SLOT_0); + sdInfo.pref = sd::SdCard::SLOT_0; + } else { + // Should not happen. + // TODO: Maybe trigger event? + sif::error << "SdCardManager::SdCardManager: Reading preferred SD card from scratch" + "buffer failed" + << std::endl; + sdInfo.pref = sd::SdCard::SLOT_0; + } + } + sdInfo.pref = static_cast(prefSdRaw); } SdCardManager::~SdCardManager() {} void SdCardManager::create() { - if (factoryInstance == nullptr) { - factoryInstance = new SdCardManager(); + if (INSTANCE == nullptr) { + INSTANCE = new SdCardManager(); } } SdCardManager* SdCardManager::instance() { SdCardManager::create(); - return SdCardManager::factoryInstance; + return SdCardManager::INSTANCE; } ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard, @@ -51,7 +79,7 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar if (statusPair == nullptr) { sdStatusPtr = std::make_unique(); statusPair = sdStatusPtr.get(); - result = getSdCardActiveStatus(*statusPair); + result = getSdCardsStatus(*statusPair); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -98,7 +126,7 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, SdStatePair* statusPair) { std::pair active; - ReturnValue_t result = getSdCardActiveStatus(active); + ReturnValue_t result = getSdCardsStatus(active); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -165,7 +193,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { return result; } -ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatePair& active) { +ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& active) { using namespace std; MutexGuard mg(mutex); if (not filesystem::exists(SD_STATE_FILE)) { @@ -273,14 +301,14 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard p resetNonBlockingState = true; } if (prefSdCard == sd::SdCard::NONE) { - result = getPreferredSdCard(prefSdCard); + result = getPreferredSdCard(); if (result != HasReturnvaluesIF::RETURN_OK) { } } if (statusPair == nullptr) { sdStatusPtr = std::make_unique(); statusPair = sdStatusPtr.get(); - getSdCardActiveStatus(*statusPair); + getSdCardsStatus(*statusPair); } if (statusPair->first == sd::SdState::ON) { @@ -351,20 +379,21 @@ void SdCardManager::processSdStatusLine(std::pair& act idx++; } -ReturnValue_t SdCardManager::getPreferredSdCard(sd::SdCard& sdCard) const { - uint8_t prefSdCard = 0; - ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; +sd::SdCard SdCardManager::getPreferredSdCard() const { + MutexGuard mg(mutex); + auto res = mg.getLockResult(); + if (res != RETURN_OK) { + sif::error << "SdCardManager::getPreferredSdCard: Lock error" << std::endl; } - sdCard = static_cast(prefSdCard); - return HasReturnvaluesIF::RETURN_OK; + return sdInfo.pref; } ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { + MutexGuard mg(mutex); if (sdCard == sd::SdCard::BOTH) { return HasReturnvaluesIF::RETURN_FAILED; } + sdInfo.pref = sdCard; return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast(sdCard)); } @@ -383,14 +412,9 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() { return result; } -std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { - if (prefSdCard == sd::SdCard::NONE) { - ReturnValue_t result = getPreferredSdCard(prefSdCard); - if (result != HasReturnvaluesIF::RETURN_OK) { - return SD_0_MOUNT_POINT; - } - } - if (prefSdCard == sd::SdCard::SLOT_0) { +std::string SdCardManager::getCurrentMountPrefix() const { + MutexGuard mg(mutex); + if (sdInfo.active == sd::SdCard::SLOT_0) { return SD_0_MOUNT_POINT; } else { return SD_1_MOUNT_POINT; @@ -443,7 +467,7 @@ void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = p bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { SdCardManager::SdStatePair active; - ReturnValue_t result = this->getSdCardActiveStatus(active); + ReturnValue_t result = this->getSdCardsStatus(active); if (result != HasReturnvaluesIF::RETURN_OK) { sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state"; @@ -466,3 +490,68 @@ bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { } return false; } + +ReturnValue_t SdCardManager::isSdCardMountedReadOnly(sd::SdCard sdcard, bool& readOnly) { + std::ostringstream command; + if (sdcard == sd::SdCard::SLOT_0) { + command << "grep -q '" << SD_0_MOUNT_POINT << " vfat ro,' /proc/mounts"; + } else { + command << "grep -q '" << SD_1_MOUNT_POINT << " vfat ro,' /proc/mounts"; + } + ReturnValue_t result = cmdExecutor.load(command.str(), true, false); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = cmdExecutor.execute(); + if (result != HasReturnvaluesIF::RETURN_OK) { + int exitStatus = cmdExecutor.getLastError(); + if (exitStatus == 1) { + readOnly = false; + return RETURN_OK; + } + return result; + } + auto& readVec = cmdExecutor.getReadVector(); + size_t readLen = strnlen(readVec.data(), readVec.size()); + if (readLen == 0) { + readOnly = false; + } + readOnly = true; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SdCardManager::remountReadWrite(sd::SdCard sdcard) { + std::ostringstream command; + if (sdcard == sd::SdCard::SLOT_0) { + command << "mount -o remount,rw " << SD_0_DEV_NAME << " " << SD_0_MOUNT_POINT; + } else { + command << "mount -o remount,rw " << SD_1_DEV_NAME << " " << SD_1_MOUNT_POINT; + } + ReturnValue_t result = cmdExecutor.load(command.str(), true, false); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return cmdExecutor.execute(); +} + +ReturnValue_t SdCardManager::performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError) { + std::ostringstream command; + if (sdcard == sd::SdCard::SLOT_0) { + command << "fsck -y " << SD_0_DEV_NAME; + } else { + command << "fsck -y " << SD_1_DEV_NAME; + } + ReturnValue_t result = cmdExecutor.load(command.str(), true, printOutput); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = cmdExecutor.execute(); + if (result != HasReturnvaluesIF::RETURN_OK) { + linuxError = cmdExecutor.getLastError(); + } + return result; +} + +void SdCardManager::setActiveSdCard(sd::SdCard sdCard) { sdInfo.active = sdCard; } + +sd::SdCard SdCardManager::getActiveSdCard() const { return sdInfo.active; } diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 37660f75..84d2d97b 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -24,7 +24,7 @@ class MutexIF; * @brief Manages handling of SD cards like switching them on or off or getting the current * state */ -class SdCardManager : public SystemObject, public SdCardMountedIF { +class SdCardManager : public SystemObject, public HasReturnvaluesIF, public SdCardMountedIF { friend class SdCardAccess; public: @@ -36,6 +36,12 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { using SdStatePair = std::pair; + struct SdInfo { + sd::SdCard pref = sd::SdCard::NONE; + sd::SdCard other = sd::SdCard::NONE; + sd::SdCard active = sd::SdCard::NONE; + } sdInfo; + static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; static constexpr ReturnValue_t OP_ONGOING = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); @@ -91,7 +97,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { * @param sdCard * @return */ - ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const override; + sd::SdCard getPreferredSdCard() const override; /** * Switch on the specified SD card. @@ -138,7 +144,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { * should call #updateSdCardStateFile again in that case * - STATUS_FILE_NEXISTS if the status file does not exist */ - ReturnValue_t getSdCardActiveStatus(SdStatePair& active); + ReturnValue_t getSdCardsStatus(SdStatePair& active); /** * Mount the specified SD card. This is necessary to use it. @@ -146,6 +152,20 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { * @return */ ReturnValue_t mountSdCard(sd::SdCard sdCard); + + /** + * Set the currently active SD card. This does not necessarily mean that the SD card is on or + * mounted + * @param sdCard + */ + void setActiveSdCard(sd::SdCard sdCard) override; + /** + * Get the currently active SD card. This does not necessarily mean that the SD card is on or + * mounted + * @return + */ + sd::SdCard getActiveSdCard() const override; + /** * Unmount the specified SD card. This is recommended before switching it off. The SD card * can't be used after it has been unmounted. @@ -173,7 +193,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { * @param prefSdCardPtr * @return */ - std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE) override; + std::string getCurrentMountPrefix() const override; OpStatus checkCurrentOp(Operations& currentOp); @@ -194,6 +214,12 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { */ bool isSdCardMounted(sd::SdCard sdCard) override; + ReturnValue_t isSdCardMountedReadOnly(sd::SdCard sdcard, bool& readOnly); + + ReturnValue_t remountReadWrite(sd::SdCard sdcard); + + ReturnValue_t performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError); + private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; @@ -210,7 +236,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { std::string currentPrefix; - static SdCardManager* factoryInstance; + static SdCardManager* INSTANCE; }; #endif /* BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ */ diff --git a/bsp_q7s/memory/scratchApi.h b/bsp_q7s/memory/scratchApi.h index 96264995..cd76fca1 100644 --- a/bsp_q7s/memory/scratchApi.h +++ b/bsp_q7s/memory/scratchApi.h @@ -76,12 +76,12 @@ ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& fil int result = std::system(oss.str().c_str()); if (result != 0) { if (WEXITSTATUS(result) == 1) { - sif::warning << "scratch::readNumber: Key " << name << " does not exist" << std::endl; + sif::warning << "scratch::readToFile: Key " << name << " does not exist" << std::endl; // Could not find value std::remove(filename.c_str()); return KEY_NOT_FOUND; } else { - utility::handleSystemError(result, "scratch::readNumber"); + utility::handleSystemError(result, "scratch::readToFile"); std::remove(filename.c_str()); return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/bsp_q7s/obsw.cpp b/bsp_q7s/obsw.cpp index 1da60783..530c4904 100644 --- a/bsp_q7s/obsw.cpp +++ b/bsp_q7s/obsw.cpp @@ -4,11 +4,11 @@ #include #include "OBSWConfig.h" -#include "q7sConfig.h" #include "commonConfig.h" #include "core/InitMission.h" #include "fsfw/tasks/TaskFactory.h" #include "fsfw/version.h" +#include "q7sConfig.h" #include "watchdog/definitions.h" static int OBSW_ALREADY_RUNNING = -2; diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index ad19e135..9581e751 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -33,6 +33,9 @@ static constexpr uint8_t OBSW_VERSION_REVISION = @OBSW_VERSION_REVISION@; // CST: Commits since tag static const char OBSW_VERSION_CST_GIT_SHA1[] = "@OBSW_VERSION_CST_GIT_SHA1@"; + +static constexpr uint32_t OBSW_MAX_SCHEDULED_TCS = @OBSW_MAX_SCHEDULED_TCS@; + extern const fsfw::Version OBSW_VERSION; extern const uint16_t PUS_PACKET_ID; diff --git a/common/config/devConf.h b/common/config/devConf.h index 37e10bf3..51da9011 100644 --- a/common/config/devConf.h +++ b/common/config/devConf.h @@ -1,11 +1,12 @@ #ifndef COMMON_CONFIG_DEVCONF_H_ #define COMMON_CONFIG_DEVCONF_H_ -#include -#include - #include +#include "fsfw/timemanager/clockDefinitions.h" +#include "fsfw_hal/linux/spi/spiDefinitions.h" +#include "fsfw_hal/linux/uart/UartCookie.h" + /** * SPI configuration will be contained here to let the device handlers remain independent * of SPI specific properties. @@ -32,6 +33,7 @@ static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3; static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000; static constexpr spi::SpiModes SUS_MAX_1227_MODE = spi::SpiModes::MODE_3; +static constexpr dur_millis_t RAD_SENSOR_CS_TIMEOUT = 120; static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000; static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3; @@ -43,6 +45,7 @@ static constexpr spi::SpiModes DEFAULT_ADIS16507_MODE = spi::SpiModes::MODE_3; static constexpr uint32_t RW_SPEED = 300'000; static constexpr spi::SpiModes RW_MODE = spi::SpiModes::MODE_0; +static constexpr dur_millis_t RTD_CS_TIMEOUT = 50; static constexpr uint32_t RTD_SPEED = 2'000'000; static constexpr spi::SpiModes RTD_MODE = spi::SpiModes::MODE_3; diff --git a/bsp_hosted/fsfwconfig/tmtc/pusIds.h b/common/config/tmtc/pusIds.h similarity index 71% rename from bsp_hosted/fsfwconfig/tmtc/pusIds.h rename to common/config/tmtc/pusIds.h index 37503786..0891992d 100644 --- a/bsp_hosted/fsfwconfig/tmtc/pusIds.h +++ b/common/config/tmtc/pusIds.h @@ -1,5 +1,5 @@ -#ifndef CONFIG_TMTC_PUSIDS_HPP_ -#define CONFIG_TMTC_PUSIDS_HPP_ +#ifndef COMMON_CONFIG_TMTC_PUSIDS_H_ +#define COMMON_CONFIG_TMTC_PUSIDS_H_ namespace pus { enum Ids { @@ -11,6 +11,7 @@ enum Ids { PUS_SERVICE_6 = 6, PUS_SERVICE_8 = 8, PUS_SERVICE_9 = 9, + PUS_SERVICE_11 = 11, PUS_SERVICE_17 = 17, PUS_SERVICE_19 = 19, PUS_SERVICE_20 = 20, @@ -20,4 +21,4 @@ enum Ids { }; }; -#endif /* CONFIG_TMTC_PUSIDS_HPP_ */ +#endif /* COMMON_CONFIG_TMTC_PUSIDS_H_ */ diff --git a/fsfw b/fsfw index e758f0be..95a64e1d 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit e758f0be2e8864c761877a4dcbdf461df52072f7 +Subproject commit 95a64e1da3bb6d334c58c9ba78747bcdaccd5a8b diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index c16f83ff..f3793f8f 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -75,6 +75,7 @@ 7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 8900;0x22c4;CLOCK_SET;INFO;;fsfw/src/fsfw/pus/Service9TimeManagement.h 8901;0x22c5;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h +9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 9700;0x25e4;TEST;INFO;;fsfw/src/fsfw/pus/Service17Test.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;;fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h @@ -182,22 +183,24 @@ 13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/devices/P60DockHandler.h 13600;0x3520;SUPV_UPDATE_FAILED;LOW;update failed;linux/devices/ploc/PlocSupvHelper.h 13601;0x3521;SUPV_UPDATE_SUCCESSFUL;LOW;update successful;linux/devices/ploc/PlocSupvHelper.h -13602;0x3522;TERMINATED_UPDATE_PROCEDURE;LOW;Terminated update procedure by command;linux/devices/ploc/PlocSupvHelper.h -13603;0x3523;SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL;LOW;Requesting event buffer was successful;linux/devices/ploc/PlocSupvHelper.h -13604;0x3524;SUPV_EVENT_BUFFER_REQUEST_FAILED;LOW;Requesting event buffer failed;linux/devices/ploc/PlocSupvHelper.h -13605;0x3525;SUPV_EVENT_BUFFER_REQUEST_TERMINATED;LOW;Terminated event buffer request by command P1: Number of packets read before process was terminated;linux/devices/ploc/PlocSupvHelper.h -13606;0x3526;SUPV_SENDING_COMMAND_FAILED;LOW;;linux/devices/ploc/PlocSupvHelper.h -13607;0x3527;SUPV_HELPER_REQUESTING_REPLY_FAILED;LOW;Request receive message of communication interface failed P1: Return value returned by the communication interface requestReceiveMessage function P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h -13608;0x3528;SUPV_HELPER_READING_REPLY_FAILED;LOW;Reading receive message of communication interface failed P1: Return value returned by the communication interface readingReceivedMessage function P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h -13609;0x3529;SUPV_MISSING_ACK;LOW;Did not receive acknowledgement report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/devices/ploc/PlocSupvHelper.h -13610;0x352a;SUPV_MISSING_EXE;LOW;Supervisor did not receive execution report P1: Number of bytes missing P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h -13611;0x352b;SUPV_ACK_FAILURE_REPORT;LOW;Supervisor received acknowledgment failure report P1: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h -13612;0x352c;SUPV_EXE_FAILURE_REPORT;LOW;Execution report failure P1:;linux/devices/ploc/PlocSupvHelper.h -13613;0x352d;SUPV_ACK_INVALID_APID;LOW;Supervisor expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h -13614;0x352e;SUPV_EXE_INVALID_APID;LOW;Supervisor helper expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h -13615;0x352f;ACK_RECEPTION_FAILURE;LOW;Failed to receive acknowledgment report P1: Return value P2: Apid of command for which the reception of the acknowledgment report failed;linux/devices/ploc/PlocSupvHelper.h -13616;0x3530;EXE_RECEPTION_FAILURE;LOW;Failed to receive execution report P1: Return value P2: Apid of command for which the reception of the execution report failed;linux/devices/ploc/PlocSupvHelper.h -13617;0x3531;WRITE_MEMORY_FAILED;LOW;Update procedure failed when sending packet with number P1 P1: Packet number for which the memory write command fails;linux/devices/ploc/PlocSupvHelper.h +13602;0x3522;SUPV_CONTINUE_UPDATE_FAILED;LOW;Continue update command failed;linux/devices/ploc/PlocSupvHelper.h +13603;0x3523;SUPV_CONTINUE_UPDATE_SUCCESSFUL;LOW;Continue update command successful;linux/devices/ploc/PlocSupvHelper.h +13604;0x3524;TERMINATED_UPDATE_PROCEDURE;LOW;Terminated update procedure by command;linux/devices/ploc/PlocSupvHelper.h +13605;0x3525;SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL;LOW;Requesting event buffer was successful;linux/devices/ploc/PlocSupvHelper.h +13606;0x3526;SUPV_EVENT_BUFFER_REQUEST_FAILED;LOW;Requesting event buffer failed;linux/devices/ploc/PlocSupvHelper.h +13607;0x3527;SUPV_EVENT_BUFFER_REQUEST_TERMINATED;LOW;Terminated event buffer request by command P1: Number of packets read before process was terminated;linux/devices/ploc/PlocSupvHelper.h +13608;0x3528;SUPV_SENDING_COMMAND_FAILED;LOW;;linux/devices/ploc/PlocSupvHelper.h +13609;0x3529;SUPV_HELPER_REQUESTING_REPLY_FAILED;LOW;Request receive message of communication interface failed P1: Return value returned by the communication interface requestReceiveMessage function P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h +13610;0x352a;SUPV_HELPER_READING_REPLY_FAILED;LOW;Reading receive message of communication interface failed P1: Return value returned by the communication interface readingReceivedMessage function P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h +13611;0x352b;SUPV_MISSING_ACK;LOW;Did not receive acknowledgement report P1: Number of bytes missing P2: Internal state of MPSoC helper;linux/devices/ploc/PlocSupvHelper.h +13612;0x352c;SUPV_MISSING_EXE;LOW;Supervisor did not receive execution report P1: Number of bytes missing P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h +13613;0x352d;SUPV_ACK_FAILURE_REPORT;LOW;Supervisor received acknowledgment failure report P1: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h +13614;0x352e;SUPV_EXE_FAILURE_REPORT;LOW;Execution report failure P1:;linux/devices/ploc/PlocSupvHelper.h +13615;0x352f;SUPV_ACK_INVALID_APID;LOW;Supervisor expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h +13616;0x3530;SUPV_EXE_INVALID_APID;LOW;Supervisor helper expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of supervisor helper;linux/devices/ploc/PlocSupvHelper.h +13617;0x3531;ACK_RECEPTION_FAILURE;LOW;Failed to receive acknowledgment report P1: Return value P2: Apid of command for which the reception of the acknowledgment report failed;linux/devices/ploc/PlocSupvHelper.h +13618;0x3532;EXE_RECEPTION_FAILURE;LOW;Failed to receive execution report P1: Return value P2: Apid of command for which the reception of the execution report failed;linux/devices/ploc/PlocSupvHelper.h +13619;0x3533;WRITE_MEMORY_FAILED;LOW;Update procedure failed when sending packet with number P1 P1: Packet number for which the memory write command fails;linux/devices/ploc/PlocSupvHelper.h 13700;0x3584;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h 13701;0x3585;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h 13702;0x3586;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index f9380ece..f0d29ee2 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -71,6 +71,7 @@ 0x49010005;GPIO_IF 0x49020004;SPI_MAIN_COM_IF 0x49020005;SPI_RW_COM_IF +0x49020006;SPI_RTD_COM_IF 0x49030003;UART_COM_IF 0x49040002;I2C_COM_IF 0x49050001;CSP_COM_IF @@ -91,6 +92,7 @@ 0x53000005;PUS_SERVICE_5_EVENT_REPORTING 0x53000008;PUS_SERVICE_8_FUNCTION_MGMT 0x53000009;PUS_SERVICE_9_TIME_MGMT +0x53000011;PUS_SERVICE_11_TC_SCHEDULER 0x53000017;PUS_SERVICE_17_TEST 0x53000020;PUS_SERVICE_20_PARAMETERS 0x53000200;PUS_SERVICE_200_MODE_MGMT diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index b25649fd..64006689 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -1,73 +1,73 @@ 0x0;OK;System-wide code for ok.;RETURN_OK;HasReturnvaluesIF.h;HasReturnvaluesIF 0x1;Failed;Unspecified system-wide code for failed.;RETURN_FAILED;HasReturnvaluesIF.h;HasReturnvaluesIF -0x63a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;0xA0;mission/tmtc/CCSDSHandler.h;CCSDS_HANDLER -0x69a0;SADPL_CommandNotSupported;;0xA0;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x69a1;SADPL_DeploymentAlreadyExecuting;;0xA1;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x69a2;SADPL_MainSwitchTimeoutFailure;;0xA2;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x69a3;SADPL_SwitchingDeplSa1Failed;;0xA3;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x69a4;SADPL_SwitchingDeplSa2Failed;;0xA4;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x5ba0;SUSS_ErrorUnlockMutex;;0xA0;mission/devices/SusHandler.h;SUS_HANDLER -0x5ba1;SUSS_ErrorLockMutex;;0xA1;mission/devices/SusHandler.h;SUS_HANDLER -0x55b0;RWHA_SpiWriteFailure;;0xB0;mission/devices/RwHandler.h;RW_HANDLER -0x55b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;0xB1;mission/devices/RwHandler.h;RW_HANDLER -0x55b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;0xB2;mission/devices/RwHandler.h;RW_HANDLER -0x55b3;RWHA_InvalidSubstitute;Can be used by the HDLC decoding mechanism to inform about an invalid substitution combination;0xB3;mission/devices/RwHandler.h;RW_HANDLER -0x55b4;RWHA_MissingEndSign;HDLC decoding mechanism never receives the end sign 0x7E;0xB4;mission/devices/RwHandler.h;RW_HANDLER -0x55b5;RWHA_NoReply;Reaction wheel only responds with empty frames.;0xB5;mission/devices/RwHandler.h;RW_HANDLER -0x55b6;RWHA_NoStartMarker;Expected a start marker as first byte;0xB6;mission/devices/RwHandler.h;RW_HANDLER -0x55a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000; 1000] or [1000; 65000];0xA0;mission/devices/RwHandler.h;RW_HANDLER -0x55a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;0xA1;mission/devices/RwHandler.h;RW_HANDLER -0x55a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;0xA2;mission/devices/RwHandler.h;RW_HANDLER -0x55a3;RWHA_ExecutionFailed;Command execution failed;0xA3;mission/devices/RwHandler.h;RW_HANDLER -0x55a4;RWHA_CrcError;Reaction wheel reply has invalid crc;0xA4;mission/devices/RwHandler.h;RW_HANDLER -0x54a0;IMTQ_InvalidCommandCode;;0xA0;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a1;IMTQ_ParameterMissing;;0xA1;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a2;IMTQ_ParameterInvalid;;0xA2;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a3;IMTQ_CcUnavailable;;0xA3;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a4;IMTQ_InternalProcessingError;;0xA4;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a5;IMTQ_RejectedWithoutReason;;0xA5;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a6;IMTQ_CmdErrUnknown;;0xA6;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x54a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;0xA7;mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x52a1;HEATER_CommandNotSupported;;0xA1;mission/devices/HeaterHandler.h;HEATER_HANDLER -0x52a2;HEATER_InitFailed;;0xA2;mission/devices/HeaterHandler.h;HEATER_HANDLER -0x52a3;HEATER_InvalidSwitchNr;;0xA3;mission/devices/HeaterHandler.h;HEATER_HANDLER -0x52a4;HEATER_MainSwitchSetTimeout;;0xA4;mission/devices/HeaterHandler.h;HEATER_HANDLER -0x52a5;HEATER_CommandAlreadyWaiting;;0xA5;mission/devices/HeaterHandler.h;HEATER_HANDLER -0x6000;GOMS_PacketTooLong;;0;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x6001;GOMS_InvalidTableId;;1;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x6002;GOMS_InvalidAddress;;2;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x6003;GOMS_InvalidParamSize;;3;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x6004;GOMS_InvalidPayloadSize;;4;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x6005;GOMS_UnknownReplyId;;5;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x53a0;SYRLINKS_CrcFailure;;0xA0;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a1;SYRLINKS_UartFraminOrParityErrorAck;;0xA1;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a2;SYRLINKS_BadCharacterAck;;0xA2;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a3;SYRLINKS_BadParameterValueAck;;0xA3;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a4;SYRLINKS_BadEndOfFrameAck;;0xA4;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a5;SYRLINKS_UnknownCommandIdAck;;0xA5;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a6;SYRLINKS_BadCrcAck;;0xA6;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a7;SYRLINKS_ReplyWrongSize;;0xA7;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a8;SYRLINKS_MissingStartFrameCharacter;;0xA8;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x66a0;NVMB_KeyNotExists;Specified key does not exist in json file;0xA0;mission/memory/NVMParameterBase.h;NVM_PARAM_BASE -0x4300; HSPI_OpeningFileFailed;;0;fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h;HAL_SPI -0x4301; HSPI_FullDuplexTransferFailed;;1;fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h;HAL_SPI -0x4302; HSPI_HalfDuplexTransferFailed;;2;fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h;HAL_SPI -0x4401; HURT_UartReadFailure;;1;fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART -0x4402; HURT_UartReadSizeMissmatch;;2;fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART -0x4403; HURT_UartRxBufferTooSmall;;3;fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART -0x4601; HGIO_UnknownGpioId;;1;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4602; HGIO_DriveGpioFailure;;2;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4603; HGIO_GpioTypeFailure;;3;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4604; HGIO_GpioInvalidInstance;;4;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4605; HGIO_GpioDuplicateDetected;;5;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4606; HGIO_GpioInitFailed;;6;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4607; HGIO_GpioGetValueFailed;;7;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4200; UXOS_ExecutionFinished;Execution of the current command has finished;0;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL -0x4201; UXOS_CommandPending;Command is pending. This will also be returned if the user tries to load another command but a command is still pending;1;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL -0x4202; UXOS_BytesRead;Some bytes have been read from the executing process;2;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL -0x4203; UXOS_CommandError;Command execution failed;3;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL -0x4204; UXOS_NoCommandLoadedOrPending;;4;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL -0x4206; UXOS_PcloseCallError;;6;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL +0x64a0; CCSDS_CommandNotImplemented;Received action message with unknown action id;0xA0;mission/tmtc/CCSDSHandler.h;CCSDS_HANDLER +0x6aa0; SADPL_CommandNotSupported;;0xA0;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x6aa1; SADPL_DeploymentAlreadyExecuting;;0xA1;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x6aa2; SADPL_MainSwitchTimeoutFailure;;0xA2;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x6aa3; SADPL_SwitchingDeplSa1Failed;;0xA3;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x6aa4; SADPL_SwitchingDeplSa2Failed;;0xA4;mission/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5ca0; SUSS_ErrorUnlockMutex;;0xA0;mission/devices/SusHandler.h;SUS_HANDLER +0x5ca1; SUSS_ErrorLockMutex;;0xA1;mission/devices/SusHandler.h;SUS_HANDLER +0x56b0; RWHA_SpiWriteFailure;;0xB0;mission/devices/RwHandler.h;RW_HANDLER +0x56b1; RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;0xB1;mission/devices/RwHandler.h;RW_HANDLER +0x56b2; RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;0xB2;mission/devices/RwHandler.h;RW_HANDLER +0x56b3; RWHA_InvalidSubstitute;Can be used by the HDLC decoding mechanism to inform about an invalid substitution combination;0xB3;mission/devices/RwHandler.h;RW_HANDLER +0x56b4; RWHA_MissingEndSign;HDLC decoding mechanism never receives the end sign 0x7E;0xB4;mission/devices/RwHandler.h;RW_HANDLER +0x56b5; RWHA_NoReply;Reaction wheel only responds with empty frames.;0xB5;mission/devices/RwHandler.h;RW_HANDLER +0x56b6; RWHA_NoStartMarker;Expected a start marker as first byte;0xB6;mission/devices/RwHandler.h;RW_HANDLER +0x56a0; RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000; 1000] or [1000; 65000];0xA0;mission/devices/RwHandler.h;RW_HANDLER +0x56a1; RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;0xA1;mission/devices/RwHandler.h;RW_HANDLER +0x56a2; RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;0xA2;mission/devices/RwHandler.h;RW_HANDLER +0x56a3; RWHA_ExecutionFailed;Command execution failed;0xA3;mission/devices/RwHandler.h;RW_HANDLER +0x56a4; RWHA_CrcError;Reaction wheel reply has invalid crc;0xA4;mission/devices/RwHandler.h;RW_HANDLER +0x55a0; IMTQ_InvalidCommandCode;;0xA0;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a1; IMTQ_ParameterMissing;;0xA1;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a2; IMTQ_ParameterInvalid;;0xA2;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a3; IMTQ_CcUnavailable;;0xA3;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a4; IMTQ_InternalProcessingError;;0xA4;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a5; IMTQ_RejectedWithoutReason;;0xA5;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a6; IMTQ_CmdErrUnknown;;0xA6;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x55a7; IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;0xA7;mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x53a1; HEATER_CommandNotSupported;;0xA1;mission/devices/HeaterHandler.h;HEATER_HANDLER +0x53a2; HEATER_InitFailed;;0xA2;mission/devices/HeaterHandler.h;HEATER_HANDLER +0x53a3; HEATER_InvalidSwitchNr;;0xA3;mission/devices/HeaterHandler.h;HEATER_HANDLER +0x53a4; HEATER_MainSwitchSetTimeout;;0xA4;mission/devices/HeaterHandler.h;HEATER_HANDLER +0x53a5; HEATER_CommandAlreadyWaiting;;0xA5;mission/devices/HeaterHandler.h;HEATER_HANDLER +0x6100; GOMS_PacketTooLong;;0;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x6101; GOMS_InvalidTableId;;1;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x6102; GOMS_InvalidAddress;;2;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x6103; GOMS_InvalidParamSize;;3;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x6104; GOMS_InvalidPayloadSize;;4;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x6105; GOMS_UnknownReplyId;;5;mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x54a0; SYRLINKS_CrcFailure;;0xA0;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a1; SYRLINKS_UartFraminOrParityErrorAck;;0xA1;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a2; SYRLINKS_BadCharacterAck;;0xA2;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a3; SYRLINKS_BadParameterValueAck;;0xA3;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a4; SYRLINKS_BadEndOfFrameAck;;0xA4;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a5; SYRLINKS_UnknownCommandIdAck;;0xA5;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a6; SYRLINKS_BadCrcAck;;0xA6;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a7; SYRLINKS_ReplyWrongSize;;0xA7;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x54a8; SYRLINKS_MissingStartFrameCharacter;;0xA8;mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x67a0; NVMB_KeyNotExists;Specified key does not exist in json file;0xA0;mission/memory/NVMParameterBase.h;NVM_PARAM_BASE +0x4400; HSPI_OpeningFileFailed;;0;fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h;HAL_SPI +0x4401; HSPI_FullDuplexTransferFailed;;1;fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h;HAL_SPI +0x4402; HSPI_HalfDuplexTransferFailed;;2;fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h;HAL_SPI +0x4501; HURT_UartReadFailure;;1;fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART +0x4502; HURT_UartReadSizeMissmatch;;2;fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART +0x4503; HURT_UartRxBufferTooSmall;;3;fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART +0x4701; HGIO_UnknownGpioId;;1;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4702; HGIO_DriveGpioFailure;;2;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4703; HGIO_GpioTypeFailure;;3;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4704; HGIO_GpioInvalidInstance;;4;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4705; HGIO_GpioDuplicateDetected;;5;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4706; HGIO_GpioInitFailed;;6;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4707; HGIO_GpioGetValueFailed;;7;fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4300; UXOS_ExecutionFinished;Execution of the current command has finished;0;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL +0x4301; UXOS_CommandPending;Command is pending. This will also be returned if the user tries to load another command but a command is still pending;1;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL +0x4302; UXOS_BytesRead;Some bytes have been read from the executing process;2;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL +0x4303; UXOS_CommandError;Command execution failed;3;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL +0x4304; UXOS_NoCommandLoadedOrPending;;4;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL +0x4306; UXOS_PcloseCallError;;6;fsfw/hal/src/fsfw_hal/linux/CommandExecutor.h;LINUX_OSAL 0x3b00; LPIF_PoolEntryNotFound;;0x00;fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF 0x3b01; LPIF_PoolEntryTypeConflict;;0x01;fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF 0x3d00; HKM_QueueOrDestinationInvalid;;0;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER @@ -104,6 +104,7 @@ 0x2c08; PAW_ColumnOrRowsZero;;0x08;fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER 0x1701; HHI_ObjectNotHealthy;;1;fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF 0x1702; HHI_InvalidHealthState;;2;fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF +0x1703; HHI_IsExternallyControlled;;3;fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF 0x2701; SM_DataTooLarge;;1;fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF 0x2702; SM_DataStorageFull;;2;fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF 0x2703; SM_IllegalStorageId;;3;fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF @@ -120,6 +121,9 @@ 0x2e01; ASC_TooLongForTargetType;;1;fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER 0x2e02; ASC_InvalidCharacters;;2;fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER 0x2e03; ASC_BufferTooSmall;;0x3;fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0x4101; PUS11_InvalidTypeTimeWindow;;1;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h;PUS_SERVICE_11 +0x4102; PUS11_TimeshiftingNotPossible;;2;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h;PUS_SERVICE_11 +0x4103; PUS11_InvalidRelativeTime;;3;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h;PUS_SERVICE_11 0x1c01; TCD_PacketLost;;1;fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION 0x1c02; TCD_DestinationNotFound;;2;fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION 0x1c03; TCD_ServiceIdAlreadyExists;;3;fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION @@ -205,8 +209,8 @@ 0x1401; SE_BufferTooShort;;1;fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF 0x1402; SE_StreamTooShort;;2;fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF 0x1403; SE_TooManyElements;;3;fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x4a00; SPPA_NoPacketFound;;0x00;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h;SPACE_PACKET_PARSER -0x4a01; SPPA_SplitPacket;;0x01;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h;SPACE_PACKET_PARSER +0x4b00; SPPA_NoPacketFound;;0x00;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h;SPACE_PACKET_PARSER +0x4b01; SPPA_SplitPacket;;0x01;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h;SPACE_PACKET_PARSER 0x1d01; PUS_ActivityStarted;;1;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF 0x1d02; PUS_InvalidSubservice;;2;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF 0x1d03; PUS_IllegalApplicationData;;3;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF @@ -303,17 +307,17 @@ 0x13e1; MH_InvalidAddress;;0xE1;fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER 0x13e2; MH_InvalidSize;;0xE2;fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER 0x13e3; MH_StateMismatch;;0xE3;fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x4100; FILS_GenericFileError;;0;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4101; FILS_IsBusy;;1;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4102; FILS_InvalidParameters;;2;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4105; FILS_FileDoesNotExist;;5;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4106; FILS_FileAlreadyExists;;6;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4107; FILS_FileLocked;;7;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x410a; FILS_DirectoryDoesNotExist;;10;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x410b; FILS_DirectoryAlreadyExists;;11;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x410c; FILS_DirectoryNotEmpty;;12;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x410f; FILS_SequencePacketMissingWrite;;15;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4110; FILS_SequencePacketMissingRead;;16;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4200; FILS_GenericFileError;;0;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4201; FILS_IsBusy;;1;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4202; FILS_InvalidParameters;;2;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4205; FILS_FileDoesNotExist;;5;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4206; FILS_FileAlreadyExists;;6;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4207; FILS_FileLocked;;7;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x420a; FILS_DirectoryDoesNotExist;;10;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x420b; FILS_DirectoryAlreadyExists;;11;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x420c; FILS_DirectoryNotEmpty;;12;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x420f; FILS_SequencePacketMissingWrite;;15;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4210; FILS_SequencePacketMissingRead;;16;fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM 0x601; PP_DoItMyself;;1;fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF 0x602; PP_PointsToVariable;;2;fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF 0x603; PP_PointsToMemory;;3;fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF @@ -446,113 +450,113 @@ 0x3a01; SPH_SemaphoreTimeout;;1;fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF 0x3a02; SPH_SemaphoreNotOwned;;2;fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF 0x3a03; SPH_SemaphoreInvalid;;3;fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x7200; SDMA_OpOngoing;;0;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x7201; SDMA_AlreadyOn;;1;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x7202; SDMA_AlreadyMounted;;2;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x7203; SDMA_AlreadyOff;;3;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x720a; SDMA_StatusFileNexists;;10;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x720b; SDMA_StatusFileFormatInvalid;;11;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x720c; SDMA_MountError;;12;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x720d; SDMA_UnmountError;;13;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x720e; SDMA_SystemCallError;;14;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x720f; SDMA_PopenCallError;;15;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x7300; SCBU_KeyNotFound;;0;bsp_q7s/memory/scratchApi.h;SCRATCH_BUFFER -0x67a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;0xA0;bsp_q7s/memory/FilesystemHelper.h;FILE_SYSTEM_HELPER -0x67a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;0xA1;bsp_q7s/memory/FilesystemHelper.h;FILE_SYSTEM_HELPER -0x6aa0;MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;0xA0;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa1;MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;0xA1;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa2;MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;0xA2;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa3;MPSOCRTVIF_InvalidApid;Received space packet with invalid APID from PLOC;0xA3;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa4;MPSOCRTVIF_InvalidLength;Received command with invalid length;0xA4;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa5;MPSOCRTVIF_FilenameTooLong;Filename of file in OBC filesystem is too long;0xA5;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa6;MPSOCRTVIF_MpsocHelperExecuting;MPSoC helper is currently executing a command;0xA6;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa7;MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);0xA7;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa8;MPSOCRTVIF_InvalidParameter;Command has invalid parameter;0xA8;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6aa9;MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;0xA9;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF -0x6ba0;SPVRTVIF_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;0xA0;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba1;SPVRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;0xA1;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba2;SPVRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC supervisor;0xA2;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba3;SPVRTVIF_InvalidApid;Received space packet with invalid APID from PLOC supervisor;0xA3;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba4;SPVRTVIF_GetTimeFailure;Failed to read current system time;0xA4;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba5;SPVRTVIF_InvalidWatchdog;Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT;0xA5;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba6;SPVRTVIF_InvalidWatchdogTimeout;Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms.;0xA6;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba7;SPVRTVIF_InvalidLatchupId;Received latchup config command with invalid latchup ID;0xA7;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba8;SPVRTVIF_SweepPeriodTooSmall;Received set adc sweep period command with invalid sweep period. Must be larger than 21.;0xA8;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6ba9;SPVRTVIF_InvalidTestParam;Receive auto EM test command with invalid test param. Valid params are 1 and 2.;0xA9;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6baa;SPVRTVIF_MramPacketParsingFailure;Returned when scanning for MRAM dump packets failed.;0xAA;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bab;SPVRTVIF_InvalidMramAddresses;Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address);0xAB;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bac;SPVRTVIF_NoMramPacket;Expect reception of an MRAM dump packet but received space packet with other apid.;0xAC;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bad;SPVRTVIF_PathDoesNotExist;Path to PLOC directory on SD card does not exist;0xAD;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bae;SPVRTVIF_MramFileNotExists;MRAM dump file does not exists. The file should actually already have been created with the reception of the first dump packet.;0xAE;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6baf;SPVRTVIF_InvalidLength;Received action command has invalid length;0xAF;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bb0;SPVRTVIF_FilenameTooLong;Filename too long;0xB0;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bb1;SPVRTVIF_UpdateStatusReportInvalidLength;Received update status report with invalid packet length field;0xB1;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bb2;SPVRTVIF_UpdateCrcFailure;Update status report does not contain expected CRC. There might be a bit flip in the update memory region.;0xB2;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x6bb3;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);0xB3;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF -0x57e0;DWLPWRON_InvalidMode;Received command has invalid JESD mode (valid modes are 0 - 5);0xE0;linux/devices/devicedefinitions/PlocMPSoCDefinitions.h;DWLPWRON_CMD -0x57e1;DWLPWRON_InvalidLaneRate;Received command has invalid lane rate (valid lane rate are 0 - 9);0xE1;linux/devices/devicedefinitions/PlocMPSoCDefinitions.h;DWLPWRON_CMD -0x61a0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;0xA0;linux/devices/ploc/PlocMemoryDumper.h;PLOC_MEMORY_DUMPER -0x61a1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;0xA1;linux/devices/ploc/PlocMemoryDumper.h;PLOC_MEMORY_DUMPER -0x68a0; PLMPHLP_FileClosedAccidentally;File accidentally close;0xA0;linux/devices/ploc/PlocMPSoCHelper.h;PLOC_MPSOC_HELPER -0x5aa0;PLSPVhLP_FileClosedAccidentally;File accidentally close;0xA0;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER -0x5aa1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;0xA1;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER -0x5aa2;PLSPVhLP_PathNotExists;Received command with invalid pathname;0xA2;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER -0x5aa3;PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;0xA3;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER -0x6501;JSONBASE_JsonFileNotExists;Specified json file does not exist;1;linux/devices/startracker/ArcsecJsonParamBase.h;ARCSEC_JSON_BASE -0x6502;JSONBASE_SetNotExists;Requested set does not exist in json file;2;linux/devices/startracker/ArcsecJsonParamBase.h;ARCSEC_JSON_BASE -0x6503;JSONBASE_ParamNotExists;Requested parameter does not exist in json file;3;linux/devices/startracker/ArcsecJsonParamBase.h;ARCSEC_JSON_BASE -0x56a0;STRH_TemperatureReqFailed;Status in temperature reply signals error;0xA0;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a1;STRH_PingFailed;Ping command failed;0xA1;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a2;STRH_VersionReqFailed;Status in version reply signals error;0xA2;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a3;STRH_InterfaceReqFailed;Status in interface reply signals error;0xA3;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a4;STRH_PowerReqFailed;Status in power reply signals error;0xA4;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a5;STRH_SetParamFailed;Status of reply to parameter set command signals error;0xA5;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a6;STRH_ActionFailed;Status of reply to action command signals error;0xA6;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a7;STRH_FilePathTooLong;Received invalid path string. Exceeds allowed length;0xA7;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a8;STRH_FilenameTooLong;Name of file received with command is too long;0xA8;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56a9;STRH_InvalidProgram;Received version reply with invalid program ID;0xA9;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56aa;STRH_ReplyError;Status field reply signals error;0xAA;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56ab;STRH_CommandTooShort;Received command which is too short (some data is missing for proper execution);0xAB;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56ac;STRH_InvalidLength;Received command with invalid length (too few or too many parameters);0xAC;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56ad;STRH_RegionMismatch;Region mismatch between send and received data;0xAD;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56ae;STRH_AddressMismatch;Address mismatch between send and received data;0xAE;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56af;STRH_LengthMismatch;Length field mismatch between send and received data;0xAF;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b0;STRH_FileNotExists;Specified file does not exist;0xB0;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b1;STRH_InvalidType;Download blob pixel command has invalid type field;0xB1;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b2;STRH_InvalidId;Received FPGA action command with invalid ID;0xB2;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b3;STRH_ReplyTooShort;Received reply is too short;0xB3;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b4;STRH_CrcFailure;Received reply with invalid CRC;0xB4;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b5;STRH_StrHelperExecuting;Star tracker handler currently executing a command and using the communication interface;0xB5;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;0xB6;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b7;STRH_StartrackerRunningFirmware;Star tracker is in firmware mode but must be in bootloader mode to execute this command;0xB7;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x56b8;STRH_StartrackerRunningBootloader;Star tracker is in bootloader mode but must be in firmware mode to execute this command;0xB8;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER -0x5fa0;STRHLP_SdNotMounted;SD card specified in path string not mounted;0xA0;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa1;STRHLP_FileNotExists;Specified file does not exist on filesystem;0xA1;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa2;STRHLP_PathNotExists;Specified path does not exist;0xA2;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa3;STRHLP_FileCreationFailed;Failed to create download image or read flash file;0xA3;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa4;STRHLP_RegionMismatch;Region in flash write/read reply does not match expected region;0xA4;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa5;STRHLP_AddressMismatch;Address in flash write/read reply does not match expected address;0xA5;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa6;STRHLP_LengthMismatch;Length in flash write/read reply does not match expected length;0xA6;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa7;STRHLP_StatusError;Status field in reply signals error;0xA7;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5fa8;STRHLP_InvalidTypeId;Reply has invalid type ID (should be of action reply type);0xA8;linux/devices/startracker/StrHelper.h;STR_HELPER -0x5ca0;IPCI_PapbBusy;;0xA0;linux/obc/PapbVcInterface.h;CCSDS_IP_CORE_BRIDGE -0x5da0;PTME_UnknownVcId;;0xA0;linux/obc/Ptme.h;PTME -0x64a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;0xA0;linux/obc/PtmeConfig.h;RATE_SETTER -0x64a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);0xA1;linux/obc/PtmeConfig.h;RATE_SETTER -0x64a2;RS_ClkInversionFailed;Failed to invert clock and thus change the time the data is updated with respect to the tx clock;0xA2;linux/obc/PtmeConfig.h;RATE_SETTER -0x64a3;RS_TxManipulatorConfigFailed;Failed to change configuration bit of tx clock manipulator;0xA3;linux/obc/PtmeConfig.h;RATE_SETTER -0x62a0;PDEC_AbandonedCltu;;0xA0;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a1;PDEC_FrameDirty;;0xA1;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a2;PDEC_FrameIllegalMultipleReasons;;0xA2;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a3;PDEC_AdDiscardedLockout;;0xA3;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a4;PDEC_AdDiscardedWait;;0xA4;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a5;PDEC_AdDiscardedNsVs;;0xA5;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62b0;PDEC_CommandNotImplemented;Received action message with unknown action id;0xB0;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a6;PDEC_NoReport;;0xA6;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a7;PDEC_ErrorVersionNumber;;0xA7;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a8;PDEC_IllegalCombination;;0xA8;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62a9;PDEC_InvalidScId;;0xA9;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62aa;PDEC_InvalidVcIdMsb;;0xAA;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62ab;PDEC_InvalidVcIdLsb;;0xAB;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62ac;PDEC_NsNotZero;;0xAC;linux/obc/PdecHandler.h;PDEC_HANDLER -0x62ae;PDEC_InvalidBcCc;;0xAE;linux/obc/PdecHandler.h;PDEC_HANDLER +0x7300; SDMA_OpOngoing;;0;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x7301; SDMA_AlreadyOn;;1;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x7302; SDMA_AlreadyMounted;;2;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x7303; SDMA_AlreadyOff;;3;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x730a; SDMA_StatusFileNexists;;10;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x730b; SDMA_StatusFileFormatInvalid;;11;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x730c; SDMA_MountError;;12;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x730d; SDMA_UnmountError;;13;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x730e; SDMA_SystemCallError;;14;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x730f; SDMA_PopenCallError;;15;bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x7400; SCBU_KeyNotFound;;0;bsp_q7s/memory/scratchApi.h;SCRATCH_BUFFER +0x68a0; FSHLP_SdNotMounted;SD card specified with path string not mounted;0xA0;bsp_q7s/memory/FilesystemHelper.h;FILE_SYSTEM_HELPER +0x68a1; FSHLP_FileNotExists;Specified file does not exist on filesystem;0xA1;bsp_q7s/memory/FilesystemHelper.h;FILE_SYSTEM_HELPER +0x6ba0; MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;0xA0;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba1; MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;0xA1;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba2; MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;0xA2;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba3; MPSOCRTVIF_InvalidApid;Received space packet with invalid APID from PLOC;0xA3;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba4; MPSOCRTVIF_InvalidLength;Received command with invalid length;0xA4;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba5; MPSOCRTVIF_FilenameTooLong;Filename of file in OBC filesystem is too long;0xA5;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba6; MPSOCRTVIF_MpsocHelperExecuting;MPSoC helper is currently executing a command;0xA6;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba7; MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);0xA7;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba8; MPSOCRTVIF_InvalidParameter;Command has invalid parameter;0xA8;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ba9; MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;0xA9;linux/devices/devicedefinitions/MPSoCReturnValuesIF.h;MPSOC_RETURN_VALUES_IF +0x6ca0; SPVRTVIF_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;0xA0;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca1; SPVRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;0xA1;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca2; SPVRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC supervisor;0xA2;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca3; SPVRTVIF_InvalidApid;Received space packet with invalid APID from PLOC supervisor;0xA3;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca4; SPVRTVIF_GetTimeFailure;Failed to read current system time;0xA4;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca5; SPVRTVIF_InvalidWatchdog;Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT;0xA5;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca6; SPVRTVIF_InvalidWatchdogTimeout;Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms.;0xA6;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca7; SPVRTVIF_InvalidLatchupId;Received latchup config command with invalid latchup ID;0xA7;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca8; SPVRTVIF_SweepPeriodTooSmall;Received set adc sweep period command with invalid sweep period. Must be larger than 21.;0xA8;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6ca9; SPVRTVIF_InvalidTestParam;Receive auto EM test command with invalid test param. Valid params are 1 and 2.;0xA9;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6caa; SPVRTVIF_MramPacketParsingFailure;Returned when scanning for MRAM dump packets failed.;0xAA;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cab; SPVRTVIF_InvalidMramAddresses;Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address);0xAB;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cac; SPVRTVIF_NoMramPacket;Expect reception of an MRAM dump packet but received space packet with other apid.;0xAC;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cad; SPVRTVIF_PathDoesNotExist;Path to PLOC directory on SD card does not exist;0xAD;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cae; SPVRTVIF_MramFileNotExists;MRAM dump file does not exists. The file should actually already have been created with the reception of the first dump packet.;0xAE;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6caf; SPVRTVIF_InvalidLength;Received action command has invalid length;0xAF;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cb0; SPVRTVIF_FilenameTooLong;Filename too long;0xB0;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cb1; SPVRTVIF_UpdateStatusReportInvalidLength;Received update status report with invalid packet length field;0xB1;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cb2; SPVRTVIF_UpdateCrcFailure;Update status report does not contain expected CRC. There might be a bit flip in the update memory region.;0xB2;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x6cb3; SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);0xB3;linux/devices/devicedefinitions/SupvReturnValuesIF.h;SUPV_RETURN_VALUES_IF +0x58e0; DWLPWRON_InvalidMode;Received command has invalid JESD mode (valid modes are 0 - 5);0xE0;linux/devices/devicedefinitions/PlocMPSoCDefinitions.h;DWLPWRON_CMD +0x58e1; DWLPWRON_InvalidLaneRate;Received command has invalid lane rate (valid lane rate are 0 - 9);0xE1;linux/devices/devicedefinitions/PlocMPSoCDefinitions.h;DWLPWRON_CMD +0x62a0; PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;0xA0;linux/devices/ploc/PlocMemoryDumper.h;PLOC_MEMORY_DUMPER +0x62a1; PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;0xA1;linux/devices/ploc/PlocMemoryDumper.h;PLOC_MEMORY_DUMPER +0x69a0; PLMPHLP_FileClosedAccidentally;File accidentally close;0xA0;linux/devices/ploc/PlocMPSoCHelper.h;PLOC_MPSOC_HELPER +0x5ba0; PLSPVhLP_FileClosedAccidentally;File accidentally close;0xA0;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER +0x5ba1; PLSPVhLP_ProcessTerminated;Process has been terminated by command;0xA1;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER +0x5ba2; PLSPVhLP_PathNotExists;Received command with invalid pathname;0xA2;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER +0x5ba3; PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;0xA3;linux/devices/ploc/PlocSupvHelper.h;PLOC_SUPV_HELPER +0x6601; JSONBASE_JsonFileNotExists;Specified json file does not exist;1;linux/devices/startracker/ArcsecJsonParamBase.h;ARCSEC_JSON_BASE +0x6602; JSONBASE_SetNotExists;Requested set does not exist in json file;2;linux/devices/startracker/ArcsecJsonParamBase.h;ARCSEC_JSON_BASE +0x6603; JSONBASE_ParamNotExists;Requested parameter does not exist in json file;3;linux/devices/startracker/ArcsecJsonParamBase.h;ARCSEC_JSON_BASE +0x57a0; STRH_TemperatureReqFailed;Status in temperature reply signals error;0xA0;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a1; STRH_PingFailed;Ping command failed;0xA1;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a2; STRH_VersionReqFailed;Status in version reply signals error;0xA2;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a3; STRH_InterfaceReqFailed;Status in interface reply signals error;0xA3;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a4; STRH_PowerReqFailed;Status in power reply signals error;0xA4;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a5; STRH_SetParamFailed;Status of reply to parameter set command signals error;0xA5;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a6; STRH_ActionFailed;Status of reply to action command signals error;0xA6;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a7; STRH_FilePathTooLong;Received invalid path string. Exceeds allowed length;0xA7;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a8; STRH_FilenameTooLong;Name of file received with command is too long;0xA8;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57a9; STRH_InvalidProgram;Received version reply with invalid program ID;0xA9;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57aa; STRH_ReplyError;Status field reply signals error;0xAA;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57ab; STRH_CommandTooShort;Received command which is too short (some data is missing for proper execution);0xAB;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57ac; STRH_InvalidLength;Received command with invalid length (too few or too many parameters);0xAC;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57ad; STRH_RegionMismatch;Region mismatch between send and received data;0xAD;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57ae; STRH_AddressMismatch;Address mismatch between send and received data;0xAE;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57af; STRH_LengthMismatch;Length field mismatch between send and received data;0xAF;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b0; STRH_FileNotExists;Specified file does not exist;0xB0;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b1; STRH_InvalidType;Download blob pixel command has invalid type field;0xB1;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b2; STRH_InvalidId;Received FPGA action command with invalid ID;0xB2;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b3; STRH_ReplyTooShort;Received reply is too short;0xB3;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b4; STRH_CrcFailure;Received reply with invalid CRC;0xB4;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b5; STRH_StrHelperExecuting;Star tracker handler currently executing a command and using the communication interface;0xB5;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b6; STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;0xB6;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b7; STRH_StartrackerRunningFirmware;Star tracker is in firmware mode but must be in bootloader mode to execute this command;0xB7;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x57b8; STRH_StartrackerRunningBootloader;Star tracker is in bootloader mode but must be in firmware mode to execute this command;0xB8;linux/devices/startracker/StarTrackerHandler.h;STR_HANDLER +0x60a0; STRHLP_SdNotMounted;SD card specified in path string not mounted;0xA0;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a1; STRHLP_FileNotExists;Specified file does not exist on filesystem;0xA1;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a2; STRHLP_PathNotExists;Specified path does not exist;0xA2;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a3; STRHLP_FileCreationFailed;Failed to create download image or read flash file;0xA3;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a4; STRHLP_RegionMismatch;Region in flash write/read reply does not match expected region;0xA4;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a5; STRHLP_AddressMismatch;Address in flash write/read reply does not match expected address;0xA5;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a6; STRHLP_LengthMismatch;Length in flash write/read reply does not match expected length;0xA6;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a7; STRHLP_StatusError;Status field in reply signals error;0xA7;linux/devices/startracker/StrHelper.h;STR_HELPER +0x60a8; STRHLP_InvalidTypeId;Reply has invalid type ID (should be of action reply type);0xA8;linux/devices/startracker/StrHelper.h;STR_HELPER +0x5da0; IPCI_PapbBusy;;0xA0;linux/obc/PapbVcInterface.h;CCSDS_IP_CORE_BRIDGE +0x5ea0; PTME_UnknownVcId;;0xA0;linux/obc/Ptme.h;PTME +0x65a0; RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;0xA0;linux/obc/PtmeConfig.h;RATE_SETTER +0x65a1; RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);0xA1;linux/obc/PtmeConfig.h;RATE_SETTER +0x65a2; RS_ClkInversionFailed;Failed to invert clock and thus change the time the data is updated with respect to the tx clock;0xA2;linux/obc/PtmeConfig.h;RATE_SETTER +0x65a3; RS_TxManipulatorConfigFailed;Failed to change configuration bit of tx clock manipulator;0xA3;linux/obc/PtmeConfig.h;RATE_SETTER +0x63a0; PDEC_AbandonedCltu;;0xA0;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a1; PDEC_FrameDirty;;0xA1;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a2; PDEC_FrameIllegalMultipleReasons;;0xA2;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a3; PDEC_AdDiscardedLockout;;0xA3;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a4; PDEC_AdDiscardedWait;;0xA4;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a5; PDEC_AdDiscardedNsVs;;0xA5;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63b0; PDEC_CommandNotImplemented;Received action message with unknown action id;0xB0;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a6; PDEC_NoReport;;0xA6;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a7; PDEC_ErrorVersionNumber;;0xA7;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a8; PDEC_IllegalCombination;;0xA8;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63a9; PDEC_InvalidScId;;0xA9;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63aa; PDEC_InvalidVcIdMsb;;0xAA;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63ab; PDEC_InvalidVcIdLsb;;0xAB;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63ac; PDEC_NsNotZero;;0xAC;linux/obc/PdecHandler.h;PDEC_HANDLER +0x63ae; PDEC_InvalidBcCc;;0xAE;linux/obc/PdecHandler.h;PDEC_HANDLER diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index cb3c2682..74b07b0b 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 204 translations. + * @brief Auto-generated event translation file. Contains 207 translations. * @details - * Generated on: 2022-05-13 18:40:51 + * Generated on: 2022-05-25 18:41:07 */ #include "translateEvents.h" @@ -82,6 +82,7 @@ const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; +const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TEST_STRING = "TEST"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; @@ -185,6 +186,8 @@ const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; const char *SUPV_UPDATE_FAILED_STRING = "SUPV_UPDATE_FAILED"; const char *SUPV_UPDATE_SUCCESSFUL_STRING = "SUPV_UPDATE_SUCCESSFUL"; +const char *SUPV_CONTINUE_UPDATE_FAILED_STRING = "SUPV_CONTINUE_UPDATE_FAILED"; +const char *SUPV_CONTINUE_UPDATE_SUCCESSFUL_STRING = "SUPV_CONTINUE_UPDATE_SUCCESSFUL"; const char *TERMINATED_UPDATE_PROCEDURE_STRING = "TERMINATED_UPDATE_PROCEDURE"; const char *SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL_STRING = "SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL"; const char *SUPV_EVENT_BUFFER_REQUEST_FAILED_STRING = "SUPV_EVENT_BUFFER_REQUEST_FAILED"; @@ -362,6 +365,8 @@ const char *translateEvents(Event event) { return CLOCK_SET_STRING; case (8901): return CLOCK_SET_FAILURE_STRING; + case (9100): + return TC_DELETION_FAILED_STRING; case (9700): return TEST_STRING; case (10600): @@ -569,36 +574,40 @@ const char *translateEvents(Event event) { case (13601): return SUPV_UPDATE_SUCCESSFUL_STRING; case (13602): - return TERMINATED_UPDATE_PROCEDURE_STRING; + return SUPV_CONTINUE_UPDATE_FAILED_STRING; case (13603): - return SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL_STRING; + return SUPV_CONTINUE_UPDATE_SUCCESSFUL_STRING; case (13604): - return SUPV_EVENT_BUFFER_REQUEST_FAILED_STRING; + return TERMINATED_UPDATE_PROCEDURE_STRING; case (13605): - return SUPV_EVENT_BUFFER_REQUEST_TERMINATED_STRING; + return SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL_STRING; case (13606): - return SUPV_SENDING_COMMAND_FAILED_STRING; + return SUPV_EVENT_BUFFER_REQUEST_FAILED_STRING; case (13607): - return SUPV_HELPER_REQUESTING_REPLY_FAILED_STRING; + return SUPV_EVENT_BUFFER_REQUEST_TERMINATED_STRING; case (13608): - return SUPV_HELPER_READING_REPLY_FAILED_STRING; + return SUPV_SENDING_COMMAND_FAILED_STRING; case (13609): - return SUPV_MISSING_ACK_STRING; + return SUPV_HELPER_REQUESTING_REPLY_FAILED_STRING; case (13610): - return SUPV_MISSING_EXE_STRING; + return SUPV_HELPER_READING_REPLY_FAILED_STRING; case (13611): - return SUPV_ACK_FAILURE_REPORT_STRING; + return SUPV_MISSING_ACK_STRING; case (13612): - return SUPV_EXE_FAILURE_REPORT_STRING; + return SUPV_MISSING_EXE_STRING; case (13613): - return SUPV_ACK_INVALID_APID_STRING; + return SUPV_ACK_FAILURE_REPORT_STRING; case (13614): - return SUPV_EXE_INVALID_APID_STRING; + return SUPV_EXE_FAILURE_REPORT_STRING; case (13615): - return ACK_RECEPTION_FAILURE_STRING; + return SUPV_ACK_INVALID_APID_STRING; case (13616): - return EXE_RECEPTION_FAILURE_STRING; + return SUPV_EXE_INVALID_APID_STRING; case (13617): + return ACK_RECEPTION_FAILURE_STRING; + case (13618): + return EXE_RECEPTION_FAILURE_STRING; + case (13619): return WRITE_MEMORY_FAILED_STRING; case (13700): return ALLOC_FAILURE_STRING; diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index fcc2c875..12ec5008 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 129 translations. - * Generated on: 2022-05-12 20:45:27 + * Contains 131 translations. + * Generated on: 2022-05-25 18:41:13 */ #include "translateObjects.h" @@ -79,6 +79,7 @@ const char *ARDUINO_COM_IF_STRING = "ARDUINO_COM_IF"; const char *GPIO_IF_STRING = "GPIO_IF"; const char *SPI_MAIN_COM_IF_STRING = "SPI_MAIN_COM_IF"; const char *SPI_RW_COM_IF_STRING = "SPI_RW_COM_IF"; +const char *SPI_RTD_COM_IF_STRING = "SPI_RTD_COM_IF"; const char *UART_COM_IF_STRING = "UART_COM_IF"; const char *I2C_COM_IF_STRING = "I2C_COM_IF"; const char *CSP_COM_IF_STRING = "CSP_COM_IF"; @@ -99,6 +100,7 @@ const char *PUS_SERVICE_3_HOUSEKEEPING_STRING = "PUS_SERVICE_3_HOUSEKEEPING"; const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTING"; const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT"; const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT"; +const char *PUS_SERVICE_11_TC_SCHEDULER_STRING = "PUS_SERVICE_11_TC_SCHEDULER"; const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST"; const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS"; const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT"; @@ -284,6 +286,8 @@ const char *translateObject(object_id_t object) { return SPI_MAIN_COM_IF_STRING; case 0x49020005: return SPI_RW_COM_IF_STRING; + case 0x49020006: + return SPI_RTD_COM_IF_STRING; case 0x49030003: return UART_COM_IF_STRING; case 0x49040002: @@ -324,6 +328,8 @@ const char *translateObject(object_id_t object) { return PUS_SERVICE_8_FUNCTION_MGMT_STRING; case 0x53000009: return PUS_SERVICE_9_TIME_MGMT_STRING; + case 0x53000011: + return PUS_SERVICE_11_TC_SCHEDULER_STRING; case 0x53000017: return PUS_SERVICE_17_TEST_STRING; case 0x53000020: diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index 269b0f79..f84cf52f 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -189,7 +191,7 @@ void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiCo } void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, - PowerSwitchIF* pwrSwitcher) { + PowerSwitchIF* pwrSwitcher, SpiComIF* comIF) { using namespace gpio; GpioCookie* rtdGpioCookie = new GpioCookie; @@ -245,8 +247,8 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, gpioChecker(gpioComIF->addGpios(rtdGpioCookie), "RTDs"); #if OBSW_ADD_RTD_DEVICES == 1 - static constexpr uint8_t NUMBER_RTDS = 16; - std::array, NUMBER_RTDS> cookieArgs = {{ + using namespace EiveMax31855; + std::array, NUM_RTDS> cookieArgs = {{ {addresses::RTD_IC_3, gpioIds::RTD_IC_3}, {addresses::RTD_IC_4, gpioIds::RTD_IC_4}, {addresses::RTD_IC_5, gpioIds::RTD_IC_5}, @@ -264,48 +266,52 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, {addresses::RTD_IC_17, gpioIds::RTD_IC_17}, {addresses::RTD_IC_18, gpioIds::RTD_IC_18}, }}; - std::array rtdIds = {objects::RTD_0_IC3_PLOC_HEATSPREADER, - objects::RTD_1_IC4_PLOC_MISSIONBOARD, - objects::RTD_2_IC5_4K_CAMERA, - objects::RTD_3_IC6_DAC_HEATSPREADER, - objects::RTD_4_IC7_STARTRACKER, - objects::RTD_5_IC8_RW1_MX_MY, - objects::RTD_6_IC9_DRO, - objects::RTD_7_IC10_SCEX, - objects::RTD_8_IC11_X8, - objects::RTD_9_IC12_HPA, - objects::RTD_10_IC13_PL_TX, - objects::RTD_11_IC14_MPA, - objects::RTD_12_IC15_ACU, - objects::RTD_13_IC16_PLPCDU_HEATSPREADER, - objects::RTD_14_IC17_TCS_BOARD, - objects::RTD_15_IC18_IMTQ}; - std::array rtdCookies = {}; - std::array rtds = {}; + // HSPD: Heatspreader + std::array, NUM_RTDS> rtdInfos = {{ + {objects::RTD_0_IC3_PLOC_HEATSPREADER, "RTD_0_PLOC_HSPD"}, + {objects::RTD_1_IC4_PLOC_MISSIONBOARD, "RTD_1_PLOC_MISSIONBRD"}, + {objects::RTD_2_IC5_4K_CAMERA, "RTD_2_4K_CAMERA"}, + {objects::RTD_3_IC6_DAC_HEATSPREADER, "RTD_3_DAC_HSPD"}, + {objects::RTD_4_IC7_STARTRACKER, "RTD_4_STARTRACKER"}, + {objects::RTD_5_IC8_RW1_MX_MY, "RTD_5_RW1_MX_MY"}, + {objects::RTD_6_IC9_DRO, "RTD_6_DRO"}, + {objects::RTD_7_IC10_SCEX, "RTD_7_SCEX"}, + {objects::RTD_8_IC11_X8, "RTD_8_X8"}, + {objects::RTD_9_IC12_HPA, "RTD_9_HPA"}, + {objects::RTD_10_IC13_PL_TX, "RTD_10_PL_TX,"}, + {objects::RTD_11_IC14_MPA, "RTD_11_MPA"}, + {objects::RTD_12_IC15_ACU, "RTD_12_ACU"}, + {objects::RTD_13_IC16_PLPCDU_HEATSPREADER, "RTD_13_PLPCDU_HSPD"}, + {objects::RTD_14_IC17_TCS_BOARD, "RTD_14_TCS_BOARD"}, + {objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"}, + }}; + std::array rtdCookies = {}; + std::array rtds = {}; RtdFdir* rtdFdir = nullptr; - for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - rtdCookies[idx] = - new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - rtds[idx] = new Max31865PT1000Handler(rtdIds[idx], objects::SPI_MAIN_COM_IF, rtdCookies[idx]); + // Create special low level reader communication interface + new Max31865RtdReader(objects::SPI_RTD_COM_IF, comIF, gpioComIF); + for (uint8_t idx = 0; idx < NUM_RTDS; idx++) { + rtdCookies[idx] = new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second, + MAX31865::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); + rtdCookies[idx]->setMutexParams(MutexIF::TimeoutType::WAITING, spi::RTD_CS_TIMEOUT); + Max31865ReaderCookie* rtdLowLevelCookie = + new Max31865ReaderCookie(rtdInfos[idx].first, idx, rtdInfos[idx].second, rtdCookies[idx]); + rtds[idx] = + new Max31865EiveHandler(rtdInfos[idx].first, objects::SPI_RTD_COM_IF, rtdLowLevelCookie); + rtds[idx]->setDeviceInfo(idx, rtdInfos[idx].second); rtds[idx]->setParent(objects::TCS_BOARD_ASS); - rtdFdir = new RtdFdir(rtdIds[idx]); + rtdFdir = new RtdFdir(rtdInfos[idx].first); rtds[idx]->setCustomFdir(rtdFdir); - rtds[idx]->setDeviceIdx(idx + 3); #if OBSW_DEBUG_RTD == 1 - rtds[idx]->setDebugMode(true); + rtds[idx]->setDebugMode(true, 5); +#endif +#if OBSW_TEST_RTD == 1 + rtds[idx]->setInstantNormal(true); + rtds[idx]->setStartUpImmediately(); #endif } -#if OBSW_TEST_RTD == 1 - for (auto& rtd : rtds) { - if (rtd != nullptr) { - rtd->setStartUpImmediately(); - rtd->setInstantNormal(true); - } - } -#endif // OBSW_TEST_RTD == 1 - TcsBoardHelper helper(rtdIds); + TcsBoardHelper helper(rtdInfos); TcsBoardAssembly* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); diff --git a/linux/ObjectFactory.h b/linux/ObjectFactory.h index 0ba78360..a5642729 100644 --- a/linux/ObjectFactory.h +++ b/linux/ObjectFactory.h @@ -12,7 +12,8 @@ namespace ObjectFactory { void createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitchIF* pwrSwitcher, std::string spiDev); -void createRtdComponents(std::string spiDev, GpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); +void createRtdComponents(std::string spiDev, GpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher, + SpiComIF* comIF); void gpioChecker(ReturnValue_t result, std::string output); diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index 45f44537..b68d1c4e 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -2,5 +2,7 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER) target_sources(${OBSW_NAME} PRIVATE GPSHyperionLinuxController.cpp) endif() +target_sources(${OBSW_NAME} PRIVATE Max31865RtdLowlevelHandler.cpp) + add_subdirectory(ploc) add_subdirectory(startracker) diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GPSHyperionLinuxController.cpp index dee3c9af..5d97554a 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GPSHyperionLinuxController.cpp @@ -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; diff --git a/linux/devices/GPSHyperionLinuxController.h b/linux/devices/GPSHyperionLinuxController.h index 94e82023..35ce0a63 100644 --- a/linux/devices/GPSHyperionLinuxController.h +++ b/linux/devices/GPSHyperionLinuxController.h @@ -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; diff --git a/linux/devices/Max31865RtdLowlevelHandler.cpp b/linux/devices/Max31865RtdLowlevelHandler.cpp new file mode 100644 index 00000000..ea038c8b --- /dev/null +++ b/linux/devices/Max31865RtdLowlevelHandler.cpp @@ -0,0 +1,465 @@ +#include "Max31865RtdLowlevelHandler.h" + +#include +#include +#include + +#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(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(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(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(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(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(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((val >> 8) & 0xff), static_cast(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((val >> 8) & 0xff), static_cast(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(); +} diff --git a/linux/devices/Max31865RtdLowlevelHandler.h b/linux/devices/Max31865RtdLowlevelHandler.h new file mode 100644 index 00000000..d3845bd5 --- /dev/null +++ b/linux/devices/Max31865RtdLowlevelHandler.h @@ -0,0 +1,87 @@ +#ifndef LINUX_DEVICES_MAX31865RTDREADER_H_ +#define LINUX_DEVICES_MAX31865RTDREADER_H_ + +#include +#include +#include +#include + +#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 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 rtds; + std::array 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_ */ diff --git a/linux/devices/devicedefinitions/PlocMPSoCDefinitions.h b/linux/devices/devicedefinitions/PlocMPSoCDefinitions.h index b2efb035..b8d76120 100644 --- a/linux/devices/devicedefinitions/PlocMPSoCDefinitions.h +++ b/linux/devices/devicedefinitions/PlocMPSoCDefinitions.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(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; } diff --git a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h index e0efda35..462ee632 100644 --- a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -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; @@ -319,6 +320,8 @@ 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 = 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), diff --git a/linux/devices/ploc/PlocMPSoCHandler.cpp b/linux/devices/ploc/PlocMPSoCHandler.cpp index f801014a..7905e82b 100644 --- a/linux/devices/ploc/PlocMPSoCHandler.cpp +++ b/linux/devices/ploc/PlocMPSoCHandler.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(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(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 ""; +} diff --git a/linux/devices/ploc/PlocMPSoCHandler.h b/linux/devices/ploc/PlocMPSoCHandler.h index e2950885..0d3445d1 100644 --- a/linux/devices/ploc/PlocMPSoCHandler.h +++ b/linux/devices/ploc/PlocMPSoCHandler.h @@ -263,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_ */ diff --git a/linux/devices/ploc/PlocSupervisorHandler.cpp b/linux/devices/ploc/PlocSupervisorHandler.cpp index 4a71fae1..f7a83528 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.cpp +++ b/linux/devices/ploc/PlocSupervisorHandler.cpp @@ -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; @@ -436,8 +441,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 +578,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 +820,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 +845,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 +965,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; diff --git a/linux/devices/ploc/PlocSupervisorHandler.h b/linux/devices/ploc/PlocSupervisorHandler.h index 3ef6a7ce..963591ab 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.h +++ b/linux/devices/ploc/PlocSupervisorHandler.h @@ -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 @@ -141,7 +143,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); diff --git a/linux/devices/ploc/PlocSupvHelper.cpp b/linux/devices/ploc/PlocSupvHelper.cpp index 167c7932..544a98eb 100644 --- a/linux/devices/ploc/PlocSupvHelper.cpp +++ b/linux/devices/ploc/PlocSupvHelper.cpp @@ -52,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) { @@ -110,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); @@ -141,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; @@ -149,66 +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; - uint32_t packetNum = 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(remainingSize); + dataLength = static_cast(update.remainingSize); } if (file.is_open()) { - file.seekg(bytesWritten, file.beg); + file.seekg(update.bytesWritten, file.beg); file.read(reinterpret_cast(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) { - triggerEvent(WRITE_MEMORY_FAILED, packetNum); + update.sequenceCount--; + triggerEvent(WRITE_MEMORY_FAILED, update.packetNum); return result; } - packetNum += 1; - 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; } @@ -235,6 +282,16 @@ 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); diff --git a/linux/devices/ploc/PlocSupvHelper.h b/linux/devices/ploc/PlocSupvHelper.h index e50693a8..69d26264 100644 --- a/linux/devices/ploc/PlocSupvHelper.h +++ b/linux/devices/ploc/PlocSupvHelper.h @@ -28,59 +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(17, severity::LOW); + static const Event WRITE_MEMORY_FAILED = MAKE_EVENT(19, severity::LOW); PlocSupvHelper(object_id_t objectId); virtual ~PlocSupvHelper(); @@ -102,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 */ @@ -141,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; @@ -154,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; @@ -179,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 = 2000); + uint32_t timeoutExecutionReport = 60000); ReturnValue_t sendCommand(SpacePacket& packet); /** * @brief Function which reads form the communication interface @@ -199,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 diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index cb3c2682..74b07b0b 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 204 translations. + * @brief Auto-generated event translation file. Contains 207 translations. * @details - * Generated on: 2022-05-13 18:40:51 + * Generated on: 2022-05-25 18:41:07 */ #include "translateEvents.h" @@ -82,6 +82,7 @@ const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; +const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TEST_STRING = "TEST"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; @@ -185,6 +186,8 @@ const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; const char *SUPV_UPDATE_FAILED_STRING = "SUPV_UPDATE_FAILED"; const char *SUPV_UPDATE_SUCCESSFUL_STRING = "SUPV_UPDATE_SUCCESSFUL"; +const char *SUPV_CONTINUE_UPDATE_FAILED_STRING = "SUPV_CONTINUE_UPDATE_FAILED"; +const char *SUPV_CONTINUE_UPDATE_SUCCESSFUL_STRING = "SUPV_CONTINUE_UPDATE_SUCCESSFUL"; const char *TERMINATED_UPDATE_PROCEDURE_STRING = "TERMINATED_UPDATE_PROCEDURE"; const char *SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL_STRING = "SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL"; const char *SUPV_EVENT_BUFFER_REQUEST_FAILED_STRING = "SUPV_EVENT_BUFFER_REQUEST_FAILED"; @@ -362,6 +365,8 @@ const char *translateEvents(Event event) { return CLOCK_SET_STRING; case (8901): return CLOCK_SET_FAILURE_STRING; + case (9100): + return TC_DELETION_FAILED_STRING; case (9700): return TEST_STRING; case (10600): @@ -569,36 +574,40 @@ const char *translateEvents(Event event) { case (13601): return SUPV_UPDATE_SUCCESSFUL_STRING; case (13602): - return TERMINATED_UPDATE_PROCEDURE_STRING; + return SUPV_CONTINUE_UPDATE_FAILED_STRING; case (13603): - return SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL_STRING; + return SUPV_CONTINUE_UPDATE_SUCCESSFUL_STRING; case (13604): - return SUPV_EVENT_BUFFER_REQUEST_FAILED_STRING; + return TERMINATED_UPDATE_PROCEDURE_STRING; case (13605): - return SUPV_EVENT_BUFFER_REQUEST_TERMINATED_STRING; + return SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL_STRING; case (13606): - return SUPV_SENDING_COMMAND_FAILED_STRING; + return SUPV_EVENT_BUFFER_REQUEST_FAILED_STRING; case (13607): - return SUPV_HELPER_REQUESTING_REPLY_FAILED_STRING; + return SUPV_EVENT_BUFFER_REQUEST_TERMINATED_STRING; case (13608): - return SUPV_HELPER_READING_REPLY_FAILED_STRING; + return SUPV_SENDING_COMMAND_FAILED_STRING; case (13609): - return SUPV_MISSING_ACK_STRING; + return SUPV_HELPER_REQUESTING_REPLY_FAILED_STRING; case (13610): - return SUPV_MISSING_EXE_STRING; + return SUPV_HELPER_READING_REPLY_FAILED_STRING; case (13611): - return SUPV_ACK_FAILURE_REPORT_STRING; + return SUPV_MISSING_ACK_STRING; case (13612): - return SUPV_EXE_FAILURE_REPORT_STRING; + return SUPV_MISSING_EXE_STRING; case (13613): - return SUPV_ACK_INVALID_APID_STRING; + return SUPV_ACK_FAILURE_REPORT_STRING; case (13614): - return SUPV_EXE_INVALID_APID_STRING; + return SUPV_EXE_FAILURE_REPORT_STRING; case (13615): - return ACK_RECEPTION_FAILURE_STRING; + return SUPV_ACK_INVALID_APID_STRING; case (13616): - return EXE_RECEPTION_FAILURE_STRING; + return SUPV_EXE_INVALID_APID_STRING; case (13617): + return ACK_RECEPTION_FAILURE_STRING; + case (13618): + return EXE_RECEPTION_FAILURE_STRING; + case (13619): return WRITE_MEMORY_FAILED_STRING; case (13700): return ALLOC_FAILURE_STRING; diff --git a/linux/fsfwconfig/objects/systemObjectList.h b/linux/fsfwconfig/objects/systemObjectList.h index 57c63863..28c87d3c 100644 --- a/linux/fsfwconfig/objects/systemObjectList.h +++ b/linux/fsfwconfig/objects/systemObjectList.h @@ -50,6 +50,7 @@ enum sourceObjects : uint32_t { SPI_MAIN_COM_IF = 0x49020004, GPIO_IF = 0x49010005, SPI_RW_COM_IF = 0x49020005, + SPI_RTD_COM_IF = 0x49020006, /* 0x54 ('T') for test handlers */ TEST_TASK = 0x54694269, diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index fcc2c875..12ec5008 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 129 translations. - * Generated on: 2022-05-12 20:45:27 + * Contains 131 translations. + * Generated on: 2022-05-25 18:41:13 */ #include "translateObjects.h" @@ -79,6 +79,7 @@ const char *ARDUINO_COM_IF_STRING = "ARDUINO_COM_IF"; const char *GPIO_IF_STRING = "GPIO_IF"; const char *SPI_MAIN_COM_IF_STRING = "SPI_MAIN_COM_IF"; const char *SPI_RW_COM_IF_STRING = "SPI_RW_COM_IF"; +const char *SPI_RTD_COM_IF_STRING = "SPI_RTD_COM_IF"; const char *UART_COM_IF_STRING = "UART_COM_IF"; const char *I2C_COM_IF_STRING = "I2C_COM_IF"; const char *CSP_COM_IF_STRING = "CSP_COM_IF"; @@ -99,6 +100,7 @@ const char *PUS_SERVICE_3_HOUSEKEEPING_STRING = "PUS_SERVICE_3_HOUSEKEEPING"; const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTING"; const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT"; const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT"; +const char *PUS_SERVICE_11_TC_SCHEDULER_STRING = "PUS_SERVICE_11_TC_SCHEDULER"; const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST"; const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS"; const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT"; @@ -284,6 +286,8 @@ const char *translateObject(object_id_t object) { return SPI_MAIN_COM_IF_STRING; case 0x49020005: return SPI_RW_COM_IF_STRING; + case 0x49020006: + return SPI_RTD_COM_IF_STRING; case 0x49030003: return UART_COM_IF_STRING; case 0x49040002: @@ -324,6 +328,8 @@ const char *translateObject(object_id_t object) { return PUS_SERVICE_8_FUNCTION_MGMT_STRING; case 0x53000009: return PUS_SERVICE_9_TIME_MGMT_STRING; + case 0x53000011: + return PUS_SERVICE_11_TC_SCHEDULER_STRING; case 0x53000017: return PUS_SERVICE_17_TEST_STRING; case 0x53000020: diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 05de8cf3..87bd9c51 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -5,6 +5,8 @@ #include #include +#include "mission/devices/devicedefinitions/Max31865Definitions.h" + #ifndef RPI_TEST_ADIS16507 #define RPI_TEST_ADIS16507 0 #endif @@ -64,157 +66,34 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { static_cast(length); #if OBSW_ADD_PL_PCDU == 1 thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::GET_READ); #endif #if OBSW_ADD_TMP_DEVICES == 1 thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, DeviceHandlerIF::PERFORM_OPERATION); #endif -#if OBSW_ADD_RTD_DEVICES == 1 - thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0, DeviceHandlerIF::PERFORM_OPERATION); -#endif /* OBSW_ADD_RTD_DEVICES */ #if OBSW_ADD_TMP_DEVICES == 1 thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE); #endif -#if OBSW_ADD_RTD_DEVICES == 1 - thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.2, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.2, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.2, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.2, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.2, DeviceHandlerIF::SEND_WRITE); -#endif /* OBSW_ADD_RTD_DEVICES */ #if OBSW_ADD_TMP_DEVICES == 1 - thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::GET_WRITE); #endif -#if OBSW_ADD_RTD_DEVICES == 1 - thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.4, DeviceHandlerIF::GET_WRITE); -#endif /* OBSW_ADD_RTD_DEVICES */ #if OBSW_ADD_TMP_DEVICES == 1 - thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_READ); #endif -#if OBSW_ADD_RTD_DEVICES == 1 - thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.6, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.6, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.6, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.6, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.6, DeviceHandlerIF::SEND_READ); -#endif /* OBSW_ADD_RTD_DEVICES */ #if OBSW_ADD_TMP_DEVICES == 1 - thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.8, DeviceHandlerIF::GET_READ); -#endif -#if OBSW_ADD_RTD_DEVICES == 1 - thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.8, - DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.8, - DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.8, - DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.8, - DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.8, DeviceHandlerIF::GET_READ); -#endif /* OBSW_ADD_RTD_DEVICES */ - -#if OBSW_ADD_RAD_SENSORS == 1 - /* Radiation sensor */ - thisSequence->addSlot(objects::RAD_SENSOR, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RAD_SENSOR, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RAD_SENSOR, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RAD_SENSOR, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RAD_SENSOR, length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::GET_READ); #endif #if OBSW_ADD_SUN_SENSORS == 1 @@ -482,6 +361,15 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { } #endif /* OBSW_ADD_SUN_SENSORS == 1 */ +#if OBSW_ADD_RAD_SENSORS == 1 + /* Radiation sensor */ + thisSequence->addSlot(objects::RAD_SENSOR, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::RAD_SENSOR, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::RAD_SENSOR, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RAD_SENSOR, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RAD_SENSOR, length * 0.8, DeviceHandlerIF::GET_READ); +#endif + #if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 bool enableAside = true; bool enableBside = true; diff --git a/linux/fsfwconfig/tmtc/pusIds.h b/linux/fsfwconfig/tmtc/pusIds.h deleted file mode 100644 index 37503786..00000000 --- a/linux/fsfwconfig/tmtc/pusIds.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CONFIG_TMTC_PUSIDS_HPP_ -#define CONFIG_TMTC_PUSIDS_HPP_ - -namespace pus { -enum Ids { - PUS_SERVICE_1 = 1, - PUS_SERVICE_2 = 2, - PUS_SERVICE_3 = 3, - PUS_SERVICE_3_PSB = 3, - PUS_SERVICE_5 = 5, - PUS_SERVICE_6 = 6, - PUS_SERVICE_8 = 8, - PUS_SERVICE_9 = 9, - PUS_SERVICE_17 = 17, - PUS_SERVICE_19 = 19, - PUS_SERVICE_20 = 20, - PUS_SERVICE_23 = 23, - PUS_SERVICE_200 = 200, - PUS_SERVICE_201 = 201, -}; -}; - -#endif /* CONFIG_TMTC_PUSIDS_HPP_ */ diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 3ab598f3..b602703f 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -21,6 +21,7 @@ #include "OBSWConfig.h" #include "eive/definitions.h" +#include "fsfw/pus/Service11TelecommandScheduling.h" #include "objects/systemObjectList.h" #include "tmtc/apid.h" #include "tmtc/pusIds.h" @@ -73,7 +74,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { new PoolManager(objects::IPC_STORE, poolCfg); } - new CCSDSDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR); + auto* ccsdsDistrib = new CCSDSDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR); new PUSDistributor(apid::EIVE_OBSW, objects::PUS_PACKET_DISTRIBUTOR, objects::CCSDS_PACKET_DISTRIBUTOR); @@ -96,6 +97,9 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_8, 3, 60); new Service9TimeManagement(objects::PUS_SERVICE_9_TIME_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_9); + + new Service11TelecommandScheduling( + objects::PUS_SERVICE_11_TC_SCHEDULER, apid::EIVE_OBSW, pus::PUS_SERVICE_11, ccsdsDistrib); new Service17Test(objects::PUS_SERVICE_17_TEST, apid::EIVE_OBSW, pus::PUS_SERVICE_17); new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, apid::EIVE_OBSW, pus::PUS_SERVICE_20); @@ -120,6 +124,6 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { tcpServer->enableWiretapping(true); #endif /* OBSW_TCP_SERVER_WIRETAPPING == 1 */ #endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */ - tmtcBridge->setMaxNumberOfPacketsStored(70); + tmtcBridge->setMaxNumberOfPacketsStored(300); #endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */ } diff --git a/mission/devices/ACUHandler.cpp b/mission/devices/ACUHandler.cpp index f881479d..a3b5eeee 100644 --- a/mission/devices/ACUHandler.cpp +++ b/mission/devices/ACUHandler.cpp @@ -6,7 +6,8 @@ ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCoo FailureIsolationBase *customFdir) : GomspaceDeviceHandler(objectId, comIF, comCookie, customFdir, ACU::MAX_CONFIGTABLE_ADDRESS, ACU::MAX_HKTABLE_ADDRESS, ACU::HK_TABLE_REPLY_SIZE), - acuHkTableDataset(this) {} + coreHk(this), + auxHk(this) {} ACUHandler::~ACUHandler() {} @@ -15,243 +16,145 @@ ReturnValue_t ACUHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { return buildCommandFromCommand(*id, NULL, 0); } -void ACUHandler::fillCommandAndReplyMap() { - GomspaceDeviceHandler::fillCommandAndReplyMap(); - this->insertInCommandMap(PRINT_CHANNEL_STATS); -} +void ACUHandler::fillCommandAndReplyMap() { GomspaceDeviceHandler::fillCommandAndReplyMap(); } void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { parseHkTableReply(packet); - handleDeviceTM(&acuHkTableDataset, id, true); - if (debugMode) { #if OBSW_VERBOSE_LEVEL >= 1 - acuHkTableDataset.read(); - float temperatureC_1 = acuHkTableDataset.temperature1.value * 0.1; - float temperatureC_2 = acuHkTableDataset.temperature2.value * 0.1; - float temperatureC_3 = acuHkTableDataset.temperature3.value * 0.1; - sif::info << "ACU: Temperature 1: " << temperatureC_1 << " °C" << std::endl; - sif::info << "ACU: Temperature 2: " << temperatureC_2 << " °C" << std::endl; - sif::info << "ACU: Temperature 3: " << temperatureC_3 << " °C" << std::endl; - sif::info << "ACU: Ground Watchdog Timer Count: " << acuHkTableDataset.wdtCntGnd.value - << std::endl; + PoolReadGuard pg0(&auxHk); + PoolReadGuard pg1(&coreHk); + if (pg0.getReadResult() != RETURN_OK or pg1.getReadResult() != RETURN_OK) { + return; + } + for (size_t idx = 0; idx < 3; idx++) { + float tempC = coreHk.temperatures[idx] * 0.1; + sif::info << "ACU: Temperature " << idx << ": " << tempC << " °C" << std::endl; + } + sif::info << "ACU: Ground Watchdog Timer Count: " << auxHk.wdtCntGnd.value << std::endl; sif::info << "ACU: Ground watchdog timer, seconds left before reboot: " - << acuHkTableDataset.wdtGndLeft.value << std::endl; - acuHkTableDataset.commit(); + << auxHk.wdtGndLeft.value << std::endl; #endif } } LocalPoolDataSetBase *ACUHandler::getDataSetHandle(sid_t sid) { - if (sid == acuHkTableDataset.getSid()) { - return &acuHkTableDataset; + if (sid == coreHk.getSid()) { + return &coreHk; + } else if (sid == auxHk.getSid()) { + return &auxHk; } return nullptr; } -void ACUHandler::parseHkTableReply(const uint8_t *packet) { +ReturnValue_t ACUHandler::parseHkTableReply(const uint8_t *packet) { uint16_t dataOffset = 0; - acuHkTableDataset.read(); + PoolReadGuard pg0(&coreHk); + PoolReadGuard pg1(&auxHk); + auto res0 = pg0.getReadResult(); + auto res1 = pg1.getReadResult(); + if (res0 != RETURN_OK) { + return res0; + } + if (res1 != RETURN_OK) { + return res1; + } dataOffset += 12; - acuHkTableDataset.currentInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + for (size_t idx = 0; idx < 6; idx++) { + coreHk.currentInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1]; + dataOffset += 4; + } + for (size_t idx = 0; idx < 6; idx++) { + coreHk.voltageInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1]; + dataOffset += 4; + } + + coreHk.vcc = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; - acuHkTableDataset.currentInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.currentInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.currentInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.currentInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.currentInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + coreHk.vbat = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; - acuHkTableDataset.voltageInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.voltageInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.voltageInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.voltageInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.voltageInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.voltageInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; + for (size_t idx = 0; idx < 3; idx++) { + coreHk.temperatures[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1]; + dataOffset += 4; + } - acuHkTableDataset.vcc = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.vbat = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - - acuHkTableDataset.temperature1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.temperature2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.temperature3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - - acuHkTableDataset.mpptMode = *(packet + dataOffset); + coreHk.mpptMode = packet[dataOffset]; dataOffset += 3; - acuHkTableDataset.vboostInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.vboostInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.vboostInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.vboostInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.vboostInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.vboostInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; + for (size_t idx = 0; idx < 6; idx++) { + coreHk.vboostInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1]; + dataOffset += 4; + } + for (size_t idx = 0; idx < 6; idx++) { + coreHk.powerInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1]; + dataOffset += 4; + } + for (size_t idx = 0; idx < 3; idx++) { + auxHk.dacEnables[idx] = packet[dataOffset]; + dataOffset += 3; + } + for (size_t idx = 0; idx < 6; idx++) { + auxHk.dacRawChannelVals[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1]; + dataOffset += 4; + } - acuHkTableDataset.powerInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.powerInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.powerInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.powerInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.powerInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.powerInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - - acuHkTableDataset.dac0Enable = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.dac1Enable = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.dac2Enable = *(packet + dataOffset); - dataOffset += 3; - - acuHkTableDataset.dacRawChannelVal0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.dacRawChannelVal1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.dacRawChannelVal2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.dacRawChannelVal3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.dacRawChannelVal4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - acuHkTableDataset.dacRawChannelVal5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); - dataOffset += 4; - - acuHkTableDataset.bootCause = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | - *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + auxHk.bootCause = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | + *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); dataOffset += 6; - acuHkTableDataset.bootcnt = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | - *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + coreHk.bootcnt = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | + *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); dataOffset += 6; - acuHkTableDataset.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | - *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + coreHk.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | + *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); dataOffset += 6; - acuHkTableDataset.resetCause = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + auxHk.resetCause = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; - acuHkTableDataset.mpptTime = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + coreHk.mpptTime = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); /* +12 because here starts the second csp packet */ dataOffset += 2 + 12; - acuHkTableDataset.mpptPeriod = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + coreHk.mpptPeriod = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; - acuHkTableDataset.device0 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device1 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device2 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device3 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device4 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device5 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device6 = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device7 = *(packet + dataOffset); - dataOffset += 3; + for (size_t idx = 0; idx < 8; idx++) { + auxHk.deviceTypes[idx] = packet[dataOffset]; + dataOffset += 3; + } + for (size_t idx = 0; idx < 8; idx++) { + auxHk.devicesStatus[idx] = packet[dataOffset]; + dataOffset += 3; + } - acuHkTableDataset.device0Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device1Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device2Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device3Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device4Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device5Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device6Status = *(packet + dataOffset); - dataOffset += 3; - acuHkTableDataset.device7Status = *(packet + dataOffset); - dataOffset += 3; - - acuHkTableDataset.wdtCntGnd = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | - *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + auxHk.wdtCntGnd = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | + *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); dataOffset += 6; - acuHkTableDataset.wdtGndLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | - *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + auxHk.wdtGndLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | + *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); dataOffset += 6; - - acuHkTableDataset.commit(); + coreHk.setValidity(true, true); + auxHk.setValidity(true, true); + return RETURN_OK; } ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { using namespace P60System; - localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNEL0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNEL1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNEL2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNEL3, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNEL4, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNEL5, new PoolEntry({0})); - - localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNEL0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNEL1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNEL2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNEL3, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNEL4, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNEL5, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNELS, new PoolEntry(6)); + localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNELS, new PoolEntry(6)); localDataPoolMap.emplace(pool::ACU_VCC, new PoolEntry({0})); localDataPoolMap.emplace(pool::ACU_VBAT, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_TEMPERATURE_1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_TEMPERATURE_2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_TEMPERATURE_3, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_TEMPERATURES, new PoolEntry(3)); localDataPoolMap.emplace(pool::ACU_MPPT_MODE, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VBOOST_CHANNEL0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VBOOST_CHANNEL1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VBOOST_CHANNEL2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VBOOST_CHANNEL3, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VBOOST_CHANNEL4, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_VBOOST_CHANNEL5, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_VBOOST_IN_CHANNELS, new PoolEntry(6)); + localDataPoolMap.emplace(pool::ACU_POWER_IN_CHANNELS, new PoolEntry(6)); - localDataPoolMap.emplace(pool::ACU_POWER_CHANNEL0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_POWER_CHANNEL1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_POWER_CHANNEL2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_POWER_CHANNEL3, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_POWER_CHANNEL4, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_POWER_CHANNEL5, new PoolEntry({0})); - - localDataPoolMap.emplace(pool::ACU_DAC_EN_0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_EN_1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_EN_2, new PoolEntry({0})); - - localDataPoolMap.emplace(pool::ACU_DAC_RAW_0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_RAW_1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_RAW_2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_RAW_3, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_RAW_4, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DAC_RAW_5, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_DAC_ENABLES, new PoolEntry(3)); + localDataPoolMap.emplace(pool::ACU_DAC_RAW_CHANNELS, new PoolEntry(6)); localDataPoolMap.emplace(pool::ACU_BOOTCAUSE, new PoolEntry({0})); localDataPoolMap.emplace(pool::ACU_BOOTCNT, new PoolEntry({0})); @@ -260,65 +163,47 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData localDataPoolMap.emplace(pool::ACU_MPPT_TIME, new PoolEntry({0})); localDataPoolMap.emplace(pool::ACU_MPPT_PERIOD, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_0, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_1, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_2, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_3, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_4, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_5, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_6, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_7, new PoolEntry({0})); - - localDataPoolMap.emplace(pool::ACU_DEVICE_0_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_1_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_2_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_3_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_4_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_5_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_6_STATUS, new PoolEntry({0})); - localDataPoolMap.emplace(pool::ACU_DEVICE_7_STATUS, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_DEVICES, new PoolEntry(8)); + localDataPoolMap.emplace(pool::ACU_DEVICES_STATUS, new PoolEntry(8)); localDataPoolMap.emplace(pool::ACU_WDT_CNT_GND, new PoolEntry({0})); localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry({0})); - poolManager.subscribeForPeriodicPacket(acuHkTableDataset.getSid(), false, 30.0, false); + poolManager.subscribeForPeriodicPacket(coreHk.getSid(), false, 10.0, true); + poolManager.subscribeForPeriodicPacket(auxHk.getSid(), false, 30.0, false); return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ACUHandler::childCommandHook(DeviceCommandId_t cmd, const uint8_t *commandData, - size_t commandDataLen) { - switch (cmd) { - case PRINT_CHANNEL_STATS: { - printChannelStats(); - return RETURN_OK; - } - default: { - return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; - } +void ACUHandler::printChannelStats() { + PoolReadGuard pg(&coreHk); + sif::info << "ACU Info: Current [mA], Voltage [mV]" << std::endl; + for (size_t idx = 0; idx < 6; idx++) { + sif::info << std::setw(8) << std::left << "Channel " << idx << std::dec << "| " + << static_cast(coreHk.currentInChannels[idx]) << std::setw(15) + << std::right << coreHk.voltageInChannels[idx] << std::endl; } } -void ACUHandler::printChannelStats() { - PoolReadGuard pg(&acuHkTableDataset); - sif::info << "ACU Info: Current [mA], Voltage [mV]" << std::endl; - sif::info << std::setw(8) << std::left << "Ch0" << std::dec << "| " - << static_cast(acuHkTableDataset.currentInChannel0.value) << std::setw(15) - << std::right << acuHkTableDataset.voltageInChannel0.value << std::endl; - sif::info << std::setw(8) << std::left << "Ch1" << std::dec << "| " - << static_cast(acuHkTableDataset.currentInChannel1.value) << std::setw(15) - << std::right << acuHkTableDataset.voltageInChannel1.value << std::endl; - sif::info << std::setw(8) << std::left << "Ch2" << std::dec << "| " - << static_cast(acuHkTableDataset.currentInChannel2.value) << std::setw(15) - << std::right << acuHkTableDataset.voltageInChannel2.value << std::endl; - sif::info << std::setw(8) << std::left << "Ch3" << std::dec << "| " - << static_cast(acuHkTableDataset.currentInChannel3.value) << std::setw(15) - << std::right << acuHkTableDataset.voltageInChannel3.value << std::endl; - sif::info << std::setw(8) << std::left << "Ch4" << std::dec << "| " - << static_cast(acuHkTableDataset.currentInChannel4.value) << std::setw(15) - << std::right << acuHkTableDataset.voltageInChannel4.value << std::endl; - sif::info << std::setw(8) << std::left << "Ch5" << std::dec << "| " - << static_cast(acuHkTableDataset.currentInChannel5.value) << std::setw(15) - << std::right << acuHkTableDataset.voltageInChannel5.value << std::endl; -} - void ACUHandler::setDebugMode(bool enable) { this->debugMode = enable; } + +ReturnValue_t ACUHandler::printStatus(DeviceCommandId_t cmd) { + ReturnValue_t result = RETURN_OK; + switch (cmd) { + case (GOMSPACE::PRINT_SWITCH_V_I): { + PoolReadGuard pg(&coreHk); + result = pg.getReadResult(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + printChannelStats(); + break; + } + default: { + return DeviceHandlerIF::COMMAND_NOT_SUPPORTED; + } + } + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Reading PDU1 HK table failed!" << std::endl; + } + return result; +} diff --git a/mission/devices/ACUHandler.h b/mission/devices/ACUHandler.h index 16a7c6db..3154e547 100644 --- a/mission/devices/ACUHandler.h +++ b/mission/devices/ACUHandler.h @@ -29,24 +29,22 @@ class ACUHandler : public GomspaceDeviceHandler { */ virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; - virtual void fillCommandAndReplyMap() override; + ReturnValue_t printStatus(DeviceCommandId_t cmd) override; - virtual ReturnValue_t childCommandHook(DeviceCommandId_t cmd, const uint8_t* commandData, - size_t commandDataLen) override; + virtual void fillCommandAndReplyMap() override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; private: - static const DeviceCommandId_t PRINT_CHANNEL_STATS = 51; - - ACU::HkTableDataset acuHkTableDataset; + ACU::CoreHk coreHk; + ACU::AuxHk auxHk; bool debugMode = false; /** * @brief Function extracts the hk table information from the received csp packet and stores * the values in the acuHkTableDataset. */ - void parseHkTableReply(const uint8_t* packet); + ReturnValue_t parseHkTableReply(const uint8_t* packet); /** * @brief Prints channel statistics (current and voltage) to console diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index b19efbc6..1a9b2efd 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -10,6 +10,7 @@ target_sources( ACUHandler.cpp SyrlinksHkHandler.cpp Max31865PT1000Handler.cpp + Max31865EiveHandler.cpp IMTQHandler.cpp HeaterHandler.cpp RadiationSensorHandler.cpp diff --git a/mission/devices/GyroADIS1650XHandler.cpp b/mission/devices/GyroADIS1650XHandler.cpp index b94c96bf..77862bfb 100644 --- a/mission/devices/GyroADIS1650XHandler.cpp +++ b/mission/devices/GyroADIS1650XHandler.cpp @@ -424,8 +424,8 @@ ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie * GpioIF *gpioIF = comIf->getGpioInterface(); MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; uint32_t timeoutMs = 0; - cookie->getMutexParams(timeoutType, timeoutMs); MutexIF *mutex = comIf->getCsMutex(); + cookie->getMutexParams(timeoutType, timeoutMs); if (mutex == nullptr or gpioIF == nullptr) { #if OBSW_VERBOSE_LEVEL >= 1 sif::warning << "GyroADIS16507Handler::spiSendCallback: " diff --git a/mission/devices/IMTQHandler.cpp b/mission/devices/IMTQHandler.cpp index 403adece..049d5b15 100644 --- a/mission/devices/IMTQHandler.cpp +++ b/mission/devices/IMTQHandler.cpp @@ -63,7 +63,9 @@ ReturnValue_t IMTQHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { return buildCommandFromCommand(*id, NULL, 0); } -ReturnValue_t IMTQHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { return RETURN_OK; } +ReturnValue_t IMTQHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + return NOTHING_TO_SEND; +} ReturnValue_t IMTQHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, @@ -606,6 +608,7 @@ ReturnValue_t IMTQHandler::initializeLocalDataPool(localpool::DataPool& localDat poolManager.subscribeForPeriodicPacket(engHkDataset.getSid(), false, 10.0, true); poolManager.subscribeForPeriodicPacket(calMtmMeasurementSet.getSid(), false, 10.0, true); + poolManager.subscribeForPeriodicPacket(rawMtmMeasurementSet.getSid(), false, 10.0, true); return HasReturnvaluesIF::RETURN_OK; } diff --git a/mission/devices/Max31865EiveHandler.cpp b/mission/devices/Max31865EiveHandler.cpp new file mode 100644 index 00000000..a77bbd51 --- /dev/null +++ b/mission/devices/Max31865EiveHandler.cpp @@ -0,0 +1,183 @@ +#include "Max31865EiveHandler.h" + +Max31865EiveHandler::Max31865EiveHandler(object_id_t objectId, object_id_t comIF, + CookieIF* comCookie) + : DeviceHandlerBase(objectId, comIF, comCookie, nullptr), + sensorDataset(this, EiveMax31855::RtdCommands::EXCHANGE_SET_ID), + debugDivider(5) { + structLen = exchangeStruct.getSerializedSize(); +} + +void Max31865EiveHandler::doStartUp() { + updatePeriodicReply(true, EiveMax31855::RtdCommands::EXCHANGE_SET_ID); + if (state == InternalState::NONE or state == InternalState::INACTIVE) { + if (instantNormal) { + state = InternalState::ACTIVE; + } else { + state = InternalState::ON; + } + transitionOk = false; + } + if ((state == InternalState::ON or state == InternalState::ACTIVE) and transitionOk) { + if (instantNormal) { + setMode(MODE_NORMAL); + } else { + setMode(MODE_ON); + } + } +} + +void Max31865EiveHandler::doShutDown() { + updatePeriodicReply(false, EiveMax31855::RtdCommands::EXCHANGE_SET_ID); + if (state == InternalState::NONE or state == InternalState::ACTIVE or + state == InternalState::ON) { + state = InternalState::INACTIVE; + transitionOk = false; + } else { + transitionOk = true; + } + if (state == InternalState::INACTIVE and transitionOk) { + setMode(_MODE_POWER_DOWN); + } +} + +ReturnValue_t Max31865EiveHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { + //*id = EiveMax31855::RtdCommands::EXCHANGE_SET_ID; + return NOTHING_TO_SEND; +} + +ReturnValue_t Max31865EiveHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + ReturnValue_t result = NOTHING_TO_SEND; + if (state == InternalState::ON) { + *id = EiveMax31855::RtdCommands::ON; + result = buildCommandFromCommand(*id, nullptr, 0); + } + if (state == InternalState::ACTIVE) { + *id = EiveMax31855::RtdCommands::ACTIVE; + result = buildCommandFromCommand(*id, nullptr, 0); + } + if (state == InternalState::INACTIVE) { + *id = EiveMax31855::RtdCommands::OFF; + result = buildCommandFromCommand(*id, nullptr, 0); + } + return result; +} + +ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t* commandData, + size_t commandDataLen) { + auto cmdTyped = static_cast(deviceCommand); + switch (cmdTyped) { + case (EiveMax31855::RtdCommands::ON): + case (EiveMax31855::RtdCommands::ACTIVE): + case (EiveMax31855::RtdCommands::OFF): { + simpleCommand(cmdTyped); + break; + } + case (EiveMax31855::RtdCommands::LOW_THRESHOLD): + case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): { + break; + } + case (EiveMax31855::RtdCommands::CFG): { + break; + } + default: + return NOTHING_TO_SEND; + } + return RETURN_OK; +} + +void Max31865EiveHandler::setInstantNormal(bool instantNormal) { + this->instantNormal = instantNormal; +} + +void Max31865EiveHandler::setDebugMode(bool enable, uint32_t divider) { + this->debugMode = enable; + debugDivider.setDivider(divider); +} + +void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) { + cmdBuf[0] = static_cast(cmd); + rawPacket = cmdBuf.data(); + rawPacketLen = 1; +} +void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { + if (mode == _MODE_TO_NORMAL) { + if (state != InternalState::ACTIVE) { + state = InternalState::ACTIVE; + transitionOk = false; + } else if (transitionOk) { + setMode(MODE_NORMAL); + } + } else { + DeviceHandlerBase::doTransition(modeFrom, subModeFrom); + } +} + +void Max31865EiveHandler::fillCommandAndReplyMap() { + insertInCommandMap(EiveMax31855::RtdCommands::ON); + insertInCommandMap(EiveMax31855::RtdCommands::ACTIVE); + insertInCommandMap(EiveMax31855::RtdCommands::OFF); + insertInReplyMap(EiveMax31855::RtdCommands::EXCHANGE_SET_ID, 200, &sensorDataset, 0, true); +} + +ReturnValue_t Max31865EiveHandler::scanForReply(const uint8_t* start, size_t remainingSize, + DeviceCommandId_t* foundId, size_t* foundLen) { + if (mode == _MODE_POWER_ON or mode == _MODE_WAIT_ON) { + return IGNORE_FULL_PACKET; + } + if (remainingSize != structLen) { + sif::error << "Invalid reply from RTD reader detected, reply size " << remainingSize + << " not equal to exchange struct size " << structLen << std::endl; + return DeviceHandlerIF::INVALID_DATA; + } + *foundId = EiveMax31855::RtdCommands::EXCHANGE_SET_ID; + *foundLen = remainingSize; + return RETURN_OK; +} + +ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id, + const uint8_t* packet) { + size_t deserTmp = structLen; + auto result = exchangeStruct.deSerialize(&packet, &deserTmp, SerializeIF::Endianness::MACHINE); + if (result != RETURN_OK) { + return result; + } + if (mode == _MODE_TO_NORMAL and exchangeStruct.active and state == InternalState::ACTIVE) { + transitionOk = true; + } + if (mode == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) { + transitionOk = true; + } + // Calculate resistance + float rtdValue = exchangeStruct.adcCode * EiveMax31855::RTD_RREF_PT1000 / INT16_MAX; + // calculate approximation + float approxTemp = exchangeStruct.adcCode / 32.0 - 256.0; + + if (debugMode) { + if (debugDivider.checkAndIncrement()) { + sif::info << "Max31865: " << std::setw(20) << std::left << locString << std::right + << " | R[Ohm] " << rtdValue << " Ohms | Approx T[C]: " << approxTemp << std::endl; + } + } + return RETURN_OK; +} + +uint32_t Max31865EiveHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2000; } + +ReturnValue_t Max31865EiveHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + using namespace MAX31865; + localDataPoolMap.emplace(static_cast(PoolIds::RTD_VALUE), new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::TEMPERATURE_C), new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::FAULT_BYTE), new PoolEntry({0})); + poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false); + return RETURN_OK; +} + +void Max31865EiveHandler::setDeviceInfo(uint8_t idx_, std::string location_) { + idx = idx_; + locString = std::move(location_); +} + +ReturnValue_t Max31865EiveHandler::initialize() { return DeviceHandlerBase::initialize(); } diff --git a/mission/devices/Max31865EiveHandler.h b/mission/devices/Max31865EiveHandler.h new file mode 100644 index 00000000..121929e7 --- /dev/null +++ b/mission/devices/Max31865EiveHandler.h @@ -0,0 +1,47 @@ +#ifndef MISSION_DEVICES_MAX31865EIVEHANDLER_H_ +#define MISSION_DEVICES_MAX31865EIVEHANDLER_H_ + +#include +#include + +#include "devicedefinitions/Max31865Definitions.h" + +class Max31865EiveHandler : public DeviceHandlerBase { + public: + Max31865EiveHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie); + void setInstantNormal(bool instantNormal); + void setDebugMode(bool enable, uint32_t divider); + void setDeviceInfo(uint8_t idx, std::string location); + + private: + void doStartUp() override; + void doShutDown() override; + void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; + ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; + ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; + void fillCommandAndReplyMap() override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, + size_t commandDataLen) override; + ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId, + size_t* foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override; + uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + ReturnValue_t initialize() override; + + void simpleCommand(EiveMax31855::RtdCommands cmd); + std::array cmdBuf = {}; + uint8_t idx = 0; + std::string locString = "Unknown"; + EiveMax31855::ReadOutStruct exchangeStruct; + bool debugMode = false; + size_t structLen = 0; + bool instantNormal = false; + MAX31865::Max31865Set sensorDataset; + PeriodicOperationDivider debugDivider; + enum class InternalState { NONE, ON, ACTIVE, INACTIVE } state = InternalState::NONE; + bool transitionOk = false; +}; + +#endif /* MISSION_DEVICES_MAX31865EIVEHANDLER_H_ */ diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 580c8637..354fe1c5 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -8,7 +8,7 @@ Max31865PT1000Handler::Max31865PT1000Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie) : DeviceHandlerBase(objectId, comIF, comCookie), - sensorDataset(this), + sensorDataset(this, MAX31865::REQUEST_RTD), sensorDatasetSid(sensorDataset.getSid()) { #if OBSW_VERBOSE_LEVEL >= 1 debugDivider = new PeriodicOperationDivider(10); @@ -93,13 +93,13 @@ void Max31865PT1000Handler::doShutDown() { ReturnValue_t Max31865PT1000Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { if (internalState == InternalState::RUNNING) { - *id = Max31865Definitions::REQUEST_RTD; + *id = MAX31865::REQUEST_RTD; return buildCommandFromCommand(*id, nullptr, 0); } else if (internalState == InternalState::REQUEST_FAULT_BYTE) { - *id = Max31865Definitions::REQUEST_FAULT_BYTE; + *id = MAX31865::REQUEST_FAULT_BYTE; return buildCommandFromCommand(*id, nullptr, 0); } else if (internalState == InternalState::CLEAR_FAULT_BYTE) { - *id = Max31865Definitions::CLEAR_FAULT_BYTE; + *id = MAX31865::CLEAR_FAULT_BYTE; return buildCommandFromCommand(*id, nullptr, 0); } else { return DeviceHandlerBase::NOTHING_TO_SEND; @@ -113,32 +113,32 @@ ReturnValue_t Max31865PT1000Handler::buildTransitionDeviceCommand(DeviceCommandI case (InternalState::RUNNING): return DeviceHandlerBase::NOTHING_TO_SEND; case (InternalState::CONFIGURE): { - *id = Max31865Definitions::CONFIG_CMD; + *id = MAX31865::CONFIG_CMD; uint8_t config[1] = {DEFAULT_CONFIG}; return buildCommandFromCommand(*id, config, 1); } case (InternalState::REQUEST_CONFIG): { - *id = Max31865Definitions::REQUEST_CONFIG; + *id = MAX31865::REQUEST_CONFIG; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::CONFIG_HIGH_THRESHOLD): { - *id = Max31865Definitions::WRITE_HIGH_THRESHOLD; + *id = MAX31865::WRITE_HIGH_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::REQUEST_HIGH_THRESHOLD): { - *id = Max31865Definitions::REQUEST_HIGH_THRESHOLD; + *id = MAX31865::REQUEST_HIGH_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::CONFIG_LOW_THRESHOLD): { - *id = Max31865Definitions::WRITE_LOW_THRESHOLD; + *id = MAX31865::WRITE_LOW_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::REQUEST_LOW_THRESHOLD): { - *id = Max31865Definitions::REQUEST_LOW_THRESHOLD; + *id = MAX31865::REQUEST_LOW_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::CLEAR_FAULT_BYTE): { - *id = Max31865Definitions::CLEAR_FAULT_BYTE; + *id = MAX31865::CLEAR_FAULT_BYTE; return buildCommandFromCommand(*id, nullptr, 0); } @@ -156,10 +156,11 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d const uint8_t *commandData, size_t commandDataLen) { switch (deviceCommand) { - case (Max31865Definitions::CONFIG_CMD): { - commandBuffer[0] = static_cast(Max31865Definitions::CONFIG_CMD); + case (MAX31865::CONFIG_CMD): { + commandBuffer[0] = static_cast(MAX31865::CONFIG_CMD); if (commandDataLen == 1) { commandBuffer[1] = commandData[0]; + currentCfg = commandData[0]; DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; @@ -167,54 +168,54 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d return DeviceHandlerIF::NO_COMMAND_DATA; } } - case (Max31865Definitions::CLEAR_FAULT_BYTE): { - commandBuffer[0] = static_cast(Max31865Definitions::CONFIG_CMD); - commandBuffer[1] = Max31865Definitions::CLEAR_FAULT_BIT_VAL; + case (MAX31865::CLEAR_FAULT_BYTE): { + commandBuffer[0] = static_cast(MAX31865::CONFIG_CMD); + commandBuffer[1] = currentCfg | MAX31865::CLEAR_FAULT_BIT_VAL; DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_CONFIG): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_CONFIG); + case (MAX31865::REQUEST_CONFIG): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_CONFIG); commandBuffer[1] = 0x00; // dummy byte DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::WRITE_HIGH_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::WRITE_HIGH_THRESHOLD); + case (MAX31865::WRITE_HIGH_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::WRITE_HIGH_THRESHOLD); commandBuffer[1] = static_cast(HIGH_THRESHOLD >> 8); commandBuffer[2] = static_cast(HIGH_THRESHOLD & 0xFF); DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_HIGH_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_HIGH_THRESHOLD); + case (MAX31865::REQUEST_HIGH_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_HIGH_THRESHOLD); commandBuffer[1] = 0x00; // dummy byte commandBuffer[2] = 0x00; // dummy byte DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::WRITE_LOW_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::WRITE_LOW_THRESHOLD); + case (MAX31865::WRITE_LOW_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::WRITE_LOW_THRESHOLD); commandBuffer[1] = static_cast(LOW_THRESHOLD >> 8); commandBuffer[2] = static_cast(LOW_THRESHOLD & 0xFF); DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_LOW_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_LOW_THRESHOLD); + case (MAX31865::REQUEST_LOW_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_LOW_THRESHOLD); commandBuffer[1] = 0x00; // dummy byte commandBuffer[2] = 0x00; // dummy byte DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_RTD): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_RTD); + case (MAX31865::REQUEST_RTD): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_RTD); // two dummy bytes commandBuffer[1] = 0x00; commandBuffer[2] = 0x00; @@ -222,8 +223,8 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_FAULT_BYTE): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_FAULT_BYTE); + case (MAX31865::REQUEST_FAULT_BYTE): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_FAULT_BYTE); commandBuffer[1] = 0x00; DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); @@ -236,15 +237,15 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d } void Max31865PT1000Handler::fillCommandAndReplyMap() { - insertInCommandAndReplyMap(Max31865Definitions::CONFIG_CMD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_CONFIG, 3); - insertInCommandAndReplyMap(Max31865Definitions::WRITE_LOW_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_LOW_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::WRITE_HIGH_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_HIGH_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_RTD, 3, &sensorDataset); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_FAULT_BYTE, 3); - insertInCommandAndReplyMap(Max31865Definitions::CLEAR_FAULT_BYTE, 3); + insertInCommandAndReplyMap(MAX31865::CONFIG_CMD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_CONFIG, 3); + insertInCommandAndReplyMap(MAX31865::WRITE_LOW_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_LOW_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::WRITE_HIGH_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_HIGH_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_RTD, 3, &sensorDataset); + insertInCommandAndReplyMap(MAX31865::REQUEST_FAULT_BYTE, 3); + insertInCommandAndReplyMap(MAX31865::CLEAR_FAULT_BYTE, 3); } ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t remainingSize, @@ -253,7 +254,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r size_t configReplySize = 2; if (remainingSize == rtdReplySize and internalState == InternalState::RUNNING) { - *foundId = Max31865Definitions::REQUEST_RTD; + *foundId = MAX31865::REQUEST_RTD; *foundLen = rtdReplySize; return RETURN_OK; } @@ -262,24 +263,24 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r switch (internalState) { case (InternalState::CONFIG_HIGH_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::WRITE_HIGH_THRESHOLD; + *foundId = MAX31865::WRITE_HIGH_THRESHOLD; commandExecuted = true; return RETURN_OK; } case (InternalState::REQUEST_HIGH_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::REQUEST_HIGH_THRESHOLD; + *foundId = MAX31865::REQUEST_HIGH_THRESHOLD; return RETURN_OK; } case (InternalState::CONFIG_LOW_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::WRITE_LOW_THRESHOLD; + *foundId = MAX31865::WRITE_LOW_THRESHOLD; commandExecuted = true; return RETURN_OK; } case (InternalState::REQUEST_LOW_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::REQUEST_LOW_THRESHOLD; + *foundId = MAX31865::REQUEST_LOW_THRESHOLD; return RETURN_OK; } default: { @@ -293,13 +294,13 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r if (internalState == InternalState::CONFIGURE) { commandExecuted = true; *foundLen = configReplySize; - *foundId = Max31865Definitions::CONFIG_CMD; + *foundId = MAX31865::CONFIG_CMD; } else if (internalState == InternalState::REQUEST_FAULT_BYTE) { - *foundId = Max31865Definitions::REQUEST_FAULT_BYTE; + *foundId = MAX31865::REQUEST_FAULT_BYTE; *foundLen = 2; internalState = InternalState::RUNNING; } else if (internalState == InternalState::CLEAR_FAULT_BYTE) { - *foundId = Max31865Definitions::CLEAR_FAULT_BYTE; + *foundId = MAX31865::CLEAR_FAULT_BYTE; *foundLen = 2; if (mode == _MODE_START_UP) { commandExecuted = true; @@ -307,7 +308,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r internalState = InternalState::RUNNING; } } else { - *foundId = Max31865Definitions::REQUEST_CONFIG; + *foundId = MAX31865::REQUEST_CONFIG; *foundLen = configReplySize; } } @@ -318,7 +319,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch (id) { - case (Max31865Definitions::REQUEST_CONFIG): { + case (MAX31865::REQUEST_CONFIG): { if (packet[1] != DEFAULT_CONFIG) { if (warningSwitch) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -342,7 +343,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, } break; } - case (Max31865Definitions::REQUEST_LOW_THRESHOLD): { + case (MAX31865::REQUEST_LOW_THRESHOLD): { uint16_t readLowThreshold = packet[1] << 8 | packet[2]; if (readLowThreshold != LOW_THRESHOLD) { #if FSFW_VERBOSE_LEVEL >= 1 @@ -360,8 +361,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, commandExecuted = true; break; } - case (Max31865Definitions::REQUEST_HIGH_THRESHOLD): { - uint16_t readHighThreshold = packet[1] << 8 | packet[2]; + case (MAX31865::REQUEST_HIGH_THRESHOLD): { + uint16_t readHighThreshold = (packet[1] << 8) | packet[2]; if (readHighThreshold != HIGH_THRESHOLD) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -378,13 +379,13 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, commandExecuted = true; break; } - case (Max31865Definitions::REQUEST_RTD): { + case (MAX31865::REQUEST_RTD): { // first bit of LSB reply byte is the fault bit - uint8_t faultBit = packet[2] & 0b0000'0001; + bool faultBit = packet[2] & 0b0000'0001; if (resetFaultBit) { internalState = InternalState::CLEAR_FAULT_BYTE; resetFaultBit = false; - } else if (faultBit == 1) { + } else if (shouldFaultStatusBeRequested(faultBit)) { // Maybe we should attempt to restart it? internalState = InternalState::REQUEST_FAULT_BYTE; resetFaultBit = true; @@ -393,9 +394,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, // RTD value consists of last seven bits of the LSB reply byte and // the MSB reply byte uint16_t adcCode = ((packet[1] << 8) | packet[2]) >> 1; - // do something with rtd value, will propably be stored in - // dataset. - float rtdValue = adcCode * RTD_RREF_PT1000 / INT16_MAX; + // Calculate resistance + float rtdValue = adcCode * EiveMax31855::RTD_RREF_PT1000 / INT16_MAX; // calculate approximation float approxTemp = adcCode / 32.0 - 256.0; @@ -403,9 +403,9 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, #if OBSW_VERBOSE_LEVEL >= 1 if (debugDivider->checkAndIncrement()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "Max31865: ObjID " << std::hex << this->getObjectId() << " | RTD " - << std::dec << static_cast(deviceIdx) << ": R[Ohm] " << rtdValue - << " Ohms | Approx T[C]: " << approxTemp << std::endl; + sif::info << "Max31865: " << std::setw(24) << std::left << locString << std::right + << " | R[Ohm] " << rtdValue << " Ohms | Approx T[C]: " << approxTemp + << std::endl; #else sif::printInfo("Max31685: Measured resistance is %f Ohms\n", rtdValue); sif::printInfo("Approximated temperature is %f C\n", approxTemp); @@ -438,58 +438,57 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, sensorDataset.temperatureCelcius = approxTemp; break; } - case (Max31865Definitions::REQUEST_FAULT_BYTE): { - faultByte = packet[1]; + case (MAX31865::REQUEST_FAULT_BYTE): { + currentFaultStatus = packet[1]; + bool faultStatusChanged = (currentFaultStatus != lastFaultStatus); + // Spam protection + if (faultStatusChanged or + ((currentFaultStatus == lastFaultStatus) and (sameFaultStatusCounter < 3))) { + // TODO: Think about triggering an event here #if OBSW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex - << this->getObjectId() - << ": Fault byte" - " is: 0b" - << std::bitset<8>(faultByte) << std::endl; + sif::warning << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex + << this->getObjectId() << ": Fault byte is: 0b" + << std::bitset<8>(currentFaultStatus) << std::endl; #else - sif::printWarning( - "Max31865PT1000Handler::interpretDeviceReply: Fault byte" - " is: 0b" BYTE_TO_BINARY_PATTERN "\n", - BYTE_TO_BINARY(faultByte)); + sif::printWarning( + "Max31865PT1000Handler::interpretDeviceReply: Fault byte" + " is: 0b" BYTE_TO_BINARY_PATTERN "\n", + BYTE_TO_BINARY(faultByte)); #endif #endif - ReturnValue_t result = sensorDataset.read(); + if (faultStatusChanged) { + sameFaultStatusCounter = 0; + } else { + sameFaultStatusCounter++; + } + } + if (faultStatusChanged) { + lastFaultStatus = currentFaultStatus; + } + + PoolReadGuard pg(&sensorDataset); + auto result = pg.getReadResult(); if (result != HasReturnvaluesIF::RETURN_OK) { // Configuration error #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex - << this->getObjectId() - << ":" - "Error reading dataset!" - << std::endl; + sif::warning << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex + << this->getObjectId() << ": Error reading dataset" << std::endl; #else - sif::printDebug( - "Max31865PT1000Handler::interpretDeviceReply: " - "Error reading dataset!\n"); + sif::printWarning("Max31865PT1000Handler::interpretDeviceReply: Error reading dataset\n"); #endif return result; } + if (faultStatusChanged) { + sensorDataset.lastErrorByte.setValid(true); + sensorDataset.lastErrorByte = lastFaultStatus; + } sensorDataset.errorByte.setValid(true); - sensorDataset.errorByte = faultByte; - if (faultByte != 0) { + sensorDataset.errorByte = currentFaultStatus; + + if (currentFaultStatus != 0) { sensorDataset.temperatureCelcius.setValid(false); } - - result = sensorDataset.commit(); - if (result != HasReturnvaluesIF::RETURN_OK) { - // Configuration error -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex - << this->getObjectId() << ": Error commiting dataset!" << std::endl; -#else - sif::printDebug( - "Max31865PT1000Handler::interpretDeviceReply: " - "Error commiting dataset!\n"); -#endif - return result; - } - break; } default: @@ -498,11 +497,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, return HasReturnvaluesIF::RETURN_OK; } -void Max31865PT1000Handler::debugInterface(uint8_t positionTracker, object_id_t objectId, - uint32_t parameter) {} - uint32_t Max31865PT1000Handler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { - return 25000; + return 5000; } ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches, @@ -512,10 +508,12 @@ ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches, ReturnValue_t Max31865PT1000Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { - localDataPoolMap.emplace(Max31865Definitions::PoolIds::RTD_VALUE, new PoolEntry({0})); - localDataPoolMap.emplace(Max31865Definitions::PoolIds::TEMPERATURE_C, - new PoolEntry({0}, 1, true)); - localDataPoolMap.emplace(Max31865Definitions::PoolIds::FAULT_BYTE, new PoolEntry({0})); + using namespace MAX31865; + localDataPoolMap.emplace(static_cast(PoolIds::RTD_VALUE), new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::TEMPERATURE_C), new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::LAST_FAULT_BYTE), + new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::FAULT_BYTE), new PoolEntry({0})); poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false); return HasReturnvaluesIF::RETURN_OK; } @@ -526,10 +524,23 @@ void Max31865PT1000Handler::setInstantNormal(bool instantNormal) { void Max31865PT1000Handler::modeChanged() { if (mode == MODE_OFF) { + lastFaultStatus = 0; + currentFaultStatus = 0; + sameFaultStatusCounter = 0; internalState = InternalState::NONE; } } -void Max31865PT1000Handler::setDeviceIdx(uint8_t idx) { deviceIdx = idx; } +void Max31865PT1000Handler::setDeviceInfo(uint8_t idx, std::string locString_) { + deviceIdx = idx; + locString = std::move(locString_); +} void Max31865PT1000Handler::setDebugMode(bool enable) { this->debugMode = enable; } + +bool Max31865PT1000Handler::shouldFaultStatusBeRequested(bool faultBit) { + if ((sameFaultStatusCounter < 3) and faultBit) { + return true; + } + return false; +} diff --git a/mission/devices/Max31865PT1000Handler.h b/mission/devices/Max31865PT1000Handler.h index 4f617b9d..6b136f13 100644 --- a/mission/devices/Max31865PT1000Handler.h +++ b/mission/devices/Max31865PT1000Handler.h @@ -48,7 +48,7 @@ class Max31865PT1000Handler : public DeviceHandlerBase { static constexpr uint8_t DEFAULT_CONFIG = 0b11000001; void setInstantNormal(bool instantNormal); - void setDeviceIdx(uint8_t idx); + void setDeviceInfo(uint8_t idx, std::string locString); /** * Expected temperature range is -100 C and 100 C. @@ -61,7 +61,6 @@ class Max31865PT1000Handler : public DeviceHandlerBase { static constexpr uint16_t HIGH_THRESHOLD = 11298; // = 100 C static constexpr uint16_t LOW_THRESHOLD = 4902; // = -100 C - static constexpr float RTD_RREF_PT1000 = 4020.0; //!< Ohm static constexpr float RTD_RESISTANCE0_PT1000 = 1000.0; //!< Ohm protected: // DeviceHandlerBase abstract function implementation @@ -77,12 +76,10 @@ class Max31865PT1000Handler : public DeviceHandlerBase { ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override; - - void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0, - uint32_t parameter = 0) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) override; void modeChanged() override; + bool shouldFaultStatusBeRequested(bool faultBit); private: uint8_t switchId = 0; @@ -109,11 +106,15 @@ class Max31865PT1000Handler : public DeviceHandlerBase { bool resetFaultBit = false; dur_millis_t startTime = 0; - uint8_t faultByte = 0; + uint8_t currentCfg = 0; + uint8_t currentFaultStatus = 0; + uint8_t lastFaultStatus = 0; + uint16_t sameFaultStatusCounter = 0; + std::string locString; uint8_t deviceIdx = 0; std::array commandBuffer{0}; - Max31865Definitions::Max31865Set sensorDataset; + MAX31865::Max31865Set sensorDataset; sid_t sensorDatasetSid; #if OBSW_VERBOSE_LEVEL >= 1 diff --git a/mission/devices/P60DockHandler.cpp b/mission/devices/P60DockHandler.cpp index f1df649d..25fb238f 100644 --- a/mission/devices/P60DockHandler.cpp +++ b/mission/devices/P60DockHandler.cpp @@ -251,7 +251,7 @@ ReturnValue_t P60DockHandler::printStatus(DeviceCommandId_t cmd) { return HasReturnvaluesIF::RETURN_OK; } default: { - return HasReturnvaluesIF::RETURN_FAILED; + return DeviceHandlerIF::COMMAND_NOT_SUPPORTED; } } sif::warning << "Reading P60 Dock HK table failed" << std::endl; diff --git a/mission/devices/PDU1Handler.cpp b/mission/devices/PDU1Handler.cpp index 44f8fb04..fca0fbeb 100644 --- a/mission/devices/PDU1Handler.cpp +++ b/mission/devices/PDU1Handler.cpp @@ -122,7 +122,7 @@ ReturnValue_t PDU1Handler::printStatus(DeviceCommandId_t cmd) { break; } default: { - return HasReturnvaluesIF::RETURN_FAILED; + return DeviceHandlerIF::COMMAND_NOT_SUPPORTED; } } if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/mission/devices/PDU2Handler.cpp b/mission/devices/PDU2Handler.cpp index 1476f95d..d0cef3f5 100644 --- a/mission/devices/PDU2Handler.cpp +++ b/mission/devices/PDU2Handler.cpp @@ -76,7 +76,7 @@ ReturnValue_t PDU2Handler::printStatus(DeviceCommandId_t cmd) { break; } default: { - return HasReturnvaluesIF::RETURN_FAILED; + return DeviceHandlerIF::COMMAND_NOT_SUPPORTED; } } if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/mission/devices/PayloadPcduHandler.cpp b/mission/devices/PayloadPcduHandler.cpp index dd576cae..3e18a94e 100644 --- a/mission/devices/PayloadPcduHandler.cpp +++ b/mission/devices/PayloadPcduHandler.cpp @@ -490,10 +490,9 @@ void PayloadPcduHandler::checkAdcValues() { void PayloadPcduHandler::checkJsonFileInit() { if (not jsonFileInitComplete) { - sd::SdCard prefSd; - sdcMan->getPreferredSdCard(prefSd); - if (sdcMan->isSdCardMounted(prefSd)) { - params.initialize(sdcMan->getCurrentMountPrefix(prefSd)); + sd::SdCard activeSd = sdcMan->getActiveSdCard(); + if (sdcMan->isSdCardMounted(activeSd)) { + params.initialize(sdcMan->getCurrentMountPrefix()); jsonFileInitComplete = true; } } @@ -716,7 +715,6 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook GpioIF* gpioIF = comIf->getGpioInterface(); MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; uint32_t timeoutMs = 0; - cookie->getMutexParams(timeoutType, timeoutMs); MutexIF* mutex = comIf->getCsMutex(); if (mutex == nullptr or gpioIF == nullptr) { #if OBSW_VERBOSE_LEVEL >= 1 @@ -728,6 +726,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook } if (gpioId != gpio::NO_GPIO) { + cookie->getMutexParams(timeoutType, timeoutMs); result = mutex->lockMutex(timeoutType, timeoutMs); if (result != RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 diff --git a/mission/devices/RadiationSensorHandler.cpp b/mission/devices/RadiationSensorHandler.cpp index b3a9954a..f2694476 100644 --- a/mission/devices/RadiationSensorHandler.cpp +++ b/mission/devices/RadiationSensorHandler.cpp @@ -158,18 +158,18 @@ ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id, int16_t tempRaw = ((packet[offset] & 0x0f) << 8) | packet[offset + 1]; dataset.temperatureCelcius = tempRaw * 0.125; offset += 2; - dataset.ain0 = (*(packet + offset) << 8 | *(packet + offset + 1)); + dataset.ain0 = (*(packet + offset) << 8) | *(packet + offset + 1); offset += 2; - dataset.ain1 = (*(packet + offset) << 8 | *(packet + offset + 1)); + dataset.ain1 = (*(packet + offset) << 8) | *(packet + offset + 1); offset += 6; - dataset.ain4 = (*(packet + offset) << 8 | *(packet + offset + 1)); + dataset.ain4 = (*(packet + offset) << 8) | *(packet + offset + 1); offset += 2; - dataset.ain5 = (*(packet + offset) << 8 | *(packet + offset + 1)); + dataset.ain5 = (*(packet + offset) << 8) | *(packet + offset + 1); offset += 2; - dataset.ain6 = (*(packet + offset) << 8 | *(packet + offset + 1)); + dataset.ain6 = (*(packet + offset) << 8) | *(packet + offset + 1); offset += 2; - dataset.ain7 = (*(packet + offset) << 8 | *(packet + offset + 1)); - + dataset.ain7 = (*(packet + offset) << 8) | *(packet + offset + 1); + dataset.setValidity(true, true); if (printPeriodicData) { sif::info << "Radiation sensor temperature: " << dataset.temperatureCelcius << " °C" << std::dec << std::endl; diff --git a/mission/devices/devicedefinitions/GPSDefinitions.h b/mission/devices/devicedefinitions/GPSDefinitions.h index f953da22..e842f54b 100644 --- a/mission/devices/devicedefinitions/GPSDefinitions.h +++ b/mission/devices/devicedefinitions/GPSDefinitions.h @@ -14,7 +14,7 @@ static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::GPS_HANDLER; static constexpr Event GPS_FIX_CHANGE = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO); static constexpr DeviceCommandId_t GPS_REPLY = 0; -static constexpr DeviceCommandId_t TRIGGER_RESET_PIN = 5; +static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5; static constexpr uint32_t DATASET_ID = 0; diff --git a/mission/devices/devicedefinitions/GomspaceDefinitions.h b/mission/devices/devicedefinitions/GomspaceDefinitions.h index 5c59d3d8..18059fc8 100644 --- a/mission/devices/devicedefinitions/GomspaceDefinitions.h +++ b/mission/devices/devicedefinitions/GomspaceDefinitions.h @@ -38,7 +38,8 @@ static const DeviceCommandId_t PARAM_GET = 0; //!< [EXPORT] : [COMMAND] static const DeviceCommandId_t PARAM_SET = 255; //!< [EXPORT] : [COMMAND] static const DeviceCommandId_t REQUEST_HK_TABLE = 16; //!< [EXPORT] : [COMMAND] -//!< [EXPORT] : [COMMAND] Print switch states, voltages and currents to the console +//! [EXPORT] : [COMMAND] Print switch states, voltages and currents to the console +//! For the ACU device, only print voltages and currents of the 6 ACU channels static const DeviceCommandId_t PRINT_SWITCH_V_I = 32; static const DeviceCommandId_t PRINT_LATCHUPS = 33; @@ -55,7 +56,8 @@ enum class SetIds : uint32_t { PDU_2_AUX = 4, P60_CORE = 5, P60_AUX = 6, - ACU = 7 + ACU_CORE = 7, + ACU_AUX = 8 }; namespace pool { @@ -129,67 +131,24 @@ enum Ids : lp_id_t { PDU_WDT_CSP_LEFT2, /** ACU Ids */ - ACU_CURRENT_IN_CHANNEL0, - ACU_CURRENT_IN_CHANNEL1, - ACU_CURRENT_IN_CHANNEL2, - ACU_CURRENT_IN_CHANNEL3, - ACU_CURRENT_IN_CHANNEL4, - ACU_CURRENT_IN_CHANNEL5, - ACU_VOLTAGE_IN_CHANNEL0, - ACU_VOLTAGE_IN_CHANNEL1, - ACU_VOLTAGE_IN_CHANNEL2, - ACU_VOLTAGE_IN_CHANNEL3, - ACU_VOLTAGE_IN_CHANNEL4, - ACU_VOLTAGE_IN_CHANNEL5, + ACU_CURRENT_IN_CHANNELS, + ACU_VOLTAGE_IN_CHANNELS, ACU_VCC, ACU_VBAT, - ACU_TEMPERATURE_1, - ACU_TEMPERATURE_2, - ACU_TEMPERATURE_3, + ACU_TEMPERATURES, ACU_MPPT_MODE, - ACU_VBOOST_CHANNEL0, - ACU_VBOOST_CHANNEL1, - ACU_VBOOST_CHANNEL2, - ACU_VBOOST_CHANNEL3, - ACU_VBOOST_CHANNEL4, - ACU_VBOOST_CHANNEL5, - ACU_POWER_CHANNEL0, - ACU_POWER_CHANNEL1, - ACU_POWER_CHANNEL2, - ACU_POWER_CHANNEL3, - ACU_POWER_CHANNEL4, - ACU_POWER_CHANNEL5, - ACU_DAC_EN_0, - ACU_DAC_EN_1, - ACU_DAC_EN_2, - ACU_DAC_RAW_0, - ACU_DAC_RAW_1, - ACU_DAC_RAW_2, - ACU_DAC_RAW_3, - ACU_DAC_RAW_4, - ACU_DAC_RAW_5, + ACU_VBOOST_IN_CHANNELS, + ACU_POWER_IN_CHANNELS, + ACU_DAC_ENABLES, + ACU_DAC_RAW_CHANNELS, ACU_BOOTCAUSE, ACU_BOOTCNT, ACU_UPTIME, ACU_RESET_CAUSE, ACU_MPPT_TIME, ACU_MPPT_PERIOD, - ACU_DEVICE_0, - ACU_DEVICE_1, - ACU_DEVICE_2, - ACU_DEVICE_3, - ACU_DEVICE_4, - ACU_DEVICE_5, - ACU_DEVICE_6, - ACU_DEVICE_7, - ACU_DEVICE_0_STATUS, - ACU_DEVICE_1_STATUS, - ACU_DEVICE_2_STATUS, - ACU_DEVICE_3_STATUS, - ACU_DEVICE_4_STATUS, - ACU_DEVICE_5_STATUS, - ACU_DEVICE_6_STATUS, - ACU_DEVICE_7_STATUS, + ACU_DEVICES, + ACU_DEVICES_STATUS, ACU_WDT_CNT_GND, ACU_WDT_GND_LEFT, }; @@ -592,143 +551,76 @@ static const uint16_t MAX_HKTABLE_ADDRESS = 120; static const uint8_t HK_TABLE_ENTRIES = 64; static const uint16_t HK_TABLE_REPLY_SIZE = 262; -/** - * @brief This class defines a dataset for the hk table of the ACU. - */ -class HkTableDataset : public StaticLocalDataSet { +class CoreHk : public StaticLocalDataSet<14> { public: - HkTableDataset(HasLocalDataPoolIF* owner) - : StaticLocalDataSet(owner, static_cast(::P60System::SetIds::ACU)) {} + CoreHk(HasLocalDataPoolIF* owner) + : StaticLocalDataSet(owner, static_cast(::P60System::SetIds::ACU_CORE)) {} - HkTableDataset(object_id_t objectId) - : StaticLocalDataSet(sid_t(objectId, static_cast(::P60System::SetIds::ACU))) {} - - lp_var_t currentInChannel0 = - lp_var_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNEL0, this); - lp_var_t currentInChannel1 = - lp_var_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNEL1, this); - lp_var_t currentInChannel2 = - lp_var_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNEL2, this); - lp_var_t currentInChannel3 = - lp_var_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNEL3, this); - lp_var_t currentInChannel4 = - lp_var_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNEL4, this); - lp_var_t currentInChannel5 = - lp_var_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNEL5, this); - - lp_var_t voltageInChannel0 = - lp_var_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNEL0, this); - lp_var_t voltageInChannel1 = - lp_var_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNEL1, this); - lp_var_t voltageInChannel2 = - lp_var_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNEL2, this); - lp_var_t voltageInChannel3 = - lp_var_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNEL3, this); - lp_var_t voltageInChannel4 = - lp_var_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNEL4, this); - lp_var_t voltageInChannel5 = - lp_var_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNEL5, this); - - lp_var_t vcc = lp_var_t(sid.objectId, P60System::pool::ACU_VCC, this); - lp_var_t vbat = lp_var_t(sid.objectId, P60System::pool::ACU_VBAT, this); - - lp_var_t temperature1 = - lp_var_t(sid.objectId, P60System::pool::ACU_TEMPERATURE_1, this); - lp_var_t temperature2 = - lp_var_t(sid.objectId, P60System::pool::ACU_TEMPERATURE_2, this); - lp_var_t temperature3 = - lp_var_t(sid.objectId, P60System::pool::ACU_TEMPERATURE_3, this); + CoreHk(object_id_t objectId) + : StaticLocalDataSet(sid_t(objectId, static_cast(::P60System::SetIds::ACU_CORE))) {} lp_var_t mpptMode = lp_var_t(sid.objectId, P60System::pool::ACU_MPPT_MODE, this); - lp_var_t vboostInChannel0 = - lp_var_t(sid.objectId, P60System::pool::ACU_VBOOST_CHANNEL0, this); - lp_var_t vboostInChannel1 = - lp_var_t(sid.objectId, P60System::pool::ACU_VBOOST_CHANNEL1, this); - lp_var_t vboostInChannel2 = - lp_var_t(sid.objectId, P60System::pool::ACU_VBOOST_CHANNEL2, this); - lp_var_t vboostInChannel3 = - lp_var_t(sid.objectId, P60System::pool::ACU_VBOOST_CHANNEL3, this); - lp_var_t vboostInChannel4 = - lp_var_t(sid.objectId, P60System::pool::ACU_VBOOST_CHANNEL4, this); - lp_var_t vboostInChannel5 = - lp_var_t(sid.objectId, P60System::pool::ACU_VBOOST_CHANNEL5, this); + lp_vec_t currentInChannels = + lp_vec_t(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNELS, this); + lp_vec_t voltageInChannels = + lp_vec_t(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNELS, this); - lp_var_t powerInChannel0 = - lp_var_t(sid.objectId, P60System::pool::ACU_POWER_CHANNEL0, this); - lp_var_t powerInChannel1 = - lp_var_t(sid.objectId, P60System::pool::ACU_POWER_CHANNEL1, this); - lp_var_t powerInChannel2 = - lp_var_t(sid.objectId, P60System::pool::ACU_POWER_CHANNEL2, this); - lp_var_t powerInChannel3 = - lp_var_t(sid.objectId, P60System::pool::ACU_POWER_CHANNEL3, this); - lp_var_t powerInChannel4 = - lp_var_t(sid.objectId, P60System::pool::ACU_POWER_CHANNEL4, this); - lp_var_t powerInChannel5 = - lp_var_t(sid.objectId, P60System::pool::ACU_POWER_CHANNEL5, this); + lp_var_t vcc = lp_var_t(sid.objectId, P60System::pool::ACU_VCC, this); + lp_var_t vbat = lp_var_t(sid.objectId, P60System::pool::ACU_VBAT, this); - lp_var_t dac0Enable = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_EN_0, this); - lp_var_t dac1Enable = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_EN_1, this); - lp_var_t dac2Enable = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_EN_2, this); + lp_vec_t vboostInChannels = + lp_vec_t(sid.objectId, P60System::pool::ACU_VBOOST_IN_CHANNELS, this); + lp_vec_t powerInChannels = + lp_vec_t(sid.objectId, P60System::pool::ACU_POWER_IN_CHANNELS, this); - lp_var_t dacRawChannelVal0 = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_RAW_0, this); - lp_var_t dacRawChannelVal1 = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_RAW_1, this); - lp_var_t dacRawChannelVal2 = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_RAW_2, this); - lp_var_t dacRawChannelVal3 = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_RAW_3, this); - lp_var_t dacRawChannelVal4 = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_RAW_4, this); - lp_var_t dacRawChannelVal5 = - lp_var_t(sid.objectId, P60System::pool::ACU_DAC_RAW_5, this); + lp_vec_t temperatures = + lp_vec_t(sid.objectId, P60System::pool::ACU_TEMPERATURES, this); - lp_var_t bootCause = - lp_var_t(sid.objectId, P60System::pool::ACU_BOOTCAUSE, this); lp_var_t bootcnt = lp_var_t(sid.objectId, P60System::pool::ACU_BOOTCNT, this); lp_var_t uptime = lp_var_t(sid.objectId, P60System::pool::ACU_UPTIME, this); - lp_var_t resetCause = - lp_var_t(sid.objectId, P60System::pool::ACU_RESET_CAUSE, this); lp_var_t mpptTime = lp_var_t(sid.objectId, P60System::pool::ACU_MPPT_TIME, this); lp_var_t mpptPeriod = lp_var_t(sid.objectId, P60System::pool::ACU_MPPT_PERIOD, this); +}; +/** + * @brief This class defines a dataset for the hk table of the ACU. + */ +class AuxHk : public StaticLocalDataSet<12> { + public: + AuxHk(HasLocalDataPoolIF* owner) + : StaticLocalDataSet(owner, static_cast(::P60System::SetIds::ACU_AUX)) {} - lp_var_t device0 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_0, this); - lp_var_t device1 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_1, this); - lp_var_t device2 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_2, this); - lp_var_t device3 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_3, this); - lp_var_t device4 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_4, this); - lp_var_t device5 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_5, this); - lp_var_t device6 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_6, this); - lp_var_t device7 = lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_7, this); + AuxHk(object_id_t objectId) + : StaticLocalDataSet(sid_t(objectId, static_cast(::P60System::SetIds::ACU_AUX))) {} - lp_var_t device0Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_0_STATUS, this); - lp_var_t device1Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_1_STATUS, this); - lp_var_t device2Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_2_STATUS, this); - lp_var_t device3Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_3_STATUS, this); - lp_var_t device4Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_4_STATUS, this); - lp_var_t device5Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_5_STATUS, this); - lp_var_t device6Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_6_STATUS, this); - lp_var_t device7Status = - lp_var_t(sid.objectId, P60System::pool::ACU_DEVICE_7_STATUS, this); + lp_vec_t dacEnables = + lp_vec_t(sid.objectId, P60System::pool::ACU_DAC_ENABLES, this); + + lp_vec_t dacRawChannelVals = + lp_vec_t(sid.objectId, P60System::pool::ACU_DAC_RAW_CHANNELS, this); + + lp_var_t bootCause = + lp_var_t(sid.objectId, P60System::pool::ACU_BOOTCAUSE, this); + lp_var_t resetCause = + lp_var_t(sid.objectId, P60System::pool::ACU_RESET_CAUSE, this); lp_var_t wdtCntGnd = lp_var_t(sid.objectId, P60System::pool::ACU_WDT_CNT_GND, this); lp_var_t wdtGndLeft = lp_var_t(sid.objectId, P60System::pool::ACU_WDT_GND_LEFT, this); + + /** + * There are 8 devices on the PDU. FRAM, ADCs, temperature sensor etc. Each device is + * identified by an ID. Refer also to gs-man-nanopower-p60-pdu-200-1.pdf on pages 17 and 18. + */ + lp_vec_t deviceTypes = + lp_vec_t(sid.objectId, P60System::pool::ACU_DEVICES, this); + /** The status of each device. 0 = None, 1 = Ok, 2 = Error, 3 = Not found */ + lp_vec_t devicesStatus = + lp_vec_t(sid.objectId, P60System::pool::ACU_DEVICES_STATUS, this); }; } // namespace ACU diff --git a/mission/devices/devicedefinitions/Max31865Definitions.h b/mission/devices/devicedefinitions/Max31865Definitions.h index 58faaf97..d7d6455d 100644 --- a/mission/devices/devicedefinitions/Max31865Definitions.h +++ b/mission/devices/devicedefinitions/Max31865Definitions.h @@ -7,20 +7,48 @@ #include "objects/systemObjectList.h" -namespace Max31865Definitions { +namespace MAX31865 { -enum PoolIds : lp_id_t { RTD_VALUE, TEMPERATURE_C, FAULT_BYTE }; +enum class PoolIds : lp_id_t { RTD_VALUE, TEMPERATURE_C, LAST_FAULT_BYTE, FAULT_BYTE }; +enum Wires : unsigned int { TWO_WIRE = 0, THREE_WIRE = 1, FOUR_WIRE = 0 }; + +enum ConvMode : unsigned int { NORM_OFF = 0, AUTO = 1 }; + +enum Bias : unsigned int { OFF = 0, ON = 1 }; + +enum FilterSel : unsigned int { FIFTY_HERTZ = 1, SIXTY_HERTZ = 0 }; + +enum CfgBitPos { + FILTER_SEL = 0, + FAULT_STATUS_CLEAR = 1, + FDCC = 2, + WIRE_SEL = 4, + ONE_SHOT = 5, + CONV_MODE = 6, + BIAS_SEL = 7 +}; + +static constexpr uint32_t WARMUP_MS = 100; + +static constexpr uint8_t WRITE_BIT = 0b10000000; + +enum Regs : uint8_t { + CONFIG = 0x00, + RTD = 0x01, + HIGH_THRESHOLD = 0x03, + LOW_THRESHOLD = 0x05, + FAULT_BYTE = 0x07 +}; static constexpr DeviceCommandId_t CONFIG_CMD = 0x80; static constexpr DeviceCommandId_t WRITE_HIGH_THRESHOLD = 0x83; static constexpr DeviceCommandId_t WRITE_LOW_THRESHOLD = 0x85; -static constexpr DeviceCommandId_t REQUEST_CONFIG = 0x00; -static constexpr DeviceCommandId_t REQUEST_RTD = 0x01; -static constexpr DeviceCommandId_t REQUEST_HIGH_THRESHOLD = 0x03; -static constexpr DeviceCommandId_t REQUEST_LOW_THRESHOLD = 0x05; -static constexpr DeviceCommandId_t REQUEST_FAULT_BYTE = 0x07; - +static constexpr DeviceCommandId_t REQUEST_CONFIG = CONFIG; +static constexpr DeviceCommandId_t REQUEST_RTD = RTD; +static constexpr DeviceCommandId_t REQUEST_HIGH_THRESHOLD = HIGH_THRESHOLD; +static constexpr DeviceCommandId_t REQUEST_LOW_THRESHOLD = LOW_THRESHOLD; +static constexpr DeviceCommandId_t REQUEST_FAULT_BYTE = FAULT_BYTE; static constexpr DeviceCommandId_t CLEAR_FAULT_BYTE = 0x08; static constexpr uint32_t MAX31865_SET_ID = REQUEST_RTD; @@ -28,26 +56,82 @@ static constexpr uint8_t CLEAR_FAULT_BIT_VAL = 0b0000'0010; static constexpr size_t MAX_REPLY_SIZE = 5; -class Max31865Set : public StaticLocalDataSet { +class Max31865Set : public StaticLocalDataSet<4> { public: /** * Constructor used by owner and data creators like device handlers. * @param owner * @param setId */ - Max31865Set(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, MAX31865_SET_ID) {} + Max31865Set(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {} /** * Constructor used by data users like controllers. * @param sid */ - Max31865Set(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, MAX31865_SET_ID)) {} + Max31865Set(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {} - lp_var_t rtdValue = lp_var_t(sid.objectId, PoolIds::RTD_VALUE, this); - lp_var_t temperatureCelcius = lp_var_t(sid.objectId, PoolIds::TEMPERATURE_C, this); - lp_var_t errorByte = lp_var_t(sid.objectId, PoolIds::FAULT_BYTE, this); + lp_var_t rtdValue = + lp_var_t(sid.objectId, static_cast(PoolIds::RTD_VALUE), this); + lp_var_t temperatureCelcius = + lp_var_t(sid.objectId, static_cast(PoolIds::TEMPERATURE_C), this); + lp_var_t lastErrorByte = + lp_var_t(sid.objectId, static_cast(PoolIds::LAST_FAULT_BYTE), this); + lp_var_t errorByte = + lp_var_t(sid.objectId, static_cast(PoolIds::FAULT_BYTE), this); }; -} // namespace Max31865Definitions +} // namespace MAX31865 + +namespace EiveMax31855 { + +static constexpr float RTD_RREF_PT1000 = 4020.0; //!< Ohm +static constexpr uint8_t NUM_RTDS = 16; + +enum RtdCommands : DeviceCommandId_t { + ON = 0, + EXCHANGE_SET_ID = MAX31865::REQUEST_RTD, + ACTIVE = 2, + LOW_THRESHOLD = 3, + HIGH_TRESHOLD = 4, + OFF = 5, + CFG = 6, + NUM_CMDS +}; + +class ReadOutStruct : public SerialLinkedListAdapter { + public: + ReadOutStruct() { setLinks(); } + ReadOutStruct(bool active, uint32_t spiErrCnt, bool faultBitSet, uint8_t faultVal, + uint16_t rtdVal) + : active(active), + adcCode(rtdVal), + faultBitSet(faultBitSet), + faultValue(faultVal), + spiErrorCount(spiErrCnt) { + setLinks(); + } + + //! RTD was set on and is configured, but is not periodically polled + SerializeElement configured = false; + //! RTD is active and polled periodically + SerializeElement active = false; + SerializeElement adcCode = 0; + SerializeElement faultBitSet = false; + SerializeElement faultValue = 0; + SerializeElement spiErrorCount = 0; + + private: + void setLinks() { + setStart(&configured); + configured.setNext(&active); + active.setNext(&adcCode); + adcCode.setNext(&faultBitSet); + faultBitSet.setNext(&faultValue); + faultValue.setNext(&spiErrorCount); + }; +}; + +}; // namespace EiveMax31855 #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MAX13865DEFINITIONS_H_ */ diff --git a/mission/memory/SdCardMountedIF.h b/mission/memory/SdCardMountedIF.h index ff6aace3..853c7e8d 100644 --- a/mission/memory/SdCardMountedIF.h +++ b/mission/memory/SdCardMountedIF.h @@ -8,9 +8,11 @@ class SdCardMountedIF { public: virtual ~SdCardMountedIF(){}; - virtual std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE) = 0; + virtual std::string getCurrentMountPrefix() const = 0; virtual bool isSdCardMounted(sd::SdCard sdCard) = 0; - virtual ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const = 0; + virtual sd::SdCard getPreferredSdCard() const = 0; + virtual void setActiveSdCard(sd::SdCard sdCard) = 0; + virtual sd::SdCard getActiveSdCard() const = 0; private: }; diff --git a/mission/system/TcsBoardAssembly.cpp b/mission/system/TcsBoardAssembly.cpp index 7655603b..f973335e 100644 --- a/mission/system/TcsBoardAssembly.cpp +++ b/mission/system/TcsBoardAssembly.cpp @@ -10,7 +10,7 @@ TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, object_id_t parentId, eventQueue = QueueFactory::instance()->createMessageQueue(24); ModeListEntry entry; for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - entry.setObject(helper.rtdIds[idx]); + entry.setObject(helper.rtdInfos[idx].first); entry.setMode(MODE_OFF); entry.setSubmode(SUBMODE_NONE); entry.setInheritSubmode(false); @@ -56,7 +56,7 @@ ReturnValue_t TcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ int devsInWrongMode = 0; try { for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - if (childrenMap.at(helper.rtdIds[idx]).mode != wantedMode) { + if (childrenMap.at(helper.rtdInfos[idx].first).mode != wantedMode) { devsInWrongMode++; } } @@ -92,8 +92,8 @@ ReturnValue_t TcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t su ReturnValue_t TcsBoardAssembly::initialize() { ReturnValue_t result = RETURN_OK; - for (const auto& obj : helper.rtdIds) { - result = registerChild(obj); + for (const auto& obj : helper.rtdInfos) { + result = registerChild(obj.first); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -125,8 +125,8 @@ ReturnValue_t TcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s object_id_t objId = 0; try { for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - devMode = childrenMap.at(helper.rtdIds[idx]).mode; - objId = helper.rtdIds[idx]; + devMode = childrenMap.at(helper.rtdInfos[idx].first).mode; + objId = helper.rtdInfos[idx].first; if (mode == devMode) { modeTable[idx].setMode(mode); } else if (mode == DeviceHandlerIF::MODE_NORMAL) { diff --git a/mission/system/TcsBoardAssembly.h b/mission/system/TcsBoardAssembly.h index c23fbd7c..10b451b2 100644 --- a/mission/system/TcsBoardAssembly.h +++ b/mission/system/TcsBoardAssembly.h @@ -6,9 +6,10 @@ #include struct TcsBoardHelper { - TcsBoardHelper(std::array rtdIds) : rtdIds(rtdIds) {} + TcsBoardHelper(std::array, 16> rtdInfos) + : rtdInfos(std::move(rtdInfos)) {} - std::array rtdIds = {}; + std::array, 16> rtdInfos = {}; }; class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF { diff --git a/mission/utility/ProgressPrinter.cpp b/mission/utility/ProgressPrinter.cpp index 50e2d14b..124ae395 100644 --- a/mission/utility/ProgressPrinter.cpp +++ b/mission/utility/ProgressPrinter.cpp @@ -1,5 +1,6 @@ #include "ProgressPrinter.h" +#include #include #include "fsfw/serviceinterface/ServiceInterfaceStream.h" @@ -16,4 +17,9 @@ void ProgressPrinter::print(uint32_t currentStep) { << std::endl; nextProgressPrint += percentageResolution; } + if (nextProgressPrint - progressInPercent < 0) { + nextProgressPrint = + (std::floor(progressInPercent / percentageResolution) * percentageResolution) + + percentageResolution; + } } diff --git a/scripts/q7s-cp.py b/scripts/q7s-cp.py index a189e3e6..d0543b45 100755 --- a/scripts/q7s-cp.py +++ b/scripts/q7s-cp.py @@ -27,7 +27,7 @@ def prompt_ssh_key_removal(): print("Invalid port detected") else: break - cmd = f'ssh-keygen -f "${{HOME}}/.ssh/known_hosts" -R "[localhost]:${port}"' + cmd = f'ssh-keygen -f "$HOME/.ssh/known_hosts" -R "[localhost]:{port}"' print(f"Removing problematic SSH key with command {cmd}..") os.system(cmd) diff --git a/tmtc b/tmtc index 480e0f07..ef349856 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 480e0f07e03edeb55a3d6e3d629e7601b6bf90a2 +Subproject commit ef349856d614be7a408ffadf0c27c677d8be3157