heater wip

This commit is contained in:
Jakob Meier 2021-01-23 17:22:40 +01:00
parent d913fbb416
commit 0a36325371
24 changed files with 810 additions and 77 deletions

View File

@ -434,7 +434,7 @@ cmp ident
List parameter table:
x values: 1,2 or 4
````
param table x
param list x
````
Table 4 lists HK parameters
Changing parameters

View File

@ -2,6 +2,7 @@
#include <OBSWConfig.h>
#include <tmtc/apid.h>
#include <devices/addresses.h>
#include <devices/gpioIds.h>
#include <tmtc/pusIds.h>
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
@ -22,6 +23,8 @@
#include <bsp_q7s/comIF/cookies/I2cCookie.h>
#include <bsp_q7s/comIF/CspComIF.h>
#include <bsp_q7s/comIF/I2cComIF.h>
#include <bsp_q7s/gpio/LinuxLibgpioIF.h>
#include <bsp_q7s/gpio/cookies/GpioCookie.h>
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
@ -87,6 +90,18 @@ void ObjectFactory::produce(){
i2cCookieTmp1075tcs2);
tmp1075Handler_2->setStartUpImmediately();
/* Thermal objects */
GpioCookie gpioCookie = new GpioCookie;
#if TE0720 == 1
// Configuration for MIO0 on TE0720-03-1CFA
GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
std::string("Heater1"), Gpio::OUT);
gpioCookie.add(gpioIds::HEATER_1, gpioConfigForDummyHeater);
#else
#endif
LinuxLibgpioIF linuxLibgpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, );
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR,

View File

