From 40d9829700dc6f2a2372d663bb76dc8bd945c18d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 16 Mar 2022 20:13:21 +0100 Subject: [PATCH 1/2] Major update for power handling and various smaller updates --- .../fsfwconfig/devices/powerSwitcherList.h | 57 ---- common/config/devices/powerSwitcherList.h | 97 +++--- linux/fsfwconfig/OBSWConfig.h.in | 25 +- linux/fsfwconfig/devices/powerSwitcherList.h | 57 ---- .../pollingSequenceFactory.cpp | 27 +- mission/devices/GomspaceDeviceHandler.cpp | 18 +- mission/devices/P60DockHandler.cpp | 91 +++-- mission/devices/P60DockHandler.h | 4 +- mission/devices/PCDUHandler.cpp | 311 +++++++++++++----- mission/devices/PCDUHandler.h | 18 +- mission/devices/PDU1Handler.cpp | 62 +++- mission/devices/PDU1Handler.h | 5 +- mission/devices/PDU2Handler.cpp | 74 ++++- mission/devices/PDU2Handler.h | 5 +- mission/devices/RadiationSensorHandler.cpp | 1 + .../devices/SolarArrayDeploymentHandler.cpp | 3 +- mission/devices/SolarArrayDeploymentHandler.h | 4 +- .../devicedefinitions/GomspaceDefinitions.h | 9 +- .../devicedefinitions/powerDefinitions.h | 20 ++ mission/devices/max1227.h | 4 +- 20 files changed, 570 insertions(+), 322 deletions(-) delete mode 100644 bsp_hosted/fsfwconfig/devices/powerSwitcherList.h delete mode 100644 linux/fsfwconfig/devices/powerSwitcherList.h create mode 100644 mission/devices/devicedefinitions/powerDefinitions.h diff --git a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h b/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index ae259374..00000000 --- a/bsp_hosted/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,57 +0,0 @@ -#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 { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - 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 BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -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; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} // namespace pcduSwitches - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/common/config/devices/powerSwitcherList.h b/common/config/devices/powerSwitcherList.h index 45428a2e..f99e0930 100644 --- a/common/config/devices/powerSwitcherList.h +++ b/common/config/devices/powerSwitcherList.h @@ -3,58 +3,67 @@ #include "OBSWConfig.h" +#include #include namespace pcduSwitches { - /* Switches are uint8_t datatype and go from 0 to 255 */ - enum SwitcherList: uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - NUMBER_OF_SWITCHES - }; +/* Switches are uint8_t datatype and go from 0 to 255 */ +enum Switches: uint8_t { + PDU1_CH0_TCS_BOARD_3V3, + PDU1_CH1_SYRLINKS_12V, + PDU1_CH2_STAR_TRACKER_5V, + PDU1_CH3_MGT_5V, + PDU1_CH4_SUS_NOMINAL_3V3, + PDU1_CH5_SOLAR_CELL_EXP_5V, + PDU1_CH6_PLOC_12V, + PDU1_CH7_ACS_A_SIDE_3V3, + PDU1_CH8_UNOCCUPIED, - static const uint8_t ON = 1; - static const uint8_t OFF = 0; + PDU2_CH0_Q7S, + PDU2_CH1_PL_PCDU_BATT_0_14V8, + PDU2_CH2_RW_5V, + PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + PDU2_CH4_SUS_REDUNDANT_3V3, + PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + PDU2_CH6_PL_PCDU_BATT_1_14V8, + PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + PDU2_CH8_PAYLOAD_CAMERA, + NUMBER_OF_SWITCHES +}; - /* 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; +static const uint8_t ON = 1; +static const uint8_t OFF = 0; + +// Output states after reboot of the PDUs + +const std::array INIT_SWITCH_STATES = { + // PDU 1 +// Because the TE0720 is not connected to the PCDU, this switch is always on #if BOARD_TE0720 == 1 - /* Because the TE0720 is not connected to the PCDU, this switch is always on */ - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON; + ON, #else - static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF; + 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; - static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; - static const uint8_t INIT_STATE_SYRLINKS = OFF; - static const uint8_t INIT_STATE_STAR_TRACKER = OFF; - static const uint8_t INIT_STATE_MGT = OFF; - static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; - static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; - static const uint8_t INIT_STATE_PLOC = OFF; - static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + + // PDU 2 + ON, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF, + OFF +}; } - #endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index e30e05ed..1a12229a 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -38,9 +38,9 @@ debugging. */ #define OBSW_USE_CCSDS_IP_CORE 1 // Set to 1 if all telemetry should be sent to the PTME IP Core -#define OBSW_TM_TO_PTME 1 +#define OBSW_TM_TO_PTME 0 // Set to 1 if telecommands are received via the PDEC IP Core -#define OBSW_TC_FROM_PDEC 1 +#define OBSW_TC_FROM_PDEC 0 #define OBSW_ENABLE_TIMERS 1 #define OBSW_ADD_MGT 1 @@ -50,18 +50,23 @@ debugging. */ #define OBSW_ADD_PLOC_MPSOC 0 #define OBSW_ADD_SUN_SENSORS 0 #define OBSW_ADD_ACS_BOARD 1 -#define OBSW_ADD_ACS_HANDLERS 0 +#define OBSW_ADD_ACS_HANDLERS 1 #define OBSW_ADD_RW 0 -#define OBSW_ADD_RTD_DEVICES 0 +#define OBSW_ADD_RTD_DEVICES 1 #define OBSW_ADD_TMP_DEVICES 0 #define OBSW_ADD_RAD_SENSORS 0 #define OBSW_ADD_PL_PCDU 0 #define OBSW_ADD_SYRLINKS 0 #define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 -#define OBSW_SYRLINKS_SIMULATED 1 #define OBSW_STAR_TRACKER_GROUND_CONFIG 1 #define OBSW_ENABLE_PERIODIC_HK 0 -#define OBSW_PRINT_CORE_HK 0 + +// This is a really tricky switch.. It initializes the PCDU switches to their default states +// at powerup. I think it would be better +// to leave it off for now. It makes testing a lot more difficult and it might mess with +// something the operators might want to do by giving the software too much intelligence +// at the wrong place. The system component might command all the Switches accordingly anyway +#define OBSW_INITIALIZE_SWITCHES 0 #endif @@ -88,6 +93,7 @@ debugging. */ #define OBSW_ADD_UART_TEST_CODE 0 #define OBSW_TEST_ACS 0 +#define OBSW_TEST_ACS_BOARD_ASS 0 #define OBSW_DEBUG_ACS 0 #define OBSW_TEST_SUS 0 #define OBSW_DEBUG_SUS 0 @@ -97,16 +103,19 @@ debugging. */ #define OBSW_DEBUG_RAD_SENSOR 0 #define OBSW_TEST_PL_PCDU 0 #define OBSW_DEBUG_PL_PCDU 0 +#define OBSW_TEST_BPX_BATT 0 +#define OBSW_DEBUG_BPX_BATT 0 + #define OBSW_TEST_LIBGPIOD 0 #define OBSW_TEST_PLOC_HANDLER 0 -#define OBSW_TEST_BPX_BATT 0 #define OBSW_TEST_CCSDS_BRIDGE 0 #define OBSW_TEST_CCSDS_PTME 0 #define OBSW_TEST_TE7020_HEATER 0 #define OBSW_TEST_GPIO_OPEN_BY_LABEL 0 #define OBSW_TEST_GPIO_OPEN_BY_LINE_NAME 0 #define OBSW_DEBUG_P60DOCK 0 -#define OBSW_DEBUG_BPX_BATT 0 + +#define OBSW_PRINT_CORE_HK 0 #define OBSW_DEBUG_PDU1 0 #define OBSW_DEBUG_PDU2 0 #define OBSW_DEBUG_GPS 0 diff --git a/linux/fsfwconfig/devices/powerSwitcherList.h b/linux/fsfwconfig/devices/powerSwitcherList.h deleted file mode 100644 index cc6bc141..00000000 --- a/linux/fsfwconfig/devices/powerSwitcherList.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ -#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ - -#include "OBSWConfig.h" - -namespace pcduSwitches { -/* Switches are uint8_t datatype and go from 0 to 255 */ -enum SwitcherList : uint8_t { - Q7S, - PAYLOAD_PCDU_CH1, - RW, - TCS_BOARD_8V_HEATER_IN, - SUS_REDUNDANT, - DEPLOYMENT_MECHANISM, - PAYLOAD_PCDU_CH6, - ACS_BOARD_SIDE_B, - PAYLOAD_CAMERA, - TCS_BOARD_3V3, - SYRLINKS, - STAR_TRACKER, - MGT, - SUS_NOMINAL, - SOLAR_CELL_EXP, - PLOC, - ACS_BOARD_SIDE_A, - 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 BOARD_TE0720 == 1 -/* Because the TE0720 is not connected to the PCDU, this switch is always on */ -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; -static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF; -static const uint8_t INIT_STATE_SYRLINKS = OFF; -static const uint8_t INIT_STATE_STAR_TRACKER = OFF; -static const uint8_t INIT_STATE_MGT = OFF; -static const uint8_t INIT_STATE_SUS_NOMINAL = OFF; -static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF; -static const uint8_t INIT_STATE_PLOC = OFF; -static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF; -} // namespace pcduSwitches - -#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 06a884ea..41866af5 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -32,6 +32,13 @@ ReturnValue_t pst::pstGpio(FixedTimeslotTaskIF *thisSequence) { ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { uint32_t length = thisSequence->getPeriodMs(); static_cast(length); +#if OBSW_ADD_PL_PCDU == 1 + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); +#endif #if OBSW_ADD_TMP_DEVICES == 1 thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, DeviceHandlerIF::PERFORM_OPERATION); @@ -357,7 +364,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { #endif #if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 - bool enableAside = false; + bool enableAside = true; bool enableBside = true; if (enableAside) { // A side @@ -424,17 +431,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { } #endif /* OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 */ - ReturnValue_t seqCheck = thisSequence->checkSequence(); - if (seqCheck != HasReturnvaluesIF::RETURN_OK) { - if (seqCheck == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { - sif::warning << "SPI PST is empty.." << std::endl; - } else { - sif::error << "SPI PST initialization failed" << std::endl; - } - - return seqCheck; - } - return HasReturnvaluesIF::RETURN_OK; + return thisSequence->checkSequence(); } ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { @@ -456,11 +453,7 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); #endif static_cast(length); - if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { - sif::error << "I2C PST initialization failed" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + return thisSequence->checkSequence(); } ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index 4cec651e..25bde5db 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -1,5 +1,9 @@ -#include -#include +#include "GomspaceDeviceHandler.h" + +#include + +#include "devicedefinitions/GomSpacePackets.h" +#include "devicedefinitions/powerDefinitions.h" GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, uint16_t maxConfigTableAddress, @@ -70,7 +74,8 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t d } break; } - case (GOMSPACE::PRINT_SWITCH_V_I): { + case (GOMSPACE::PRINT_SWITCH_V_I): + case (GOMSPACE::PRINT_LATCHUPS): { result = printStatus(deviceCommand); break; } @@ -95,6 +100,7 @@ void GomspaceDeviceHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3); this->insertInCommandMap(GOMSPACE::GNDWDT_RESET); this->insertInCommandMap(GOMSPACE::PRINT_SWITCH_V_I); + this->insertInCommandMap(GOMSPACE::PRINT_LATCHUPS); } ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize, @@ -189,6 +195,12 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm size_t commandDataLen) { ReturnValue_t result = setParamCacher.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG); + // This breaks layering but I really don't want to accept this command.. + if (setParamCacher.getAddress() == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S and + this->getObjectId() == objects::PDU2_HANDLER) { + triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0); + return HasReturnvaluesIF::RETURN_FAILED; + } if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " "message" diff --git a/mission/devices/P60DockHandler.cpp b/mission/devices/P60DockHandler.cpp index a89debc6..b506a92b 100644 --- a/mission/devices/P60DockHandler.cpp +++ b/mission/devices/P60DockHandler.cpp @@ -217,9 +217,10 @@ void P60DockHandler::parseHkTableReply(const uint8_t *packet) { p60dockHkTableDataset.latchupsGS3V3 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; - p60dockHkTableDataset.vbatVoltageValue = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + p60dockHkTableDataset.dockVbatVoltageValue = + *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; - p60dockHkTableDataset.vccCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); + p60dockHkTableDataset.dockVccCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; p60dockHkTableDataset.batteryCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1); dataOffset += 4; @@ -444,63 +445,113 @@ ReturnValue_t P60DockHandler::initializeLocalDataPool(localpool::DataPool &local } ReturnValue_t P60DockHandler::printStatus(DeviceCommandId_t cmd) { + ReturnValue_t result = RETURN_OK; switch (cmd) { case (GOMSPACE::PRINT_SWITCH_V_I): { PoolReadGuard pg(&p60dockHkTableDataset); - ReturnValue_t readResult = pg.getReadResult(); - if (readResult != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Reading PDU1 HK table failed!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + result = pg.getReadResult(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + printHkTableSwitchIV(); + return HasReturnvaluesIF::RETURN_OK; + } + case (GOMSPACE::PRINT_LATCHUPS): { + PoolReadGuard pg(&p60dockHkTableDataset); + result = pg.getReadResult(); + printHkTableLatchups(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; } - printHkTable(); return HasReturnvaluesIF::RETURN_OK; } default: { return HasReturnvaluesIF::RETURN_FAILED; } } + sif::warning << "Reading P60 Dock HK table failed" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } -void P60DockHandler::printHkTable() { - sif::info << "P60 Dock Info: SwitchState, Currents [mA], Voltages [mV]" << std::endl; - - sif::info << std::setw(30) << std::left << "ACU VCC" << std::dec << "| " +void P60DockHandler::printHkTableSwitchIV() { + sif::info << "P60 Dock Info:" << std::endl; + sif::info << "Boot Cause: " << p60dockHkTableDataset.bootcause + << " | Boot Count: " << std::setw(4) << std::right << p60dockHkTableDataset.bootCount + << std::endl; + sif::info << "Reset Cause: " << p60dockHkTableDataset.resetcause + << " | Battery Mode: " << static_cast(p60dockHkTableDataset.battMode.value) + << std::endl; + sif::info << "SwitchState, Currents [mA], Voltages [mV]:" << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Dock VBAT VCC" << std::dec + << "| -, " << std::setw(4) << std::right << p60dockHkTableDataset.dockVccCurrent << ", " + << std::setw(5) << p60dockHkTableDataset.dockVbatVoltageValue << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "BATT" << std::dec << "| -, " + << std::setw(4) << std::right << p60dockHkTableDataset.batteryCurrent.value << ", " + << std::setw(5) << p60dockHkTableDataset.batteryVoltage.value << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "ACU VCC" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStateAcuVcc.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentAcuVcc.value << ", " << std::setw(5) << p60dockHkTableDataset.voltageAcuVcc.value << std::endl; - sif::info << std::setw(30) << std::left << "ACU VBAT" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "ACU VBAT" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStateAcuVbat.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentAcuVbat.value << ", " << std::setw(5) << p60dockHkTableDataset.voltageAcuVbat.value << std::endl; - sif::info << std::setw(30) << std::left << "PDU1 VCC" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU1 VCC" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStatePdu1Vcc.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentPdu1Vcc.value << ", " << std::setw(5) << p60dockHkTableDataset.voltagePdu1Vcc.value << std::endl; - sif::info << std::setw(30) << std::left << "PDU1 VBAT" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU1 VBAT" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStatePdu1Vbat.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentPdu1Vbat.value << ", " << std::setw(5) << p60dockHkTableDataset.voltagePdu1Vbat.value << std::endl; - sif::info << std::setw(30) << std::left << "PDU2 VCC" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU2 VCC" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStatePdu2Vcc.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentPdu2Vcc.value << ", " << std::setw(5) << p60dockHkTableDataset.voltagePdu2Vcc.value << std::endl; - sif::info << std::setw(30) << std::left << "PDU2 VBAT" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU2 VBAT" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStatePdu2Vbat.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentPdu2Vbat.value << ", " << std::setw(5) << p60dockHkTableDataset.voltagePdu2Vbat.value << std::endl; - - sif::info << std::setw(30) << std::left << "Stack VBAT" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Stack VBAT" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStateStackVbat.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentStackVbat.value << ", " << std::setw(5) << p60dockHkTableDataset.voltageStackVbat.value << std::endl; - sif::info << std::setw(30) << std::left << "Stack 3V3" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Stack 3V3" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStateStack3V3.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentStack3V3.value << ", " << std::setw(5) << p60dockHkTableDataset.voltageStack3V3.value << std::endl; - sif::info << std::setw(30) << std::left << "Stack 5V" << std::dec << "| " + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Stack 5V" << std::dec << "| " << unsigned(p60dockHkTableDataset.outputEnableStateStack5V.value) << ", " << std::setw(4) << std::right << p60dockHkTableDataset.currentStack5V.value << ", " << std::setw(5) << p60dockHkTableDataset.voltageStack5V.value << std::endl; } + +void P60DockHandler::printHkTableLatchups() { + sif::info << "P60 Latchup Information" << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "ACU VCC" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsAcuVcc << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "ACU VBAT" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsAcuVbat << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU1 VCC" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsPdu1Vcc << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU1 VBAT" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsPdu1Vbat << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU2 VCC" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsPdu2Vcc << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PDU2 VBAT" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsPdu2Vbat << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Stack 3V3" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsStack3V3 << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Stack 5V" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsStack5V << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "GS 3V3" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsGS3V3 << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "GS 5V" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsGS5V << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "X3 VBAT" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsX3IdleVbat << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "X3 VCC" << std::dec << "| " + << std::setw(4) << std::right << p60dockHkTableDataset.latchupsX3IdleVcc << std::endl; +} diff --git a/mission/devices/P60DockHandler.h b/mission/devices/P60DockHandler.h index 937ef122..38ca391a 100644 --- a/mission/devices/P60DockHandler.h +++ b/mission/devices/P60DockHandler.h @@ -32,10 +32,12 @@ class P60DockHandler : public GomspaceDeviceHandler { */ ReturnValue_t printStatus(DeviceCommandId_t cmd) override; - void printHkTable(); + void printHkTableSwitchIV(); + void printHkTableLatchups(); private: P60Dock::HkTableDataset p60dockHkTableDataset; + static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 16; /** * @brief Function extracts the hk table information from the received csp packet and stores diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 13bed074..e54222b1 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -1,10 +1,12 @@ #include "PCDUHandler.h" #include +#include +#include #include +#include #include #include -#include PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) : SystemObject(setObjectId), @@ -12,8 +14,10 @@ PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) pdu2HkTableDataset(this), pdu1HkTableDataset(this), cmdQueueSize(cmdQueueSize) { + auto mqArgs = MqArgs(setObjectId, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( - cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); + cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); + pwrMutex = MutexFactory::instance()->createMutex(); } PCDUHandler::~PCDUHandler() {} @@ -23,7 +27,6 @@ ReturnValue_t PCDUHandler::performOperation(uint8_t counter) { readCommandQueue(); return RETURN_OK; } - return RETURN_OK; } @@ -74,24 +77,10 @@ ReturnValue_t PCDUHandler::initialize() { } 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; - switchStates[pcduSwitches::TCS_BOARD_3V3] = pcduSwitches::INIT_STATE_TCS_BOARD_3V3; - switchStates[pcduSwitches::SYRLINKS] = pcduSwitches::INIT_STATE_SYRLINKS; - switchStates[pcduSwitches::STAR_TRACKER] = pcduSwitches::INIT_STATE_STAR_TRACKER; - switchStates[pcduSwitches::MGT] = pcduSwitches::INIT_STATE_MGT; - switchStates[pcduSwitches::SUS_NOMINAL] = pcduSwitches::INIT_STATE_SUS_NOMINAL; - switchStates[pcduSwitches::SOLAR_CELL_EXP] = pcduSwitches::INIT_STATE_SOLAR_CELL_EXP; - switchStates[pcduSwitches::PLOC] = pcduSwitches::INIT_STATE_PLOC; - switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_A; + using namespace pcduSwitches; + for (uint8_t idx = 0; idx < Switches::NUMBER_OF_SWITCHES; idx++) { + switchStates[idx] = INIT_SWITCH_STATES[idx]; + } } void PCDUHandler::readCommandQueue() { @@ -111,7 +100,7 @@ void PCDUHandler::readCommandQueue() { MessageQueueId_t PCDUHandler::getCommandQueue() const { return commandQueue->getId(); } -void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) { +void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) { if (sid == sid_t(objects::PDU2_HANDLER, PDU2::HK_TABLE_DATA_SET_ID)) { updateHkTableDataset(storeId, &pdu2HkTableDataset, &timeStampPdu2HkDataset); updatePdu2SwitchStates(); @@ -152,63 +141,176 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet } void PCDUHandler::updatePdu2SwitchStates() { - // TODO: pool read helper - 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.outEnabledSUSRedundant.value; - switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = - pdu2HkTableDataset.outEnabledDeplMechanism.value; - switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pdu2HkTableDataset.outEnabledPlPCDUCh6.value; - switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pdu2HkTableDataset.outEnabledAcsBoardSideB.value; - switchStates[pcduSwitches::PAYLOAD_CAMERA] = pdu2HkTableDataset.outEnabledPayloadCamera.value; + using namespace pcduSwitches; + GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2; + PoolReadGuard rg(&pdu2HkTableDataset); + if (rg.getReadResult() == RETURN_OK) { + MutexGuard mg(pwrMutex); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH0_Q7S, pdu2HkTableDataset.outEnabledQ7S.value); + + checkAndUpdateSwitch(pdu, Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8, + pdu2HkTableDataset.outEnabledPlPCDUCh1.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH2_RW_5V, + pdu2HkTableDataset.outEnabledReactionWheels.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V, + pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH4_SUS_REDUNDANT_3V3, + pdu2HkTableDataset.outEnabledSUSRedundant.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + pdu2HkTableDataset.outEnabledDeplMechanism.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8, + pdu2HkTableDataset.outEnabledPlPCDUCh6.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3, + pdu2HkTableDataset.outEnabledAcsBoardSideB.value); + checkAndUpdateSwitch(pdu, Switches::PDU2_CH8_PAYLOAD_CAMERA, + pdu2HkTableDataset.outEnabledPayloadCamera.value); + if (firstSwitchInfoPdu2) { + firstSwitchInfoPdu2 = false; + } } else { sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset" << std::endl; } - pdu2HkTableDataset.commit(); } void PCDUHandler::updatePdu1SwitchStates() { - if (pdu1HkTableDataset.read() == RETURN_OK) { - switchStates[pcduSwitches::TCS_BOARD_3V3] = pdu1HkTableDataset.voltageOutTCSBoard3V3.value; - switchStates[pcduSwitches::SYRLINKS] = pdu1HkTableDataset.voltageOutSyrlinks.value; - switchStates[pcduSwitches::STAR_TRACKER] = pdu1HkTableDataset.voltageOutStarTracker.value; - switchStates[pcduSwitches::MGT] = pdu1HkTableDataset.voltageOutMGT.value; - switchStates[pcduSwitches::SUS_NOMINAL] = pdu1HkTableDataset.voltageOutSUSNominal.value; - switchStates[pcduSwitches::SOLAR_CELL_EXP] = pdu1HkTableDataset.voltageOutSolarCellExp.value; - switchStates[pcduSwitches::PLOC] = pdu1HkTableDataset.voltageOutPLOC.value; - switchStates[pcduSwitches::ACS_BOARD_SIDE_A] = pdu1HkTableDataset.voltageOutACSBoardSideA.value; + using namespace pcduSwitches; + PoolReadGuard rg(&pdu1HkTableDataset); + GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1; + if (rg.getReadResult() == RETURN_OK) { + MutexGuard mg(pwrMutex); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH0_TCS_BOARD_3V3, + pdu1HkTableDataset.outEnabledTCSBoard3V3.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH1_SYRLINKS_12V, + pdu1HkTableDataset.outEnabledSyrlinks.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH2_STAR_TRACKER_5V, + pdu1HkTableDataset.outEnabledStarTracker.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH3_MGT_5V, pdu1HkTableDataset.outEnabledMGT.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH4_SUS_NOMINAL_3V3, + pdu1HkTableDataset.outEnabledSUSNominal.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH5_SOLAR_CELL_EXP_5V, + pdu1HkTableDataset.outEnabledSolarCellExp.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH6_PLOC_12V, pdu1HkTableDataset.outEnabledPLOC.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH7_ACS_A_SIDE_3V3, + pdu1HkTableDataset.outEnabledAcsBoardSideA.value); + checkAndUpdateSwitch(pdu, Switches::PDU1_CH8_UNOCCUPIED, + pdu1HkTableDataset.outEnabledChannel8.value); + if (firstSwitchInfoPdu1) { + firstSwitchInfoPdu1 = false; + } } else { sif::debug << "PCDUHandler::updatePdu1SwitchStates: Failed to read dataset" << std::endl; } - pdu1HkTableDataset.commit(); } LocalDataPoolManager* PCDUHandler::getHkManagerHandle() { return &poolManager; } void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const { + using namespace pcduSwitches; ReturnValue_t result; - uint16_t memoryAddress; + uint16_t memoryAddress = 0; size_t parameterValueSize = sizeof(uint8_t); - uint8_t parameterValue; - GomspaceDeviceHandler* pdu; + uint8_t parameterValue = 0; + GomspaceDeviceHandler* pdu = nullptr; switch (switchNr) { - case pcduSwitches::TCS_BOARD_8V_HEATER_IN: + case pcduSwitches::PDU1_CH0_TCS_BOARD_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH1_SYRLINKS_12V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SYRLINKS; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH2_STAR_TRACKER_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_STAR_TRACKER; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH3_MGT_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_MGT; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH4_SUS_NOMINAL_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH5_SOLAR_CELL_EXP_5V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH6_PLOC_12V: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_PLOC; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH7_ACS_A_SIDE_3V3: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + case pcduSwitches::PDU1_CH8_UNOCCUPIED: { + memoryAddress = PDU1::CONFIG_ADDRESS_OUT_EN_CHANNEL8; + pdu = ObjectManager::instance()->get(objects::PDU1_HANDLER); + break; + } + // This is a dangerous command. Reject/Igore it for now + case pcduSwitches::PDU2_CH0_Q7S: { + return; + // memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_Q7S; + // pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + // break; + } + case pcduSwitches::PDU2_CH1_PL_PCDU_BATT_0_14V8: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH2_RW_5V: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_RW; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; - case pcduSwitches::DEPLOYMENT_MECHANISM: + } + case pcduSwitches::PDU2_CH4_SUS_REDUNDANT_3V3: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V: { memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM; pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); break; - default: + } + case pcduSwitches::PDU2_CH6_PL_PCDU_BATT_1_14V8: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + case pcduSwitches::PDU2_CH8_PAYLOAD_CAMERA: { + memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA; + pdu = ObjectManager::instance()->get(objects::PDU2_HANDLER); + break; + } + + default: { sif::error << "PCDUHandler::sendSwitchCommand: Invalid switch number " << std::endl; return; + } } switch (onOff) { @@ -241,6 +343,9 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const if (result != RETURN_OK) { sif::debug << "PCDUHandler::sendSwitchCommand: Failed to send message to PDU Handler" << std::endl; + } else { + // Can't use trigger event because of const function constraint, but this hack seems to work + this->forwardEvent(power::SWITCH_CMD_SENT, parameterValue, switchNr); } } @@ -251,7 +356,10 @@ ReturnValue_t PCDUHandler::getSwitchState(uint8_t switchNr) const { sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl; return RETURN_FAILED; } - if (switchStates[switchNr] == 1) { + pwrMutex->lockMutex(); + uint8_t currentState = switchStates[switchNr]; + pwrMutex->unlockMutex(); + if (currentState == 1) { return PowerSwitchIF::SWITCH_ON; } else { return PowerSwitchIF::SWITCH_OFF; @@ -266,6 +374,7 @@ object_id_t PCDUHandler::getObjectId() const { return SystemObject::getObjectId( ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { + using namespace pcduSwitches; localDataPoolMap.emplace(P60System::PDU2_CURRENT_OUT_Q7S, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, new PoolEntry({0})); @@ -304,28 +413,34 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat localDataPoolMap.emplace(P60System::PDU2_CONV_EN_3, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_OUT_EN_Q7S, - new PoolEntry({pcduSwitches::INIT_STATE_Q7S})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, - new PoolEntry({pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1})); + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH0_Q7S]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8]})); localDataPoolMap.emplace(P60System::PDU2_OUT_EN_RW, - new PoolEntry({pcduSwitches::INIT_STATE_RW})); + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH2_RW_5V]})); #if BOARD_TE0720 == 1 localDataPoolMap.emplace(P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry({1})); #else localDataPoolMap.emplace( P60System::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, - new PoolEntry({pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN})); + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V]})); #endif - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_SUS_REDUNDANT, - new PoolEntry({pcduSwitches::INIT_STATE_SUS_REDUNDANT})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, - new PoolEntry({pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, - new PoolEntry({pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_ACS_BOARD_SIDE_B, - new PoolEntry({pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B})); - localDataPoolMap.emplace(P60System::PDU2_OUT_EN_PAYLOAD_CAMERA, - new PoolEntry({pcduSwitches::INIT_STATE_PAYLOAD_CAMERA})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_SUS_REDUNDANT, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH4_SUS_REDUNDANT_3V3]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH6_PL_PCDU_BATT_1_14V8]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_ACS_BOARD_SIDE_B, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3]})); + localDataPoolMap.emplace( + P60System::PDU2_OUT_EN_PAYLOAD_CAMERA, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU2_CH8_PAYLOAD_CAMERA]})); localDataPoolMap.emplace(P60System::PDU2_BOOTCAUSE, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_BOOTCNT, new PoolEntry({0})); @@ -387,16 +502,32 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU1_CURRENT_OUT_CHANNEL8, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SYRLINKS, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_STAR_TRACKER, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_MGT, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SUS_NOMINAL, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_PLOC, new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A, - new PoolEntry({0})); - localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_CHANNEL8, new PoolEntry({0})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH0_TCS_BOARD_3V3]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_SYRLINKS, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH1_SYRLINKS_12V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_STAR_TRACKER, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH2_STAR_TRACKER_5V]})); + localDataPoolMap.emplace(P60System::PDU1_VOLTAGE_OUT_MGT, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH3_MGT_5V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_SUS_NOMINAL, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH4_SUS_NOMINAL_3V3]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH5_SOLAR_CELL_EXP_5V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_PLOC, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH6_PLOC_12V]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH7_ACS_A_SIDE_3V3]})); + localDataPoolMap.emplace( + P60System::PDU1_VOLTAGE_OUT_CHANNEL8, + new PoolEntry({INIT_SWITCH_STATES[Switches::PDU1_CH8_UNOCCUPIED]})); localDataPoolMap.emplace(P60System::PDU1_VCC, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU1_VBAT, new PoolEntry({0})); @@ -486,3 +617,27 @@ LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) { return nullptr; } } + +void PCDUHandler::checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches switchIdx, + uint8_t setValue) { + using namespace pcduSwitches; + if (switchStates[switchIdx] != setValue) { +#if OBSW_INITIALIZE_SWITCHES == 1 + // This code initializes the switches to the default init switch states on every reboot. + // This is not done by the PCDU unless it is power-cycled. + if (((pdu == GOMSPACE::Pdu::PDU1) and firstSwitchInfoPdu1) or + ((pdu == GOMSPACE::Pdu::PDU2) and firstSwitchInfoPdu2)) { + ReturnValue_t state = PowerSwitchIF::SWITCH_OFF; + if (INIT_SWITCH_STATES[switchIdx] == ON) { + state = PowerSwitchIF::SWITCH_ON; + } + sendSwitchCommand(switchIdx, state); + } else { + triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); + } +#else + triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx); +#endif + } + switchStates[switchIdx] = setValue; +} diff --git a/mission/devices/PCDUHandler.h b/mission/devices/PCDUHandler.h index c045ed03..3d014205 100644 --- a/mission/devices/PCDUHandler.h +++ b/mission/devices/PCDUHandler.h @@ -8,13 +8,16 @@ #include #include #include -#include + +#include "devicedefinitions/GomspaceDefinitions.h" +#include "devicedefinitions/powerDefinitions.h" /** * @brief The PCDUHandler provides a compact interface to handle all devices related to the - * control of power. This is necessary because the fsfw manages all power - * related functionalities via one power object. This includes for example the switch on and off of - * devices. + * control of power. + * @details + * This is necessary because the FSFW manages all power related functionalities via one + * power object. This includes for example switching on and off of devices. */ class PCDUHandler : public PowerSwitchIF, public HasLocalDataPoolIF, @@ -27,7 +30,8 @@ class PCDUHandler : public PowerSwitchIF, virtual ReturnValue_t initialize() override; virtual ReturnValue_t performOperation(uint8_t counter) override; virtual void handleChangedDataset(sid_t sid, - store_address_t storeId = storeId::INVALID_STORE_ADDRESS); + store_address_t storeId = storeId::INVALID_STORE_ADDRESS, + bool* clearMessage = nullptr) override; virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override; virtual void sendFuseOnCommand(uint8_t fuseNr) const override; @@ -47,6 +51,7 @@ class PCDUHandler : public PowerSwitchIF, private: uint32_t pstIntervalMs = 0; + MutexIF* pwrMutex = nullptr; /** Housekeeping manager. Handles updates of local pool variables. */ LocalDataPoolManager poolManager; @@ -79,6 +84,8 @@ class PCDUHandler : public PowerSwitchIF, MessageQueueIF* commandQueue = nullptr; size_t cmdQueueSize; + bool firstSwitchInfoPdu1 = true; + bool firstSwitchInfoPdu2 = true; PeriodicTaskIF* executingTask = nullptr; @@ -112,6 +119,7 @@ class PCDUHandler : public PowerSwitchIF, */ void updateHkTableDataset(store_address_t storeId, LocalPoolDataSetBase* dataset, CCSDSTime::CDS_short* datasetTimeStamp); + void checkAndUpdateSwitch(GOMSPACE::Pdu pdu, pcduSwitches::Switches switchIdx, uint8_t setValue); }; #endif /* MISSION_DEVICES_PCDUHANDLER_H_ */ diff --git a/mission/devices/PDU1Handler.cpp b/mission/devices/PDU1Handler.cpp index 48b79551..38256cf9 100644 --- a/mission/devices/PDU1Handler.cpp +++ b/mission/devices/PDU1Handler.cpp @@ -412,30 +412,51 @@ ReturnValue_t PDU1Handler::initializeLocalDataPool(localpool::DataPool &localDat localDataPoolMap.emplace(P60System::PDU1_WDT_CAN_LEFT, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU1_WDT_CSP_LEFT1, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU1_WDT_CSP_LEFT2, new PoolEntry({0})); - +#if OBSW_ENABLE_PERIODIC_HK == 1 + poolManager.subscribeForPeriodicPacket(pdu1HkTableDataset.getSid(), false, 0.4, true); +#endif return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PDU1Handler::printStatus(DeviceCommandId_t cmd) { + ReturnValue_t result = RETURN_OK; switch (cmd) { case (GOMSPACE::PRINT_SWITCH_V_I): { PoolReadGuard pg(&pdu1HkTableDataset); - ReturnValue_t readResult = pg.getReadResult(); - if (readResult != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Reading PDU1 HK table failed!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + result = pg.getReadResult(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; } - printHkTable(); - return HasReturnvaluesIF::RETURN_OK; + printHkTableSwitchVI(); + break; + } + case (GOMSPACE::PRINT_LATCHUPS): { + PoolReadGuard pg(&pdu1HkTableDataset); + result = pg.getReadResult(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + printHkTableLatchups(); + break; } default: { return HasReturnvaluesIF::RETURN_FAILED; } } + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Reading PDU1 HK table failed!" << std::endl; + } + return result; } -void PDU1Handler::printHkTable() { - sif::info << "PDU1 Info: SwitchState, Currents [mA], Voltages [mV]" << std::endl; +void PDU1Handler::printHkTableSwitchVI() { + sif::info << "PDU1 Info: " << std::endl; + sif::info << "Boot Cause: " << pdu1HkTableDataset.bootcause << " | Boot Count: " << std::setw(4) + << std::right << pdu1HkTableDataset.bootcount << std::endl; + sif::info << "Reset Cause: " << pdu1HkTableDataset.resetcause + << " | Battery Mode: " << static_cast(pdu1HkTableDataset.battMode.value) + << std::endl; + sif::info << "SwitchState, Currents [mA], Voltages [mV]:" << std::endl; sif::info << std::setw(30) << std::left << "TCS Board" << std::dec << "| " << unsigned(pdu1HkTableDataset.outEnabledTCSBoard3V3.value) << ", " << std::setw(4) << std::right << pdu1HkTableDataset.currentOutTCSBoard3V3.value << ", " << std::setw(4) @@ -475,3 +496,26 @@ void PDU1Handler::printHkTable() { << std::setw(4) << pdu1HkTableDataset.voltageOutChannel8.value << std::right << std::endl; } + +void PDU1Handler::printHkTableLatchups() { + sif::info << "PDU1 Latchup Information" << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "TCS Board" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsTcsBoard3V3 << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Syrlinks" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsSyrlinks << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Star Tracker" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsStarTracker << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "MGT" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsMgt << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "SuS Nominal" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsSusNominal << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Solar Cell Experiment" << std::dec + << "| " << std::setw(4) << std::right << pdu1HkTableDataset.latchupsSolarCellExp + << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "PLOC" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsPloc << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "ACS A Side" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsAcsBoardSideA << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Channel 8" << std::dec << "| " + << std::setw(4) << std::right << pdu1HkTableDataset.latchupsChannel8 << std::endl; +} diff --git a/mission/devices/PDU1Handler.h b/mission/devices/PDU1Handler.h index c140648b..732c38d2 100644 --- a/mission/devices/PDU1Handler.h +++ b/mission/devices/PDU1Handler.h @@ -40,12 +40,15 @@ class PDU1Handler : public GomspaceDeviceHandler { ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExectuion) override; private: + static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 24; + /** Dataset for the housekeeping table of the PDU1 */ PDU1::PDU1HkTableDataset pdu1HkTableDataset; GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr; void* hookArgs = nullptr; - void printHkTable(); + void printHkTableSwitchVI(); + void printHkTableLatchups(); void parseHkTableReply(const uint8_t* packet); }; diff --git a/mission/devices/PDU2Handler.cpp b/mission/devices/PDU2Handler.cpp index 776cae58..3d7e260d 100644 --- a/mission/devices/PDU2Handler.cpp +++ b/mission/devices/PDU2Handler.cpp @@ -364,30 +364,51 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool(localpool::DataPool &localDat localDataPoolMap.emplace(P60System::PDU2_WDT_CAN_LEFT, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_WDT_CSP_LEFT1, new PoolEntry({0})); localDataPoolMap.emplace(P60System::PDU2_WDT_CSP_LEFT2, new PoolEntry({0})); - +#if OBSW_ENABLE_PERIODIC_HK == 1 + poolManager.subscribeForPeriodicPacket(pdu2HkTableDataset.getSid(), false, 0.4, true); +#endif return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PDU2Handler::printStatus(DeviceCommandId_t cmd) { + ReturnValue_t result = RETURN_OK; switch (cmd) { case (GOMSPACE::PRINT_SWITCH_V_I): { PoolReadGuard pg(&pdu2HkTableDataset); - ReturnValue_t readResult = pg.getReadResult(); - if (readResult != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Reading PDU1 HK table failed!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + result = pg.getReadResult(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; } - printHkTable(); - return HasReturnvaluesIF::RETURN_OK; + printHkTableSwitchVI(); + break; + } + case (GOMSPACE::PRINT_LATCHUPS): { + PoolReadGuard pg(&pdu2HkTableDataset); + result = pg.getReadResult(); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + printHkTableLatchups(); + break; } default: { return HasReturnvaluesIF::RETURN_FAILED; } } + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Reading PDU1 HK table failed!" << std::endl; + } + return result; } -void PDU2Handler::printHkTable() { - sif::info << "PDU2 Info: SwitchState, Currents [mA], Voltages [mV]" << std::endl; +void PDU2Handler::printHkTableSwitchVI() { + sif::info << "PDU2 Info:" << std::endl; + sif::info << "Boot Cause: " << pdu2HkTableDataset.bootcause << " | Boot Count: " << std::setw(4) + << std::right << pdu2HkTableDataset.bootcount << std::endl; + sif::info << "Reset Cause: " << pdu2HkTableDataset.resetcause + << " | Battery Mode: " << static_cast(pdu2HkTableDataset.battMode.value) + << std::endl; + sif::info << "SwitchState, Currents [mA], Voltages [mV]: " << std::endl; sif::info << std::setw(30) << std::left << "Q7S" << std::dec << "| " << unsigned(pdu2HkTableDataset.outEnabledQ7S.value) << ", " << std::setw(4) << std::right << pdu2HkTableDataset.currentOutQ7S.value << ", " << std::setw(4) @@ -400,11 +421,11 @@ void PDU2Handler::printHkTable() { << unsigned(pdu2HkTableDataset.outEnabledReactionWheels.value) << ", " << std::setw(4) << std::right << pdu2HkTableDataset.currentOutReactionWheels.value << ", " << std::setw(4) << pdu2HkTableDataset.voltageOutReactionWheels.value << std::endl; - sif::info << std::setw(30) << std::left << "TCS Board 8V heater input" << std::dec << "| " + sif::info << std::setw(30) << std::left << "TCS Board Heater Input" << std::dec << "| " << unsigned(pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value) << ", " << std::setw(4) << std::right << pdu2HkTableDataset.currentOutTCSBoardHeaterIn.value << ", " << std::setw(4) << pdu2HkTableDataset.voltageOutTCSBoardHeaterIn.value << std::endl; - sif::info << std::setw(30) << std::left << "Redundant SUS group" << std::dec << "| " + sif::info << std::setw(30) << std::left << "SuS Redundant" << std::dec << "| " << unsigned(pdu2HkTableDataset.outEnabledSUSRedundant.value) << ", " << std::setw(4) << std::right << pdu2HkTableDataset.currentOutSUSRedundant.value << ", " << std::setw(4) << pdu2HkTableDataset.voltageOutSUSRedundant.value << std::endl; @@ -420,13 +441,40 @@ void PDU2Handler::printHkTable() { << unsigned(pdu2HkTableDataset.outEnabledAcsBoardSideB.value) << ", " << std::setw(4) << std::right << pdu2HkTableDataset.currentOutACSBoardSideB.value << ", " << std::setw(4) << pdu2HkTableDataset.voltageOutACSBoardSideB.value << std::endl; - sif::info << std::setw(30) << std::left << "Payload Camera enable state" << std::dec << "| " + sif::info << std::setw(30) << std::left << "Payload Camera" << std::dec << "| " << unsigned(pdu2HkTableDataset.outEnabledPayloadCamera.value) << ", " << std::setw(4) << std::right << pdu2HkTableDataset.currentOutPayloadCamera.value << ", " << std::setw(4) << pdu2HkTableDataset.voltageOutPayloadCamera.value << std::right << std::endl; } +void PDU2Handler::printHkTableLatchups() { + sif::info << "PDU2 Latchup Information" << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Q7S" << std::dec << "| " + << std::setw(4) << std::right << pdu2HkTableDataset.latchupsQ7S << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Payload PCDU Channel 1" << std::dec + << "| " << std::setw(4) << std::right << pdu2HkTableDataset.latchupsPayloadPcduCh1 + << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Reaction Wheels" << std::dec + << "| " << std::setw(4) << std::right << pdu2HkTableDataset.latchupsRw << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "TCS Board Heater Input" << std::dec + << "| " << std::setw(4) << std::right << pdu2HkTableDataset.latchupsTcsBoardHeaterIn + << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "SuS Nominal" << std::dec << "| " + << std::setw(4) << std::right << pdu2HkTableDataset.latchupsSusRedundant << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Deployment mechanism" << std::dec + << "| " << std::setw(4) << std::right << pdu2HkTableDataset.latchupsDeplMenchanism + << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Payload PCDU Channel 6" << std::dec + << "| " << std::setw(4) << std::right << pdu2HkTableDataset.latchupsPayloadPcduCh6 + << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "ACS Board Side B" << std::dec + << "| " << std::setw(4) << std::right << pdu2HkTableDataset.latchupsAcsBoardSideB + << std::endl; + sif::info << std::setw(MAX_CHANNEL_STR_WIDTH) << std::left << "Payload Camera" << std::dec << "| " + << std::setw(4) << std::right << pdu2HkTableDataset.latchupsPayloadCamera << std::endl; +} + ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, bool afterExecution) { using namespace PDU2; @@ -460,7 +508,7 @@ ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs); break; } - case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC): { + case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6): { channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs); break; } diff --git a/mission/devices/PDU2Handler.h b/mission/devices/PDU2Handler.h index f2323615..ca639568 100644 --- a/mission/devices/PDU2Handler.h +++ b/mission/devices/PDU2Handler.h @@ -38,12 +38,15 @@ class PDU2Handler : public GomspaceDeviceHandler { ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution) override; private: + static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 24; + /** Dataset for the housekeeping table of the PDU2 */ PDU2::PDU2HkTableDataset pdu2HkTableDataset; GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr; void* hookArgs = nullptr; - void printHkTable(); + void printHkTableSwitchVI(); + void printHkTableLatchups(); void parseHkTableReply(const uint8_t* packet); }; diff --git a/mission/devices/RadiationSensorHandler.cpp b/mission/devices/RadiationSensorHandler.cpp index 57714d03..52d58fd8 100644 --- a/mission/devices/RadiationSensorHandler.cpp +++ b/mission/devices/RadiationSensorHandler.cpp @@ -156,6 +156,7 @@ ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id, #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RAD_SENSOR == 1 sif::info << "Radiation sensor temperature: " << dataset.temperatureCelcius << " °C" << std::endl; + sif::info << std::dec; sif::info << "Radiation sensor ADC value channel 0: " << dataset.ain0 << std::endl; sif::info << "Radiation sensor ADC value channel 1: " << dataset.ain1 << std::endl; sif::info << "Radiation sensor ADC value channel 4: " << dataset.ain4 << std::endl; diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 13b46171..ee1dba07 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -1,7 +1,6 @@ #include "SolarArrayDeploymentHandler.h" #include -#include #include #include #include @@ -10,7 +9,7 @@ SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId object_id_t gpioDriverId_, CookieIF* gpioCookie_, object_id_t mainLineSwitcherObjectId_, - uint8_t mainLineSwitch_, gpioId_t deplSA1, + pcduSwitches::Switches mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) : SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 90380ae2..1e5bd9b1 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -1,6 +1,8 @@ #ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ +#include + #include #include #include @@ -42,7 +44,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF* gpioCookie, object_id_t mainLineSwitcherObjectId, - uint8_t mainLineSwitch, gpioId_t deplSA1, gpioId_t deplSA2, + pcduSwitches::Switches mainLineSwitch, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs); virtual ~SolarArrayDeploymentHandler(); diff --git a/mission/devices/devicedefinitions/GomspaceDefinitions.h b/mission/devices/devicedefinitions/GomspaceDefinitions.h index 995d9a7a..d06c7eef 100644 --- a/mission/devices/devicedefinitions/GomspaceDefinitions.h +++ b/mission/devices/devicedefinitions/GomspaceDefinitions.h @@ -34,8 +34,10 @@ static const DeviceCommandId_t GNDWDT_RESET = 9; //!< [EXPORT] : [COMMAND] static const DeviceCommandId_t PARAM_GET = 0; //!< [EXPORT] : [COMMAND] static const DeviceCommandId_t PARAM_SET = 255; //!< [EXPORT] : [COMMAND] static const DeviceCommandId_t REQUEST_HK_TABLE = 16; //!< [EXPORT] : [COMMAND] + //!< [EXPORT] : [COMMAND] Print switch states, voltages and currents to the console static const DeviceCommandId_t PRINT_SWITCH_V_I = 32; +static const DeviceCommandId_t PRINT_LATCHUPS = 33; } // namespace GOMSPACE @@ -535,10 +537,11 @@ class HkTableDataset : public StaticLocalDataSet { lp_var_t latchupsGS5V = lp_var_t(sid.objectId, P60System::P60DOCK_LATCHUP_GS5V, this); - lp_var_t vbatVoltageValue = + lp_var_t dockVbatVoltageValue = lp_var_t(sid.objectId, P60System::P60DOCK_VBAT_VALUE, this); - lp_var_t vccCurrent = + lp_var_t dockVccCurrent = lp_var_t(sid.objectId, P60System::P60DOCK_VCC_CURRENT_VALUE, this); + // Difference between charge and discharge current lp_var_t batteryCurrent = lp_var_t(sid.objectId, P60System::P60DOCK_BATTERY_CURRENT, this); lp_var_t batteryVoltage = @@ -848,7 +851,7 @@ static const uint16_t CONFIG_ADDRESS_OUT_EN_RW = 0x4A; static const uint16_t CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN = 0x4B; static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT = 0x4C; static const uint16_t CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM = 0x4D; -static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC = 0x4E; +static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6 = 0x4E; static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B = 0x4F; static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA = 0x50; diff --git a/mission/devices/devicedefinitions/powerDefinitions.h b/mission/devices/devicedefinitions/powerDefinitions.h new file mode 100644 index 00000000..746bda34 --- /dev/null +++ b/mission/devices/devicedefinitions/powerDefinitions.h @@ -0,0 +1,20 @@ +#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ +#define MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ + +#include +#include + +namespace power { + +static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_HANDLER; +//! [EXPORT] : [COMMENT] Indicates that a FSFW object requested setting a switch +//! P1: 1 if on was requested, 0 for off | P2: Switch Index +static constexpr Event SWITCH_CMD_SENT = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO); +//! [EXPORT] : [COMMENT] Indicated that a swithc state has changed +//! P1: New switch state, 1 for on, 0 for off | P2: Switch Index +static constexpr Event SWITCH_HAS_CHANGED = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); +static constexpr Event SWITCHING_Q7S_DENIED = event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); + +} // namespace power + +#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_POWERDEFINITIONS_H_ */ diff --git a/mission/devices/max1227.h b/mission/devices/max1227.h index 1a6082fb..fc317b39 100644 --- a/mission/devices/max1227.h +++ b/mission/devices/max1227.h @@ -65,7 +65,7 @@ void prepareExternallyClockedSingleChannelRead(uint8_t* spiBuf, uint8_t channel, * the first byte (first conversion byte) the the rest of the SPI buffer. * @param spiBuf * @param n Channel number. Example: If the ADC has 6 channels, n will be 5 - * @param sz + * @param sz Will be incremented by amount which should be sent */ void prepareExternallyClockedRead0ToN(uint8_t* spiBuf, uint8_t n, size_t& sz); @@ -73,7 +73,7 @@ void prepareExternallyClockedRead0ToN(uint8_t* spiBuf, uint8_t n, size_t& sz); * Prepare an externally clocked temperature read. 25 bytes have to be sent * and the raw temperature value will appear on the last 2 bytes of the reply. * @param spiBuf - * @param sz + * @param sz Will be incremented by amount which should be sent */ void prepareExternallyClockedTemperatureRead(uint8_t* spiBuf, size_t& sz); From c212f0ad48c59830893d16a3c3d0cc2c12b0ad7b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 17 Mar 2022 10:04:51 +0100 Subject: [PATCH 2/2] Obj Factory fixes --- bsp_q7s/core/ObjectFactory.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 519dec8f..a1faee53 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -579,12 +579,13 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); auto mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, spi::LIS3_TRANSITION_DELAY); + static_cast(mgmLis3Handler); #if OBSW_TEST_ACS == 1 mgmLis3Handler->setStartUpImmediately(); mgmLis3Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmLis3Handler->enablePeriodicPrintouts(true, 10); -#endif #endif spiCookie = @@ -592,25 +593,26 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, spi::RM3100_TRANSITION_DELAY); + static_cast(mgmRm3100Handler); #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setStartUpImmediately(); mgmRm3100Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmRm3100Handler->enablePeriodicPrintouts(true, 10); -#endif #endif spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev, MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); - auto mgmLis3Handler2 = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, + mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, spi::LIS3_TRANSITION_DELAY); #if OBSW_TEST_ACS == 1 - mgmLis3Handler2->setStartUpImmediately(); - mgmLis3Handler2->setToGoToNormalMode(true); -#if OBSW_DEBUG_ACS == 1 - mgmLis3Handler2->enablePeriodicPrintouts(true, 10); + mgmLis3Handler->setStartUpImmediately(); + mgmLis3Handler->setToGoToNormalMode(true); #endif +#if OBSW_DEBUG_ACS == 1 + mgmLis3Handler->enablePeriodicPrintouts(true, 10); #endif spiCookie = @@ -621,9 +623,9 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI #if OBSW_TEST_ACS == 1 mgmRm3100Handler->setStartUpImmediately(); mgmRm3100Handler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 mgmRm3100Handler->enablePeriodicPrintouts(true, 10); -#endif #endif // Commented until ACS board V2 in in clean room again @@ -633,12 +635,13 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI spi::DEFAULT_ADIS16507_SPEED); auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie, ADIS1650X::Type::ADIS16505); + static_cast(adisHandler); #if OBSW_TEST_ACS == 1 adisHandler->setStartUpImmediately(); adisHandler->setToGoToNormalModeImmediately(); +#endif #if OBSW_DEBUG_ACS == 1 adisHandler->enablePeriodicPrintouts(true, 10); -#endif #endif // Gyro 1 Side A @@ -647,13 +650,15 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, spi::L3G_TRANSITION_DELAY); + static_cast(gyroL3gHandler); #if OBSW_TEST_ACS == 1 gyroL3gHandler->setStartUpImmediately(); gyroL3gHandler->setToGoToNormalMode(true); +#endif #if OBSW_DEBUG_ACS == 1 gyroL3gHandler->enablePeriodicPrintouts(true, 10); #endif -#endif + // Gyro 2 Side B spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, @@ -736,7 +741,7 @@ void ObjectFactory::createHeaterComponents() { heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, - objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); + objects::PCDU_HANDLER, pcduSwitches::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } void ObjectFactory::createSolarArrayDeploymentComponents() { @@ -756,8 +761,8 @@ void ObjectFactory::createSolarArrayDeploymentComponents() { // 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); + pcduSwitches::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, + gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); } void ObjectFactory::createSyrlinksComponents() {