diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index d308420c..751aedee 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -117,20 +117,28 @@ void initmission::initTasks() { #if OBSW_ADD_ACS_HANDLERS == 1 PeriodicTaskIF* acsTask = factory->createPeriodicTask( - "ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + "ACS_CTRL", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); result = acsTask->addComponent(objects::GPS_CONTROLLER); if (result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER); + initmission::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER); } - result = acsTask->addComponent(objects::ACS_BOARD_ASS); + +#endif /* OBSW_ADD_ACS_HANDLERS */ + + PeriodicTaskIF* sysTask = factory->createPeriodicTask( + "SYS_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + result = sysTask->addComponent(objects::ACS_BOARD_ASS); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("ACS_ASS", objects::ACS_BOARD_ASS); } - result = acsTask->addComponent(objects::SUS_BOARD_ASS); + result = sysTask->addComponent(objects::SUS_BOARD_ASS); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("SUS_ASS", objects::SUS_BOARD_ASS); } -#endif /* OBSW_ADD_ACS_HANDLERS */ + result = sysTask->addComponent(objects::TCS_BOARD_ASS); + if (result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TCS_BOARD_ASS", objects::TCS_BOARD_ASS); + } #if BOARD_TE0720 == 0 // FS task, task interval does not matter because it runs in permanent loop, priority low @@ -219,6 +227,7 @@ void initmission::initTasks() { #if OBSW_ADD_ACS_HANDLERS == 1 acsTask->startTask(); #endif + sysTask->startTask(); sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 2a82a22f..e74536c5 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include "OBSWConfig.h" #include "bsp_q7s/boardtest/Q7STestTask.h" @@ -150,7 +152,7 @@ void ObjectFactory::produce(void* args) { #if OBSW_ADD_SYRLINKS == 1 createSyrlinksComponents(); #endif /* OBSW_ADD_SYRLINKS == 1 */ - createRtdComponents(gpioComIF); + createRtdComponents(gpioComIF, pwrSwitcher); #if OBSW_ADD_MGT == 1 I2cCookie* imtqI2cCookie = @@ -374,95 +376,84 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI #if OBSW_ADD_SUN_SENSORS == 1 SpiCookie* spiCookie = new SpiCookie(addresses::SUS_0, gpioIds::CS_SUS_0, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[0] = new SusHandler(objects::SUS_0, 0, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_0); susHandlers[0]->setParent(objects::SUS_BOARD_ASS); susHandlers[0]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_1, gpioIds::CS_SUS_1, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_1, gpioIds::CS_SUS_1, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[1] = new SusHandler(objects::SUS_1, 1, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_1); susHandlers[1]->setParent(objects::SUS_BOARD_ASS); susHandlers[1]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_2, gpioIds::CS_SUS_2, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_2, gpioIds::CS_SUS_2, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[2] = new SusHandler(objects::SUS_2, 2, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_2); susHandlers[2]->setParent(objects::SUS_BOARD_ASS); susHandlers[2]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_3, gpioIds::CS_SUS_3, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_3, gpioIds::CS_SUS_3, std::string(q7s::SPI_DEFAULT_DEV), + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[3] = new SusHandler(objects::SUS_3, 3, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_3); susHandlers[3]->setParent(objects::SUS_BOARD_ASS); susHandlers[3]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_4, gpioIds::CS_SUS_4, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_4, gpioIds::CS_SUS_4, std::string(q7s::SPI_DEFAULT_DEV), + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[4] = new SusHandler(objects::SUS_4, 4, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_4); susHandlers[4]->setParent(objects::SUS_BOARD_ASS); susHandlers[4]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_5, gpioIds::CS_SUS_5, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_5, gpioIds::CS_SUS_5, std::string(q7s::SPI_DEFAULT_DEV), + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[5] = new SusHandler(objects::SUS_5, 5, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_5); susHandlers[5]->setParent(objects::SUS_BOARD_ASS); susHandlers[5]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_6, gpioIds::CS_SUS_6, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_6, gpioIds::CS_SUS_6, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[6] = new SusHandler(objects::SUS_6, 6, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_6); susHandlers[6]->setParent(objects::SUS_BOARD_ASS); susHandlers[6]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_7, gpioIds::CS_SUS_7, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_7, gpioIds::CS_SUS_7, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[7] = new SusHandler(objects::SUS_7, 7, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_7); susHandlers[7]->setParent(objects::SUS_BOARD_ASS); susHandlers[7]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_8, gpioIds::CS_SUS_8, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_8, gpioIds::CS_SUS_8, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[8] = new SusHandler(objects::SUS_8, 8, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_8); susHandlers[8]->setParent(objects::SUS_BOARD_ASS); susHandlers[8]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_9, gpioIds::CS_SUS_9, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_9, gpioIds::CS_SUS_9, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[9] = new SusHandler(objects::SUS_9, 9, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_9); susHandlers[9]->setParent(objects::SUS_BOARD_ASS); susHandlers[9]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_10, gpioIds::CS_SUS_10, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_10, gpioIds::CS_SUS_10, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[10] = new SusHandler(objects::SUS_10, 10, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_10); susHandlers[10]->setParent(objects::SUS_BOARD_ASS); susHandlers[10]->setCustomFdir(fdir); - spiCookie = - new SpiCookie(addresses::SUS_11, gpioIds::CS_SUS_11, q7s::SPI_DEFAULT_DEV, SUS::MAX_CMD_SIZE, - spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_11, gpioIds::CS_SUS_11, q7s::SPI_DEFAULT_DEV, + SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[11] = new SusHandler(objects::SUS_11, 11, objects::SPI_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_11); susHandlers[11]->setParent(objects::SUS_BOARD_ASS); @@ -835,7 +826,7 @@ void ObjectFactory::createSyrlinksComponents() { new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF, syrlinksUartCookie); } -void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF) { +void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher) { using namespace gpio; GpioCookie* rtdGpioCookie = new GpioCookie; @@ -890,142 +881,58 @@ void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF) { gpioComIF->addGpios(rtdGpioCookie); + static constexpr uint8_t NUMBER_RTDS = 16; #if OBSW_ADD_RTD_DEVICES == 1 - SpiCookie* spiRtdIc0 = - new SpiCookie(addresses::RTD_IC_3, gpioIds::RTD_IC_3, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc1 = - new SpiCookie(addresses::RTD_IC_4, gpioIds::RTD_IC_4, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc2 = - new SpiCookie(addresses::RTD_IC_5, gpioIds::RTD_IC_5, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc3 = - new SpiCookie(addresses::RTD_IC_6, gpioIds::RTD_IC_6, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc4 = - new SpiCookie(addresses::RTD_IC_7, gpioIds::RTD_IC_7, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc5 = - new SpiCookie(addresses::RTD_IC_8, gpioIds::RTD_IC_8, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc6 = - new SpiCookie(addresses::RTD_IC_9, gpioIds::RTD_IC_9, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc7 = - new SpiCookie(addresses::RTD_IC_10, gpioIds::RTD_IC_10, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc8 = - new SpiCookie(addresses::RTD_IC_11, gpioIds::RTD_IC_11, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc9 = - new SpiCookie(addresses::RTD_IC_12, gpioIds::RTD_IC_12, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc10 = - new SpiCookie(addresses::RTD_IC_13, gpioIds::RTD_IC_13, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc11 = - new SpiCookie(addresses::RTD_IC_14, gpioIds::RTD_IC_14, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc12 = - new SpiCookie(addresses::RTD_IC_15, gpioIds::RTD_IC_15, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc13 = - new SpiCookie(addresses::RTD_IC_16, gpioIds::RTD_IC_16, std::string(q7s::SPI_DEFAULT_DEV), - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc14 = - new SpiCookie(addresses::RTD_IC_17, gpioIds::RTD_IC_17, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - SpiCookie* spiRtdIc15 = - new SpiCookie(addresses::RTD_IC_18, gpioIds::RTD_IC_18, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - - Max31865PT1000Handler* rtdIc0 = - new Max31865PT1000Handler(objects::RTD_IC_3, objects::SPI_COM_IF, spiRtdIc0); - Max31865PT1000Handler* rtdIc1 = - new Max31865PT1000Handler(objects::RTD_IC_4, objects::SPI_COM_IF, spiRtdIc1); - Max31865PT1000Handler* rtdIc2 = - new Max31865PT1000Handler(objects::RTD_IC_5, objects::SPI_COM_IF, spiRtdIc2); - Max31865PT1000Handler* rtdIc3 = - new Max31865PT1000Handler(objects::RTD_IC_6, objects::SPI_COM_IF, spiRtdIc3); - Max31865PT1000Handler* rtdIc4 = - new Max31865PT1000Handler(objects::RTD_IC_7, objects::SPI_COM_IF, spiRtdIc4); - Max31865PT1000Handler* rtdIc5 = - new Max31865PT1000Handler(objects::RTD_IC_8, objects::SPI_COM_IF, spiRtdIc5); - Max31865PT1000Handler* rtdIc6 = - new Max31865PT1000Handler(objects::RTD_IC_9, objects::SPI_COM_IF, spiRtdIc6); - Max31865PT1000Handler* rtdIc7 = - new Max31865PT1000Handler(objects::RTD_IC_10, objects::SPI_COM_IF, spiRtdIc7); - Max31865PT1000Handler* rtdIc8 = - new Max31865PT1000Handler(objects::RTD_IC_11, objects::SPI_COM_IF, spiRtdIc8); - Max31865PT1000Handler* rtdIc9 = - new Max31865PT1000Handler(objects::RTD_IC_12, objects::SPI_COM_IF, spiRtdIc9); - Max31865PT1000Handler* rtdIc10 = - new Max31865PT1000Handler(objects::RTD_IC_13, objects::SPI_COM_IF, spiRtdIc10); - Max31865PT1000Handler* rtdIc11 = - new Max31865PT1000Handler(objects::RTD_IC_14, objects::SPI_COM_IF, spiRtdIc11); - Max31865PT1000Handler* rtdIc12 = - new Max31865PT1000Handler(objects::RTD_IC_15, objects::SPI_COM_IF, spiRtdIc12); - Max31865PT1000Handler* rtdIc13 = - new Max31865PT1000Handler(objects::RTD_IC_16, objects::SPI_COM_IF, spiRtdIc13); - Max31865PT1000Handler* rtdIc14 = - new Max31865PT1000Handler(objects::RTD_IC_17, objects::SPI_COM_IF, spiRtdIc14); - Max31865PT1000Handler* rtdIc15 = - new Max31865PT1000Handler(objects::RTD_IC_18, objects::SPI_COM_IF, spiRtdIc15); + std::array, NUMBER_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}, + {addresses::RTD_IC_6, gpioIds::RTD_IC_6}, + {addresses::RTD_IC_7, gpioIds::RTD_IC_7}, + {addresses::RTD_IC_8, gpioIds::RTD_IC_8}, + {addresses::RTD_IC_9, gpioIds::RTD_IC_9}, + {addresses::RTD_IC_10, gpioIds::RTD_IC_10}, + {addresses::RTD_IC_11, gpioIds::RTD_IC_11}, + {addresses::RTD_IC_12, gpioIds::RTD_IC_12}, + {addresses::RTD_IC_13, gpioIds::RTD_IC_13}, + {addresses::RTD_IC_14, gpioIds::RTD_IC_14}, + {addresses::RTD_IC_15, gpioIds::RTD_IC_15}, + {addresses::RTD_IC_16, gpioIds::RTD_IC_16}, + {addresses::RTD_IC_17, gpioIds::RTD_IC_17}, + {addresses::RTD_IC_18, gpioIds::RTD_IC_18}, + }}; + std::array rtdIds = { + objects::RTD_IC_3, objects::RTD_IC_4, objects::RTD_IC_5, objects::RTD_IC_6, + objects::RTD_IC_7, objects::RTD_IC_8, objects::RTD_IC_9, objects::RTD_IC_10, + objects::RTD_IC_11, objects::RTD_IC_12, objects::RTD_IC_13, objects::RTD_IC_14, + objects::RTD_IC_15, objects::RTD_IC_16, objects::RTD_IC_17, objects::RTD_IC_18}; + 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, q7s::SPI_DEFAULT_DEV, + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); + rtds[idx] = new Max31865PT1000Handler(rtdIds[idx], objects::SPI_COM_IF, rtdCookies[idx]); + rtds[idx]->setParent(objects::TCS_BOARD_ASS); + rtdFdir = new RtdFdir(rtdIds[idx]); + rtds[idx]->setCustomFdir(rtdFdir); + } #if OBSW_TEST_RTD == 1 - rtdIc0->setStartUpImmediately(); - rtdIc1->setStartUpImmediately(); - rtdIc2->setStartUpImmediately(); - rtdIc3->setStartUpImmediately(); - rtdIc4->setStartUpImmediately(); - rtdIc5->setStartUpImmediately(); - rtdIc6->setStartUpImmediately(); - rtdIc7->setStartUpImmediately(); - rtdIc8->setStartUpImmediately(); - rtdIc9->setStartUpImmediately(); - rtdIc10->setStartUpImmediately(); - rtdIc11->setStartUpImmediately(); - rtdIc12->setStartUpImmediately(); - rtdIc13->setStartUpImmediately(); - rtdIc14->setStartUpImmediately(); - rtdIc15->setStartUpImmediately(); - - rtdIc0->setInstantNormal(true); - rtdIc1->setInstantNormal(true); - rtdIc2->setInstantNormal(true); - rtdIc3->setInstantNormal(true); - rtdIc4->setInstantNormal(true); - rtdIc5->setInstantNormal(true); - rtdIc6->setInstantNormal(true); - rtdIc7->setInstantNormal(true); - rtdIc8->setInstantNormal(true); - rtdIc9->setInstantNormal(true); - rtdIc10->setInstantNormal(true); - rtdIc11->setInstantNormal(true); - rtdIc12->setInstantNormal(true); - rtdIc13->setInstantNormal(true); - rtdIc14->setInstantNormal(true); - rtdIc15->setInstantNormal(true); -#endif - - static_cast(rtdIc0); - static_cast(rtdIc1); - static_cast(rtdIc2); - static_cast(rtdIc3); - static_cast(rtdIc4); - static_cast(rtdIc5); - static_cast(rtdIc6); - static_cast(rtdIc7); - static_cast(rtdIc8); - static_cast(rtdIc9); - static_cast(rtdIc10); - static_cast(rtdIc11); - static_cast(rtdIc12); - static_cast(rtdIc13); - static_cast(rtdIc14); - static_cast(rtdIc15); -#endif + for (auto& rtd : rtds) { + if (rtd != nullptr) { + rtd->setStartUpImmediately(); + rtd->setInstantNormal(true); + } + } +#endif // OBSW_TEST_RTD == 1 + TcsBoardHelper helper(rtdIds); + TcsBoardAssembly* tcsBoardAss = + new TcsBoardAssembly(objects::TCS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, + pcduSwitches::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); + static_cast(tcsBoardAss); +#endif // OBSW_ADD_RTD_DEVICES == 1 } void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) { diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index a3ee6a7a..ff88db8e 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -25,7 +25,7 @@ void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF, void createHeaterComponents(); void createSolarArrayDeploymentComponents(); void createSyrlinksComponents(); -void createRtdComponents(LinuxLibgpioIF* gpioComIF); +void createRtdComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF); void createCcsdsComponents(LinuxLibgpioIF* gpioComIF); void createTestComponents(LinuxLibgpioIF* gpioComIF); diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 1743dcf7..2e7c8411 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -94,7 +94,8 @@ enum commonObjects: uint32_t { // 0x73 ('s') for assemblies and system/subsystem components ACS_BOARD_ASS = 0x73000001, - SUS_BOARD_ASS = 0x73000002 + SUS_BOARD_ASS = 0x73000002, + TCS_BOARD_ASS = 0x73000003 }; } diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 0e64e634..77a3a810 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -22,6 +22,7 @@ enum: uint8_t { PL_PCDU_HANDLER = 121, ACS_BOARD_ASS = 122, SUS_BOARD_ASS = 123, + TCS_BOARD_ASS = 124, COMMON_SUBSYSTEM_ID_END }; } diff --git a/common/config/devConf.h b/common/config/devConf.h index 8a35a0fa..73252e35 100644 --- a/common/config/devConf.h +++ b/common/config/devConf.h @@ -28,6 +28,7 @@ static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3; * the decoder and buffer circuits. Thus frequency is here defined to 1 MHz. */ static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000; +static constexpr spi::SpiModes SUS_MAX_1227_MODE = spi::SpiModes::MODE_3; static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000; static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3; diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 17a6b2ea..53d6d6aa 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -161,6 +161,7 @@ 12301;0x300d;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;;mission/system/SusAssembly.h 12302;0x300e;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;;mission/system/SusAssembly.h 12303;0x300f;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/SusAssembly.h +12400;0x3070;CHILDREN_LOST_MODE;MEDIUM;;mission/system/TcsBoardAssembly.h 13600;0x3520;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h 13601;0x3521;REBOOT_SW;MEDIUM; Software reboot occured. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h 13602;0x3522;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 63116d0f..9f8ce56a 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -109,6 +109,7 @@ 0x54694269;TEST_TASK 0x73000001;ACS_BOARD_ASS 0x73000002;SUS_BOARD_ASS +0x73000003;TCS_BOARD_ASS 0x73000100;TM_FUNNEL 0x73500000;CCSDS_IP_CORE_BRIDGE 0xFFFFFFFF;NO_OBJECT diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 93802bbf..9ac5c923 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 167 translations. + * @brief Auto-generated event translation file. Contains 168 translations. * @details - * Generated on: 2022-03-22 10:19:12 + * Generated on: 2022-03-22 20:43:04 */ #include "translateEvents.h" @@ -164,6 +164,7 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; const char *REBOOT_SW_STRING = "REBOOT_SW"; const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; @@ -489,6 +490,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12203): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12400): + return CHILDREN_LOST_MODE_STRING; case (13600): return ALLOC_FAILURE_STRING; case (13601): diff --git a/generators/gen.py b/generators/gen.py index 3d6c1038..f79e7226 100755 --- a/generators/gen.py +++ b/generators/gen.py @@ -31,7 +31,11 @@ def main(): LOGGER.info("Generating returnvalue data") time.sleep(0.05) parse_returnvalues() - pass + elif args.type == "all": + LOGGER.info("Generating all data") + parse_objects() + parse_events() + parse_returnvalues() if __name__ == "__main__": diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 95f9cae1..272de238 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 114 translations. - * Generated on: 2022-03-22 10:13:27 + * Contains 115 translations. + * Generated on: 2022-03-22 20:43:04 */ #include "translateObjects.h" @@ -117,6 +117,7 @@ const char *LIBGPIOD_TEST_STRING = "LIBGPIOD_TEST"; const char *TEST_TASK_STRING = "TEST_TASK"; const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS"; const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS"; +const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -345,6 +346,8 @@ const char *translateObject(object_id_t object) { return ACS_BOARD_ASS_STRING; case 0x73000002: return SUS_BOARD_ASS_STRING; + case 0x73000003: + return TCS_BOARD_ASS_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73500000: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 93802bbf..9ac5c923 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 167 translations. + * @brief Auto-generated event translation file. Contains 168 translations. * @details - * Generated on: 2022-03-22 10:19:12 + * Generated on: 2022-03-22 20:43:04 */ #include "translateEvents.h" @@ -164,6 +164,7 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; const char *REBOOT_SW_STRING = "REBOOT_SW"; const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; @@ -489,6 +490,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12203): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12400): + return CHILDREN_LOST_MODE_STRING; case (13600): return ALLOC_FAILURE_STRING; case (13601): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 95f9cae1..272de238 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 114 translations. - * Generated on: 2022-03-22 10:13:27 + * Contains 115 translations. + * Generated on: 2022-03-22 20:43:04 */ #include "translateObjects.h" @@ -117,6 +117,7 @@ const char *LIBGPIOD_TEST_STRING = "LIBGPIOD_TEST"; const char *TEST_TASK_STRING = "TEST_TASK"; const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS"; const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS"; +const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -345,6 +346,8 @@ const char *translateObject(object_id_t object) { return ACS_BOARD_ASS_STRING; case 0x73000002: return SUS_BOARD_ASS_STRING; + case 0x73000003: + return TCS_BOARD_ASS_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73500000: diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 809e669b..21631134 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -87,6 +87,7 @@ void Max31865PT1000Handler::doStartUp() { void Max31865PT1000Handler::doShutDown() { commandExecuted = false; + warningSwitch = true; setMode(_MODE_POWER_DOWN); } @@ -319,14 +320,17 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, switch (id) { case (Max31865Definitions::REQUEST_CONFIG): { if (packet[1] != DEFAULT_CONFIG) { + if (warningSwitch) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - // it propably would be better if we at least try one restart.. - sif::error << "Max31865PT1000Handler: 0x" << std::hex << this->getObjectId() - << ": Invalid configuration reply" << std::endl; + // it propably would be better if we at least try one restart.. + sif::warning << "Max31865PT1000Handler: 0x" << std::hex << this->getObjectId() + << ": Invalid configuration reply" << std::endl; #else - sif::printError("Max31865PT1000Handler: %04x: Invalid configuration reply!\n", - this->getObjectId()); + sif::printWarning("Max31865PT1000Handler: %04x: Invalid configuration reply!\n", + this->getObjectId()); #endif + warningSwitch = false; + } return HasReturnvaluesIF::RETURN_OK; } // set to true for invalid configs too for now. @@ -505,10 +509,6 @@ ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches, return DeviceHandlerBase::NO_SWITCH; } -void Max31865PT1000Handler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { - DeviceHandlerBase::doTransition(modeFrom, subModeFrom); -} - ReturnValue_t Max31865PT1000Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { localDataPoolMap.emplace(Max31865Definitions::PoolIds::RTD_VALUE, new PoolEntry({0})); diff --git a/mission/devices/Max31865PT1000Handler.h b/mission/devices/Max31865PT1000Handler.h index 44d7a2e7..1be4c323 100644 --- a/mission/devices/Max31865PT1000Handler.h +++ b/mission/devices/Max31865PT1000Handler.h @@ -74,8 +74,6 @@ class Max31865PT1000Handler : public DeviceHandlerBase { uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override; - void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; - void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0, uint32_t parameter = 0) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, @@ -84,7 +82,8 @@ class Max31865PT1000Handler : public DeviceHandlerBase { private: uint8_t switchId = 0; - bool instantNormal = true; + bool instantNormal = false; + bool warningSwitch = true; enum class InternalState { NONE, diff --git a/mission/system/CMakeLists.txt b/mission/system/CMakeLists.txt index f29f5336..27637339 100644 --- a/mission/system/CMakeLists.txt +++ b/mission/system/CMakeLists.txt @@ -2,13 +2,14 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE AcsBoardAssembly.cpp SusAssembly.cpp AcsSubsystem.cpp - TcsSubsystem.cpp EiveSystem.cpp ComSubsystem.cpp - TcsSubsystem.cpp DualLanePowerStateMachine.cpp + PowerStateMachineBase.cpp DualLaneAssemblyBase.cpp + TcsBoardAssembly.cpp AcsBoardFdir.cpp SusFdir.cpp + RtdFdir.cpp ) \ No newline at end of file diff --git a/mission/system/DualLaneAssemblyBase.cpp b/mission/system/DualLaneAssemblyBase.cpp index 3460d44f..fbd69d8f 100644 --- a/mission/system/DualLaneAssemblyBase.cpp +++ b/mission/system/DualLaneAssemblyBase.cpp @@ -63,8 +63,8 @@ bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) { } ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() { - using namespace duallane; - OpCodes opCode = pwrStateMachine.powerStateMachine(); + using namespace power; + OpCodes opCode = pwrStateMachine.fsm(); if (customRecoveryStates == RecoveryCustomStates::IDLE) { if (opCode == OpCodes::NONE) { return RETURN_OK; @@ -163,7 +163,7 @@ void DualLaneAssemblyBase::handleModeTransitionFailed(ReturnValue_t result) { } bool DualLaneAssemblyBase::checkAndHandleRecovery() { - using namespace duallane; + using namespace power; OpCodes opCode = OpCodes::NONE; if (recoveryState == RECOVERY_IDLE) { return AssemblyBase::checkAndHandleRecovery(); @@ -173,14 +173,14 @@ bool DualLaneAssemblyBase::checkAndHandleRecovery() { customRecoveryStates = RecoveryCustomStates::POWER_SWITCHING_OFF; } if (customRecoveryStates == POWER_SWITCHING_OFF) { - opCode = pwrStateMachine.powerStateMachine(); + opCode = pwrStateMachine.fsm(); if (opCode == OpCodes::TO_OFF_DONE or opCode == OpCodes::TIMEOUT_OCCURED) { customRecoveryStates = RecoveryCustomStates::POWER_SWITCHING_ON; pwrStateMachine.start(targetMode, targetSubmode); } } if (customRecoveryStates == POWER_SWITCHING_ON) { - opCode = pwrStateMachine.powerStateMachine(); + opCode = pwrStateMachine.fsm(); if (opCode == OpCodes::TO_NOT_OFF_DONE or opCode == OpCodes::TIMEOUT_OCCURED) { customRecoveryStates = RecoveryCustomStates::DONE; } diff --git a/mission/system/DualLaneAssemblyBase.h b/mission/system/DualLaneAssemblyBase.h index f62c521d..e0996848 100644 --- a/mission/system/DualLaneAssemblyBase.h +++ b/mission/system/DualLaneAssemblyBase.h @@ -69,7 +69,7 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF { virtual void startTransition(Mode_t mode, Submode_t submode) override; virtual void handleChildrenLostMode(ReturnValue_t result) override; virtual void handleModeTransitionFailed(ReturnValue_t result) override; - virtual void handleModeReached(); + virtual void handleModeReached() override; MessageQueueId_t getEventReceptionQueue() override; diff --git a/mission/system/DualLanePowerStateMachine.cpp b/mission/system/DualLanePowerStateMachine.cpp index e69f0310..666e1d1e 100644 --- a/mission/system/DualLanePowerStateMachine.cpp +++ b/mission/system/DualLanePowerStateMachine.cpp @@ -7,37 +7,16 @@ DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches swit pcduSwitches::Switches switchB, PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout) - : SWITCH_A(switchA), SWITCH_B(switchB), pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {} + : PowerStateMachineBase(pwrSwitcher, checkTimeout), SWITCH_A(switchA), SWITCH_B(switchB) {} -void DualLanePowerStateMachine::setCheckTimeout(dur_millis_t timeout) { - checkTimeout.setTimeout(timeout); -} - -void DualLanePowerStateMachine::start(Mode_t mode, Submode_t submode) { - reset(); - checkTimeout.resetTimer(); - targetMode = mode; - targetSubmode = submode; - state = duallane::PwrStates::SWITCHING_POWER; -} - -duallane::PwrStates DualLanePowerStateMachine::getState() const { return state; } - -bool DualLanePowerStateMachine::active() { - if (state == duallane::PwrStates::IDLE or state == duallane::PwrStates::MODE_COMMANDING) { - return false; - } - return true; -} - -duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { +power::OpCodes DualLanePowerStateMachine::fsm() { using namespace duallane; ReturnValue_t switchStateA = RETURN_OK; ReturnValue_t switchStateB = RETURN_OK; - if (state == PwrStates::IDLE or state == PwrStates::MODE_COMMANDING) { + if (state == power::States::IDLE or state == power::States::MODE_COMMANDING) { return opResult; } - if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) { + if (state == power::States::SWITCHING_POWER or state == power::States::CHECKING_POWER) { switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); } else { @@ -45,8 +24,8 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { } if (targetMode == HasModesIF::MODE_OFF) { if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { - state = PwrStates::IDLE; - opResult = OpCodes::TO_OFF_DONE; + state = power::States::IDLE; + opResult = power::OpCodes::TO_OFF_DONE; return opResult; } } else { @@ -54,8 +33,8 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { case (A_SIDE): { if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { - state = PwrStates::MODE_COMMANDING; - opResult = OpCodes::TO_NOT_OFF_DONE; + state = power::States::MODE_COMMANDING; + opResult = power::OpCodes::TO_NOT_OFF_DONE; return opResult; } break; @@ -63,22 +42,22 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { case (B_SIDE): { if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = PwrStates::MODE_COMMANDING; - opResult = OpCodes::TO_NOT_OFF_DONE; + state = power::States::MODE_COMMANDING; + opResult = power::OpCodes::TO_NOT_OFF_DONE; return opResult; } break; } case (DUAL_MODE): { if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) { - state = PwrStates::MODE_COMMANDING; - opResult = OpCodes::TO_NOT_OFF_DONE; + state = power::States::MODE_COMMANDING; + opResult = power::OpCodes::TO_NOT_OFF_DONE; return opResult; } } } } - if (state == PwrStates::SWITCHING_POWER) { + if (state == power::States::SWITCHING_POWER) { if (targetMode == HasModesIF::MODE_OFF) { if (switchStateA != PowerSwitchIF::SWITCH_OFF) { pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF); @@ -121,20 +100,12 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { } } } - state = PwrStates::CHECKING_POWER; + state = power::States::CHECKING_POWER; } - if (state == PwrStates::CHECKING_POWER) { + if (state == power::States::CHECKING_POWER) { if (checkTimeout.hasTimedOut()) { - return OpCodes::TIMEOUT_OCCURED; + return power::OpCodes::TIMEOUT_OCCURED; } } return opResult; } - -void DualLanePowerStateMachine::reset() { - state = duallane::PwrStates::IDLE; - opResult = duallane::OpCodes::NONE; - targetMode = HasModesIF::MODE_OFF; - targetSubmode = 0; - checkTimeout.resetTimer(); -} diff --git a/mission/system/DualLanePowerStateMachine.h b/mission/system/DualLanePowerStateMachine.h index bf8679c4..e22e7ae4 100644 --- a/mission/system/DualLanePowerStateMachine.h +++ b/mission/system/DualLanePowerStateMachine.h @@ -3,32 +3,23 @@ #include #include +#include #include "definitions.h" class AssemblyBase; class PowerSwitchIF; -class DualLanePowerStateMachine : public HasReturnvaluesIF { +class DualLanePowerStateMachine : public PowerStateMachineBase { public: DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout = 5000); - void setCheckTimeout(dur_millis_t timeout); - void reset(); - void start(Mode_t mode, Submode_t submode); - bool active(); - duallane::PwrStates getState() const; - duallane::OpCodes powerStateMachine(); + power::OpCodes fsm() override; + const pcduSwitches::Switches SWITCH_A; const pcduSwitches::Switches SWITCH_B; private: - duallane::OpCodes opResult = duallane::OpCodes::NONE; - duallane::PwrStates state = duallane::PwrStates::IDLE; - PowerSwitchIF* pwrSwitcher = nullptr; - Mode_t targetMode = HasModesIF::MODE_OFF; - Submode_t targetSubmode = 0; - Countdown checkTimeout; }; #endif /* MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_ */ diff --git a/mission/system/PowerStateMachineBase.cpp b/mission/system/PowerStateMachineBase.cpp new file mode 100644 index 00000000..37bd91f2 --- /dev/null +++ b/mission/system/PowerStateMachineBase.cpp @@ -0,0 +1,33 @@ +#include "PowerStateMachineBase.h" + +PowerStateMachineBase::PowerStateMachineBase(PowerSwitchIF *pwrSwitcher, dur_millis_t checkTimeout) + : pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {} + +void PowerStateMachineBase::reset() { + state = power::States::IDLE; + opResult = power::OpCodes::NONE; + targetMode = HasModesIF::MODE_OFF; + targetSubmode = 0; + checkTimeout.resetTimer(); +} + +void PowerStateMachineBase::setCheckTimeout(dur_millis_t timeout) { + checkTimeout.setTimeout(timeout); +} + +void PowerStateMachineBase::start(Mode_t mode, Submode_t submode) { + reset(); + checkTimeout.resetTimer(); + targetMode = mode; + targetSubmode = submode; + state = power::States::SWITCHING_POWER; +} + +power::States PowerStateMachineBase::getState() const { return state; } + +bool PowerStateMachineBase::active() { + if (state == power::States::IDLE or state == power::States::MODE_COMMANDING) { + return false; + } + return true; +} diff --git a/mission/system/PowerStateMachineBase.h b/mission/system/PowerStateMachineBase.h new file mode 100644 index 00000000..3adeebb6 --- /dev/null +++ b/mission/system/PowerStateMachineBase.h @@ -0,0 +1,31 @@ +#ifndef MISSION_SYSTEM_POWERSTATEMACHINE_H_ +#define MISSION_SYSTEM_POWERSTATEMACHINE_H_ + +#include +#include +#include + +#include "definitions.h" + +class PowerStateMachineBase : public HasReturnvaluesIF { + public: + PowerStateMachineBase(PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout); + + virtual power::OpCodes fsm() = 0; + + void setCheckTimeout(dur_millis_t timeout); + void reset(); + void start(Mode_t mode, Submode_t submode); + bool active(); + power::States getState() const; + + protected: + power::OpCodes opResult = power::OpCodes::NONE; + power::States state = power::States::IDLE; + PowerSwitchIF* pwrSwitcher = nullptr; + Mode_t targetMode = HasModesIF::MODE_OFF; + Submode_t targetSubmode = 0; + Countdown checkTimeout; +}; + +#endif /* MISSION_SYSTEM_POWERSTATEMACHINE_H_ */ diff --git a/mission/system/RtdFdir.cpp b/mission/system/RtdFdir.cpp new file mode 100644 index 00000000..f4f9806e --- /dev/null +++ b/mission/system/RtdFdir.cpp @@ -0,0 +1,6 @@ +#include "RtdFdir.h" + +#include + +RtdFdir::RtdFdir(object_id_t sensorId) + : DeviceHandlerFailureIsolation(sensorId, objects::TCS_BOARD_ASS) {} diff --git a/mission/system/RtdFdir.h b/mission/system/RtdFdir.h new file mode 100644 index 00000000..1dedbb82 --- /dev/null +++ b/mission/system/RtdFdir.h @@ -0,0 +1,11 @@ +#ifndef MISSION_SYSTEM_RTDFDIR_H_ +#define MISSION_SYSTEM_RTDFDIR_H_ + +#include + +class RtdFdir : public DeviceHandlerFailureIsolation { + public: + RtdFdir(object_id_t sensorId); +}; + +#endif /* MISSION_SYSTEM_RTDFDIR_H_ */ diff --git a/mission/system/TcsBoardAssembly.cpp b/mission/system/TcsBoardAssembly.cpp new file mode 100644 index 00000000..f011c931 --- /dev/null +++ b/mission/system/TcsBoardAssembly.cpp @@ -0,0 +1,206 @@ +#include "TcsBoardAssembly.h" + +#include +#include + +TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, object_id_t parentId, + PowerSwitchIF* pwrSwitcher, power::Switch_t theSwitch, + TcsBoardHelper helper) + : AssemblyBase(objectId, parentId, 24), switcher(pwrSwitcher, theSwitch), helper(helper) { + eventQueue = QueueFactory::instance()->createMessageQueue(24); + ModeListEntry entry; + for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { + entry.setObject(helper.rtdIds[idx]); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + entry.setInheritSubmode(false); + modeTable.insert(entry); + } +} + +void TcsBoardAssembly::performChildOperation() { + auto state = switcher.getState(); + if (state != PowerSwitcher::WAIT_OFF and state != PowerSwitcher::WAIT_ON) { + AssemblyBase::performChildOperation(); + return; + } + switcher.doStateMachine(); + if (state == PowerSwitcher::WAIT_OFF and switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) { + // Indicator that a transition to off is finished + AssemblyBase::handleModeReached(); + } else if (state == PowerSwitcher::WAIT_ON and + switcher.getState() == PowerSwitcher::SWITCH_IS_ON) { + // Indicator that mode commanding can be performed now + AssemblyBase::startTransition(targetMode, targetSubmode); + // AssemblyBase::performChildOperation(); + } +} + +ReturnValue_t TcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) { + ReturnValue_t result = RETURN_OK; + // Initialize the mode table to ensure all devices are in a defined state + for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { + modeTable[idx].setMode(MODE_OFF); + modeTable[idx].setSubmode(SUBMODE_NONE); + } + if (recoveryState != RecoveryState::RECOVERY_STARTED) { + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + result = handleNormalOrOnModeCmd(mode, submode); + } + } + HybridIterator tableIter(modeTable.begin(), modeTable.end()); + executeTable(tableIter); + return result; +} + +ReturnValue_t TcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + int devsInWrongMode = 0; + try { + for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { + if (childrenMap.at(helper.rtdIds[idx]).mode != wantedMode) { + devsInWrongMode++; + } + } + } catch (const std::out_of_range& e) { + sif::error << "TcsBoardAssembly: Invalid children map: " << e.what() << std::endl; + } + if (devsInWrongMode >= 3) { + if (warningSwitch) { + sif::warning << "TcsBoardAssembly::checkChildrenStateOn: " << devsInWrongMode << " devices in" + << " wrong mode" << std::endl; + warningSwitch = false; + } + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + // TODO: Can't really do something other than power cycling if devices in wrong mode. + // Might attempt one power-cycle. In any case, trigger an event + if (devsInWrongMode > 0) { + if (warningSwitch) { + sif::warning << "TcsBoardAssembly::checkChildrenStateOn: " << devsInWrongMode << " devices in" + << " wrong mode" << std::endl; + warningSwitch = false; + } + } + return RETURN_OK; +} + +ReturnValue_t TcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if (mode == MODE_ON or mode == MODE_OFF or mode == DeviceHandlerIF::MODE_NORMAL) { + return RETURN_OK; + } + return HasModesIF::INVALID_MODE; +} + +ReturnValue_t TcsBoardAssembly::initialize() { + ReturnValue_t result = RETURN_OK; + for (const auto& obj : helper.rtdIds) { + result = registerChild(obj); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return SubsystemBase::initialize(); +} + +void TcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) { + if (mode != MODE_OFF) { + switcher.turnOn(true); + switcher.doStateMachine(); + if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) { + AssemblyBase::startTransition(mode, submode); + } else { + // Need to wait with mode commanding until power switcher is done + targetMode = mode; + targetSubmode = submode; + } + } else { + // Perform regular mode commanding first + AssemblyBase::startTransition(mode, submode); + } +} + +ReturnValue_t TcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) { + ReturnValue_t result = RETURN_OK; + bool needsSecondStep = false; + Mode_t devMode = 0; + 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]; + if (mode == devMode) { + modeTable[idx].setMode(mode); + } else if (mode == DeviceHandlerIF::MODE_NORMAL) { + if (isUseable(objId, devMode)) { + if (devMode == MODE_ON) { + modeTable[idx].setMode(mode); + modeTable[idx].setSubmode(SUBMODE_NONE); + } else { + modeTable[idx].setMode(MODE_ON); + modeTable[idx].setSubmode(SUBMODE_NONE); + if (internalState != STATE_SECOND_STEP) { + needsSecondStep = true; + } + } + } + } else if (mode == MODE_ON) { + if (isUseable(objId, devMode)) { + modeTable[idx].setMode(MODE_ON); + modeTable[idx].setSubmode(SUBMODE_NONE); + } + } + } + } catch (const std::out_of_range& e) { + sif::error << "TcsBoardAssembly: Invalid children map: " << e.what() << std::endl; + } + if (needsSecondStep) { + result = NEED_SECOND_STEP; + } + return result; +} + +bool TcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { + if (healthHelper.healthTable->isFaulty(object)) { + return false; + } + + // Check if device is already in target mode + if (childrenMap[object].mode == mode) { + return true; + } + + if (healthHelper.healthTable->isCommandable(object)) { + return true; + } + return false; +} + +MessageQueueId_t TcsBoardAssembly::getEventReceptionQueue() { return eventQueue->getId(); } + +void TcsBoardAssembly::handleModeReached() { + if (targetMode == MODE_OFF) { + switcher.turnOff(true); + switcher.doStateMachine(); + // Need to wait with call to AssemblyBase::handleModeReached until power switcher is done + if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) { + AssemblyBase::handleModeReached(); + } + } else { + AssemblyBase::handleModeReached(); + } +} + +void TcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { + // TODO: Maybe try a reboot once here? + triggerEvent(CHILDREN_LOST_MODE, result); + return; +} + +void TcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) { + if (targetMode == MODE_OFF) { + AssemblyBase::handleModeTransitionFailed(result); + } else { + // To avoid transitioning back to off + triggerEvent(MODE_TRANSITION_FAILED, result); + } +} diff --git a/mission/system/TcsBoardAssembly.h b/mission/system/TcsBoardAssembly.h new file mode 100644 index 00000000..cda78317 --- /dev/null +++ b/mission/system/TcsBoardAssembly.h @@ -0,0 +1,60 @@ +#ifndef MISSION_SYSTEM_TCSSUBSYSTEM_H_ +#define MISSION_SYSTEM_TCSSUBSYSTEM_H_ + +#include +#include +#include + +struct TcsBoardHelper { + TcsBoardHelper(std::array rtdIds) : rtdIds(rtdIds) {} + + std::array rtdIds = {}; +}; + +class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF { + public: + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_BOARD_ASS; + static constexpr Event CHILDREN_LOST_MODE = + event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); + + TcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, + power::Switch_t switcher, TcsBoardHelper helper); + + ReturnValue_t initialize() override; + + void performChildOperation() override; + + private: + static constexpr uint8_t NUMBER_RTDS = 16; + PowerSwitcher switcher; + bool warningSwitch = true; + TcsBoardHelper helper; + FixedArrayList modeTable; + MessageQueueIF* eventQueue = nullptr; + + ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); + /** + * Check whether it makes sense to send mode commands to the device + * @param object + * @param mode + * @return + */ + bool isUseable(object_id_t object, Mode_t mode); + + // ConfirmFailureIF implementation + MessageQueueId_t getEventReceptionQueue() override; + + // AssemblyBase implementation + ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; + ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + void startTransition(Mode_t mode, Submode_t submode) override; + void handleModeReached() override; + + // These two overrides prevent a transition of the whole assembly back to off just because + // some devices are not working + void handleChildrenLostMode(ReturnValue_t result) override; + void handleModeTransitionFailed(ReturnValue_t result) override; +}; + +#endif /* MISSION_SYSTEM_TCSSUBSYSTEM_H_ */ diff --git a/mission/system/TcsSubsystem.cpp b/mission/system/TcsSubsystem.cpp deleted file mode 100644 index 3ecfde2b..00000000 --- a/mission/system/TcsSubsystem.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "TcsSubsystem.h" diff --git a/mission/system/TcsSubsystem.h b/mission/system/TcsSubsystem.h deleted file mode 100644 index 24136f82..00000000 --- a/mission/system/TcsSubsystem.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MISSION_SYSTEM_TCSSUBSYSTEM_H_ -#define MISSION_SYSTEM_TCSSUBSYSTEM_H_ - -#include - -class TcsSubsystem : SubsystemBase {}; - -#endif /* MISSION_SYSTEM_TCSSUBSYSTEM_H_ */ diff --git a/mission/system/definitions.h b/mission/system/definitions.h index 8b22e1f4..aee127bb 100644 --- a/mission/system/definitions.h +++ b/mission/system/definitions.h @@ -3,10 +3,15 @@ #include +namespace power { + +enum class States { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING }; +enum class OpCodes { NONE, TO_OFF_DONE, TO_NOT_OFF_DONE, TIMEOUT_OCCURED }; + +} // namespace power + namespace duallane { -enum class PwrStates { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING }; -enum class OpCodes { NONE, TO_OFF_DONE, TO_NOT_OFF_DONE, TIMEOUT_OCCURED }; enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; } // namespace duallane