diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 987cb7a3..43239ea1 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -152,7 +152,7 @@ void ObjectFactory::produce(void* args) { createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher); #endif - createHeaterComponents(pwrSwitcher, healthTable); + createHeaterComponents(gpioComIF, pwrSwitcher, healthTable); createSolarArrayDeploymentComponents(); createPlPcduComponents(gpioComIF, spiComIF, pwrSwitcher); #if OBSW_ADD_SYRLINKS == 1 @@ -581,7 +581,8 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } -void ObjectFactory::createHeaterComponents(PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable) { +void ObjectFactory::createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, + HealthTableIF* healthTable) { using namespace gpio; GpioCookie* heaterGpiosCookie = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; @@ -622,7 +623,19 @@ void ObjectFactory::createHeaterComponents(PowerSwitchIF* pwrSwitcher, HealthTab Levels::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, pwrSwitcher, + gpioIF->addGpios(heaterGpiosCookie); + + HeaterHelper helper({{ + {new HealthDevice(objects::HEATER_0, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_0}, + {new HealthDevice(objects::HEATER_1, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1}, + {new HealthDevice(objects::HEATER_2, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2}, + {new HealthDevice(objects::HEATER_3, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3}, + {new HealthDevice(objects::HEATER_4, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4}, + {new HealthDevice(objects::HEATER_5, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5}, + {new HealthDevice(objects::HEATER_6, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6}, + {new HealthDevice(objects::HEATER_7, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7}, + }}); + new HeaterHandler(objects::HEATER_HANDLER, gpioIF, helper, pwrSwitcher, pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 39dd5a6a..7dee478c 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -8,6 +8,7 @@ class I2cComIF; class PowerSwitchIF; class HealthTableIF; class AcsBoardAssembly; +class GpioIF; namespace ObjectFactory { @@ -23,7 +24,7 @@ void createTmpComponents(); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF, PowerSwitchIF* pwrSwitcher); -void createHeaterComponents(PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable); +void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable); void createSolarArrayDeploymentComponents(); void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher); void createPayloadComponents(LinuxLibgpioIF* gpioComIF); diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index a4f3319e..38b735c0 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -22,13 +22,6 @@ enum commonObjects: uint32_t { CORE_CONTROLLER = 0x43000003, /* 0x44 ('D') for device handlers */ - P60DOCK_HANDLER = 0x44250000, - PDU1_HANDLER = 0x44250001, - PDU2_HANDLER = 0x44250002, - ACU_HANDLER = 0x44250003, - BPX_BATT_HANDLER = 0x44260000, - TMP1075_HANDLER_1 = 0x44420004, - TMP1075_HANDLER_2 = 0x44420005, MGM_0_LIS3_HANDLER = 0x44120006, MGM_1_RM3100_HANDLER = 0x44120107, MGM_2_LIS3_HANDLER = 0x44120208, @@ -37,12 +30,45 @@ enum commonObjects: uint32_t { GYRO_1_L3G_HANDLER = 0x44120111, GYRO_2_ADIS_HANDLER = 0x44120212, GYRO_3_L3G_HANDLER = 0x44120313, - PLPCDU_HANDLER = 0x44300000, + SUS_0 = 0x44120032, + SUS_1 = 0x44120033, + SUS_2 = 0x44120034, + SUS_3 = 0x44120035, + SUS_4 = 0x44120036, + SUS_5 = 0x44120037, + SUS_6 = 0x44120038, + SUS_7 = 0x44120039, + SUS_8 = 0x44120040, + SUS_9 = 0x44120041, + SUS_10 = 0x44120042, + SUS_11 = 0x44120043, + RW1 = 0x44120047, + RW2 = 0x44120148, + RW3 = 0x44120249, + RW4 = 0x44120350, + STAR_TRACKER = 0x44130001, + GPS_CONTROLLER = 0x44130045, IMTQ_HANDLER = 0x44140014, + TMP1075_HANDLER_1 = 0x44420004, + TMP1075_HANDLER_2 = 0x44420005, + PCDU_HANDLER = 0x442000A1, + P60DOCK_HANDLER = 0x44250000, + PDU1_HANDLER = 0x44250001, + PDU2_HANDLER = 0x44250002, + ACU_HANDLER = 0x44250003, + BPX_BATT_HANDLER = 0x44260000, + PLPCDU_HANDLER = 0x44300000, + RAD_SENSOR = 0x443200A5, + PLOC_UPDATER = 0x44330000, + PLOC_MEMORY_DUMPER = 0x44330001, + STR_HELPER = 0x44330002, + PLOC_MPSOC_HELPER = 0x44330003, PLOC_MPSOC_HANDLER = 0x44330015, PLOC_SUPERVISOR_HANDLER = 0x44330016, PLOC_SUPERVISOR_HELPER = 0x44330017, + SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2, + HEATER_HANDLER = 0x444100A4, /** * Not yet specified which pt1000 will measure which device/location in the satellite. @@ -65,35 +91,22 @@ enum commonObjects: uint32_t { RTD_IC_17 = 0x44420030, RTD_IC_18 = 0x44420031, - SUS_0 = 0x44120032, - SUS_1 = 0x44120033, - SUS_2 = 0x44120034, - SUS_3 = 0x44120035, - SUS_4 = 0x44120036, - SUS_5 = 0x44120037, - SUS_6 = 0x44120038, - SUS_7 = 0x44120039, - SUS_8 = 0x44120040, - SUS_9 = 0x44120041, - SUS_10 = 0x44120042, - SUS_11 = 0x44120043, - GPS_CONTROLLER = 0x44130045, - RW1 = 0x44120047, - RW2 = 0x44120148, - RW3 = 0x44120249, - RW4 = 0x44120350, - - STAR_TRACKER = 0x44130001, - - PLOC_UPDATER = 0x44330000, - PLOC_MEMORY_DUMPER = 0x44330001, - STR_HELPER = 0x44330002, - PLOC_MPSOC_HELPER = 0x44330003, + SYRLINKS_HK_HANDLER = 0x445300A3, AXI_PTME_CONFIG = 44330004, PTME_CONFIG = 44330005, + // 0x60 for other stuff + HEATER_0 = 0x60000000, + HEATER_1 = 0x60000001, + HEATER_2 = 0x60000002, + HEATER_3 = 0x60000003, + HEATER_4 = 0x60000004, + HEATER_5 = 0x60000005, + HEATER_6 = 0x60000006, + HEATER_7 = 0x60000007, + // 0x73 ('s') for assemblies and system/subsystem components ACS_BOARD_ASS = 0x73000001, SUS_BOARD_ASS = 0x73000002, diff --git a/linux/fsfwconfig/objects/systemObjectList.h b/linux/fsfwconfig/objects/systemObjectList.h index a03e4d38..cf5b7423 100644 --- a/linux/fsfwconfig/objects/systemObjectList.h +++ b/linux/fsfwconfig/objects/systemObjectList.h @@ -50,13 +50,6 @@ enum sourceObjects : uint32_t { SPI_COM_IF = 0x49020004, GPIO_IF = 0x49010005, - /* Custom device handler */ - PCDU_HANDLER = 0x442000A1, - SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2, - SYRLINKS_HK_HANDLER = 0x445300A3, - HEATER_HANDLER = 0x444100A4, - RAD_SENSOR = 0x443200A5, - /* 0x54 ('T') for test handlers */ TEST_TASK = 0x54694269, LIBGPIOD_TEST = 0x54123456, diff --git a/mission/devices/HeaterHandler.cpp b/mission/devices/HeaterHandler.cpp index dec71a2a..e27d74b6 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/mission/devices/HeaterHandler.cpp @@ -10,16 +10,22 @@ #include "devices/gpioIds.h" #include "devices/powerSwitcherList.h" -HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, - CookieIF* gpioCookie_, PowerSwitchIF* mainLineSwitcher_, - power::Switch_t mainLineSwitch_) +HeaterHandler::HeaterHandler(object_id_t setObjectId_, GpioIF* gpioInterface_, HeaterHelper helper, + PowerSwitchIF* mainLineSwitcher_, power::Switch_t mainLineSwitch_) : SystemObject(setObjectId_), - gpioDriverId(gpioDriverId_), - gpioCookie(gpioCookie_), + helper(helper), + gpioInterface(gpioInterface_), mainLineSwitcher(mainLineSwitcher_), mainLineSwitch(mainLineSwitch_), - healthHelper(this, getObjectId()), actionHelper(this, nullptr) { + for (const auto& heater : helper.heaters) { + if (heater.first == nullptr) { + throw std::invalid_argument("HeaterHandler::HeaterHandler: Invalid Heater Object"); + } + } + if (gpioInterface_ == nullptr) { + throw std::invalid_argument("HeaterHandler::HeaterHandler: Invalid Gpio IF"); + } if (mainLineSwitcher == nullptr) { throw std::invalid_argument("HeaterHandler::HeaterHandler: Invalid PowerSwitchIF"); } @@ -31,10 +37,10 @@ HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_ HeaterHandler::~HeaterHandler() {} ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) { - if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) { - readCommandQueue(); - handleActiveCommands(); - return RETURN_OK; + readCommandQueue(); + handleActiveCommands(); + for (const auto& heater : helper.heaters) { + heater.first->performOperation(0); } return RETURN_OK; } @@ -50,22 +56,8 @@ ReturnValue_t HeaterHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - gpioInterface = ObjectManager::instance()->get(gpioDriverId); - if (gpioInterface == nullptr) { - sif::error << "HeaterHandler::initialize: Invalid Gpio interface." << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - result = gpioInterface->addGpios(dynamic_cast(gpioCookie)); - if (result != RETURN_OK) { - sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - healthHelper.initialize(commandQueue->getId()); - - IPCStore = ObjectManager::instance()->get(objects::IPC_STORE); - if (IPCStore == nullptr) { + ipcStore = ObjectManager::instance()->get(objects::IPC_STORE); + if (ipcStore == nullptr) { sif::error << "HeaterHandler::initialize: IPC store not set up in factory." << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -79,24 +71,12 @@ ReturnValue_t HeaterHandler::initialize() { } 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; - } + for (power::Switch_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) { + heaterVec.push_back(HeaterWrapper(helper.heaters[switchNr])); } return RETURN_OK; } -void HeaterHandler::setInitialSwitchStates() { - for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) { - switchStates[switchNr] = OFF; - } -} - void HeaterHandler::readCommandQueue() { ReturnValue_t result = RETURN_OK; CommandMessage command; @@ -111,41 +91,44 @@ void HeaterHandler::readCommandQueue() { if (result == RETURN_OK) { continue; } - result = healthHelper.handleHealthCommand(&command); - if (result == RETURN_OK) { - continue; - } } while (result == RETURN_OK); } 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; + if (data == nullptr or size < 2) { + return HasActionsIF::INVALID_PARAMETERS; } - return result; + if (actionId != SWITCH_HEATER) { + return COMMAND_NOT_SUPPORTED; + } + auto switchNr = *data; + if (switchNr > 7) { + return HasActionsIF::INVALID_PARAMETERS; + } + auto heater = heaterVec.at(switchNr); + HasHealthIF::HealthState health = heater.healthDevice->getHealth(); + if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or + health == HasHealthIF::NEEDS_RECOVERY) { + return HasHealthIF::OBJECT_NOT_HEALTHY; + } + if (heater.active) { + return COMMAND_ALREADY_WAITING; + } + auto action = data[1]; + if (action != 0 and action != 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + heater.action = static_cast(data[1]); + heater.active = true; + heater.replyQueue = commandedBy; + return RETURN_OK; } ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) { ReturnValue_t result; store_address_t storeAddress; - uint8_t commandData[2]; + uint8_t commandData[2] = {}; switch (onOff) { case PowerSwitchIF::SWITCH_ON: @@ -161,7 +144,7 @@ ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t o break; } - result = IPCStore->addData(&storeAddress, commandData, sizeof(commandData)); + result = ipcStore->addData(&storeAddress, commandData, sizeof(commandData)); if (result == RETURN_OK) { CommandMessage message; ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress); @@ -176,15 +159,14 @@ ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t o } void HeaterHandler::handleActiveCommands() { - HeaterMapIter heaterMapIter = heaterMap.begin(); - for (; heaterMapIter != heaterMap.end(); heaterMapIter++) { - if (heaterMapIter->second.active) { - switch (heaterMapIter->second.action) { + for (uint8_t idx = 0; idx < heater::NUMBER_OF_HEATERS; idx++) { + if (heaterVec[idx].active) { + switch (heaterVec[idx].action) { case SET_SWITCH_ON: - handleSwitchOnCommand(heaterMapIter); + handleSwitchOnCommand(idx); break; case SET_SWITCH_OFF: - handleSwitchOffCommand(heaterMapIter); + handleSwitchOffCommand(idx); break; default: sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded" @@ -195,156 +177,113 @@ void HeaterHandler::handleActiveCommands() { } } -void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) { +void HeaterHandler::handleSwitchOnCommand(uint8_t heaterIdx) { ReturnValue_t result = RETURN_OK; - switchNr_t switchNr; - + auto& heater = heaterVec.at(heaterIdx); /* Check if command waits for main switch being set on and whether the timeout has expired */ - if (heaterMapIter->second.waitMainSwitchOn && - heaterMapIter->second.mainSwitchCountdown.hasTimedOut()) { + if (heater.waitMainSwitchOn && heater.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); + heater.active = false; + heater.waitMainSwitchOn = false; + if (heater.replyQueue != commandQueue->getId()) { + actionHelper.finish(false, heater.replyQueue, heater.action, MAIN_SWITCH_SET_TIMEOUT); } return; } - switchNr = heaterMapIter->first; - /* Check state of main line switch */ + // 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); + if (!checkSwitchState(heaterIdx)) { + gpioId_t gpioId = heater.gpioId; 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; + heater.switchState = ON; } } else { - triggerEvent(SWITCH_ALREADY_ON, switchNr); + triggerEvent(SWITCH_ALREADY_ON, heaterIdx); } - /* There is no need to send action finish replies if the sender was the - * HeaterHandler itself. */ - if (heaterMapIter->second.replyQueue != commandQueue->getId()) { + // There is no need to send action finish replies if the sender was the + // HeaterHandler itself + if (heater.replyQueue != commandQueue->getId()) { if (result == RETURN_OK) { - actionHelper.finish(true, heaterMapIter->second.replyQueue, heaterMapIter->second.action, - result); + actionHelper.finish(true, heater.replyQueue, heater.action, result); } else { - actionHelper.finish(false, heaterMapIter->second.replyQueue, heaterMapIter->second.action, - result); + actionHelper.finish(false, heater.replyQueue, heater.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 */ + heater.active = false; + heater.waitMainSwitchOn = false; + } else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF && heater.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; + heater.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs()); + heater.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); + if (heater.replyQueue != commandQueue->getId()) { + actionHelper.finish(false, heater.replyQueue, heater.action, mainSwitchState); } - heaterMapIter->second.active = false; + heater.active = false; } } -void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) { +void HeaterHandler::handleSwitchOffCommand(uint8_t heaterIdx) { ReturnValue_t result = RETURN_OK; - switchNr_t switchNr = heaterMapIter->first; - /* Check whether switch is already off */ - if (checkSwitchState(switchNr)) { - gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr); + auto& heater = heaterVec.at(heaterIdx); + // Check whether switch is already off + if (checkSwitchState(heaterIdx)) { + gpioId_t gpioId = heater.gpioId; 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 */ + heater.switchState = 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); + triggerEvent(SWITCH_ALREADY_OFF, heaterIdx); } - if (heaterMapIter->second.replyQueue != NO_COMMANDER) { - /* Report back switch command reply if necessary */ + if (heater.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); + actionHelper.finish(true, heater.replyQueue, heater.action, result); } else { - actionHelper.finish(false, heaterMapIter->second.replyQueue, heaterMapIter->second.action, - result); + actionHelper.finish(false, heater.replyQueue, heater.action, result); } } - heaterMapIter->second.active = false; + heater.active = false; } -bool HeaterHandler::checkSwitchState(int switchNr) { return switchStates[switchNr]; } +HeaterHandler::SwitchState HeaterHandler::checkSwitchState(uint8_t switchNr) { + return heaterVec.at(switchNr).switchState; +} 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]; + for (power::Switch_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) { + allSwitchesOrd = allSwitchesOrd || heaterVec.at(switchNr).switchState; } 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(); } ReturnValue_t HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) { return RETURN_OK; } @@ -354,10 +293,3 @@ 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 2000; } - -ReturnValue_t HeaterHandler::setHealth(HealthState health) { - healthHelper.setHealth(health); - return RETURN_OK; -} - -HasHealthIF::HealthState HeaterHandler::getHealth() { return healthHelper.getHealth(); } diff --git a/mission/devices/HeaterHandler.h b/mission/devices/HeaterHandler.h index aa8eea90..28ac9899 100644 --- a/mission/devices/HeaterHandler.h +++ b/mission/devices/HeaterHandler.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -13,13 +14,26 @@ #include #include -#include +#include #include "devices/heaterSwitcherList.h" class PowerSwitchIF; class HealthTableIF; +namespace heater { + +static constexpr uint8_t NUMBER_OF_HEATERS = 8; + +} + +using HeaterPair = std::pair; + +struct HeaterHelper { + public: + HeaterHelper(std::array heaters) : heaters(heaters) {} + std::array heaters = {}; +}; /** * @brief This class intends the control of heaters. * @@ -27,7 +41,6 @@ class HealthTableIF; */ class HeaterHandler : public ExecutableObjectIF, public PowerSwitchIF, - public HasHealthIF, public SystemObject, public HasActionsIF { public: @@ -42,24 +55,11 @@ class HeaterHandler : public ExecutableObjectIF, /** Device command IDs */ static const DeviceCommandId_t SWITCH_HEATER = 0x0; - HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF* gpioCookie, + HeaterHandler(object_id_t setObjectId, GpioIF* gpioInterface_, HeaterHelper helper, PowerSwitchIF* mainLineSwitcherObjectId, power::Switch_t mainLineSwitch); virtual ~HeaterHandler(); - /** - * @brief Set the Health State - * The parent will be informed, if the Health changes - * @param health - */ - ReturnValue_t setHealth(HealthState health) override; - - /** - * @brief Get Health State - * @return Health State of the object - */ - HasHealthIF::HealthState getHealth() override; - virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; virtual ReturnValue_t sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override; @@ -88,6 +88,7 @@ class HeaterHandler : public ExecutableObjectIF, static const MessageQueueId_t NO_COMMANDER = 0; enum SwitchState : bool { ON = true, OFF = false }; + enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE }; /** * @brief Struct holding information about a heater command to execute. @@ -99,35 +100,27 @@ class HeaterHandler : public ExecutableObjectIF, * @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; + struct HeaterWrapper { + HeaterWrapper(HeaterPair pair) : healthDevice(pair.first), gpioId(pair.second) {} + HealthDevice* healthDevice = nullptr; + gpioId_t gpioId = gpio::NO_GPIO; + SwitchAction action = SwitchAction::NONE; + MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE; bool active = false; + SwitchState switchState = SwitchState::OFF; bool waitMainSwitchOn = false; Countdown mainSwitchCountdown; - } HeaterCommandInfo_t; + }; - enum SwitchAction { SET_SWITCH_OFF, SET_SWITCH_ON }; + using HeaterMap = std::vector; - using switchNr_t = uint8_t; - using HeaterMap = std::unordered_map; - using HeaterMapIter = HeaterMap::iterator; + HeaterMap heaterVec = {}; - HeaterMap heaterMap; - - bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES]; + HeaterHelper helper; /** 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. */ @@ -141,11 +134,9 @@ class HeaterHandler : public ExecutableObjectIF, /** Switch number of the heater power supply switch */ power::Switch_t mainLineSwitch; - HealthHelper healthHelper; - ActionHelper actionHelper; - StorageManagerIF* IPCStore = nullptr; + StorageManagerIF* ipcStore = nullptr; void readCommandQueue(); @@ -153,13 +144,7 @@ class HeaterHandler : public ExecutableObjectIF, * @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); + SwitchState checkSwitchState(power::Switch_t switchNr); /** * @brief This function runs commands waiting for execution. @@ -173,9 +158,9 @@ class HeaterHandler : public ExecutableObjectIF, */ void setInitialSwitchStates(); - void handleSwitchOnCommand(HeaterMapIter heaterMapIter); + void handleSwitchOnCommand(uint8_t heaterIdx); - void handleSwitchOffCommand(HeaterMapIter heaterMapIter); + void handleSwitchOffCommand(uint8_t heaterIdx); /** * @brief Checks if all switches are off.