fixed merge conflicts

This commit is contained in:
2021-06-24 17:49:23 +02:00
195 changed files with 9106 additions and 3418 deletions

View File

@ -6,9 +6,6 @@ target_sources(${TARGET_NAME} PUBLIC
add_subdirectory(boardconfig)
add_subdirectory(comIF)
add_subdirectory(devices)
add_subdirectory(boardtest)
add_subdirectory(gpio)
add_subdirectory(core)

35
bsp_q7s/Dockerfile Normal file
View File

@ -0,0 +1,35 @@
FROM ubuntu:latest
# FROM alpine:latest
ENV TZ=Europe/Berlin
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y curl cmake g++
# Q7S root filesystem, required for cross-compilation. Use IPv6 for curl
RUN mkdir -p /usr/rootfs; \
curl -6 https://eive-cloud.irs.uni-stuttgart.de/index.php/s/dnfMy9kGpgynN6J/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz \
| tar xvz -C /usr/rootfs
# Q7S C++ cross-compiler. Use IPv6 for curl
RUN mkdir -p /usr/tools; \
curl -6 https://eive-cloud.irs.uni-stuttgart.de/index.php/s/RMsbHydJc6PSqcz/download/gcc-arm-linux-gnueabi.tar.gz \
| tar xvz -C /usr/tools
# RUN apk add cmake make g++
# Required for cmake build
ENV Q7S_SYSROOT="/usr/rootfs/cortexa9hf-neon-xiphos-linux-gnueabi"
ENV PATH=$PATH:"/usr/tools/gcc-arm-linux-gnueabi/bin"
WORKDIR /usr/src/app
COPY . .
RUN set -ex; \
rm -rf build-q7s; \
mkdir build-q7s; \
cd build-q7s; \
cmake -DCMAKE_BUILD_TYPE=Release -DOS_FSFW=linux -DTGT_BSP="arm/q7s" ..;
ENTRYPOINT ["cmake", "--build", "build-q7s"]
CMD ["-j"]
# CMD ["bash"]

View File

@ -1,6 +1,7 @@
#include "InitMission.h"
#include "ObjectFactory.h"
#include <OBSWConfig.h>
#include "OBSWConfig.h"
#include "pollingsequence/pollingSequenceFactory.h"
#include <mission/utility/InitMission.h>
@ -11,7 +12,7 @@
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfwconfig/pollingsequence/pollingSequenceFactory.h>
#include <iostream>
/* This is configured for linux without CR */
@ -30,11 +31,12 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true);
ObjectManagerIF *objectManager = nullptr;
void initmission::initMission() {
sif::info << "Building global objects.." << std::endl;
/* Instantiate global object manager and also create all objects */
objectManager = new ObjectManager(ObjectFactory::produce);
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
sif::info << "Initializing all objects.." << std::endl;
objectManager->initialize();
ObjectManager::instance()->initialize();
/* This function creates and starts all tasks */
initTasks();
@ -83,6 +85,15 @@ void initmission::initTasks() {
initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK);
}
#if TEST_CCSDS_BRIDGE == 1
PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask(
"PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE);
}
#endif
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
@ -134,30 +145,51 @@ void initmission::initTasks() {
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST);
}
result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER);
}
#if TE0720 == 0
//TODO: Add handling of missed deadlines
/* Polling Sequence Table Default */
#if Q7S_ADD_SPI_TEST == 0
FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask(
"PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
FixedTimeslotTaskIF* spiPst = factory->createFixedTimeslotTask(
"PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
missedDeadlineFunc);
result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault);
result = pst::pstSpi(spiPst);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
#endif
FixedTimeslotTaskIF* gomSpacePstTask = factory->
createFixedTimeslotTask("GS_PST_TASK", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 1.0, missedDeadlineFunc);
result = pst::gomspacePstInit(gomSpacePstTask);
FixedTimeslotTaskIF* uartPst = factory->createFixedTimeslotTask(
"UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc);
result = pst::pstUart(uartPst);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
FixedTimeslotTaskIF* gpioPst = factory->createFixedTimeslotTask(
"GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc);
result = pst::pstGpio(gpioPst);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
FixedTimeslotTaskIF* i2cPst = factory->createFixedTimeslotTask(
"I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc);
result = pst::pstI2c(i2cPst);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
FixedTimeslotTaskIF* gomSpacePstTask = factory->createFixedTimeslotTask(
"GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc);
result = pst::pstGompaceCan(gomSpacePstTask);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl;
}
#else
#else /* TE7020 == 0 */
FixedTimeslotTaskIF * pollingSequenceTaskTE0720 = factory->createFixedTimeslotTask(
"PST_TASK_TE0720", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE * 8, 3.0,
missedDeadlineFunc);
@ -165,7 +197,7 @@ void initmission::initTasks() {
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating TE0720 PST failed!" << std::endl;
}
#endif
#endif /* TE7020 == 1 */
#if OBSW_ADD_TEST_CODE == 1
PeriodicTaskIF* testTask = factory->createPeriodicTask(
@ -194,9 +226,15 @@ void initmission::initTasks() {
udpBridgeTask->startTask();
udpPollingTask->startTask();
#if TE0720 == 0 && Q7S_ADD_SPI_TEST == 0
#if TE0720 == 0
uartPst->startTask();
gpioPst->startTask();
i2cPst->startTask();
#if Q7S_ADD_SPI_TEST == 0
gomSpacePstTask->startTask();
pollingSequenceTableTaskDefault->startTask();
spiPst->startTask();
#endif /* Q7S_ADD_SPI_TEST == 0 */
#elif TE0720 == 1 && Q7S_ADD_SPI_TEST == 0
pollingSequenceTaskTE0720->startTask();
#endif
@ -210,5 +248,9 @@ void initmission::initTasks() {
#if OBSW_ADD_TEST_CODE == 1
testTask->startTask();
#endif
#if TEST_CCSDS_BRIDGE == 1
ptmeTestTask->startTask();
#endif
sif::info << "Tasks started.." << std::endl;
}

View File

@ -1,15 +1,21 @@
#include "ObjectFactory.h"
#include <OBSWConfig.h>
#include <tmtc/apid.h>
#include <devices/addresses.h>
#include <devices/gpioIds.h>
#include <tmtc/pusIds.h>
#include <devices/powerSwitcherList.h>
#include <devices/spi.h>
#include "OBSWConfig.h"
#include "tmtc/apid.h"
#include "devices/addresses.h"
#include "devices/gpioIds.h"
#include "tmtc/pusIds.h"
#include "devices/powerSwitcherList.h"
#include "spiConf.h"
#include <bsp_q7s/devices/HeaterHandler.h>
#include <bsp_q7s/devices/SolarArrayDeploymentHandler.h>
#include <bsp_q7s/gpio/gpioCallbacks.h>
#include "bsp_q7s/gpio/gpioCallbacks.h"
#include "bsp_q7s/core/CoreController.h"
#include <linux/devices/HeaterHandler.h>
#include <linux/devices/SolarArrayDeploymentHandler.h>
#include <linux/devices/devicedefinitions/SusDefinitions.h>
#include <linux/devices/SusHandler.h>
#include <linux/csp/CspCookie.h>
#include <linux/csp/CspComIF.h>
#include <mission/core/GenericFactory.h>
#include <mission/devices/PDU1Handler.h>
@ -23,25 +29,19 @@
#include <mission/devices/SyrlinksHkHandler.h>
#include <mission/devices/MGMHandlerLIS3MDL.h>
#include <mission/devices/MGMHandlerRM3100.h>
#include <mission/devices/GyroL3GD20Handler.h>
#include <mission/devices/PlocHandler.h>
#include <mission/devices/RadiationSensorHandler.h>
#include <mission/devices/SusHandler.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/devices/devicedefinitions/SyrlinksDefinitions.h>
#include <mission/devices/devicedefinitions/PlocDefinitions.h>
#include <mission/devices/devicedefinitions/RadSensorDefinitions.h>
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
#include <mission/devices/devicedefinitions/SusDefinitions.h>
#include <mission/utility/TmFunnel.h>
#include <linux/obc/CCSDSIPCoreBridge.h>
#include <linux/csp/CspCookie.h>
#include <linux/csp/CspComIF.h>
#include <linux/uart/UartComIF.h>
#include <linux/uart/UartCookie.h>
#include "fsfw_hal/linux/uart/UartComIF.h"
#include "fsfw_hal/linux/uart/UartCookie.h"
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
#include <fsfw_hal/linux/i2c/I2cCookie.h>
#include <fsfw_hal/linux/i2c/I2cComIF.h>
#include <fsfw_hal/linux/spi/SpiCookie.h>
@ -52,7 +52,7 @@
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#include <fsfw/tmtcpacket/pus/tm.h>
/* UDP server includes */
#include <fsfw/osal/common/UdpTmTcBridge.h>
@ -82,9 +82,20 @@ void Factory::setStaticFrameworkObjectIds() {
void ObjectFactory::produce(){
void ObjectFactory::produce(void* args){
Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects();
LinuxLibgpioIF* gpioComIF = new LinuxLibgpioIF(objects::GPIO_IF);
/* Communication interfaces */
new CspComIF(objects::CSP_COM_IF);
new I2cComIF(objects::I2C_COM_IF);
new UartComIF(objects::UART_COM_IF);
#if Q7S_ADD_SPI_TEST == 0
new SpiComIF(objects::SPI_COM_IF, gpioComIF);
#endif /* Q7S_ADD_SPI_TEST == 0 */
new CoreController(objects::CORE_CONTROLLER);
#if TE0720 == 1
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
@ -97,15 +108,6 @@ void ObjectFactory::produce(){
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
#endif
LinuxLibgpioIF* gpioComIF = new LinuxLibgpioIF(objects::GPIO_IF);
/* Communication interfaces */
new CspComIF(objects::CSP_COM_IF);
new I2cComIF(objects::I2C_COM_IF);
new UartComIF(objects::UART_COM_IF);
#if Q7S_ADD_SPI_TEST == 0
new SpiComIF(objects::SPI_COM_IF, gpioComIF);
#endif /* Q7S_ADD_SPI_TEST == 0 */
/* Temperature sensors */
Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(
@ -389,8 +391,8 @@ void ObjectFactory::produce(){
solarArrayDeplCookie, objects::PCDU_HANDLER, pcduSwitches::DEPLOYMENT_MECHANISM,
gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000);
UartCookie* syrlinksUartCookie = new UartCookie(
std::string("/dev/ttyUL0"), 38400, SYRLINKS::MAX_REPLY_SIZE);
UartCookie* syrlinksUartCookie = new UartCookie(objects::SYRLINKS_HK_HANDLER,
std::string("/dev/ttyUL0"), UartModes::NON_CANONICAL, 38400, SYRLINKS::MAX_REPLY_SIZE);
syrlinksUartCookie->setParityEven();
SyrlinksHkHandler* syrlinksHkHandler = new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER,
@ -453,7 +455,7 @@ void ObjectFactory::produce(){
SpiCookie* spiRtdIc3 = new SpiCookie(addresses::RTD_IC3, gpioIds::RTD_IC3,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
spi::SpiModes::MODE_3, 2000000);
SpiCookie* spiRtdIc4 = new SpiCookie(addresses::RTD_IC4, gpioIds::RTD_IC4,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
@ -489,7 +491,7 @@ void ObjectFactory::produce(){
spi::SpiModes::MODE_1, 2000000);
SpiCookie* spiRtdIc15 = new SpiCookie(addresses::RTD_IC15, gpioIds::RTD_IC15,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
spi::SpiModes::MODE_1, 3900000);
SpiCookie* spiRtdIc16 = new SpiCookie(addresses::RTD_IC16, gpioIds::RTD_IC16,
std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE,
spi::SpiModes::MODE_1, 2000000);
@ -516,7 +518,11 @@ void ObjectFactory::produce(){
Max31865PT1000Handler* rtdIc16 = new Max31865PT1000Handler(objects::RTD_IC16, objects::SPI_COM_IF, spiRtdIc16, 0);
Max31865PT1000Handler* rtdIc17 = new Max31865PT1000Handler(objects::RTD_IC17, objects::SPI_COM_IF, spiRtdIc17, 0);
Max31865PT1000Handler* rtdIc18 = new Max31865PT1000Handler(objects::RTD_IC18, objects::SPI_COM_IF, spiRtdIc18, 0);
<<<<<<< HEAD
rtdIc3->setStartUpImmediately();
=======
rtdIc17->setStartUpImmediately();
>>>>>>> develop
// rtdIc4->setStartUpImmediately();
(void) rtdIc3;
@ -533,19 +539,17 @@ void ObjectFactory::produce(){
(void) rtdIc14;
(void) rtdIc15;
(void) rtdIc16;
(void) rtdIc17;
// (void) rtdIc17;
(void) rtdIc18;
#endif /* Q7S_ADD_RTD_DEVICES == 1 */
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE,
std::string("/dev/i2c-0"));
IMTQHandler* imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie);
// imtqHandler->setStartUpImmediately();
(void) imtqHandler;
new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie);
UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyUL3"), 115200,
PLOC::MAX_REPLY_SIZE);
UartCookie* plocUartCookie = new UartCookie(objects::PLOC_HANDLER, std::string("/dev/ttyUL3"),
UartModes::NON_CANONICAL, 115200, PLOC::MAX_REPLY_SIZE);
PlocHandler* plocHandler = new PlocHandler(objects::PLOC_HANDLER, objects::UART_COM_IF,
plocUartCookie);
// plocHandler->setStartUpImmediately();
@ -553,8 +557,7 @@ void ObjectFactory::produce(){
#endif /* TE0720 == 0 */
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE,
objects::TC_STORE);
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
#if TE0720 == 1 && TEST_LIBGPIOD == 1
@ -576,9 +579,22 @@ void ObjectFactory::produce(){
SpiCookie* spiCookieSus = new SpiCookie(addresses::SUS_1, std::string("/dev/spidev1.0"),
SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED);
SusHandler* sus1 = new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus, gpioComIF,
new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus, gpioComIF,
gpioIds::CS_SUS_1);
sus1->setStartUpImmediately();
#endif
#if TE0720 == 1 && TEST_CCSDS_BRIDGE == 1
GpioCookie* gpioCookieCcsdsIp = new GpioCookie;
GpiodRegular* papbBusyN = new GpiodRegular(std::string("gpiochip0"), 0, std::string("PAPBBusy_N"));
gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_BUSY_N, papbBusyN);
GpiodRegular* papbEmpty = new GpiodRegular(std::string("gpiochip0"), 1,
std::string("Chip Select Sus Sensor"));
gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_EMPTY, papbEmpty);
gpioComIF->addGpios(gpioCookieCcsdsIp);
new CCSDSIPCoreBridge(objects::CCSDS_IP_CORE_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE, gpioComIF, std::string("/dev/uio0"),
gpioIds::PAPB_BUSY_N, gpioIds::PAPB_EMPTY);
#endif
#if TE0720 == 1 && TEST_RADIATION_SENSOR_HANDLER == 1

View File

@ -3,7 +3,7 @@
namespace ObjectFactory {
void setStatics();
void produce();
void produce(void* args);
};
#endif /* BSP_Q7S_OBJECTFACTORY_H_ */

View File

@ -5,6 +5,3 @@ target_sources(${TARGET_NAME} PRIVATE
target_include_directories(${TARGET_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,13 +1,13 @@
#ifndef BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_
#define BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_
#define Q7S_ADD_RTD_DEVICES 1
#define Q7S_ADD_RTD_DEVICES 0
/* Only one of those 2 should be enabled! */
/* Add code for ACS board */
#define OBSW_ADD_ACS_BOARD 0
#if OBSW_ADD_ACS_BOARD == 0
#define Q7S_ADD_SPI_TEST 0
#endif
#endif /* BSP_Q7S_BOARDCONFIG_Q7S_CONFIG_H_ */

View File

@ -0,0 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
CoreController.cpp
)

View File

@ -0,0 +1,26 @@
#include "CoreController.h"
CoreController::CoreController(object_id_t objectId):
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
}
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
return HasReturnvaluesIF::RETURN_OK;
}
void CoreController::performControlOperation() {
}
ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
return HasReturnvaluesIF::RETURN_OK;
}
LocalPoolDataSetBase* CoreController::getDataSetHandle(sid_t sid) {
return nullptr;
}
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,22 @@
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
#define BSP_Q7S_CORE_CORECONTROLLER_H_
#include "fsfw/controller/ExtendedControllerBase.h"
class CoreController: public ExtendedControllerBase {
public:
CoreController(object_id_t objectId);
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
void performControlOperation() override;
private:
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode);
};
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */

View File

@ -1,4 +0,0 @@
target_sources(${TARGET_NAME} PRIVATE
HeaterHandler.cpp
SolarArrayDeploymentHandler.cpp
)

View File

@ -1,371 +0,0 @@
#include "HeaterHandler.h"
#include <fsfwconfig/devices/powerSwitcherList.h>
#include <fsfw/ipc/QueueFactory.h>
#include <devices/gpioIds.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_,
CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) :
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
actionHelper(this, nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
HeaterHandler::~HeaterHandler() {
}
ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
readCommandQueue();
handleActiveCommands();
return RETURN_OK;
}
return RETURN_OK;
}
ReturnValue_t HeaterHandler::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = initializeHeaterMap();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
if (gpioInterface == nullptr) {
sif::error << "HeaterHandler::initialize: Invalid Gpio interface." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
if (result != RETURN_OK) {
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) {
sif::error << "HeaterHandler::initialize: IPC store not set up in factory." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if(mainLineSwitcherObjectId != objects::NO_OBJECT) {
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
if (mainLineSwitcher == nullptr) {
sif::error
<< "HeaterHandler::initialize: Failed to get main line switcher. Make sure "
<< "main line switcher object is initialized." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
return RETURN_OK;
}
ReturnValue_t HeaterHandler::initializeHeaterMap(){
HeaterCommandInfo_t heaterCommandInfo;
for(switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
std::pair status = heaterMap.emplace(switchNr, heaterCommandInfo);
if (status.second == false) {
sif::error << "HeaterHandler::initializeHeaterMap: Failed to initialize heater map"
<< std::endl;
return RETURN_FAILED;
}
}
return RETURN_OK;
}
void HeaterHandler::setInitialSwitchStates() {
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
switchStates[switchNr] = OFF;
}
}
void HeaterHandler::readCommandQueue() {
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&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;
if (actionId != SWITCH_HEATER) {
result = COMMAND_NOT_SUPPORTED;
} else {
switchNr_t switchNr = *data;
HeaterMapIter heaterMapIter = heaterMap.find(switchNr);
if (heaterMapIter != heaterMap.end()) {
if (heaterMapIter->second.active) {
return COMMAND_ALREADY_WAITING;
}
heaterMapIter->second.action = *(data + 1);
heaterMapIter->second.active = true;
heaterMapIter->second.replyQueue = commandedBy;
}
else {
sif::error << "HeaterHandler::executeAction: Invalid switchNr" << std::endl;
return INVALID_SWITCH_NR;
}
result = RETURN_OK;
}
return result;
}
void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
ReturnValue_t onOff) const {
ReturnValue_t result;
store_address_t storeAddress;
uint8_t commandData[2];
switch(onOff) {
case PowerSwitchIF::SWITCH_ON:
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_ON;
break;
case PowerSwitchIF::SWITCH_OFF:
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_OFF;
break;
default:
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request"
<< std::endl;
break;
}
result = IPCStore->addData(&storeAddress, commandData, sizeof(commandData));
if (result == RETURN_OK) {
CommandMessage message;
ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress);
/* Send heater command to own command queue */
result = commandQueue->sendMessage(commandQueue->getId(), &message, 0);
if (result != RETURN_OK) {
sif::debug << "HeaterHandler::sendSwitchCommand: Failed to send switch"
<< "message" << std::endl;
}
}
}
void HeaterHandler::handleActiveCommands(){
HeaterMapIter heaterMapIter = heaterMap.begin();
for (; heaterMapIter != heaterMap.end(); heaterMapIter++) {
if (heaterMapIter->second.active) {
switch(heaterMapIter->second.action) {
case SET_SWITCH_ON:
handleSwitchOnCommand(heaterMapIter);
break;
case SET_SWITCH_OFF:
handleSwitchOffCommand(heaterMapIter);
break;
default:
sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded"
<< std::endl;
break;
}
}
}
}
void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) {
ReturnValue_t result = RETURN_OK;
switchNr_t switchNr;
/* Check if command waits for main switch being set on and whether the timeout has expired */
if (heaterMapIter->second.waitMainSwitchOn
&& heaterMapIter->second.mainSwitchCountdown.hasTimedOut()) {
//TODO - This requires the initiation of an FDIR procedure
triggerEvent(MAIN_SWITCH_TIMEOUT);
sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout"
<< std::endl;
heaterMapIter->second.active = false;
heaterMapIter->second.waitMainSwitchOn = false;
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, MAIN_SWITCH_SET_TIMEOUT );
}
return;
}
switchNr = heaterMapIter->first;
/* Check state of main line switch */
ReturnValue_t mainSwitchState = mainLineSwitcher->getSwitchState(mainLineSwitch);
if (mainSwitchState == PowerSwitchIF::SWITCH_ON) {
if (!checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullHigh(gpioId);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id "
<< gpioId << " high" << std::endl;
triggerEvent(GPIO_PULL_HIGH_FAILED, result);
}
else {
switchStates[switchNr] = ON;
}
}
else {
triggerEvent(SWITCH_ALREADY_ON, switchNr);
}
/* There is no need to send action finish replies if the sender was the
* HeaterHandler itself. */
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
if(result == RETURN_OK) {
actionHelper.finish(true, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
else {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
}
heaterMapIter->second.active = false;
heaterMapIter->second.waitMainSwitchOn = false;
}
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF
&& heaterMapIter->second.waitMainSwitchOn) {
/* Just waiting for the main switch being set on */
return;
}
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF) {
mainLineSwitcher->sendSwitchCommand(mainLineSwitch,
PowerSwitchIF::SWITCH_ON);
heaterMapIter->second.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
heaterMapIter->second.waitMainSwitchOn = true;
}
else {
sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of"
<< " main line switch" << std::endl;
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, mainSwitchState);
}
heaterMapIter->second.active = false;
}
}
void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) {
ReturnValue_t result = RETURN_OK;
switchNr_t switchNr = heaterMapIter->first;
/* Check whether switch is already off */
if (checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullLow(gpioId);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id"
<< gpioId << " low" << std::endl;
triggerEvent(GPIO_PULL_LOW_FAILED, result);
}
else {
switchStates[switchNr] = OFF;
/* When all switches are off, also main line switch will be turned off */
if (allSwitchesOff()) {
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
}
}
}
else {
sif::info << "HeaterHandler::handleSwitchOffCommand: Switch already off" << std::endl;
triggerEvent(SWITCH_ALREADY_OFF, switchNr);
}
if (heaterMapIter->second.replyQueue != NO_COMMANDER) {
/* Report back switch command reply if necessary */
if(result == HasReturnvaluesIF::RETURN_OK) {
actionHelper.finish(true, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
else {
actionHelper.finish(false, heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
}
heaterMapIter->second.active = false;
}
bool HeaterHandler::checkSwitchState(int switchNr) {
return switchStates[switchNr];
}
bool HeaterHandler::allSwitchesOff() {
bool allSwitchesOrd = false;
/* Or all switches. As soon one switch is on, allSwitchesOrd will be true */
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
allSwitchesOrd = allSwitchesOrd || switchStates[switchNr];
}
return !allSwitchesOrd;
}
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) {
gpioId_t gpioId = 0xFFFF;
switch(switchNr) {
case heaterSwitches::HEATER_0:
gpioId = gpioIds::HEATER_0;
break;
case heaterSwitches::HEATER_1:
gpioId = gpioIds::HEATER_1;
break;
case heaterSwitches::HEATER_2:
gpioId = gpioIds::HEATER_2;
break;
case heaterSwitches::HEATER_3:
gpioId = gpioIds::HEATER_3;
break;
case heaterSwitches::HEATER_4:
gpioId = gpioIds::HEATER_4;
break;
case heaterSwitches::HEATER_5:
gpioId = gpioIds::HEATER_5;
break;
case heaterSwitches::HEATER_6:
gpioId = gpioIds::HEATER_6;
break;
case heaterSwitches::HEATER_7:
gpioId = gpioIds::HEATER_7;
break;
default:
sif::error << "HeaterHandler::getGpioIdFromSwitchNr: Unknown heater switch number"
<< std::endl;
break;
}
return gpioId;
}
MessageQueueId_t HeaterHandler::getCommandQueue() const {
return commandQueue->getId();
}
void HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) const {
}
ReturnValue_t HeaterHandler::getSwitchState( uint8_t switchNr ) const {
return 0;
}
ReturnValue_t HeaterHandler::getFuseState( uint8_t fuseNr ) const {
return 0;
}
uint32_t HeaterHandler::getSwitchDelayMs(void) const {
return 0;
}

