#ifndef LINUX_DEVICES_PLPCDUHANDLER_H_ #define LINUX_DEVICES_PLPCDUHANDLER_H_ #include #include #include #include #include #include #include "events/subsystemIdRanges.h" #include "fsfw/FSFW.h" #include "fsfw_hal/common/gpio/GpioIF.h" #include "mission/memory/SdCardMountedIF.h" #include "mission/power/defs.h" #include "mission/system/DualLanePowerStateMachine.h" #ifdef FSFW_OSAL_LINUX class SpiComIF; class SpiCookie; #endif /** * @brief Device handler for the EIVE Payload PCDU * @details * Documentation: * https://egit.irs.uni-stuttgart.de/eive/eive_dokumente/src/branch/master/400_Raumsegment/412_PayloaPCDUDocumentation/release/EIVE-D-421-001_PLPCDU_Documentation.pdf * * Important components: * - SSR - Solid State Relay: Decouples voltages from battery * - DRO - Dielectric Resonsant Oscillator: Generates modulation signal * - X8: Frequency X8 Multiplicator * - TX: Transmitter/Sender module. Modulates data onto carrier signal * - MPA - Medium Power Amplifier * - HPA - High Power Amplifier */ class PayloadPcduHandler : public DeviceHandlerBase { public: static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PL_PCDU_HANDLER; //! [EXPORT] : [COMMENT] Could not transition properly and went back to ALL OFF static constexpr Event TRANSITION_BACK_TO_OFF = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event NEG_V_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event U_DRO_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event I_DRO_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event U_X8_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 4, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event I_X8_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 5, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event U_TX_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 6, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event I_TX_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 7, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event U_MPA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event I_MPA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 9, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event U_HPA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM); //! [EXPORT] : [COMMENT] P1: 0 -> too low, 1 -> too high P2: Float value static constexpr Event I_HPA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM); PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie, GpioIF* gpioIF, SdCardMountedIF* sdcMan, Stack5VHandler& stackHandler, bool periodicPrintout); void setToGoToNormalModeImmediately(bool enable); void enablePeriodicPrintout(bool enable, uint8_t divider); #ifdef XIPHOS_Q7S static ReturnValue_t extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData, size_t sendLen, void* args); static ReturnValue_t transferAsTwo(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData, size_t sendLen, bool tempOnly); #endif private: static constexpr bool NO_ADC_CHECKS = false; enum class States : uint8_t { PL_PCDU_OFF, STACK_5V_SWITCHING, STACK_5V_PENDING, STACK_5V_CORRECT, // Solid State Relay, enable battery voltages VBAT0 and VBAT1. This will also switch on // the ADC ON_TRANS_SSR, ON_TRANS_ADC_CLOSE_ZERO } state = States::PL_PCDU_OFF; duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE; enum class AdcMode { EXT_CONV, INT_CONV } adcMode = AdcMode::INT_CONV; enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE; enum class AdcState { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcState::OFF; bool goToNormalMode = false; plpcdu::PlPcduAdcSet adcSet; Stack5VHandler& stackHandler; std::array cmdBuf = {}; // This variable is tied to DRO +6 V voltage. Voltages, currents are monitored and the experiment // is shut down immediately if there is a negative voltage. bool transitionOk = false; bool commandExecuted = false; bool adcCmdExecuted = false; bool periodicPrintout = false; bool jsonFileInitComplete = false; double doubleDummy = 0.0; bool ssrToDroInjectionRequested = false; bool droToX8InjectionRequested = false; bool x8ToTxInjectionRequested = false; bool txToMpaInjectionRequested = false; bool mpaToHpaInjectionRequested = false; bool allOnInjectRequested = false; bool clearSetOnOffFlag = true; bool toNormalOneShot = true; PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t tempReadDivisor = 1; Countdown countdown = Countdown(5000); Countdown adcCountdown = Countdown(50); GpioIF* gpioIF; SdCardMountedIF* sdcMan; plpcdu::PlPcduParameter params; bool quickTransitionAlreadyCalled = true; uint8_t diffMask = 0; PoolEntry channelValues = PoolEntry({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); PoolEntry processedValues = PoolEntry({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); PoolEntry tempC = PoolEntry({0.0}); void updateSwitchGpio(gpioId_t id, gpio::Levels level); void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; void doStartUp() override; void doShutDown() override; // Main FDIR function which goes from any PL PCDU state back to all off void quickTransitionBackToOff(bool startTransitionToOff, bool notifyFdir); ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; void fillCommandAndReplyMap() override; ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, size_t commandDataLen) override; ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId, size_t* foundLen) override; ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override; uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex) override; void handleExtConvRead(const uint8_t* bufStart); void handlePrintout(); void pullAllGpiosLow(uint32_t delayBeforeSwitchingOffDro); void checkAdcValues(); void handleOutOfBoundsPrintout(); void checkJsonFileInit(); ReturnValue_t stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom); bool checkVoltage(float val, float lowerBound, float upperBound, Event event); bool checkCurrent(float val, float upperBound, Event event); void handleFailureInjection(std::string output, Event event); ReturnValue_t serializeFloat(uint32_t& param, float val); ReturnValue_t handleDoubleParamUpdate(std::string key, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues); LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER); ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, uint32_t* msToReachTheMode) override; }; #endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */