eive-obsw/mission/devices/ImtqHandler.h
Robin Mueller 75a4cd1b69
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
awful solution but works
2022-10-20 16:09:18 +02:00

228 lines
9.9 KiB
C++

#ifndef MISSION_DEVICES_IMTQHANDLER_H_
#define MISSION_DEVICES_IMTQHANDLER_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/devices/devicedefinitions/imtqHandlerDefinitions.h>
#include <string.h>
#include "events/subsystemIdRanges.h"
#include "returnvalues/classIds.h"
/**
* @brief This is the device handler for the ISIS Magnetorquer iMTQ.
*
* @author J. Meier
*/
class ImtqHandler : public DeviceHandlerBase {
public:
enum NormalPollingMode { UNCALIBRATED = 0, CALIBRATED = 1, BOTH = 2 };
ImtqHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
power::Switch_t pwrSwitcher);
virtual ~ImtqHandler();
void setPollingMode(NormalPollingMode pollMode);
void doSendRead() override;
/**
* @brief Sets mode to MODE_NORMAL. Can be used for debugging.
*/
void setToGoToNormal(bool enable);
void setDebugMode(bool enable);
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 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;
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::IMTQ_HANDLER;
static const ReturnValue_t INVALID_COMMAND_CODE = MAKE_RETURN_CODE(0xA0);
static const ReturnValue_t PARAMETER_MISSING = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t PARAMETER_INVALID = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t CC_UNAVAILABLE = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t INTERNAL_PROCESSING_ERROR = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t REJECTED_WITHOUT_REASON = MAKE_RETURN_CODE(0xA5);
static const ReturnValue_t CMD_ERR_UNKNOWN = MAKE_RETURN_CODE(0xA6);
//! [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 uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::IMTQ_HANDLER;
//! [EXPORT] : [COMMENT] Get self test result returns I2C failure
//! P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 ->
//! -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_I2C_FAILURE = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Get self test result returns SPI failure. This concerns the MTM
//! connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3
//! -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_SPI_FAILURE = MAKE_EVENT(2, severity::LOW);
//! [EXPORT] : [COMMENT] Get self test result returns failure in measurement of current and
//! temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3
//! -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_ADC_FAILURE = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] Get self test result returns PWM failure which concerns the coil
//! actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 ->
//! +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_PWM_FAILURE = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] Get self test result returns TC failure (system failure)
//! P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 ->
//! -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_TC_FAILURE = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] Get self test result returns failure that MTM values were outside of the
//! expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X,
//! 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_MTM_RANGE_FAILURE = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Get self test result returns failure indicating that the coil current was
//! outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1
//! -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA
static const Event SELF_TEST_COIL_CURRENT_FAILURE = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Received invalid error byte. This indicates an error of the communication
//! link between IMTQ and OBC.
static const Event INVALID_ERROR_BYTE = MAKE_EVENT(8, severity::LOW);
IMTQ::EngHkDataset engHkDataset;
IMTQ::CalibratedMtmMeasurementSet calMtmMeasurementSet;
IMTQ::RawMtmMeasurementSet rawMtmMeasurementSet;
IMTQ::DipoleActuationSet dipoleSet;
IMTQ::PosXSelfTestSet posXselfTestDataset;
IMTQ::NegXSelfTestSet negXselfTestDataset;
IMTQ::PosYSelfTestSet posYselfTestDataset;
IMTQ::NegYSelfTestSet negYselfTestDataset;
IMTQ::PosZSelfTestSet posZselfTestDataset;
IMTQ::NegZSelfTestSet negZselfTestDataset;
NormalPollingMode pollingMode = NormalPollingMode::UNCALIBRATED;
PoolEntry<int32_t> mgmCalEntry = PoolEntry<int32_t>(3);
PoolEntry<int16_t> dipoleXEntry = PoolEntry<int16_t>(0, false);
PoolEntry<int16_t> dipoleYEntry = PoolEntry<int16_t>(0, false);
PoolEntry<int16_t> dipoleZEntry = PoolEntry<int16_t>(0, false);
PoolEntry<uint16_t> torqueDurationEntry = PoolEntry<uint16_t>(0, false);
// Hardcoded to default integration time of 10 ms.
// SHOULDDO: Support for other integration times
Countdown integrationTimeCd = Countdown(10);
power::Switch_t switcher = power::NO_SWITCH;
uint8_t commandBuffer[IMTQ::MAX_COMMAND_SIZE];
bool goToNormalMode = false;
bool debugMode = false;
enum class CommunicationStep {
GET_ENG_HK_DATA,
START_MTM_MEASUREMENT,
GET_CAL_MTM_MEASUREMENT,
GET_RAW_MTM_MEASUREMENT,
DIPOLE_ACTUATION
};
CommunicationStep communicationStep = CommunicationStep::GET_ENG_HK_DATA;
enum class StartupStep { NONE, COMMAND_SELF_TEST, GET_SELF_TEST_RESULT };
StartupStep startupStep = StartupStep::COMMAND_SELF_TEST;
bool selfTestPerformed = false;
/**
* @brief In case of a status reply to a single axis self test command, this function
* searches for the actual pending command.
*/
ReturnValue_t getSelfTestCommandId(DeviceCommandId_t* id);
/**
* @brief Each reply contains a status byte giving information about a request. This function
* parses this byte and returns the associated failure message.
*
* @param packet Pointer to the received message containing the status byte.
*
* @return The return code derived from the received status byte.
*/
ReturnValue_t parseStatusByte(const uint8_t* packet);
/**
* @brief This function fills the engineering housekeeping dataset with the received data.
* @param packet Pointer to the received data.
*
*/
void fillEngHkDataset(const uint8_t* packet);
/**
* @brief This function sends a command reply to the requesting queue.
*
* @param data Pointer to the data to send.
* @param dataSize Size of the data to send.
* @param relplyId Reply id which will be inserted at the beginning of the action message.
*/
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
/**
* @brief This function handles the reply containing the commanded dipole.
*
* @param packet Pointer to the reply data.
*/
void handleGetCommandedDipoleReply(const uint8_t* packet);
/**
* @brief This function parses the reply containing the calibrated MTM measurement and writes
* the values to the appropriate dataset.
* @param packet Pointer to the reply data.
*/
void fillCalibratedMtmDataset(const uint8_t* packet);
/**
* @brief This function copies the raw MTM measurements to the MTM raw dataset.
* @param packet Pointer to the reply data requested with the GET_RAW_MTM_MEASUREMENTS
* command.
*/
void fillRawMtmDataset(const uint8_t* packet);
/**
* @brief This function handles all self test results. This comprises parsing the error byte
* and step byte and calling the function to fill the respective dataset.
*/
void handleSelfTestReply(const uint8_t* packet);
/**
* @brief The following functions fill the respective dataset of the single axis self tests.
* @param packet Pointer to the reply data holding the self test result.
*/
void handlePositiveXSelfTestReply(const uint8_t* packet);
void handleNegativeXSelfTestReply(const uint8_t* packet);
void handlePositiveYSelfTestReply(const uint8_t* packet);
void handleNegativeYSelfTestReply(const uint8_t* packet);
void handlePositiveZSelfTestReply(const uint8_t* packet);
void handleNegativeZSelfTestReply(const uint8_t* packet);
ReturnValue_t buildDipoleActuationCommand();
/**
* @brief This function checks the error byte of a self test measurement.
*
* @param errorByte The received error byte to check
* @param step The step of the error byte.
*/
void checkErrorByte(const uint8_t errorByte, const uint8_t step);
std::string makeStepString(const uint8_t step);
};
#endif /* MISSION_DEVICES_IMTQHANDLER_H_ */