View File

@ -1,177 +0,0 @@
#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/power/PowerSwitchIF.h>
#include <fsfwconfig/devices/heaterSwitcherList.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <unordered_map>
/**
* @brief This class intends the control of heaters.
*
* @author J. Meier
*/
class HeaterHandler: public ExecutableObjectIF,
public PowerSwitchIF,
public SystemObject,
public HasActionsIF {
public:
/** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER = 0x0;
HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF * gpioCookie,
object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch);
virtual ~HeaterHandler();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override;
virtual void sendFuseOnCommand(uint8_t fuseNr) const override;
/**
* @brief This function will be called from the Heater object to check
* the current switch state.
*/
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) const override;
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) const override;
virtual uint32_t getSwitchDelayMs(void) const override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
virtual ReturnValue_t initialize() override;
private:
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);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER_HANDLER;
static const Event GPIO_PULL_HIGH_FAILED = MAKE_EVENT(0, severity::LOW);
static const Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
static const Event SWITCH_ALREADY_ON = MAKE_EVENT(2, severity::LOW);
static const Event SWITCH_ALREADY_OFF = MAKE_EVENT(3, severity::LOW);
static const Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(4, severity::LOW);
static const MessageQueueId_t NO_COMMANDER = 0;
enum SwitchState : bool {
ON = true,
OFF = false
};
/**
* @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.
*/
typedef struct HeaterCommandInfo {
uint8_t action;
MessageQueueId_t replyQueue;
bool active = false;
bool waitMainSwitchOn = false;
Countdown mainSwitchCountdown;
} HeaterCommandInfo_t;
enum SwitchAction {
SET_SWITCH_OFF,
SET_SWITCH_ON
};
using switchNr_t = uint8_t;
using HeaterMap = std::unordered_map<switchNr_t, HeaterCommandInfo_t>;
using HeaterMapIter = HeaterMap::iterator;
HeaterMap heaterMap;
bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES];
/** Size of command queue */
size_t cmdQueueSize = 20;
/**
* The object ID of the GPIO driver which enables and disables the
* heaters.
*/
object_id_t gpioDriverId;
CookieIF * gpioCookie;
GpioIF* gpioInterface = nullptr;
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
object_id_t mainLineSwitcherObjectId;
/** Switch number of the heater power supply switch */
uint8_t mainLineSwitch;
/**
* Power switcher object which controls the 8V main line of the heater
* logic on the TCS board.
*/
PowerSwitchIF *mainLineSwitcher = nullptr;
ActionHelper actionHelper;
StorageManagerIF *IPCStore = nullptr;
void readCommandQueue();
/**
* @brief Returns the state of a switch (ON - true, or OFF - false).
* @param switchNr The number of the switch to check.
*/
bool checkSwitchState(int switchNr);
/**
* @brief Returns the ID of the GPIO related to a heater identified by the switch number
* which is defined in the heaterSwitches list.
*/
gpioId_t getGpioIdFromSwitchNr(int switchNr);
/**
* @brief This function runs commands waiting for execution.
*/
void handleActiveCommands();
ReturnValue_t initializeHeaterMap();
/**
* @brief Sets all switches to OFF.
*/
void setInitialSwitchStates();
void handleSwitchOnCommand(HeaterMapIter heaterMapIter);
void handleSwitchOffCommand(HeaterMapIter heaterMapIter);
/**
* @brief Checks if all switches are off.
* @return True if all switches are off, otherwise false.
*/
bool allSwitchesOff();
};
#endif /* MISSION_DEVICES_HEATERHANDLER_H_ */

