/************************************************************************** * * Copyright (c) 2021-2022 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) Dara Navaei * @date (last) 02-May-2022 * * @author (original) Sean Nash * @date (original) 21-Apr-2021 * ***************************************************************************/ #include "AlarmMgmt.h" #include "InternalADC.h" #include "MessageSupport.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" #include "Voltages.h" #include "FPGA.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. #define DATA_PUBLISH_COUNTER_START_COUNT 1 ///< Data publish counter start count. /*#define SIZE_OF_ROLLING_AVG 16 ///< Number of DG FPGA ADC samples in rolling average calculations for each channel. #define ROLLING_AVG_SHIFT_DIVIDER 4 ///< Rolling average shift divider for DG FPGA ADC readings. #define FPGA_ADC_BITS_PER_CHANNEL 12 ///< DG FPGA ADC bits per channel. #define FPGA_ADC_FULL_SCALE_BITS ((1<> ROLLING_AVG_SHIFT_DIVIDER; adcReadingsIdx[ ch ] = INC_WRAP( adcReadingsIdx[ ch ], 0, SIZE_OF_ROLLING_AVG - 1 ); fpgaVoltage[ch] = (F32)adcReadingsAvgs[ ch ] * FPGA_ADC_READ_TO_UNITS[ ch ]; }*/ } /*********************************************************************//** * @brief * The checkVoltageRanges function checks each monitored voltage or current * against its minimum and maximum range. * @details Inputs: voltageAlarmPersistenceCtr, MAX_VOLTAGES[], MIN_VOLTAGES[], voltages[] * @details Outputs: voltageAlarmPersistenceCtr, alarm if out of range * @return none *************************************************************************/ static void checkVoltageRanges( void ) { U32 i; // Check range for ( i = 0; i <= MONITORED_LINE_LAST_RANGE_CHECKED_LINE; i++ ) { F32 volts = getMonitoredLineLevel( (MONITORED_VOLTAGES_T)i ); if ( volts > MAX_VOLTAGES[ i ] ) { if ( ++voltageAlarmPersistenceCtr[ i ] > VOLTAGES_ALARM_PERSISTENCE ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_VOLTAGE_OUT_OF_RANGE, (F32)i, volts ) } } else if ( volts < MIN_VOLTAGES[ i ] ) { if ( ++voltageAlarmPersistenceCtr[ i ] > VOLTAGES_ALARM_PERSISTENCE ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_VOLTAGE_OUT_OF_RANGE, (F32)i, volts ) } } else { voltageAlarmPersistenceCtr[ i ] = 0; } } // TODO - check heater voltages depending on current PWM level } /*********************************************************************//** * @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 = getF32OverrideValue( &voltages[ signal ] ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)SW_FAULT_ID_INVALID_MONITORED_VOLTAGE_ID, (U32)signal ) } 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 >= getU32OverrideValue( &voltagesDataPublishInterval ) ) { VOLTAGES_DATA_PAYLOAD_T data; data.adc1VFPGA = getMonitoredLineLevel( MONITORED_LINE_1V_FPGA ); data.adc1_2VProc = getMonitoredLineLevel( MONITORED_LINE_1_2V_PROC ); data.adc1_8VProc = getMonitoredLineLevel( MONITORED_LINE_1_8V_PROC ); data.adc1_8VFPGA = getMonitoredLineLevel( MONITORED_LINE_1_8V_FPGA ); data.adc3VRef = getMonitoredLineLevel( MONITORED_LINE_V_REF ); data.adc3VExtADC1 = getMonitoredLineLevel( MONITORED_LINE_EXT_ADC_1_REF_V ); data.adc3VExtADC2 = getMonitoredLineLevel( MONITORED_LINE_EXT_ADC_2_REF_V ); data.adc3_3V = getMonitoredLineLevel( MONITORED_LINE_3_3V ); data.adc3_3VSensors = getMonitoredLineLevel( MONITORED_LINE_3_3V_SENSORS ); data.adc5VLogic = getMonitoredLineLevel( MONITORED_LINE_5V_LOGIC ); data.adc5VSensors = getMonitoredLineLevel( MONITORED_LINE_5V_SENSORS ); data.adc5VPSGateDriver = getMonitoredLineLevel( MONITORED_LINE_PS_GATE_DRIVER_V ); data.adc24V = getMonitoredLineLevel( MONITORED_LINE_24V_MAIN ); data.adc24VPrimaryHtr = getMonitoredLineLevel( MONITORED_LINE_24V_PRIM_HTR_V ); data.adc24VPrimaryHtrGnd = getMonitoredLineLevel( MONITORED_LINE_24V_PRIM_HTR_V ); data.adc24VSecondaryHtr = getMonitoredLineLevel( MONITORED_LINE_24V_SEC_HTR_V ); data.adc24VTrimmerHtr = getMonitoredLineLevel( MONITORED_LINE_24V_TRIM_HTR_V ); broadcastData( MSG_ID_DG_VOLTAGES_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( VOLTAGES_DATA_PAYLOAD_T ) ); voltagesDataPublicationTimerCounter = 0; } } /************************************************************************* * 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; } /**@}*/