Merge branch 'develop' into acs-flp-safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
This commit is contained in:
@ -1,13 +1,17 @@
|
||||
add_subdirectory(controller)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(devices)
|
||||
add_subdirectory(utility)
|
||||
add_subdirectory(memory)
|
||||
add_subdirectory(tmtc)
|
||||
add_subdirectory(system)
|
||||
add_subdirectory(csp)
|
||||
add_subdirectory(com)
|
||||
add_subdirectory(acs)
|
||||
add_subdirectory(power)
|
||||
add_subdirectory(tcs)
|
||||
add_subdirectory(payload)
|
||||
add_subdirectory(cfdp)
|
||||
add_subdirectory(config)
|
||||
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE acsDefs.cpp payloadDefs.cpp
|
||||
trace.cpp)
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE SolarArrayDeploymentHandler.cpp genericFactory.cpp
|
||||
pollingSeqTables.cpp scheduling.cpp)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "SolarArrayDeploymentHandler.h"
|
||||
|
||||
#include <fsfw/filesystem/HasFileSystemIF.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <mission/SolarArrayDeploymentHandler.h>
|
||||
#include <mission/utility/trace.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
@ -11,14 +11,13 @@
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw_hal/common/gpio/GpioCookie.h"
|
||||
#include "mission/trace.h"
|
||||
|
||||
static constexpr bool DEBUG_MODE = true;
|
||||
|
||||
SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_,
|
||||
GpioIF& gpioInterface,
|
||||
PowerSwitchIF& mainLineSwitcher_,
|
||||
pcdu::Switches mainLineSwitch_,
|
||||
power::Switches mainLineSwitch_,
|
||||
gpioId_t deplSA1, gpioId_t deplSA2,
|
||||
SdCardMountedIF& sdcMountedIF)
|
||||
: SystemObject(setObjectId_),
|
@ -2,6 +2,7 @@
|
||||
#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
||||
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
#include <mission/utility/trace.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@ -19,7 +20,6 @@
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "mission/memory/SdCardMountedIF.h"
|
||||
#include "mission/trace.h"
|
||||
#include "returnvalues/classIds.h"
|
||||
|
||||
enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 };
|
||||
@ -107,7 +107,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
|
||||
* @param burnTimeMs Time duration the power will be applied to the burn wires.
|
||||
*/
|
||||
SolarArrayDeploymentHandler(object_id_t setObjectId, GpioIF& gpio,
|
||||
PowerSwitchIF& mainLineSwitcher, pcdu::Switches mainLineSwitch,
|
||||
PowerSwitchIF& mainLineSwitcher, power::Switches mainLineSwitch,
|
||||
gpioId_t deplSA1, gpioId_t deplSA2, SdCardMountedIF& sdcMountedIF);
|
||||
|
||||
virtual ~SolarArrayDeploymentHandler();
|
18
mission/acs/CMakeLists.txt
Normal file
18
mission/acs/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE GyrAdis1650XHandler.cpp
|
||||
GyrL3gCustomHandler.cpp
|
||||
ImtqHandler.cpp
|
||||
MgmLis3CustomHandler.cpp
|
||||
MgmRm3100CustomHandler.cpp
|
||||
RwHandler.cpp
|
||||
SusHandler.cpp
|
||||
gyroAdisHelpers.cpp
|
||||
imtqHelpers.cpp
|
||||
rwHelpers.cpp
|
||||
defs.cpp)
|
||||
|
||||
# Dependency on proprietary library
|
||||
if(TGT_BSP MATCHES "arm/q7s")
|
||||
add_subdirectory(str)
|
||||
endif()
|
@ -1,8 +1,8 @@
|
||||
#include "mission/devices/GyrAdis1650XHandler.h"
|
||||
#include "GyrAdis1650XHandler.h"
|
||||
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "mission/devices/devicedefinitions/acsPolling.h"
|
||||
#include "mission/acs/acsBoardPolling.h"
|
||||
|
||||
GyrAdis1650XHandler::GyrAdis1650XHandler(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF *comCookie, adis1650x::Type type)
|
||||
@ -28,11 +28,7 @@ void GyrAdis1650XHandler::doStartUp() {
|
||||
}
|
||||
if (breakCountdown.hasTimedOut()) {
|
||||
updatePeriodicReply(true, adis1650x::REPLY);
|
||||
if (goToNormalMode) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else {
|
||||
setMode(MODE_ON);
|
||||
}
|
||||
setMode(MODE_ON);
|
||||
internalState = InternalState::NONE;
|
||||
}
|
||||
}
|
||||
@ -91,12 +87,11 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
|
||||
getMode() == _MODE_POWER_DOWN) {
|
||||
return IGNORE_FULL_PACKET;
|
||||
}
|
||||
*foundLen = remainingSize;
|
||||
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
||||
*foundLen = remainingSize;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
*foundId = adis1650x::REPLY;
|
||||
*foundLen = remainingSize;
|
||||
if (internalState == InternalState::SHUTDOWN) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
@ -208,8 +203,6 @@ adis1650x::BurstModes GyrAdis1650XHandler::getBurstMode() {
|
||||
return adis1650x::burstModeFromMscCtrl(currentCtrlReg);
|
||||
}
|
||||
|
||||
void GyrAdis1650XHandler::setToGoToNormalModeImmediately() { goToNormalMode = true; }
|
||||
|
||||
void GyrAdis1650XHandler::enablePeriodicPrintouts(bool enable, uint8_t divider) {
|
||||
periodicPrintout = enable;
|
||||
debugDivider.setDivider(divider);
|
@ -1,8 +1,8 @@
|
||||
#ifndef MISSION_DEVICES_GYROADIS16507HANDLER_H_
|
||||
#define MISSION_DEVICES_GYROADIS16507HANDLER_H_
|
||||
|
||||
#include <mission/devices/devicedefinitions/acsPolling.h>
|
||||
#include <mission/devices/devicedefinitions/gyroAdisHelpers.h>
|
||||
#include <mission/acs/acsBoardPolling.h>
|
||||
#include <mission/acs/gyroAdisHelpers.h>
|
||||
|
||||
#include "FSFWConfig.h"
|
||||
#include "OBSWConfig.h"
|
||||
@ -21,7 +21,6 @@ class GyrAdis1650XHandler : public DeviceHandlerBase {
|
||||
adis1650x::Type type);
|
||||
|
||||
void enablePeriodicPrintouts(bool enable, uint8_t divider);
|
||||
void setToGoToNormalModeImmediately();
|
||||
|
||||
// DeviceHandlerBase abstract function implementation
|
||||
void doStartUp() override;
|
||||
@ -47,7 +46,6 @@ class GyrAdis1650XHandler : public DeviceHandlerBase {
|
||||
AdisGyroConfigDataset configDataset;
|
||||
double sensitivity = adis1650x::SENSITIVITY_UNSET;
|
||||
|
||||
bool goToNormalMode = false;
|
||||
bool warningSwitch = true;
|
||||
|
||||
enum class InternalState { NONE, STARTUP, SHUTDOWN };
|
@ -1,10 +1,10 @@
|
||||
|
||||
#include <mission/devices/GyrL3gCustomHandler.h>
|
||||
#include <mission/acs/GyrL3gCustomHandler.h>
|
||||
#include <mission/acs/acsBoardPolling.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "mission/devices/devicedefinitions/acsPolling.h"
|
||||
|
||||
GyrL3gCustomHandler::GyrL3gCustomHandler(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF *comCookie, uint32_t transitionDelayMs)
|
||||
@ -23,11 +23,7 @@ void GyrL3gCustomHandler::doStartUp() {
|
||||
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
if (commandExecuted) {
|
||||
if (goNormalModeImmediately) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
setMode(MODE_ON);
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
}
|
||||
@ -103,12 +99,11 @@ ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len
|
||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
|
||||
return IGNORE_FULL_PACKET;
|
||||
}
|
||||
*foundLen = len;
|
||||
if (len != sizeof(acs::GyroL3gReply)) {
|
||||
*foundLen = len;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
*foundId = l3gd20h::REPLY;
|
||||
*foundLen = len;
|
||||
*foundId = adis1650x::REPLY;
|
||||
if (internalState == InternalState::SHUTDOWN) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
@ -145,8 +140,6 @@ uint32_t GyrL3gCustomHandler::getTransitionDelayMs(Mode_t from, Mode_t to) {
|
||||
return this->transitionDelayMs;
|
||||
}
|
||||
|
||||
void GyrL3gCustomHandler::setToGoToNormalMode(bool enable) { this->goNormalModeImmediately = true; }
|
||||
|
||||
ReturnValue_t GyrL3gCustomHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
@ -4,7 +4,7 @@
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/acsPolling.h>
|
||||
#include <mission/acs/acsBoardPolling.h>
|
||||
|
||||
/**
|
||||
* @brief Device Handler for the L3GD20H gyroscope sensor
|
||||
@ -32,11 +32,6 @@ class GyrL3gCustomHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
void setAbsoluteLimits(float limitX, float limitY, float limitZ);
|
||||
|
||||
/**
|
||||
* @brief Configure device handler to go to normal mode immediately
|
||||
*/
|
||||
void setToGoToNormalMode(bool enable);
|
||||
|
||||
protected:
|
||||
/* DeviceHandlerBase overrides */
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
|
||||
@ -69,7 +64,6 @@ class GyrL3gCustomHandler : public DeviceHandlerBase {
|
||||
bool commandExecuted = false;
|
||||
|
||||
uint8_t statusReg = 0;
|
||||
bool goNormalModeImmediately = false;
|
||||
|
||||
uint8_t ctrlReg1Value = l3gd20h::CTRL_REG_1_VAL;
|
||||
uint8_t ctrlReg2Value = l3gd20h::CTRL_REG_2_VAL;
|
@ -20,7 +20,7 @@
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <fsfw/timemanager/clockDefinitions.h>
|
||||
#include <mission/devices/ImtqHandler.h>
|
||||
#include <mission/acs/ImtqHandler.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <fsfw/datapoollocal/LocalPoolVariable.tpp>
|
||||
@ -30,8 +30,9 @@
|
||||
static constexpr bool ACTUATION_WIRETAPPING = false;
|
||||
|
||||
ImtqHandler::ImtqHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
power::Switch_t pwrSwitcher)
|
||||
power::Switch_t pwrSwitcher, bool enableHkSets)
|
||||
: DeviceHandlerBase(objectId, comIF, comCookie),
|
||||
enableHkSets(enableHkSets),
|
||||
statusSet(this),
|
||||
dipoleSet(*this),
|
||||
rawMtmNoTorque(this),
|
||||
@ -150,19 +151,25 @@ void ImtqHandler::doStartUp() {
|
||||
}
|
||||
|
||||
void ImtqHandler::doShutDown() {
|
||||
updatePeriodicReply(false, imtq::cmdIds::REPLY_NO_TORQUE);
|
||||
updatePeriodicReply(false, imtq::cmdIds::REPLY_WITH_TORQUE);
|
||||
specialRequestActive = false;
|
||||
firstReplyCycle = true;
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
statusSet.setValidity(false, true);
|
||||
rawMtmNoTorque.setValidity(false, true);
|
||||
rawMtmWithTorque.setValidity(false, true);
|
||||
hkDatasetNoTorque.setValidity(false, true);
|
||||
hkDatasetWithTorque.setValidity(false, true);
|
||||
calMtmMeasurementSet.setValidity(false, true);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
if (internalState != InternalState::SHUTDOWN) {
|
||||
commandExecuted = false;
|
||||
internalState = InternalState::SHUTDOWN;
|
||||
}
|
||||
if (internalState == InternalState::SHUTDOWN and commandExecuted) {
|
||||
updatePeriodicReply(false, imtq::cmdIds::REPLY_NO_TORQUE);
|
||||
updatePeriodicReply(false, imtq::cmdIds::REPLY_WITH_TORQUE);
|
||||
specialRequestActive = false;
|
||||
firstReplyCycle = true;
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
statusSet.setValidity(false, true);
|
||||
rawMtmNoTorque.setValidity(false, true);
|
||||
rawMtmWithTorque.setValidity(false, true);
|
||||
hkDatasetNoTorque.setValidity(false, true);
|
||||
hkDatasetWithTorque.setValidity(false, true);
|
||||
calMtmMeasurementSet.setValidity(false, true);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
@ -177,7 +184,7 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
default: {
|
||||
*id = imtq::cmdIds::REQUEST;
|
||||
request.request = imtq::RequestType::DO_NOTHING;
|
||||
request.requestType = imtq::RequestType::DO_NOTHING;
|
||||
request.specialRequest = imtq::SpecialRequest::NONE;
|
||||
expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(&request);
|
||||
@ -189,7 +196,7 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
if (internalState == InternalState::STARTUP or internalState == InternalState::SHUTDOWN) {
|
||||
*id = imtq::cmdIds::REQUEST;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
@ -200,7 +207,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
|
||||
const uint8_t* commandData,
|
||||
size_t commandDataLen) {
|
||||
auto genericSpecialRequest = [&](imtq::SpecialRequest specialRequest) {
|
||||
request.request = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
request.requestType = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
request.specialRequest = specialRequest;
|
||||
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
|
||||
specialRequestActive = true;
|
||||
@ -237,9 +244,16 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (imtq::cmdIds::REQUEST): {
|
||||
request.request = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
request.requestType = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
request.specialRequest = imtq::SpecialRequest::NONE;
|
||||
// 6 ms integration time instead of 10 ms.
|
||||
request.integrationTimeSel = 2;
|
||||
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
|
||||
if (internalState == InternalState::SHUTDOWN) {
|
||||
request.mode = acs::SimpleSensorMode::OFF;
|
||||
} else {
|
||||
request.mode = acs::SimpleSensorMode::NORMAL;
|
||||
}
|
||||
rawPacket = reinterpret_cast<uint8_t*>(&request);
|
||||
rawPacketLen = sizeof(imtq::Request);
|
||||
return returnvalue::OK;
|
||||
@ -266,7 +280,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
|
||||
}
|
||||
|
||||
expectedReply = imtq::cmdIds::REPLY_WITH_TORQUE;
|
||||
request.request = imtq::RequestType::ACTUATE;
|
||||
request.requestType = imtq::RequestType::ACTUATE;
|
||||
request.specialRequest = imtq::SpecialRequest::NONE;
|
||||
std::memcpy(request.dipoles, dipoleSet.dipoles.value, sizeof(request.dipoles));
|
||||
request.torqueDuration = dipoleSet.currentTorqueDurationMs.value;
|
||||
@ -308,6 +322,9 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi
|
||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
|
||||
return IGNORE_FULL_PACKET;
|
||||
}
|
||||
if (internalState == InternalState::SHUTDOWN) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
if (remainingSize > 0) {
|
||||
*foundLen = remainingSize;
|
||||
*foundId = expectedReply;
|
||||
@ -778,9 +795,9 @@ ReturnValue_t ImtqHandler::initializeLocalDataPool(localpool::DataPool& localDat
|
||||
localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0}));
|
||||
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), false, 10.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), false, 10.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
@ -2,7 +2,7 @@
|
||||
#define MISSION_DEVICES_IMTQHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
#include <mission/acs/imtqHelpers.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "events/subsystemIdRanges.h"
|
||||
@ -18,7 +18,7 @@ class ImtqHandler : public DeviceHandlerBase {
|
||||
enum NormalPollingMode { UNCALIBRATED = 0, CALIBRATED = 1, BOTH = 2 };
|
||||
|
||||
ImtqHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
power::Switch_t pwrSwitcher);
|
||||
power::Switch_t pwrSwitcher, bool enableHkSets);
|
||||
virtual ~ImtqHandler();
|
||||
|
||||
void setPollingMode(NormalPollingMode pollMode);
|
||||
@ -85,6 +85,7 @@ class ImtqHandler : public DeviceHandlerBase {
|
||||
|
||||
enum class InternalState { NONE, STARTUP, SHUTDOWN } internalState = InternalState::NONE;
|
||||
bool commandExecuted = false;
|
||||
bool enableHkSets = false;
|
||||
|
||||
imtq::Request request{};
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <mission/devices/MgmLis3CustomHandler.h>
|
||||
#include "MgmLis3CustomHandler.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -20,7 +20,7 @@ void MgmLis3CustomHandler::doStartUp() {
|
||||
}
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
if (commandExecuted) {
|
||||
setMode(MODE_NORMAL);
|
||||
setMode(MODE_ON);
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
#include "mission/devices/devicedefinitions/acsPolling.h"
|
||||
#include "mission/acs/acsBoardPolling.h"
|
||||
|
||||
class PeriodicOperationDivider;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <mission/devices/MgmRm3100CustomHandler.h>
|
||||
#include "MgmRm3100CustomHandler.h"
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "fsfw/devicehandlers/DeviceHandlerMessage.h"
|
||||
@ -25,7 +25,7 @@ void MgmRm3100CustomHandler::doStartUp() {
|
||||
if (commandExecuted) {
|
||||
commandExecuted = false;
|
||||
internalState = InternalState::NONE;
|
||||
setMode(MODE_NORMAL);
|
||||
setMode(MODE_ON);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
#include "mission/devices/devicedefinitions/acsPolling.h"
|
||||
#include "mission/acs/acsBoardPolling.h"
|
||||
|
||||
/**
|
||||
* @brief Device Handler for the RM3100 geomagnetic magnetometer sensor
|
@ -33,6 +33,7 @@ void RwHandler::doStartUp() {
|
||||
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to high";
|
||||
}
|
||||
updatePeriodicReply(true, rws::REPLY_ID);
|
||||
statusSet.setReportingEnabled(true);
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
|
||||
@ -48,6 +49,7 @@ void RwHandler::doShutDown() {
|
||||
statusSet.referenceSpeed = 0.0;
|
||||
statusSet.state = 0;
|
||||
statusSet.setValidity(false, true);
|
||||
statusSet.setReportingEnabled(false);
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&tmDataset);
|
||||
@ -304,7 +306,7 @@ ReturnValue_t RwHandler::initializeLocalDataPool(localpool::DataPool& localDataP
|
||||
localDataPoolMap.emplace(rws::SPI_REG_OVERRUN_ERRORS, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(rws::SPI_TOTAL_ERRORS, new PoolEntry<uint32_t>({0}));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(statusSet.getSid(), false, 5.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(statusSet.getSid(), false, 12.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(tmDataset.getSid(), false, 30.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/rwHelpers.h>
|
||||
#include <mission/acs/rwHelpers.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "events/subsystemIdRanges.h"
|
@ -1,6 +1,6 @@
|
||||
#include "SusHandler.h"
|
||||
|
||||
#include <mission/devices/max1227.h>
|
||||
#include <mission/tcs/max1227.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -20,7 +20,7 @@ void SusHandler::doStartUp() {
|
||||
}
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
if (commandExecuted) {
|
||||
setMode(MODE_NORMAL);
|
||||
setMode(MODE_ON);
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
}
|
@ -3,11 +3,11 @@
|
||||
|
||||
#include <eive/eventSubsystemIds.h>
|
||||
#include <eive/resultClassIds.h>
|
||||
#include <mission/acs/susMax1227Helpers.h>
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
#include "mission/devices/devicedefinitions/acsPolling.h"
|
||||
#include "mission/devices/devicedefinitions/susMax1227Helpers.h"
|
||||
#include "mission/acs/acsBoardPolling.h"
|
||||
|
||||
class SusHandler : public DeviceHandlerBase {
|
||||
public:
|
@ -1,13 +1,13 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_ACSPOLLING_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_ACSPOLLING_H_
|
||||
|
||||
#include <mission/acs/defs.h>
|
||||
|
||||
#include "fsfw/thermal/tcsDefinitions.h"
|
||||
#include "gyroAdisHelpers.h"
|
||||
|
||||
namespace acs {
|
||||
|
||||
enum SimpleSensorMode { NORMAL = 0, OFF = 1 };
|
||||
|
||||
struct Adis1650XRequest {
|
||||
SimpleSensorMode mode;
|
||||
adis1650x::Type type;
|
@ -1,5 +1,5 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GPSDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_GPSDEFINITIONS_H_
|
||||
#ifndef MISSION_ACS_ARCHIVE_GPSDEFINITIONS_H_
|
||||
#define MISSION_ACS_ARCHIVE_GPSDEFINITIONS_H_
|
||||
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
#include "fsfw/datapoollocal/StaticLocalDataSet.h"
|
||||
@ -72,4 +72,4 @@ class GpsPrimaryDataset : public StaticLocalDataSet<18> {
|
||||
: StaticLocalDataSet(hkOwner, GpsHyperion::DATASET_ID) {}
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GPSDEFINITIONS_H_ */
|
||||
#endif /* MISSION_ACS_ARCHIVE_GPSDEFINITIONS_H_ */
|
@ -1,6 +1,7 @@
|
||||
#include "GPSHyperionHandler.h"
|
||||
|
||||
#include "devicedefinitions/GPSDefinitions.h"
|
||||
#include <mission/acs/archive/GPSDefinitions.h>
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "fsfw/timemanager/Clock.h"
|
||||
#include "lwgps/lwgps.h"
|
@ -1,7 +1,8 @@
|
||||
#ifndef MISSION_DEVICES_GPSHYPERIONHANDLER_H_
|
||||
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_
|
||||
|
||||
#include "devicedefinitions/GPSDefinitions.h"
|
||||
#include <mission/acs/archive/GPSDefinitions.h>
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "lwgps/lwgps.h"
|
@ -2,11 +2,11 @@
|
||||
#define MISSION_DEVICES_LEGACYSUSHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/devices/devicedefinitions/susMax1227Helpers.h>
|
||||
#include <mission/acs/susMax1227Helpers.h>
|
||||
#include <mission/tcs/max1227.h>
|
||||
|
||||
#include "events/subsystemIdRanges.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
#include "mission/devices/max1227.h"
|
||||
#include "returnvalues/classIds.h"
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
#include "acsDefs.h"
|
||||
#include "defs.h"
|
||||
|
||||
const char* acs::getModeStr(AcsMode mode) {
|
||||
static const char* modeStr = "UNKNOWN";
|
@ -6,6 +6,8 @@
|
||||
|
||||
namespace acs {
|
||||
|
||||
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
|
||||
|
||||
// These modes are the modes of the ACS controller and of the ACS subsystem.
|
||||
enum AcsMode : Mode_t {
|
||||
OFF = HasModesIF::MODE_OFF,
|
@ -1,5 +1,26 @@
|
||||
#include "imtqHelpers.h"
|
||||
|
||||
uint16_t imtq::integrationTimeFromSelectValue(uint8_t value) {
|
||||
switch (value) {
|
||||
case (0):
|
||||
return 2;
|
||||
case (1):
|
||||
return 3;
|
||||
case (2):
|
||||
return 6;
|
||||
case (3):
|
||||
return 10;
|
||||
case (4):
|
||||
return 20;
|
||||
case (5):
|
||||
return 40;
|
||||
case (6):
|
||||
return 80;
|
||||
default:
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
size_t imtq::getReplySize(CC::CC cc, size_t* optSecondSize) {
|
||||
switch (cc) {
|
||||
// Software reset is a bit special and can also cause a I2C NAK because
|
@ -5,11 +5,17 @@
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <mission/acs/defs.h>
|
||||
|
||||
class ImtqHandler;
|
||||
|
||||
// C garbage which can be included from gps.h
|
||||
#undef STATUS_SET
|
||||
|
||||
namespace imtq {
|
||||
|
||||
uint16_t integrationTimeFromSelectValue(uint8_t value);
|
||||
|
||||
enum class RequestType : uint8_t { MEASURE_NO_ACTUATION, ACTUATE, DO_NOTHING };
|
||||
|
||||
enum class SpecialRequest : uint8_t {
|
||||
@ -24,7 +30,8 @@ enum class SpecialRequest : uint8_t {
|
||||
};
|
||||
|
||||
struct Request {
|
||||
imtq::RequestType request = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||
imtq::RequestType requestType = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
|
||||
uint8_t integrationTimeSel = 3;
|
||||
int16_t dipoles[3]{};
|
||||
@ -54,9 +61,10 @@ static const ReturnValue_t CC_UNAVAILABLE = MAKE_RETURN_CODE(5);
|
||||
static const ReturnValue_t INTERNAL_PROCESSING_ERROR = MAKE_RETURN_CODE(6);
|
||||
static const ReturnValue_t REJECTED_WITHOUT_REASON = MAKE_RETURN_CODE(7);
|
||||
static const ReturnValue_t CMD_ERR_UNKNOWN = MAKE_RETURN_CODE(8);
|
||||
static constexpr ReturnValue_t STARTUP_CFG_ERROR = MAKE_RETURN_CODE(9);
|
||||
//! [EXPORT] : [COMMENT] The status reply to a self test command was received but no self test
|
||||
//! command has been sent. This should normally never happen.
|
||||
static const ReturnValue_t UNEXPECTED_SELF_TEST_REPLY = MAKE_RETURN_CODE(0xA7);
|
||||
static const ReturnValue_t UNEXPECTED_SELF_TEST_REPLY = MAKE_RETURN_CODE(10);
|
||||
|
||||
namespace cmdIds {
|
||||
|
||||
@ -159,6 +167,13 @@ enum CC : uint8_t {
|
||||
|
||||
} // namespace CC
|
||||
|
||||
namespace param {
|
||||
|
||||
static constexpr uint16_t SEL_MTM = 0x2002;
|
||||
static constexpr uint16_t INTEGRATION_TIME_SELECT = 0x2003;
|
||||
|
||||
} // namespace param
|
||||
|
||||
size_t getReplySize(CC::CC cc, size_t* optSecondSize = nullptr);
|
||||
|
||||
namespace mode {
|
73
mission/acs/str/ArcsecDatalinkLayer.cpp
Normal file
73
mission/acs/str/ArcsecDatalinkLayer.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include <mission/acs/str/ArcsecDatalinkLayer.h>
|
||||
|
||||
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) { slipInit(); }
|
||||
|
||||
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
|
||||
|
||||
ReturnValue_t ArcsecDatalinkLayer::checkRingBufForFrame(const uint8_t** decodedFrame,
|
||||
size_t& frameLen) {
|
||||
size_t currentLen = decodeRingBuf.getAvailableReadData();
|
||||
if (currentLen == 0) {
|
||||
return DEC_IN_PROGRESS;
|
||||
}
|
||||
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
|
||||
for (size_t idx = 0; idx < currentLen; idx++) {
|
||||
enum arc_dec_result decResult =
|
||||
arc_transport_decode_body(rxAnalysisBuffer[idx], &slipInfo, decodedRxFrame, &rxFrameSize);
|
||||
switch (decResult) {
|
||||
case ARC_DEC_INPROGRESS: {
|
||||
break;
|
||||
}
|
||||
case ARC_DEC_ERROR_FRAME_SHORT: {
|
||||
decodeRingBuf.deleteData(idx);
|
||||
return REPLY_TOO_SHORT;
|
||||
}
|
||||
case ARC_DEC_ERROR_CHECKSUM:
|
||||
decodeRingBuf.deleteData(idx);
|
||||
return CRC_FAILURE;
|
||||
case ARC_DEC_ASYNC:
|
||||
case ARC_DEC_SYNC: {
|
||||
// Reset length of SLIP struct for next frame
|
||||
slipInfo.length = 0;
|
||||
if (decodedFrame != nullptr) {
|
||||
*decodedFrame = decodedRxFrame;
|
||||
}
|
||||
frameLen = rxFrameSize;
|
||||
decodeRingBuf.deleteData(idx);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default:
|
||||
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
|
||||
break;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
decodeRingBuf.deleteData(currentLen);
|
||||
return DEC_IN_PROGRESS;
|
||||
}
|
||||
|
||||
ReturnValue_t ArcsecDatalinkLayer::feedData(const uint8_t* rawData, size_t rawDataLen) {
|
||||
if (rawDataLen > 4096) {
|
||||
sif::error << "ArcsecDatalinklayer: Can not write more than 4096 bytes to ring buffer"
|
||||
<< std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return decodeRingBuf.writeData(rawData, rawDataLen);
|
||||
}
|
||||
|
||||
void ArcsecDatalinkLayer::reset() {
|
||||
slipInit();
|
||||
decodeRingBuf.clear();
|
||||
}
|
||||
|
||||
void ArcsecDatalinkLayer::slipInit() {
|
||||
slip_decode_init(rxBufferArc, sizeof(rxBufferArc), &slipInfo);
|
||||
}
|
||||
|
||||
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
|
||||
size_t& size) {
|
||||
arc_transport_encode_body(data, length, txEncoded, &size);
|
||||
if (txFrame != nullptr) {
|
||||
*txFrame = txEncoded;
|
||||
}
|
||||
}
|
90
mission/acs/str/ArcsecDatalinkLayer.h
Normal file
90
mission/acs/str/ArcsecDatalinkLayer.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_
|
||||
#define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_
|
||||
|
||||
#include <fsfw/container/SimpleRingBuffer.h>
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
|
||||
#include "arcsec/common/misc.h"
|
||||
#include "eive/resultClassIds.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
/**
|
||||
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
||||
*/
|
||||
class ArcsecDatalinkLayer {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] More data required to complete frame
|
||||
static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0);
|
||||
//! [EXPORT] : [COMMENT] Data too short to represent a valid frame
|
||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
||||
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||
|
||||
static const uint8_t STATUS_OK = 0;
|
||||
|
||||
static constexpr size_t BUFFER_LENGTHS = 4096;
|
||||
|
||||
ArcsecDatalinkLayer();
|
||||
virtual ~ArcsecDatalinkLayer();
|
||||
|
||||
/**
|
||||
* Feed received data to the internal ring buffer.
|
||||
* @param rawData
|
||||
* @param rawDataLen
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t feedData(const uint8_t* rawData, size_t rawDataLen);
|
||||
|
||||
/**
|
||||
* Runs the arcsec datalink layer decoding algorithm on the data in the ring buffer, decoding
|
||||
* frames in the process.
|
||||
* @param decodedFrame
|
||||
* @param frameLen
|
||||
* @return
|
||||
* - returnvalue::OK if a frame was found
|
||||
* - DEC_IN_PROGRESS if frame decoding is in progress
|
||||
* - Anything else is a decoding error
|
||||
*/
|
||||
ReturnValue_t checkRingBufForFrame(const uint8_t** decodedFrame, size_t& frameLen);
|
||||
|
||||
/**
|
||||
* @brief SLIP encodes data pointed to by data pointer.
|
||||
*
|
||||
* @param data Pointer to data to encode
|
||||
* @param length Length of buffer to encode
|
||||
*/
|
||||
void encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame, size_t& frameLen);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
static const uint8_t ID_OFFSET = 1;
|
||||
static const uint8_t STATUS_OFFSET = 2;
|
||||
|
||||
// User to buffer and analyse data and allow feeding and checking for frames asychronously.
|
||||
SimpleRingBuffer decodeRingBuf;
|
||||
uint8_t rxAnalysisBuffer[BUFFER_LENGTHS];
|
||||
|
||||
// Used by arcsec slip decoding function to process received data. This should only be written
|
||||
// to or read from by arcsec functions!
|
||||
uint8_t rxBufferArc[startracker::MAX_FRAME_SIZE];
|
||||
// Decoded frame will be copied to this buffer
|
||||
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
|
||||
// Size of decoded frame
|
||||
uint32_t rxFrameSize = 0;
|
||||
|
||||
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
||||
// reply
|
||||
uint8_t txEncoded[startracker::MAX_FRAME_SIZE * 2 + 2];
|
||||
// Size of encoded frame
|
||||
uint32_t txFrameSize = 0;
|
||||
|
||||
slip_decode_state slipInfo;
|
||||
|
||||
void slipInit();
|
||||
};
|
||||
|
||||
#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */
|
102
mission/acs/str/ArcsecJsonParamBase.cpp
Normal file
102
mission/acs/str/ArcsecJsonParamBase.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include <mission/acs/str/ArcsecJsonParamBase.h>
|
||||
#include <mission/acs/str/arcsecJsonKeys.h>
|
||||
|
||||
#include "arcsecJsonKeys.h"
|
||||
|
||||
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
||||
|
||||
ReturnValue_t ArcsecJsonParamBase::create(uint8_t* buffer) {
|
||||
ReturnValue_t result = createCommand(buffer);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "ArcsecJsonParamBase::create: Failed to create parameter command for set "
|
||||
<< setName << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) {
|
||||
for (json::iterator it = set.begin(); it != set.end(); ++it) {
|
||||
if ((*it)[arcseckeys::NAME] == name) {
|
||||
value = (*it)[arcseckeys::VALUE];
|
||||
convertEmpty(value);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
return PARAM_NOT_EXISTS;
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::convertEmpty(std::string& value) {
|
||||
if (value == "") {
|
||||
value = "0";
|
||||
}
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) {
|
||||
float param = std::stof(value);
|
||||
std::memcpy(buffer, ¶m, sizeof(param));
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) {
|
||||
uint8_t param = std::stoi(value);
|
||||
std::memcpy(buffer, ¶m, sizeof(param));
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) {
|
||||
int16_t param = std::stoi(value);
|
||||
std::memcpy(buffer, ¶m, sizeof(param));
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) {
|
||||
uint16_t param = std::stoi(value);
|
||||
std::memcpy(buffer, ¶m, sizeof(param));
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) {
|
||||
uint32_t param = std::stoi(value);
|
||||
std::memcpy(buffer, ¶m, sizeof(param));
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) {
|
||||
*buffer = static_cast<uint8_t>(TMTC_SETPARAMREQ);
|
||||
*(buffer + 1) = setId;
|
||||
}
|
||||
|
||||
ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
if (not std::filesystem::exists(filename)) {
|
||||
sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist"
|
||||
<< std::endl;
|
||||
return JSON_FILE_NOT_EXISTS;
|
||||
}
|
||||
try {
|
||||
createJsonObject(filename);
|
||||
result = initSet();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
} catch (json::exception& e) {
|
||||
// TODO: Re-create json file from backup here.
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::createJsonObject(const std::string fullname) {
|
||||
json j;
|
||||
std::ifstream file(fullname);
|
||||
file >> j;
|
||||
file.close();
|
||||
properties = j[arcseckeys::PROPERTIES];
|
||||
}
|
||||
|
||||
ReturnValue_t ArcsecJsonParamBase::initSet() {
|
||||
for (json::iterator it = properties.begin(); it != properties.end(); ++it) {
|
||||
if ((*it)["name"] == setName) {
|
||||
set = (*it)["fields"];
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
sif::warning << "ArcsecJsonParamBase::initSet: Set " << setName << "not present in json file"
|
||||
<< std::endl;
|
||||
return SET_NOT_EXISTS;
|
||||
}
|
146
mission/acs/str/ArcsecJsonParamBase.h
Normal file
146
mission/acs/str/ArcsecJsonParamBase.h
Normal file
@ -0,0 +1,146 @@
|
||||
#ifndef BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_
|
||||
#define BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_
|
||||
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "arcsec/common/generated/tmtcstructs.h"
|
||||
#include "arcsec/common/genericstructs.h"
|
||||
#include "eive/resultClassIds.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
* @brief Base class for creation of parameter configuration commands. Reads parameter set
|
||||
* from a json file located on the filesystem and generates the appropriate command
|
||||
* to apply the parameters to the star tracker software.
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class ArcsecJsonParamBase {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE;
|
||||
//! [EXPORT] : [COMMENT] Specified json file does not exist
|
||||
static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1);
|
||||
//! [EXPORT] : [COMMENT] Requested set does not exist in json file
|
||||
static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2);
|
||||
//! [EXPORT] : [COMMENT] Requested parameter does not exist in json file
|
||||
static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3);
|
||||
|
||||
virtual ~ArcsecJsonParamBase() = default;
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param fullname Name with absolute path of json file containing the parameters to set.
|
||||
*/
|
||||
ArcsecJsonParamBase(std::string setName);
|
||||
|
||||
/**
|
||||
* @brief Initializes the properties json object and the set json object
|
||||
*
|
||||
* @param fullname Name including absolute path to json file
|
||||
* @param setName The name of the set to work on
|
||||
*
|
||||
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
|
||||
* returnvalue::OK
|
||||
*/
|
||||
ReturnValue_t init(const std::string filename);
|
||||
|
||||
/**
|
||||
* @brief Fills a buffer with a parameter set
|
||||
*
|
||||
* @param fullname The name including the absolute path of the json file containing the
|
||||
* parameter set.
|
||||
* @param buffer Pointer to the buffer the command will be written to
|
||||
*/
|
||||
ReturnValue_t create(uint8_t* buffer);
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the parameter command.
|
||||
*/
|
||||
virtual size_t getSize() = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Reads the value of a parameter from a json set
|
||||
*
|
||||
* @param name The name of the parameter
|
||||
* @param value The string representation of the read value
|
||||
*
|
||||
* @return returnvalue::OK if successful, otherwise PARAM_NOT_EXISTS
|
||||
*/
|
||||
ReturnValue_t getParam(const std::string name, std::string& value);
|
||||
|
||||
/**
|
||||
* @brief Converts empty string which is equal to define a value as zero.
|
||||
*/
|
||||
void convertEmpty(std::string& value);
|
||||
|
||||
/**
|
||||
* @brief This function adds a float represented as string to a buffer
|
||||
*
|
||||
* @param value The float in string representation to add
|
||||
* @param buffer Pointer to the buffer the float will be written to
|
||||
*/
|
||||
void addfloat(const std::string value, uint8_t* buffer);
|
||||
|
||||
/**
|
||||
* @brief This function adds a uint8_t represented as string to a buffer
|
||||
*
|
||||
* @param value The uint8_t in string representation to add
|
||||
* @param buffer Pointer to the buffer the uint8_t will be written to
|
||||
*/
|
||||
void adduint8(const std::string value, uint8_t* buffer);
|
||||
|
||||
/**
|
||||
* @brief This function adds a int16_t represented as string to a buffer
|
||||
*
|
||||
* @param value The int16_t in string representation to add
|
||||
* @param buffer Pointer to the buffer the int16_t will be written to
|
||||
*/
|
||||
void addint16(const std::string value, uint8_t* buffer);
|
||||
|
||||
/**
|
||||
* @brief This function adds a uint16_t represented as string to a buffer
|
||||
*
|
||||
* @param value The uint16_t in string representation to add
|
||||
* @param buffer Pointer to the buffer the uint16_t will be written to
|
||||
*/
|
||||
void adduint16(const std::string value, uint8_t* buffer);
|
||||
|
||||
/**
|
||||
* @brief This function adds a uint32_t represented as string to a buffer
|
||||
*
|
||||
* @param value The uint32_t in string representation to add
|
||||
* @param buffer Pointer to the buffer the uint32_t will be written to
|
||||
*/
|
||||
void adduint32(const std::string value, uint8_t* buffer);
|
||||
|
||||
void addSetParamHeader(uint8_t* buffer, uint8_t setId);
|
||||
|
||||
private:
|
||||
json properties;
|
||||
json set;
|
||||
std::string setName;
|
||||
|
||||
/**
|
||||
* @brief This function must be implemented by the derived class to define creation of a
|
||||
* parameter command.
|
||||
*/
|
||||
virtual ReturnValue_t createCommand(uint8_t* buffer) = 0;
|
||||
|
||||
void createJsonObject(const std::string fullname);
|
||||
|
||||
/**
|
||||
* @brief Extracts the json set object form the json file
|
||||
*
|
||||
* @param setName The name of the set to create the json object from
|
||||
*/
|
||||
ReturnValue_t initSet();
|
||||
};
|
||||
|
||||
#endif /* BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ */
|
4
mission/acs/str/CMakeLists.txt
Normal file
4
mission/acs/str/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(
|
||||
${OBSW_NAME}
|
||||
PRIVATE StarTrackerHandler.cpp strJsonCommands.cpp ArcsecDatalinkLayer.cpp
|
||||
ArcsecJsonParamBase.cpp strHelpers.cpp)
|
2136
mission/acs/str/StarTrackerHandler.cpp
Normal file
2136
mission/acs/str/StarTrackerHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
501
mission/acs/str/StarTrackerHandler.h
Normal file
501
mission/acs/str/StarTrackerHandler.h
Normal file
@ -0,0 +1,501 @@
|
||||
#ifndef MISSION_DEVICES_STARTRACKERHANDLER_H_
|
||||
#define MISSION_DEVICES_STARTRACKERHANDLER_H_
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <linux/acs/StrComHandler.h>
|
||||
#include <mission/acs/str/ArcsecJsonParamBase.h>
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
#include <mission/acs/str/strJsonCommands.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "arcsec/common/SLIP.h"
|
||||
#include "devices/powerSwitcherList.h"
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the star tracker from arcsec.
|
||||
*
|
||||
* @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
|
||||
* Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/
|
||||
* Sagitta%201.0%20Datapack&fileid=659181
|
||||
* @author J. Meier
|
||||
*/
|
||||
class StarTrackerHandler : public DeviceHandlerBase {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
* @param comIF
|
||||
* @param comCookie
|
||||
* @param gpioComIF Pointer to gpio communication interface
|
||||
* @param enablePin GPIO connected to the enable pin of the reaction wheels. Must be pulled
|
||||
* to high to enable the device.
|
||||
*/
|
||||
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
const char* jsonFileStr, StrComHandler* strHelper,
|
||||
power::Switch_t powerSwitch);
|
||||
virtual ~StarTrackerHandler();
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
/**
|
||||
* @brief Overwrite this function from DHB to handle commands executed by the str image
|
||||
* loader task.
|
||||
*/
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
|
||||
void performOperationHook() override;
|
||||
|
||||
Submode_t getInitialSubmode() override;
|
||||
|
||||
static const Submode_t SUBMODE_BOOTLOADER = 1;
|
||||
static const Submode_t SUBMODE_FIRMWARE = 2;
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen) override;
|
||||
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
|
||||
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
|
||||
size_t* foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
/**
|
||||
* @brief Overwritten here to always read all available data from theSerialComIF.
|
||||
*/
|
||||
virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||
virtual ReturnValue_t doSendReadHook() override;
|
||||
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
|
||||
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
|
||||
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Status in temperature reply signals error
|
||||
static const ReturnValue_t TEMPERATURE_REQ_FAILED = MAKE_RETURN_CODE(0xA0);
|
||||
//! [EXPORT] : [COMMENT] Ping command failed
|
||||
static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1);
|
||||
//! [EXPORT] : [COMMENT] Status in version reply signals error
|
||||
static const ReturnValue_t VERSION_REQ_FAILED = MAKE_RETURN_CODE(0xA2);
|
||||
//! [EXPORT] : [COMMENT] Status in interface reply signals error
|
||||
static const ReturnValue_t INTERFACE_REQ_FAILED = MAKE_RETURN_CODE(0xA3);
|
||||
//! [EXPORT] : [COMMENT] Status in power reply signals error
|
||||
static const ReturnValue_t POWER_REQ_FAILED = MAKE_RETURN_CODE(0xA4);
|
||||
//! [EXPORT] : [COMMENT] Status of reply to parameter set command signals error
|
||||
static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA5);
|
||||
//! [EXPORT] : [COMMENT] Status of reply to action command signals error
|
||||
static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA6);
|
||||
//! [EXPORT] : [COMMENT] Received invalid path string. Exceeds allowed length
|
||||
static const ReturnValue_t FILE_PATH_TOO_LONG = MAKE_RETURN_CODE(0xA7);
|
||||
//! [EXPORT] : [COMMENT] Name of file received with command is too long
|
||||
static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA8);
|
||||
//! [EXPORT] : [COMMENT] Received version reply with invalid program ID
|
||||
static const ReturnValue_t INVALID_PROGRAM = MAKE_RETURN_CODE(0xA9);
|
||||
//! [EXPORT] : [COMMENT] Status field reply signals error
|
||||
static const ReturnValue_t REPLY_ERROR = MAKE_RETURN_CODE(0xAA);
|
||||
//! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper
|
||||
//! execution)
|
||||
static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAB);
|
||||
//! [EXPORT] : [COMMENT] Received command with invalid length (too few or too many parameters)
|
||||
static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xAC);
|
||||
//! [EXPORT] : [COMMENT] Region mismatch between send and received data
|
||||
static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xAD);
|
||||
//! [EXPORT] : [COMMENT] Address mismatch between send and received data
|
||||
static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xAE);
|
||||
//! [EXPORT] : [COMMENT] Length field mismatch between send and received data
|
||||
static const ReturnValue_t lENGTH_MISMATCH = MAKE_RETURN_CODE(0xAF);
|
||||
//! [EXPORT] : [COMMENT] Specified file does not exist
|
||||
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xB0);
|
||||
//! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field
|
||||
static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB1);
|
||||
//! [EXPORT] : [COMMENT] Received FPGA action command with invalid ID
|
||||
static const ReturnValue_t INVALID_ID = MAKE_RETURN_CODE(0xB2);
|
||||
//! [EXPORT] : [COMMENT] Received reply is too short
|
||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB3);
|
||||
//! [EXPORT] : [COMMENT] Received reply with invalid CRC
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB4);
|
||||
//! [EXPORT] : [COMMENT] Star tracker handler currently executing a command and using the
|
||||
//! communication interface
|
||||
static const ReturnValue_t STR_HELPER_EXECUTING = MAKE_RETURN_CODE(0xB5);
|
||||
//! [EXPORT] : [COMMENT] Star tracker is already in firmware mode
|
||||
static const ReturnValue_t STARTRACKER_ALREADY_BOOTED = MAKE_RETURN_CODE(0xB6);
|
||||
//! [EXPORT] : [COMMENT] Star tracker must be in firmware mode to run this command
|
||||
static const ReturnValue_t STARTRACKER_NOT_RUNNING_FIRMWARE = MAKE_RETURN_CODE(0xB7);
|
||||
//! [EXPORT] : [COMMENT] Star tracker must be in bootloader mode to run this command
|
||||
static const ReturnValue_t STARTRACKER_NOT_RUNNING_BOOTLOADER = MAKE_RETURN_CODE(0xB8);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Failed to boot firmware
|
||||
static const Event BOOTING_FIRMWARE_FAILED_EVENT = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Failed to boot star tracker into bootloader mode
|
||||
static const Event BOOTING_BOOTLOADER_FAILED_EVENT = MAKE_EVENT(2, severity::LOW);
|
||||
|
||||
static const size_t MAX_PATH_SIZE = 50;
|
||||
static const size_t MAX_FILE_NAME = 30;
|
||||
|
||||
static const uint8_t STATUS_OFFSET = 2;
|
||||
static const uint8_t PARAMS_OFFSET = 2;
|
||||
static const uint8_t TICKS_OFFSET = 3;
|
||||
static const uint8_t TIME_OFFSET = 7;
|
||||
static const uint8_t PARAMETER_ID_OFFSET = 1;
|
||||
static const uint8_t ACTION_ID_OFFSET = 1;
|
||||
static const uint8_t ACTION_DATA_OFFSET = 3;
|
||||
|
||||
// Ping request will reply ping with this ID (data field)
|
||||
static const uint32_t PING_ID = 0x55;
|
||||
static const uint32_t BOOT_REGION_ID = 1;
|
||||
static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
|
||||
static const uint32_t MUTEX_TIMEOUT = 20;
|
||||
static const uint32_t BOOT_TIMEOUT = 1000;
|
||||
static const uint32_t DEFAULT_TRANSITION_DELAY = 15000;
|
||||
|
||||
struct FlashReadCmd {
|
||||
// Minimum length of a read command (region, length and filename)
|
||||
static const size_t MIN_LENGTH = 7;
|
||||
};
|
||||
|
||||
struct ChecksumCmd {
|
||||
static const uint8_t ADDRESS_OFFSET = 1;
|
||||
static const uint8_t LENGTH_OFFSET = 5;
|
||||
// Length of checksum command
|
||||
static const size_t LENGTH = 9;
|
||||
uint8_t rememberRegion = 0;
|
||||
uint32_t rememberAddress = 0;
|
||||
uint32_t rememberLength = 0;
|
||||
};
|
||||
|
||||
ChecksumCmd checksumCmd;
|
||||
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
|
||||
startracker::TemperatureSet temperatureSet;
|
||||
startracker::VersionSet versionSet;
|
||||
startracker::PowerSet powerSet;
|
||||
startracker::InterfaceSet interfaceSet;
|
||||
startracker::TimeSet timeSet;
|
||||
startracker::SolutionSet solutionSet;
|
||||
startracker::HistogramSet histogramSet;
|
||||
startracker::ChecksumSet checksumSet;
|
||||
startracker::CameraSet cameraSet;
|
||||
startracker::LimitsSet limitsSet;
|
||||
startracker::LogLevelSet loglevelSet;
|
||||
startracker::MountingSet mountingSet;
|
||||
startracker::ImageProcessorSet imageProcessorSet;
|
||||
startracker::CentroidingSet centroidingSet;
|
||||
startracker::LisaSet lisaSet;
|
||||
startracker::MatchingSet matchingSet;
|
||||
startracker::TrackingSet trackingSet;
|
||||
startracker::ValidationSet validationSet;
|
||||
startracker::AlgoSet algoSet;
|
||||
startracker::SubscriptionSet subscriptionSet;
|
||||
startracker::LogSubscriptionSet logSubscriptionSet;
|
||||
startracker::DebugCameraSet debugCameraSet;
|
||||
|
||||
// Pointer to object responsible for uploading and downloading images to/from the star tracker
|
||||
StrComHandler* strHelper = nullptr;
|
||||
|
||||
uint8_t commandBuffer[startracker::MAX_FRAME_SIZE];
|
||||
|
||||
// Countdown to insert delay for star tracker to switch from bootloader to firmware program
|
||||
// Loading firmware requires some time and the command will not trigger a reply when executed
|
||||
Countdown bootCountdown;
|
||||
|
||||
struct JsonConfigs {
|
||||
Tracking tracking;
|
||||
LogLevel logLevel;
|
||||
LogSubscription logSubscription;
|
||||
DebugCamera debugCamera;
|
||||
Algo algo;
|
||||
Validation validation;
|
||||
Matching matching;
|
||||
Lisa lisa;
|
||||
Centroiding centroiding;
|
||||
Camera camera;
|
||||
ImageProcessor imageProcessor;
|
||||
Mounting mounting;
|
||||
Limits limits;
|
||||
Subscription subscription;
|
||||
};
|
||||
JsonConfigs jcfgs;
|
||||
Countdown jcfgCountdown = Countdown(250);
|
||||
bool commandExecuted = false;
|
||||
std::thread jsonCfgTask;
|
||||
static void setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile);
|
||||
|
||||
std::string paramJsonFile;
|
||||
|
||||
enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST };
|
||||
|
||||
NormalState normalState = NormalState::TEMPERATURE_REQUEST;
|
||||
|
||||
enum class StartupState {
|
||||
IDLE,
|
||||
CHECK_PROGRAM,
|
||||
WAIT_CHECK_PROGRAM,
|
||||
BOOT_BOOTLOADER,
|
||||
WAIT_JCFG,
|
||||
DONE
|
||||
};
|
||||
StartupState startupState = StartupState::IDLE;
|
||||
|
||||
enum class InternalState {
|
||||
IDLE,
|
||||
BOOT_FIRMWARE,
|
||||
DONE,
|
||||
FAILED_FIRMWARE_BOOT,
|
||||
BOOT_BOOTLOADER,
|
||||
BOOTLOADER_CHECK,
|
||||
FAILED_BOOTLOADER_BOOT
|
||||
};
|
||||
|
||||
enum class FwBootState {
|
||||
NONE,
|
||||
BOOT_DELAY,
|
||||
REQ_VERSION,
|
||||
VERIFY_BOOT,
|
||||
LOGLEVEL,
|
||||
LIMITS,
|
||||
TRACKING,
|
||||
MOUNTING,
|
||||
IMAGE_PROCESSOR,
|
||||
CAMERA,
|
||||
BLOB,
|
||||
CENTROIDING,
|
||||
LISA,
|
||||
MATCHING,
|
||||
VALIDATION,
|
||||
ALGO,
|
||||
LOG_SUBSCRIPTION,
|
||||
DEBUG_CAMERA,
|
||||
WAIT_FOR_EXECUTION,
|
||||
};
|
||||
FwBootState bootState = FwBootState::NONE;
|
||||
|
||||
InternalState internalState = InternalState::IDLE;
|
||||
|
||||
bool reinitNextSetParam = false;
|
||||
|
||||
bool strHelperHandlingSpecialRequest = false;
|
||||
|
||||
const power::Switch_t powerSwitch = power::NO_SWITCH;
|
||||
|
||||
/**
|
||||
* @brief Handles internal state
|
||||
*/
|
||||
void handleInternalState();
|
||||
|
||||
/**
|
||||
* @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution.
|
||||
*
|
||||
* @param actionId Action id of command to execute
|
||||
*/
|
||||
ReturnValue_t checkMode(ActionId_t actionId);
|
||||
|
||||
/**
|
||||
* @brief This function initializes the serial link ip protocol struct slipInfo.
|
||||
*/
|
||||
void slipInit();
|
||||
|
||||
ReturnValue_t scanForActionReply(uint8_t replyId, DeviceCommandId_t* foundId);
|
||||
ReturnValue_t scanForSetParameterReply(uint8_t replyId, DeviceCommandId_t* foundId);
|
||||
ReturnValue_t scanForGetParameterReply(uint8_t replyId, DeviceCommandId_t* foundId);
|
||||
ReturnValue_t scanForTmReply(uint8_t replyId, DeviceCommandId_t* foundId);
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to ping the star tracker
|
||||
*/
|
||||
void preparePingRequest();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to request the time telemetry.
|
||||
*/
|
||||
void prepareTimeRequest();
|
||||
|
||||
/**
|
||||
* @brief Handles all received event messages
|
||||
*/
|
||||
void handleEvent(EventMessage* eventMessage);
|
||||
|
||||
/**
|
||||
* @brief Extracts information for flash-read-command from TC data and starts execution of
|
||||
* flash-read-procedure
|
||||
*
|
||||
* @param commandData Pointer to received command data
|
||||
* @param commandDataLen Size of received command data
|
||||
*
|
||||
* @return returnvalue::OK if start of execution was successful, otherwise error return value
|
||||
*/
|
||||
ReturnValue_t executeFlashReadCommand(const uint8_t* commandData, size_t commandDataLen);
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to boot image (works only when star tracker is
|
||||
* in bootloader mode).
|
||||
*/
|
||||
void prepareBootCommand();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with command to get the checksum of a flash part
|
||||
*/
|
||||
ReturnValue_t prepareChecksumCommand(const uint8_t* commandData, size_t commandDataLen);
|
||||
|
||||
/**
|
||||
* @brief Fills the command buffer with the command to take an image.
|
||||
*/
|
||||
void prepareTakeImageCommand(const uint8_t* commandData);
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to request the version telemetry packet
|
||||
*/
|
||||
void prepareVersionRequest();
|
||||
|
||||
/**
|
||||
* @brief Fills the command buffer with data to request the interface telemetry packet.
|
||||
*/
|
||||
void prepareInterfaceRequest();
|
||||
|
||||
/**
|
||||
* @brief Fills the command buffer with data to request the power telemetry packet.
|
||||
*/
|
||||
void preparePowerRequest();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to reboot star tracker.
|
||||
*/
|
||||
void prepareSwitchToBootloaderCmd();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to subscribe to a telemetry packet.
|
||||
*
|
||||
* @param tmId The ID of the telemetry packet to subscribe to
|
||||
*/
|
||||
void prepareSubscriptionCommand(const uint8_t* tmId);
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to request solution telemtry packet (contains
|
||||
* attitude information)
|
||||
*/
|
||||
void prepareSolutionRequest();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to request temperature from star tracker
|
||||
*/
|
||||
void prepareTemperatureRequest();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to request histogram
|
||||
*/
|
||||
void prepareHistogramRequest();
|
||||
|
||||
/**
|
||||
* @brief Reads parameters from json file specified by string in commandData and
|
||||
* prepares the command to apply the parameter set to the star tracker
|
||||
*
|
||||
* @param commandData Contains string with file name
|
||||
* @param commandDataLen Length of command
|
||||
* @param paramSet The object defining the command generation
|
||||
*
|
||||
* @return returnvalue::OK if successful, otherwise error return Value
|
||||
*/
|
||||
ReturnValue_t prepareParamCommand(const uint8_t* commandData, size_t commandDataLen,
|
||||
ArcsecJsonParamBase& paramSet, bool reinitSet);
|
||||
|
||||
/**
|
||||
* @brief The following function will fill the command buffer with the command to request
|
||||
* a parameter set.
|
||||
*/
|
||||
ReturnValue_t prepareRequestCameraParams();
|
||||
ReturnValue_t prepareRequestLimitsParams();
|
||||
ReturnValue_t prepareRequestLogLevelParams();
|
||||
ReturnValue_t prepareRequestMountingParams();
|
||||
ReturnValue_t prepareRequestImageProcessorParams();
|
||||
ReturnValue_t prepareRequestCentroidingParams();
|
||||
ReturnValue_t prepareRequestLisaParams();
|
||||
ReturnValue_t prepareRequestMatchingParams();
|
||||
ReturnValue_t prepareRequestTrackingParams();
|
||||
ReturnValue_t prepareRequestValidationParams();
|
||||
ReturnValue_t prepareRequestAlgoParams();
|
||||
ReturnValue_t prepareRequestSubscriptionParams();
|
||||
ReturnValue_t prepareRequestLogSubscriptionParams();
|
||||
ReturnValue_t prepareRequestDebugCameraParams();
|
||||
|
||||
/**
|
||||
* @brief Handles action replies with datasets.
|
||||
*/
|
||||
ReturnValue_t handleActionReplySet(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* @brief Default function to handle action replies
|
||||
*/
|
||||
ReturnValue_t handleActionReply(const uint8_t* rawFrame);
|
||||
|
||||
/**
|
||||
* @brief Handles reply to upload centroid command
|
||||
*/
|
||||
ReturnValue_t handleUploadCentroidReply();
|
||||
|
||||
/**
|
||||
* @brief Handles reply to checksum command
|
||||
*/
|
||||
ReturnValue_t handleChecksumReply(const uint8_t* rawFrame);
|
||||
|
||||
/**
|
||||
* @brief Handles all set parameter replies
|
||||
*/
|
||||
ReturnValue_t handleSetParamReply(const uint8_t* rawFrame);
|
||||
|
||||
ReturnValue_t handlePingReply(const uint8_t* rawFrame);
|
||||
|
||||
ReturnValue_t handleParamRequest(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* @brief Checks the loaded program by means of the version set
|
||||
*/
|
||||
ReturnValue_t checkProgram();
|
||||
|
||||
/**
|
||||
* @brief Handles the startup state machine
|
||||
*/
|
||||
void handleStartup(uint8_t parameterId);
|
||||
|
||||
/**
|
||||
* @brief Handles telemtry replies and fills the appropriate dataset
|
||||
*
|
||||
* @param dataset Dataset where reply data will be written to
|
||||
* @param size Size of the dataset
|
||||
*
|
||||
* @return returnvalue::OK if successful, otherwise error return value
|
||||
*/
|
||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Checks if star tracker is in valid mode for executing the received command.
|
||||
*
|
||||
* @param actioId Id of received command
|
||||
*
|
||||
* @return returnvalue::OK if star tracker is in valid mode, otherwise error return value
|
||||
*/
|
||||
ReturnValue_t checkCommand(ActionId_t actionId);
|
||||
|
||||
void doOnTransition(Submode_t subModeFrom);
|
||||
void doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom);
|
||||
void bootFirmware(Mode_t toMode);
|
||||
void bootBootloader();
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */
|
181
mission/acs/str/arcsecJsonKeys.h
Normal file
181
mission/acs/str/arcsecJsonKeys.h
Normal file
@ -0,0 +1,181 @@
|
||||
#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_
|
||||
#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_
|
||||
|
||||
/**
|
||||
* @brief Keys used in JSON file of ARCSEC.
|
||||
*/
|
||||
namespace arcseckeys {
|
||||
static const char PROPERTIES[] = "properties";
|
||||
static const char NAME[] = "name";
|
||||
static const char VALUE[] = "value";
|
||||
|
||||
static const char LIMITS[] = "limits";
|
||||
static const char ACTION[] = "action";
|
||||
static const char FPGA18CURRENT[] = "FPGA18Current";
|
||||
static const char FPGA25CURRENT[] = "FPGA25Current";
|
||||
static const char FPGA10CURRENT[] = "FPGA10Current";
|
||||
static const char MCUCURRENT[] = "MCUCurrent";
|
||||
static const char CMOS21CURRENT[] = "CMOS21Current";
|
||||
static const char CMOSPIXCURRENT[] = "CMOSPixCurrent";
|
||||
static const char CMOS33CURRENT[] = "CMOS33Current";
|
||||
static const char CMOSVRESCURRENT[] = "CMOSVResCurrent";
|
||||
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
||||
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
||||
|
||||
static const char MOUNTING[] = "mounting";
|
||||
static const char qw[] = "qw";
|
||||
static const char qx[] = "qx";
|
||||
static const char qy[] = "qy";
|
||||
static const char qz[] = "qz";
|
||||
|
||||
static const char IMAGE_PROCESSOR[] = "imageprocessor";
|
||||
static const char IMAGE_PROCESSOR_MODE[] = "mode";
|
||||
static const char STORE[] = "store";
|
||||
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
|
||||
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
|
||||
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
|
||||
|
||||
static const char CAMERA[] = "camera";
|
||||
static const char MODE[] = "mode";
|
||||
static const char FOCALLENGTH[] = "focallength";
|
||||
static const char EXPOSURE[] = "exposure";
|
||||
static const char INTERVAL[] = "interval";
|
||||
static const char OFFSET[] = "offset";
|
||||
static const char PGAGAIN[] = "PGAGain";
|
||||
static const char ADCGAIN[] = "ADCGain";
|
||||
static const char REG_1[] = "reg1";
|
||||
static const char VAL_1[] = "val1";
|
||||
static const char REG_2[] = "reg2";
|
||||
static const char VAL_2[] = "val2";
|
||||
static const char REG_3[] = "reg3";
|
||||
static const char VAL_3[] = "val3";
|
||||
static const char REG_4[] = "reg4";
|
||||
static const char VAL_4[] = "val4";
|
||||
static const char REG_5[] = "reg5";
|
||||
static const char VAL_5[] = "val5";
|
||||
static const char REG_6[] = "reg6";
|
||||
static const char VAL_6[] = "val6";
|
||||
static const char REG_7[] = "reg7";
|
||||
static const char VAL_7[] = "val7";
|
||||
static const char REG_8[] = "reg8";
|
||||
static const char VAL_8[] = "val8";
|
||||
static const char FREQ_1[] = "freq1";
|
||||
|
||||
static const char BLOB[] = "blob";
|
||||
static const char MIN_VALUE[] = "minValue";
|
||||
static const char MIN_DISTANCE[] = "minDistance";
|
||||
static const char NEIGHBOUR_DISTANCE[] = "neighbourDistance";
|
||||
static const char NEIGHBOUR_BRIGHT_PIXELS[] = "neighbourBrightPixels";
|
||||
static const char MIN_TOTAL_VALUE[] = "minTotalValue";
|
||||
static const char MAX_TOTAL_VALUE[] = "maxTotalValue";
|
||||
static const char MIN_BRIGHT_NEIGHBOURS[] = "minBrightNeighbours";
|
||||
static const char MAX_BRIGHT_NEIGHBOURS[] = "maxBrightNeighbours";
|
||||
static const char MAX_PIXEL_TO_CONSIDER[] = "maxPixelsToConsider";
|
||||
// static const char SIGNAL_THRESHOLD[] = "signalThreshold";
|
||||
static const char BLOB_DARK_THRESHOLD[] = "darkThreshold";
|
||||
static const char ENABLE_HISTOGRAM[] = "enableHistogram";
|
||||
static const char ENABLE_CONTRAST[] = "enableContrast";
|
||||
static const char BIN_MODE[] = "binMode";
|
||||
|
||||
static const char CENTROIDING[] = "centroiding";
|
||||
static const char ENABLE_FILTER[] = "enableFilter";
|
||||
static const char MAX_QUALITY[] = "maxquality";
|
||||
static const char DARK_THRESHOLD[] = "darkthreshold";
|
||||
static const char MIN_QUALITY[] = "minquality";
|
||||
static const char MAX_INTENSITY[] = "maxintensity";
|
||||
static const char MIN_INTENSITY[] = "minintensity";
|
||||
static const char MAX_MAGNITUDE[] = "maxmagnitude";
|
||||
static const char GAUSSIAN_CMAX[] = "gaussianCmax";
|
||||
static const char GAUSSIAN_CMIN[] = "gaussianCmin";
|
||||
static const char TRANSMATRIX_00[] = "transmatrix00";
|
||||
static const char TRANSMATRIX_01[] = "transmatrix01";
|
||||
static const char TRANSMATRIX_10[] = "transmatrix10";
|
||||
static const char TRANSMATRIX_11[] = "transmatrix11";
|
||||
|
||||
static const char LISA[] = "lisa";
|
||||
static const char LISA_MODE[] = "mode";
|
||||
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
|
||||
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
|
||||
static const char FOV_WIDTH[] = "fov_width";
|
||||
static const char FOV_HEIGHT[] = "fov_height";
|
||||
static const char FLOAT_STAR_LIMIT[] = "float_star_limit";
|
||||
static const char CLOSE_STAR_LIMIT[] = "close_star_limit";
|
||||
static const char RATING_WEIGHT_CLOSE_STAR_COUNT[] = "rating_weight_close_star_count";
|
||||
static const char RATING_WEIGHT_FRACTION_CLOSE[] = "rating_weight_fraction_close";
|
||||
static const char RATING_WEIGHT_MEAN_SUM[] = "rating_weight_mean_sum";
|
||||
static const char RATING_WEIGHT_DB_STAR_COUNT[] = "rating_weight_db_star_count";
|
||||
static const char MAX_COMBINATIONS[] = "max_combinations";
|
||||
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
||||
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
||||
|
||||
static const char MATCHING[] = "matching";
|
||||
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
||||
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
||||
|
||||
static const char VALIDATION[] = "validation";
|
||||
static const char STABLE_COUNT[] = "stable_count";
|
||||
static const char MAX_DIFFERENCE[] = "max_difference";
|
||||
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
||||
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
||||
|
||||
static const char TRACKING[] = "tracking";
|
||||
static const char THIN_LIMIT[] = "thinLimit";
|
||||
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
||||
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
||||
static const char TRACKER_CHOICE[] = "trackerChoice";
|
||||
|
||||
static const char ALGO[] = "algo";
|
||||
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
|
||||
static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
|
||||
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
|
||||
static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
|
||||
|
||||
static const char LOGLEVEL[] = "loglevel";
|
||||
static const char LOGLEVEL1[] = "loglevel1";
|
||||
static const char LOGLEVEL2[] = "loglevel2";
|
||||
static const char LOGLEVEL3[] = "loglevel3";
|
||||
static const char LOGLEVEL4[] = "loglevel4";
|
||||
static const char LOGLEVEL5[] = "loglevel5";
|
||||
static const char LOGLEVEL6[] = "loglevel6";
|
||||
static const char LOGLEVEL7[] = "loglevel7";
|
||||
static const char LOGLEVEL8[] = "loglevel8";
|
||||
static const char LOGLEVEL9[] = "loglevel9";
|
||||
static const char LOGLEVEL10[] = "loglevel10";
|
||||
static const char LOGLEVEL11[] = "loglevel11";
|
||||
static const char LOGLEVEL12[] = "loglevel12";
|
||||
static const char LOGLEVEL13[] = "loglevel13";
|
||||
static const char LOGLEVEL14[] = "loglevel14";
|
||||
static const char LOGLEVEL15[] = "loglevel15";
|
||||
static const char LOGLEVEL16[] = "loglevel16";
|
||||
|
||||
static const char SUBSCRIPTION[] = "subscription";
|
||||
static const char TELEMETRY_1[] = "telemetry1";
|
||||
static const char TELEMETRY_2[] = "telemetry2";
|
||||
static const char TELEMETRY_3[] = "telemetry3";
|
||||
static const char TELEMETRY_4[] = "telemetry4";
|
||||
static const char TELEMETRY_5[] = "telemetry5";
|
||||
static const char TELEMETRY_6[] = "telemetry6";
|
||||
static const char TELEMETRY_7[] = "telemetry7";
|
||||
static const char TELEMETRY_8[] = "telemetry8";
|
||||
static const char TELEMETRY_9[] = "telemetry9";
|
||||
static const char TELEMETRY_10[] = "telemetry10";
|
||||
static const char TELEMETRY_11[] = "telemetry11";
|
||||
static const char TELEMETRY_12[] = "telemetry12";
|
||||
static const char TELEMETRY_13[] = "telemetry13";
|
||||
static const char TELEMETRY_14[] = "telemetry14";
|
||||
static const char TELEMETRY_15[] = "telemetry15";
|
||||
static const char TELEMETRY_16[] = "telemetry16";
|
||||
|
||||
static const char LOG_SUBSCRIPTION[] = "logsubscription";
|
||||
static const char LEVEL1[] = "level1";
|
||||
static const char MODULE1[] = "module1";
|
||||
static const char LEVEL2[] = "level2";
|
||||
static const char MODULE2[] = "module2";
|
||||
|
||||
static const char DEBUG_CAMERA[] = "debugcamera";
|
||||
static const char TIMING[] = "timing";
|
||||
static const char TEST[] = "test";
|
||||
|
||||
} // namespace arcseckeys
|
||||
|
||||
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */
|
7
mission/acs/str/strHelpers.cpp
Normal file
7
mission/acs/str/strHelpers.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
|
||||
uint8_t startracker::getReplyFrameType(const uint8_t* rawFrame) { return rawFrame[0]; }
|
||||
|
||||
uint8_t startracker::getId(const uint8_t* rawFrame) { return rawFrame[1]; }
|
||||
|
||||
uint8_t startracker::getStatusField(const uint8_t* rawFrame) { return rawFrame[2]; }
|
1518
mission/acs/str/strHelpers.h
Normal file
1518
mission/acs/str/strHelpers.h
Normal file
File diff suppressed because it is too large
Load Diff
918
mission/acs/str/strJsonCommands.cpp
Normal file
918
mission/acs/str/strJsonCommands.cpp
Normal file
@ -0,0 +1,918 @@
|
||||
#include <mission/acs/str/arcsecJsonKeys.h>
|
||||
#include <mission/acs/str/strJsonCommands.h>
|
||||
|
||||
#include "arcsecJsonKeys.h"
|
||||
|
||||
Limits::Limits() : ArcsecJsonParamBase(arcseckeys::LIMITS) {}
|
||||
|
||||
size_t Limits::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Limits::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::LIMITS);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::ACTION, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::FPGA18CURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::FPGA25CURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::FPGA10CURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MCUCURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::CMOS21CURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::CMOSPIXCURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::CMOS33CURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::CMOSVRESCURRENT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::CMOS_TEMPERATURE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MCU_TEMPERATURE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Tracking::Tracking() : ArcsecJsonParamBase(arcseckeys::TRACKING) {}
|
||||
|
||||
size_t Tracking::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Tracking::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::TRACKING);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::THIN_LIMIT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::OUTLIER_THRESHOLD, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::OUTLIER_THRESHOLD_QUEST, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::TRACKER_CHOICE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Mounting::Mounting() : ArcsecJsonParamBase(arcseckeys::MOUNTING) {}
|
||||
|
||||
size_t Mounting::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Mounting::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::MOUNTING);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::qw, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::qx, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::qy, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::qz, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ImageProcessor::ImageProcessor() : ArcsecJsonParamBase(arcseckeys::IMAGE_PROCESSOR) {}
|
||||
|
||||
size_t ImageProcessor::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t ImageProcessor::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::IMAGE_PROCESSOR);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::IMAGE_PROCESSOR_MODE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::STORE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::SIGNAL_THRESHOLD, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint16(param, buffer + offset);
|
||||
offset += sizeof(uint16_t);
|
||||
result = getParam(arcseckeys::IMAGE_PROCESSOR_DARK_THRESHOLD, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint16(param, buffer + offset);
|
||||
offset += sizeof(uint16_t);
|
||||
result = getParam(arcseckeys::BACKGROUND_COMPENSATION, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Camera::Camera() : ArcsecJsonParamBase(arcseckeys::CAMERA) {}
|
||||
|
||||
size_t Camera::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Camera::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::CAMERA);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::MODE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::FOCALLENGTH, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::EXPOSURE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::INTERVAL, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::OFFSET, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addint16(param, buffer + offset);
|
||||
offset += sizeof(int16_t);
|
||||
result = getParam(arcseckeys::PGAGAIN, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::ADCGAIN, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_2, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_2, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_3, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_3, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_4, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_4, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_5, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_5, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_6, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_6, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_7, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_7, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::REG_8, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::VAL_8, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::FREQ_1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint32(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Centroiding::Centroiding() : ArcsecJsonParamBase(arcseckeys::CENTROIDING) {}
|
||||
|
||||
size_t Centroiding::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Centroiding::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::CENTROIDING);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::ENABLE_FILTER, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::MAX_QUALITY, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::DARK_THRESHOLD, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MIN_QUALITY, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MAX_INTENSITY, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MIN_INTENSITY, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MAX_MAGNITUDE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::GAUSSIAN_CMAX, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::GAUSSIAN_CMIN, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::TRANSMATRIX_00, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::TRANSMATRIX_01, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::TRANSMATRIX_10, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::TRANSMATRIX_11, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Lisa::Lisa() : ArcsecJsonParamBase(arcseckeys::LISA) {}
|
||||
|
||||
size_t Lisa::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Lisa::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::LISA);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::LISA_MODE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint32(param, buffer + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
result = getParam(arcseckeys::PREFILTER_DIST_THRESHOLD, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::PREFILTER_ANGLE_THRESHOLD, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::FOV_WIDTH, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::FOV_HEIGHT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::FLOAT_STAR_LIMIT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::CLOSE_STAR_LIMIT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::RATING_WEIGHT_CLOSE_STAR_COUNT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::RATING_WEIGHT_FRACTION_CLOSE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::RATING_WEIGHT_MEAN_SUM, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::RATING_WEIGHT_DB_STAR_COUNT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MAX_COMBINATIONS, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::NR_STARS_STOP, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::FRACTION_CLOSE_STOP, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Matching::Matching() : ArcsecJsonParamBase(arcseckeys::MATCHING) {}
|
||||
|
||||
size_t Matching::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Matching::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::MATCHING);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::SQUARED_DISTANCE_LIMIT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::SQUARED_SHIFT_LIMIT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Validation::Validation() : ArcsecJsonParamBase(arcseckeys::VALIDATION) {}
|
||||
|
||||
size_t Validation::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Validation::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::VALIDATION);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::STABLE_COUNT, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::MAX_DIFFERENCE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MIN_TRACKER_CONFIDENCE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::MIN_MATCHED_STARS, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Algo::Algo() : ArcsecJsonParamBase(arcseckeys::ALGO) {}
|
||||
|
||||
size_t Algo::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Algo::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::ALGO);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::MODE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::L2T_MIN_CONFIDENCE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::L2T_MIN_MATCHED, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::T2L_MIN_CONFIDENCE, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addfloat(param, buffer + offset);
|
||||
offset += sizeof(float);
|
||||
result = getParam(arcseckeys::T2L_MIN_MATCHED, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
LogLevel::LogLevel() : ArcsecJsonParamBase(arcseckeys::LOGLEVEL) {}
|
||||
|
||||
size_t LogLevel::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t LogLevel::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::LOG_LEVEL);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::LOGLEVEL1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL2, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL3, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL4, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL5, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL6, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL7, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL8, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL9, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL10, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL11, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL12, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL13, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL14, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL15, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LOGLEVEL16, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
Subscription::Subscription() : ArcsecJsonParamBase(arcseckeys::SUBSCRIPTION) {}
|
||||
|
||||
size_t Subscription::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t Subscription::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::SUBSCRIPTION);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::TELEMETRY_1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_2, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_3, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_4, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_5, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_6, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_7, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_8, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_9, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_10, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_11, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_12, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_13, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_14, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_15, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::TELEMETRY_16, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
LogSubscription::LogSubscription() : ArcsecJsonParamBase(arcseckeys::LOG_SUBSCRIPTION) {}
|
||||
|
||||
size_t LogSubscription::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t LogSubscription::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::LOG_SUBSCRIPTION);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::LEVEL1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::MODULE1, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::LEVEL2, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
result = getParam(arcseckeys::MODULE2, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint8(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
DebugCamera::DebugCamera() : ArcsecJsonParamBase(arcseckeys::DEBUG_CAMERA) {}
|
||||
|
||||
size_t DebugCamera::getSize() { return COMMAND_SIZE; }
|
||||
|
||||
ReturnValue_t DebugCamera::createCommand(uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t offset = 0;
|
||||
std::string param;
|
||||
addSetParamHeader(buffer, startracker::ID::DEBUG_CAMERA);
|
||||
offset = 2;
|
||||
result = getParam(arcseckeys::TIMING, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint32(param, buffer + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
result = getParam(arcseckeys::TEST, param);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adduint32(param, buffer + offset);
|
||||
return returnvalue::OK;
|
||||
}
|
241
mission/acs/str/strJsonCommands.h
Normal file
241
mission/acs/str/strJsonCommands.h
Normal file
@ -0,0 +1,241 @@
|
||||
#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_
|
||||
#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_
|
||||
|
||||
/**
|
||||
* @brief This file defines a few helper classes to generate commands by means of the parameters
|
||||
* defined in the arcsec json files.
|
||||
* @author J. Meier
|
||||
*/
|
||||
|
||||
#include <mission/acs/str/ArcsecJsonParamBase.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
/**
|
||||
* @brief Generates command to set the limit parameters
|
||||
*
|
||||
*/
|
||||
class Limits : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Limits();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 43;
|
||||
|
||||
virtual ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to configure the tracking algorithm.
|
||||
*
|
||||
*/
|
||||
class Tracking : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Tracking();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 15;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to set the mounting quaternion
|
||||
*
|
||||
*/
|
||||
class Mounting : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Mounting();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 18;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to configure the image processor
|
||||
*
|
||||
*/
|
||||
class ImageProcessor : public ArcsecJsonParamBase {
|
||||
public:
|
||||
ImageProcessor();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 9;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to set the mounting quaternion
|
||||
*
|
||||
*/
|
||||
class Camera : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Camera();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 39;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to configure the centroiding algorithm
|
||||
*
|
||||
*/
|
||||
class Centroiding : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Centroiding();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 51;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to configure the LISA (lost in space algorithm)
|
||||
*
|
||||
*/
|
||||
class Lisa : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Lisa();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 52;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to configure the matching algorithm
|
||||
*
|
||||
*/
|
||||
class Matching : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Matching();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 10;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates the command to configure the validation parameters
|
||||
*
|
||||
*/
|
||||
class Validation : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Validation();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 12;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates command to configure the mechanism of automatically switching between the
|
||||
* LISA and other algorithms.
|
||||
*
|
||||
*/
|
||||
class Algo : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Algo();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 13;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates command to configure the log level parameters.
|
||||
*
|
||||
*/
|
||||
class LogLevel : public ArcsecJsonParamBase {
|
||||
public:
|
||||
LogLevel();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 18;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates command to set subscription parameters.
|
||||
*
|
||||
*/
|
||||
class Subscription : public ArcsecJsonParamBase {
|
||||
public:
|
||||
Subscription();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 18;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates command to set log subscription parameters.
|
||||
*
|
||||
*/
|
||||
class LogSubscription : public ArcsecJsonParamBase {
|
||||
public:
|
||||
LogSubscription();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 6;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates command to set debug camera parameters
|
||||
*
|
||||
*/
|
||||
class DebugCamera : public ArcsecJsonParamBase {
|
||||
public:
|
||||
DebugCamera();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
private:
|
||||
static const size_t COMMAND_SIZE = 10;
|
||||
|
||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||
};
|
||||
|
||||
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */
|
11
mission/com/CMakeLists.txt
Normal file
11
mission/com/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE SyrlinksHandler.cpp
|
||||
CcsdsIpCoreHandler.cpp
|
||||
LiveTmTask.cpp
|
||||
PersistentLogTmStoreTask.cpp
|
||||
TmStoreTaskBase.cpp
|
||||
VirtualChannel.cpp
|
||||
VirtualChannelWithQueue.cpp
|
||||
PersistentSingleTmStoreTask.cpp
|
||||
LiveTmTask.cpp)
|
@ -11,13 +11,15 @@
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||
#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h"
|
||||
#include "mission/com/syrlinksDefs.h"
|
||||
|
||||
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination,
|
||||
PtmeConfig& ptmeConfig, std::atomic_bool& linkState,
|
||||
GpioIF* gpioIF, PtmeGpios gpioIds)
|
||||
GpioIF* gpioIF, PtmeGpios gpioIds,
|
||||
std::atomic_bool& ptmeLocked)
|
||||
: SystemObject(objectId),
|
||||
linkState(linkState),
|
||||
ptmeLocked(ptmeLocked),
|
||||
tcDestination(tcDestination),
|
||||
parameterHelper(this),
|
||||
actionHelper(this, nullptr),
|
||||
@ -29,12 +31,14 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDesti
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
ptmeLocked = true;
|
||||
}
|
||||
|
||||
CcsdsIpCoreHandler::~CcsdsIpCoreHandler() = default;
|
||||
|
||||
ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) {
|
||||
readCommandQueue();
|
||||
performPtmeUpdateWhenApplicable();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -71,11 +75,11 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
|
||||
}
|
||||
|
||||
// This also pulls the PTME out of reset state.
|
||||
if (batPriorityParam == 0) {
|
||||
disablePrioritySelectMode();
|
||||
} else {
|
||||
enablePrioritySelectMode();
|
||||
}
|
||||
updateBatPriorityFromParam();
|
||||
ptmeConfig.setPollThreshold(
|
||||
static_cast<AxiPtmeConfig::IdlePollThreshold>(params.pollThresholdParam));
|
||||
resetPtme();
|
||||
ptmeLocked = false;
|
||||
|
||||
#if OBSW_SYRLINKS_SIMULATED == 1
|
||||
// Update data on rising edge
|
||||
@ -117,7 +121,10 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
|
||||
ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
if ((domainId == 0) and (uniqueIdentifier == ParamId::BAT_PRIORITY)) {
|
||||
if (domainId != 0) {
|
||||
return HasParametersIF::INVALID_DOMAIN_ID;
|
||||
}
|
||||
if (uniqueIdentifier == ParamId::BAT_PRIORITY) {
|
||||
uint8_t newVal = 0;
|
||||
ReturnValue_t result = newValues->getElement(&newVal);
|
||||
if (result != returnvalue::OK) {
|
||||
@ -126,11 +133,33 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
|
||||
if (newVal > 1) {
|
||||
return HasParametersIF::INVALID_VALUE;
|
||||
}
|
||||
parameterWrapper->set(batPriorityParam);
|
||||
if (mode == MODE_ON) {
|
||||
updateBatPriorityOnTxOff = true;
|
||||
} else if (mode == MODE_OFF) {
|
||||
updateBatPriorityFromParam();
|
||||
parameterWrapper->set(params.batPriorityParam);
|
||||
if (newVal != params.batPriorityParam) {
|
||||
// This ensures that the BAT priority is updated at some point when an update of the PTME is
|
||||
// allowed
|
||||
updateContext.updateBatPrio = true;
|
||||
// If we are off, we can do the update after X cycles. Otherwise, wait until the transmitter
|
||||
// goes off.
|
||||
if (mode == MODE_OFF) {
|
||||
initPtmeUpdateAfterXCycles();
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
} else if (uniqueIdentifier == ParamId::POLL_THRESHOLD) {
|
||||
uint8_t newVal = 0;
|
||||
ReturnValue_t result = newValues->getElement(&newVal);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
if (newVal > static_cast<uint8_t>(AxiPtmeConfig::NEVER)) {
|
||||
return HasParametersIF::INVALID_VALUE;
|
||||
}
|
||||
parameterWrapper->set(newVal);
|
||||
if (newVal != params.pollThresholdParam) {
|
||||
updateContext.updatePollThreshold = true;
|
||||
if (mode == MODE_OFF) {
|
||||
initPtmeUpdateAfterXCycles();
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
@ -148,50 +177,33 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
|
||||
const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
switch (actionId) {
|
||||
case SET_LOW_RATE: {
|
||||
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW);
|
||||
result = ptmeConfig.setRate(RATE_100KBPS);
|
||||
break;
|
||||
}
|
||||
case SET_HIGH_RATE: {
|
||||
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH);
|
||||
result = ptmeConfig.setRate(RATE_500KBPS);
|
||||
break;
|
||||
}
|
||||
case ARBITRARY_RATE: {
|
||||
uint32_t bitrate = 0;
|
||||
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
|
||||
result = ptmeConfig.setRate(bitrate);
|
||||
result = SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
ptmeConfig.setRate(bitrate);
|
||||
updateContext.updateClockRate = true;
|
||||
if (mode == MODE_OFF) {
|
||||
initPtmeUpdateAfterXCycles();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EN_TRANSMITTER: {
|
||||
enableTransmit();
|
||||
if (mode == HasModesIF::MODE_OFF) {
|
||||
mode = HasModesIF::MODE_ON;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case DISABLE_TRANSMITTER: {
|
||||
disableTransmit();
|
||||
if (mode == HasModesIF::MODE_ON) {
|
||||
mode = HasModesIF::MODE_OFF;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case ENABLE_TX_CLK_MANIPULATOR: {
|
||||
result = ptmeConfig.configTxManipulator(true);
|
||||
ptmeConfig.configTxManipulator(true);
|
||||
break;
|
||||
}
|
||||
case DISABLE_TX_CLK_MANIPULATOR: {
|
||||
result = ptmeConfig.configTxManipulator(false);
|
||||
ptmeConfig.configTxManipulator(false);
|
||||
break;
|
||||
}
|
||||
case UPDATE_ON_RISING_EDGE: {
|
||||
result = ptmeConfig.invertTxClock(false);
|
||||
ptmeConfig.invertTxClock(false);
|
||||
break;
|
||||
}
|
||||
case UPDATE_ON_FALLING_EDGE: {
|
||||
result = ptmeConfig.invertTxClock(true);
|
||||
ptmeConfig.invertTxClock(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -206,12 +218,8 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
|
||||
void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
|
||||
|
||||
void CcsdsIpCoreHandler::enableTransmit() {
|
||||
// Reset PTME on each transmit enable.
|
||||
updateBatPriorityFromParam();
|
||||
#ifndef TE0720_1CFA
|
||||
gpioIF->pullHigh(ptmeGpios.enableTxClock);
|
||||
gpioIF->pullHigh(ptmeGpios.enableTxData);
|
||||
#endif
|
||||
linkState = LINK_UP;
|
||||
}
|
||||
|
||||
@ -236,34 +244,23 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
||||
auto rateSet = [&](uint32_t rate) {
|
||||
ReturnValue_t result = ptmeConfig.setRate(rate);
|
||||
if (result == returnvalue::OK) {
|
||||
this->mode = HasModesIF::MODE_ON;
|
||||
}
|
||||
};
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
if (mode == HasModesIF::MODE_ON) {
|
||||
enableTransmit();
|
||||
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
|
||||
com::Datarate currentDatarate = com::getCurrentDatarate();
|
||||
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
||||
rateSet(RATE_100KBPS);
|
||||
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
||||
rateSet(RATE_500KBPS);
|
||||
}
|
||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
|
||||
rateSet(RATE_500KBPS);
|
||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
|
||||
rateSet(RATE_100KBPS);
|
||||
if (this->submode != submode) {
|
||||
initPtmeUpdateAfterXCycles();
|
||||
updateContext.enableTransmitAfterPtmeUpdate = true;
|
||||
updateContext.updateClockRate = true;
|
||||
this->submode = submode;
|
||||
this->mode = mode;
|
||||
updateContext.setModeAfterUpdate = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// No rate change, so enable transmitter right away.
|
||||
enableTransmit();
|
||||
} else if (mode == HasModesIF::MODE_OFF) {
|
||||
disableTransmit();
|
||||
this->mode = HasModesIF::MODE_OFF;
|
||||
}
|
||||
this->submode = submode;
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
setMode(mode, submode);
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
|
||||
@ -274,9 +271,9 @@ void CcsdsIpCoreHandler::disableTransmit() {
|
||||
gpioIF->pullLow(ptmeGpios.enableTxData);
|
||||
#endif
|
||||
linkState = LINK_DOWN;
|
||||
if (updateBatPriorityOnTxOff) {
|
||||
updateBatPriorityFromParam();
|
||||
updateBatPriorityOnTxOff = false;
|
||||
// Some parameters need update and transmitter is off now.
|
||||
if (updateContext.updateBatPrio or updateContext.updateClockRate) {
|
||||
initPtmeUpdateAfterXCycles();
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,26 +291,95 @@ ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; }
|
||||
|
||||
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
void CcsdsIpCoreHandler::enablePrioritySelectMode() {
|
||||
ptmeConfig.enableBatPriorityBit(true);
|
||||
// Reset the PTME
|
||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
||||
usleep(10);
|
||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
||||
}
|
||||
void CcsdsIpCoreHandler::enablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(true); }
|
||||
|
||||
void CcsdsIpCoreHandler::disablePrioritySelectMode() {
|
||||
ptmeConfig.enableBatPriorityBit(false);
|
||||
// Reset the PTME
|
||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
||||
usleep(10);
|
||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
||||
}
|
||||
void CcsdsIpCoreHandler::disablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(false); }
|
||||
|
||||
void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
|
||||
if (batPriorityParam == 0) {
|
||||
if (params.batPriorityParam == 0) {
|
||||
disablePrioritySelectMode();
|
||||
} else {
|
||||
enablePrioritySelectMode();
|
||||
}
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::setMode(Mode_t mode, Submode_t submode) {
|
||||
this->submode = submode;
|
||||
this->mode = mode;
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::performPtmeUpdateWhenApplicable() {
|
||||
if (not updateContext.performPtmeUpdateAfterXCycles) {
|
||||
return;
|
||||
}
|
||||
if (updateContext.ptmeUpdateCycleCount >= 2) {
|
||||
bool doResetPtme = false;
|
||||
if (updateContext.updateBatPrio) {
|
||||
updateBatPriorityFromParam();
|
||||
updateContext.updateBatPrio = false;
|
||||
doResetPtme = true;
|
||||
}
|
||||
if (updateContext.updatePollThreshold) {
|
||||
ptmeConfig.setPollThreshold(
|
||||
static_cast<AxiPtmeConfig::IdlePollThreshold>(params.pollThresholdParam));
|
||||
updateContext.updatePollThreshold = false;
|
||||
doResetPtme = true;
|
||||
}
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
if (updateContext.updateClockRate) {
|
||||
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
|
||||
com::Datarate currentDatarate = com::getCurrentDatarate();
|
||||
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
||||
result = ptmeConfig.setRate(RATE_100KBPS);
|
||||
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
||||
result = ptmeConfig.setRate(RATE_500KBPS);
|
||||
}
|
||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
|
||||
result = ptmeConfig.setRate(RATE_500KBPS);
|
||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
|
||||
result = ptmeConfig.setRate(RATE_100KBPS);
|
||||
}
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "CcsdsIpCoreHandler: Setting datarate failed" << std::endl;
|
||||
}
|
||||
updateContext.updateClockRate = false;
|
||||
doResetPtme = true;
|
||||
}
|
||||
finishPtmeUpdateAfterXCycles(doResetPtme);
|
||||
return;
|
||||
}
|
||||
updateContext.ptmeUpdateCycleCount++;
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::resetPtme() {
|
||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
||||
usleep(10);
|
||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::initPtmeUpdateAfterXCycles() {
|
||||
if (not updateContext.performPtmeUpdateAfterXCycles) {
|
||||
updateContext.performPtmeUpdateAfterXCycles = true;
|
||||
updateContext.ptmeUpdateCycleCount = 0;
|
||||
ptmeLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CcsdsIpCoreHandler::finishPtmeUpdateAfterXCycles(bool doResetPtme) {
|
||||
if (doResetPtme) {
|
||||
resetPtme();
|
||||
}
|
||||
ptmeLocked = false;
|
||||
updateContext.performPtmeUpdateAfterXCycles = false;
|
||||
updateContext.ptmeUpdateCycleCount = 0;
|
||||
if (updateContext.enableTransmitAfterPtmeUpdate) {
|
||||
enableTransmit();
|
||||
updateContext.enableTransmitAfterPtmeUpdate = false;
|
||||
}
|
||||
if (updateContext.setModeAfterUpdate) {
|
||||
setMode(mode, submode);
|
||||
updateContext.setModeAfterUpdate = false;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
#define CCSDSHANDLER_H_
|
||||
|
||||
#include <fsfw/modes/HasModesIF.h>
|
||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
||||
#include <mission/com/VirtualChannelWithQueue.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
@ -23,7 +23,7 @@
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
#include "linux/ipcore/PtmeConfig.h"
|
||||
#include "mission/comDefs.h"
|
||||
#include "mission/com/defs.h"
|
||||
|
||||
struct PtmeGpios {
|
||||
gpioId_t enableTxClock = gpio::NO_GPIO;
|
||||
@ -36,6 +36,10 @@ struct PtmeGpios {
|
||||
* programmable logic of the Q7S.
|
||||
*
|
||||
* @details
|
||||
* From a system view, OFF means that the transmitter is off, on means that the transmitter is on.
|
||||
* The handler will only take care of the IP configuration, the actual swithing and configuration
|
||||
* of the COM hardware (Syrlinks for the EIVE project) will be done in a separate device handler.
|
||||
*
|
||||
* After reboot default CADU bitrate is always set to 100 kbps (results in downlink rate
|
||||
* of 200 kbps due to convolutional code added by syrlinks transceiver). The IP core handler exposes
|
||||
* a parameter to enable the priority selection mode for the PTME core.
|
||||
@ -56,7 +60,7 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
enum ParamId : uint8_t { BAT_PRIORITY = 0 };
|
||||
enum ParamId : uint8_t { BAT_PRIORITY = 0, POLL_THRESHOLD = 1 };
|
||||
|
||||
static const bool LINK_UP = true;
|
||||
static const bool LINK_DOWN = false;
|
||||
@ -75,7 +79,8 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
* @param enTxData GPIO ID of RS485 tx data enable
|
||||
*/
|
||||
CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig,
|
||||
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds);
|
||||
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds,
|
||||
std::atomic_bool& ptmeLocked);
|
||||
|
||||
~CcsdsIpCoreHandler();
|
||||
|
||||
@ -133,9 +138,8 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
||||
|
||||
// using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannelWithQueue*>;
|
||||
// VirtualChannelMap virtualChannelMap;
|
||||
std::atomic_bool& linkState;
|
||||
std::atomic_bool& ptmeLocked;
|
||||
|
||||
object_id_t tcDestination;
|
||||
|
||||
@ -152,9 +156,22 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
|
||||
PtmeConfig& ptmeConfig;
|
||||
PtmeGpios ptmeGpios;
|
||||
// BAT priority bit on by default to enable priority selection mode for the PTME.
|
||||
uint8_t batPriorityParam = 0;
|
||||
bool updateBatPriorityOnTxOff = false;
|
||||
struct Parameters {
|
||||
// BAT priority bit on by default to enable priority selection mode for the PTME.
|
||||
uint8_t batPriorityParam = 0;
|
||||
uint8_t pollThresholdParam = static_cast<uint8_t>(AxiPtmeConfig::IdlePollThreshold::POLL_4);
|
||||
|
||||
} params;
|
||||
|
||||
struct UpdateContext {
|
||||
bool updateBatPrio = false;
|
||||
bool updateClockRate = false;
|
||||
bool updatePollThreshold = false;
|
||||
bool enableTransmitAfterPtmeUpdate = false;
|
||||
uint8_t ptmeUpdateCycleCount = 0;
|
||||
bool performPtmeUpdateAfterXCycles = false;
|
||||
bool setModeAfterUpdate = false;
|
||||
} updateContext{};
|
||||
|
||||
GpioIF* gpioIF = nullptr;
|
||||
|
||||
@ -176,6 +193,8 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
*/
|
||||
void disableTransmit();
|
||||
|
||||
void performPtmeUpdateWhenApplicable();
|
||||
|
||||
/**
|
||||
* The following set of functions configure the mode of the PTME bandwith allocation table (BAT)
|
||||
* module. This consists of the following 2 steps:
|
||||
@ -185,6 +204,11 @@ class CcsdsIpCoreHandler : public SystemObject,
|
||||
void enablePrioritySelectMode();
|
||||
void disablePrioritySelectMode();
|
||||
void updateBatPriorityFromParam();
|
||||
|
||||
void setMode(Mode_t mode, Submode_t submode);
|
||||
void resetPtme();
|
||||
void initPtmeUpdateAfterXCycles();
|
||||
void finishPtmeUpdateAfterXCycles(bool doResetPtme);
|
||||
};
|
||||
|
||||
#endif /* CCSDSHANDLER_H_ */
|
107
mission/com/LiveTmTask.cpp
Normal file
107
mission/com/LiveTmTask.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "LiveTmTask.h"
|
||||
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/subsystem/helper.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
|
||||
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked)
|
||||
: SystemObject(objectId),
|
||||
modeHelper(this),
|
||||
pusFunnel(pusFunnel),
|
||||
cfdpFunnel(cfdpFunnel),
|
||||
channel(channel),
|
||||
ptmeLocked(ptmeLocked) {
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue();
|
||||
}
|
||||
|
||||
ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
|
||||
readCommandQueue();
|
||||
while (true) {
|
||||
bool performWriteOp = true;
|
||||
if (mode == MODE_OFF or ptmeLocked) {
|
||||
performWriteOp = false;
|
||||
}
|
||||
|
||||
// The funnel tasks are scheduled here directly as well.
|
||||
ReturnValue_t result = channel.handleNextTm(performWriteOp);
|
||||
if (result == DirectTmSinkIF::IS_BUSY) {
|
||||
sif::error << "Lost live TM, PAPB busy" << std::endl;
|
||||
}
|
||||
if (result == MessageQueueIF::EMPTY) {
|
||||
if (tmFunnelCd.hasTimedOut()) {
|
||||
pusFunnel.performOperation(0);
|
||||
cfdpFunnel.performOperation(0);
|
||||
tmFunnelCd.resetTimer();
|
||||
}
|
||||
// Read command queue during idle times.
|
||||
readCommandQueue();
|
||||
// 40 ms IDLE delay. Might tweak this in the future.
|
||||
TaskFactory::delayTask(40);
|
||||
} else {
|
||||
packetCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueId_t LiveTmTask::getCommandQueue() const { return requestQueue->getId(); }
|
||||
|
||||
void LiveTmTask::getMode(Mode_t* mode, Submode_t* submode) {
|
||||
if (mode != nullptr) {
|
||||
*mode = this->mode;
|
||||
}
|
||||
if (submode != nullptr) {
|
||||
*submode = SUBMODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t LiveTmTask::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
if (mode == MODE_ON or mode == MODE_OFF) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
void LiveTmTask::startTransition(Mode_t mode, Submode_t submode) {
|
||||
this->mode = mode;
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
}
|
||||
|
||||
void LiveTmTask::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); }
|
||||
|
||||
object_id_t LiveTmTask::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
const HasHealthIF* LiveTmTask::getOptHealthIF() const { return nullptr; }
|
||||
|
||||
const HasModesIF& LiveTmTask::getModeIF() const { return *this; }
|
||||
|
||||
ReturnValue_t LiveTmTask::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
|
||||
}
|
||||
|
||||
void LiveTmTask::readCommandQueue(void) {
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = returnvalue::FAILED;
|
||||
|
||||
result = requestQueue->receiveMessage(&commandMessage);
|
||||
if (result == returnvalue::OK) {
|
||||
result = modeHelper.handleModeCommand(&commandMessage);
|
||||
if (result == returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
CommandMessage reply;
|
||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
|
||||
requestQueue->reply(&reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; }
|
||||
|
||||
ReturnValue_t LiveTmTask::initialize() {
|
||||
modeHelper.initialize();
|
||||
return returnvalue::OK;
|
||||
}
|
57
mission/com/LiveTmTask.h
Normal file
57
mission/com/LiveTmTask.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef MISSION_TMTC_LIVETMTASK_H_
|
||||
#define MISSION_TMTC_LIVETMTASK_H_
|
||||
|
||||
#include <fsfw/modes/HasModesIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
||||
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <mission/com/VirtualChannelWithQueue.h>
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PusTmFunnel.h>
|
||||
|
||||
class LiveTmTask : public SystemObject,
|
||||
public HasModesIF,
|
||||
public ExecutableObjectIF,
|
||||
public ModeTreeChildIF,
|
||||
public ModeTreeConnectionIF {
|
||||
public:
|
||||
LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked);
|
||||
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
||||
|
||||
private:
|
||||
MessageQueueIF* requestQueue;
|
||||
ModeHelper modeHelper;
|
||||
Mode_t mode = HasModesIF::MODE_OFF;
|
||||
Countdown tmFunnelCd = Countdown(100);
|
||||
PusTmFunnel& pusFunnel;
|
||||
CfdpTmFunnel& cfdpFunnel;
|
||||
VirtualChannelWithQueue& channel;
|
||||
uint32_t packetCounter = 0;
|
||||
const std::atomic_bool& ptmeLocked;
|
||||
|
||||
void readCommandQueue(void);
|
||||
|
||||
MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
void getMode(Mode_t* mode, Submode_t* submode) override;
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
|
||||
void announceMode(bool recursive) override;
|
||||
|
||||
object_id_t getObjectId() const override;
|
||||
const HasHealthIF* getOptHealthIF() const override;
|
||||
const HasModesIF& getModeIF() const override;
|
||||
ModeTreeChildIF& getModeTreeChildIF() override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_TMTC_LIVETMTASK_H_ */
|
74
mission/com/PersistentLogTmStoreTask.cpp
Normal file
74
mission/com/PersistentLogTmStoreTask.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include "PersistentLogTmStoreTask.h"
|
||||
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
|
||||
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||
LogStores stores, VirtualChannel& channel,
|
||||
SdCardMountedIF& sdcMan,
|
||||
const std::atomic_bool& ptmeLocked)
|
||||
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
|
||||
stores(stores),
|
||||
okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED),
|
||||
notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED),
|
||||
miscStoreContext(persTmStore::DUMP_MISC_STORE_DONE, persTmStore::DUMP_MISC_CANCELLED) {}
|
||||
|
||||
ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
|
||||
bool someonesBusy = false;
|
||||
bool vcBusyDuringDump = false;
|
||||
auto stateHandlingForStore = [&](bool storeIsBusy, DumpContext& ctx) {
|
||||
if (storeIsBusy) {
|
||||
someonesBusy = true;
|
||||
}
|
||||
if (fileHasSwapped) {
|
||||
someFileWasSwapped = fileHasSwapped;
|
||||
}
|
||||
if (ctx.vcBusyDuringDump) {
|
||||
vcBusyDuringDump = true;
|
||||
}
|
||||
};
|
||||
while (true) {
|
||||
readCommandQueue();
|
||||
|
||||
if (not cyclicStoreCheck()) {
|
||||
continue;
|
||||
}
|
||||
someonesBusy = false;
|
||||
someFileWasSwapped = false;
|
||||
vcBusyDuringDump = false;
|
||||
stateHandlingForStore(handleOneStore(stores.okStore, okStoreContext), okStoreContext);
|
||||
stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext), notOkStoreContext);
|
||||
stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext), miscStoreContext);
|
||||
if (not someonesBusy) {
|
||||
TaskFactory::delayTask(100);
|
||||
} else if (vcBusyDuringDump) {
|
||||
// TODO: Might not be necessary
|
||||
sif::debug << "VC busy, delaying" << std::endl;
|
||||
TaskFactory::delayTask(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PersistentLogTmStoreTask::initStoresIfPossible() {
|
||||
if (sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
stores.okStore.initializeTmStore();
|
||||
stores.miscStore.initializeTmStore();
|
||||
stores.notOkStore.initializeTmStore();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PersistentLogTmStoreTask::startTransition(Mode_t mode, Submode_t submode) {
|
||||
if (mode == MODE_OFF) {
|
||||
bool channelIsOn = channel.isTxOn();
|
||||
cancelDump(okStoreContext, stores.okStore, channelIsOn);
|
||||
cancelDump(notOkStoreContext, stores.notOkStore, channelIsOn);
|
||||
cancelDump(miscStoreContext, stores.miscStore, channelIsOn);
|
||||
this->mode = MODE_OFF;
|
||||
} else if (mode == MODE_ON) {
|
||||
this->mode = MODE_ON;
|
||||
}
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
}
|
@ -5,11 +5,11 @@
|
||||
#include <fsfw/storagemanager/StorageManagerIF.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <mission/core/GenericFactory.h>
|
||||
#include <mission/com/TmStoreTaskBase.h>
|
||||
#include <mission/com/VirtualChannelWithQueue.h>
|
||||
#include <mission/genericFactory.h>
|
||||
#include <mission/tmtc/PersistentTmStore.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
#include <mission/tmtc/TmStoreTaskBase.h>
|
||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
||||
|
||||
struct LogStores {
|
||||
LogStores(PersistentTmStores& stores)
|
||||
@ -22,7 +22,8 @@ struct LogStores {
|
||||
class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
||||
public:
|
||||
PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore,
|
||||
VirtualChannel& channel, SdCardMountedIF& sdcMan);
|
||||
VirtualChannel& channel, SdCardMountedIF& sdcMan,
|
||||
const std::atomic_bool& ptmeLocked);
|
||||
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
@ -35,7 +36,8 @@ class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObject
|
||||
Countdown graceDelayDuringDumping = Countdown(200);
|
||||
bool someFileWasSwapped = false;
|
||||
|
||||
bool initStoresIfPossible();
|
||||
bool initStoresIfPossible() override;
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */
|
54
mission/com/PersistentSingleTmStoreTask.cpp
Normal file
54
mission/com/PersistentSingleTmStoreTask.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "PersistentSingleTmStoreTask.h"
|
||||
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <unistd.h>
|
||||
|
||||
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
|
||||
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
|
||||
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan,
|
||||
const std::atomic_bool& ptmeLocked)
|
||||
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
|
||||
storeWithQueue(tmStore),
|
||||
dumpContext(eventIfDumpDone, eventIfCancelled) {}
|
||||
|
||||
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
||||
while (true) {
|
||||
readCommandQueue();
|
||||
|
||||
// Delay done by the check
|
||||
if (not cyclicStoreCheck()) {
|
||||
continue;
|
||||
}
|
||||
bool busy = handleOneStore(storeWithQueue, dumpContext);
|
||||
if (not busy) {
|
||||
TaskFactory::delayTask(100);
|
||||
} else if (dumpContext.vcBusyDuringDump) {
|
||||
sif::debug << "VC busy, delaying" << std::endl;
|
||||
// TODO: Might not be necessary
|
||||
TaskFactory::delayTask(10);
|
||||
} else {
|
||||
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
||||
TaskFactory::delayTask(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PersistentSingleTmStoreTask::initStoresIfPossible() {
|
||||
if (sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
storeWithQueue.initializeTmStore();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PersistentSingleTmStoreTask::startTransition(Mode_t mode, Submode_t submode) {
|
||||
if (mode == MODE_OFF) {
|
||||
cancelDump(dumpContext, storeWithQueue, channel.isTxOn());
|
||||
this->mode = MODE_OFF;
|
||||
} else if (mode == MODE_ON) {
|
||||
this->mode = MODE_ON;
|
||||
}
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
}
|
@ -3,15 +3,16 @@
|
||||
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <mission/com/TmStoreTaskBase.h>
|
||||
#include <mission/com/VirtualChannel.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
#include <mission/tmtc/TmStoreTaskBase.h>
|
||||
#include <mission/tmtc/VirtualChannel.h>
|
||||
|
||||
class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
||||
public:
|
||||
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||
PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel,
|
||||
Event eventIfDumpDone, SdCardMountedIF& sdcMan);
|
||||
Event eventIfDumpDone, Event eventIfCancelled,
|
||||
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
|
||||
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
@ -21,7 +22,9 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj
|
||||
Countdown tcHandlingCd = Countdown(400);
|
||||
Countdown graceDelayDuringDumping = Countdown(100);
|
||||
|
||||
bool initStoresIfPossible();
|
||||
bool initStoresIfPossible() override;
|
||||
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */
|
@ -1,6 +1,6 @@
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <mission/devices/SyrlinksHandler.h>
|
||||
#include <mission/com/SyrlinksHandler.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "mission/config/comCfg.h"
|
||||
@ -27,8 +27,9 @@ void SyrlinksHandler::doStartUp() {
|
||||
if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) {
|
||||
if (commandExecuted) {
|
||||
// Go to normal mode immediately and disable transmitter on startup.
|
||||
setMode(_MODE_TO_NORMAL);
|
||||
setMode(_MODE_TO_ON);
|
||||
internalState = InternalState::IDLE;
|
||||
transState = TransitionState::IDLE;
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
@ -36,14 +37,16 @@ void SyrlinksHandler::doStartUp() {
|
||||
|
||||
void SyrlinksHandler::doShutDown() {
|
||||
// In any case, always disable TX first.
|
||||
if (internalState != InternalState::SET_TX_STANDBY) {
|
||||
internalState = InternalState::SET_TX_STANDBY;
|
||||
if (internalState != InternalState::TX_TRANSITION) {
|
||||
internalState = InternalState::TX_TRANSITION;
|
||||
transState = TransitionState::SET_TX_STANDBY;
|
||||
commandExecuted = false;
|
||||
}
|
||||
if (internalState == InternalState::SET_TX_STANDBY) {
|
||||
if (internalState == InternalState::TX_TRANSITION) {
|
||||
if (commandExecuted) {
|
||||
temperatureSet.setValidity(false, true);
|
||||
internalState = InternalState::OFF;
|
||||
transState = TransitionState::IDLE;
|
||||
commandExecuted = false;
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
@ -97,33 +100,47 @@ ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
|
||||
ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (transState == TransitionState::CMD_PENDING or transState == TransitionState::DONE) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
switch (internalState) {
|
||||
case InternalState::ENABLE_TEMPERATURE_PROTECTION: {
|
||||
*id = syrlinks::WRITE_LCL_CONFIG;
|
||||
transState = TransitionState::CMD_PENDING;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case InternalState::SET_TX_MODULATION: {
|
||||
*id = syrlinks::SET_TX_MODE_MODULATION;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case InternalState::SELECT_MODULATION_BPSK: {
|
||||
*id = syrlinks::SET_WAVEFORM_BPSK;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case InternalState::SELECT_MODULATION_0QPSK: {
|
||||
*id = syrlinks::SET_WAVEFORM_0QPSK;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case InternalState::SET_TX_CW: {
|
||||
*id = syrlinks::SET_TX_MODE_CW;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case InternalState::SET_TX_STANDBY: {
|
||||
*id = syrlinks::SET_TX_MODE_STANDBY;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
default:
|
||||
case InternalState::TX_TRANSITION: {
|
||||
switch (transState) {
|
||||
case TransitionState::SET_TX_MODULATION: {
|
||||
*id = syrlinks::SET_TX_MODE_MODULATION;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case TransitionState::SELECT_MODULATION_BPSK: {
|
||||
*id = syrlinks::SET_WAVEFORM_BPSK;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case TransitionState::SELECT_MODULATION_0QPSK: {
|
||||
*id = syrlinks::SET_WAVEFORM_0QPSK;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case TransitionState::SET_TX_CW: {
|
||||
*id = syrlinks::SET_TX_MODE_CW;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case TransitionState::SET_TX_STANDBY: {
|
||||
*id = syrlinks::SET_TX_MODE_STANDBY;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
default: {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
}
|
||||
transState = TransitionState::CMD_PENDING;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
@ -442,7 +459,6 @@ ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
|
||||
}
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -620,8 +636,6 @@ void SyrlinksHandler::parseAgcHighByte(const uint8_t* packet) {
|
||||
agcValueHighByte = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
|
||||
}
|
||||
|
||||
void SyrlinksHandler::setNormalDatapoolEntriesInvalid() {}
|
||||
|
||||
uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; }
|
||||
|
||||
ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
@ -641,16 +655,20 @@ ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& loca
|
||||
localDataPoolMap.emplace(syrlinks::TEMP_BASEBAND_BOARD, new PoolEntry<float>({0}));
|
||||
localDataPoolMap.emplace(syrlinks::TEMP_POWER_AMPLIFIER, new PoolEntry<float>({0}));
|
||||
|
||||
bool enableHkSets = false;
|
||||
#if OBSW_ENABLE_PERIODIC_HK == 1
|
||||
enableHkSets = true;
|
||||
#endif
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(txDataset.getSid(), false, 5.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(txDataset.getSid(), enableHkSets, 60.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(rxDataset.getSid(), false, 5.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(rxDataset.getSid(), enableHkSets, 60.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), false, 10.0));
|
||||
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 120.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void SyrlinksHandler::setModeNormal() { setMode(MODE_NORMAL); }
|
||||
void SyrlinksHandler::setModeNormal() { setMode(_MODE_TO_NORMAL); }
|
||||
|
||||
float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; }
|
||||
|
||||
@ -669,15 +687,37 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
|
||||
break;
|
||||
}
|
||||
case (syrlinks::SET_WAVEFORM_BPSK):
|
||||
case (syrlinks::SET_WAVEFORM_0QPSK):
|
||||
case (syrlinks::SET_TX_MODE_STANDBY):
|
||||
case (syrlinks::SET_TX_MODE_MODULATION):
|
||||
case (syrlinks::SET_TX_MODE_CW): {
|
||||
case (syrlinks::SET_WAVEFORM_0QPSK): {
|
||||
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||
transState = TransitionState::SET_TX_MODULATION;
|
||||
commandExecuted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (syrlinks::SET_TX_MODE_STANDBY): {
|
||||
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||
transState = TransitionState::DONE;
|
||||
commandExecuted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (syrlinks::SET_TX_MODE_MODULATION): {
|
||||
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||
transState = TransitionState::DONE;
|
||||
commandExecuted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (syrlinks::SET_TX_MODE_CW): {
|
||||
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||
commandExecuted = true;
|
||||
transState = TransitionState::DONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::error << "Syrlinks: Unexpected ACK reply" << std::endl;
|
||||
}
|
||||
}
|
||||
switch (rememberCommandId) {
|
||||
case (syrlinks::SET_TX_MODE_STANDBY): {
|
||||
@ -695,7 +735,7 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
|
||||
|
||||
ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (submode >= com::Submode::NUM_SUBMODES) {
|
||||
if (submode >= com::Submode::NUM_SUBMODES or submode < com::Submode::RX_ONLY) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -722,68 +762,54 @@ void SyrlinksHandler::setDebugMode(bool enable) { this->debugMode = enable; }
|
||||
|
||||
void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
Mode_t tgtMode = getBaseMode(getMode());
|
||||
auto commandDone = [&]() {
|
||||
setMode(tgtMode);
|
||||
auto doneHandler = [&]() {
|
||||
internalState = InternalState::IDLE;
|
||||
transState = TransitionState::IDLE;
|
||||
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||
};
|
||||
auto txOnHandler = [&](InternalState selMod) {
|
||||
if (internalState == InternalState::IDLE) {
|
||||
commandExecuted = false;
|
||||
internalState = selMod;
|
||||
}
|
||||
// Select modulation first (BPSK or 0QPSK).
|
||||
if (internalState == selMod) {
|
||||
if (commandExecuted) {
|
||||
internalState = InternalState::SET_TX_MODULATION;
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
// Now go into modulation mode.
|
||||
if (internalState == InternalState::SET_TX_MODULATION) {
|
||||
if (commandExecuted) {
|
||||
commandDone();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (transState == TransitionState::DONE) {
|
||||
return doneHandler();
|
||||
}
|
||||
auto txStandbyHandler = [&]() {
|
||||
if (internalState == InternalState::IDLE) {
|
||||
internalState = InternalState::SET_TX_STANDBY;
|
||||
commandExecuted = false;
|
||||
}
|
||||
if (internalState == InternalState::SET_TX_STANDBY) {
|
||||
if (commandExecuted) {
|
||||
commandDone();
|
||||
return;
|
||||
}
|
||||
}
|
||||
txDataset.setReportingEnabled(false);
|
||||
poolManager.changeCollectionInterval(temperatureSet.getSid(), 60.0);
|
||||
transState = TransitionState::SET_TX_STANDBY;
|
||||
internalState = InternalState::TX_TRANSITION;
|
||||
};
|
||||
auto txOnHandler = [&](TransitionState tgtTransitionState) {
|
||||
txDataset.setReportingEnabled(true);
|
||||
poolManager.changeCollectionInterval(txDataset.getSid(), 10.0);
|
||||
poolManager.changeCollectionInterval(temperatureSet.getSid(), 5.0);
|
||||
transState = tgtTransitionState;
|
||||
internalState = InternalState::TX_TRANSITION;
|
||||
};
|
||||
|
||||
if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
// If submode has not changed, no special transition handling necessary.
|
||||
if (getSubmode() == subModeFrom) {
|
||||
return doneHandler();
|
||||
}
|
||||
// Transition is on-going, wait for it to finish.
|
||||
if (transState != TransitionState::IDLE) {
|
||||
return;
|
||||
}
|
||||
// Transition start logic.
|
||||
switch (getSubmode()) {
|
||||
case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): {
|
||||
auto currentDatarate = com::getCurrentDatarate();
|
||||
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
||||
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
|
||||
return;
|
||||
}
|
||||
txOnHandler(TransitionState::SELECT_MODULATION_BPSK);
|
||||
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
||||
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
|
||||
return;
|
||||
}
|
||||
txOnHandler(TransitionState::SELECT_MODULATION_0QPSK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (com::Submode::RX_AND_TX_LOW_DATARATE): {
|
||||
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
|
||||
return;
|
||||
}
|
||||
txOnHandler(TransitionState::SELECT_MODULATION_BPSK);
|
||||
break;
|
||||
}
|
||||
case (com::Submode::RX_AND_TX_HIGH_DATARATE): {
|
||||
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
|
||||
return;
|
||||
}
|
||||
txOnHandler(TransitionState::SELECT_MODULATION_0QPSK);
|
||||
break;
|
||||
}
|
||||
case (com::Submode::RX_ONLY): {
|
||||
@ -791,21 +817,17 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
return;
|
||||
}
|
||||
case (com::Submode::RX_AND_TX_CW): {
|
||||
if (internalState == InternalState::IDLE) {
|
||||
internalState = InternalState::SET_TX_STANDBY;
|
||||
commandExecuted = false;
|
||||
}
|
||||
if (commandExecuted) {
|
||||
commandDone();
|
||||
return;
|
||||
}
|
||||
txOnHandler(TransitionState::SET_TX_CW);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
commandDone();
|
||||
sif::error << "SyrlinksHandler: Unexpected submode " << getSubmode() << std::endl;
|
||||
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||
}
|
||||
}
|
||||
} else if (tgtMode == HasModesIF::MODE_OFF) {
|
||||
txStandbyHandler();
|
||||
} else {
|
||||
return doneHandler();
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
#include "fsfw_hal/linux/gpio/Gpio.h"
|
||||
#include "mission/comDefs.h"
|
||||
#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h"
|
||||
#include "mission/com/defs.h"
|
||||
#include "mission/com/syrlinksDefs.h"
|
||||
#include "returnvalues/classIds.h"
|
||||
|
||||
/**
|
||||
@ -46,7 +46,6 @@ class SyrlinksHandler : public DeviceHandlerBase {
|
||||
size_t* foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
@ -118,15 +117,20 @@ class SyrlinksHandler : public DeviceHandlerBase {
|
||||
enum class InternalState {
|
||||
OFF,
|
||||
ENABLE_TEMPERATURE_PROTECTION,
|
||||
TX_TRANSITION,
|
||||
IDLE
|
||||
} internalState = InternalState::OFF;
|
||||
|
||||
enum class TransitionState {
|
||||
IDLE,
|
||||
SELECT_MODULATION_BPSK,
|
||||
SELECT_MODULATION_0QPSK,
|
||||
SET_TX_MODULATION,
|
||||
SET_TX_CW,
|
||||
SET_TX_STANDBY,
|
||||
IDLE
|
||||
};
|
||||
|
||||
InternalState internalState = InternalState::OFF;
|
||||
CMD_PENDING,
|
||||
DONE
|
||||
} transState = TransitionState::IDLE;
|
||||
|
||||
/**
|
||||
* This object is used to store the id of the next command to execute. This controls the
|
228
mission/com/TmStoreTaskBase.cpp
Normal file
228
mission/com/TmStoreTaskBase.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
#include "TmStoreTaskBase.h"
|
||||
|
||||
#include <fsfw/ipc/CommandMessageIF.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/subsystem/helper.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <fsfw/tmstorage/TmStoreMessage.h>
|
||||
|
||||
#include "mission/persistentTmStoreDefs.h"
|
||||
|
||||
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||
VirtualChannel& channel, SdCardMountedIF& sdcMan,
|
||||
const std::atomic_bool& ptmeLocked)
|
||||
: SystemObject(objectId),
|
||||
modeHelper(this),
|
||||
ipcStore(ipcStore),
|
||||
tmReader(&timeReader),
|
||||
channel(channel),
|
||||
sdcMan(sdcMan),
|
||||
ptmeLocked(ptmeLocked) {
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(10);
|
||||
}
|
||||
|
||||
bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
|
||||
DumpContext& dumpContext) {
|
||||
ReturnValue_t result;
|
||||
bool tmToStoreReceived = false;
|
||||
bool tcRequestReceived = false;
|
||||
bool dumpPerformed = false;
|
||||
fileHasSwapped = false;
|
||||
dumpContext.packetWasDumped = false;
|
||||
dumpContext.vcBusyDuringDump = false;
|
||||
|
||||
// Store TM persistently
|
||||
result = store.handleNextTm();
|
||||
if (result == returnvalue::OK) {
|
||||
tmToStoreReceived = true;
|
||||
}
|
||||
// Dump TMs
|
||||
if (store.getState() == PersistentTmStore::State::DUMPING) {
|
||||
if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
Command_t execCmd;
|
||||
// Handle TC requests, for example deletion or retrieval requests.
|
||||
result = store.handleCommandQueue(ipcStore, execCmd);
|
||||
if (result == returnvalue::OK) {
|
||||
if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
|
||||
cancelDumpCd.resetTimer();
|
||||
tmSinkBusyCd.resetTimer();
|
||||
dumpContext.reset();
|
||||
}
|
||||
tcRequestReceived = true;
|
||||
}
|
||||
}
|
||||
if (tcRequestReceived or tmToStoreReceived or dumpPerformed) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TmStoreTaskBase::cyclicStoreCheck() {
|
||||
if (not storesInitialized) {
|
||||
storesInitialized = initStoresIfPossible();
|
||||
if (not storesInitialized) {
|
||||
TaskFactory::delayTask(400);
|
||||
return false;
|
||||
}
|
||||
} else if (sdCardCheckCd.hasTimedOut()) {
|
||||
if (not sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
// Might be due to imminent shutdown or SD card switch.
|
||||
storesInitialized = false;
|
||||
TaskFactory::delayTask(100);
|
||||
return false;
|
||||
}
|
||||
sdCardCheckCd.resetTimer();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) {
|
||||
ctx.reset();
|
||||
if (store.getState() == PersistentTmStore::State::DUMPING) {
|
||||
triggerEvent(ctx.eventIfCancelled, ctx.numberOfDumpedPackets, ctx.dumpedBytes);
|
||||
}
|
||||
store.cancelDump();
|
||||
if (isTxOn) {
|
||||
channel.cancelTransfer();
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
|
||||
DumpContext& dumpContext, bool& dumpPerformed) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
// The PTME might have been reset an transmitter state change, so there is no point in continuing
|
||||
// the dump.
|
||||
// TODO: Will be solved in a cleaner way, this is kind of a hack.
|
||||
if (not channel.isTxOn()) {
|
||||
cancelDump(dumpContext, store, false);
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
// It is assumed that the PTME will only be locked for a short period (e.g. to change datarate).
|
||||
if (not channel.isBusy() and not ptmeLocked) {
|
||||
performDump(store, dumpContext, dumpPerformed);
|
||||
} else {
|
||||
// The PTME might be at full load, so it might sense to delay for a bit to let it do
|
||||
// its work until some more bandwidth is available. Set a flag here so the upper layer can
|
||||
// do ths.
|
||||
dumpContext.vcBusyDuringDump = true;
|
||||
dumpContext.ptmeBusyCounter++;
|
||||
if (dumpContext.ptmeBusyCounter == 100) {
|
||||
// If this happens, something is probably wrong.
|
||||
sif::warning << "PTME busy for longer period. Cancelling dump" << std::endl;
|
||||
cancelDump(dumpContext, store, channel.isTxOn());
|
||||
}
|
||||
}
|
||||
if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) {
|
||||
cancelDump(dumpContext, store, channel.isTxOn());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
|
||||
DumpContext& dumpContext, bool& dumpPerformed) {
|
||||
size_t dumpedLen = 0;
|
||||
|
||||
auto dumpDoneHandler = [&]() {
|
||||
uint32_t startTime;
|
||||
uint32_t endTime;
|
||||
store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime);
|
||||
triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets,
|
||||
dumpContext.dumpedBytes);
|
||||
dumpContext.reset();
|
||||
};
|
||||
// Dump the next packet into the PTME.
|
||||
dumpContext.ptmeBusyCounter = 0;
|
||||
tmSinkBusyCd.resetTimer();
|
||||
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
||||
} else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) {
|
||||
// This can happen if a file is corrupted and the next file swap completes the dump.
|
||||
dumpDoneHandler();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
dumpedLen = tmReader.getFullPacketLen();
|
||||
// Only write to VC if mode is on, but always confirm the dump.
|
||||
// If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written
|
||||
// (e.g. to confirm a reset or the transmitter is off anyway).
|
||||
if (mode == MODE_ON) {
|
||||
result = channel.write(tmReader.getFullData(), dumpedLen);
|
||||
if (result == DirectTmSinkIF::IS_BUSY) {
|
||||
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
|
||||
} else if (result != returnvalue::OK) {
|
||||
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;
|
||||
}
|
||||
}
|
||||
result = store.confirmDump(tmReader, fileHasSwapped);
|
||||
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
|
||||
dumpPerformed = true;
|
||||
if (dumpedLen > 0) {
|
||||
dumpContext.dumpedBytes += dumpedLen;
|
||||
dumpContext.numberOfDumpedPackets += 1;
|
||||
dumpContext.packetWasDumped = true;
|
||||
}
|
||||
}
|
||||
if (result == PersistentTmStore::DUMP_DONE) {
|
||||
dumpDoneHandler();
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TmStoreTaskBase::initialize() {
|
||||
modeHelper.initialize();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void TmStoreTaskBase::getMode(Mode_t* mode, Submode_t* submode) {
|
||||
if (mode != nullptr) {
|
||||
*mode = this->mode;
|
||||
}
|
||||
if (submode != nullptr) {
|
||||
*submode = SUBMODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TmStoreTaskBase::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
if (mode == MODE_ON or mode == MODE_OFF) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
MessageQueueId_t TmStoreTaskBase::getCommandQueue() const { return requestQueue->getId(); }
|
||||
|
||||
void TmStoreTaskBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); }
|
||||
|
||||
object_id_t TmStoreTaskBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
const HasHealthIF* TmStoreTaskBase::getOptHealthIF() const { return nullptr; }
|
||||
|
||||
const HasModesIF& TmStoreTaskBase::getModeIF() const { return *this; }
|
||||
|
||||
ReturnValue_t TmStoreTaskBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
|
||||
}
|
||||
|
||||
ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; }
|
||||
|
||||
void TmStoreTaskBase::readCommandQueue(void) {
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = returnvalue::FAILED;
|
||||
|
||||
result = requestQueue->receiveMessage(&commandMessage);
|
||||
if (result == returnvalue::OK) {
|
||||
result = modeHelper.handleModeCommand(&commandMessage);
|
||||
if (result == returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
CommandMessage reply;
|
||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
|
||||
requestQueue->reply(&reply);
|
||||
return;
|
||||
}
|
||||
}
|
106
mission/com/TmStoreTaskBase.h
Normal file
106
mission/com/TmStoreTaskBase.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
|
||||
#define MISSION_TMTC_TMSTORETASKBASE_H_
|
||||
|
||||
#include <fsfw/modes/HasModesIF.h>
|
||||
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
||||
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
||||
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <mission/com/VirtualChannel.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
|
||||
/**
|
||||
* Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping
|
||||
* the TM store into the virtual channel directly.
|
||||
*/
|
||||
class TmStoreTaskBase : public SystemObject,
|
||||
public HasModesIF,
|
||||
public ModeTreeChildIF,
|
||||
public ModeTreeConnectionIF {
|
||||
public:
|
||||
struct DumpContext {
|
||||
DumpContext(Event eventIfDone, Event eventIfCancelled)
|
||||
: eventIfDone(eventIfDone), eventIfCancelled(eventIfCancelled) {}
|
||||
void reset() {
|
||||
numberOfDumpedPackets = 0;
|
||||
dumpedBytes = 0;
|
||||
vcBusyDuringDump = false;
|
||||
packetWasDumped = false;
|
||||
bytesDumpedAtLastDelay = 0;
|
||||
ptmeBusyCounter = 0;
|
||||
}
|
||||
const Event eventIfDone;
|
||||
const Event eventIfCancelled;
|
||||
size_t numberOfDumpedPackets = 0;
|
||||
size_t bytesDumpedAtLastDelay = 0;
|
||||
size_t dumpedBytes = 0;
|
||||
uint32_t ptmeBusyCounter = 0;
|
||||
bool packetWasDumped = false;
|
||||
bool vcBusyDuringDump = false;
|
||||
};
|
||||
|
||||
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
|
||||
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
||||
|
||||
protected:
|
||||
ModeHelper modeHelper;
|
||||
MessageQueueIF* requestQueue;
|
||||
StorageManagerIF& ipcStore;
|
||||
PusTmReader tmReader;
|
||||
CdsShortTimeStamper timeReader;
|
||||
VirtualChannel& channel;
|
||||
SdCardMountedIF& sdcMan;
|
||||
const std::atomic_bool& ptmeLocked;
|
||||
|
||||
Mode_t mode = HasModesIF::MODE_OFF;
|
||||
Countdown sdCardCheckCd = Countdown(800);
|
||||
// 20 minutes are allowed as maximum dump time.
|
||||
Countdown cancelDumpCd = Countdown(60 * 20 * 1000);
|
||||
// If the TM sink is busy for 1 minute for whatever reason, cancel the dump.
|
||||
Countdown tmSinkBusyCd = Countdown(60 * 1000);
|
||||
|
||||
bool storesInitialized = false;
|
||||
bool fileHasSwapped = false;
|
||||
|
||||
void readCommandQueue(void);
|
||||
|
||||
virtual bool initStoresIfPossible() = 0;
|
||||
virtual void startTransition(Mode_t mode, Submode_t submode) = 0;
|
||||
|
||||
void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn);
|
||||
/**
|
||||
*
|
||||
* Handling for one store. Returns if anything was done.
|
||||
* @param store
|
||||
* @return
|
||||
*/
|
||||
bool handleOneStore(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext);
|
||||
|
||||
ReturnValue_t handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext,
|
||||
bool& dumpPerformed);
|
||||
ReturnValue_t performDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext,
|
||||
bool& dumpPerformed);
|
||||
|
||||
/**
|
||||
* Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to
|
||||
* be used again and re-initialize stores. Returns whether store is okay to be used.
|
||||
*/
|
||||
bool cyclicStoreCheck();
|
||||
|
||||
MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
void getMode(Mode_t* mode, Submode_t* submode) override;
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
void announceMode(bool recursive) override;
|
||||
object_id_t getObjectId() const override;
|
||||
const HasHealthIF* getOptHealthIF() const override;
|
||||
const HasModesIF& getModeIF() const override;
|
||||
ModeTreeChildIF& getModeTreeChildIF() override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */
|
@ -1,12 +1,8 @@
|
||||
#include "VirtualChannel.h"
|
||||
|
||||
VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
|
||||
const std::atomic_bool& linkStateProvider)
|
||||
: SystemObject(objectId),
|
||||
ptme(ptme),
|
||||
vcId(vcId),
|
||||
vcName(vcName),
|
||||
linkStateProvider(linkStateProvider) {}
|
||||
const std::atomic_bool& txOn)
|
||||
: SystemObject(objectId), ptme(ptme), vcId(vcId), vcName(vcName), txOn(txOn) {}
|
||||
|
||||
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
|
||||
|
||||
@ -15,7 +11,7 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) {
|
||||
}
|
||||
|
||||
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
|
||||
if (linkStateProvider.load()) {
|
||||
if (txOn) {
|
||||
return ptme.writeToVc(vcId, data, size);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -27,10 +23,12 @@ const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
||||
|
||||
bool VirtualChannel::isBusy() const {
|
||||
// Data is discarded, so channel is not busy.
|
||||
if (linkStateProvider.load()) {
|
||||
if (not txOn) {
|
||||
return false;
|
||||
}
|
||||
return ptme.isBusy(vcId);
|
||||
}
|
||||
|
||||
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
|
||||
|
||||
bool VirtualChannel::isTxOn() const { return txOn; }
|
@ -30,6 +30,7 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
|
||||
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
||||
void cancelTransfer() override;
|
||||
uint8_t getVcid() const;
|
||||
bool isTxOn() const;
|
||||
|
||||
const char* getName() const;
|
||||
|
||||
@ -37,5 +38,5 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
|
||||
PtmeIF& ptme;
|
||||
uint8_t vcId = 0;
|
||||
std::string vcName;
|
||||
const std::atomic_bool& linkStateProvider;
|
||||
const std::atomic_bool& txOn;
|
||||
};
|
@ -1,11 +1,11 @@
|
||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
||||
#include "VirtualChannelWithQueue.h"
|
||||
|
||||
#include "CcsdsIpCoreHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
#include "mission/com/CcsdsIpCoreHandler.h"
|
||||
|
||||
VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t vcId,
|
||||
const char* vcName, PtmeIF& ptme,
|
||||
@ -19,7 +19,7 @@ VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t v
|
||||
|
||||
const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); }
|
||||
|
||||
ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
||||
ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
|
||||
TmTcMessage message;
|
||||
ReturnValue_t result = tmQueue->receiveMessage(&message);
|
||||
if (result == MessageQueueIF::EMPTY) {
|
||||
@ -36,15 +36,13 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = write(data, size);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
if (performWriteOp) {
|
||||
result = write(data, size);
|
||||
}
|
||||
// Try delete in any case, ignore failures (which should not happen), it is more important to
|
||||
// propagate write errors.
|
||||
tmStore.deleteData(storeId);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t VirtualChannelWithQueue::getReportReceptionQueue(uint8_t virtualChannel) const {
|
@ -4,7 +4,7 @@
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <linux/ipcore/PtmeIF.h>
|
||||
#include <mission/tmtc/VirtualChannel.h>
|
||||
#include <mission/com/VirtualChannel.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
@ -34,7 +34,7 @@ class VirtualChannelWithQueue : public VirtualChannel, public AcceptsTelemetryIF
|
||||
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
||||
[[nodiscard]] const char* getName() const override;
|
||||
ReturnValue_t sendNextTm();
|
||||
ReturnValue_t handleNextTm(bool performWriteOp);
|
||||
|
||||
private:
|
||||
MessageQueueIF* tmQueue = nullptr;
|
@ -1,6 +1,8 @@
|
||||
#ifndef MISSION_COMDEFS_H_
|
||||
#define MISSION_COMDEFS_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace com {
|
||||
|
||||
enum class Datarate : uint8_t {
|
@ -3,6 +3,8 @@
|
||||
#include <fsfw/ipc/MutexFactory.h>
|
||||
#include <fsfw/ipc/MutexGuard.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK;
|
||||
MutexIF* DATARATE_LOCK = nullptr;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <fsfw/ipc/MutexIF.h>
|
||||
|
||||
#include "mission/comDefs.h"
|
||||
#include "mission/com/defs.h"
|
||||
|
||||
namespace com {
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include "AcsController.h"
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <mission/acsDefs.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/config/torquer.h>
|
||||
|
||||
AcsController::AcsController(object_id_t objectId)
|
||||
AcsController::AcsController(object_id_t objectId, bool enableHkSets)
|
||||
: ExtendedControllerBase(objectId),
|
||||
enableHkSets(enableHkSets),
|
||||
guidance(&acsParameters),
|
||||
safeCtrl(&acsParameters),
|
||||
ptgCtrl(&acsParameters),
|
||||
@ -591,7 +592,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 10.0});
|
||||
// MGM Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc);
|
||||
@ -601,7 +602,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf);
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 10.0});
|
||||
// SUS Raw
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw);
|
||||
@ -615,7 +616,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw);
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 10.0});
|
||||
// SUS Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc);
|
||||
@ -632,43 +633,43 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk);
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 10.0});
|
||||
// GYR Raw
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw);
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 5.0});
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 10.0});
|
||||
// GYR Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot);
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), false, 5.0});
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 10.0});
|
||||
// GPS Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
|
||||
// MEKF
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), false, 5.0});
|
||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
|
||||
// Ctrl Values
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
|
||||
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 10.0});
|
||||
// Actuator CMD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole);
|
||||
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 10.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,10 @@
|
||||
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/rwHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/susMax1227Helpers.h>
|
||||
#include <mission/trace.h>
|
||||
#include <mission/acs/imtqHelpers.h>
|
||||
#include <mission/acs/rwHelpers.h>
|
||||
#include <mission/acs/susMax1227Helpers.h>
|
||||
#include <mission/utility/trace.h>
|
||||
|
||||
#include "acs/ActuatorCmd.h"
|
||||
#include "acs/Guidance.h"
|
||||
@ -28,7 +28,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
public:
|
||||
static constexpr dur_millis_t INIT_DELAY = 500;
|
||||
|
||||
AcsController(object_id_t objectId);
|
||||
AcsController(object_id_t objectId, bool enableHkSets);
|
||||
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
@ -46,6 +46,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
static constexpr double RW_OFF_TORQUE[4] = {0.0, 0.0, 0.0, 0.0};
|
||||
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
|
||||
|
||||
bool enableHkSets = false;
|
||||
|
||||
AcsParameters acsParameters;
|
||||
SensorProcessing sensorProcessing;
|
||||
Navigation navigation;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,24 +7,23 @@
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/mgmLis3Helpers.h>
|
||||
#include <linux/devices/devicedefinitions/StarTrackerDefinitions.h>
|
||||
#include <mission/controller/controllerdefinitions/ThermalControllerDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/BpxBatteryDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
|
||||
#include <mission/devices/devicedefinitions/SyrlinksDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/Tmp1075Definitions.h>
|
||||
#include <mission/devices/devicedefinitions/gyroAdisHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/payloadPcduDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/rwHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/susMax1227Helpers.h>
|
||||
#include <mission/acs/gyroAdisHelpers.h>
|
||||
#include <mission/acs/imtqHelpers.h>
|
||||
#include <mission/acs/rwHelpers.h>
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
#include <mission/acs/susMax1227Helpers.h>
|
||||
#include <mission/com/syrlinksDefs.h>
|
||||
#include <mission/controller/tcsDefs.h>
|
||||
#include <mission/payload/payloadPcduDefinitions.h>
|
||||
#include <mission/power/bpxBattDefs.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
#include <mission/tcs/HeaterHandler.h>
|
||||
#include <mission/tcs/Max31865Definitions.h>
|
||||
#include <mission/tcs/Tmp1075Definitions.h>
|
||||
#include <mission/utility/trace.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "mission/devices/HeaterHandler.h"
|
||||
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
|
||||
#include "mission/trace.h"
|
||||
|
||||
/**
|
||||
* NOP Limit: Hard limit for device, usually from datasheet. Device damage is possible lif NOP limit
|
||||
* is exceeded.
|
||||
@ -46,17 +45,73 @@ struct TempLimits {
|
||||
float nopUpperLimit;
|
||||
};
|
||||
|
||||
struct ThermalState {
|
||||
uint8_t errorCounter;
|
||||
bool heating;
|
||||
uint32_t heaterStartTime;
|
||||
};
|
||||
|
||||
struct HeaterState {
|
||||
bool switchTransition;
|
||||
HeaterHandler::SwitchState target;
|
||||
uint8_t heaterSwitchControlCycles;
|
||||
};
|
||||
|
||||
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
|
||||
|
||||
enum ThermalComponents : uint8_t {
|
||||
NONE = 0,
|
||||
ACS_BOARD = 1,
|
||||
MGT = 2,
|
||||
RW = 3,
|
||||
STR = 4,
|
||||
IF_BOARD = 5,
|
||||
TCS_BOARD = 6,
|
||||
OBC = 7,
|
||||
OBCIF_BOARD = 8,
|
||||
SBAND_TRANSCEIVER = 9,
|
||||
PCDUP60_BOARD = 10,
|
||||
PCDUACU = 11,
|
||||
PCDUPDU = 12,
|
||||
PLPCDU_BOARD = 13,
|
||||
PLOCMISSION_BOARD = 14,
|
||||
PLOCPROCESSING_BOARD = 15,
|
||||
DAC = 16,
|
||||
CAMERA = 17,
|
||||
DRO = 18,
|
||||
X8 = 19,
|
||||
HPA = 20,
|
||||
TX = 21,
|
||||
MPA = 22,
|
||||
SCEX_BOARD = 23,
|
||||
NUM_ENTRIES
|
||||
};
|
||||
|
||||
class ThermalController : public ExtendedControllerBase {
|
||||
public:
|
||||
static const uint16_t INVALID_TEMPERATURE = 999;
|
||||
static const uint8_t NUMBER_OF_SENSORS = 16;
|
||||
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
|
||||
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
|
||||
|
||||
ThermalController(object_id_t objectId, HeaterHandler& heater);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
void performThermalModuleCtrl();
|
||||
struct HeaterContext {
|
||||
public:
|
||||
HeaterContext(heater::Switchers switchNr, heater::Switchers redundantSwitchNr,
|
||||
const TempLimits& tempLimit)
|
||||
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
|
||||
bool doHeaterHandling = true;
|
||||
heater::Switchers switchNr;
|
||||
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
|
||||
heater::Switchers redSwitchNr;
|
||||
const TempLimits& tempLimit;
|
||||
};
|
||||
|
||||
void performThermalModuleCtrl(const HeaterSwitchStates& heaterSwitchStates);
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
void performControlOperation() override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
@ -68,16 +123,7 @@ class ThermalController : public ExtendedControllerBase {
|
||||
uint32_t* msToReachTheMode) override;
|
||||
|
||||
private:
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_CONTROLLER;
|
||||
static constexpr Event NO_VALID_SENSOR_TEMPERATURE = MAKE_EVENT(0, severity::MEDIUM);
|
||||
static constexpr Event NO_HEALTHY_HEATER_AVAILABLE = MAKE_EVENT(1, severity::MEDIUM);
|
||||
static constexpr Event SYRLINKS_OVERHEATING = MAKE_EVENT(2, severity::HIGH);
|
||||
static constexpr Event PLOC_OVERHEATING = MAKE_EVENT(3, severity::HIGH);
|
||||
static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
|
||||
static constexpr Event HPA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
|
||||
static constexpr Event PLPCDU_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
|
||||
|
||||
static const uint32_t DELAY = 500;
|
||||
static const uint32_t INIT_DELAY = 1500;
|
||||
|
||||
static const uint32_t TEMP_OFFSET = 5;
|
||||
|
||||
@ -97,22 +143,22 @@ class ThermalController : public ExtendedControllerBase {
|
||||
DeviceHandlerThermalSet imtqThermalSet;
|
||||
|
||||
// Temperature Sensors
|
||||
MAX31865::PrimarySet max31865Set0;
|
||||
MAX31865::PrimarySet max31865Set1;
|
||||
MAX31865::PrimarySet max31865Set2;
|
||||
MAX31865::PrimarySet max31865Set3;
|
||||
MAX31865::PrimarySet max31865Set4;
|
||||
MAX31865::PrimarySet max31865Set5;
|
||||
MAX31865::PrimarySet max31865Set6;
|
||||
MAX31865::PrimarySet max31865Set7;
|
||||
MAX31865::PrimarySet max31865Set8;
|
||||
MAX31865::PrimarySet max31865Set9;
|
||||
MAX31865::PrimarySet max31865Set10;
|
||||
MAX31865::PrimarySet max31865Set11;
|
||||
MAX31865::PrimarySet max31865Set12;
|
||||
MAX31865::PrimarySet max31865Set13;
|
||||
MAX31865::PrimarySet max31865Set14;
|
||||
MAX31865::PrimarySet max31865Set15;
|
||||
MAX31865::PrimarySet maxSet0PlocHspd;
|
||||
MAX31865::PrimarySet maxSet1PlocMissionBrd;
|
||||
MAX31865::PrimarySet maxSet2PlCam;
|
||||
MAX31865::PrimarySet maxSet3DacHspd;
|
||||
MAX31865::PrimarySet maxSet4Str;
|
||||
MAX31865::PrimarySet maxSet5Rw1MxMy;
|
||||
MAX31865::PrimarySet maxSet6Dro;
|
||||
MAX31865::PrimarySet maxSet7Scex;
|
||||
MAX31865::PrimarySet maxSet8X8;
|
||||
MAX31865::PrimarySet maxSet9Hpa;
|
||||
MAX31865::PrimarySet maxSet10EbandTx;
|
||||
MAX31865::PrimarySet maxSet11Mpa;
|
||||
MAX31865::PrimarySet maxSet31865Set12;
|
||||
MAX31865::PrimarySet maxSet13PlPcduHspd;
|
||||
MAX31865::PrimarySet maxSet14TcsBrd;
|
||||
MAX31865::PrimarySet maxSet15Imtq;
|
||||
|
||||
TMP1075::Tmp1075Dataset tmp1075SetTcs0;
|
||||
TMP1075::Tmp1075Dataset tmp1075SetTcs1;
|
||||
@ -192,18 +238,38 @@ class ThermalController : public ExtendedControllerBase {
|
||||
TempLimits dacLimits = TempLimits(-65.0, -40.0, 113.0, 118.0, 150.0);
|
||||
TempLimits cameraLimits = TempLimits(-40.0, -30.0, 60.0, 65.0, 85.0);
|
||||
TempLimits droLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
|
||||
TempLimits x8Limits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
|
||||
TempLimits hpaLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
|
||||
TempLimits txLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
|
||||
TempLimits mpaLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0);
|
||||
TempLimits x8Limits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
|
||||
TempLimits hpaLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
|
||||
TempLimits txLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
|
||||
TempLimits mpaLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
|
||||
TempLimits scexBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0);
|
||||
|
||||
double sensorTemp = INVALID_TEMPERATURE;
|
||||
ThermalComponents thermalComponent = NONE;
|
||||
bool redSwitchNrInUse = false;
|
||||
MessageQueueId_t camId = MessageQueueIF::NO_QUEUE;
|
||||
bool componentAboveCutOffLimit = false;
|
||||
bool componentAboveUpperLimit = false;
|
||||
Event overHeatEventToTrigger;
|
||||
bool eBandTooHotFlag = false;
|
||||
bool camTooHotOneShotFlag = false;
|
||||
bool scexTooHotFlag = false;
|
||||
bool plocTooHotFlag = false;
|
||||
bool pcduSystemTooHotFlag = false;
|
||||
bool syrlinksTooHotFlag = false;
|
||||
bool obcTooHotFlag = false;
|
||||
bool strTooHotFlag = false;
|
||||
bool rwTooHotFlag = false;
|
||||
|
||||
// Initial delay to make sure all pool variables have been initialized their owners
|
||||
Countdown initialCountdown = Countdown(DELAY);
|
||||
bool transitionToOff = false;
|
||||
uint32_t transitionToOffCycles = 0;
|
||||
uint32_t cycles = 0;
|
||||
std::array<ThermalState, 30> thermalStates{};
|
||||
std::array<HeaterState, 7> heaterStates{};
|
||||
|
||||
// Initial delay to make sure all pool variables have been initialized their owners.
|
||||
// Also, wait for system initialization to complete.
|
||||
Countdown initialCountdown = Countdown(INIT_DELAY);
|
||||
|
||||
#if OBSW_THREAD_TRACING == 1
|
||||
uint32_t opCounter = 0;
|
||||
@ -222,16 +288,20 @@ class ThermalController : public ExtendedControllerBase {
|
||||
|
||||
static constexpr dur_millis_t MUTEX_TIMEOUT = 50;
|
||||
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
|
||||
void resetSensorsArray();
|
||||
void copySensors();
|
||||
void copySus();
|
||||
void copyDevices();
|
||||
|
||||
void ctrlComponentTemperature(heater::Switchers switchNr, heater::Switchers redSwitchNr,
|
||||
TempLimits& tempLimit);
|
||||
void ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr, TempLimits& tempLimit);
|
||||
void ctrlComponentTemperature(HeaterContext& heaterContext);
|
||||
void checkLimitsAndCtrlHeater(HeaterContext& heaterContext);
|
||||
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
|
||||
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
|
||||
|
||||
bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr);
|
||||
bool selectAndReadSensorTemp();
|
||||
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
|
||||
|
||||
void ctrlAcsBoard();
|
||||
void ctrlMgt();
|
||||
@ -256,6 +326,11 @@ class ThermalController : public ExtendedControllerBase {
|
||||
void ctrlTx();
|
||||
void ctrlMpa();
|
||||
void ctrlScexBoard();
|
||||
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
||||
void setMode(Mode_t mode);
|
||||
uint32_t tempFloatToU32() const;
|
||||
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
|
||||
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);
|
||||
};
|
||||
|
||||
#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
|
||||
#include <linux/devices/devicedefinitions/StarTrackerDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/GPSDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/GyroL3GD20Definitions.h>
|
||||
#include <mission/devices/devicedefinitions/gyroAdisHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/rwHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/susMax1227Helpers.h>
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
||||
#include <mission/acs/archive/GPSDefinitions.h>
|
||||
#include <mission/acs/gyroAdisHelpers.h>
|
||||
#include <mission/acs/imtqHelpers.h>
|
||||
#include <mission/acs/rwHelpers.h>
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
#include <mission/acs/susMax1227Helpers.h>
|
||||
|
||||
namespace ACS {
|
||||
|
||||
|
@ -5,9 +5,19 @@
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
|
||||
#include "devices/heaterSwitcherList.h"
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
|
||||
namespace tcsCtrl {
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_CONTROLLER;
|
||||
static constexpr Event NO_VALID_SENSOR_TEMPERATURE = MAKE_EVENT(0, severity::MEDIUM);
|
||||
static constexpr Event NO_HEALTHY_HEATER_AVAILABLE = MAKE_EVENT(1, severity::MEDIUM);
|
||||
static constexpr Event SYRLINKS_OVERHEATING = MAKE_EVENT(2, severity::HIGH);
|
||||
static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
|
||||
static constexpr Event CAMERA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
|
||||
static constexpr Event PCDU_SYSTEM_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
|
||||
static constexpr Event HEATER_NOT_OFF_FOR_OFF_MODE = MAKE_EVENT(7, severity::MEDIUM);
|
||||
|
||||
enum SetId : uint32_t {
|
||||
SENSOR_TEMPERATURES = 0,
|
||||
DEVICE_TEMPERATURES = 1,
|
||||
@ -93,34 +103,33 @@ static const uint8_t ENTRIES_SUS_TEMPERATURE_SET = 12;
|
||||
*/
|
||||
class SensorTemperatures : public StaticLocalDataSet<ENTRIES_SENSOR_TEMPERATURE_SET> {
|
||||
public:
|
||||
SensorTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SENSOR_TEMPERATURES) {}
|
||||
explicit SensorTemperatures(HasLocalDataPoolIF* owner)
|
||||
: StaticLocalDataSet(owner, SENSOR_TEMPERATURES) {}
|
||||
|
||||
SensorTemperatures(object_id_t objectId)
|
||||
explicit SensorTemperatures(object_id_t objectId)
|
||||
: StaticLocalDataSet(sid_t(objectId, SENSOR_TEMPERATURES)) {}
|
||||
|
||||
lp_var_t<float> sensor_ploc_heatspreader =
|
||||
lp_var_t<float> plocHeatspreader =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLOC_HEATSPREADER, this);
|
||||
lp_var_t<float> sensor_ploc_missionboard =
|
||||
lp_var_t<float> plocMissionboard =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLOC_MISSIONBOARD, this);
|
||||
lp_var_t<float> sensor_4k_camera = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_4K_CAMERA, this);
|
||||
lp_var_t<float> sensor_dac_heatspreader =
|
||||
lp_var_t<float> payload4kCamera = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_4K_CAMERA, this);
|
||||
lp_var_t<float> dacHeatspreader =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DAC_HEATSPREADER, this);
|
||||
lp_var_t<float> sensor_startracker =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_STARTRACKER, this);
|
||||
lp_var_t<float> sensor_rw1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_RW1, this);
|
||||
lp_var_t<float> sensor_scex = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_SCEX, this);
|
||||
lp_var_t<float> sensor_tx_modul = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
|
||||
lp_var_t<float> startracker = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_STARTRACKER, this);
|
||||
lp_var_t<float> rw1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_RW1, this);
|
||||
lp_var_t<float> scex = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_SCEX, this);
|
||||
lp_var_t<float> eBandTx = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
|
||||
// E-Band module
|
||||
lp_var_t<float> sensor_dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
|
||||
lp_var_t<float> sensor_mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
|
||||
lp_var_t<float> sensor_x8 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_X8, this);
|
||||
lp_var_t<float> sensor_hpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_HPA, this);
|
||||
lp_var_t<float> sensor_acu = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_ACU, this);
|
||||
lp_var_t<float> sensor_plpcdu_heatspreader =
|
||||
lp_var_t<float> dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
|
||||
lp_var_t<float> mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
|
||||
lp_var_t<float> x8 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_X8, this);
|
||||
lp_var_t<float> hpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_HPA, this);
|
||||
lp_var_t<float> acu = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_ACU, this);
|
||||
lp_var_t<float> plpcduHeatspreader =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLPCDU_HEATSPREADER, this);
|
||||
lp_var_t<float> sensor_tcs_board = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TCS_BOARD, this);
|
||||
lp_var_t<float> sensor_magnettorquer =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MAGNETTORQUER, this);
|
||||
lp_var_t<float> tcsBoard = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TCS_BOARD, this);
|
||||
lp_var_t<float> mgt = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MAGNETTORQUER, this);
|
||||
lp_var_t<float> tmp1075Tcs0 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_TCS_0, this);
|
||||
lp_var_t<float> tmp1075Tcs1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_TCS_1, this);
|
||||
lp_var_t<float> tmp1075PlPcdu0 =
|
||||
@ -137,9 +146,10 @@ class SensorTemperatures : public StaticLocalDataSet<ENTRIES_SENSOR_TEMPERATURE_
|
||||
*/
|
||||
class DeviceTemperatures : public StaticLocalDataSet<ENTRIES_DEVICE_TEMPERATURE_SET> {
|
||||
public:
|
||||
DeviceTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, DEVICE_TEMPERATURES) {}
|
||||
explicit DeviceTemperatures(HasLocalDataPoolIF* owner)
|
||||
: StaticLocalDataSet(owner, DEVICE_TEMPERATURES) {}
|
||||
|
||||
DeviceTemperatures(object_id_t objectId)
|
||||
explicit DeviceTemperatures(object_id_t objectId)
|
||||
: StaticLocalDataSet(sid_t(objectId, DEVICE_TEMPERATURES)) {}
|
||||
|
||||
lp_var_t<float> q7s = lp_var_t<float>(sid.objectId, PoolIds::TEMP_Q7S, this);
|
||||
@ -178,9 +188,11 @@ class DeviceTemperatures : public StaticLocalDataSet<ENTRIES_DEVICE_TEMPERATURE_
|
||||
*/
|
||||
class SusTemperatures : public StaticLocalDataSet<ENTRIES_SUS_TEMPERATURE_SET> {
|
||||
public:
|
||||
SusTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SUS_TEMPERATURES) {}
|
||||
explicit SusTemperatures(HasLocalDataPoolIF* owner)
|
||||
: StaticLocalDataSet(owner, SUS_TEMPERATURES) {}
|
||||
|
||||
SusTemperatures(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, SUS_TEMPERATURES)) {}
|
||||
explicit SusTemperatures(object_id_t objectId)
|
||||
: StaticLocalDataSet(sid_t(objectId, SUS_TEMPERATURES)) {}
|
||||
|
||||
lp_var_t<float> sus_0_n_loc_xfyfzm_pt_xf =
|
||||
lp_var_t<float>(sid.objectId, PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, this);
|
@ -1,2 +0,0 @@
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp scheduling.cpp
|
||||
pollingSeqTables.cpp)
|
@ -1 +0,0 @@
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE CspCookie.cpp)
|
@ -1,28 +0,0 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE GomspaceDeviceHandler.cpp
|
||||
BpxBatteryHandler.cpp
|
||||
Tmp1075Handler.cpp
|
||||
PcduHandler.cpp
|
||||
P60DockHandler.cpp
|
||||
Pdu1Handler.cpp
|
||||
Pdu2Handler.cpp
|
||||
ACUHandler.cpp
|
||||
SyrlinksHandler.cpp
|
||||
Max31865PT1000Handler.cpp
|
||||
Max31865EiveHandler.cpp
|
||||
ImtqHandler.cpp
|
||||
HeaterHandler.cpp
|
||||
RadiationSensorHandler.cpp
|
||||
GyrAdis1650XHandler.cpp
|
||||
GyrL3gCustomHandler.cpp
|
||||
MgmRm3100CustomHandler.cpp
|
||||
MgmLis3CustomHandler.cpp
|
||||
RwHandler.cpp
|
||||
max1227.cpp
|
||||
SusHandler.cpp
|
||||
PayloadPcduHandler.cpp
|
||||
SolarArrayDeploymentHandler.cpp
|
||||
ScexDeviceHandler.cpp)
|
||||
|
||||
add_subdirectory(devicedefinitions)
|
@ -1,2 +0,0 @@
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE ScexDefinitions.cpp rwHelpers.cpp
|
||||
imtqHelpers.cpp gyroAdisHelpers.cpp)
|
@ -1,130 +0,0 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_
|
||||
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace l3gd20h {
|
||||
|
||||
/* Actual size is 15 but we round up a bit */
|
||||
static constexpr size_t MAX_BUFFER_SIZE = 16;
|
||||
|
||||
static constexpr uint8_t READ_MASK = 0b1000'0000;
|
||||
|
||||
static constexpr uint8_t AUTO_INCREMENT_MASK = 0b0100'0000;
|
||||
|
||||
static constexpr uint8_t WHO_AM_I_REG = 0b0000'1111;
|
||||
static constexpr uint8_t WHO_AM_I_VAL = 0b1101'0111;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Control registers */
|
||||
/*------------------------------------------------------------------------*/
|
||||
static constexpr uint8_t CTRL_REG_1 = 0b0010'0000;
|
||||
static constexpr uint8_t CTRL_REG_2 = 0b0010'0001;
|
||||
static constexpr uint8_t CTRL_REG_3 = 0b0010'0010;
|
||||
static constexpr uint8_t CTRL_REG_4 = 0b0010'0011;
|
||||
static constexpr uint8_t CTRL_REG_5 = 0b0010'0100;
|
||||
|
||||
/* Register 1 */
|
||||
static constexpr uint8_t SET_DR_1 = 1 << 7;
|
||||
static constexpr uint8_t SET_DR_0 = 1 << 6;
|
||||
static constexpr uint8_t SET_BW_1 = 1 << 5;
|
||||
static constexpr uint8_t SET_BW_0 = 1 << 4;
|
||||
static constexpr uint8_t SET_POWER_NORMAL_MODE = 1 << 3;
|
||||
static constexpr uint8_t SET_Z_ENABLE = 1 << 2;
|
||||
static constexpr uint8_t SET_X_ENABLE = 1 << 1;
|
||||
static constexpr uint8_t SET_Y_ENABLE = 1;
|
||||
|
||||
static constexpr uint8_t CTRL_REG_1_VAL =
|
||||
SET_POWER_NORMAL_MODE | SET_Z_ENABLE | SET_Y_ENABLE | SET_X_ENABLE;
|
||||
|
||||
/* Register 2 */
|
||||
static constexpr uint8_t EXTERNAL_EDGE_ENB = 1 << 7;
|
||||
static constexpr uint8_t LEVEL_SENSITIVE_TRIGGER = 1 << 6;
|
||||
static constexpr uint8_t SET_HPM_1 = 1 << 5;
|
||||
static constexpr uint8_t SET_HPM_0 = 1 << 4;
|
||||
static constexpr uint8_t SET_HPCF_3 = 1 << 3;
|
||||
static constexpr uint8_t SET_HPCF_2 = 1 << 2;
|
||||
static constexpr uint8_t SET_HPCF_1 = 1 << 1;
|
||||
static constexpr uint8_t SET_HPCF_0 = 1;
|
||||
|
||||
static constexpr uint8_t CTRL_REG_2_VAL = 0b0000'0000;
|
||||
|
||||
/* Register 3 */
|
||||
static constexpr uint8_t CTRL_REG_3_VAL = 0b0000'0000;
|
||||
|
||||
/* Register 4 */
|
||||
static constexpr uint8_t SET_BNU = 1 << 7;
|
||||
static constexpr uint8_t SET_BLE = 1 << 6;
|
||||
static constexpr uint8_t SET_FS_1 = 1 << 5;
|
||||
static constexpr uint8_t SET_FS_0 = 1 << 4;
|
||||
static constexpr uint8_t SET_IMP_ENB = 1 << 3;
|
||||
static constexpr uint8_t SET_SELF_TEST_ENB_1 = 1 << 2;
|
||||
static constexpr uint8_t SET_SELF_TEST_ENB_0 = 1 << 1;
|
||||
static constexpr uint8_t SET_SPI_IF_SELECT = 1;
|
||||
|
||||
/* Enable big endian data format */
|
||||
static constexpr uint8_t CTRL_REG_4_VAL = SET_BLE;
|
||||
|
||||
/* Register 5 */
|
||||
static constexpr uint8_t SET_REBOOT_MEM = 1 << 7;
|
||||
static constexpr uint8_t SET_FIFO_ENB = 1 << 6;
|
||||
|
||||
static constexpr uint8_t CTRL_REG_5_VAL = 0b0000'0000;
|
||||
|
||||
/* Possible range values in degrees per second (DPS). */
|
||||
static constexpr uint16_t RANGE_DPS_00 = 245;
|
||||
static constexpr uint16_t RANGE_DPS_01 = 500;
|
||||
static constexpr uint16_t RANGE_DPS_11 = 2000;
|
||||
|
||||
static constexpr uint8_t READ_START = CTRL_REG_1;
|
||||
static constexpr size_t READ_LEN = 14;
|
||||
|
||||
/* Indexing */
|
||||
static constexpr uint8_t REFERENCE_IDX = 6;
|
||||
static constexpr uint8_t TEMPERATURE_IDX = 7;
|
||||
static constexpr uint8_t STATUS_IDX = 8;
|
||||
static constexpr uint8_t OUT_X_H = 9;
|
||||
static constexpr uint8_t OUT_X_L = 10;
|
||||
static constexpr uint8_t OUT_Y_H = 11;
|
||||
static constexpr uint8_t OUT_Y_L = 12;
|
||||
static constexpr uint8_t OUT_Z_H = 13;
|
||||
static constexpr uint8_t OUT_Z_L = 14;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Device Handler specific */
|
||||
/*------------------------------------------------------------------------*/
|
||||
static constexpr DeviceCommandId_t READ_REGS = 0;
|
||||
static constexpr DeviceCommandId_t CONFIGURE_CTRL_REGS = 1;
|
||||
static constexpr DeviceCommandId_t READ_CTRL_REGS = 2;
|
||||
|
||||
static constexpr uint32_t GYRO_DATASET_ID = READ_REGS;
|
||||
|
||||
enum GyroPoolIds : lp_id_t { ANG_VELOC_X, ANG_VELOC_Y, ANG_VELOC_Z, TEMPERATURE };
|
||||
|
||||
} // namespace l3gd20h
|
||||
|
||||
class GyroPrimaryDataset : public StaticLocalDataSet<5> {
|
||||
public:
|
||||
/** Constructor for data users like controllers */
|
||||
GyroPrimaryDataset(object_id_t mgmId)
|
||||
: StaticLocalDataSet(sid_t(mgmId, l3gd20h::GYRO_DATASET_ID)) {
|
||||
setAllVariablesReadOnly();
|
||||
}
|
||||
|
||||
/* Angular velocities in degrees per second (DPS) */
|
||||
lp_var_t<float> angVelocX = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_X, this);
|
||||
lp_var_t<float> angVelocY = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_Y, this);
|
||||
lp_var_t<float> angVelocZ = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_Z, this);
|
||||
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, l3gd20h::TEMPERATURE, this);
|
||||
|
||||
private:
|
||||
friend class GyroHandlerL3GD20H;
|
||||
/** Constructor for the data creator */
|
||||
GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner)
|
||||
: StaticLocalDataSet(hkOwner, l3gd20h::GYRO_DATASET_ID) {}
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_ */
|
@ -1,23 +0,0 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_
|
||||
|
||||
#include <fsfw/events/Event.h>
|
||||
|
||||
#include "eive/eventSubsystemIds.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 switch 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);
|
||||
|
||||
static constexpr Event FDIR_REACTION_IGNORED = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
||||
|
||||
} // namespace power
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ */
|
@ -1,5 +1,3 @@
|
||||
#include "GenericFactory.h"
|
||||
|
||||
#include <fsfw/cfdp/CfdpDistributor.h>
|
||||
#include <fsfw/cfdp/handler/CfdpHandler.h>
|
||||
#include <fsfw/cfdp/handler/RemoteConfigTableIF.h>
|
||||
@ -26,13 +24,14 @@
|
||||
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
||||
#include <fsfw_hal/host/HostFilesystem.h>
|
||||
#include <mission/controller/ThermalController.h>
|
||||
#include <mission/devices/HeaterHandler.h>
|
||||
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||
#include <mission/genericFactory.h>
|
||||
#include <mission/persistentTmStoreDefs.h>
|
||||
#include <mission/system/objects/AcsBoardAssembly.h>
|
||||
#include <mission/system/objects/RwAssembly.h>
|
||||
#include <mission/system/objects/SusAssembly.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
#include <mission/system/acs/AcsBoardAssembly.h>
|
||||
#include <mission/system/acs/RwAssembly.h>
|
||||
#include <mission/system/acs/SusAssembly.h>
|
||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
||||
#include <mission/tcs/HeaterHandler.h>
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PersistentTmStore.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
@ -46,8 +45,8 @@
|
||||
#include "eive/definitions.h"
|
||||
#include "fsfw/pus/Service11TelecommandScheduling.h"
|
||||
#include "mission/cfdp/Config.h"
|
||||
#include "mission/system/objects/RwAssembly.h"
|
||||
#include "mission/system/tree/acsModeTree.h"
|
||||
#include "mission/system/acs/RwAssembly.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
#include "objects/systemObjectList.h"
|
||||
@ -193,8 +192,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
||||
|
||||
// HK store and PUS funnel to HK store routing
|
||||
{
|
||||
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY,
|
||||
15, *ramToFileStore, sdcMan);
|
||||
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 2,
|
||||
*ramToFileStore, sdcMan);
|
||||
stores.hkStore =
|
||||
new PersistentTmStoreWithTmQueue(storeArgs, "HK STORE", config::HK_STORE_QUEUE_SIZE);
|
||||
(*pusFunnel)
|
||||
@ -235,7 +234,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
||||
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
|
||||
pus::PUS_SERVICE_2, 3, 10);
|
||||
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
|
||||
pus::PUS_SERVICE_3);
|
||||
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH);
|
||||
new Service5EventReporting(
|
||||
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
||||
40, 120);
|
||||
@ -296,7 +295,7 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
|
||||
{new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
|
||||
}});
|
||||
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
|
||||
pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
|
||||
power::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
|
||||
heaterHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||
}
|
||||
|
||||
@ -348,7 +347,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||
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);
|
||||
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER,
|
||||
objects::GPS_0_HEALTH_DEV, objects::GPS_1_HEALTH_DEV);
|
||||
auto acsAss =
|
||||
new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF);
|
||||
for (auto& assChild : assemblyDhbs) {
|
||||
@ -359,13 +359,17 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||
}
|
||||
}
|
||||
gpsCtrl->connectModeTreeParent(*acsAss);
|
||||
auto* gps0HealthDev = new HealthDevice(objects::GPS_0_HEALTH_DEV, acsAss->getCommandQueue());
|
||||
auto* gps1HealthDev = new HealthDevice(objects::GPS_1_HEALTH_DEV, acsAss->getCommandQueue());
|
||||
acsAss->registerChild(objects::GPS_0_HEALTH_DEV, gps0HealthDev->getCommandQueue());
|
||||
acsAss->registerChild(objects::GPS_1_HEALTH_DEV, gps1HealthDev->getCommandQueue());
|
||||
acsAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
}
|
||||
|
||||
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) {
|
||||
TcsBoardHelper helper(RTD_INFOS);
|
||||
auto* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
|
||||
pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
|
||||
power::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
|
||||
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||
return tcsBoardAss;
|
||||
}
|
@ -2,14 +2,15 @@
|
||||
#define MISSION_CORE_GENERICFACTORY_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/devicehandlers/HealthDevice.h>
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
#include <mission/persistentTmStoreDefs.h>
|
||||
#include <mission/tcs/Max31865Definitions.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "fsfw/power/PowerSwitchIF.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||
|
||||
using persTmStore::PersistentTmStores;
|
||||
|
@ -1,17 +0,0 @@
|
||||
# add main and others
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/*.c)
|
||||
|
||||
CSRC += $(wildcard $(CURRENTPATH)/core/*.c)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/core/*.cpp)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/devices/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/devices/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/utility/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/utility/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/test/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/test/*.c)
|
||||
|
||||
|
3
mission/payload/CMakeLists.txt
Normal file
3
mission/payload/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION} PRIVATE PayloadPcduHandler.cpp RadiationSensorHandler.cpp
|
||||
ScexDeviceHandler.cpp scexHelpers.cpp defs.cpp)
|
@ -1,6 +1,5 @@
|
||||
#include "PayloadPcduHandler.h"
|
||||
|
||||
#include <fsfw/src/fsfw/datapool/PoolReadGuard.h>
|
||||
#include <mission/payload/PayloadPcduHandler.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
|
@ -4,15 +4,15 @@
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <mission/payload/payloadPcduDefinitions.h>
|
||||
#include <mission/system/objects/Stack5VHandler.h>
|
||||
|
||||
#include "events/subsystemIdRanges.h"
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "mission/devices/devicedefinitions/payloadPcduDefinitions.h"
|
||||
#include "mission/memory/SdCardMountedIF.h"
|
||||
#include "mission/system/objects/DualLanePowerStateMachine.h"
|
||||
#include "mission/system/objects/definitions.h"
|
||||
#include "mission/power/defs.h"
|
||||
#include "mission/system/DualLanePowerStateMachine.h"
|
||||
|
||||
#ifdef FSFW_OSAL_LINUX
|
||||
class SpiComIF;
|
@ -1,9 +1,9 @@
|
||||
#include <OBSWConfig.h>
|
||||
#include <devices/gpioIds.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <mission/devices/RadiationSensorHandler.h>
|
||||
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||
#include <mission/devices/max1227.h>
|
||||
#include <mission/payload/RadiationSensorHandler.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
#include <mission/tcs/max1227.h>
|
||||
|
||||
RadiationSensorHandler::RadiationSensorHandler(object_id_t objectId, object_id_t comIF,
|
||||
CookieIF *comCookie, GpioIF *gpioIF,
|
@ -1,9 +1,9 @@
|
||||
#ifndef MISSION_DEVICES_RADIATIONSENSORHANDLER_H_
|
||||
#define MISSION_DEVICES_RADIATIONSENSORHANDLER_H_
|
||||
#ifndef MISSION_PAYLOAD_RADIATIONSENSORHANDLER_H_
|
||||
#define MISSION_PAYLOAD_RADIATIONSENSORHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||
#include <mission/devices/devicedefinitions/RadSensorDefinitions.h>
|
||||
#include <mission/payload/radSensorDefinitions.h>
|
||||
#include <mission/system/objects/Stack5VHandler.h>
|
||||
|
||||
/**
|
||||
@ -54,4 +54,4 @@ class RadiationSensorHandler : public DeviceHandlerBase {
|
||||
CommunicationStep communicationStep = CommunicationStep::START_CONVERSION;
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_RADIATIONSENSORHANDLER_H_ */
|
||||
#endif /* MISSION_PAYLOAD_RADIATIONSENSORHANDLER_H_ */
|
@ -1,8 +1,8 @@
|
||||
#include "ScexDeviceHandler.h"
|
||||
|
||||
#include <fsfw/filesystem/HasFileSystemIF.h>
|
||||
#include <linux/devices/ScexHelper.h>
|
||||
#include <linux/payload/ScexHelper.h>
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
#include <mission/payload/ScexDeviceHandler.h>
|
||||
#include <mission/payload/scexHelpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
@ -11,8 +11,8 @@
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include "eive/definitions.h"
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
#include "mission/devices/devicedefinitions/ScexDefinitions.h"
|
||||
|
||||
using std::ofstream;
|
||||
using namespace returnvalue;
|
||||
@ -28,6 +28,7 @@ void ScexDeviceHandler::doStartUp() { setMode(MODE_ON); }
|
||||
void ScexDeviceHandler::doShutDown() {
|
||||
reader.reset();
|
||||
commandActive = false;
|
||||
fileNameSet = false;
|
||||
multiFileFinishOutstanding = false;
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
@ -206,50 +207,13 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
using namespace scex;
|
||||
|
||||
ReturnValue_t status = OK;
|
||||
auto oneFileHandler = [&](std::string cmdName) {
|
||||
auto activeSd = sdcMan.getActiveSdCard();
|
||||
if (not activeSd) {
|
||||
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
||||
}
|
||||
fileId = date_time_string();
|
||||
std::ostringstream oss;
|
||||
auto prefix = sdcMan.getCurrentMountPrefix();
|
||||
if (prefix == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
|
||||
fileName = oss.str();
|
||||
ofstream out(fileName, ofstream::binary);
|
||||
if (out.bad()) {
|
||||
sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName
|
||||
<< std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
out << helper;
|
||||
return OK;
|
||||
};
|
||||
auto multiFileHandler = [&](std::string cmdName) {
|
||||
auto multiFileHandler = [&](const char* cmdName) {
|
||||
if ((helper.getPacketCounter() == 1) or (not fileNameSet)) {
|
||||
auto activeSd = sdcMan.getActiveSdCard();
|
||||
if (not activeSd) {
|
||||
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
||||
status = generateNewScexFile(cmdName);
|
||||
if (status != returnvalue::OK) {
|
||||
return status;
|
||||
}
|
||||
fileId = date_time_string();
|
||||
std::ostringstream oss;
|
||||
auto prefix = sdcMan.getCurrentMountPrefix();
|
||||
if (prefix == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
|
||||
fileName = oss.str();
|
||||
fileNameSet = true;
|
||||
ofstream out(fileName, ofstream::binary);
|
||||
if (out.bad()) {
|
||||
sif::error << "ScexDeviceHandler::handleValidReply: Could not open file " << fileName
|
||||
<< std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
out << helper;
|
||||
} else {
|
||||
ofstream out(fileName,
|
||||
ofstream::binary | ofstream::app); // append
|
||||
@ -265,31 +229,31 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
id = helper.getCmd();
|
||||
switch (id) {
|
||||
case (PING): {
|
||||
status = oneFileHandler("ping_");
|
||||
status = generateNewScexFile(PING_IDLE_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
case (ION_CMD): {
|
||||
status = oneFileHandler("ion_");
|
||||
status = generateNewScexFile(ION_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
case (TEMP_CMD): {
|
||||
status = oneFileHandler("temp_");
|
||||
status = generateNewScexFile(TEMPERATURE_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
case (EXP_STATUS_CMD): {
|
||||
status = oneFileHandler("exp_status_");
|
||||
status = generateNewScexFile(EXP_STATUS_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
case (FRAM): {
|
||||
status = multiFileHandler("fram_");
|
||||
status = multiFileHandler(FRAM_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
case (ONE_CELL): {
|
||||
status = multiFileHandler("one_cell_");
|
||||
status = multiFileHandler(ONE_CELL_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
case (ALL_CELLS_CMD): {
|
||||
status = multiFileHandler("multi_cell_");
|
||||
status = multiFileHandler(ALL_CELLS_BASE_NAME);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -355,37 +319,41 @@ ReturnValue_t ScexDeviceHandler::initializeLocalDataPool(localpool::DataPool& lo
|
||||
return OK;
|
||||
}
|
||||
|
||||
std::string ScexDeviceHandler::date_time_string() {
|
||||
using namespace std;
|
||||
string date_time;
|
||||
Clock::TimeOfDay_t tod;
|
||||
Clock::getDateAndTime(&tod);
|
||||
ostringstream oss(std::ostringstream::ate);
|
||||
|
||||
if (tod.hour < 10) {
|
||||
oss << tod.year << tod.month << tod.day << "_0" << tod.hour;
|
||||
} else {
|
||||
oss << tod.year << tod.month << tod.day << "_" << tod.hour;
|
||||
}
|
||||
if (tod.minute < 10) {
|
||||
oss << 0 << tod.minute;
|
||||
|
||||
} else {
|
||||
oss << tod.minute;
|
||||
}
|
||||
if (tod.second < 10) {
|
||||
oss << 0 << tod.second;
|
||||
} else {
|
||||
oss << tod.second;
|
||||
ReturnValue_t ScexDeviceHandler::generateNewScexFile(const char* cmdName) {
|
||||
char timeString[64]{};
|
||||
auto activeSd = sdcMan.getActiveSdCard();
|
||||
if (not activeSd) {
|
||||
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
||||
}
|
||||
|
||||
date_time = oss.str();
|
||||
|
||||
return date_time;
|
||||
std::ostringstream oss;
|
||||
auto prefix = sdcMan.getCurrentMountPrefix();
|
||||
if (prefix == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
timeval tv;
|
||||
Clock::getClock_timeval(&tv);
|
||||
time_t epoch = tv.tv_sec;
|
||||
struct tm* time = gmtime(&epoch);
|
||||
size_t writtenBytes = strftime(reinterpret_cast<char*>(timeString), sizeof(timeString),
|
||||
config::FILE_DATE_FORMAT, time);
|
||||
if (writtenBytes == 0) {
|
||||
sif::error << "PersistentTmStore::createMostRecentFile: Could not create file timestamp"
|
||||
<< std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
oss << prefix << "/scex/scex-" << cmdName << "-" << timeString << ".bin";
|
||||
fileName = oss.str();
|
||||
ofstream out(fileName, ofstream::binary);
|
||||
if (out.bad()) {
|
||||
sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName
|
||||
<< std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
out << helper;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void ScexDeviceHandler::modeChanged() {}
|
||||
|
||||
void ScexDeviceHandler::setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Switch_t switchId) {
|
||||
DeviceHandlerBase::setPowerSwitcher(&powerSwitcher);
|
||||
this->switchId = switchId;
|
@ -1,9 +1,9 @@
|
||||
#ifndef MISSION_DEVICES_SCEXDEVICEHANDLER_H_
|
||||
#define MISSION_DEVICES_SCEXDEVICEHANDLER_H_
|
||||
#ifndef MISSION_PAYLOAD_SCEXDEVICEHANDLER_H_
|
||||
#define MISSION_PAYLOAD_SCEXDEVICEHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <linux/devices/ScexHelper.h>
|
||||
#include <linux/devices/ScexUartReader.h>
|
||||
#include <linux/payload/ScexHelper.h>
|
||||
#include <linux/payload/ScexUartReader.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
@ -13,6 +13,14 @@ class SdCardMountedIF;
|
||||
|
||||
class ScexDeviceHandler : public DeviceHandlerBase {
|
||||
public:
|
||||
static constexpr char FRAM_BASE_NAME[] = "framContent";
|
||||
static constexpr char ION_BASE_NAME[] = "ion";
|
||||
static constexpr char TEMPERATURE_BASE_NAME[] = "temperature";
|
||||
static constexpr char EXP_STATUS_BASE_NAME[] = "expStatus";
|
||||
static constexpr char ONE_CELL_BASE_NAME[] = "oneCell";
|
||||
static constexpr char ALL_CELLS_BASE_NAME[] = "allCells";
|
||||
static constexpr char PING_IDLE_BASE_NAME[] = "pingIdle";
|
||||
|
||||
ScexDeviceHandler(object_id_t objectId, ScexUartReader &reader, CookieIF *cookie,
|
||||
SdCardMountedIF &sdcMan);
|
||||
void setPowerSwitcher(PowerSwitchIF &powerSwitcher, power::Switch_t switchId);
|
||||
@ -35,8 +43,6 @@ class ScexDeviceHandler : public DeviceHandlerBase {
|
||||
SdCardMountedIF &sdcMan;
|
||||
Countdown finishCountdown = Countdown(LONG_CD);
|
||||
|
||||
std::string date_time_string();
|
||||
|
||||
// DeviceHandlerBase private function implementation
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
@ -59,7 +65,8 @@ class ScexDeviceHandler : public DeviceHandlerBase {
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
void modeChanged() override;
|
||||
|
||||
ReturnValue_t generateNewScexFile(const char *cmdName);
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_SCEXDEVICEHANDLER_H_ */
|
||||
#endif /* MISSION_PAYLOAD_SCEXDEVICEHANDLER_H_ */
|
@ -1,4 +1,4 @@
|
||||
#include "payloadDefs.h"
|
||||
#include <mission/payload/defs.h>
|
||||
|
||||
const char* payload::getModeStr(Mode mode) {
|
||||
static const char* modeStr = "UNKNOWN";
|
@ -4,13 +4,13 @@
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <mission/memory/NvmParameterBase.h>
|
||||
#include <mission/tcs/max1227.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "mission/devices/max1227.h"
|
||||
|
||||
namespace plpcdu {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_SPBASE_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_SPBASE_H_
|
||||
#ifndef MISSION_PAYLOAD_PLOCSPBASE_H_
|
||||
#define MISSION_PAYLOAD_PLOCSPBASE_H_
|
||||
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/tmtcpacket/ccsds/SpacePacketCreator.h>
|
||||
#include <fsfw/tmtcpacket/ccsds/SpacePacketReader.h>
|
||||
|
||||
@ -117,4 +118,4 @@ class SpTmReader : public SpacePacketReader {
|
||||
|
||||
} // namespace ploc
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_SPBASE_H_ */
|
||||
#endif /* MISSION_PAYLOAD_PLOCSPBASE_H_ */
|
@ -1,6 +1,5 @@
|
||||
#include "ScexDefinitions.h"
|
||||
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <mission/payload/scexHelpers.h>
|
||||
|
||||
#include <cstring>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_
|
||||
#ifndef MISSION_PAYLOAD_SCEXHELPERS_H_
|
||||
#define MISSION_PAYLOAD_SCEXHELPERS_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/events/Event.h>
|
||||
@ -49,4 +49,4 @@ ReturnValue_t prepareScexCmd(Cmds cmd, std::pair<uint8_t*, size_t> cmdBufPair, s
|
||||
|
||||
} // namespace scex
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_ */
|
||||
#endif /* MISSION_PAYLOAD_SCEXHELPERS_H_ */
|
@ -25,8 +25,6 @@ static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID,
|
||||
//! P2: Allowed file size
|
||||
static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
||||
static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Dump was cancelled. P1: Object ID of store.
|
||||
static constexpr Event DUMP_WAS_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
|
||||
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_OK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
|
||||
@ -38,6 +36,17 @@ static constexpr Event DUMP_MISC_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 7,
|
||||
static constexpr Event DUMP_HK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_CFDP_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 9, severity::INFO);
|
||||
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_OK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_NOK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_MISC_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 12, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_HK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 13, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_CFDP_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 14, severity::LOW);
|
||||
}; // namespace persTmStore
|
||||
|
||||
#endif /* MISSION_PERSISTENTTMSTOREDEFS_H_ */
|
||||
|
@ -4,11 +4,11 @@
|
||||
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
#include <mission/acs/imtqHelpers.h>
|
||||
#include <mission/tcs/Max31865Definitions.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "eive/definitions.h"
|
||||
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||
|
||||
#ifndef RPI_TEST_ADIS16507
|
||||
#define RPI_TEST_ADIS16507 0
|
||||
@ -26,10 +26,11 @@ ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) {
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
||||
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
|
||||
|
||||
static_cast<void>(length);
|
||||
|
||||
@ -102,25 +103,25 @@ ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) {
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
|
||||
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
if (thisSequence->checkSequence() != returnvalue::OK) {
|
||||
sif::error << "GomSpace PST initialization failed" << std::endl;
|
||||
return returnvalue::FAILED;
|
@ -1,10 +1,10 @@
|
||||
#include "ACUHandler.h"
|
||||
#include <mission/power/AcuHandler.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
|
||||
FailureIsolationBase *customFdir)
|
||||
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
|
||||
FailureIsolationBase *customFdir, bool enableHkSets)
|
||||
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir, enableHkSets),
|
||||
coreHk(this),
|
||||
auxHk(this) {
|
||||
cfg.maxConfigTableAddress = ACU::MAX_CONFIGTABLE_ADDRESS;
|
||||
@ -149,9 +149,9 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData
|
||||
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
|
||||
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), false, 10.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), false, 30.0));
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef MISSION_DEVICES_ACUHANDLER_H_
|
||||
#define MISSION_DEVICES_ACUHANDLER_H_
|
||||
#ifndef MISSION_POWER_ACUHANDLER_H_
|
||||
#define MISSION_POWER_ACUHANDLER_H_
|
||||
|
||||
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||
#include <mission/power/GomspaceDeviceHandler.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
|
||||
#include "GomspaceDeviceHandler.h"
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
|
||||
/**
|
||||
@ -13,7 +13,7 @@
|
||||
class ACUHandler : public GomspaceDeviceHandler {
|
||||
public:
|
||||
ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
FailureIsolationBase* customFdir);
|
||||
FailureIsolationBase* customFdir, bool enableHkSets);
|
||||
virtual ~ACUHandler();
|
||||
|
||||
void setDebugMode(bool enable);
|
||||
@ -53,4 +53,4 @@ class ACUHandler : public GomspaceDeviceHandler {
|
||||
void printChannelStats();
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_ACUHANDLER_H_ */
|
||||
#endif /* MISSION_POWER_ACUHANDLER_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user