View File

@ -1,201 +0,0 @@
#include "SolarArrayDeploymentHandler.h"
#include <devices/powerSwitcherList.h>
#include <devices/gpioIds.h>
#include <fsfw_hal/common/gpio/GpioCookie.h>
#include <fsfw/ipc/QueueFactory.h>
SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_,
object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_,
uint8_t mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) :
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
deplSA1(deplSA1), deplSA2(deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {
}
ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) {
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
handleStateMachine();
return RETURN_OK;
}
return RETURN_OK;
}
ReturnValue_t SolarArrayDeploymentHandler::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
if (gpioInterface == nullptr) {
sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface."
<< std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
if (result != RETURN_OK) {
sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface"
<< std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if (mainLineSwitcherObjectId != objects::NO_OBJECT) {
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
if (mainLineSwitcher == nullptr) {
sif::error
<< "SolarArrayDeploymentHandler::initialize: Main line switcher failed to fetch object"
<< "from object ID." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
return RETURN_OK;
}
void SolarArrayDeploymentHandler::handleStateMachine() {
switch (stateMachine) {
case WAIT_ON_DELOYMENT_COMMAND:
readCommandQueue();
break;
case SWITCH_8V_ON:
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON);
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
stateMachine = WAIT_ON_8V_SWITCH;
break;
case WAIT_ON_8V_SWITCH:
performWaitOn8VActions();
break;
case SWITCH_DEPL_GPIOS:
switchDeploymentTransistors();
break;
case WAIT_ON_DEPLOYMENT_FINISH:
handleDeploymentFinish();
break;
case WAIT_FOR_MAIN_SWITCH_OFF:
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) {
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
} else if (mainSwitchCountdown.hasTimedOut()) {
triggerEvent(MAIN_SWITCH_OFF_TIMEOUT);
sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main"
<< " switch off" << std::endl;
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
}
break;
default:
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl;
break;
}
}
void SolarArrayDeploymentHandler::performWaitOn8VActions() {
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) {
stateMachine = SWITCH_DEPL_GPIOS;
} else {
if (mainSwitchCountdown.hasTimedOut()) {
triggerEvent(MAIN_SWITCH_ON_TIMEOUT);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
MAIN_SWITCH_TIMEOUT_FAILURE);
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
}
}
}
void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
ReturnValue_t result = RETURN_OK;
result = gpioInterface->pullHigh(deplSA1);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 1 high " << std::endl;
/* If gpio switch high failed, state machine is reset to wait for a command reinitiating
* the deployment sequence. */
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
SWITCHING_DEPL_SA2_FAILED);
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
}
result = gpioInterface->pullHigh(deplSA2);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 2 high " << std::endl;
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
SWITCHING_DEPL_SA2_FAILED);
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
}
deploymentCountdown.setTimeout(burnTimeMs);
stateMachine = WAIT_ON_DEPLOYMENT_FINISH;
}
void SolarArrayDeploymentHandler::handleDeploymentFinish() {
ReturnValue_t result = RETURN_OK;
if (deploymentCountdown.hasTimedOut()) {
actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK);
result = gpioInterface->pullLow(deplSA1);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 1 low " << std::endl;
}
result = gpioInterface->pullLow(deplSA2);
if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
" array deployment switch 2 low " << std::endl;
}
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
stateMachine = WAIT_FOR_MAIN_SWITCH_OFF;
}
}
void SolarArrayDeploymentHandler::readCommandQueue() {
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
result = actionHelper.handleActionMessage(&command);
if (result == RETURN_OK) {
return;
}
}
ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
ReturnValue_t result;
if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) {
sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in"
<< "waiting-on-command-state" << std::endl;
return DEPLOYMENT_ALREADY_EXECUTING;
}
if (actionId != DEPLOY_SOLAR_ARRAYS) {
sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command"
<< std::endl;
result = COMMAND_NOT_SUPPORTED;
} else {
stateMachine = SWITCH_8V_ON;
rememberCommanderId = commandedBy;
result = RETURN_OK;
}
return result;
}
MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const {
return commandQueue->getId();
}