@ -32,9 +32,12 @@ ReturnValue_t GpioComIF::initializeInterface(CookieIF * cookie) {
}
/* Register new GPIOs in gpioMap*/
result = initializeAndConfigure(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
std::pair insertionResult = gpioMap.insert(mapToAdd.begin(),
mapToAdd.end());
if (insertionResult.second() != true) {
sif::error << "GpioComIF::initializeAndConfigure: Failed to add "
<< "GPIO " << gpioStr.c_st() << " to gpioMap" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
@ -188,14 +191,14 @@ ReturnValue_t GpioComIF::openDevice(std::string deviceFile,
}
ReturnValue_t GpioComIF::checkForConflicts(GpioMap mapToAdd){
gpio_t gpio;
gpioId_t gpioId;
GpioMapIter mapToAddIter = mapToAdd.begin();
for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){
gpio = mapToAddIter.first();
if(gpioMapIter.find(gpio) != mapToAdd.end()){
if(gpioMapIter.find(gpioId) != mapToAdd.end()){
/* An entry for this GPIO already exists. Check if configuration
* of direction is equivalent */
if (mapToAddIter.second() != gpioMapIter.second()){
if (mapToAddIter.second.direction != gpioMapIter.second.direction){
sif::error << "GpioComIF::checkForConflicts: Detected conflict "
<< "for GPIO " << mapToAddIter.first() << std::endl;
return HasReturnvaluesIF::RETURN_OK;

View File

@ -1,48 +0,0 @@
#ifndef SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#define SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <string>
namespace Gpio {
enum Direction {
IN = 0,
OUT = 1
};
}
using gpio_t = uint32_t;
using direction_t = bool;
using GpioMap = std::unordered_map<gpio_t, direction_t>;
using GpioMapIter = GpioMap::iterator;
/**
* @brief Cookie for the GpioComIF. Allows the GpioComIF to determine which
* GPIOs to initialize and whether they should be configured as in- or
* output.
* @details One GpioCookie can hold multiple GPIO configurations. To add a new
* GPIO configuration to a GpioCookie use the GpioCookie::addGpio
* function.
*
* @author J. Meier
*/
class GpioCookie: public CookieIF {
public:
GpioCookie();
virtual ~GpioCookie();
void addGpio(gpioMap newEntry);
/**
* @brief Get map with register GPIOs.
*/
GpioMap getGpioMap() const;
private:
GpioMap gpioMap;
GpioMapIter gpioMapIter;
};
#endif

18
bsp_q7s/gpio/GpioIF.cpp Normal file
View File

@ -0,0 +1,18 @@
/*
* GpioIF.cpp
*
* Created on: 16.01.2021
* Author: jakob
*/
#include "GpioIF.h"
GpioIF::GpioIF() {
// TODO Auto-generated constructor stub
}
GpioIF::~GpioIF() {
// TODO Auto-generated destructor stub
}

43
bsp_q7s/gpio/GpioIF.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef BSP_Q7S_GPIO_GPIOIF_H_
#define BSP_Q7S_GPIO_GPIOIF_H_
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/devicehandlers/CookieIF.h>
typedef uint16_t gpioId_t;
/**
* @brief This class defines the interface for objects requiring the control
* over GPIOs.
* @author J. Meier
*/
class GpioIF : public HasReturnvaluesIF{
public:
GpioIF();
virtual ~GpioIF();
/**
* @brief Called by the GPIO using object.
* @param cookie Cookie specifying informations of the GPIOs required
* by a object.
*/
virtual ReturnValue_t initialize(CookieIF * cookie) = 0;
/**
* @brief By implementing this function a child must provide the
* functionality to pull a certain GPIO to high logic level.
*
* @param gpioId A unique number which specifies the GPIO to drive.
*/
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
/**
* @brief By implementing this function a child must provide the
* functionality to pull a certain GPIO to low logic level.
*
* @param gpioId A unique number which specifies the GPIO to drive.
*/
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
};
#endif /* BSP_Q7S_GPIO_GPIOIF_H_ */

View File

@ -0,0 +1,134 @@
#include <bsp_q7s/gpio/LinuxLibgpioIF.h>
#include <gpio.h>
#include <unistd.h>
LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) {
}
LinuxLibgpioIF::~LinuxLibgpioIF() {
}
ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){
ReturnValue_t result;
GpioMap mapToAdd;
GpioMapIter mapToAddIter;
if(cookie == nullptr) {
return NULLPOINTER;
}
GpioCookie* GpioCookie = dynamic_cast<GpioCookie*>(cookie);
if(GpioCookie == nullptr) {
sif::error << "LinuxLibgpioIF: Invalid Gpio Cookie!"
<< std::endl;
return NULLPOINTER;
}
mapToAdd = GpioCookie->getGpioMap();
result = checkForConflicts(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
/* Register new GPIOs in gpioMap*/
result = initializeAndConfigure(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
/* Register new GPIOs in gpioMap*/
std::pair insertionResult = gpioMap.insert(mapToAdd.begin(),
mapToAdd.end());
if (insertionResult.second() != true) {
sif::error << "LinuxLibgpioIF::initialize: Failed to add "
<< "GPIO with ID " << mapToAddIter.first << " to gpioMap"
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId){
return driveGpio(gpioId, 1);
}
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId){
return driveGpio(gpioId, 0);
}
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
unsigned int logiclevel) {
GpioMapIter gpioMapIter = gpioMap.find(gpioId);
char *chipname;
unsigned int lineNum;
struct gpiod_chip *chip;
struct gpiod_line *line;
int result;
Gpio::Direction direction;
/* Verify if GPIO has been configured as output */
direction = gpioMapIter.second.direction;
if (direction != Gpio::OUT) {
sif::error << "LinuxLibgpioIF::pullHigh: GPIO with ID " << gpioId
<< "not configured as output" << std::endl;
return CONFIGURATION_FAILURE;
}
chipname = gpioMapIter.second.chipname;
chip = gpiod_chip_open_by_name(chipname);
if (!chip) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to open chip "
<< chipname << ". Gpio ID: " << gpioId << std::endl;
return OPEN_CHIP_FAILURE;
}
lineNum = gpioMapIter.second.lineNum;
line = gpiod_chip_get_line(chip, lineNum);
if (!line) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to open line. Gpio ID "
<< gpioId << std::endl;
gpiod_chip_close(chip);
return OPEN_LINE_FAILURE;
}
result = gpiod_line_request_output(line, CONSUMER, 0);
if (result < 0) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to request line "
<< line << " from GPIO instance with ID: " << gpioId
<< std::endl;
gpiod_line_release(line);
return REQUEST_LINE_FAILURE;
}
result = gpiod_line_set_value(line, logiclevel);
if (result < 0) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to pull GPIO with ID "
<< gpioId << "to low" << std::endl;
gpiod_line_release(line);
return PULLING_HIGH_FAILURE;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){
gpioId_t gpioId;
GpioMapIter mapToAddIter = mapToAdd.begin();
for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){
gpio = mapToAddIter.first();
if(gpioMapIter.find(gpioId) != mapToAdd.end()){
/* An entry for this GPIO already exists. Check if configuration
* of direction is equivalent */
if (mapToAddIter.second.direction != gpioMapIter.second.direction){
sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict "
<< "for GPIO " << mapToAddIter.first() << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
/* Remove element from map to add because a entry for this GPIO
* already exists */
mapToAdd.erase(mapToAddIter);
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,58 @@
#ifndef BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_
#define BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_
#include <bsp_q7s/gpio/GpioIF.h>
#include <fsfwconfig/returnvalues/classIds.h>
/**
* @brief This class implements the GpioIF for a linux based system. The
* implementation is based on the libgpiod lib which requires linux 4.8
* or higher.
* @note The Petalinux SDK from Xilinx supports libgpiod since Petalinux
* 2019.1.
*/
class LinuxLibgpioIF: public GpioIF, public SystemObject {
public:
static const ReturnValue_t CONFIGURATION_FAILURE = MAKE_RETURN_CODE(0x1);
static const ReturnValue_t OPEN_CHIP_FAILURE = MAKE_RETURN_CODE(0x2);
static const ReturnValue_t OPEN_LINE_FAILURE = MAKE_RETURN_CODE(0x3);
static const ReturnValue_t REQUEST_LINE_FAILURE = MAKE_RETURN_CODE(0x4);
static const ReturnValue_t PULLING_HIGH_FAILURE = MAKE_RETURN_CODE(0x5);
LinuxLibgpioIF(object_id_t objectId);
virtual ~LinuxLibgpioIF();
ReturnValue_t initialize(CookieIF * cookie) override;
ReturnValue_t pullHigh(gpioId_t gpioId) override;
ReturnValue_t pullLow(gpioId_t gpioId) override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF;
/*Holds the information and configuration of all used GPIOs */
GpioMap gpioMap;
/**
* @brief This functions drives line of a GPIO specified by the GPIO ID.
*
* @param gpioId The GPIO ID of the GPIO to drive.
* @param logiclevel The logic level to set. O or 1.
*/
ReturnValue_t driveGpio(gpioId_t gpioId,
unsigned int logiclevel);
/**
* @brief This function checks if GPIOs are already registered and whether
* there exists a conflict in the GPIO configuration. E.g. the
* direction.
*
* @param mapToAdd The GPIOs which shall be added to the gpioMap.
*
* @return RETURN_OK if successful, otherwise RETURN_FAILED
*/
ReturnValue_t checkForConflicts(GpioMap mapToAdd);
};
#endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */

View File

@ -1,12 +1,12 @@
#include <bsp_q7s/comIF/cookies/GpioCookie.h>
#include <bsp_q7s/gpio/cookies/GpioCookie.h>
GpioCookie::GpioCookie() {
}
void GpioCookie::addGpio(gpioMap newEntry){
void GpioCookie::addGpio(GpioMap newEntry){
gpioMapIter = gpioMap.find(newEntry);
if(gpioMapIter == gpioMap.end()) {
std::pair status = i2cDeviceMap.emplace(newEntry);
std::pair status = gpioMap.emplace(newEntry);
if (status.second == false) {
sif::error << "GpioCookie::addGpio: Failed to add GPIO "
<< newEntry.first << "to GPIO map" << std::endl;

View File

@ -0,0 +1,68 @@
#ifndef SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#define SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <bsp_q7s/gpio/GpioIF.h>
#include <string>
namespace Gpio {
enum Direction {
IN = 0,
OUT = 1
};
}
/**
* @brief Struct containing information about the GPIO to use. This is
* required by the libgpiod to access and drive a GPIO.
* @param chipname String of the chipname specifying the group which contains
* the GPIO to access. E.g. gpiochip0. To detect names of
* GPIO groups run gpiodetect on the linux command line.
* @param lineNum The offset of the GPIO within the GPIO group.
* @param consumer Name of the consumer currently accessing the GPIO.
* @param direction Specifies whether the GPIO should be used as in- or output.
*/
typedef struct GpioConfig {
GpioConfig(std::string chipname_, int lineNum_, std::string consumer_,
Gpio::Direction direction_) :
chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction(
directio_) {
}
std::string chipname;
int lineNum;
std::string consumer;
Gpio::Direction direction;
} GpioConfig_t;
using GpioMap = std::unordered_map<gpioId_t, GpioConfig_t>;
using GpioMapIter = GpioMap::iterator;
/**
* @brief Cookie for the GpioIF. Allows the GpioIF to determine which
* GPIOs to initialize and whether they should be configured as in- or
* output.
* @details One GpioCookie can hold multiple GPIO configurations. To add a new
* GPIO configuration to a GpioCookie use the GpioCookie::addGpio
* function.
*
* @author J. Meier
*/
class GpioCookie: public CookieIF {
public:
GpioCookie();
virtual ~GpioCookie();
void addGpio(GpioMap newEntry);
/**
* @brief Get map with registered GPIOs.
*/
GpioMap getGpioMap() const;
private:
GpioMap gpioMap;
GpioMapIter gpioMapIter;
};
#endif

View File

@ -12,6 +12,8 @@
// debugging.
#define OBSW_ENHANCED_PRINTOUT 1
#define TE0720 1
#include "OBSWVersion.h"
#ifdef __cplusplus

View File

@ -0,0 +1,15 @@
#ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_
#define FSFWCONFIG_DEVICES_GPIOIDS_H_
#include <bsp_q7s/gpio/GpioIF.h>
namespace gpioIds {
enum gpioId_t {
HEATER_1
};
}
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */

View File

@ -1,9 +1,3 @@
/**
* @file switcherList.cpp
*
* @date 28.11.2019
*/
#include <fsfwconfig/devices/powerSwitcherList.h>

View File

@ -1,19 +1,14 @@
/**
* @file switcherList.h
*
* @date 28.11.2019
*/
#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
namespace switches {
namespace pcduSwitches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
PCDU,
GPS0,
GPS1,
DUMMY = 129
TCS_BOARD_8V_HEATER_IN,
DUMMY = 129,
};
}

View File

@ -22,7 +22,6 @@ namespace objects {
TM_FUNNEL = 0x52000002,
/* Test Task */
TEST_TASK = 0x42694269,
DUMMY_INTERFACE = 0xCAFECAFE,
DUMMY_HANDLER = 0x4400AFFE,
@ -33,13 +32,19 @@ namespace objects {
CSP_COM_IF = 0x49000002,
I2C_COM_IF = 0x49000003,
/* 0x47 ('G') for Gpio Interfaces */
GPIO_IF = 0x470000001,
/* 0x44 ('D') for device handlers */
P60DOCK_HANDLER = 0x44000001,
PDU1_HANDLER = 0x44000002,
PDU2_HANDLER = 0x44000003,
ACU_HANDLER = 0x44000004,
TMP1075_HANDLER_1 = 0x44000005,
TMP1075_HANDLER_2 = 0x44000006
TMP1075_HANDLER_2 = 0x44000006,
/* 0x54 ('T') for thermal objects */
HEATER_HANDLER = 0x54000001
};
}

View File

@ -12,7 +12,8 @@ namespace CLASS_ID {
enum {
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
MGM_LIS3MDL,
MGM_RM3100
MGM_RM3100,
LINUX_LIBGPIO_IF
};
}

View File

@ -37,7 +37,8 @@ public:
protected:
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id)
override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override;
void fillCommandAndReplyMap() override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,

View File

@ -0,0 +1,214 @@
#include <mission/devices/HeaterHandler.h>
HeaterHandler::HeaterHandler(object_id_t setObjectId,
object_id_t gpioDriverId, CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
gpioDriverId(gpioDriver), gpioCookie(gpioCookie), mainLineSwitcherObjectId(mainLineSwitcherObjectId), mainLineSwitch(mainLineSwitch),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
actionHelper(this, nullptr), hkManager(this, nullptr),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
switchOffWasReported(false), childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceSubMode(SUBMODE_NONE) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
powerSwitcher = objectManager->get<PowerSwitcherIF>(
mainLineSwitcherObjectId);
}
HeaterHandler::~HeaterHandler() {
}
ReturnValue_t performOperation(uint8_t operationCode) {
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
readCommandQueue();
handlePendingCommand();
doStateMachine();
checkSwitchState();
decrementDeviceReplyMap();
fdirInstance->checkForFailures();
hkSwitcher.performOperation();
performOperationHook();
return RETURN_OK;
}
}
ReturnValue_t DeviceHandlerBase::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return result;
}
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
if (gpioInterface == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: Invalid Gpio interface."
<< std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->initializeInterface(gpioCookie);
if (result != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio "
<< "interface"<< std::endl;
#endif
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: IPC store not set up in "
"factory." << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if(powerSwitcherId != objects::NO_OBJECT) {
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: Power switcher "
<< "object ID set but no valid object found." << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
result = healthHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = modeHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return result;
}
fillCommandAndReplyMap();
return RETURN_OK;
}
void DeviceHandlerBase::readCommandQueue() {
if (dontCheckQueue()) {
return;
}
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) {
return;
}
result = actionHelper.handleActionMessage(&command);
if (result == RETURN_OK) {
return;
}
}
ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
ReturnValue_t result = acceptExternalDeviceCommands();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
heaterCommandMap::iterator iter = HeaterCommandMap.find(actionId);
if (iter == heaterCommandMap.end()) {
result = COMMAND_NOT_SUPPORTED;
} else {
if (commandedBy == commandQueue){
heaterCommand(*(data), *(data + 1), NO_COMMANDER);
commandPending = true;
}
else {
heaterCommand(*(data), *(data + 1), commandedBy);
commandPending = true;
}
result = RETURN_OK;
}
return result;
}
ReturnValue_t DeviceHandlerBase::acceptExternalDeviceCommands() {
if (mode != MODE_ON) {
return WRONG_MODE_FOR_COMMAND;
}
return RETURN_OK;
}
void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
ReturnValue_t onOff) const {
ReturnValue_t result;
store_address_t address;
HeaterCommand_t command;
switch(onOff) {
case PowerSwitchIF::SWITCH_ON:
command(SWITCH_ON, switchNr);
case PowerSwitchIF::SWITCH_OFF:
command(SWITCH_OFF, switchNr);
default:
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request"
<< std::endl;
}
result = IPCStore->addData(&address, &command, sizeof(command));
if (result == RETURN_OK) {
CommandMessage message;
ActionMessage::setCommand(&message,
HeaterHandler::SWITCH_HEATER, address);
/* Send heater command to own command queue */
result = commandQueue->sendMessage(commandQueue, &message, 0);
if (result != RETURN_OK) {
debug << "HeaterHandler::sendSwitchCommand: Failed to send switch"
<< "message" << std::endl;
}
}
}
void HeaterHandler::handlePendingCommand(){
ReturnValue_t result;
if (!commandPending) {
return;
}
switch(heaterCommand.action) {
case SET_SWITCH_ON:
result = gpioInterface->pullHigh(heaterCommand.heaterSwitchNr);
if (result != RETURN_OK) {
triggerEvent()
}
if (heaterCommand.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterCommand.replyQueue, heaterCommand.action,
result);
}
commandPending = false;
break;
case SET_SWITCH_OFF:
result = gpioInterface->pullLow(heaterCommand.heaterSwitchNr);
if (heaterCommand.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterCommand.replyQueue, heaterCommand.action,
result);
}
commandPending = false;
break;
}
}

View File

@ -0,0 +1,132 @@
#ifndef MISSION_DEVICES_HEATERHANDLER_H_
#define MISSION_DEVICES_HEATERHANDLER_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/power/PowerSwitchIF.h>
/**
* @brief This class intends the control of heaters.
*
* @author J. Meier
*/
class HeaterHandler: public ExecutableObjectIF,
public PowerSwitchIF,
public SystemObject,
public HasActionsIF,
public HasModesIF,
public HasReturnvaluesIF {
public:
/** Command not in heaterCommandMap */
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
/** Heater mode is MODE_OFF */
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
/** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER;
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override;
virtual void sendFuseOnCommand(uint8_t fuseNr) override;
/**
* @brief This function will be called from the Heater object to check
* the current switch state.
*/
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) override;
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) override;
virtual uint32_t getSwitchDelayMs(void) override;
ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size)
override;
private:
static const MessageQueueId_t NO_COMMANDER = 0;
ReturnValue_t buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen);
ReturnValue_t acceptExternalDeviceCommands();
/**
* @brief This function runs commands waiting for execution.
*/
void handlePendingCommand();
/**
* @brief Struct holding information about a heater command to execute.
*
* @param action The action to perform.
* @param heaterSwitchNr The number of a switch which correlates with the
* GPIO to drive.
* @param replyQueue The queue of the commander to which status replies
* will be sent.
*/
typedef struct HeaterCommand {
HeaterCommand(uint8_t action_, uint8_t heaterSwitchNr,
MessageQueueId_t replyQueue_) {
action = action_;
heaterSwitchNr = heaterSwitchNr_;
replyQueue = replyQueue_;
}
uint8_t action;
uint8_t heaterSwitchNr;
MessageQueueId_t replyQueue;
} HeaterCommand_t;
enum SwitchAction {
SET_SWITCH_ON,
SET_SWITCH_OFF
};
/** This HeaterCommand instance holds the next heater command to execute */
HeaterCommand_t heaterCommand;
/**
* This variable is set when the command stored in heaterCommand shall be
* executed.
*/
bool commandPending;
/** Size of command queue */
size_t cmdQueueSize = 20;
/**
* Current mode of the HeaterHandler. Should only be changed with setMode().
*/
Mode_t mode;
/**
* Current submode of the HeaterHandler. Should only be change with
* setMode().
*/
Submode_t submode;
/**
* The object ID of the GPIO driver which enables and disables the
* heaters.
*/
object_id_t gpioDriverId;
GpioIF* gpioInterface;
/** 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 *powerSwitcher;
HeaterHandler();
virtual ~HeaterHandler();
};
#endif /* MISSION_DEVICES_HEATERHANDLER_H_ */

