Index: firmware/App/Controllers/Pressures.c =================================================================== diff -u -r68fc03b5a22f14190146fc9069f022c109682b63 -r3522b1667b4b156ea14aa90f83b7d1d23d9d5d5b --- firmware/App/Controllers/Pressures.c (.../Pressures.c) (revision 68fc03b5a22f14190146fc9069f022c109682b63) +++ firmware/App/Controllers/Pressures.c (.../Pressures.c) (revision 3522b1667b4b156ea14aa90f83b7d1d23d9d5d5b) @@ -1,25 +1,33 @@ -/**********************************************************************//** - * - * 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 Pressures.c - * - * @date 05-Apr-2020 - * @author S. Nash - * - * @brief Monitor for DG pressure sensors. - * - **************************************************************************/ - -#include "Pressures.h" +/************************************************************************** +* +* Copyright (c) 2020-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 Pressures.c +* +* @author (last) Dara Navaei +* @date (last) 21-Sep-2022 +* +* @author (original) Sean +* @date (original) 04-Apr-2020 +* +***************************************************************************/ +#include + #include "AlarmMgmt.h" #include "FPGA.h" -#include "OperationModes.h" -#include "SystemCommMessages.h" -#include "TaskPriority.h" +#include "InternalADC.h" +#include "MessageSupport.h" +#include "NVDataMgmt.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "Pressures.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "TaskPriority.h" +#include "TemperatureSensors.h" #include "Timers.h" /** @@ -29,66 +37,172 @@ // ********** private definitions ********** -/// Default publication interval for pressure and occlusion data. -#define PRESSURES_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< interval (ms/task time) at which the pressures data is published on the CAN bus. +#define PUMP_PRESSURE_ZERO 777 ///< ADC counts equivalent to 0 PSI for pump in/out pressure sensors. +#define PUMP_PRESSURE_PSIA_PER_COUNT 0.06583F ///< PSIA per ADC count conversion factor for pump in/out pressure sensors. +#define PUMP_PRESSURE_PSIA_TO_PSI_OFFSET 14.7F ///< Subtract this offset to convert PSIA to PSI. +#define ONE_BAR_TO_PSI_CONVERSION 14.5F ///< 1 bar to PSI conversion. +#define ONE_BAR_TO_MILLI_BAR 1000 ///< 1 bar to milli bar conversion. +#define COUNTS_TO_MILLI_BAR 100 ///< Counts to milli bar conversion. +#define PRESSURE_SAMPLES_TO_AVERAGE ( 200 / TASK_PRIORITY_INTERVAL ) ///< Averaging pressure data over the reporting interval. +#define PRESSURE_AVERAGE_MULTIPLIER ( 1.0F / (F32)PRESSURE_SAMPLES_TO_AVERAGE ) ///< Optimization - multiplying is faster than dividing. + +#define MIN_VALID_PRESSURE_RANGE 0.0F ///< Minimum valid range on pressure reading. +#define MAX_VALID_PRESSURE_RANGE 200.0F ///< Maximum valid range on pressure reading. + +#define MAX_INLET_WATER_PRESSURE_WARNING_LOW 25.0F ///< Maximum allowed low pressure value. +#define MIN_INLET_WATER_PRESSURE_WARNING_LOW 28.0F ///< Minimum allowed low pressure value. + +#define INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for pressure out of range error. +#define PRESSURE_OUT_OF_RANGE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Pressure out of range persistence period in milliseconds. +#define PRESSURES_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the pressures data is published on the CAN bus. +#define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. +#define PRESSURE_SENSORS_ADC_CHECK_ARRAY_LEN 4 ///< Pressure sensors ADC check array length. + +static const U32 TWO_TO_POWER_OF_6 = ( 1 << 6 ); ///< 2^6. +static const U32 TWO_TO_POWER_OF_7 = ( 1 << 7 ); ///< 2^7. +static const U32 TWO_TO_POWER_OF_15 = ( 1 << 15 ); ///< 2^15. +static const U32 TWO_TO_POWER_OF_16 = ( 1 << 16 ); ///< 2^16. +static const U32 TWO_TO_POWER_OF_17 = ( 1 << 17 ); ///< 2^17. +static const U32 TWO_TO_POWER_OF_21 = ( 1 << 21 ); ///< 2^21. + /// Defined states for the pressures monitor state machine. typedef enum PresOccl_States { - PRESSURE_INIT_STATE = 0, ///< Initialization state. - PRESSURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. - NUM_OF_PRESSURE_STATES ///< Number of pressure monitor states. + PRESSURE_INIT_STATE = 0, ///< Initialization state. + PRESSURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. + NUM_OF_PRESSURE_STATES ///< Number of pressure monitor states. } PRESSURE_STATE_T; -/// Defined states for the pressures self test state machine. +/// Defined states for the pressures self-test state machine. typedef enum Pressures_Self_Test_States { - PRESSURE_SELF_TEST_STATE_START = 0, ///< Self test start state. - PRESSURE_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. - PRESSURE_TEST_STATE_COMPLETE, ///< Self test completed state. - NUM_OF_PRESSURE_SELF_TEST_STATES ///< Number of pressure self test states. -} PRESSURE_SELF_TEST_STATE_T; + PRESSURE_SELF_TEST_STATE_START = 0, ///< Self-test start state. + PRESSURE_TEST_STATE_IN_PROGRESS, ///< Self-test in progress state. + PRESSURE_TEST_STATE_COMPLETE, ///< Self-test completed state. + NUM_OF_PRESSURE_SELF_TEST_STATES ///< Number of pressure self-test states. +} PRESSURE_SELF_TEST_STATE_T; + +/// Barometric sensor conversion coefficients +typedef struct +{ + U16 pressureSensitivity; ///< Barometric sensor pressure sensitivity constant. + U16 pressureOffset; ///< Barometric sensor pressure offset constant. + U16 pressureSensitivityTempCoeff; ///< Barometric sensor pressure sensitivity temperature coefficient. + U16 pressureOffsetTempCoeff; ///< Barometric sensor pressure offset temperature coefficient. +} BARO_SENSOR_CONSTS_T; // ********** private data ********** -static PRESSURE_STATE_T pressuresState = PRESSURE_INIT_STATE; ///< current state of pressure monitor state machine. -static U32 pressuresDataPublicationTimerCounter = 0; ///< used to schedule pressure data publication to CAN bus. +static PRESSURE_STATE_T pressuresState; ///< current state of pressure monitor state machine. +static U32 pressuresDataPublicationTimerCounter; ///< used to schedule pressure data publication to CAN bus. +static OVERRIDE_U32_T pressuresDataPublishInterval = { PRESSURES_DATA_PUB_INTERVAL, + PRESSURES_DATA_PUB_INTERVAL, 0, 0 }; /// Pressure data publish interval. +static OVERRIDE_F32_T pressures[ NUM_OF_PRESSURE_SENSORS ]; ///< Measured pressure from sensors. +static S32 msrdPressureSum[ NUM_OF_PRESSURE_SENSORS ]; ///< Raw pressure sensor sums for averaging. +static U32 pressureFilterCounter; ///< Used to schedule pressure sensor filtering. +static BARO_SENSOR_CONSTS_T baroConvConsts; ///< Barometric sensor conversion constants. +static PRESSURE_SELF_TEST_STATE_T pressuresSelfTestState; ///< Current pressure self-test state. +static SELF_TEST_STATUS_T pressuresSelfTestResult; ///< Self-test result of the Pressures module. +static DG_PRES_SENSORS_CAL_RECORD_T pressuresCalRecord; ///< Pressures calibration record. -static OVERRIDE_U32_T pressuresDataPublishInterval = { PRESSURES_DATA_PUB_INTERVAL, PRESSURES_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish pressures data to CAN bus. -static OVERRIDE_F32_T pressures[ NUM_OF_PRESSURE_SENSORS ]; ///< Measured weight from load cells. - -static PRESSURE_SELF_TEST_STATE_T pressuresSelfTestState = PRESSURE_SELF_TEST_STATE_START; ///< current pressure self test state. -static U32 pressuresSelfTestTimerCount = 0; ///< timer counter for pressure self test. - // ********** private function prototypes ********** static PRESSURE_STATE_T handlePressuresInitState( void ); static PRESSURE_STATE_T handlePressuresContReadState( void ); -static void checkPressures( void ); -static void publishPressuresData( void ); -static DATA_GET_PROTOTYPE( U32, getPublishPressuresDataInterval ); +static void publishPressuresData( void ); +static SELF_TEST_STATUS_T handleSelfTestADCCheck( void ); +static F32 calculateBaroPressure( U32 adcSum ); +static F32 getCalibrationAppliedPressure( U08 sensorId, F32 pressure ); +static F32 getBaroPressurePSI( void ); -/**@}*/ - /*********************************************************************//** * @brief * The initPressures function initializes the Pressures module. - * @details - * Inputs : none - * Outputs : Pressures module initialized. + * @details Inputs: none + * @details Outputs: Pressures module initialized. * @return none *************************************************************************/ void initPressures( void ) { - // TODO - anything to initialize? -} + U08 i; + pressuresState = PRESSURE_INIT_STATE; + pressuresSelfTestState = PRESSURE_SELF_TEST_STATE_START; + pressuresDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + pressureFilterCounter = 0; + for ( i = 0; i < NUM_OF_PRESSURE_SENSORS; i++ ) + { + pressures[ i ].data = 0.0; + pressures[ i ].ovData = 0.0; + pressures[ i ].ovInitData = 0.0; + pressures[ i ].override = OVERRIDE_RESET; + msrdPressureSum[ i ] = 0; + } + + initPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_PRESSURE_OUT_OF_RANGE, PRESSURE_OUT_OF_RANGE_TIMEOUT_MS, PRESSURE_OUT_OF_RANGE_TIMEOUT_MS ); +} + +/*********************************************************************//** + * @brief + * The checkInletWaterPressure function checks inlet water pressure value + * and triggers an alarm when pressure value is out of allowed range. + * @details Inputs: RO pump inlet pressure sensor value + * @details Outputs: Triggers low pressure persistent alarm + * @return none + *************************************************************************/ +void checkInletWaterPressure( void ) +{ +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + F32 pressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ); + BOOL isPressureTooLow = ( pressure < MAX_INLET_WATER_PRESSURE_WARNING_LOW ? TRUE : FALSE ); + + // Alarm per PRS 401 + if ( TRUE == isPressureTooLow ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE, isPressureTooLow, pressure, MAX_INLET_WATER_PRESSURE_WARNING_LOW ); + } + else + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE, FALSE, pressure, MAX_INLET_WATER_PRESSURE_WARNING_LOW ); + } + } +} + +/*********************************************************************//** + * @brief + * The getMeasuredArterialPressure function gets the current arterial pressure. + * @details Inputs: arterialPressure + * @details Outputs: none + * @param pressureID pressure sensor ID + * @return the current arterial pressure (in mmHg). + *************************************************************************/ +F32 getMeasuredDGPressure( U32 pressureID ) +{ + F32 result = 0.0; + + if ( pressureID < NUM_OF_PRESSURE_SENSORS ) + { + result = getF32OverrideValue( &pressures[ pressureID ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_PRESSURE_SENSOR_ID, pressureID ); + } + + return result; +} + /*********************************************************************//** * @brief - * The execPressures function executes the pressure monitor. - * @details - * Inputs : pressuresState - * Outputs : pressuresState + * The execPressures function executes the pressures' monitor state machine + * and publish pressures' data. + * @details Inputs: pressuresState + * @details Outputs: pressuresState * @return none *************************************************************************/ void execPressures( void ) @@ -105,186 +219,286 @@ break; default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_PRESSURE_INVALID_EXEC_STATE, pressuresState ) pressuresState = PRESSURE_INIT_STATE; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, 0, pressuresState ) // TODO - replace 1st param with s/w fault enum break; } // publish pressure/occlusion data on interval publishPressuresData(); +} + +/*********************************************************************//** + * @brief + * The execPressureSelfTest function executes the pressures self-test's + * state machine. + * @details Inputs: pressuresSelfTestState + * @details Outputs: pressuresSelfTestState + * @return PressuresSelfTestResult (SELF_TEST_STATUS_T) + *************************************************************************/ +SELF_TEST_STATUS_T execPressureSelfTest( void ) +{ + switch ( pressuresSelfTestState ) + { + case PRESSURE_SELF_TEST_STATE_START: + { + BOOL calStatus = getNVRecord2Driver( GET_CAL_PRESSURE_SENOSRS, (U08*)&pressuresCalRecord, sizeof( DG_PRES_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_PRES_SENSORS, ALARM_ID_NO_ALARM ); + if ( TRUE == calStatus ) + { + pressuresSelfTestState = PRESSURE_TEST_STATE_IN_PROGRESS; + pressuresSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; + } + else + { + pressuresSelfTestResult = SELF_TEST_STATUS_FAILED; + } + } + break; + + case PRESSURE_TEST_STATE_IN_PROGRESS: + pressuresSelfTestResult = handleSelfTestADCCheck(); + pressuresSelfTestState = PRESSURE_TEST_STATE_COMPLETE; + + break; + + case PRESSURE_TEST_STATE_COMPLETE: + // Done with self-test + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DG_PRESSURES_INVALID_SELF_TEST_STATE, pressuresSelfTestState ); + break; + } + + return pressuresSelfTestResult; } /*********************************************************************//** * @brief - * The handlePressuresInitState function handles the pressures initialize state \n + * The handlePressuresInitState function handles the pressures initialize state * of the pressures monitor state machine. - * @details - * Inputs : TBD - * Outputs : TBD + * @details Inputs: none + * @details Outputs: none * @return next state *************************************************************************/ static PRESSURE_STATE_T handlePressuresInitState( void ) { - PRESSURE_STATE_T result = PRESSURE_CONTINUOUS_READ_STATE; - - return result; + return PRESSURE_CONTINUOUS_READ_STATE; } /*********************************************************************//** * @brief - * The handlePressuresContReadState function handles the continuous read state \n + * The handlePressuresContReadState function handles the continuous read state * of the pressures monitor state machine. - * @details - * Inputs : TBD - * Outputs : pressure sensor values updated + * @details Inputs: pressureFilterCounter + * @details Outputs: pressure sensor values updated * @return next state *************************************************************************/ static PRESSURE_STATE_T handlePressuresContReadState( void ) -{ - PRESSURE_STATE_T result = PRESSURE_CONTINUOUS_READ_STATE; - - U16 roIn = getFPGAROPumpInletPressure(); - U16 roOut = getFPGAROPumpOutletPressure(); - U16 drainIn = getFPGADrainPumpInletPressure(); - U16 drainOut = getFPGADrainPumpOutletPressure(); - - // TODO - convert ADC counts to mmHg for each sensor - pressures[ PRESSURE_SENSOR_RO_PUMP_INLET ].data = (F32)roIn; - pressures[ PRESSURE_SENSOR_RO_PUMP_OUTLET ].data = (F32)roOut; - pressures[ PRESSURE_SENSOR_DRAIN_PUMP_INLET ].data = (F32)drainIn; - pressures[ PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ].data = (F32)drainOut; - - // TODO - any filtering required??? - - // check for pressure ranges - checkPressures(); - - // TODO - any other checks - - return result; -} - -/*********************************************************************//** - * @brief - * The checkPressures function checks the pressure sensors are in range. - * @details - * Inputs : pressures[] - * Outputs : none - * @return none - *************************************************************************/ -static void checkPressures( void ) -{ -} - -/*********************************************************************//** - * @brief - * The getPublishPresOcclDataInterval function gets the pressure/occlusion data \n - * publication interval. - * @details - * Inputs : pressuresDataPublishInterval - * Outputs : none - * @return the current pressures data publication interval (in task intervals). - *************************************************************************/ -U32 getPublishPressuresDataInterval( void ) -{ - U32 result = pressuresDataPublishInterval.data; - - if ( OVERRIDE_KEY == pressuresDataPublishInterval.override ) - { - result = pressuresDataPublishInterval.ovData; +{ + PRESSURE_STATE_T result = PRESSURE_CONTINUOUS_READ_STATE; + U08 sensorId; + F32 pressureReading; + BOOL isPressureOutOfRange; + + // Update sums for pressure average calculations + msrdPressureSum[ PRESSURE_SENSOR_RO_PUMP_INLET ] += (S32)getIntADCReading( INT_ADC_RO_PUMP_INLET_PRESSURE ) - PUMP_PRESSURE_ZERO; + msrdPressureSum[ PRESSURE_SENSOR_RO_PUMP_OUTLET ] += (S32)getIntADCReading( INT_ADC_RO_PUMP_OUTLET_PRESSURE ) - PUMP_PRESSURE_ZERO; + msrdPressureSum[ PRESSURE_SENSOR_DRAIN_PUMP_INLET ] += (S32)getIntADCReading( INT_ADC_DRAIN_PUMP_INLET_PRESSURE ) - PUMP_PRESSURE_ZERO; + msrdPressureSum[ PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ] += (S32)getIntADCReading( INT_ADC_DRAIN_PUMP_OUTLET_PRESSURE ) - PUMP_PRESSURE_ZERO; + msrdPressureSum[ PRESSURE_SENSOR_BAROMETRIC ] += (S32)( getFPGABaroPressure() & MASK_OFF_U32_MSB ); + + // Check if a new calibration is available + if ( TRUE == isNewCalibrationRecordAvailable() ) + { + getNVRecord2Driver( GET_CAL_PRESSURE_SENOSRS, (U08*)&pressuresCalRecord, sizeof( DG_PRES_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_PRES_SENSORS, ALARM_ID_NO_ALARM ); } - return result; -} - -/*********************************************************************//** - * @brief - * The getMeasuredArterialPressure function gets the current arterial pressure. - * @details - * Inputs : arterialPressure - * Outputs : none - * @return the current arterial pressure (in mmHg). - *************************************************************************/ -F32 getMeasuredDGPressure( U32 pressureID ) -{ - F32 result = 0.0; - - if ( pressureID <= NUM_OF_PRESSURE_SENSORS ) - { - if ( OVERRIDE_KEY == pressures[ pressureID ].override ) - { - result = pressures[ pressureID ].ovData; - } - else - { - result = pressures[ pressureID ].data; - } + // filter every 200ms + if ( ++pressureFilterCounter >= PRESSURE_SAMPLES_TO_AVERAGE ) + { + F32 adcSum; + F32 pressureBeforeCal = 0.0; + F32 baroPressure = getBaroPressurePSI(); + pressureFilterCounter = 0; + + for ( sensorId = 0; sensorId < NUM_OF_PRESSURE_SENSORS; sensorId++ ) + { + adcSum = (F32)msrdPressureSum[ sensorId ] * PRESSURE_AVERAGE_MULTIPLIER; + + switch ( sensorId ) + { + case PRESSURE_SENSOR_RO_PUMP_INLET: + case PRESSURE_SENSOR_RO_PUMP_OUTLET: + case PRESSURE_SENSOR_DRAIN_PUMP_OUTLET: + case PRESSURE_SENSOR_DRAIN_PUMP_INLET: + pressureBeforeCal = ( adcSum * PUMP_PRESSURE_PSIA_PER_COUNT ) - baroPressure; + pressures[ sensorId ].data = getCalibrationAppliedPressure( sensorId, pressureBeforeCal ); + msrdPressureSum[ sensorId ] = 0; + break; + + case PRESSURE_SENSOR_BAROMETRIC: + baroConvConsts.pressureSensitivity = getFPGABaroPressureSensitivity(); + baroConvConsts.pressureSensitivityTempCoeff = getFPGABaroTempCoeffOfPressSensitvity(); + baroConvConsts.pressureOffset = getFPGABaroPressureOffset(); + baroConvConsts.pressureOffsetTempCoeff = getFPGABaroTempCoeffOfPressOffset(); + pressureBeforeCal = calculateBaroPressure( (U32)adcSum ); + pressures[ sensorId ].data = getCalibrationAppliedPressure( sensorId, pressureBeforeCal ); + msrdPressureSum[ sensorId ] = 0; + break; + } + } } - else - { - activateAlarmNoData( ALARM_ID_SOFTWARE_FAULT ); + + for ( sensorId = 0; sensorId < NUM_OF_PRESSURE_SENSORS; sensorId++ ) + { + pressureReading = getMeasuredDGPressure( sensorId ) + getBaroPressurePSI(); + isPressureOutOfRange = ( ( pressureReading < MIN_VALID_PRESSURE_RANGE ) || ( pressureReading > MAX_VALID_PRESSURE_RANGE ) ? TRUE : FALSE ); + + checkPersistentAlarm( ALARM_ID_DG_PRESSURE_OUT_OF_RANGE, isPressureOutOfRange, (F32)sensorId, pressureReading ); } return result; -} +} + /*********************************************************************//** * @brief - * The publishPressuresData function publishes DG pressures data at the \n - * set interval. - * @details - * Inputs : pressuresDataPublicationTimerCounter - * Outputs : DG Pressures data are published to CAN bus. + * The publishPressuresData function publishes DG pressures data at a set interval. + * @details Inputs: pressuresDataPublicationTimerCounter + * @details Outputs: pressuresDataPublicationTimerCounter * @return none *************************************************************************/ static void publishPressuresData( void ) { // publish pressure/occlusion data on interval - if ( ++pressuresDataPublicationTimerCounter >= getPublishPressuresDataInterval() ) - { - F32 roIn = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ); - F32 roOut = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); - F32 drainIn = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_INLET ); - F32 drainOut = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); + if ( ++pressuresDataPublicationTimerCounter >= getU32OverrideValue( &pressuresDataPublishInterval ) ) + { + PRESSURES_DATA_T data; + data.roPumpInletPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ); + data.roPumpOutletPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); + data.drainPumpInletPressure = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_INLET ); + data.drainPumpOutletPressure = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); - broadcastPressuresData( roIn, roOut, drainIn, drainOut ); + broadcastData( MSG_ID_DG_PRESSURES_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( PRESSURES_DATA_T ) ); pressuresDataPublicationTimerCounter = 0; } } -/*********************************************************************//** - * @brief - * The execPressuresTest function executes the state machine for the \n - * Pressures self test. - * @details - * Inputs : none - * Outputs : none - * @return the current state of the Pressures self test. - *************************************************************************/ -SELF_TEST_STATUS_T execPressuresTest( void ) -{ - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; +/*********************************************************************//** + * @brief + * The handleSelfTestADCCheck function checks whether the ADC reads and + * report status back. If the reads are above the maximum 12bit ADC count + * or equals zero, it will throw an alarm. + * @details Inputs: ADC reading for RO pump inlet pressure sensor + * @details Outputs: Performed ADC check self-test. + * @return result (SELF_TEST_STATUS_T) + *************************************************************************/ +static SELF_TEST_STATUS_T handleSelfTestADCCheck( void ) +{ + U08 i; + U16 sensorADC; + U16 sensorsADC[ PRESSURE_SENSORS_ADC_CHECK_ARRAY_LEN ]; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; + + // Insert the pressure sensors ADC read into the array + sensorsADC[ 0 ] = getIntADCReading( INT_ADC_RO_PUMP_INLET_PRESSURE ); + sensorsADC[ 1 ] = getIntADCReading( INT_ADC_RO_PUMP_OUTLET_PRESSURE ); + sensorsADC[ 2 ] = getIntADCReading( INT_ADC_DRAIN_PUMP_INLET_PRESSURE ); + sensorsADC[ 3 ] = getIntADCReading( INT_ADC_DRAIN_PUMP_OUTLET_PRESSURE ); + + for ( i = 0; i < PRESSURE_SENSORS_ADC_CHECK_ARRAY_LEN; i++ ) + { + sensorADC = sensorsADC[ i ]; + + if ( ( 0 == sensorADC ) || ( sensorADC >= INT_ADC_FULL_SCALE_BITS ) ) + { + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_PRESSURE_SENSOR_FAULT, i ); + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The calculateBaroPressure function calculates the barometric pressure + * @details Inputs: measuredPressureReadingsSum + * @details Outputs: none + * @param adcSum sum of barometric pressure sensor ADC counts + * @return barometric pressure in millibars + *************************************************************************/ +static F32 calculateBaroPressure( U32 adcSum ) +{ + S32 tempDiff = getBaroSensorTemperatureDiff(); + S64 tempOffset = ( baroConvConsts.pressureOffsetTempCoeff * tempDiff ) / TWO_TO_POWER_OF_6; + S64 presOffset = baroConvConsts.pressureOffset * TWO_TO_POWER_OF_17; + S64 offset = presOffset + tempOffset; + S64 tempSensitivity = ( baroConvConsts.pressureSensitivityTempCoeff * tempDiff ) / TWO_TO_POWER_OF_7; + S64 presSensitivity = baroConvConsts.pressureSensitivity * TWO_TO_POWER_OF_16; + S64 sensitivity = tempSensitivity + presSensitivity; + S32 pres = (S32)( ( ( adcSum * sensitivity ) / TWO_TO_POWER_OF_21 ) - offset ) / TWO_TO_POWER_OF_15; + F32 presPSI = ( (F32)pres / (F32)( COUNTS_TO_MILLI_BAR * ONE_BAR_TO_MILLI_BAR ) ) * ONE_BAR_TO_PSI_CONVERSION; + + return presPSI; +} + +/*********************************************************************//** + * @brief + * The getCalibrationAppliedPressure function applies the calibration values + * to the provided pressure and returns the values. + * @details Inputs: pressuresCalRecord + * @details Outputs: none + * @param sensorId the ID of the pressure sensor + * @param pressure the pressure before applying calibration to it + * @return calibration applied pressure + *************************************************************************/ +static F32 getCalibrationAppliedPressure( U08 sensorId, F32 pressure ) +{ + F32 calPressure = pow( pressure, 4 ) * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].fourthOrderCoeff + + pow( pressure, 3 ) * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].thirdOrderCoeff + + pow( pressure, 2 ) * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].secondOrderCoeff + + pressure * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].gain + + pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].offset; + return calPressure; +} + +/*********************************************************************//** + * @brief + * The getBaroPressurePSI function returns the barometric pressure value. + * @details Inputs: none + * @details Outputs: none + * @return barometric pressure value + *************************************************************************/ +static F32 getBaroPressurePSI( void ) +{ + F32 baroPressure = getF32OverrideValue( &pressures[ PRESSURE_SENSOR_BAROMETRIC ] ); + +#ifndef _RELEASE_ + if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) + { + baroPressure = PUMP_PRESSURE_PSIA_TO_PSI_OFFSET; + } +#endif + + return baroPressure; +} - // TODO - implement self test(s) - return result; -} - -/**@}*/ - - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ - - + + /*********************************************************************//** * @brief - * The testSetPressuresDataPublishIntervalOverride function overrides the \n - * pressure and occlusion data publish interval. - * @details - * Inputs : none - * Outputs : pressuresDataPublishInterval - * @param value : override pressure and occlusion data publish interval with (in ms) + * The testSetPressuresDataPublishIntervalOverride function overrides the + * pressure data publish interval. + * @details Inputs: none + * @details Outputs: pressuresDataPublishInterval + * @param value value to override pressure data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetPressuresDataPublishIntervalOverride( U32 value ) @@ -305,11 +519,10 @@ /*********************************************************************//** * @brief - * The testResetPressuresDataPublishIntervalOverride function resets the override \n + * The testResetPressuresDataPublishIntervalOverride function resets the override * of the pressure and occlusion data publish interval. - * @details - * Inputs : none - * Outputs : pressuresDataPublishInterval + * @details Inputs: none + * @details Outputs: pressuresDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetPressuresDataPublishIntervalOverride( void ) @@ -326,14 +539,14 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief - * The testSetDGPressureSensorOverride function overrides the value of the \n + * The testSetDGPressureSensorOverride function overrides the value of the * specified pressure sensor with a given value. - * Inputs : none - * Outputs : pressures[] - * @param sensor : ID of pressure sensor to override for - * @param value : override value for the given pressure sensor ID + * @details Inputs: none + * @details Outputs: pressures[] + * @param sensor pressure sensor ID + * @param value override value for pressure data * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDGPressureSensorOverride( U32 sensor, F32 value ) @@ -353,14 +566,13 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetDGPressureSensorOverride function resets the override of the \n * specified DG pressure sensor. - * @details - * Inputs : none - * Outputs : pressures[] - * @param value : ID of sensor to reset override pressure for + * @details Inputs: none + * @details Outputs: pressures[] + * @param sensor pressure sensor ID * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetDGPressureSensorOverride( U32 sensor ) @@ -380,3 +592,4 @@ return result; } +/**@}*/