2023-03-26 16:42:00 +02:00
|
|
|
#ifndef MISSION_TCS_HEATERHANDLER_H_
|
|
|
|
#define MISSION_TCS_HEATERHANDLER_H_
|
2021-01-23 17:22:40 +01:00
|
|
|
|
|
|
|
#include <fsfw/action/HasActionsIF.h>
|
2021-02-01 11:17:20 +01:00
|
|
|
#include <fsfw/devicehandlers/CookieIF.h>
|
2022-01-17 15:58:27 +01:00
|
|
|
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
2022-05-02 22:45:27 +02:00
|
|
|
#include <fsfw/devicehandlers/HealthDevice.h>
|
2022-05-02 17:37:00 +02:00
|
|
|
#include <fsfw/health/HasHealthIF.h>
|
2022-05-02 17:51:00 +02:00
|
|
|
#include <fsfw/health/HealthHelper.h>
|
2022-01-17 15:58:27 +01:00
|
|
|
#include <fsfw/objectmanager/SystemObject.h>
|
|
|
|
#include <fsfw/power/PowerSwitchIF.h>
|
2022-08-24 17:27:47 +02:00
|
|
|
#include <fsfw/returnvalues/returnvalue.h>
|
2023-02-17 11:50:14 +01:00
|
|
|
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
|
|
|
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
2022-01-17 15:58:27 +01:00
|
|
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
2021-02-01 11:17:20 +01:00
|
|
|
#include <fsfw/timemanager/Countdown.h>
|
2021-08-03 15:58:01 +02:00
|
|
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-05-19 23:06:18 +02:00
|
|
|
#include <array>
|
2022-11-24 19:41:57 +01:00
|
|
|
#include <utility>
|
2022-06-17 08:31:36 +02:00
|
|
|
#include <vector>
|
2021-01-23 17:22:40 +01:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
#include "devices/heaterSwitcherList.h"
|
2022-09-14 13:44:43 +02:00
|
|
|
#include "events/subsystemIdRanges.h"
|
|
|
|
#include "returnvalues/classIds.h"
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-05-02 17:37:00 +02:00
|
|
|
class PowerSwitchIF;
|
|
|
|
class HealthTableIF;
|
|
|
|
|
2022-05-02 22:45:27 +02:00
|
|
|
using HeaterPair = std::pair<HealthDevice*, gpioId_t>;
|
|
|
|
|
|
|
|
struct HeaterHelper {
|
|
|
|
public:
|
2022-11-25 10:13:24 +01:00
|
|
|
HeaterHelper(std::array<HeaterPair, heater::NUMBER_OF_SWITCHES> heaters)
|
|
|
|
: heaters(std::move(heaters)) {}
|
2022-05-02 22:55:39 +02:00
|
|
|
std::array<HeaterPair, heater::NUMBER_OF_SWITCHES> heaters = {};
|
2022-05-02 22:45:27 +02:00
|
|
|
};
|
2021-01-23 17:22:40 +01:00
|
|
|
/**
|
|
|
|
* @brief This class intends the control of heaters.
|
|
|
|
*
|
|
|
|
* @author J. Meier
|
|
|
|
*/
|
2022-01-17 15:58:27 +01:00
|
|
|
class HeaterHandler : public ExecutableObjectIF,
|
|
|
|
public PowerSwitchIF,
|
2023-02-17 11:50:14 +01:00
|
|
|
public HasModesIF,
|
|
|
|
public ModeTreeChildIF,
|
|
|
|
public ModeTreeConnectionIF,
|
2022-01-17 15:58:27 +01:00
|
|
|
public SystemObject,
|
|
|
|
public HasActionsIF {
|
2022-11-16 17:33:19 +01:00
|
|
|
friend class ThermalController;
|
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
public:
|
|
|
|
static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER;
|
|
|
|
|
|
|
|
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
|
|
|
|
static const ReturnValue_t INIT_FAILED = MAKE_RETURN_CODE(0xA2);
|
|
|
|
static const ReturnValue_t INVALID_SWITCH_NR = MAKE_RETURN_CODE(0xA3);
|
|
|
|
static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4);
|
|
|
|
static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5);
|
|
|
|
|
2022-05-12 20:44:36 +02:00
|
|
|
enum CmdSourceParam : uint8_t { INTERNAL = 0, EXTERNAL = 1 };
|
2023-02-21 02:28:57 +01:00
|
|
|
enum SwitchState : uint8_t { ON = 1, OFF = 0 };
|
2022-05-12 20:12:01 +02:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
/** Device command IDs */
|
|
|
|
static const DeviceCommandId_t SWITCH_HEATER = 0x0;
|
|
|
|
|
2022-05-02 22:45:27 +02:00
|
|
|
HeaterHandler(object_id_t setObjectId, GpioIF* gpioInterface_, HeaterHelper helper,
|
2022-05-02 17:51:00 +02:00
|
|
|
PowerSwitchIF* mainLineSwitcherObjectId, power::Switch_t mainLineSwitch);
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2023-02-17 13:04:40 +01:00
|
|
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
2023-02-21 02:28:57 +01:00
|
|
|
ReturnValue_t getAllSwitchStates(std::array<SwitchState, 8>& statesBuf);
|
2023-02-17 13:04:40 +01:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
virtual ~HeaterHandler();
|
|
|
|
|
2022-11-16 17:33:19 +01:00
|
|
|
protected:
|
2022-11-28 08:56:36 +01:00
|
|
|
enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE };
|
|
|
|
|
|
|
|
ReturnValue_t switchHeater(heater::Switchers heater, SwitchState switchState);
|
2022-12-13 10:19:28 +01:00
|
|
|
HasHealthIF::HealthState getHealth(heater::Switchers heater);
|
|
|
|
|
2022-05-04 11:11:29 +02:00
|
|
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-05-04 11:11:29 +02:00
|
|
|
ReturnValue_t sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override;
|
|
|
|
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
2022-01-17 15:58:27 +01:00
|
|
|
/**
|
|
|
|
* @brief This function will be called from the Heater object to check
|
|
|
|
* the current switch state.
|
|
|
|
*/
|
2022-05-04 11:11:29 +02:00
|
|
|
ReturnValue_t getSwitchState(uint8_t switchNr) const override;
|
|
|
|
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
|
|
|
uint32_t getSwitchDelayMs(void) const override;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-05-04 11:11:29 +02:00
|
|
|
MessageQueueId_t getCommandQueue() const override;
|
|
|
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
|
|
|
const uint8_t* data, size_t size) override;
|
|
|
|
ReturnValue_t initialize() override;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER_HANDLER;
|
2022-05-04 10:34:11 +02:00
|
|
|
static constexpr Event GPIO_PULL_HIGH_FAILED = MAKE_EVENT(0, severity::LOW);
|
|
|
|
static constexpr Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
|
|
|
|
static constexpr Event HEATER_WENT_ON = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
|
|
|
static constexpr Event HEATER_WENT_OFF = event::makeEvent(SUBSYSTEM_ID, 3, severity::INFO);
|
|
|
|
static constexpr Event SWITCH_ALREADY_ON = MAKE_EVENT(4, severity::LOW);
|
|
|
|
static constexpr Event SWITCH_ALREADY_OFF = MAKE_EVENT(5, severity::LOW);
|
|
|
|
static constexpr Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(6, severity::MEDIUM);
|
2022-05-12 20:44:36 +02:00
|
|
|
//! A faulty heater was one. The SW will autonomously attempt to shut it down. P1: Heater Index
|
|
|
|
static constexpr Event FAULTY_HEATER_WAS_ON = event::makeEvent(SUBSYSTEM_ID, 7, severity::LOW);
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
static const MessageQueueId_t NO_COMMANDER = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Struct holding information about a heater command to execute.
|
|
|
|
*
|
|
|
|
* @param action The action to perform.
|
|
|
|
* @param replyQueue The queue of the commander to which status replies
|
|
|
|
* will be sent.
|
|
|
|
* @param active True if command is waiting for execution, otherwise false.
|
|
|
|
* @param waitSwitchOn True if the command is waiting for the main switch being set on.
|
|
|
|
* @param mainSwitchCountdown Sets timeout to wait for main switch being set on.
|
|
|
|
*/
|
2022-05-02 22:45:27 +02:00
|
|
|
struct HeaterWrapper {
|
2022-05-04 10:34:11 +02:00
|
|
|
HeaterWrapper(HeaterPair pair, SwitchState initState)
|
2022-05-04 11:11:29 +02:00
|
|
|
: healthDevice(pair.first), gpioId(pair.second), switchState(initState) {}
|
2022-05-02 22:45:27 +02:00
|
|
|
HealthDevice* healthDevice = nullptr;
|
|
|
|
gpioId_t gpioId = gpio::NO_GPIO;
|
|
|
|
SwitchAction action = SwitchAction::NONE;
|
|
|
|
MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE;
|
2022-05-12 20:44:36 +02:00
|
|
|
bool cmdActive = false;
|
2022-05-02 22:45:27 +02:00
|
|
|
SwitchState switchState = SwitchState::OFF;
|
2022-01-17 15:58:27 +01:00
|
|
|
bool waitMainSwitchOn = false;
|
|
|
|
Countdown mainSwitchCountdown;
|
2022-05-02 22:45:27 +02:00
|
|
|
};
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-05-02 22:45:27 +02:00
|
|
|
using HeaterMap = std::vector<HeaterWrapper>;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-05-02 22:45:27 +02:00
|
|
|
HeaterMap heaterVec = {};
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2023-03-02 15:32:12 +01:00
|
|
|
MutexIF* handlerLock = nullptr;
|
|
|
|
static constexpr MutexIF::TimeoutType LOCK_TYPE = MutexIF::TimeoutType::WAITING;
|
|
|
|
static constexpr uint32_t LOCK_TIMEOUT = 20;
|
|
|
|
static constexpr char LOCK_CTX[] = "HeaterHandler";
|
2022-05-04 11:11:29 +02:00
|
|
|
|
2022-05-02 22:45:27 +02:00
|
|
|
HeaterHelper helper;
|
2023-02-17 11:50:14 +01:00
|
|
|
ModeHelper modeHelper;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
/** Size of command queue */
|
|
|
|
size_t cmdQueueSize = 20;
|
2023-02-17 11:50:14 +01:00
|
|
|
bool waitForSwitchOff = true;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
GpioIF* gpioInterface = nullptr;
|
|
|
|
|
|
|
|
/** Queue to receive messages from other objects. */
|
|
|
|
MessageQueueIF* commandQueue = nullptr;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Power switcher object which controls the 8V main line of the heater
|
|
|
|
* logic on the TCS board.
|
|
|
|
*/
|
|
|
|
PowerSwitchIF* mainLineSwitcher = nullptr;
|
2022-05-02 17:37:00 +02:00
|
|
|
/** Switch number of the heater power supply switch */
|
|
|
|
power::Switch_t mainLineSwitch;
|
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
ActionHelper actionHelper;
|
2021-01-28 14:55:21 +01:00
|
|
|
|
2022-05-02 22:45:27 +02:00
|
|
|
StorageManagerIF* ipcStore = nullptr;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2023-02-17 11:50:14 +01:00
|
|
|
Mode_t mode = HasModesIF::MODE_OFF;
|
|
|
|
Submode_t submode = 0;
|
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
void readCommandQueue();
|
2021-01-28 14:55:21 +01:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
/**
|
|
|
|
* @brief Returns the state of a switch (ON - true, or OFF - false).
|
|
|
|
* @param switchNr The number of the switch to check.
|
|
|
|
*/
|
2022-05-04 11:11:29 +02:00
|
|
|
SwitchState checkSwitchState(heater::Switchers switchNr) const;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function runs commands waiting for execution.
|
|
|
|
*/
|
2022-05-12 20:44:36 +02:00
|
|
|
void handleSwitchHandling();
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
ReturnValue_t initializeHeaterMap();
|
2021-01-28 14:55:21 +01:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
/**
|
|
|
|
* @brief Sets all switches to OFF.
|
|
|
|
*/
|
|
|
|
void setInitialSwitchStates();
|
2021-01-23 17:22:40 +01:00
|
|
|
|
2023-02-17 11:50:14 +01:00
|
|
|
// HasModesIF implementation
|
|
|
|
void announceMode(bool recursive) override;
|
|
|
|
void getMode(Mode_t* mode, Submode_t* submode) override;
|
|
|
|
|
|
|
|
// Mode Tree helper overrides
|
|
|
|
object_id_t getObjectId() const override;
|
|
|
|
const HasHealthIF* getOptHealthIF() const override;
|
|
|
|
const HasModesIF& getModeIF() const override;
|
|
|
|
ModeTreeChildIF& getModeTreeChildIF() override;
|
|
|
|
|
2022-05-02 22:55:39 +02:00
|
|
|
void handleSwitchOnCommand(heater::Switchers heaterIdx);
|
2021-01-23 17:22:40 +01:00
|
|
|
|
2022-05-02 22:55:39 +02:00
|
|
|
void handleSwitchOffCommand(heater::Switchers heaterIdx);
|
2021-02-11 08:19:48 +01:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
/**
|
|
|
|
* @brief Checks if all switches are off.
|
|
|
|
* @return True if all switches are off, otherwise false.
|
|
|
|
*/
|
|
|
|
bool allSwitchesOff();
|
2021-01-23 17:22:40 +01:00
|
|
|
};
|
|
|
|
|
2023-03-26 16:42:00 +02:00
|
|
|
#endif /* MISSION_TCS_HEATERHANDLER_H_ */
|