View File

@ -1,158 +0,0 @@
#ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <unordered_map>
/**
* @brief This class is used to control the solar array deployment.
*
* @author J. Meier
*/
class SolarArrayDeploymentHandler: public ExecutableObjectIF,
public SystemObject,
public HasReturnvaluesIF,
public HasActionsIF {
public:
static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5;
/**
* @brief constructor
*
* @param setObjectId The object id of the SolarArrayDeploymentHandler.
* @param gpioDriverId The id of the gpio com if.
* @param gpioCookie GpioCookie holding information about the gpios used to switch the
* transistors.
* @param mainLineSwitcherObjectId The object id of the object responsible for switching
* the 8V power source. This is normally the PCDU.
* @param mainLineSwitch The id of the main line switch. This is defined in
* powerSwitcherList.h.
* @param deplSA1 gpioId of the GPIO controlling the deployment 1 transistor.
* @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor.
* @param burnTimeMs Time duration the power will be applied to the burn wires.
*/
SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId,
CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch,
gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs);
virtual ~SolarArrayDeploymentHandler();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
virtual ReturnValue_t initialize() override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER;
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
static const ReturnValue_t DEPLOYMENT_ALREADY_EXECUTING = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t MAIN_SWITCH_TIMEOUT_FAILURE = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t SWITCHING_DEPL_SA1_FAILED = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER;
static const Event MAIN_SWITCH_ON_TIMEOUT = MAKE_EVENT(0, severity::LOW);
static const Event MAIN_SWITCH_OFF_TIMEOUT = MAKE_EVENT(1, severity::LOW);
static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH);
static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH);
static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH);
enum StateMachine {
WAIT_ON_DELOYMENT_COMMAND,
SWITCH_8V_ON,
WAIT_ON_8V_SWITCH,
SWITCH_DEPL_GPIOS,
WAIT_ON_DEPLOYMENT_FINISH,
WAIT_FOR_MAIN_SWITCH_OFF
};
StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND;
/**
* This countdown is used to check if the PCDU sets the 8V line on in the intended time.
*/
Countdown mainSwitchCountdown;
/**
* This countdown is used to wait for the burn wire being successful cut.
*/
Countdown deploymentCountdown;
/**
* The message queue id of the component commanding an action will be stored in this variable.
* This is necessary to send later the action finish replies.
*/
MessageQueueId_t rememberCommanderId = 0;
/** Size of command queue */
size_t cmdQueueSize = 20;
/** The object ID of the GPIO driver which switches the deployment transistors */
object_id_t gpioDriverId;
CookieIF * gpioCookie;
/** Object id of the object responsible to switch the 8V power input. Typically the PCDU. */
object_id_t mainLineSwitcherObjectId;
/** Switch number of the 8V power switch */
uint8_t mainLineSwitch;
gpioId_t deplSA1;
gpioId_t deplSA2;
GpioIF* gpioInterface = nullptr;
/** Time duration switches are active to cut the burn wire */
uint32_t burnTimeMs;
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
/**
* After initialization this pointer will hold the reference to the main line switcher object.
*/
PowerSwitchIF *mainLineSwitcher = nullptr;
ActionHelper actionHelper;
void readCommandQueue();
/**
* @brief This function performs actions dependent on the current state.
*/
void handleStateMachine();
/**
* @brief This function polls the 8V switch state and changes the state machine when the
* switch has been enabled.
*/
void performWaitOn8VActions();
/**
* @brief This functions handles the switching of the solar array deployment transistors.
*/
void switchDeploymentTransistors();
/**
* @brief This function performs actions to finish the deployment. Essentially switches
* are turned of after the burn time has expired.
*/
void handleDeploymentFinish();
};
#endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */

View File

@ -0,0 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
FileSystemManager.cpp
SdCardAccess.cpp
)

View File

@ -0,0 +1,7 @@
#include "FileSystemManager.h"
class FileSystemManager {
public:
private:
};

View File

@ -0,0 +1,8 @@
#ifndef BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_
#define BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_
#endif /* BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_ */

View File

@ -0,0 +1,4 @@
#include "SdCardAccess.h"
SdCardAccess::SdCardAccess() {
}

View File

@ -0,0 +1,11 @@
#ifndef BSP_Q7S_MEMORY_SDCARDACCESS_H_
#define BSP_Q7S_MEMORY_SDCARDACCESS_H_
class SdCardAccess {
public:
SdCardAccess();
private:
};
#endif /* BSP_Q7S_MEMORY_SDCARDACCESS_H_ */