View File

@ -0,0 +1,18 @@
/*
* PCDUHandler.cpp
*
* Created on: 21.01.2021
* Author: jakob
*/
#include "PCDUHandler.h"
PCDUHandler::PCDUHandler() {
// TODO Auto-generated constructor stub
}
PCDUHandler::~PCDUHandler() {
// TODO Auto-generated destructor stub
}

View File

@ -0,0 +1,20 @@
/*
* PCDUHandler.h
*
* Created on: 21.01.2021
* Author: jakob
*/
#ifndef MISSION_DEVICES_PCDUHANDLER_H_
#define MISSION_DEVICES_PCDUHANDLER_H_
/**
* @brief
*/
class PCDUHandler: public PowerSwitchIF {
public:
PCDUHandler();
virtual ~PCDUHandler();
};
#endif /* MISSION_DEVICES_PCDUHANDLER_H_ */

View File

@ -0,0 +1,18 @@
/*
* PDU2Handler.cpp
*
* Created on: 23.01.2021
* Author: jakob
*/
#include "PDU2Handler.h"
PDU2Handler::PDU2Handler() {
// TODO Auto-generated constructor stub
}
PDU2Handler::~PDU2Handler() {
// TODO Auto-generated destructor stub
}

View File

@ -0,0 +1,26 @@
#ifndef MISSION_DEVICES_PDU2HANDLER_H_
#define MISSION_DEVICES_PDU2HANDLER_H_
#include "GomspaceDeviceHandler.h"
/**
* @brief This is the device handler for the PDU2.
*
* @details The PDU2 controls the
* power supply of the following devices:
* Xiphos Q7S, 8V, channel 0
* Reaction wheels 5V, channel 2
* TCS Board heater input, 8V, channel 3
* SUS, 3,3V, channel 4
* Deployment mechanism, 8V, channel 5
* P/L PCDU, 15,9V, channel 1 and channel 6
* ACS Board (Gyro, MGMs, GPS), 3,3V channel 7
* Payload Camera, 8V, channel 8
*/
class PDU2Handler: public GomspaceDeviceHandler {
public:
PDU2Handler();
virtual ~PDU2Handler();
};
#endif /* MISSION_DEVICES_PDU2HANDLER_H_ */

View File

@ -178,7 +178,8 @@ private:
* device*/
SerializeElement<uint8_t> action = 0x00; // get param
SerializeElement<uint8_t> tableId;
SerializeElement<uint16_t> addresslength; // size of address
/* Size of address. Set to 0 to get full table */
SerializeElement<uint16_t> addresslength;
SerializeElement<uint16_t> checksum;
SerializeElement<uint16_t> seq;
SerializeElement<uint16_t> total;