diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 72e11d44..d3078f82 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -114,46 +116,59 @@ void ObjectFactory::produce(){ i2cCookieTmp1075tcs2); tmp1075Handler_2->setStartUpImmediately(); - GpioCookie* gpioCookie = new GpioCookie; + GpioCookie* heaterGpiosCookie = new GpioCookie; new LinuxLibgpioIF(objects::GPIO_IF); #if TE0720 == 0 /* Pin H2-11 on stack connector */ GpioConfig_t gpioConfigHeater0(std::string("gpiochip7"), 18, std::string("Heater0"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0); + heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0); /* Pin H2-12 on stack connector */ GpioConfig_t gpioConfigHeater1(std::string("gpiochip7"), 14, std::string("Heater1"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1); + heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1); /* Pin H2-13 on stack connector */ GpioConfig_t gpioConfigHeater2(std::string("gpiochip7"), 20, std::string("Heater2"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2); + heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2); GpioConfig_t gpioConfigHeater3(std::string("gpiochip7"), 16, std::string("Heater3"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3); + heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3); GpioConfig_t gpioConfigHeater4(std::string("gpiochip7"), 24, std::string("Heater4"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4); + heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4); GpioConfig_t gpioConfigHeater5(std::string("gpiochip7"), 26, std::string("Heater5"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5); + heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5); GpioConfig_t gpioConfigHeater6(std::string("gpiochip7"), 22, std::string("Heater6"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6); + heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6); GpioConfig_t gpioConfigHeater7(std::string("gpiochip7"), 28, std::string("Heater7"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7); + heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); + + GpioCookie* solarArrayDeplCookie = new GpioCookie; + GpioConfig_t gpioConfigDeplSA1(std::string("gpiochip7"), 25, + std::string("DeplSA1"), gpio::OUT, 0); + solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpioConfigDeplSA1); + GpioConfig_t gpioConfigDeplSA2(std::string("gpiochip7"), 23, + std::string("DeplSA2"), gpio::OUT, 0); + solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpioConfigDeplSA2); + + //TODO: Find out burn time. For now set to 1000 ms. + new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, + solarArrayDeplCookie, objects::PCDU_HANDLER, pcduSwitches::DEPLOYMENT_MECHANISM, + gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); #endif new TmTcUnixUdpBridge(objects::UDP_BRIDGE, @@ -165,14 +180,15 @@ void ObjectFactory::produce(){ /* Configure MIO0 as input */ GpioConfig_t gpioConfigMio0(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); + GpioCookie* gpioCookie = new GpioCookie; gpioCookie->addGpio(gpioIds::Test_ID, gpioConfigMio0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #elif TE0720 == 1 /* Configuration for MIO0 on TE0720-03-1CFA */ GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0, std::string("Heater0"), gpio::OUT, 0); - gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER, + heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); #endif } diff --git a/bsp_q7s/devices/HeaterHandler.h b/bsp_q7s/devices/HeaterHandler.h index 5406df8d..01319ce9 100644 --- a/bsp_q7s/devices/HeaterHandler.h +++ b/bsp_q7s/devices/HeaterHandler.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,7 @@ public: private: - static const uint8_t INTERFACE_ID = CLASS_ID::PCDU_HANDLER; + 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); @@ -60,7 +59,7 @@ private: 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::PCDU_HANDLER; + 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); @@ -139,9 +138,6 @@ private: void readCommandQueue(); - ReturnValue_t buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen); /** * @brief Returns the state of a switch (ON - true, or OFF - false). * @param switchNr The number of the switch to check. diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index b429f491..abfb7456 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -19,9 +19,10 @@ debugging. */ #define TE0720 0 -#define P60DOCK_DEBUG 0 -#define PDU1_DEBUG 0 -#define PDU2_DEBUG 0 +#define P60DOCK_DEBUG 0 +#define PDU1_DEBUG 0 +#define PDU2_DEBUG 0 +#define ACU_DEBUG 1 #ifdef __cplusplus diff --git a/fsfwconfig/devices/gpioIds.h b/fsfwconfig/devices/gpioIds.h index cfef7e75..70507b42 100644 --- a/fsfwconfig/devices/gpioIds.h +++ b/fsfwconfig/devices/gpioIds.h @@ -13,6 +13,8 @@ namespace gpioIds { HEATER_5, HEATER_6, HEATER_7, + DEPLSA1, + DEPLSA2, Test_ID }; } diff --git a/fsfwconfig/events/subsystemIdRanges.h b/fsfwconfig/events/subsystemIdRanges.h index e04d57fb..b2e9aaac 100644 --- a/fsfwconfig/events/subsystemIdRanges.h +++ b/fsfwconfig/events/subsystemIdRanges.h @@ -19,7 +19,9 @@ enum: uint8_t { PUS_SERVICE_23, MGM_LIS3MDL, MGM_RM3100, - PCDU_HANDLER + PCDU_HANDLER, + HEATER_HANDLER, + SA_DEPL_HANDLER }; } diff --git a/fsfwconfig/objects/systemObjectList.h b/fsfwconfig/objects/systemObjectList.h index d5a2e737..153b3155 100644 --- a/fsfwconfig/objects/systemObjectList.h +++ b/fsfwconfig/objects/systemObjectList.h @@ -43,10 +43,11 @@ namespace objects { TMP1075_HANDLER_2 = 0x44000006, /* Custom device handler */ - PCDU_HANDLER = 0x45000001, + PCDU_HANDLER = 0x44000007, + SOLAR_ARRAY_DEPL_HANDLER = 0x44000008, /* 0x54 ('T') for thermal objects */ - HEATER_HANDLER = 0x54000001, + HEATER_HANDLER = 0x54000003, /* 0x54 ('T') for test handlers */ TEST_TASK = 0x54694269, diff --git a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp index ba6706cf..d6f922dd 100644 --- a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp @@ -15,6 +15,8 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::HEATER_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SOLAR_ARRAY_DEPL_HANDLER, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE); diff --git a/fsfwconfig/returnvalues/classIds.h b/fsfwconfig/returnvalues/classIds.h index e259b46f..419a24ef 100644 --- a/fsfwconfig/returnvalues/classIds.h +++ b/fsfwconfig/returnvalues/classIds.h @@ -14,7 +14,9 @@ enum { MGM_LIS3MDL, MGM_RM3100, LINUX_LIBGPIO_IF, - PCDU_HANDLER + PCDU_HANDLER, + HEATER_HANDLER, + SA_DEPL_HANDLER }; } diff --git a/linux/csp/CspComIF.cpp b/linux/csp/CspComIF.cpp index 64808eff..bfe7e7e9 100644 --- a/linux/csp/CspComIF.cpp +++ b/linux/csp/CspComIF.cpp @@ -214,6 +214,7 @@ ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort, if(expectedSize != 0){ sif::error << "CspComIF::cspTransfer: Received more bytes than requested" << std::endl; + sif::debug << "CspComIF::cspTransfer: Received bytes: " << bytesRead << std::endl; csp_close(conn); return RETURN_FAILED; } diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 65b82573..269174e4 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -41,7 +41,7 @@ public: virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0; /** - * @brief This function requires a child to implement the functionaliy to read the state of + * @brief This function requires a child to implement the functionality to read the state of * an ouput or input gpio. * * @param gpioId A unique number which specifies the GPIO to read. diff --git a/mission/devices/ACUHandler.cpp b/mission/devices/ACUHandler.cpp index f1a823b3..3d5d82e8 100644 --- a/mission/devices/ACUHandler.cpp +++ b/mission/devices/ACUHandler.cpp @@ -1,14 +1,268 @@ #include "ACUHandler.h" +#include "OBSWConfig.h" ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : GomspaceDeviceHandler(objectId, comIF, comCookie, ACU::MAX_CONFIGTABLE_ADDRESS, - ACU::MAX_HKTABLE_ADDRESS, ACU::HK_TABLE_SIZE, &acuHkTableDataset), acuHkTableDataset( + ACU::MAX_HKTABLE_ADDRESS, ACU::HK_TABLE_REPLY_SIZE, &acuHkTableDataset), acuHkTableDataset( this) { } ACUHandler::~ACUHandler() { } +ReturnValue_t ACUHandler::buildNormalDeviceCommand( + DeviceCommandId_t * id) { + *id = GOMSPACE::REQUEST_HK_TABLE; + return buildCommandFromCommand(*id, NULL, 0); +} + void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { + parseHkTableReply(packet); + handleDeviceTM(&acuHkTableDataset, id, true); + +#if OBSW_ENHANCED_PRINTOUT == 1 && ACU_DEBUG == 1 + acuHkTableDataset.read(); + float temperatureC_1 = acuHkTableDataset.temperature1.value * 0.1; + float temperatureC_2 = acuHkTableDataset.temperature2.value * 0.1; + float temperatureC_3 = acuHkTableDataset.temperature3.value * 0.1; + sif::info << "ACU: Temperature 1: " << temperatureC_1 << " °C" << std::endl; + sif::info << "ACU: Temperature 2: " << temperatureC_2 << " °C" << std::endl; + sif::info << "ACU: Temperature 3: " << temperatureC_3 << " °C" << std::endl; + sif::info << "ACU: Ground Watchdog Timer Count: " + << acuHkTableDataset.wdtCntGnd.value << std::endl; + sif::info << "ACU: Ground watchdog timer, seconds left before reboot: " + << acuHkTableDataset.wdtGndLeft.value << std::endl; + acuHkTableDataset.commit(); +#endif +} + +void ACUHandler::parseHkTableReply(const uint8_t *packet) { + uint16_t dataOffset = 0; + acuHkTableDataset.read(); + dataOffset += 12; + acuHkTableDataset.currentInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.currentInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.currentInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.currentInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.currentInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.currentInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.voltageInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.voltageInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.voltageInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.voltageInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.voltageInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.voltageInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.vcc = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.vbat = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.temperature1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.temperature2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.temperature3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.mpptMode = *(packet + dataOffset); + dataOffset += 3; + + acuHkTableDataset.vboostInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.vboostInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.vboostInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.vboostInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.vboostInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.vboostInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.powerInChannel0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.powerInChannel1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.powerInChannel2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.powerInChannel3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.powerInChannel4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.powerInChannel5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.dac0Enable = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.dac1Enable = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.dac2Enable = *(packet + dataOffset); + dataOffset += 3; + + acuHkTableDataset.dacRawChannelVal0 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.dacRawChannelVal1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.dacRawChannelVal2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.dacRawChannelVal3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.dacRawChannelVal4 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.dacRawChannelVal5 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.bootCause = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + dataOffset += 6; + acuHkTableDataset.bootcnt = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + dataOffset += 6; + acuHkTableDataset.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + dataOffset += 6; + acuHkTableDataset.resetCause = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + acuHkTableDataset.mpptTime = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + /* +12 because here starts the second csp packet */ + dataOffset += 2 + 12; + + acuHkTableDataset.mpptPeriod = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + dataOffset += 4; + + acuHkTableDataset.device0 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device1 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device2 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device3 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device4 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device5 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device6 = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device7 = *(packet + dataOffset); + dataOffset += 3; + + acuHkTableDataset.device0Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device1Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device2Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device3Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device4Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device5Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device6Status = *(packet + dataOffset); + dataOffset += 3; + acuHkTableDataset.device7Status = *(packet + dataOffset); + dataOffset += 3; + + acuHkTableDataset.wdtCntGnd = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + dataOffset += 6; + acuHkTableDataset.wdtGndLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 | *(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3); + dataOffset += 6; + + acuHkTableDataset.commit(); +} + +ReturnValue_t ACUHandler::initializeLocalDataPool( + localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + + localDataPoolMap.emplace(P60System::ACU_CURRENT_IN_CHANNEL0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_CURRENT_IN_CHANNEL1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_CURRENT_IN_CHANNEL2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_CURRENT_IN_CHANNEL3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_CURRENT_IN_CHANNEL4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_CURRENT_IN_CHANNEL5, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_VOLTAGE_IN_CHANNEL0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VOLTAGE_IN_CHANNEL1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VOLTAGE_IN_CHANNEL2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VOLTAGE_IN_CHANNEL3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VOLTAGE_IN_CHANNEL4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VOLTAGE_IN_CHANNEL5, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_VCC, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VBAT, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_TEMPERATURE_1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_TEMPERATURE_2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_TEMPERATURE_3, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_MPPT_MODE, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_VBOOST_CHANNEL0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VBOOST_CHANNEL1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VBOOST_CHANNEL2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VBOOST_CHANNEL3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VBOOST_CHANNEL4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_VBOOST_CHANNEL5, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_POWER_CHANNEL0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_POWER_CHANNEL1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_POWER_CHANNEL2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_POWER_CHANNEL3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_POWER_CHANNEL4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_POWER_CHANNEL5, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_DAC_EN_0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_EN_1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_EN_2, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_DAC_RAW_0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_RAW_1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_RAW_2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_RAW_3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_RAW_4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DAC_RAW_5, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_BOOTCAUSE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_BOOTCNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_UPTIME, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_RESET_CAUSE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_MPPT_TIME, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_MPPT_PERIOD, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_DEVICE_0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_7, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_DEVICE_0_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_1_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_2_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_3_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_4_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_5_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_6_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_DEVICE_7_STATUS, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(P60System::ACU_WDT_CNT_GND, new PoolEntry( { 0 })); + localDataPoolMap.emplace(P60System::ACU_WDT_GND_LEFT, new PoolEntry( { 0 })); + + return HasReturnvaluesIF::RETURN_OK; } diff --git a/mission/devices/ACUHandler.h b/mission/devices/ACUHandler.h index e03780a4..8ab32a24 100644 --- a/mission/devices/ACUHandler.h +++ b/mission/devices/ACUHandler.h @@ -12,13 +12,28 @@ class ACUHandler: public GomspaceDeviceHandler { public: ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie); virtual ~ACUHandler(); + + virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + protected: virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override; + /** + * @brief As soon as the device is in MODE_NORMAL, this function is executed periodically. + */ + virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override; + private: ACU::HkTableDataset acuHkTableDataset; + + /** + * @brief Function extracts the hk table information from the received csp packet and stores + * the values in the acuHkTableDataset. + */ + void parseHkTableReply(const uint8_t *packet); }; #endif /* MISSION_DEVICES_ACUHANDLER_H_ */ diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index a8205276..4f45a7e6 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -10,6 +10,8 @@ target_sources(${TARGET_NAME} PUBLIC PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp + HeaterHandler.cpp + SolarArrayDeploymentHandler.cpp ) diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 9fe9fbdb..0b3b1459 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -206,6 +206,10 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN; pdu = objectManager->get(objects::PDU2_HANDLER); break; + case pcduSwitches::DEPLOYMENT_MECHANISM: + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM; + pdu = objectManager->get(objects::PDU2_HANDLER); + break; default: sif::error << "PCDUHandler::sendSwitchCommand: Invalid switch number " << std::endl; return; diff --git a/mission/devices/PDU1Handler.cpp b/mission/devices/PDU1Handler.cpp index 540f0637..92281f49 100644 --- a/mission/devices/PDU1Handler.cpp +++ b/mission/devices/PDU1Handler.cpp @@ -15,7 +15,6 @@ ReturnValue_t PDU1Handler::buildNormalDeviceCommand( DeviceCommandId_t * id) { *id = GOMSPACE::REQUEST_HK_TABLE; return buildCommandFromCommand(*id, NULL, 0); - return RETURN_OK; } void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp new file mode 100644 index 00000000..45521800 --- /dev/null +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -0,0 +1,197 @@ +#include +#include +#include +#include + +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(gpioDriverId); + if (gpioInterface == nullptr) { + sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface." + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + result = gpioInterface->initialize(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(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(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(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(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(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(); +} diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h new file mode 100644 index 00000000..279ae5da --- /dev/null +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -0,0 +1,158 @@ +#ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ +#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @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; + + /** 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_ */ diff --git a/mission/devices/devicedefinitions/GomspaceDefinitions.h b/mission/devices/devicedefinitions/GomspaceDefinitions.h index 7ff13d21..4600ecc7 100644 --- a/mission/devices/devicedefinitions/GomspaceDefinitions.h +++ b/mission/devices/devicedefinitions/GomspaceDefinitions.h @@ -318,7 +318,6 @@ namespace P60System { ACU_POWER_CHANNEL3, ACU_POWER_CHANNEL4, ACU_POWER_CHANNEL5, - ACU_POWER_GROUP, ACU_DAC_EN_0, ACU_DAC_EN_1, ACU_DAC_EN_2, @@ -357,10 +356,9 @@ namespace P60System { namespace P60Dock { - /* The maximum size of a reply from the P60 dock. Maximum size is reached - * when retrieving the full parameter configuration table. 412 bytes of - * payload data and 12 bytes of CSP header data. */ - static const uint16_t MAX_REPLY_LENGTH = 424; + + /** Max reply size reached when requesting full hk table */ + static const uint16_t MAX_REPLY_LENGTH = 407; static const uint16_t MAX_CONFIGTABLE_ADDRESS = 408; static const uint16_t MAX_HKTABLE_ADDRESS = 187; @@ -1043,11 +1041,11 @@ namespace ACU { static const uint32_t HK_TABLE_DATA_SET_ID = 0x4; /* When receiving full housekeeping (telemetry) table */ - static const uint16_t MAX_REPLY_LENGTH = 124; + static const uint16_t MAX_REPLY_LENGTH = 262; static const uint16_t MAX_CONFIGTABLE_ADDRESS = 26; static const uint16_t MAX_HKTABLE_ADDRESS = 120; - static const uint16_t HK_TABLE_SIZE = 125; static const uint8_t HK_TABLE_ENTRIES = 64; + static const uint16_t HK_TABLE_REPLY_SIZE = 262; /** * @brief This class defines a dataset for the hk table of the ACU. @@ -1153,8 +1151,6 @@ namespace ACU { lp_var_t bootCause = lp_var_t(sid.objectId, P60System::ACU_BOOTCAUSE, this); - lp_var_t bootcause = lp_var_t(sid.objectId, - P60System::ACU_BOOTCAUSE, this); lp_var_t bootcnt = lp_var_t(sid.objectId, P60System::ACU_BOOTCNT, this); lp_var_t uptime = lp_var_t(sid.objectId,