From fd1e4f347320f3702885a033b7f9183630b9d2fa Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 1 Feb 2021 11:17:20 +0100 Subject: [PATCH] commanding of HeaterHandler and GpioIF working --- bsp_q7s/ObjectFactory.cpp | 14 +- bsp_q7s/gpio/GpioIF.h | 2 +- bsp_q7s/gpio/LinuxLibgpioIF.cpp | 65 +++--- bsp_q7s/gpio/LinuxLibgpioIF.h | 8 +- bsp_q7s/gpio/cookies/GpioCookie.cpp | 11 +- bsp_q7s/gpio/cookies/GpioCookie.h | 5 +- cmake/Q7SCrossCompileConfig.cmake | 13 +- fsfwconfig/OBSWConfig.h | 2 +- fsfwconfig/devices/heaterSwitcherList.h | 2 +- fsfwconfig/devices/powerSwitcherList.h | 34 ++- mission/devices/ACUHandler.cpp | 2 +- mission/devices/GomspaceDeviceHandler.cpp | 6 +- mission/devices/HeaterHandler.cpp | 198 ++++++++++++------ mission/devices/HeaterHandler.h | 172 ++++++++------- mission/devices/PCDUHandler.cpp | 140 +++++++++---- mission/devices/PCDUHandler.h | 27 ++- mission/devices/PDU1Handler.cpp | 11 +- mission/devices/PDU2Handler.cpp | 6 + .../devicedefinitions/GomSpacePackets.h | 18 +- tmtc | 2 +- 20 files changed, 474 insertions(+), 264 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 45529c33..bbfea341 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include #include @@ -19,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -102,19 +105,20 @@ void ObjectFactory::produce(){ tmp1075Handler_2->setStartUpImmediately(); /* Thermal objects */ - GpioCookie gpioCookie = new GpioCookie; + GpioCookie* gpioCookie = new GpioCookie; #if TE0720 == 1 // Configuration for MIO0 on TE0720-03-1CFA GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0, std::string("Heater0"), Gpio::OUT); - gpioCookie.add(gpioIds::HEATER_0, gpioConfigForDummyHeater); + gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); #else GpioConfig_t gpioConfigHeater0(std::string("gpiochip5"), 6, std::string("Heater0"), Gpio::OUT); - gpioCookie.add(gpioIds::HEATER_0, gpioConfigHeater0); + gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0); #endif - LinuxLibgpioIF linuxLibgpioIF = new LinuxLibgpioIF(objects::GPIO_IF); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie); + new LinuxLibgpioIF(objects::GPIO_IF); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, + pcduSwitches::TCS_BOARD_8V_HEATER_IN); new TmTcUnixUdpBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR, diff --git a/bsp_q7s/gpio/GpioIF.h b/bsp_q7s/gpio/GpioIF.h index 313351fb..cf688db8 100644 --- a/bsp_q7s/gpio/GpioIF.h +++ b/bsp_q7s/gpio/GpioIF.h @@ -14,7 +14,7 @@ typedef uint16_t gpioId_t; class GpioIF : public HasReturnvaluesIF{ public: - virtual ~GpioIF(); + virtual ~GpioIF() {}; /** * @brief Called by the GPIO using object. diff --git a/bsp_q7s/gpio/LinuxLibgpioIF.cpp b/bsp_q7s/gpio/LinuxLibgpioIF.cpp index 5070c5e1..7e98abd6 100644 --- a/bsp_q7s/gpio/LinuxLibgpioIF.cpp +++ b/bsp_q7s/gpio/LinuxLibgpioIF.cpp @@ -1,6 +1,9 @@ #include -#include +#include + +#include #include +#include LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) { } @@ -14,16 +17,17 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ GpioMapIter mapToAddIter; if(cookie == nullptr) { - return NULLPOINTER; + sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; + return RETURN_FAILED; } - GpioCookie* GpioCookie = dynamic_cast(cookie); - if(GpioCookie == nullptr) { + GpioCookie* gpioCookie = dynamic_cast(cookie); + if(gpioCookie == nullptr) { sif::error << "LinuxLibgpioIF: Invalid Gpio Cookie!" << std::endl; - return NULLPOINTER; + return RETURN_FAILED; } - mapToAdd = GpioCookie->getGpioMap(); + mapToAdd = gpioCookie->getGpioMap(); result = checkForConflicts(mapToAdd); if (result != HasReturnvaluesIF::RETURN_OK){ @@ -31,20 +35,7 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ } /* 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; - } + gpioMap.insert(mapToAdd.begin(), mapToAdd.end()); return HasReturnvaluesIF::RETURN_OK; } @@ -60,41 +51,43 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId){ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, unsigned int logiclevel) { GpioMapIter gpioMapIter = gpioMap.find(gpioId); - char *chipname; + std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; struct gpiod_line *line; int result; Gpio::Direction direction; + std::string consumer; /* Verify if GPIO has been configured as output */ - direction = gpioMapIter.second.direction; + direction = gpioMapIter->second.direction; if (direction != Gpio::OUT) { - sif::error << "LinuxLibgpioIF::pullHigh: GPIO with ID " << gpioId + sif::error << "LinuxLibgpioIF::driveGpio: GPIO with ID " << gpioId << "not configured as output" << std::endl; return CONFIGURATION_FAILURE; } - chipname = gpioMapIter.second.chipname; - chip = gpiod_chip_open_by_name(chipname); + chipname = gpioMapIter->second.chipname; + chip = gpiod_chip_open_by_name(chipname.c_str()); if (!chip) { - sif::error << "LinuxLibgpioIF::pullHigh: Failed to open chip " + sif::error << "LinuxLibgpioIF::driveGpio: Failed to open chip " << chipname << ". Gpio ID: " << gpioId << std::endl; return OPEN_CHIP_FAILURE; } - lineNum = gpioMapIter.second.lineNum; + lineNum = gpioMapIter->second.lineNum; line = gpiod_chip_get_line(chip, lineNum); if (!line) { - sif::error << "LinuxLibgpioIF::pullHigh: Failed to open line. Gpio ID " + sif::error << "LinuxLibgpioIF::driveGpio: 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); + consumer = gpioMapIter->second.consumer; + result = gpiod_line_request_output(line, consumer.c_str(), 0); if (result < 0) { - sif::error << "LinuxLibgpioIF::pullHigh: Failed to request line " + sif::error << "LinuxLibgpioIF::driveGpio: Failed to request line " << line << " from GPIO instance with ID: " << gpioId << std::endl; gpiod_line_release(line); @@ -103,11 +96,12 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, result = gpiod_line_set_value(line, logiclevel); if (result < 0) { - sif::error << "LinuxLibgpioIF::pullHigh: Failed to pull GPIO with ID " + sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId << "to low" << std::endl; gpiod_line_release(line); return PULLING_HIGH_FAILURE; } + gpiod_line_release(line); return HasReturnvaluesIF::RETURN_OK; } @@ -116,13 +110,14 @@ 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()){ + gpioId = mapToAddIter->first; + gpioMapIter = gpioMap.find(gpioId); + if(gpioMapIter != mapToAdd.end()){ /* An entry for this GPIO already exists. Check if configuration * of direction is equivalent */ - if (mapToAddIter.second.direction != gpioMapIter.second.direction){ + if (mapToAddIter->second.direction != gpioMapIter->second.direction){ sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict " - << "for GPIO " << mapToAddIter.first() << std::endl; + << "for GPIO " << mapToAddIter->first << std::endl; return HasReturnvaluesIF::RETURN_OK; } /* Remove element from map to add because a entry for this GPIO diff --git a/bsp_q7s/gpio/LinuxLibgpioIF.h b/bsp_q7s/gpio/LinuxLibgpioIF.h index 27a68858..0eaf8c48 100644 --- a/bsp_q7s/gpio/LinuxLibgpioIF.h +++ b/bsp_q7s/gpio/LinuxLibgpioIF.h @@ -4,6 +4,7 @@ #include #include #include +#include /** * @brief This class implements the GpioIF for a linux based system. The @@ -12,9 +13,11 @@ * @note The Petalinux SDK from Xilinx supports libgpiod since Petalinux * 2019.1. */ -class LinuxLibgpioIF: public GpioIF, public SystemObject { +class LinuxLibgpioIF : public GpioIF, public SystemObject { public: + static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF; + 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); @@ -30,10 +33,9 @@ public: private: - static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF; - /*Holds the information and configuration of all used GPIOs */ GpioMap gpioMap; + GpioMapIter gpioMapIter; /** * @brief This functions drives line of a GPIO specified by the GPIO ID. diff --git a/bsp_q7s/gpio/cookies/GpioCookie.cpp b/bsp_q7s/gpio/cookies/GpioCookie.cpp index d71bc682..36760c4d 100644 --- a/bsp_q7s/gpio/cookies/GpioCookie.cpp +++ b/bsp_q7s/gpio/cookies/GpioCookie.cpp @@ -1,15 +1,16 @@ #include +#include GpioCookie::GpioCookie() { } -void GpioCookie::addGpio(GpioMap newEntry){ - gpioMapIter = gpioMap.find(newEntry); +void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ + gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { - std::pair status = gpioMap.emplace(newEntry); + std::pair status = gpioMap.emplace(gpioId, gpioConfig); if (status.second == false) { sif::error << "GpioCookie::addGpio: Failed to add GPIO " - << newEntry.first << "to GPIO map" << std::endl; + << gpioId << "to GPIO map" << std::endl; } } else { @@ -18,7 +19,7 @@ void GpioCookie::addGpio(GpioMap newEntry){ } } -GpioMap getGpioMap() const{ +GpioMap GpioCookie::getGpioMap() const{ return gpioMap; } diff --git a/bsp_q7s/gpio/cookies/GpioCookie.h b/bsp_q7s/gpio/cookies/GpioCookie.h index 1a99a676..16ba3b8c 100644 --- a/bsp_q7s/gpio/cookies/GpioCookie.h +++ b/bsp_q7s/gpio/cookies/GpioCookie.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace Gpio { enum Direction { @@ -27,7 +28,7 @@ typedef struct GpioConfig { GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, Gpio::Direction direction_) : chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction( - directio_) { + direction_) { } std::string chipname; int lineNum; @@ -54,7 +55,7 @@ public: virtual ~GpioCookie(); - void addGpio(GpioMap newEntry); + void addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig); /** * @brief Get map with registered GPIOs. */ diff --git a/cmake/Q7SCrossCompileConfig.cmake b/cmake/Q7SCrossCompileConfig.cmake index 2fb8134b..2c5bd4e9 100644 --- a/cmake/Q7SCrossCompileConfig.cmake +++ b/cmake/Q7SCrossCompileConfig.cmake @@ -23,7 +23,7 @@ else() ) endif() -# message(STATUS "Using sysroot path: ${SYSROOT_PATH}") +message(STATUS "Using sysroot path: ${SYSROOT_PATH}") set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc") set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++") @@ -40,7 +40,7 @@ find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED) find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED) set(CMAKE_CROSSCOMPILING TRUE) -# set(CMAKE_SYSROOT "${SYSROOT_PATH}") +set(CMAKE_SYSROOT "${SYSROOT_PATH}") # Define name of the target system set(CMAKE_SYSTEM_NAME "Linux") @@ -52,9 +52,16 @@ set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX}) # List of library dirs where LD has to look. Pass them directly through gcc. set(LIB_DIRS + "${SYSROOT_PATH}/usr/include" + "${SYSROOT_PATH}/usr/include/linux" + "${SYSROOT_PATH}/usr/lib" + "${SYSROOT_PATH}/lib" + "${SYSROOT_PATH}" + "${SYSROOT_PATH}/usr/lib/arm-xiphos-linux-gnueabi" ) # You can additionally check the linker paths if you add the # flags ' -Xlinker --verbose' +set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/lib") foreach(LIB ${LIB_DIRS}) set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}") endforeach() @@ -65,7 +72,7 @@ set(CMAKE_PREFIX_PATH ) set(CMAKE_C_FLAGS - "-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS}" + "-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod" CACHE STRING "C flags for Q7S" ) set(CMAKE_CXX_FLAGS diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 0682a0c3..bc534929 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -12,7 +12,7 @@ // debugging. #define OBSW_ENHANCED_PRINTOUT 1 -#define TE0720 0 +#define TE0720 1 #include "OBSWVersion.h" diff --git a/fsfwconfig/devices/heaterSwitcherList.h b/fsfwconfig/devices/heaterSwitcherList.h index c673b1d8..3ebcfcc2 100644 --- a/fsfwconfig/devices/heaterSwitcherList.h +++ b/fsfwconfig/devices/heaterSwitcherList.h @@ -2,7 +2,7 @@ #define FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_ namespace heaterSwitches { - enum switcherList { + enum switcherList: uint8_t { PAYLOAD_CAMERA, NUMBER_OF_SWITCHES }; diff --git a/fsfwconfig/devices/powerSwitcherList.h b/fsfwconfig/devices/powerSwitcherList.h index 0c0442a2..881c9fa7 100644 --- a/fsfwconfig/devices/powerSwitcherList.h +++ b/fsfwconfig/devices/powerSwitcherList.h @@ -1,16 +1,40 @@ #ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ #define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ +#include + namespace pcduSwitches { /* Switches are uint8_t datatype and go from 0 to 255 */ enum switcherList { - PCDU, - GPS0, - GPS1, - TCS_BOARD_8V_HEATER_IN, - DUMMY = 129, + Q7S, + PAYLOAD_PCDU_CH1, + RW, + TCS_BOARD_8V_HEATER_IN, + SUS_REDUNDANT, + DEPLOYMENT_MECHANISM, + PAYLOAD_PCDU_CH6, + ACS_BOARD_SIDE_B, + PAYLOAD_CAMERA, + NUMBER_OF_SWITCHES }; + static const uint8_t ON = 1; + static const uint8_t OFF = 0; + + /* Output states after reboot of the PDUs */ + static const uint8_t INIT_STATE_Q7S = ON; + static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF; + static const uint8_t INIT_STATE_RW = OFF; +#if TE0720 == 1 + static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; +#else + static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; +#endif + static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF; + static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF; + static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF; + static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF; + static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF; } diff --git a/mission/devices/ACUHandler.cpp b/mission/devices/ACUHandler.cpp index 638c3f9b..1e9c908a 100644 --- a/mission/devices/ACUHandler.cpp +++ b/mission/devices/ACUHandler.cpp @@ -1,7 +1,7 @@ #include "ACUHandler.h" ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, - uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16 hkTableSize) : + uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize) : GomspaceDeviceHandler(objectId, comIF, comCookie, maxConfigTableAddress, maxHkTableAddress, hkTableSize) { } diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index 2529100a..45d3ba22 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -71,7 +71,11 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand( break; } case(GOMSPACE::REQUEST_HK_TABLE): { - generateRequestFullHkTableCmd(hkTableSize); + result = generateRequestFullHkTableCmd(hkTableSize); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + break; } default: return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; diff --git a/mission/devices/HeaterHandler.cpp b/mission/devices/HeaterHandler.cpp index e09568ea..2393696e 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/mission/devices/HeaterHandler.cpp @@ -1,11 +1,13 @@ #include #include +#include +#include -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), actionHelper(this, nullptr) { +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); } @@ -20,7 +22,7 @@ ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) { handleActiveCommands(); return RETURN_OK; } - + return RETURN_OK; } ReturnValue_t HeaterHandler::initialize() { @@ -40,7 +42,7 @@ ReturnValue_t HeaterHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initializeInterface(gpioCookie); + result = gpioInterface->initialize(gpioCookie); if (result != RETURN_OK) { sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; @@ -70,9 +72,8 @@ ReturnValue_t HeaterHandler::initialize() { } ReturnValue_t HeaterHandler::initializeHeaterMap(){ - heaterMapIter = heaterMap.begin(); HeaterCommandInfo_t heaterCommandInfo; - for(int switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) { + 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" @@ -84,7 +85,7 @@ ReturnValue_t HeaterHandler::initializeHeaterMap(){ } void HeaterHandler::setInitialSwitchStates() { - for (int switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) { + for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) { switchStates[switchNr] = OFF; } } @@ -104,16 +105,16 @@ void HeaterHandler::readCommandQueue() { ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - if (actionId != SWITCH_ON && actionId != SWITCH_OFF) { + ReturnValue_t result; + if (actionId != SWITCH_HEATER) { result = COMMAND_NOT_SUPPORTED; } else { - heaterMapIter = heaterMap.find(*data); + switchNr_t switchNr = *data; + HeaterMapIter heaterMapIter = heaterMap.find(switchNr); if (heaterMapIter != heaterMap.end()) { - heaterMapIter.second.action = *(data + 1); - heaterMapIter.second.active = true; + heaterMapIter->second.action = *(data + 1); + heaterMapIter->second.active = true; + heaterMapIter->second.replyQueue = commandedBy; } else { sif::error << "HeaterHandler::executeAction: Invalid switchNr" << std::endl; @@ -136,77 +137,42 @@ void HeaterHandler::sendSwitchCommand(uint8_t switchNr, 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, - HeaterHandler::SWITCH_HEATER, storeAddress); + ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress); /* Send heater command to own command queue */ - result = commandQueue->sendMessage(commandQueue, &message, 0); + result = commandQueue->sendMessage(commandQueue->getId(), &message, 0); if (result != RETURN_OK) { - debug << "HeaterHandler::sendSwitchCommand: Failed to send switch" + sif::debug << "HeaterHandler::sendSwitchCommand: Failed to send switch" << "message" << std::endl; } } } void HeaterHandler::handleActiveCommands(){ - ReturnValue_t result; - heaterMapIter = heaterMap.begin(); - for (; heaterMapIter != mapToAdd.end(); heaterMapIter++) { - if (heaterMapIter.second.active) { - switch(heaterMapIter.second.action) { + HeaterMapIter heaterMapIter = heaterMap.begin(); + for (; heaterMapIter != heaterMap.end(); heaterMapIter++) { + if (heaterMapIter->second.active) { + switch(heaterMapIter->second.action) { case SET_SWITCH_ON: - int switchNr = heaterMapIter.first(); - /* Check state of main line switch */ - if (mainLineSwitcher->getSwitchState(pcduSwitches::TCS_BOARD_8V_HEATER_IN) - == SWITCH_ON) { - if (!checkSwitchState(switchNr)) { - gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr); - result = gpioInterface->pullHigh(gpioId); - if (result != RETURN_OK) { - triggerEvent(GPIO_PULL_HIGH_FAILED, result); - } - } - 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) { - actionHelper.finish(heaterMapIter.second.replyQueue, - heaterMapIter.second.action, result); - } - heaterMapIter.second.active = false; - } - else { - mainLineSwitcher->sendSwitchCommand(pcduSwitches::TCS_BOARD_8V_HEATER_IN); - } + handleSwitchOnCommand(heaterMapIter); break; case SET_SWITCH_OFF: - int switchNr = heaterMapIter.first(); - if (checkSwitchState(switchNr)) { - gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr); - result = gpioInterface->pullLow(gpioId); - triggerEvent(GPIO_PULL_LOW_FAILED, result); - } - else { - triggerEvent(SWITCH_ALREADY_OFF, switchNr); - } - if (heaterCommand.replyQueue != NO_COMMANDER) { - actionHelper.finish(heaterMapIter.second.replyQueue, - heaterMapIter.second.action, result); - } - break; + handleSwitchOffCommand(heaterMapIter); + break; default: sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded" << std::endl; @@ -216,11 +182,93 @@ void HeaterHandler::handleActiveCommands(){ } } +void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) { + + ReturnValue_t result; + 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); + heaterMapIter->second.active = false; + 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::handleSwitchOffCommand: 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()) { + actionHelper.finish(heaterMapIter->second.replyQueue, + heaterMapIter->second.action, result); + } + heaterMapIter->second.active = false; + } + else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF) { + mainLineSwitcher->sendSwitchCommand(mainLineSwitch, + PowerSwitchIF::SWITCH_ON); + heaterMapIter->second.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs()); + } + else { + sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of" + << " main line switch" << std::endl; + if (heaterMapIter->second.replyQueue != commandQueue->getId()) { + actionHelper.finish(heaterMapIter->second.replyQueue, + heaterMapIter->second.action, mainSwitchState); + } + heaterMapIter->second.active = false; + } +} + +void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) { + ReturnValue_t result; + switchNr_t switchNr = heaterMapIter->first; + 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; + } + } + else { + triggerEvent(SWITCH_ALREADY_OFF, switchNr); + } + if (heaterMapIter->second.replyQueue != NO_COMMANDER) { + actionHelper.finish(heaterMapIter->second.replyQueue, + heaterMapIter->second.action, result); + } + heaterMapIter->second.active = false; +} + bool HeaterHandler::checkSwitchState(int switchNr) { return switchStates[switchNr]; } -gpioId_t HeaterHandler::getGpioIdFromSwitchNr(switchNr) { +gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) { gpioId_t gpioId = 0xFFFF; switch(switchNr) { case heaterSwitches::PAYLOAD_CAMERA: @@ -234,3 +282,21 @@ gpioId_t HeaterHandler::getGpioIdFromSwitchNr(switchNr) { 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; +} diff --git a/mission/devices/HeaterHandler.h b/mission/devices/HeaterHandler.h index 30cd12b8..d05b7609 100644 --- a/mission/devices/HeaterHandler.h +++ b/mission/devices/HeaterHandler.h @@ -8,6 +8,11 @@ #include #include #include +#include +#include +#include +#include +#include /** * @brief This class intends the control of heaters. @@ -15,35 +20,35 @@ * @author J. Meier */ class HeaterHandler: public ExecutableObjectIF, - public PowerSwitchIF, - public SystemObject, - public HasActionsIF, - public HasModesIF, - public HasReturnvaluesIF { + public PowerSwitchIF, + public SystemObject, + public HasActionsIF { public: /** Device command IDs */ - static const DeviceCommandId_t SWITCH_HEATER; + 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); + virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; - void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override; - virtual void sendFuseOnCommand(uint8_t fuseNr) 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 ) 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; + 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: @@ -58,6 +63,79 @@ private: 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; + 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; + + /** 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(); ReturnValue_t buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t *commandData, @@ -72,7 +150,7 @@ private: * @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(switchNr); + gpioId_t getGpioIdFromSwitchNr(int switchNr); /** * @brief This function runs commands waiting for execution. @@ -86,68 +164,10 @@ private: */ void setInitialSwitchStates(); - enum SwitchState : bool { - ON = true, - OFF = false - }; + void handleSwitchOnCommand(HeaterMapIter heaterMapIter); + void handleSwitchOffCommand(HeaterMapIter heaterMapIter); - /** - * @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. - */ - typedef struct HeaterCommandInfo { - uint8_t action; - MessageQueueId_t replyQueue; - bool active = false; - } HeaterCommandInfo_t; - - enum SwitchAction { - SET_SWITCH_ON, - SET_SWITCH_OFF - }; - - using switchNr_t = int; - using HeaterMap = std::unordered_map; - using HeaterMapIter = HeaterMap::iterator; - - HeateerMap heaterMap; - HeaterMapIter heaterMapIter; - - 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; - - GpioIF* gpioInterface; - - /** 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; }; #endif /* MISSION_DEVICES_HEATERHANDLER_H_ */ diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 1d68b776..b5f593ad 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) : SystemObject(setObjectId), poolManager(this, nullptr), pdu2HkTableDataset(this), cmdQueueSize( @@ -55,6 +55,18 @@ ReturnValue_t PCDUHandler::initialize() { return RETURN_OK; } +void PCDUHandler::initializeSwitchStates() { + switchStates[pcduSwitches::Q7S] = pcduSwitches::INIT_STATE_Q7S; + switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1; + switchStates[pcduSwitches::RW] = pcduSwitches::INIT_STATE_RW; + switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN; + switchStates[pcduSwitches::SUS_REDUNDANT] = pcduSwitches::INIT_STATE_SUS_REDUNDANT; + switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM; + switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6; + switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B; + switchStates[pcduSwitches::PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA; +} + void PCDUHandler::readCommandQueue() { ReturnValue_t result; CommandMessage command; @@ -75,7 +87,7 @@ void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) { if (sid == sid_t(objects::PCDU_HANDLER, PDU2::HK_TABLE_DATA_SET_ID)) { HousekeepingPacketUpdate packetUpdate(reinterpret_cast(&timeStamp), sizeof(timeStamp), &pdu2HkTableDataset); - const uint8_t** packet_ptr; + const uint8_t** packet_ptr = NULL; size_t size; result = IPCStore->getData(storeId, packet_ptr, &size); if (result != RETURN_OK) { @@ -93,12 +105,36 @@ void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) { sif::error << "PCDUHandler::handleChangedDataset: Failed to deserialize packet in " << "pdu2HkTableDataset" << std::endl; } + updatePdu2SwitchStates(); } else { sif::error << "PCDUHandler::handleChangedDataset: Invalid sid" << std::endl; } } +void PCDUHandler::updatePdu2SwitchStates() { + if (pdu2HkTableDataset.read() != RETURN_OK) { + switchStates[pcduSwitches::Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; + switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pdu2HkTableDataset.outEnabledPlPCDUCh1.value; + switchStates[pcduSwitches::RW] = pdu2HkTableDataset.outEnabledReactionWheels.value; + switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value; + switchStates[pcduSwitches::SUS_REDUNDANT] = pdu2HkTableDataset.outEnabledSUS.value; + switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = pdu2HkTableDataset.outEnabledDeplMechanism.value; + switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pdu2HkTableDataset.outEnabledPlPCDUCh6.value; + switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pdu2HkTableDataset.outEnabledAcsBoard.value; + switchStates[pcduSwitches::PAYLOAD_CAMERA] = pdu2HkTableDataset.outEnabledPayloadCamera.value; + } + else { + sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" + << std::endl; + } + pdu2HkTableDataset.commit(); +} + +void PCDUHandler::updatePdu1SwitchStates() { + +} + LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; } @@ -133,11 +169,13 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const return; } + const uint8_t* parameterValuePtr = ¶meterValue; + GomspaceSetParamMessage setParamMessage(memoryAddress, ¶meterValuePtr, parameterValueSize); + size_t serializedLength = 0; uint8_t command[4]; uint8_t* commandPtr = command; size_t maxSize = sizeof(command); - GomspaceSetParamMessage setParamMessage(memoryAddress, ¶meterValue, parameterValueSize); setParamMessage.serialize(&commandPtr, &serializedLength, maxSize, SerializeIF::Endianness::BIG); @@ -159,18 +197,16 @@ void PCDUHandler::sendFuseOnCommand(uint8_t fuseNr) const { } ReturnValue_t PCDUHandler::getSwitchState( uint8_t switchNr ) const { - switch (switchNr) { - case pcduSwitches::TCS_BOARD_8V_HEATER_IN: - if (pdu2HkTableDataset.outEnabledTCSBoardHeaterIn == 1) { - return PowerSwitchIF::SWITCH_ON; - } - else { - return PowerSwitchIF::SWITCH_OFF; - } - default: - sif::error << "PCDUHandler::getSwitchState: Invalid switchNr" << std::endl; - return RETURN_FAILED; - } + if (switchNr >= pcduSwitches::NUMBER_OF_SWITCHES) { + sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl; + return RETURN_FAILED; + } + if (switchStates[switchNr] == 1) { + return PowerSwitchIF::SWITCH_ON; + } + else { + return PowerSwitchIF::SWITCH_OFF; + } } ReturnValue_t PCDUHandler::getFuseState( uint8_t fuseNr ) const { @@ -178,34 +214,44 @@ ReturnValue_t PCDUHandler::getFuseState( uint8_t fuseNr ) const { } uint32_t PCDUHandler::getSwitchDelayMs(void) const { - return 0; + return 5000; } object_id_t PCDUHandler::getObjectId() const { return SystemObject::getObjectId(); } -ReturnValue_t PCDUHandler::initializeLocalDataPool( - localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { +ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) { localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_Q7S, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, + new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_RW, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN, + new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_SUS_REDUNDANT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM, + new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6, + new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B, + new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_CAMERA, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_Q7S, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, + new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_RW, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, + new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, + new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, + new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B, + new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_CAMERA, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VCC, new PoolEntry( { 0 })); @@ -213,15 +259,27 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool( localDataPoolMap.emplace(PDU::PDU2_TEMPERATURE, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_CONV_EN, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, new PoolEntry( { 0 })); - localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry( { + pcduSwitches::INIT_STATE_Q7S })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry( { + pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1 })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry( { + pcduSwitches::INIT_STATE_RW })); +#if TE0720 == 1 + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry( { 1 })); +#else + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry( {pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN})); +#endif + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry( { + pcduSwitches::INIT_STATE_SUS_REDUNDANT })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry( { + pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry( { + pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6 })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, new PoolEntry( { + pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B })); + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, new PoolEntry( { + pcduSwitches::INIT_STATE_PAYLOAD_CAMERA })); localDataPoolMap.emplace(PDU::PDU2_BOOTCAUSE, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_BOOTCNT, new PoolEntry( { 0 })); @@ -266,6 +324,8 @@ ReturnValue_t PCDUHandler::initializeAfterTaskCreation() { } this->poolManager.initializeAfterTaskCreation(); + initializeSwitchStates(); + return HasReturnvaluesIF::RETURN_OK; } @@ -278,12 +338,10 @@ void PCDUHandler::setTaskIF(PeriodicTaskIF* task){ } LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) { - switch (sid) { - case pdu2HkTableDataset.getSid(): + if (sid == pdu2HkTableDataset.getSid()) { return &pdu2HkTableDataset; - default: + } else { sif::error << "PCDUHandler::getDataSetHandle: Invalid sid" << std::endl; return nullptr; - break; } } diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index 7bb4c8a1..509d61d9 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -9,6 +9,7 @@ #include #include #include +#include /** * @brief The PCDUHandler provides a compact interface to handle all devices related to the @@ -43,12 +44,16 @@ public: LocalDataPoolManager& poolManager) override; virtual uint32_t getPeriodicOperationFrequency() const override; virtual ReturnValue_t initializeAfterTaskCreation() override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; virtual void setTaskIF(PeriodicTaskIF* task_); private: uint32_t pstIntervalMs = 0; + /** Housekeeping manager. Handles updates of local pool variables. */ + LocalDataPoolManager poolManager; + /** * The dataset holding the hk table of PDU2. This dataset is a copy of the PDU2 HK dataset * of the PDU2Handler. Each time the PDU2Handler updates his HK dataset, a copy is sent @@ -58,6 +63,7 @@ private: /** The timeStamp of the current pdu2HkTableDataset */ CCSDSTime::CDS_short timeStamp; + uint8_t switchStates[pcduSwitches::NUMBER_OF_SWITCHES]; /** * Pointer to the IPCStore. * This caches the pointer received from the objectManager in the constructor. @@ -72,12 +78,27 @@ private: size_t cmdQueueSize; - /** Housekeeping manager. Handles updates of local pool variables. */ - LocalDataPoolManager poolManager; - PeriodicTaskIF* executingTask = nullptr; void readCommandQueue(); + + /** + * @brief This function sets all switchStates to the initial switch configuration of the + * two PDUs after reboot. + */ + void initializeSwitchStates(); + + /** + * @brief Updates all switchStates related to the PDU2. + * Function is called each time a new hk dataset has been received from the PDU2Handler. + */ + void updatePdu2SwitchStates(); + + /** + * @brief Updates all switchStates related to the PDU1. Called each time the PDU1Handler + * sends a new hk dataset. + */ + void updatePdu1SwitchStates(); }; #endif /* MISSION_DEVICES_PCDUHANDLER_H_ */ diff --git a/mission/devices/PDU1Handler.cpp b/mission/devices/PDU1Handler.cpp index 1df70acc..bd46d407 100644 --- a/mission/devices/PDU1Handler.cpp +++ b/mission/devices/PDU1Handler.cpp @@ -1,9 +1,10 @@ #include "PDU1Handler.h" +#include -PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, - CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, - uint16_t hkTableSize) : GomspaceDeviceHandler(objectId, comIF, - comCookie, maxConfigTableAddress, maxHkTableAddress, hkTableSize) { +PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, + uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize) : + GomspaceDeviceHandler(objectId, comIF, comCookie, maxConfigTableAddress, maxHkTableAddress, + hkTableSize), hkTableDataset(this) { } PDU1Handler::~PDU1Handler() { @@ -19,7 +20,7 @@ void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac const uint8_t* payloadPtr = packet + GOMSPACE::GS_HDR_LENGTH; size_t size = (size_t)hkTableSize; hkTableDataset.deSerialize(&payloadPtr, &size, SerializeIF::Endianness::BIG); - FullTableReply fullTableReply(id, HK_TABLE_ID, hkTableDataset); + FullTableReply fullTableReply(id, HK_TABLE_ID, &hkTableDataset); handleDeviceTM(&fullTableReply, id, true); } diff --git a/mission/devices/PDU2Handler.cpp b/mission/devices/PDU2Handler.cpp index 2da40d28..d008962b 100644 --- a/mission/devices/PDU2Handler.cpp +++ b/mission/devices/PDU2Handler.cpp @@ -1,5 +1,6 @@ #include "PDU2Handler.h" #include +#include PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, @@ -41,6 +42,7 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool( localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_RW, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, new PoolEntry( { 0 })); @@ -55,7 +57,11 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool( localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry( { 0 })); +#if TE0720 == 1 + localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry( { 1 })); +#else localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry( { 0 })); +#endif localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry( { 0 })); localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry( { 0 })); diff --git a/mission/devices/devicedefinitions/GomSpacePackets.h b/mission/devices/devicedefinitions/GomSpacePackets.h index 7c4d0cf7..4e2ef19f 100644 --- a/mission/devices/devicedefinitions/GomSpacePackets.h +++ b/mission/devices/devicedefinitions/GomSpacePackets.h @@ -186,7 +186,7 @@ private: class RequestFullTableCommand : public SerialLinkedListAdapter { public: - RequestFullTableCommand(uint16_t querySize_, uint8_t tableId) : + RequestFullTableCommand(uint16_t querySize_, uint8_t tableId_) : querySize(querySize_), tableId(tableId_) { setLinks(); } @@ -337,8 +337,8 @@ private: void setLinks() { setStart(&action); action.setNext(&tableId); - tableId.setNext(&tableLength); - tableLength.setNext(&tableDataset); + tableId.setNext(&tableDataset); + tableDataset.setNext(&tableDataset); } SerializeElement action; SerializeElement tableId; @@ -404,11 +404,11 @@ public: * @param parameterSize The size of the parameter. * */ - GomspaceSetParamMessage(uint16_t memoryAddress, uint8_t* parameterValue, uint8_t parameterSize) : - memoryAddress(memoryAddress) { - const uint8_t** buffer; - *buffer = parameterValue; - parameterInfo.deserialize(buffer, parameterSize, SerializeIF::Endianness::BIG); + GomspaceSetParamMessage(uint16_t memoryAddress, const uint8_t** parameterValue, + uint8_t parameterSize) : + memoryAddress(memoryAddress) { + size_t size = parameterSize; + parameterValueInfo.deSerialize(parameterValue, &size, SerializeIF::Endianness::BIG); setLinks(); } @@ -416,7 +416,7 @@ private: GomspaceSetParamMessage(const FullTableReply &reply); void setLinks() { setStart(&memoryAddress); - memoryAddress.setNext(¶meter); + memoryAddress.setNext(¶meterValueInfo); } SerializeElement memoryAddress; SerializeElement> parameterValueInfo; diff --git a/tmtc b/tmtc index 6b840eff..39e8ff71 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6b840eff43440a7b44df1cc089338f600a4a6d88 +Subproject commit 39e8ff713431ed1a6484f6980b518aecd0d8288b