/************************************************************************** * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file Voltages.c * * @author (last) Sean Nash * @date (last) 15-Apr-2021 * * @author (original) Sean * @date (original) 15-Apr-2021 * ***************************************************************************/ #include "AlarmMgmt.h" #include "InternalADC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" #include "Voltages.h" /** * @addtogroup Voltages * @{ */ // ********** private definitions ********** #define VOLTAGES_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the voltages data is published on the CAN bus. #define VOLTAGES_ALARM_PERSISTENCE ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Alarm persistence period for voltage monitor alarms. /// Defined states for the pressure and occlusion monitor state machine. typedef enum Voltages_States { VOLTAGES_INIT_STATE = 0, ///< Initialization state. VOLTAGES_MONITOR_STATE, ///< Continuous read sensors state. NUM_OF_VOLTAGES_STATES ///< Number of voltage monitor states. } VOLTAGES_STATE_T; /// Defined states for the voltage monitor self-test state machine. typedef enum Voltages_Self_Test_States { VOLTAGES_SELF_TEST_STATE_START = 0, ///< Self test start state. VOLTAGES_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. VOLTAGES_TEST_STATE_COMPLETE, ///< Self test completed state. NUM_OF_VOLTAGES_SELF_TEST_STATES ///< Number of voltage monitor self-test states. } VOLTAGES_SELF_TEST_STATE_T; /// Maximum voltage/current level for each monitored signal. static const F32 MAX_VOLTAGES[ NUM_OF_MONITORED_LINES ] = { 1.32, // MONITORED_LINE_1_2V 3.63, // MONITORED_LINE_3_3V 5.5, // MONITORED_LINE_5V_LOGIC 5.5, // MONITORED_LINE_5V_SENSORS 26.4, // MONITORED_LINE_24V 30.0, // MONITORED_LINE_24V_REGEN 1.05, // MONITORED_LINE_FPGA_REF_V 3.3, // MONITORED_LINE_PBA_REF_V }; /// Minimum voltage/current level for each monitored signal. static const F32 MIN_VOLTAGES[ NUM_OF_MONITORED_LINES ] = { 1.08, // MONITORED_LINE_1_2V 2.97, // MONITORED_LINE_3_3V 4.5, // MONITORED_LINE_5V_LOGIC 4.5, // MONITORED_LINE_5V_SENSORS 21.6, // MONITORED_LINE_24V 18.0, // MONITORED_LINE_24V_REGEN 0.95, // MONITORED_LINE_FPGA_REF_V 2.7, // MONITORED_LINE_PBA_REF_V }; // ********** private data ********** static VOLTAGES_STATE_T voltagesState; ///< Current state of voltages monitor state machine. static U32 voltagesDataPublicationTimerCounter = 14; ///< Used to schedule voltages monitor data publication to CAN bus. /// Interval (in ms) at which to publish voltages monitor data to CAN bus. static OVERRIDE_U32_T voltagesDataPublishInterval = { VOLTAGES_DATA_PUB_INTERVAL, VOLTAGES_DATA_PUB_INTERVAL, 0, 0 }; static OVERRIDE_F32_T voltages[ NUM_OF_MONITORED_LINES ]; ///< Monitored voltages and currents. static U32 voltageAlarmPerisistenceCtr[ NUM_OF_MONITORED_LINES ]; ///< Alarm persistence counters for voltage check failures. // ********** private function prototypes ********** static VOLTAGES_STATE_T handleVoltagesInitState( void ); static VOLTAGES_STATE_T handleVoltagesMonitorState( void ); static void checkVoltageRanges( void ); static void publishVoltagesData( void ); static U32 getPublishVoltagesDataInterval( void ); /*********************************************************************//** * @brief * The initVoltagesMonitor function initializes the Voltages module. * @details Inputs: none * @details Outputs: Voltages module initialized. * @return none *************************************************************************/ void initVoltagesMonitor( void ) { U32 i; voltagesState = VOLTAGES_INIT_STATE; for ( i = 0; i < (U32)NUM_OF_MONITORED_LINES; i++ ) { voltages[i].data = 0.0; voltages[i].ovData = 0.0; voltages[i].ovInitData = 0.0; voltages[i].override = OVERRIDE_RESET; voltageAlarmPerisistenceCtr[i] = 0; } } /*********************************************************************//** * @brief * The execVoltagesMonitor function executes the voltages monitor. * @details Inputs: voltagesState * @details Outputs: voltagesState * @return none *************************************************************************/ void execVoltagesMonitor( void ) { // State machine switch ( voltagesState ) { case VOLTAGES_INIT_STATE: voltagesState = handleVoltagesInitState(); break; case VOLTAGES_MONITOR_STATE: voltagesState = handleVoltagesMonitorState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, 0, voltagesState ) // TODO - add enum for this s/w fault break; } // Publish voltages data on interval publishVoltagesData(); } /*********************************************************************//** * @brief * The handleVoltagesInitState function handles the initialize state * of the voltages monitor state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static VOLTAGES_STATE_T handleVoltagesInitState( void ) { VOLTAGES_STATE_T result = VOLTAGES_MONITOR_STATE; return result; } /*********************************************************************//** * @brief * The handleVoltagesMonitorState function handles the monitor state * of the voltages monitor state machine. * @details Inputs: converted internal ADC readings * @details Outputs: alarm on failed check * @return next state *************************************************************************/ static VOLTAGES_STATE_T handleVoltagesMonitorState( void ) { VOLTAGES_STATE_T result = VOLTAGES_MONITOR_STATE; // Get latest signal levels voltages[ MONITORED_LINE_1_2V ].data = getIntADCVoltageConverted( INT_ADC_1_2V_PROCESSOR ); voltages[ MONITORED_LINE_3_3V ].data = getIntADCVoltageConverted( INT_ADC_3_3V ); voltages[ MONITORED_LINE_5V_LOGIC ].data = getIntADCVoltageConverted( INT_ADC_5V_LOGIC ); voltages[ MONITORED_LINE_5V_SENSORS ].data = getIntADCVoltageConverted( INT_ADC_5V_SENSORS ); voltages[ MONITORED_LINE_24V ].data = getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS ); voltages[ MONITORED_LINE_24V_REGEN ].data = getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS_REG ); voltages[ MONITORED_LINE_FPGA_REF_V ].data = getIntADCVoltageConverted( INT_ADC_FPGA_ADC_REF ); voltages[ MONITORED_LINE_PBA_REF_V ].data = getIntADCVoltageConverted( INT_ADC_PBA_ADC_REF ); // Check voltage ranges checkVoltageRanges(); return result; } /*********************************************************************//** * @brief * The checkVoltageRanges function checks each monitored voltage or current * against its minimum and maximum range. * @details Inputs: voltageAlarmPerisistenceCtr, MAX_VOLTAGES[], MIN_VOLTAGES[], voltages[] * @details Outputs: voltageAlarmPerisistenceCtr, alarm if out of range * @return none *************************************************************************/ static void checkVoltageRanges( void ) { U32 i; // Check range for ( i = 0; i < NUM_OF_MONITORED_LINES; i++ ) { F32 volts = getMonitoredLineLevel( (MONITORED_VOLTAGES_T)i ); if ( volts > MAX_VOLTAGES[ i ] ) { if ( ++voltageAlarmPerisistenceCtr[ i ] > VOLTAGES_ALARM_PERSISTENCE ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_VOLTAGE_OUT_OF_RANGE, (F32)i, volts ) } } else if ( volts < MIN_VOLTAGES[ i ] ) { if ( ++voltageAlarmPerisistenceCtr[ i ] > VOLTAGES_ALARM_PERSISTENCE ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_VOLTAGE_OUT_OF_RANGE, (F32)i, volts ) } } else { voltageAlarmPerisistenceCtr[ i ] = 0; } } } /*********************************************************************//** * @brief * The getPublishVoltagesDataInterval function gets the voltages monitor data * publication interval. * @details Inputs: voltagesDataPublishInterval * @details Outputs: none * @return the current voltage monitor data publication interval (in task intervals). *************************************************************************/ static U32 getPublishVoltagesDataInterval( void ) { U32 result = voltagesDataPublishInterval.data; if ( OVERRIDE_KEY == voltagesDataPublishInterval.override ) { result = voltagesDataPublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The getMonitoredLineLevel function gets the current voltage or current * level for a given signal. * @details Inputs: voltages[] * @details Outputs: none * @param signal the signal that is being asked for * @return the voltage/current for the given signal *************************************************************************/ F32 getMonitoredLineLevel( MONITORED_VOLTAGES_T signal ) { F32 result = 0.0; if ( signal < NUM_OF_MONITORED_LINES ) { result = voltages[ signal ].data; if ( OVERRIDE_KEY == voltages[ signal ].override ) { result = voltages[ signal ].ovData; } } else { // TODO - s/w fault } return result; } /*********************************************************************//** * @brief * The publishVoltagesData function publishes voltages monitor data at the * set interval. * @details Inputs: latest voltages and currents * @details Outputs: voltages monitor data are published to CAN bus. * @return none *************************************************************************/ static void publishVoltagesData( void ) { // Publish voltages monitor data on interval if ( ++voltagesDataPublicationTimerCounter >= getPublishVoltagesDataInterval() ) { VOLTAGES_DATA_PAYLOAD_T data; data.adc1_2VProc = getMonitoredLineLevel( MONITORED_LINE_1_2V ); data.adc3_3V = getMonitoredLineLevel( MONITORED_LINE_3_3V ); data.adc5VLogic = getMonitoredLineLevel( MONITORED_LINE_5V_LOGIC ); data.adc5VSensors = getMonitoredLineLevel( MONITORED_LINE_5V_SENSORS ); data.adc24V = getMonitoredLineLevel( MONITORED_LINE_24V ); data.adc24VRegen = getMonitoredLineLevel( MONITORED_LINE_24V_REGEN ); data.adcFpgaAdcRef = getMonitoredLineLevel( MONITORED_LINE_FPGA_REF_V ); data.adcPbaRef = getMonitoredLineLevel( MONITORED_LINE_PBA_REF_V ); broadcastVoltagesData( data ); voltagesDataPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The execVoltagesTest function executes the voltage monitor self-test. * @details Inputs: none * @details Outputs: none * @return the result of the voltage monitor self-test. *************************************************************************/ SELF_TEST_STATUS_T execVoltagesTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; // TODO - implement return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetVoltagesDataPublishIntervalOverride function overrides the * monitored voltages data publish interval. * @details Inputs: none * @details Outputs: voltagesDataPublishInterval * @param value override monitored voltages data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetVoltagesDataPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_GENERAL_INTERVAL; result = TRUE; voltagesDataPublishInterval.ovData = intvl; voltagesDataPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetVoltagesDataPublishIntervalOverride function resets the override * of the monitored voltages data publish interval. * @details Inputs: none * @details Outputs: voltagesDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetVoltagesDataPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; voltagesDataPublishInterval.override = OVERRIDE_RESET; voltagesDataPublishInterval.ovData = voltagesDataPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetLineLevelOverride function overrides the given monitored voltage * or current. * @details Inputs: none * @details Outputs: voltages[] * @param signal the signal to override * @param value override signal level with this value * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetLineLevelOverride( U32 signal, F32 value ) { BOOL result = FALSE; if ( signal < NUM_OF_MONITORED_LINES ) { if ( TRUE == isTestingActivated() ) { result = TRUE; voltages[ signal ].ovData = value; voltages[ signal ].override = OVERRIDE_KEY; } } return result; } /*********************************************************************//** * @brief * The testResetLineLevelOverride function resets the override of the * given monitored voltage or current. * @details Inputs: none * @details Outputs: voltages[] * @param signal the signal to reset override * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetLineLevelOverride( U32 signal ) { BOOL result = FALSE; if ( signal < NUM_OF_MONITORED_LINES ) { if ( TRUE == isTestingActivated() ) { result = TRUE; voltages[ signal ].override = OVERRIDE_RESET; voltages[ signal ].ovData = voltages[ signal ].ovInitData; } } return result; } /**@}*/