v1.10.0 #220
@ -159,23 +159,41 @@ find_package(Catch2 3)
|
||||
|
||||
#global compiler options need to be set before adding executables
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Wimplicit-fallthrough=1"
|
||||
"-Wno-unused-parameter"
|
||||
"-Wno-psabi"
|
||||
)
|
||||
# Remove unused sections.
|
||||
add_compile_options(
|
||||
"-ffunction-sections"
|
||||
"-fdata-sections"
|
||||
)
|
||||
add_compile_options(
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Wimplicit-fallthrough=1"
|
||||
"-Wno-unused-parameter"
|
||||
"-Wno-psabi"
|
||||
"-Wduplicated-cond" # check for duplicate conditions
|
||||
"-Wduplicated-branches" # check for duplicate branches
|
||||
"-Wlogical-op" # Search for bitwise operations instead of logical
|
||||
"-Wnull-dereference" # Search for NULL dereference
|
||||
"-Wundef" # Warn if undefind marcos are used
|
||||
"-Wformat=2" # Format string problem detection
|
||||
"-Wformat-overflow=2" # Formatting issues in printf
|
||||
"-Wformat-truncation=2" # Formatting issues in printf
|
||||
"-Wformat-security" # Search for dangerous printf operations
|
||||
"-Wstrict-overflow=3" # Warn if integer overflows might happen
|
||||
"-Warray-bounds=2" # Some array bounds violations will be found
|
||||
"-Wshift-overflow=2" # Search for bit left shift overflows (<c++14)
|
||||
"-Wcast-qual" # Warn if the constness is cast away
|
||||
"-Wstringop-overflow=4"
|
||||
# -Wstack-protector # Emits a few false positives for low level access
|
||||
# -Wconversion # Creates many false positives
|
||||
# -Warith-conversion # Use with Wconversion to find more implicit conversions
|
||||
# -fanalyzer # Should be used to look through problems
|
||||
)
|
||||
# Remove unused sections.
|
||||
add_compile_options(
|
||||
"-ffunction-sections"
|
||||
"-fdata-sections"
|
||||
)
|
||||
|
||||
# Removed unused sections.
|
||||
add_link_options(
|
||||
"-Wl,--gc-sections"
|
||||
)
|
||||
# Removed unused sections.
|
||||
add_link_options(
|
||||
"-Wl,--gc-sections"
|
||||
)
|
||||
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(COMPILER_FLAGS "/permissive-")
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
#define Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST 0
|
||||
|
||||
#ifndef Q7S_SIMPLE_MODE
|
||||
#define Q7S_SIMPLE_MODE 0
|
||||
#endif
|
||||
|
||||
namespace config {
|
||||
|
||||
static const uint32_t SD_CARD_ACCESS_MUTEX_TIMEOUT = 50;
|
||||
|
@ -116,12 +116,16 @@ void initmission::initTasks() {
|
||||
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
||||
|
||||
#if OBSW_ADD_ACS_HANDLERS == 1
|
||||
PeriodicTaskIF* acsCtrl = factory->createPeriodicTask(
|
||||
PeriodicTaskIF* acsTask = factory->createPeriodicTask(
|
||||
"ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc);
|
||||
result = acsCtrl->addComponent(objects::GPS_CONTROLLER);
|
||||
result = acsTask->addComponent(objects::GPS_CONTROLLER);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER);
|
||||
}
|
||||
result = acsTask->addComponent(objects::ACS_BOARD_ASS);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("ACS_ASS", objects::GPS_CONTROLLER);
|
||||
}
|
||||
#endif /* OBSW_ADD_ACS_HANDLERS */
|
||||
|
||||
#if BOARD_TE0720 == 0
|
||||
@ -209,7 +213,7 @@ void initmission::initTasks() {
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_ACS_HANDLERS == 1
|
||||
acsCtrl->startTask();
|
||||
acsTask->startTask();
|
||||
#endif
|
||||
|
||||
sif::info << "Tasks started.." << std::endl;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ObjectFactory.h"
|
||||
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <linux/obc/AxiPtmeConfig.h>
|
||||
#include <linux/obc/PapbVcInterface.h>
|
||||
#include <linux/obc/PdecHandler.h>
|
||||
@ -83,6 +84,7 @@
|
||||
#include "mission/devices/devicedefinitions/SusDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/payloadPcduDefinitions.h"
|
||||
#include "mission/system/AcsBoardAssembly.h"
|
||||
#include "mission/tmtc/CCSDSHandler.h"
|
||||
#include "mission/tmtc/VirtualChannel.h"
|
||||
#include "mission/utility/TmFunnel.h"
|
||||
@ -124,18 +126,19 @@ void ObjectFactory::produce(void* args) {
|
||||
UartComIF* uartComIF = nullptr;
|
||||
SpiComIF* spiComIF = nullptr;
|
||||
I2cComIF* i2cComIF = nullptr;
|
||||
PowerSwitchIF* pwrSwitcher = nullptr;
|
||||
createCommunicationInterfaces(&gpioComIF, &uartComIF, &spiComIF, &i2cComIF);
|
||||
createTmpComponents();
|
||||
#if BOARD_TE0720 == 0
|
||||
new CoreController(objects::CORE_CONTROLLER);
|
||||
|
||||
gpioCallbacks::disableAllDecoder();
|
||||
createPcduComponents(gpioComIF);
|
||||
createPcduComponents(gpioComIF, &pwrSwitcher);
|
||||
createRadSensorComponent(gpioComIF);
|
||||
createSunSensorComponents(gpioComIF, spiComIF);
|
||||
|
||||
#if OBSW_ADD_ACS_BOARD == 1
|
||||
createAcsBoardComponents(gpioComIF, uartComIF);
|
||||
createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher);
|
||||
#endif
|
||||
|
||||
createHeaterComponents();
|
||||
@ -260,7 +263,7 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua
|
||||
#endif
|
||||
}
|
||||
|
||||
void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) {
|
||||
void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher) {
|
||||
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK);
|
||||
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1);
|
||||
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2);
|
||||
@ -275,7 +278,7 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) {
|
||||
new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie);
|
||||
pdu2handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF);
|
||||
ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie);
|
||||
new PCDUHandler(objects::PCDU_HANDLER, 50);
|
||||
auto pcduHandler = new PCDUHandler(objects::PCDU_HANDLER, 50);
|
||||
|
||||
/**
|
||||
* Setting PCDU devices to mode normal immediately after start up because PCDU is always
|
||||
@ -285,6 +288,9 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) {
|
||||
pdu1handler->setModeNormal();
|
||||
pdu2handler->setModeNormal();
|
||||
acuhandler->setModeNormal();
|
||||
if (pwrSwitcher != nullptr) {
|
||||
*pwrSwitcher = pcduHandler;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
|
||||
@ -453,6 +459,7 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI
|
||||
susHandler9->setToGoToNormalMode(true);
|
||||
susHandler10->setToGoToNormalMode(true);
|
||||
susHandler11->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_SUS == 1
|
||||
susHandler0->enablePeriodicPrintout(true, 3);
|
||||
susHandler1->enablePeriodicPrintout(true, 3);
|
||||
@ -467,12 +474,11 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI
|
||||
susHandler10->enablePeriodicPrintout(true, 3);
|
||||
susHandler11->enablePeriodicPrintout(true, 3);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* OBSW_ADD_SUN_SENSORS == 1 */
|
||||
}
|
||||
|
||||
void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF) {
|
||||
void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF,
|
||||
PowerSwitchIF* pwrSwitcher) {
|
||||
using namespace gpio;
|
||||
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
||||
|
||||
@ -579,40 +585,40 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
|
||||
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, spi::LIS3_TRANSITION_DELAY);
|
||||
static_cast<void>(mgmLis3Handler);
|
||||
#if OBSW_TEST_ACS == 1
|
||||
mgmLis3Handler->setStartUpImmediately();
|
||||
mgmLis3Handler->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
mgmLis3Handler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#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);
|
||||
auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF,
|
||||
spiCookie, spi::RM3100_TRANSITION_DELAY);
|
||||
static_cast<void>(mgmRm3100Handler);
|
||||
#if OBSW_TEST_ACS == 1
|
||||
mgmRm3100Handler->setStartUpImmediately();
|
||||
mgmRm3100Handler->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
mgmRm3100Handler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#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);
|
||||
auto mgmLis3Handler2 = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF,
|
||||
spiCookie, spi::LIS3_TRANSITION_DELAY);
|
||||
mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF,
|
||||
spiCookie, spi::LIS3_TRANSITION_DELAY);
|
||||
static_cast<void>(mgmLis3Handler);
|
||||
#if OBSW_TEST_ACS == 1
|
||||
mgmLis3Handler2->setStartUpImmediately();
|
||||
mgmLis3Handler2->setToGoToNormalMode(true);
|
||||
mgmLis3Handler->setStartUpImmediately();
|
||||
mgmLis3Handler->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
mgmLis3Handler2->enablePeriodicPrintouts(true, 10);
|
||||
mgmLis3Handler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#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);
|
||||
@ -621,11 +627,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
|
||||
#if OBSW_TEST_ACS == 1
|
||||
mgmRm3100Handler->setStartUpImmediately();
|
||||
mgmRm3100Handler->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
mgmRm3100Handler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Commented until ACS board V2 in in clean room again
|
||||
// Gyro 0 Side A
|
||||
spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
|
||||
@ -633,12 +638,13 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
|
||||
spi::DEFAULT_ADIS16507_SPEED);
|
||||
auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF,
|
||||
spiCookie, ADIS1650X::Type::ADIS16505);
|
||||
static_cast<void>(adisHandler);
|
||||
#if OBSW_TEST_ACS == 1
|
||||
adisHandler->setStartUpImmediately();
|
||||
adisHandler->setToGoToNormalModeImmediately();
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
adisHandler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Gyro 1 Side A
|
||||
@ -647,12 +653,13 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
|
||||
spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
|
||||
spiCookie, spi::L3G_TRANSITION_DELAY);
|
||||
static_cast<void>(gyroL3gHandler);
|
||||
#if OBSW_TEST_ACS == 1
|
||||
gyroL3gHandler->setStartUpImmediately();
|
||||
gyroL3gHandler->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
gyroL3gHandler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#endif
|
||||
// Gyro 2 Side B
|
||||
spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev,
|
||||
@ -673,9 +680,9 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
|
||||
#if OBSW_TEST_ACS == 1
|
||||
gyroL3gHandler->setStartUpImmediately();
|
||||
gyroL3gHandler->setToGoToNormalMode(true);
|
||||
#endif
|
||||
#if OBSW_DEBUG_ACS == 1
|
||||
gyroL3gHandler->enablePeriodicPrintouts(true, 10);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool debugGps = false;
|
||||
@ -691,6 +698,24 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
|
||||
auto gpsHandler0 =
|
||||
new GPSHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
|
||||
gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0);
|
||||
|
||||
AcsBoardHelper acsBoardHelper = AcsBoardHelper(
|
||||
objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER,
|
||||
objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER,
|
||||
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER);
|
||||
auto acsAss = new AcsBoardAssembly(objects::ACS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher,
|
||||
acsBoardHelper, gpioComIF);
|
||||
static_cast<void>(acsAss);
|
||||
|
||||
#if OBSW_TEST_ACS_BOARD_ASS == 1
|
||||
CommandMessage msg;
|
||||
ModeMessage::setModeMessage(&msg, ModeMessage::CMD_MODE_COMMAND, DeviceHandlerIF::MODE_NORMAL,
|
||||
duallane::A_SIDE);
|
||||
ReturnValue_t result = MessageQueueSenderIF::sendMessage(acsAss->getCommandQueue(), &msg);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "Sending mode command failed" << std::endl;
|
||||
}
|
||||
#endif
|
||||
#endif /* OBSW_ADD_ACS_HANDLERS == 1 */
|
||||
}
|
||||
|
||||
@ -1214,11 +1239,11 @@ void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF*
|
||||
static_cast<void>(plPcduHandler);
|
||||
#if OBSW_TEST_PL_PCDU == 1
|
||||
plPcduHandler->setStartUpImmediately();
|
||||
#endif
|
||||
#if OBSW_DEBUG_PL_PCDU == 1
|
||||
plPcduHandler->setToGoToNormalModeImmediately(true);
|
||||
plPcduHandler->enablePeriodicPrintout(true, 5);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
|
||||
|
@ -5,6 +5,7 @@ class LinuxLibgpioIF;
|
||||
class UartComIF;
|
||||
class SpiComIF;
|
||||
class I2cComIF;
|
||||
class PowerSwitchIF;
|
||||
|
||||
namespace ObjectFactory {
|
||||
|
||||
@ -13,13 +14,13 @@ void produce(void* args);
|
||||
|
||||
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF,
|
||||
SpiComIF** spiComIF, I2cComIF** i2cComIF);
|
||||
|
||||
void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher);
|
||||
void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF);
|
||||
void createTmpComponents();
|
||||
void createPcduComponents(LinuxLibgpioIF* gpioComIF);
|
||||
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
|
||||
void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF);
|
||||
void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF);
|
||||
void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF,
|
||||
PowerSwitchIF* pwrSwitcher);
|
||||
void createHeaterComponents();
|
||||
void createSolarArrayDeploymentComponents();
|
||||
void createSyrlinksComponents();
|
||||
|
@ -6,13 +6,15 @@
|
||||
#include "InitMission.h"
|
||||
#include "OBSWConfig.h"
|
||||
#include "OBSWVersion.h"
|
||||
#include "fsfw/FSFWVersion.h"
|
||||
#include "fsfw/tasks/TaskFactory.h"
|
||||
#include "fsfw/version.h"
|
||||
#include "watchdogConf.h"
|
||||
|
||||
static int OBSW_ALREADY_RUNNING = -2;
|
||||
|
||||
int obsw::obsw() {
|
||||
fsfw::Version version;
|
||||
fsfw::getVersion(version);
|
||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||
#if BOARD_TE0720 == 0
|
||||
std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl;
|
||||
@ -20,7 +22,8 @@ int obsw::obsw() {
|
||||
std::cout << "-- Compiled for Linux (TE0720) --" << std::endl;
|
||||
#endif
|
||||
std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v"
|
||||
<< FSFW_VERSION << "." << FSFW_SUBVERSION << "." << FSFW_REVISION << "--" << std::endl;
|
||||
<< version.major << "." << version.minor << "." << version.revision << "--"
|
||||
<< std::endl;
|
||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||
|
||||
#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw_hal/linux/uart/UartComIF.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "devicedefinitions/PlocSupervisorDefinitions.h"
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "SdCardManager.h"
|
||||
|
||||
#include <fsfw/ipc/MutexGuard.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
@ -8,6 +9,7 @@
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "common/config/commonObjects.h"
|
||||
#include "fsfw/ipc/MutexFactory.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
@ -404,16 +406,13 @@ SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations& currentOp) {
|
||||
bool bytesRead = false;
|
||||
|
||||
#if OBSW_ENABLE_TIMERS == 1
|
||||
Timer timer;
|
||||
timer.setTimer(100);
|
||||
uint32_t remainingTimeMs = 0;
|
||||
Countdown timer(100);
|
||||
#endif
|
||||
while (true) {
|
||||
ReturnValue_t result = cmdExecutor.check(bytesRead);
|
||||
// This timer can prevent deadlocks due to missconfigurations
|
||||
#if OBSW_ENABLE_TIMERS == 1
|
||||
timer.getTimer(&remainingTimeMs);
|
||||
if (remainingTimeMs == 0) {
|
||||
if (timer.hasTimedOut()) {
|
||||
sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl;
|
||||
return OpStatus::FAIL;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
const char* const SW_NAME = "eive";
|
||||
|
||||
#define SW_VERSION 1
|
||||
#define SW_SUBVERSION 8
|
||||
#define SW_SUBVERSION 9
|
||||
#define SW_REVISION 0
|
||||
|
||||
#endif /* COMMON_CONFIG_OBSWVERSION_H_ */
|
||||
|
@ -12,7 +12,7 @@
|
||||
// because UDP packets are not allowed in the VPN
|
||||
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
|
||||
// CCSDS IP Cores.
|
||||
#define OBSW_USE_TCP_BRIDGE 1
|
||||
#define OBSW_USE_TMTC_TCP_BRIDGE 1
|
||||
|
||||
namespace common {
|
||||
extern const uint16_t PUS_PACKET_ID;
|
||||
|
@ -91,6 +91,9 @@ enum commonObjects: uint32_t {
|
||||
STR_HELPER = 0x44330002,
|
||||
AXI_PTME_CONFIG = 44330003,
|
||||
PTME_CONFIG = 44330004,
|
||||
|
||||
// 0x73 ('s') for assemblies and system/subsystem components
|
||||
ACS_BOARD_ASS = 0x73000001
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace pcduSwitches {
|
||||
@ -33,32 +34,36 @@ enum Switches: uint8_t {
|
||||
static const uint8_t ON = 1;
|
||||
static const uint8_t OFF = 0;
|
||||
|
||||
/* Output states after reboot of the PDUs */
|
||||
// Output states after reboot of the PDUs
|
||||
|
||||
const std::array<uint8_t, NUMBER_OF_SWITCHES> INIT_SWITCH_STATES = {
|
||||
// PDU 1
|
||||
// Because the TE0720 is not connected to the PCDU, this switch is always on
|
||||
#if BOARD_TE0720 == 1
|
||||
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||
ON,
|
||||
#else
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||
OFF,
|
||||
#endif
|
||||
static const uint8_t INIT_STATE_SYRLINKS = OFF;
|
||||
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
|
||||
static const uint8_t INIT_STATE_MGT = OFF;
|
||||
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
|
||||
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
|
||||
static const uint8_t INIT_STATE_PLOC = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
|
||||
|
||||
static const uint8_t INIT_STATE_Q7S = ON;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||
static const uint8_t INIT_STATE_RW = OFF;
|
||||
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
||||
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
|
||||
// PDU 2
|
||||
ON,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF,
|
||||
OFF
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
||||
|
@ -41,4 +41,8 @@
|
||||
* copy & replace here settings you want to change values
|
||||
*/
|
||||
|
||||
#ifndef __DOXYGEN__
|
||||
#define __DOXYGEN__ 0
|
||||
#endif
|
||||
|
||||
#endif /* LWGPS_HDR_OPTS_H */
|
||||
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
||||
Subproject commit 7571987a1d90528d067e2ab86d1b589bc0e89b42
|
||||
Subproject commit 3b497dbb8dae77f1cf28f50f7ba770c4256acd2d
|
@ -77,6 +77,9 @@
|
||||
8901;0x22c5;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.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
|
||||
10800;0x2a30;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
|
||||
10801;0x2a31;SWITCH_HAS_CHANGED;INFO;Indicated that a swithc state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
|
||||
10802;0x2a32;SWITCHING_Q7S_DENIED;MEDIUM;;mission/devices/devicedefinitions/powerDefinitions.h
|
||||
10900;0x2a94;GPIO_PULL_HIGH_FAILED;LOW;;mission/devices/HeaterHandler.h
|
||||
10901;0x2a95;GPIO_PULL_LOW_FAILED;LOW;;mission/devices/HeaterHandler.h
|
||||
10902;0x2a96;SWITCH_ALREADY_ON;LOW;;mission/devices/HeaterHandler.h
|
||||
@ -106,9 +109,8 @@
|
||||
11502;0x2cee;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;bsp_q7s/devices/PlocSupervisorHandler.h
|
||||
11503;0x2cef;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;bsp_q7s/devices/PlocSupervisorHandler.h
|
||||
11504;0x2cf0;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;bsp_q7s/devices/PlocSupervisorHandler.h
|
||||
11600;0x2d50;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h
|
||||
11601;0x2d51;REBOOT_SW;MEDIUM; Software reboot occured. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
11603;0x2d53;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h
|
||||
11600;0x2d50;SANITIZATION_FAILED;LOW;;bsp_q7s/memory/SdCardManager.h
|
||||
11601;0x2d51;MOUNTED_SD_CARD;INFO;;bsp_q7s/memory/SdCardManager.h
|
||||
11700;0x2db4;UPDATE_FILE_NOT_EXISTS;LOW;;bsp_q7s/devices/PlocUpdater.h
|
||||
11701;0x2db5;ACTION_COMMANDING_FAILED;LOW;Failed to send command to supervisor handler P1: Return value of CommandActionHelper::commandAction P2: Action ID of command to send;bsp_q7s/devices/PlocUpdater.h
|
||||
11702;0x2db6;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;bsp_q7s/devices/PlocUpdater.h
|
||||
@ -139,6 +141,7 @@
|
||||
12014;0x2eee;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;linux/devices/startracker/StrHelper.h
|
||||
12015;0x2eef;STR_HELPER_SENDING_PACKET_FAILED;LOW;;linux/devices/startracker/StrHelper.h
|
||||
12016;0x2ef0;STR_HELPER_REQUESTING_MSG_FAILED;LOW;;linux/devices/startracker/StrHelper.h
|
||||
12100;0x2f44;TRANSITION_BACK_TO_OFF;MEDIUM;Could not transition properly and went back to ALL OFF;mission/devices/PayloadPcduHandler.h
|
||||
12101;0x2f45;NEG_V_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h
|
||||
12102;0x2f46;U_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h
|
||||
12103;0x2f47;I_DRO_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h
|
||||
@ -150,3 +153,10 @@
|
||||
12109;0x2f4d;I_MPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h
|
||||
12110;0x2f4e;U_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h
|
||||
12111;0x2f4f;I_HPA_OUT_OF_BOUNDS;MEDIUM;P1: 0 -> too low, 1 -> too high P2: Float value;mission/devices/PayloadPcduHandler.h
|
||||
12200;0x2fa8;TRANSITION_OTHER_SIDE_FAILED;HIGH;;mission/system/AcsBoardAssembly.h
|
||||
12201;0x2fa9;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;;mission/system/AcsBoardAssembly.h
|
||||
12202;0x2faa;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;;mission/system/AcsBoardAssembly.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
|
||||
13603;0x3523;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h
|
||||
|
|
@ -107,6 +107,7 @@
|
||||
0x5400CAFE;DUMMY_INTERFACE
|
||||
0x54123456;LIBGPIOD_TEST
|
||||
0x54694269;TEST_TASK
|
||||
0x73000001;ACS_BOARD_ASS
|
||||
0x73000100;TM_FUNNEL
|
||||
0x73500000;CCSDS_IP_CORE_BRIDGE
|
||||
0xFFFFFFFF;NO_OBJECT
|
||||
|
|
@ -82,7 +82,10 @@ def parse_events(
|
||||
handle_csv_export(
|
||||
file_name=CSV_FILENAME, event_list=event_list, file_separator=FILE_SEPARATOR
|
||||
)
|
||||
copy_file(filename=CSV_FILENAME, destination=CSV_COPY_DEST, delete_existing_file=True)
|
||||
LOGGER.info(f"Copying CSV file to {CSV_COPY_DEST}")
|
||||
copy_file(
|
||||
filename=CSV_FILENAME, destination=CSV_COPY_DEST, delete_existing_file=True
|
||||
)
|
||||
|
||||
if generate_cpp:
|
||||
handle_cpp_export(
|
||||
@ -93,7 +96,7 @@ def parse_events(
|
||||
header_file_name=CPP_H_FILENAME,
|
||||
)
|
||||
if COPY_CPP_FILE:
|
||||
LOGGER.info(f"EventParser: Copying file to {CPP_COPY_DESTINATION}")
|
||||
LOGGER.info(f"EventParser: Copying CPP translation file to {CPP_COPY_DESTINATION}")
|
||||
copy_file(CPP_FILENAME, CPP_COPY_DESTINATION)
|
||||
copy_file(CPP_H_FILENAME, CPP_COPY_DESTINATION)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 152 translations.
|
||||
* @brief Auto-generated event translation file. Contains 162 translations.
|
||||
* @details
|
||||
* Generated on: 2022-03-04 14:55:20
|
||||
* Generated on: 2022-03-07 17:09:35
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -84,6 +84,9 @@ const char *CLOCK_SET_STRING = "CLOCK_SET";
|
||||
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
|
||||
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";
|
||||
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
|
||||
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
|
||||
const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED";
|
||||
const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED";
|
||||
const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON";
|
||||
@ -113,9 +116,8 @@ const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_
|
||||
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
|
||||
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE";
|
||||
const char *REBOOT_SW_STRING = "REBOOT_SW";
|
||||
const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
|
||||
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
|
||||
const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS";
|
||||
const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED";
|
||||
const char *UPDATE_AVAILABLE_FAILED_STRING = "UPDATE_AVAILABLE_FAILED";
|
||||
@ -146,6 +148,7 @@ const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH";
|
||||
const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS";
|
||||
const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED";
|
||||
const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED";
|
||||
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
||||
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
||||
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
||||
const char *I_DRO_OUT_OF_BOUNDS_STRING = "I_DRO_OUT_OF_BOUNDS";
|
||||
@ -157,6 +160,13 @@ const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS";
|
||||
const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS";
|
||||
const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS";
|
||||
const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS";
|
||||
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 *ALLOC_FAILURE_STRING = "ALLOC_FAILURE";
|
||||
const char *REBOOT_SW_STRING = "REBOOT_SW";
|
||||
const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED";
|
||||
const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -318,6 +328,12 @@ const char *translateEvents(Event event) {
|
||||
return TEST_STRING;
|
||||
case (10600):
|
||||
return CHANGE_OF_SETUP_PARAMETER_STRING;
|
||||
case (10800):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (10801):
|
||||
return SWITCH_HAS_CHANGED_STRING;
|
||||
case (10802):
|
||||
return SWITCHING_Q7S_DENIED_STRING;
|
||||
case (10900):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case (10901):
|
||||
@ -377,11 +393,9 @@ const char *translateEvents(Event event) {
|
||||
case (11504):
|
||||
return SUPV_CRC_FAILURE_EVENT_STRING;
|
||||
case (11600):
|
||||
return ALLOC_FAILURE_STRING;
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case (11601):
|
||||
return REBOOT_SW_STRING;
|
||||
case (11603):
|
||||
return REBOOT_HW_STRING;
|
||||
return MOUNTED_SD_CARD_STRING;
|
||||
case (11700):
|
||||
return UPDATE_FILE_NOT_EXISTS_STRING;
|
||||
case (11701):
|
||||
@ -442,6 +456,8 @@ const char *translateEvents(Event event) {
|
||||
return STR_HELPER_SENDING_PACKET_FAILED_STRING;
|
||||
case (12016):
|
||||
return STR_HELPER_REQUESTING_MSG_FAILED_STRING;
|
||||
case (12100):
|
||||
return TRANSITION_BACK_TO_OFF_STRING;
|
||||
case (12101):
|
||||
return NEG_V_OUT_OF_BOUNDS_STRING;
|
||||
case (12102):
|
||||
@ -464,6 +480,20 @@ const char *translateEvents(Event event) {
|
||||
return U_HPA_OUT_OF_BOUNDS_STRING;
|
||||
case (12111):
|
||||
return I_HPA_OUT_OF_BOUNDS_STRING;
|
||||
case (12200):
|
||||
return TRANSITION_OTHER_SIDE_FAILED_STRING;
|
||||
case (12201):
|
||||
return NOT_ENOUGH_DEVICES_DUAL_MODE_STRING;
|
||||
case (12202):
|
||||
return POWER_STATE_MACHINE_TIMEOUT_STRING;
|
||||
case (13600):
|
||||
return ALLOC_FAILURE_STRING;
|
||||
case (13601):
|
||||
return REBOOT_SW_STRING;
|
||||
case (13602):
|
||||
return REBOOT_MECHANISM_TRIGGERED_STRING;
|
||||
case (13603):
|
||||
return REBOOT_HW_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 348877b5d93ad17db4b03d08b134a2e1c87af2df
|
||||
Subproject commit c5ef1783a3b082c0e88561bd91bc3ee0f459fafc
|
@ -118,5 +118,5 @@ def handle_file_export(list_items):
|
||||
copy_file(
|
||||
filename=CSV_OBJECT_FILENAME,
|
||||
destination=CSV_COPY_DEST,
|
||||
delete_existing_file=True
|
||||
delete_existing_file=True,
|
||||
)
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 112 translations.
|
||||
* Generated on: 2022-03-04 14:55:17
|
||||
* Contains 113 translations.
|
||||
* Generated on: 2022-03-07 17:15:28
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -115,6 +115,7 @@ const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER";
|
||||
const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE";
|
||||
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 *TM_FUNNEL_STRING = "TM_FUNNEL";
|
||||
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
|
||||
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
||||
@ -339,6 +340,8 @@ const char *translateObject(object_id_t object) {
|
||||
return LIBGPIOD_TEST_STRING;
|
||||
case 0x54694269:
|
||||
return TEST_TASK_STRING;
|
||||
case 0x73000001:
|
||||
return ACS_BOARD_ASS_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73500000:
|
||||
|
@ -87,7 +87,7 @@ def parse_returnvalues():
|
||||
copy_file(
|
||||
filename=CSV_RETVAL_FILENAME,
|
||||
destination=CSV_COPY_DEST,
|
||||
delete_existing_file=True
|
||||
delete_existing_file=True,
|
||||
)
|
||||
if EXPORT_TO_SQL:
|
||||
LOGGER.info("ReturnvalueParser: Exporting to SQL")
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
#define GPS_REPLY_WIRETAPPING 0
|
||||
|
||||
#ifndef RPI_TEST_GPS_HANDLER
|
||||
#define RPI_TEST_GPS_HANDLER 0
|
||||
#endif
|
||||
|
||||
UartTestClass::UartTestClass(object_id_t objectId) : TestTask(objectId) { mode = TestModes::SCEX; }
|
||||
|
||||
ReturnValue_t UartTestClass::initialize() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "GPSHyperionLinuxController.h"
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "fsfw/timemanager/Clock.h"
|
||||
|
||||
@ -30,10 +31,12 @@ ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_
|
||||
uint32_t *msToReachTheMode) {
|
||||
if (not modeCommanded) {
|
||||
if (mode == MODE_ON or mode == MODE_OFF) {
|
||||
// 10 minutes time to reach fix
|
||||
*msToReachTheMode = 600000;
|
||||
// 5h time to reach fix
|
||||
*msToReachTheMode = MAX_SECONDS_TO_REACH_FIX;
|
||||
maxTimeToReachFix.resetTimer();
|
||||
modeCommanded = true;
|
||||
} else if (mode == MODE_NORMAL) {
|
||||
return HasModesIF::INVALID_MODE;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
class GPSHyperionLinuxController : public ExtendedControllerBase {
|
||||
public:
|
||||
static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 600;
|
||||
static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 60 * 5;
|
||||
GPSHyperionLinuxController(object_id_t objectId, object_id_t parentId,
|
||||
bool debugHyperionGps = false);
|
||||
virtual ~GPSHyperionLinuxController();
|
||||
|
@ -41,6 +41,7 @@ debugging. */
|
||||
#define OBSW_TC_FROM_PDEC 0
|
||||
|
||||
#define OBSW_ENABLE_TIMERS 1
|
||||
#define OBSW_INITIALIZE_SWITCHES 1
|
||||
#define OBSW_ADD_MGT 1
|
||||
#define OBSW_ADD_BPX_BATTERY_HANDLER 1
|
||||
#define OBSW_ADD_STAR_TRACKER 0
|
||||
@ -48,7 +49,7 @@ debugging. */
|
||||
#define OBSW_ADD_PLOC_MPSOC 0
|
||||
#define OBSW_ADD_SUN_SENSORS 0
|
||||
#define OBSW_ADD_ACS_BOARD 1
|
||||
#define OBSW_ADD_ACS_HANDLERS 0
|
||||
#define OBSW_ADD_ACS_HANDLERS 1
|
||||
#define OBSW_ADD_RW 0
|
||||
#define OBSW_ADD_RTD_DEVICES 0
|
||||
#define OBSW_ADD_TMP_DEVICES 0
|
||||
@ -84,6 +85,7 @@ debugging. */
|
||||
#define OBSW_ADD_UART_TEST_CODE 0
|
||||
|
||||
#define OBSW_TEST_ACS 0
|
||||
#define OBSW_TEST_ACS_BOARD_ASS 0
|
||||
#define OBSW_DEBUG_ACS 0
|
||||
#define OBSW_TEST_SUS 0
|
||||
#define OBSW_DEBUG_SUS 0
|
||||
|
@ -13,7 +13,7 @@
|
||||
namespace SUBSYSTEM_ID {
|
||||
enum : uint8_t {
|
||||
SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END,
|
||||
CORE = 116,
|
||||
CORE = 136,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 152 translations.
|
||||
* @brief Auto-generated event translation file. Contains 162 translations.
|
||||
* @details
|
||||
* Generated on: 2022-03-04 14:55:20
|
||||
* Generated on: 2022-03-07 17:09:35
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -84,6 +84,9 @@ const char *CLOCK_SET_STRING = "CLOCK_SET";
|
||||
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
|
||||
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";
|
||||
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
|
||||
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
|
||||
const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED";
|
||||
const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED";
|
||||
const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON";
|
||||
@ -113,9 +116,8 @@ const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_
|
||||
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
|
||||
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE";
|
||||
const char *REBOOT_SW_STRING = "REBOOT_SW";
|
||||
const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
|
||||
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
|
||||
const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS";
|
||||
const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED";
|
||||
const char *UPDATE_AVAILABLE_FAILED_STRING = "UPDATE_AVAILABLE_FAILED";
|
||||
@ -146,6 +148,7 @@ const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH";
|
||||
const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS";
|
||||
const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED";
|
||||
const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED";
|
||||
const char *TRANSITION_BACK_TO_OFF_STRING = "TRANSITION_BACK_TO_OFF";
|
||||
const char *NEG_V_OUT_OF_BOUNDS_STRING = "NEG_V_OUT_OF_BOUNDS";
|
||||
const char *U_DRO_OUT_OF_BOUNDS_STRING = "U_DRO_OUT_OF_BOUNDS";
|
||||
const char *I_DRO_OUT_OF_BOUNDS_STRING = "I_DRO_OUT_OF_BOUNDS";
|
||||
@ -157,6 +160,13 @@ const char *U_MPA_OUT_OF_BOUNDS_STRING = "U_MPA_OUT_OF_BOUNDS";
|
||||
const char *I_MPA_OUT_OF_BOUNDS_STRING = "I_MPA_OUT_OF_BOUNDS";
|
||||
const char *U_HPA_OUT_OF_BOUNDS_STRING = "U_HPA_OUT_OF_BOUNDS";
|
||||
const char *I_HPA_OUT_OF_BOUNDS_STRING = "I_HPA_OUT_OF_BOUNDS";
|
||||
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 *ALLOC_FAILURE_STRING = "ALLOC_FAILURE";
|
||||
const char *REBOOT_SW_STRING = "REBOOT_SW";
|
||||
const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED";
|
||||
const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -318,6 +328,12 @@ const char *translateEvents(Event event) {
|
||||
return TEST_STRING;
|
||||
case (10600):
|
||||
return CHANGE_OF_SETUP_PARAMETER_STRING;
|
||||
case (10800):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (10801):
|
||||
return SWITCH_HAS_CHANGED_STRING;
|
||||
case (10802):
|
||||
return SWITCHING_Q7S_DENIED_STRING;
|
||||
case (10900):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case (10901):
|
||||
@ -377,11 +393,9 @@ const char *translateEvents(Event event) {
|
||||
case (11504):
|
||||
return SUPV_CRC_FAILURE_EVENT_STRING;
|
||||
case (11600):
|
||||
return ALLOC_FAILURE_STRING;
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case (11601):
|
||||
return REBOOT_SW_STRING;
|
||||
case (11603):
|
||||
return REBOOT_HW_STRING;
|
||||
return MOUNTED_SD_CARD_STRING;
|
||||
case (11700):
|
||||
return UPDATE_FILE_NOT_EXISTS_STRING;
|
||||
case (11701):
|
||||
@ -442,6 +456,8 @@ const char *translateEvents(Event event) {
|
||||
return STR_HELPER_SENDING_PACKET_FAILED_STRING;
|
||||
case (12016):
|
||||
return STR_HELPER_REQUESTING_MSG_FAILED_STRING;
|
||||
case (12100):
|
||||
return TRANSITION_BACK_TO_OFF_STRING;
|
||||
case (12101):
|
||||
return NEG_V_OUT_OF_BOUNDS_STRING;
|
||||
case (12102):
|
||||
@ -464,6 +480,20 @@ const char *translateEvents(Event event) {
|
||||
return U_HPA_OUT_OF_BOUNDS_STRING;
|
||||
case (12111):
|
||||
return I_HPA_OUT_OF_BOUNDS_STRING;
|
||||
case (12200):
|
||||
return TRANSITION_OTHER_SIDE_FAILED_STRING;
|
||||
case (12201):
|
||||
return NOT_ENOUGH_DEVICES_DUAL_MODE_STRING;
|
||||
case (12202):
|
||||
return POWER_STATE_MACHINE_TIMEOUT_STRING;
|
||||
case (13600):
|
||||
return ALLOC_FAILURE_STRING;
|
||||
case (13601):
|
||||
return REBOOT_SW_STRING;
|
||||
case (13602):
|
||||
return REBOOT_MECHANISM_TRIGGERED_STRING;
|
||||
case (13603):
|
||||
return REBOOT_HW_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 112 translations.
|
||||
* Generated on: 2022-03-04 14:55:17
|
||||
* Contains 113 translations.
|
||||
* Generated on: 2022-03-07 17:15:28
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -115,6 +115,7 @@ const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER";
|
||||
const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE";
|
||||
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 *TM_FUNNEL_STRING = "TM_FUNNEL";
|
||||
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
|
||||
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
||||
@ -339,6 +340,8 @@ const char *translateObject(object_id_t object) {
|
||||
return LIBGPIOD_TEST_STRING;
|
||||
case 0x54694269:
|
||||
return TEST_TASK_STRING;
|
||||
case 0x73000001:
|
||||
return ACS_BOARD_ASS_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73500000:
|
||||
|
@ -5,8 +5,13 @@
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "objects/systemObjectList.h"
|
||||
#ifndef RPI_TEST_ADIS16507
|
||||
#define RPI_TEST_ADIS16507 0
|
||||
#endif
|
||||
|
||||
#ifndef RPI_TEST_GPS_HANDLER
|
||||
#define RPI_TEST_GPS_HANDLER 0
|
||||
#endif
|
||||
|
||||
ReturnValue_t pst::pstGpio(FixedTimeslotTaskIF *thisSequence) {
|
||||
// Length of a communication cycle
|
||||
@ -359,7 +364,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) {
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1
|
||||
bool enableAside = false;
|
||||
bool enableAside = true;
|
||||
bool enableBside = true;
|
||||
if (enableAside) {
|
||||
// A side
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "objects/systemObjectList.h"
|
||||
|
||||
#if OBSW_ADD_TCPIP_BRIDGE == 1
|
||||
#if OBSW_USE_TCP_BRIDGE == 0
|
||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||
// UDP server includes
|
||||
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
||||
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
||||
@ -90,7 +90,7 @@ void ObjectFactory::produceGenericObjects() {
|
||||
pus::PUS_SERVICE_200);
|
||||
|
||||
#if OBSW_ADD_TCPIP_BRIDGE == 1
|
||||
#if OBSW_USE_TCP_BRIDGE == 0
|
||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||
auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
||||
sif::info << "Created UDP server for TMTC commanding with listener port "
|
||||
|
@ -23,7 +23,7 @@ void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pack
|
||||
parseHkTableReply(packet);
|
||||
handleDeviceTM(&acuHkTableDataset, id, true);
|
||||
|
||||
#if OBSW_ENHANCED_PRINTOUT == 1 && OBSW_DEBUG_ACU == 1
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_ACU == 1
|
||||
acuHkTableDataset.read();
|
||||
float temperatureC_1 = acuHkTableDataset.temperature1.value * 0.1;
|
||||
float temperatureC_2 = acuHkTableDataset.temperature2.value * 0.1;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <mission/devices/GomspaceDeviceHandler.h>
|
||||
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
|
||||
#include "GomspaceDeviceHandler.h"
|
||||
|
||||
#include "devicedefinitions/GomSpacePackets.h"
|
||||
#include "devicedefinitions/powerDefinitions.h"
|
||||
|
||||
GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF,
|
||||
CookieIF* comCookie, uint16_t maxConfigTableAddress,
|
||||
@ -189,6 +191,11 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
|
||||
size_t commandDataLen) {
|
||||
ReturnValue_t result =
|
||||
setParamCacher.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG);
|
||||
// This breaks layering but I really don't want to accept this command..
|
||||
if (setParamCacher.getAddress() == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S) {
|
||||
triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0);
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter "
|
||||
"message"
|
||||
|
@ -27,7 +27,6 @@ ReturnValue_t PCDUHandler::performOperation(uint8_t counter) {
|
||||
readCommandQueue();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
@ -79,25 +78,9 @@ ReturnValue_t PCDUHandler::initialize() {
|
||||
|
||||
void PCDUHandler::initializeSwitchStates() {
|
||||
using namespace pcduSwitches;
|
||||
switchStates[Switches::PDU2_CH0_Q7S] = pcduSwitches::INIT_STATE_Q7S;
|
||||
switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1;
|
||||
switchStates[Switches::PDU2_CH2_RW_5V] = pcduSwitches::INIT_STATE_RW;
|
||||
switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] =
|
||||
pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN;
|
||||
switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] = pcduSwitches::INIT_STATE_SUS_REDUNDANT;
|
||||
switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] =
|
||||
pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM;
|
||||
switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6;
|
||||
switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B;
|
||||
switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA;
|
||||
switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3;
|
||||
switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pcduSwitches::INIT_STATE_SYRLINKS;
|
||||
switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = pcduSwitches::INIT_STATE_STAR_TRACKER;
|
||||
switchStates[Switches::PDU1_CH3_MGT_5V] = pcduSwitches::INIT_STATE_MGT;
|
||||
switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] = pcduSwitches::INIT_STATE_SUS_NOMINAL;
|
||||
switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP;
|
||||
switchStates[Switches::PDU1_CH6_PLOC_12V] = pcduSwitches::INIT_STATE_PLOC;
|
||||
switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A;
|
||||
for (uint8_t idx = 0; idx < Switches::NUMBER_OF_SWITCHES; idx++) {
|
||||
switchStates[idx] = INIT_SWITCH_STATES[idx];
|
||||
}
|
||||
}
|
||||
|
||||
void PCDUHandler::readCommandQueue() {
|
||||
@ -117,7 +100,7 @@ void PCDUHandler::readCommandQueue() {
|
||||
|
||||
MessageQueueId_t PCDUHandler::getCommandQueue() const { return commandQueue->getId(); }
|
||||
|
||||
void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) {
|
||||
void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) {
|
||||
if (sid == sid_t(objects::PDU2_HANDLER, PDU2::HK_TABLE_DATA_SET_ID)) {
|
||||
updateHkTableDataset(storeId, &pdu2HkTableDataset, &timeStampPdu2HkDataset);
|
||||
updatePdu2SwitchStates();
|
||||
@ -159,25 +142,31 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet
|
||||
|
||||
void PCDUHandler::updatePdu2SwitchStates() {
|
||||
using namespace pcduSwitches;
|
||||
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2;
|
||||
PoolReadGuard rg(&pdu2HkTableDataset);
|
||||
if (rg.getReadResult() == RETURN_OK) {
|
||||
MutexGuard mg(pwrMutex);
|
||||
switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value;
|
||||
switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] =
|
||||
pdu2HkTableDataset.outEnabledPlPCDUCh1.value;
|
||||
switchStates[Switches::PDU2_CH2_RW_5V] = pdu2HkTableDataset.outEnabledReactionWheels.value;
|
||||
switchStates[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V] =
|
||||
pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value;
|
||||
switchStates[Switches::PDU2_CH4_SUS_REDUNDANT_3V3] =
|
||||
pdu2HkTableDataset.outEnabledSUSRedundant.value;
|
||||
switchStates[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V] =
|
||||
pdu2HkTableDataset.outEnabledDeplMechanism.value;
|
||||
switchStates[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8] =
|
||||
pdu2HkTableDataset.outEnabledPlPCDUCh6.value;
|
||||
switchStates[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3] =
|
||||
pdu2HkTableDataset.outEnabledAcsBoardSideB.value;
|
||||
switchStates[Switches::PDU2_CH8_PAYLOAD_CAMERA] =
|
||||
pdu2HkTableDataset.outEnabledPayloadCamera.value;
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH0_Q7S, pdu2HkTableDataset.outEnabledQ7S.value);
|
||||
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8,
|
||||
pdu2HkTableDataset.outEnabledPlPCDUCh1.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH2_RW_5V,
|
||||
pdu2HkTableDataset.outEnabledReactionWheels.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V,
|
||||
pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH4_SUS_REDUNDANT_3V3,
|
||||
pdu2HkTableDataset.outEnabledSUSRedundant.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V,
|
||||
pdu2HkTableDataset.outEnabledDeplMechanism.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8,
|
||||
pdu2HkTableDataset.outEnabledPlPCDUCh6.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3,
|
||||
pdu2HkTableDataset.outEnabledAcsBoardSideB.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU2_CH8_PAYLOAD_CAMERA,
|
||||
pdu2HkTableDataset.outEnabledPayloadCamera.value);
|
||||
if (firstSwitchInfoPdu2) {
|
||||
firstSwitchInfoPdu2 = false;
|
||||
}
|
||||
} else {
|
||||
sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset"
|
||||
<< std::endl;
|
||||
@ -187,25 +176,31 @@ void PCDUHandler::updatePdu2SwitchStates() {
|
||||
void PCDUHandler::updatePdu1SwitchStates() {
|
||||
using namespace pcduSwitches;
|
||||
PoolReadGuard rg(&pdu1HkTableDataset);
|
||||
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1;
|
||||
if (rg.getReadResult() == RETURN_OK) {
|
||||
MutexGuard mg(pwrMutex);
|
||||
switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value;
|
||||
switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value;
|
||||
switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] =
|
||||
pdu1HkTableDataset.outEnabledStarTracker.value;
|
||||
switchStates[Switches::PDU1_CH3_MGT_5V] = pdu1HkTableDataset.outEnabledMGT.value;
|
||||
switchStates[Switches::PDU1_CH4_SUS_NOMINAL_3V3] =
|
||||
pdu1HkTableDataset.outEnabledSUSNominal.value;
|
||||
switchStates[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V] =
|
||||
pdu1HkTableDataset.outEnabledSolarCellExp.value;
|
||||
switchStates[Switches::PDU1_CH6_PLOC_12V] = pdu1HkTableDataset.outEnabledPLOC.value;
|
||||
switchStates[Switches::PDU1_CH7_ACS_A_SIDE_3V3] =
|
||||
pdu1HkTableDataset.outEnabledAcsBoardSideA.value;
|
||||
switchStates[Switches::PDU1_CH8_UNOCCUPIED] = pdu1HkTableDataset.outEnabledChannel8.value;
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH0_TCS_BOARD_3V3,
|
||||
pdu1HkTableDataset.outEnabledTCSBoard3V3.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH1_SYRLINKS_12V,
|
||||
pdu1HkTableDataset.outEnabledSyrlinks.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH2_STAR_TRACKER_5V,
|
||||
pdu1HkTableDataset.outEnabledStarTracker.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH3_MGT_5V, pdu1HkTableDataset.outEnabledMGT.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH4_SUS_NOMINAL_3V3,
|
||||
pdu1HkTableDataset.outEnabledSUSNominal.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH5_SOLAR_CELL_EXP_5V,
|
||||
pdu1HkTableDataset.outEnabledSolarCellExp.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH6_PLOC_12V, pdu1HkTableDataset.outEnabledPLOC.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH7_ACS_A_SIDE_3V3,
|
||||
pdu1HkTableDataset.outEnabledAcsBoardSideA.value);
|
||||
checkAndUpdateSwitch(pdu, Switches::PDU1_CH8_UNOCCUPIED,
|
||||
pdu1HkTableDataset.outEnabledChannel8.value);
|
||||
if (firstSwitchInfoPdu1) {
|
||||
firstSwitchInfoPdu1 = false;
|
||||
}
|
||||
} else {
|
||||
sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl;
|
||||
}
|
||||
pdu1HkTableDataset.commit();
|
||||
}
|
||||
|
||||
LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; }
|
||||
@ -264,11 +259,12 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const
|
||||
pdu = ObjectManager::instance()->get<GomspaceDeviceHandler>(objects::PDU1_HANDLER);
|
||||
break;
|
||||
}
|
||||
// That does not really make sense but let's keep it here for completeness reasons..
|
||||
// This is a dangerous command. Reject/Igore it for now
|
||||
case pcduSwitches::PDU2_CH0_Q7S: {
|
||||
memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_Q7S;
|
||||
pdu = ObjectManager::instance()->get<GomspaceDeviceHandler>(objects::PDU2_HANDLER);
|
||||
break;
|
||||
return;
|
||||
// memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_Q7S;
|
||||
// pdu = ObjectManager::instance()->get<GomspaceDeviceHandler>(objects::PDU2_HANDLER);
|
||||
// break;
|
||||
}
|
||||
case pcduSwitches::PDU2_CH1_PL_PCDU_BATT_0_14V8: {
|
||||
memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1;
|
||||
@ -347,6 +343,9 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PCDUHandler::sendSwitchCommand: Failed to send message to PDU Handler"
|
||||
<< std::endl;
|
||||
} else {
|
||||
// Can't use trigger event because of const function constraint, but this hack seems to work
|
||||
this->forwardEvent(power::SWITCH_CMD_SENT, parameterValue, switchNr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,6 +374,7 @@ object_id_t PCDUHandler::getObjectId() const { return SystemObject::getObjectId(
|
||||
|
||||
ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
using namespace pcduSwitches;
|
||||
localDataPoolMap.emplace(P60System::PDU2_CURRENT_OUT_Q7S, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1,
|
||||
new PoolEntry<int16_t>({0}));
|
||||
@ -413,28 +413,34 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat
|
||||
localDataPoolMap.emplace(P60System::PDU2_CONV_EN_3, new PoolEntry<uint8_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_Q7S,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_Q7S}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1}));
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH0_Q7S]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1,
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8]}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_RW,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_RW}));
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH2_RW_5V]}));
|
||||
#if BOARD_TE0720 == 1
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>({1}));
|
||||
#else
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN}));
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V]}));
|
||||
#endif
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_SUS_REDUNDANT,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_SUS_REDUNDANT}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_DEPLOYMENT_MECHANISM,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH6,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_ACS_BOARD_SIDE_B,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_CAMERA,
|
||||
new PoolEntry<uint8_t>({pcduSwitches::INIT_STATE_PAYLOAD_CAMERA}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_SUS_REDUNDANT,
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH4_SUS_REDUNDANT_3V3]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_DEPLOYMENT_MECHANISM,
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH6,
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_ACS_BOARD_SIDE_B,
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU2_OUT_EN_PAYLOAD_CAMERA,
|
||||
new PoolEntry<uint8_t>({INIT_SWITCH_STATES[Switches::PDU2_CH8_PAYLOAD_CAMERA]}));
|
||||
|
||||
localDataPoolMap.emplace(P60System::PDU2_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU2_BOOTCNT, new PoolEntry<uint32_t>({0}));
|
||||
@ -496,16 +502,32 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat
|
||||
new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_CURRENT_OUT_CHANNEL8, new PoolEntry<int16_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SYRLINKS, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_STAR_TRACKER, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_MGT, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SUS_NOMINAL, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_PLOC, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A,
|
||||
new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_CHANNEL8, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH0_TCS_BOARD_3V3]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_SYRLINKS,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH1_SYRLINKS_12V]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_STAR_TRACKER,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH2_STAR_TRACKER_5V]}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_MGT,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH3_MGT_5V]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_SUS_NOMINAL,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH4_SUS_NOMINAL_3V3]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_PLOC,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH6_PLOC_12V]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH7_ACS_A_SIDE_3V3]}));
|
||||
localDataPoolMap.emplace(
|
||||
P60System::PDU1_VOLTAGE_OUT_CHANNEL8,
|
||||
new PoolEntry<int16_t>({INIT_SWITCH_STATES[Switches::PDU1_CH8_UNOCCUPIED]}));
|
||||
|
||||
localDataPoolMap.emplace(P60System::PDU1_VCC, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(P60System::PDU1_VBAT, new PoolEntry<int16_t>({0}));
|
||||
@ -595,3 +617,27 @@ LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PCDUHandler::checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches switchIdx,
|
||||
uint8_t setValue) {
|
||||
using namespace pcduSwitches;
|
||||
if (switchStates[switchIdx] != setValue) {
|
||||
#if OBSW_INITIALIZE_SWITCHES == 1
|
||||
// This code initializes the switches to the default init switch states on every reboot.
|
||||
// This is not done by the PCDU unless it is power-cycled.
|
||||
if (((pdu == GOMSPACE::Pdu::PDU1) and firstSwitchInfoPdu1) or
|
||||
((pdu == GOMSPACE::Pdu::PDU2) and firstSwitchInfoPdu2)) {
|
||||
ReturnValue_t state = PowerSwitchIF::SWITCH_OFF;
|
||||
if (INIT_SWITCH_STATES[switchIdx] == ON) {
|
||||
state = PowerSwitchIF::SWITCH_ON;
|
||||
}
|
||||
sendSwitchCommand(switchIdx, state);
|
||||
} else {
|
||||
triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx);
|
||||
}
|
||||
#else
|
||||
triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx);
|
||||
#endif
|
||||
}
|
||||
switchStates[switchIdx] = setValue;
|
||||
}
|
||||
|
@ -8,13 +8,16 @@
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/timemanager/CCSDSTime.h>
|
||||
#include <mission/devices/GomspaceDeviceHandler.h>
|
||||
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||
|
||||
#include "devicedefinitions/GomspaceDefinitions.h"
|
||||
#include "devicedefinitions/powerDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief The PCDUHandler provides a compact interface to handle all devices related to the
|
||||
* control of power. This is necessary because the fsfw manages all power
|
||||
* related functionalities via one power object. This includes for example the switch on and off of
|
||||
* devices.
|
||||
* control of power.
|
||||
* @details
|
||||
* This is necessary because the FSFW manages all power related functionalities via one
|
||||
* power object. This includes for example switching on and off of devices.
|
||||
*/
|
||||
class PCDUHandler : public PowerSwitchIF,
|
||||
public HasLocalDataPoolIF,
|
||||
@ -27,7 +30,8 @@ class PCDUHandler : public PowerSwitchIF,
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual ReturnValue_t performOperation(uint8_t counter) override;
|
||||
virtual void handleChangedDataset(sid_t sid,
|
||||
store_address_t storeId = storeId::INVALID_STORE_ADDRESS);
|
||||
store_address_t storeId = storeId::INVALID_STORE_ADDRESS,
|
||||
bool* clearMessage = nullptr) override;
|
||||
|
||||
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override;
|
||||
virtual void sendFuseOnCommand(uint8_t fuseNr) const override;
|
||||
@ -80,6 +84,8 @@ class PCDUHandler : public PowerSwitchIF,
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
|
||||
size_t cmdQueueSize;
|
||||
bool firstSwitchInfoPdu1 = true;
|
||||
bool firstSwitchInfoPdu2 = true;
|
||||
|
||||
PeriodicTaskIF* executingTask = nullptr;
|
||||
|
||||
@ -113,6 +119,7 @@ class PCDUHandler : public PowerSwitchIF,
|
||||
*/
|
||||
void updateHkTableDataset(store_address_t storeId, LocalPoolDataSetBase* dataset,
|
||||
CCSDSTime::CDS_short* datasetTimeStamp);
|
||||
void checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches switchIdx, uint8_t setValue);
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_PCDUHANDLER_H_ */
|
||||
|
20
mission/devices/devicedefinitions/powerDefinitions.h
Normal file
20
mission/devices/devicedefinitions/powerDefinitions.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_
|
||||
|
||||
#include <common/config/commonSubsystemIds.h>
|
||||
#include <fsfw/events/Event.h>
|
||||
|
||||
namespace power {
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_HANDLER;
|
||||
//! [EXPORT] : [COMMENT] Indicates that a FSFW object requested setting a switch
|
||||
//! P1: 1 if on was requested, 0 for off | P2: Switch Index
|
||||
static constexpr Event SWITCH_CMD_SENT = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Indicated that a swithc state has changed
|
||||
//! P1: New switch state, 1 for on, 0 for off | P2: Switch Index
|
||||
static constexpr Event SWITCH_HAS_CHANGED = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
|
||||
static constexpr Event SWITCHING_Q7S_DENIED = event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
||||
|
||||
} // namespace power
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ */
|
@ -6,7 +6,10 @@
|
||||
|
||||
AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId,
|
||||
PowerSwitchIF* switcher, AcsBoardHelper helper, GpioIF* gpioIF)
|
||||
: AssemblyBase(objectId, parentId), pwrSwitcher(switcher), helper(helper), gpioIF(gpioIF) {
|
||||
: AssemblyBase(objectId, parentId),
|
||||
pwrStateMachine(SWITCH_A, SWITCH_B, switcher),
|
||||
helper(helper),
|
||||
gpioIF(gpioIF) {
|
||||
if (switcher == nullptr) {
|
||||
sif::error << "AcsBoardAssembly::AcsBoardAssembly: Invalid Power Switcher "
|
||||
"IF passed"
|
||||
@ -27,14 +30,43 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId,
|
||||
initModeTableEntry(helper.gpsId, entry);
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::performChildOperation() {
|
||||
using namespace duallane;
|
||||
if (pwrStateMachine.active()) {
|
||||
pwrStateMachineWrapper();
|
||||
// This state is the indicator that the power state machine is done
|
||||
}
|
||||
if (not pwrStateMachine.active()) {
|
||||
AssemblyBase::performChildOperation();
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) {
|
||||
using namespace duallane;
|
||||
pwrStateMachine.reset();
|
||||
// If anything other than MODE_OFF is commanded, perform power state machine first
|
||||
if (mode != MODE_OFF) {
|
||||
// Cache the target modes, required by power state machine
|
||||
pwrStateMachine.start(mode, submode);
|
||||
// Cache these for later after the power state machine has finished
|
||||
targetMode = mode;
|
||||
targetSubmode = submode;
|
||||
// Perform power state machine first, then start mode transition. The power state machine will
|
||||
// start the transition after it has finished
|
||||
pwrStateMachineWrapper();
|
||||
} else {
|
||||
// Command the devices to off first before switching off the power. The handleModeReached
|
||||
// custom implementation will take care of starting the power state machine.
|
||||
AssemblyBase::startTransition(mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
using namespace duallane;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
refreshHelperModes();
|
||||
powerStateMachine(mode, submode);
|
||||
if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) {
|
||||
if (state == States::MODE_COMMANDING) {
|
||||
handleNormalOrOnModeCmd(mode, submode);
|
||||
}
|
||||
result = handleNormalOrOnModeCmd(mode, submode);
|
||||
} else {
|
||||
modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF);
|
||||
modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE);
|
||||
@ -55,36 +87,39 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode)
|
||||
modeTable[ModeTableIdx::GPS].setMode(MODE_OFF);
|
||||
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
|
||||
HybridIterator<ModeListEntry> tableIter(modeTable.begin(), modeTable.end());
|
||||
executeTable(tableIter);
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) {
|
||||
using namespace duallane;
|
||||
refreshHelperModes();
|
||||
if (submode == A_SIDE) {
|
||||
// if (state == PwrStates::SWITCHING_POWER) {
|
||||
// // Wrong mode
|
||||
// sif::error << "Wrong mode, currently switching power" << std::endl;
|
||||
// return RETURN_OK;
|
||||
// }
|
||||
if (wantedSubmode == A_SIDE) {
|
||||
if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or
|
||||
(helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or
|
||||
helper.gpsMode != wantedMode) {
|
||||
submode = B_SIDE;
|
||||
helper.gpsMode != MODE_ON) {
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
}
|
||||
return RETURN_OK;
|
||||
} else if (submode == B_SIDE) {
|
||||
} else if (wantedSubmode == B_SIDE) {
|
||||
if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or
|
||||
(helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or
|
||||
helper.gpsMode != wantedMode) {
|
||||
submode = DUAL_MODE;
|
||||
helper.gpsMode != MODE_ON) {
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
}
|
||||
return RETURN_OK;
|
||||
} else if (submode == DUAL_MODE) {
|
||||
} else if (wantedSubmode == DUAL_MODE) {
|
||||
if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode and
|
||||
helper.gyro2AdisIdSideB != wantedMode and helper.gyro3SideBMode != wantedMode) or
|
||||
(helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode and
|
||||
helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or
|
||||
helper.gpsMode != wantedMode) {
|
||||
helper.gpsMode != MODE_ON) {
|
||||
// Trigger event, but don't start any other transitions. This is the last fallback mode.
|
||||
if (dualModeErrorSwitch) {
|
||||
triggerEvent(NOT_ENOUGH_DEVICES_DUAL_MODE, 0, 0);
|
||||
@ -98,35 +133,41 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) {
|
||||
using namespace duallane;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) {
|
||||
if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (isUseable(objectId, devMode)) {
|
||||
if (mode != MODE_OFF) {
|
||||
modeTable[tableIdx].setMode(devMode);
|
||||
if (devMode == MODE_ON) {
|
||||
modeTable[tableIdx].setMode(mode);
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
|
||||
} else {
|
||||
result = NEED_SECOND_STEP;
|
||||
modeTable[tableIdx].setMode(MODE_ON);
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
} else if (devMode == MODE_ON) {
|
||||
} else if (mode == MODE_ON) {
|
||||
if (isUseable(objectId, devMode)) {
|
||||
modeTable[tableIdx].setMode(MODE_ON);
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
switch (this->submode) {
|
||||
if (this->mode == MODE_OFF and mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (internalState != STATE_SECOND_STEP) {
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
switch (submode) {
|
||||
case (A_SIDE): {
|
||||
cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A);
|
||||
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
|
||||
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
|
||||
cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A);
|
||||
cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS);
|
||||
ReturnValue_t result = gpioIF->pullLow(gpioIds::GNSS_SELECT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
modeTable[ModeTableIdx::GPS].setMode(MODE_ON);
|
||||
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
|
||||
if (gpioIF->pullLow(gpioIds::GNSS_SELECT) != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low"
|
||||
<< std::endl;
|
||||
@ -148,8 +189,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
||||
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
|
||||
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
|
||||
cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS);
|
||||
gpioIF->pullHigh(gpioIds::GNSS_SELECT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (gpioIF->pullHigh(gpioIds::GNSS_SELECT) != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high"
|
||||
<< std::endl;
|
||||
@ -175,12 +215,13 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
||||
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
|
||||
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
|
||||
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
|
||||
ReturnValue_t status = RETURN_OK;
|
||||
if (defaultSubmode == Submodes::A_SIDE) {
|
||||
result = gpioIF->pullLow(gpioIds::GNSS_SELECT);
|
||||
status = gpioIF->pullLow(gpioIds::GNSS_SELECT);
|
||||
} else {
|
||||
result = gpioIF->pullHigh(gpioIds::GNSS_SELECT);
|
||||
status = gpioIF->pullHigh(gpioIds::GNSS_SELECT);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (status != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to"
|
||||
"default side for dual mode"
|
||||
@ -196,90 +237,165 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
||||
return result;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t switchStateA = RETURN_OK;
|
||||
ReturnValue_t switchStateB = RETURN_OK;
|
||||
if (state == States::IDLE or state == States::SWITCHING_POWER) {
|
||||
switchStateA = pwrSwitcher->getSwitchState(SWITCH_A);
|
||||
switchStateB = pwrSwitcher->getSwitchState(SWITCH_B);
|
||||
ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
using namespace duallane;
|
||||
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool AcsBoardAssembly::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;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::handleModeReached() {
|
||||
using namespace duallane;
|
||||
if (targetMode == MODE_OFF) {
|
||||
pwrStateMachine.start(targetMode, targetSubmode);
|
||||
// Now we can switch off the power. After that, the AssemblyBase::handleModeReached function
|
||||
// will be called
|
||||
pwrStateMachineWrapper();
|
||||
} else {
|
||||
finishModeOp();
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) {
|
||||
using namespace duallane;
|
||||
// Some ACS board components are required for Safe-Mode. It would be good if the software
|
||||
// transitions from A side to B side and from B side to dual mode autonomously
|
||||
// to ensure that that enough sensors are available without an operators intervention.
|
||||
// Therefore, the lost mode handler was overwritten to start these transitions
|
||||
Submode_t nextSubmode = Submodes::A_SIDE;
|
||||
if (submode == Submodes::A_SIDE) {
|
||||
nextSubmode = Submodes::B_SIDE;
|
||||
}
|
||||
if (not tryingOtherSide) {
|
||||
triggerEvent(CANT_KEEP_MODE, mode, submode);
|
||||
startTransition(mode, nextSubmode);
|
||||
tryingOtherSide = true;
|
||||
} else {
|
||||
// Not sure when this would happen. This flag is reset if the mode was reached. If it
|
||||
// was not reached, the transition failure handler should be called.
|
||||
sif::error << "AcsBoardAssembly::handleChildrenLostMode: Wrong handler called" << std::endl;
|
||||
triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode);
|
||||
startTransition(mode, Submodes::DUAL_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
using namespace duallane;
|
||||
Submode_t nextSubmode = Submodes::A_SIDE;
|
||||
if (submode == Submodes::A_SIDE) {
|
||||
nextSubmode = Submodes::B_SIDE;
|
||||
}
|
||||
// Check whether the transition was started because the mode could not be kept (not commanded).
|
||||
// If this is not the case, start transition to other side. If it is the case, start
|
||||
// transition to dual mode.
|
||||
if (not tryingOtherSide) {
|
||||
triggerEvent(CANT_KEEP_MODE, mode, submode);
|
||||
startTransition(mode, nextSubmode);
|
||||
tryingOtherSide = true;
|
||||
} else {
|
||||
triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode);
|
||||
startTransition(mode, Submodes::DUAL_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::setPreferredSide(duallane::Submodes submode) {
|
||||
using namespace duallane;
|
||||
if (submode != Submodes::A_SIDE and submode != Submodes::B_SIDE) {
|
||||
return;
|
||||
}
|
||||
if (mode == MODE_OFF) {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) {
|
||||
state = States::MODE_COMMANDING;
|
||||
return;
|
||||
}
|
||||
this->defaultSubmode = submode;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::selectGpsInDualMode(duallane::Submodes side) {
|
||||
using namespace duallane;
|
||||
if (submode != Submodes::DUAL_MODE) {
|
||||
return;
|
||||
}
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (side == Submodes::A_SIDE) {
|
||||
result = gpioIF->pullLow(gpioIds::GNSS_SELECT);
|
||||
} else {
|
||||
switch (this->submode) {
|
||||
case (A_SIDE): {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_ON and
|
||||
switchStateB == PowerSwitchIF::SWITCH_OFF) {
|
||||
state = States::MODE_COMMANDING;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (B_SIDE): {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_OFF and
|
||||
switchStateB == PowerSwitchIF::SWITCH_ON) {
|
||||
state = States::MODE_COMMANDING;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (DUAL_MODE): {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) {
|
||||
state = States::MODE_COMMANDING;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = gpioIF->pullHigh(gpioIds::GNSS_SELECT);
|
||||
}
|
||||
if (state == States::IDLE) {
|
||||
if (mode == MODE_OFF) {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, false);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, false);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "AcsBoardAssembly::switchGpsInDualMode: Switching GPS failed" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::refreshHelperModes() {
|
||||
try {
|
||||
helper.gyro0SideAMode = childrenMap.at(helper.gyro0AdisIdSideA).mode;
|
||||
helper.gyro1SideAMode = childrenMap.at(helper.gyro1L3gIdSideA).mode;
|
||||
helper.gyro2SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode;
|
||||
helper.gyro3SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode;
|
||||
helper.mgm0SideAMode = childrenMap.at(helper.mgm0Lis3IdSideA).mode;
|
||||
helper.mgm1SideAMode = childrenMap.at(helper.mgm1Rm3100IdSideA).mode;
|
||||
helper.mgm2SideBMode = childrenMap.at(helper.mgm2Lis3IdSideB).mode;
|
||||
helper.mgm3SideBMode = childrenMap.at(helper.mgm3Rm3100IdSideB).mode;
|
||||
helper.gpsMode = childrenMap.at(helper.gpsId).mode;
|
||||
} catch (const std::out_of_range& e) {
|
||||
sif::error << "AcsBoardAssembly::refreshHelperModes: Invalid map: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) {
|
||||
entry.setObject(id);
|
||||
entry.setMode(MODE_OFF);
|
||||
entry.setSubmode(SUBMODE_NONE);
|
||||
entry.setInheritSubmode(false);
|
||||
modeTable.insert(entry);
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::finishModeOp() {
|
||||
using namespace duallane;
|
||||
AssemblyBase::handleModeReached();
|
||||
pwrStateMachine.reset();
|
||||
powerRetryCounter = 0;
|
||||
tryingOtherSide = false;
|
||||
dualModeErrorSwitch = true;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper() {
|
||||
using namespace duallane;
|
||||
OpCodes opCode = pwrStateMachine.powerStateMachine();
|
||||
if (opCode == OpCodes::NONE) {
|
||||
return RETURN_OK;
|
||||
} else if (opCode == OpCodes::FINISH_OP) {
|
||||
finishModeOp();
|
||||
} else if (opCode == OpCodes::START_TRANSITION) {
|
||||
AssemblyBase::startTransition(targetMode, targetSubmode);
|
||||
} else if (opCode == OpCodes::TIMEOUT_OCCURED) {
|
||||
if (powerRetryCounter == 0) {
|
||||
powerRetryCounter++;
|
||||
pwrStateMachine.reset();
|
||||
} else {
|
||||
switch (submode) {
|
||||
case (A_SIDE): {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, true);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (B_SIDE): {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, false);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (DUAL_MODE): {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, true);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::warning << "Timeout occured in power state machine" << std::endl;
|
||||
#endif
|
||||
triggerEvent(POWER_STATE_MACHINE_TIMEOUT, 0, 0);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
state = States::SWITCHING_POWER;
|
||||
}
|
||||
if (state == States::SWITCHING_POWER) {
|
||||
// TODO: Could check for a timeout (temporal or cycles) here and resend command
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::initialize() {
|
||||
@ -315,118 +431,9 @@ ReturnValue_t AcsBoardAssembly::initialize() {
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
bool AcsBoardAssembly::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;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::handleModeReached() {
|
||||
AssemblyBase::handleModeReached();
|
||||
state = States::IDLE;
|
||||
tryingOtherSide = false;
|
||||
dualModeErrorSwitch = true;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) {
|
||||
// Some ACS board components are required for Safe-Mode. It would be good if the software
|
||||
// transitions from A side to B side and from B side to dual mode autonomously
|
||||
// to ensure that that enough sensors are available without an operators intervention.
|
||||
// Therefore, the lost mode handler was overwritten to start these transitions
|
||||
Submode_t nextSubmode = Submodes::A_SIDE;
|
||||
if (submode == Submodes::A_SIDE) {
|
||||
nextSubmode = Submodes::B_SIDE;
|
||||
}
|
||||
if (not tryingOtherSide) {
|
||||
triggerEvent(CANT_KEEP_MODE, mode, submode);
|
||||
startTransition(mode, nextSubmode);
|
||||
tryingOtherSide = true;
|
||||
} else {
|
||||
// Not sure when this would happen. This flag is reset if the mode was reached. If it
|
||||
// was not reached, the transition failure handler should be called.
|
||||
sif::error << "AcsBoardAssembly::handleChildrenLostMode: Wrong handler called" << std::endl;
|
||||
triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode);
|
||||
startTransition(mode, Submodes::DUAL_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
Submode_t nextSubmode = Submodes::A_SIDE;
|
||||
if (submode == Submodes::A_SIDE) {
|
||||
nextSubmode = Submodes::B_SIDE;
|
||||
}
|
||||
// Check whether the transition was started because the mode could not be kept (not commanded).
|
||||
// If this is not the case, start transition to other side. If it is the case, start
|
||||
// transition to dual mode.
|
||||
if (not tryingOtherSide) {
|
||||
triggerEvent(CANT_KEEP_MODE, mode, submode);
|
||||
startTransition(mode, nextSubmode);
|
||||
tryingOtherSide = true;
|
||||
} else {
|
||||
triggerEvent(TRANSITION_OTHER_SIDE_FAILED, mode, targetSubmode);
|
||||
startTransition(mode, Submodes::DUAL_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::setPreferredSide(Submodes submode) {
|
||||
if (submode != Submodes::A_SIDE and submode != Submodes::B_SIDE) {
|
||||
return;
|
||||
}
|
||||
this->defaultSubmode = submode;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::selectGpsInDualMode(Submodes side) {
|
||||
if (submode != Submodes::DUAL_MODE) {
|
||||
return;
|
||||
}
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (side == Submodes::A_SIDE) {
|
||||
result = gpioIF->pullLow(gpioIds::GNSS_SELECT);
|
||||
} else {
|
||||
result = gpioIF->pullHigh(gpioIds::GNSS_SELECT);
|
||||
}
|
||||
result = registerChild(helper.gpsId);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "AcsBoardAssembly::switchGpsInDualMode: Switching GPS failed" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::refreshHelperModes() {
|
||||
helper.gyro0SideAMode = childrenMap[helper.gyro0AdisIdSideA].mode;
|
||||
helper.gyro1SideAMode = childrenMap[helper.gyro1L3gIdSideA].mode;
|
||||
helper.gyro2SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode;
|
||||
helper.gyro3SideBMode = childrenMap[helper.gyro2AdisIdSideB].mode;
|
||||
helper.mgm0SideAMode = childrenMap[helper.mgm0Lis3IdSideA].mode;
|
||||
helper.mgm1SideAMode = childrenMap[helper.mgm1Rm3100IdSideA].mode;
|
||||
helper.mgm2SideBMode = childrenMap[helper.mgm2Lis3IdSideB].mode;
|
||||
helper.mgm3SideBMode = childrenMap[helper.mgm3Rm3100IdSideB].mode;
|
||||
}
|
||||
|
||||
void AcsBoardAssembly::initModeTableEntry(object_id_t id, ModeListEntry& entry) {
|
||||
entry.setObject(id);
|
||||
entry.setMode(MODE_OFF);
|
||||
entry.setSubmode(SUBMODE_NONE);
|
||||
entry.setInheritSubmode(false);
|
||||
modeTable.insert(entry);
|
||||
return AssemblyBase::initialize();
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||
|
||||
#include "DualLanePowerStateMachine.h"
|
||||
|
||||
struct AcsBoardHelper {
|
||||
AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id,
|
||||
object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id,
|
||||
@ -17,7 +19,8 @@ struct AcsBoardHelper {
|
||||
gyro0AdisIdSideA(gyro0Id),
|
||||
gyro1L3gIdSideA(gyro1Id),
|
||||
gyro2AdisIdSideB(gyro2Id),
|
||||
gyro3L3gIdSideB(gyro3Id) {}
|
||||
gyro3L3gIdSideB(gyro3Id),
|
||||
gpsId(gpsId) {}
|
||||
|
||||
object_id_t mgm0Lis3IdSideA = objects::NO_OBJECT;
|
||||
object_id_t mgm1Rm3100IdSideA = objects::NO_OBJECT;
|
||||
@ -57,6 +60,17 @@ enum ModeTableIdx : uint8_t {
|
||||
class PowerSwitchIF;
|
||||
class GpioIF;
|
||||
|
||||
/**
|
||||
* @brief Assembly class which manages redundant ACS board sides
|
||||
* @details
|
||||
* This class takes care of ensuring that enough devices on the ACS board are available at all
|
||||
* times. It does so by doing autonomous transitions to the redundant side or activating both sides
|
||||
* if not enough devices are available.
|
||||
*
|
||||
* This class also takes care of switching on the A side and/or B side power lanes. Normally,
|
||||
* doing this task would be performed by the device handlers, but this is not possible for the
|
||||
* ACS board where multiple sensors share the same power supply.
|
||||
*/
|
||||
class AcsBoardAssembly : public AssemblyBase {
|
||||
public:
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_BOARD_ASS;
|
||||
@ -64,21 +78,22 @@ class AcsBoardAssembly : public AssemblyBase {
|
||||
event::makeEvent(SUBSYSTEM_ID, 0, severity::HIGH);
|
||||
static constexpr Event NOT_ENOUGH_DEVICES_DUAL_MODE =
|
||||
event::makeEvent(SUBSYSTEM_ID, 1, severity::HIGH);
|
||||
static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9;
|
||||
static constexpr Event POWER_STATE_MACHINE_TIMEOUT =
|
||||
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
||||
|
||||
enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 };
|
||||
static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9;
|
||||
|
||||
AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher,
|
||||
AcsBoardHelper helper, GpioIF* gpioIF);
|
||||
|
||||
void setPreferredSide(Submodes submode);
|
||||
void setPreferredSide(duallane::Submodes submode);
|
||||
|
||||
/**
|
||||
* In dual mode, the A side or the B side GPS device can be used, but not both.
|
||||
* This function can be used to switch the used GPS device.
|
||||
* @param side
|
||||
*/
|
||||
void selectGpsInDualMode(Submodes side);
|
||||
void selectGpsInDualMode(duallane::Submodes side);
|
||||
|
||||
private:
|
||||
static constexpr pcduSwitches::Switches SWITCH_A =
|
||||
@ -86,13 +101,14 @@ class AcsBoardAssembly : public AssemblyBase {
|
||||
static constexpr pcduSwitches::Switches SWITCH_B =
|
||||
pcduSwitches::Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3;
|
||||
|
||||
enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE;
|
||||
|
||||
PowerSwitchIF* pwrSwitcher = nullptr;
|
||||
// This helper object complete encapsulates power switching
|
||||
DualLanePowerStateMachine pwrStateMachine;
|
||||
bool tryingOtherSide = false;
|
||||
AcsBoardHelper helper;
|
||||
GpioIF* gpioIF = nullptr;
|
||||
Submodes defaultSubmode = Submodes::A_SIDE;
|
||||
uint8_t powerRetryCounter = 0;
|
||||
// duallane::PwrStates state = duallane::PwrStates::IDLE;
|
||||
duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE;
|
||||
bool dualModeErrorSwitch = true;
|
||||
FixedArrayList<ModeListEntry, NUMBER_DEVICES_MODE_TABLE> modeTable;
|
||||
|
||||
@ -102,6 +118,8 @@ class AcsBoardAssembly : public AssemblyBase {
|
||||
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 performChildOperation() override;
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void handleModeReached() override;
|
||||
void handleModeTransitionFailed(ReturnValue_t result) override;
|
||||
void handleChildrenLostMode(ReturnValue_t result) override;
|
||||
@ -114,9 +132,16 @@ class AcsBoardAssembly : public AssemblyBase {
|
||||
*/
|
||||
bool isUseable(object_id_t object, Mode_t mode);
|
||||
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
||||
void powerStateMachine(Mode_t mode, Submode_t submode);
|
||||
void initModeTableEntry(object_id_t id, ModeListEntry& entry);
|
||||
void refreshHelperModes();
|
||||
void finishModeOp();
|
||||
/**
|
||||
* Thin wrapper function which is required because the helper class
|
||||
* can not access protected member functions.
|
||||
* @param mode
|
||||
* @param submode
|
||||
*/
|
||||
ReturnValue_t pwrStateMachineWrapper();
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */
|
||||
|
@ -6,4 +6,5 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE
|
||||
EiveSystem.cpp
|
||||
ComSubsystem.cpp
|
||||
TcsSubsystem.cpp
|
||||
DualLanePowerStateMachine.cpp
|
||||
)
|
134
mission/system/DualLanePowerStateMachine.cpp
Normal file
134
mission/system/DualLanePowerStateMachine.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include "DualLanePowerStateMachine.h"
|
||||
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
|
||||
DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches switchA,
|
||||
pcduSwitches::Switches switchB,
|
||||
PowerSwitchIF* pwrSwitcher,
|
||||
dur_millis_t checkTimeout)
|
||||
: SWITCH_A(switchA), SWITCH_B(switchB), pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {}
|
||||
|
||||
void DualLanePowerStateMachine::setCheckTimeout(dur_millis_t timeout) {
|
||||
checkTimeout.setTimeout(timeout);
|
||||
}
|
||||
|
||||
void DualLanePowerStateMachine::start(Mode_t mode, Submode_t submode) {
|
||||
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() {
|
||||
using namespace duallane;
|
||||
ReturnValue_t switchStateA = RETURN_OK;
|
||||
ReturnValue_t switchStateB = RETURN_OK;
|
||||
if (state == PwrStates::IDLE or state == PwrStates::MODE_COMMANDING) {
|
||||
return duallane::OpCodes::NONE;
|
||||
}
|
||||
if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) {
|
||||
switchStateA = pwrSwitcher->getSwitchState(SWITCH_A);
|
||||
switchStateB = pwrSwitcher->getSwitchState(SWITCH_B);
|
||||
} else {
|
||||
return OpCodes::NONE;
|
||||
}
|
||||
if (targetMode == HasModesIF::MODE_OFF) {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) {
|
||||
state = PwrStates::IDLE;
|
||||
return OpCodes::FINISH_OP;
|
||||
}
|
||||
} else {
|
||||
switch (targetSubmode) {
|
||||
case (A_SIDE): {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_ON and
|
||||
switchStateB == PowerSwitchIF::SWITCH_OFF) {
|
||||
state = PwrStates::MODE_COMMANDING;
|
||||
return OpCodes::START_TRANSITION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (B_SIDE): {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_OFF and
|
||||
switchStateB == PowerSwitchIF::SWITCH_ON) {
|
||||
state = PwrStates::MODE_COMMANDING;
|
||||
return OpCodes::START_TRANSITION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (DUAL_MODE): {
|
||||
if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) {
|
||||
state = PwrStates::MODE_COMMANDING;
|
||||
return OpCodes::START_TRANSITION;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state == PwrStates::SWITCHING_POWER) {
|
||||
if (targetMode == HasModesIF::MODE_OFF) {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
checkTimeout.resetTimer();
|
||||
} else {
|
||||
switch (targetSubmode) {
|
||||
case (A_SIDE): {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
checkTimeout.resetTimer();
|
||||
break;
|
||||
}
|
||||
case (B_SIDE): {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_OFF) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
checkTimeout.resetTimer();
|
||||
break;
|
||||
}
|
||||
case (DUAL_MODE): {
|
||||
if (switchStateA != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON);
|
||||
}
|
||||
if (switchStateB != PowerSwitchIF::SWITCH_ON) {
|
||||
pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_ON);
|
||||
}
|
||||
checkTimeout.resetTimer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = PwrStates::CHECKING_POWER;
|
||||
}
|
||||
if (state == PwrStates::CHECKING_POWER) {
|
||||
if (checkTimeout.hasTimedOut()) {
|
||||
return OpCodes::TIMEOUT_OCCURED;
|
||||
}
|
||||
}
|
||||
return OpCodes::NONE;
|
||||
}
|
||||
|
||||
void DualLanePowerStateMachine::reset() {
|
||||
state = duallane::PwrStates::IDLE;
|
||||
targetMode = HasModesIF::MODE_OFF;
|
||||
targetSubmode = 0;
|
||||
checkTimeout.resetTimer();
|
||||
}
|
33
mission/system/DualLanePowerStateMachine.h
Normal file
33
mission/system/DualLanePowerStateMachine.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_
|
||||
#define MISSION_SYSTEM_DUALLANEPOWERSTATEMACHINE_H_
|
||||
|
||||
#include <devices/powerSwitcherList.h>
|
||||
#include <fsfw/modes/HasModesIF.h>
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
class AssemblyBase;
|
||||
class PowerSwitchIF;
|
||||
|
||||
class DualLanePowerStateMachine : public HasReturnvaluesIF {
|
||||
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();
|
||||
const pcduSwitches::Switches SWITCH_A;
|
||||
const pcduSwitches::Switches SWITCH_B;
|
||||
|
||||
private:
|
||||
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_ */
|
14
mission/system/definitions.h
Normal file
14
mission/system/definitions.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef MISSION_SYSTEM_DEFINITIONS_H_
|
||||
#define MISSION_SYSTEM_DEFINITIONS_H_
|
||||
|
||||
#include <fsfw/modes/ModeMessage.h>
|
||||
|
||||
namespace duallane {
|
||||
|
||||
enum class PwrStates { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING };
|
||||
enum class OpCodes { NONE, FINISH_OP, START_TRANSITION, TIMEOUT_OCCURED };
|
||||
enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 };
|
||||
|
||||
} // namespace duallane
|
||||
|
||||
#endif /* MISSION_SYSTEM_DEFINITIONS_H_ */
|
2
thirdparty/arcsec_star_tracker
vendored
2
thirdparty/arcsec_star_tracker
vendored
@ -1 +1 @@
|
||||
Subproject commit b1594df9303056456604726592635d8a1c987e75
|
||||
Subproject commit 93e93965e2c6405170b62c523dea1990db02d2ad
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
||||
Subproject commit e1d43b8de9e2b09493245fdf6c050b8b819eab41
|
||||
Subproject commit abe9c8bc000e834b99a2c367ed10f927eeb666b0
|
Loading…
Reference in New Issue
Block a user