Index: firmware/App/Drivers/InternalADC.c =================================================================== diff -u -rf3fedc73df117154665ba07bbae8e9c8dc8880d4 -r4671ebebf1334c098a4725320be54f0b94eff7bc --- firmware/App/Drivers/InternalADC.c (.../InternalADC.c) (revision f3fedc73df117154665ba07bbae8e9c8dc8880d4) +++ firmware/App/Drivers/InternalADC.c (.../InternalADC.c) (revision 4671ebebf1334c098a4725320be54f0b94eff7bc) @@ -44,6 +44,7 @@ INT_ADC_PRIMARY_ALARM_CURRENT_HG, // 8 INT_ADC_NOT_USED, // 9 INT_ADC_BOARD_THERMISTOR, // 10 + INT_ADC_1_8V_XADC, // 11 INT_ADC_3_3V, // 12 INT_ADC_5V_LOGIC, // 13 INT_ADC_PRIMARY_ALARM_CURRENT_LG, // 14 @@ -66,12 +67,12 @@ 0.001465, // V - Internal ADC channel for 5V to logic 0.001465, // V - Internal ADC channel for 3.3V 0.000733, // V - Internal ADC channel for 1.2V to processor - 0.000000, // V - Internal ADC channel for 1.8V external ADC - 0.000000, // V - Internal ADC channel for 1.0V FPGA - 0.000000, // V - Internal ADC channel for 1.8V FPGA + 0.000733, // V - Internal ADC channel for 1.8V external ADC + 0.000733, // V - Internal ADC channel for 1.0V FPGA + 0.000733, // V - Internal ADC channel for 1.8V FPGA 0.001221, // V - Internal ADC channel for PCB temperature - 0.000000, // V - Internal ADC channel for ADC reference voltage - 0.007106, // mA - Internal ADC channel for VBackup + 0.001465, // V - Internal ADC channel for ADC reference voltage + 0.009420, // V - Internal ADC channel for VBackup 0.007106, // V - Internal ADC channel for 24V to actuators (1) 0.007106, // V - Internal ADC channel for 24V to actuators (2) 0.000000, // - Not used Index: firmware/App/Monitors/Voltages.c =================================================================== diff -u --- firmware/App/Monitors/Voltages.c (revision 0) +++ firmware/App/Monitors/Voltages.c (revision 4671ebebf1334c098a4725320be54f0b94eff7bc) @@ -0,0 +1,329 @@ +/************************************************************************** +* +* Copyright (c) 2024-2024 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 +* @date (last) 07-Aug-2024 +* +* @author (original) Sean +* @date (original) 07-Aug-2024 +* +***************************************************************************/ + +#include "AlarmMgmtDD.h" +#include "FpgaDD.h" +#include "InternalADC.h" +#include "Messaging.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "SystemCommDD.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 ( 1 * MS_PER_SECOND ) ///< Alarm persistence period for voltage monitor alarms in milliseconds. +#define POWER_LOSS_VOLTAGE_PERSISTENCE_MS 500 ///< Power supply voltage out of range persistence in milliseconds. +#define DATA_PUBLISH_COUNTER_START_COUNT 14 ///< Data publish counter start count. + +/// Defined states for the voltage 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; + +/// Maximum voltage/current level for each monitored signal. +static const F32 MAX_VOLTAGES[ NUM_OF_MONITORED_VOLTAGES ] = +{ + 1.32, // MONITORED_VOLTAGE_1_2V + 3.63, // MONITORED_VOLTAGE_3_3V + 5.5, // MONITORED_VOLTAGE_5V_LOGIC + 26.4, // MONITORED_VOLTAGE_24V_1 + 26.4, // MONITORED_VOLTAGE_24V_2 + 1.1, // MONITORED_VOLTAGE_FPGA_VCC_V + 1.98, // MONITORED_VOLTAGE_FPGA_AUX_V + 0.1 // MONITORED_VOLTAGE_FPGA_PVN_V +}; +/// Minimum voltage/current level for each monitored signal. +static const F32 MIN_VOLTAGES[ NUM_OF_MONITORED_VOLTAGES ] = +{ + 1.08, // MONITORED_VOLTAGE_1_2V + 2.97, // MONITORED_VOLTAGE_3_3V + 4.5, // MONITORED_VOLTAGE_5V_LOGIC + 21.6, // MONITORED_VOLTAGE_24V_1 + 21.6, // MONITORED_VOLTAGE_24V_2 + 0.9, // MONITORED_VOLTAGE_FPGA_VCC_V + 1.62, // MONITORED_VOLTAGE_FPGA_AUX_V + -0.1 // MONITORED_VOLTAGE_FPGA_PVN_V +}; + +// ********** private data ********** + +static VOLTAGES_STATE_T voltagesState; ///< Current state of voltages monitor state machine. +static U32 voltagesDataPublicationTimerCounter; ///< 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_VOLTAGES ]; ///< Monitored voltages and currents. + +// ********** private function prototypes ********** + +static VOLTAGES_STATE_T handleVoltagesInitState( void ); +static VOLTAGES_STATE_T handleVoltagesMonitorState( void ); +static void checkVoltageRanges( void ); +static void publishVoltagesData( void ); + +/*********************************************************************//** + * @brief + * The initVoltagesMonitor function initializes the Voltages unit. + * @details \b Inputs: none + * @details \b Outputs: Voltages unit initialized. + * @return none + *************************************************************************/ +void initVoltagesMonitor( void ) +{ + U32 i; + + voltagesState = VOLTAGES_INIT_STATE; + voltagesDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + + for ( i = 0; i < (U32)NUM_OF_MONITORED_VOLTAGES; i++ ) + { + voltages[i].data = 0.0; + voltages[i].ovData = 0.0; + voltages[i].ovInitData = 0.0; + voltages[i].override = OVERRIDE_RESET; + } + +// initPersistentAlarm( ALARM_ID_DD_VOLTAGE_OUT_OF_RANGE, VOLTAGES_ALARM_PERSISTENCE_MS, VOLTAGES_ALARM_PERSISTENCE_MS ); +} + +/*********************************************************************//** + * @brief + * The execVoltagesMonitor function executes the voltages monitor state + * machine. + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if voltages state is invalid + * @details \b Inputs: voltagesState + * @details \b 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_DD_SOFTWARE_FAULT, SW_FAULT_ID_VOLTAGES_INVALID_STATE, voltagesState ) + break; + } + + // Publish voltages data on interval + publishVoltagesData(); +} + +/*********************************************************************//** + * @brief + * The handleVoltagesInitState function handles the initialize state + * of the voltages monitor state machine. + * @details \b Inputs: none + * @details \b Outputs: none + * @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 \b Inputs: converted internal ADC readings + * @details \b 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_VOLTAGE_1_2V ].data = getIntADCVoltageConverted( INT_ADC_1_2V_PROCESSOR ); + voltages[ MONITORED_VOLTAGE_3_3V ].data = getIntADCVoltageConverted( INT_ADC_3_3V ); + voltages[ MONITORED_VOLTAGE_5V_LOGIC ].data = getIntADCVoltageConverted( INT_ADC_5V_LOGIC ); + voltages[ MONITORED_VOLTAGE_24V_1 ].data = getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS_1 ); + voltages[ MONITORED_VOLTAGE_24V_2 ].data = getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS_2 ); + voltages[ MONITORED_VOLTAGE_FPGA_VCC_V ].data = 0.0F; // TODO + voltages[ MONITORED_VOLTAGE_FPGA_AUX_V ].data = 0.0F; // TODO + voltages[ MONITORED_VOLTAGE_FPGA_PVN_V ].data = 0.0F; // TODO + + // Check voltage ranges + checkVoltageRanges(); + + return result; +} + +/*********************************************************************//** + * @brief + * The checkVoltageRanges function checks each monitored voltage or current + * against its minimum and maximum range. + * @details \b Alarm: ALARM_ID_TD_VOLTAGE_OUT_OF_RANGE if voltage is out + * of range. + * @details \b Alarm: ALARM_ID_TD_AC_POWER_LOST if AC power has been lost. + * @details \b Inputs: MAX_VOLTAGES[], MIN_VOLTAGES[] + * @details \b Outputs: alarm if out of range + * @return none + *************************************************************************/ +static void checkVoltageRanges( void ) +{ + MONITORED_VOLTAGES_T channel; + MONITORED_VOLTAGES_T channelInAlarm; + BOOL isVoltageOutOfRange = FALSE; + F32 volts = 0.0F; + F32 alarmVoltage = 0.0F; + + // Check range + for ( channel = MONITORED_VOLTAGE_FIRST_VOLTAGE; channel < NUM_OF_MONITORED_VOLTAGES; channel++ ) + { + if ( /*( ( isSafetyShutdownActivated() != TRUE ) && ( hasPowerBeenLost != TRUE ) ) || */ + ( ( channel != MONITORED_VOLTAGE_24V_1 ) && ( channel != MONITORED_VOLTAGE_24V_2 ) ) ) + { +#ifndef _RELEASE_ +// if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_VOLTAGES_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + volts = getMonitoredLineLevel( channel ); + if ( ( volts > MAX_VOLTAGES[ channel ] ) || ( volts < MIN_VOLTAGES[ channel] ) ) + { + isVoltageOutOfRange = TRUE; + channelInAlarm = channel; + alarmVoltage = volts; + break; // once a channel is out of range there is no need to continue + } + } + } + } + + // Check the persistence alarm +// checkPersistentAlarm ( ALARM_ID_DD_VOLTAGE_OUT_OF_RANGE, isVoltageOutOfRange, channelInAlarm, alarmVoltage ); // TODO +} + +/*********************************************************************//** + * @brief + * The getMonitoredLineLevel function gets the current voltage or current + * level for a given signal. + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given signal is invalid. + * @details \b Inputs: voltages[] + * @details \b 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_VOLTAGES ) + { + result = getF32OverrideValue( &voltages[ signal ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VOLTAGES_INVALID_SIGNAL, (U32)signal ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The publishVoltagesData function publishes voltages monitor data at the + * set interval. + * @details \b Inputs: latest voltages and currents + * @details \b 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.adc1_2VProc = getMonitoredLineLevel( MONITORED_VOLTAGE_1_2V ); + data.adc3_3V = getMonitoredLineLevel( MONITORED_VOLTAGE_3_3V ); + data.adc5VLogic = getMonitoredLineLevel( MONITORED_VOLTAGE_5V_LOGIC ); + data.adc24V_1 = getMonitoredLineLevel( MONITORED_VOLTAGE_24V_1 ); + data.adc24V_2 = getMonitoredLineLevel( MONITORED_VOLTAGE_24V_2 ); + data.fpgaVcc = getMonitoredLineLevel( MONITORED_VOLTAGE_FPGA_VCC_V ); + data.fpgaVaux = getMonitoredLineLevel( MONITORED_VOLTAGE_FPGA_AUX_V ); + data.fpgaVpvn = getMonitoredLineLevel( MONITORED_VOLTAGE_FPGA_PVN_V ); + + broadcastData( MSG_ID_DD_VOLTAGES_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( VOLTAGES_DATA_PAYLOAD_T ) ); + voltagesDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testVoltageDataPublishIntervalOverride function overrides the interval + * at which the TD voltage data is published. + * @details \b Inputs: none + * @details \b Outputs: voltagesDataPublishInterval + * @param message Override message from Dialin which includes the interval + * (in ms) to override the voltage broadcast interval to. + * @return TRUE if override request is successful, FALSE if not + *************************************************************************/ +BOOL testVoltageDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &voltagesDataPublishInterval, TASK_GENERAL_INTERVAL ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testVoltageOverride function overrides the value for a given voltage. + * @details \b Inputs: none + * @details \b Outputs: voltages[] + * @param message Override message from Dialin which includes an ID of + * the voltage to override and the value to override the voltage to. + * @return TRUE if override request is successful, FALSE if not + *************************************************************************/ +BOOL testVoltageOverride( MESSAGE_T *message ) +{ + BOOL result = f32ArrayOverride( message, &voltages[0], NUM_OF_MONITORED_VOLTAGES - 1 ); + + return result; +} + +/**@}*/ Index: firmware/App/Monitors/Voltages.h =================================================================== diff -u --- firmware/App/Monitors/Voltages.h (revision 0) +++ firmware/App/Monitors/Voltages.h (revision 4671ebebf1334c098a4725320be54f0b94eff7bc) @@ -0,0 +1,76 @@ +/************************************************************************** +* +* Copyright (c) 2024-2024 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.h +* +* @author (last) Sean +* @date (last) 07-Aug-2024 +* +* @author (original) Sean +* @date (original) 07-Aug-2024 +* +***************************************************************************/ + +#ifndef __VOLTAGES_H__ +#define __VOLTAGES_H__ + +#include "DDCommon.h" + +/** + * @defgroup Voltages Voltages + * @brief Voltages monitor module. Monitors the various system voltages + * to ensure they are in expected range. + * + * @addtogroup Voltages + * @{ + */ + +// ********** public definitions ********** + +#define MIN_24V_MEASURED_FOR_AC 5.0F ///< Minimum voltage from 24V in order to say we have AC power. + +/// Enumeration of voltages monitored by this module. +typedef enum Voltages +{ + MONITORED_VOLTAGE_1_2V = 0, ///< Processor 1.2V + MONITORED_VOLTAGE_FIRST_VOLTAGE = MONITORED_VOLTAGE_1_2V, ///< First voltage in list + MONITORED_VOLTAGE_3_3V, ///< Logic voltage (3.3V) + MONITORED_VOLTAGE_5V_LOGIC, ///< Logic voltage (5V) + MONITORED_VOLTAGE_24V_1, ///< Actuators voltage (24V) + MONITORED_VOLTAGE_24V_2, ///< Actuators regen voltage (24V) + MONITORED_VOLTAGE_FPGA_VCC_V, ///< FPGA input voltage (3V) + MONITORED_VOLTAGE_FPGA_AUX_V, ///< FPGA aux. voltage (3V) + MONITORED_VOLTAGE_FPGA_PVN_V, ///< FPGA pvn voltage (1V) + NUM_OF_MONITORED_VOLTAGES ///< Number of monitored voltages +} MONITORED_VOLTAGES_T; + +/// Payload record structure for the voltages data message. +typedef struct +{ + F32 adc1_2VProc; ///< Internal ADC channel for 1.2V to processor + F32 adc3_3V; ///< Internal ADC channel for 3.3V + F32 adc5VLogic; ///< Internal ADC channel for 5V to logic + F32 adc24V_1; ///< Internal ADC channel for 24V to actuators + F32 adc24V_2; ///< Internal ADC channel for 24V regen (diode drop) to actuators + F32 fpgaVcc; ///< FPGA source voltage + F32 fpgaVaux; ///< FPGA aux. voltage + F32 fpgaVpvn; ///< FPGA pvn voltage +} VOLTAGES_DATA_PAYLOAD_T; + +// ********** public function prototypes ********** + +void initVoltagesMonitor( void ); +void execVoltagesMonitor( void ); + +F32 getMonitoredLineLevel( MONITORED_VOLTAGES_T signal ); + +BOOL testVoltageDataPublishIntervalOverride( MESSAGE_T *message ); +BOOL testVoltageOverride( MESSAGE_T *message ); + +/**@}*/ + +#endif Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -re01f6c0b94312dec30878967be9ffa3228e8773b -r4671ebebf1334c098a4725320be54f0b94eff7bc --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision e01f6c0b94312dec30878967be9ffa3228e8773b) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 4671ebebf1334c098a4725320be54f0b94eff7bc) @@ -144,6 +144,8 @@ SW_FAULT_ID_BLOOD_LEAK_ENQUEUE_FAILURE = 113, SW_FAULT_ID_BLOOD_LEAK_INVALID_EMB_MODE_CMD_SELECTED = 114, SW_FAULT_ID_INVALID_FILTERED_CONDUCTIVITY_SENSOR_ID = 115, + SW_FAULT_ID_VOLTAGES_INVALID_STATE = 116, + SW_FAULT_ID_VOLTAGES_INVALID_SIGNAL = 117, NUM_OF_SW_FAULT_IDS } DD_SW_FAULT_ID_T; Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r4bc9893a967e7afe3d657907cafacc335755db27 -r4671ebebf1334c098a4725320be54f0b94eff7bc --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 4bc9893a967e7afe3d657907cafacc335755db27) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 4671ebebf1334c098a4725320be54f0b94eff7bc) @@ -60,6 +60,7 @@ #include "Utilities.h" #include "Ultrafiltration.h" #include "Valves.h" +#include "Voltages.h" /** * @addtogroup Messaging @@ -228,6 +229,8 @@ { MSG_ID_FP_CONDUCTIVITY_ERROR_COUNT_OVERRIDE_REQUEST, &testFPConductivitySensorErrorCounterOverride }, { MSG_ID_FP_FILTERED_COND_SENSOR_READINGS_OVERRIDE_REQUEST, &testFPConductivitySensorFilteredReadingsOverride }, { MSG_ID_FP_FILTERED_COND_SENSOR_TEMPERATURE_OVERRIDE_REQUEST, &testFPConductivitySensorFilteredTemperatureReadingsOverride }, + { MSG_ID_DD_VOLTAGE_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testVoltageDataPublishIntervalOverride }, + { MSG_ID_DD_MONITORED_VOLTAGE_OVERRIDE_REQUEST, &testVoltageOverride }, }; /// Calculation for number of entries in the incoming message function handler look-up table.