2021-03-17 11:14:48 +01:00
|
|
|
#ifndef MISSION_DEVICES_IMTQHANDLER_H_
|
|
|
|
#define MISSION_DEVICES_IMTQHANDLER_H_
|
|
|
|
|
|
|
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
2023-03-24 20:50:33 +01:00
|
|
|
#include <mission/acs/imtqHelpers.h>
|
2021-03-17 11:14:48 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
2022-09-14 13:44:43 +02:00
|
|
|
#include "events/subsystemIdRanges.h"
|
|
|
|
#include "returnvalues/classIds.h"
|
|
|
|
|
2021-03-17 11:14:48 +01:00
|
|
|
/**
|
|
|
|
* @brief This is the device handler for the ISIS Magnetorquer iMTQ.
|
|
|
|
*
|
|
|
|
* @author J. Meier
|
|
|
|
*/
|
2022-10-19 18:52:16 +02:00
|
|
|
class ImtqHandler : public DeviceHandlerBase {
|
2022-01-18 11:41:19 +01:00
|
|
|
public:
|
2022-10-20 10:32:17 +02:00
|
|
|
enum NormalPollingMode { UNCALIBRATED = 0, CALIBRATED = 1, BOTH = 2 };
|
|
|
|
|
2022-10-19 18:52:16 +02:00
|
|
|
ImtqHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
2023-03-26 15:28:00 +02:00
|
|
|
power::Switch_t pwrSwitcher, bool enableHkSets);
|
2022-10-19 18:52:16 +02:00
|
|
|
virtual ~ImtqHandler();
|
2022-01-18 11:41:19 +01:00
|
|
|
|
2022-10-20 10:32:17 +02:00
|
|
|
void setPollingMode(NormalPollingMode pollMode);
|
|
|
|
|
2022-01-18 11:41:19 +01:00
|
|
|
/**
|
|
|
|
* @brief Sets mode to MODE_NORMAL. Can be used for debugging.
|
|
|
|
*/
|
2022-01-27 16:04:45 +01:00
|
|
|
void setToGoToNormal(bool enable);
|
2022-01-18 11:41:19 +01:00
|
|
|
|
2022-04-26 10:37:25 +02:00
|
|
|
void setDebugMode(bool enable);
|
|
|
|
|
2022-01-18 11:41:19 +01:00
|
|
|
protected:
|
2023-02-20 19:35:36 +01:00
|
|
|
ReturnValue_t performOperation(uint8_t opCode);
|
2022-01-18 11:41:19 +01:00
|
|
|
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;
|
|
|
|
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;
|
2022-04-14 11:17:07 +02:00
|
|
|
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
|
2022-01-18 11:41:19 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
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);
|
|
|
|
|
2023-03-06 09:17:03 +01:00
|
|
|
enum class InternalState { NONE, STARTUP, SHUTDOWN } internalState = InternalState::NONE;
|
|
|
|
bool commandExecuted = false;
|
2023-03-26 15:28:00 +02:00
|
|
|
bool enableHkSets = false;
|
2023-03-06 09:17:03 +01:00
|
|
|
|
|
|
|
imtq::Request request{};
|
|
|
|
|
2023-02-19 12:25:26 +01:00
|
|
|
imtq::StatusDataset statusSet;
|
|
|
|
imtq::DipoleActuationSet dipoleSet;
|
|
|
|
imtq::RawMtmMeasurementNoTorque rawMtmNoTorque;
|
|
|
|
imtq::HkDatasetNoTorque hkDatasetNoTorque;
|
|
|
|
|
|
|
|
imtq::RawMtmMeasurementWithTorque rawMtmWithTorque;
|
|
|
|
imtq::HkDatasetWithTorque hkDatasetWithTorque;
|
|
|
|
|
|
|
|
imtq::CalibratedMtmMeasurementSet calMtmMeasurementSet;
|
|
|
|
imtq::PosXSelfTestSet posXselfTestDataset;
|
|
|
|
imtq::NegXSelfTestSet negXselfTestDataset;
|
|
|
|
imtq::PosYSelfTestSet posYselfTestDataset;
|
|
|
|
imtq::NegYSelfTestSet negYselfTestDataset;
|
|
|
|
imtq::PosZSelfTestSet posZselfTestDataset;
|
|
|
|
imtq::NegZSelfTestSet negZselfTestDataset;
|
2023-03-04 14:32:18 +01:00
|
|
|
bool manualTorqueCmdActive = false;
|
|
|
|
bool ignoreActForRestOfComSteps = false;
|
|
|
|
Countdown manuallyCommandedTorqueDuration = Countdown();
|
2022-01-18 11:41:19 +01:00
|
|
|
|
2022-10-20 15:08:33 +02:00
|
|
|
NormalPollingMode pollingMode = NormalPollingMode::UNCALIBRATED;
|
2022-10-20 10:32:17 +02:00
|
|
|
|
2023-02-19 12:25:26 +01:00
|
|
|
PoolEntry<uint8_t> statusMode = PoolEntry<uint8_t>({0});
|
|
|
|
PoolEntry<uint8_t> statusError = PoolEntry<uint8_t>({0});
|
|
|
|
PoolEntry<uint8_t> statusConfig = PoolEntry<uint8_t>({0});
|
|
|
|
PoolEntry<uint32_t> statusUptime = PoolEntry<uint32_t>({0});
|
|
|
|
|
2022-08-15 10:50:19 +02:00
|
|
|
PoolEntry<int32_t> mgmCalEntry = PoolEntry<int32_t>(3);
|
2023-03-04 14:32:18 +01:00
|
|
|
PoolEntry<int16_t> dipolesPoolEntry = PoolEntry<int16_t>({0, 0, 0}, false);
|
2023-03-04 10:33:47 +01:00
|
|
|
PoolEntry<uint16_t> torqueDurationEntry = PoolEntry<uint16_t>({0}, false);
|
2023-03-04 14:32:18 +01:00
|
|
|
PoolEntry<float> coilCurrentsMilliampsNoTorque = PoolEntry<float>(3);
|
|
|
|
PoolEntry<float> coilCurrentsMilliampsWithTorque = PoolEntry<float>(3);
|
|
|
|
PoolEntry<int16_t> coilTempsNoTorque = PoolEntry<int16_t>(3);
|
|
|
|
PoolEntry<int16_t> coilTempsWithTorque = PoolEntry<int16_t>(3);
|
|
|
|
PoolEntry<float> mtmRawNoTorque = PoolEntry<float>(3);
|
|
|
|
PoolEntry<uint8_t> actStatusNoTorque = PoolEntry<uint8_t>(1);
|
|
|
|
PoolEntry<float> mtmRawWithTorque = PoolEntry<float>(3);
|
|
|
|
PoolEntry<uint8_t> actStatusWithTorque = PoolEntry<uint8_t>(1);
|
|
|
|
|
2022-05-07 13:19:59 +02:00
|
|
|
power::Switch_t switcher = power::NO_SWITCH;
|
|
|
|
|
2023-03-06 11:02:56 +01:00
|
|
|
DeviceCommandId_t expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
|
2022-01-27 15:29:58 +01:00
|
|
|
bool goToNormalMode = false;
|
2022-04-26 10:37:25 +02:00
|
|
|
bool debugMode = false;
|
2023-02-20 11:47:26 +01:00
|
|
|
bool specialRequestActive = false;
|
|
|
|
bool firstReplyCycle = true;
|
2022-01-18 11:41:19 +01:00
|
|
|
|
2023-02-20 19:35:36 +01:00
|
|
|
imtq::RequestType requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
|
2022-01-18 11:41:19 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-02-19 12:25:26 +01:00
|
|
|
ReturnValue_t parseStatusByte(imtq::CC::CC command, const uint8_t* packet);
|
2022-01-18 11:41:19 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function fills the engineering housekeeping dataset with the received data.
|
|
|
|
|
|
|
|
* @param packet Pointer to the received data.
|
|
|
|
*
|
|
|
|
*/
|
2023-02-19 12:25:26 +01:00
|
|
|
void fillEngHkDataset(imtq::HkDataset& hkDataset, const uint8_t* packet);
|
|
|
|
|
|
|
|
void fillSystemStateIntoDataset(const uint8_t* packet);
|
2022-01-18 11:41:19 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2023-03-02 14:42:42 +01:00
|
|
|
void fillRawMtmDataset(imtq::RawMtmMeasurementSet& set, const uint8_t* packet);
|
2022-01-18 11:41:19 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
|
|
|
|
2023-02-19 12:25:26 +01:00
|
|
|
// ReturnValue_t buildDipoleActuationCommand();
|
2022-01-18 11:41:19 +01:00
|
|
|
/**
|
|
|
|
* @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);
|
2021-03-17 11:14:48 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* MISSION_DEVICES_IMTQHANDLER_H_ */
|