Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r28b5f2e7f757647145a82a39aca0a5f3652c68a1 -rd3819286869611f9c02add72a0f8e321598fdf42 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 28b5f2e7f757647145a82a39aca0a5f3652c68a1) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision d3819286869611f9c02add72a0f8e321598fdf42) @@ -14,7 +14,8 @@ * @date (original) 08-Apr-2020 * ***************************************************************************/ -#include // For temperature calculation +#include // For temperature calculation +#include // For memset() #include "FPGA.h" #include "PersistentAlarm.h" @@ -51,7 +52,7 @@ #define MAX_ALLOWED_TEMP_DELTA_BETWEEN_SENSORS 2U ///< Maximum allowed temperature delta between sensors. #define SHIFT_BITS_BY_2 2U ///< Shift bits by 2 to create a 4 for averaging 4 samples. #define SHIFT_BITS_BY_2_FOR_AVERAGING 2U ///< Shift the ADCs of the temperature sensors by 2 to average them. -#define INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for temperature sensors out of range error period. +#define INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for temperature sensors out of range error period. #define MIN_WATER_INPUT_TEMPERATURE 22U ///< Minimum water input temperature. #define MAX_WATER_INPUT_TEMPERATURE 35U ///< Maximum water input temperature. @@ -75,16 +76,22 @@ #define TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ( 5 * MS_PER_SECOND ) ///< Temperature sensors FPGA error persistent period. #define TEMPERATURE_SENSORS_INTERNAL_ERROR_PERSISTENT_PERIOD ( 3 * MS_PER_SECOND ) ///< Temperature sensors internal error persistent period. #define FPGA_RAW_ADC_READ_INTERVAL_COUNT 8 ///< Time interval in counts to read the raw ADC reads from FPGA. +#define TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ( 5 * MS_PER_SECOND ) ///< Temperature sensors error flag persistent period. -/// Temperature sensor self-test states. -typedef enum tempSensors_Self_Test_States -{ - TEMPSENSORS_SELF_TEST_START = 0, ///< Temperature sensors self-test start - TEMPSENSORS_SELF_TEST_ADC_CHECK, ///< Temperature sensors self ADC check - TEMPSENSORS_SELF_TEST_COMPLETE, ///< Temperature sensors self-test complete - NUM_OF_TEMPSENSORS_SELF_TEST_STATES ///< Total number of self-test states -} TEMPSENSORS_SELF_TEST_STATES_T; +#define TEMP_SENSORS_MIN_ALLOWED_DEGREE_C 0.0 ///< Temperature sensors minimum allowed temperature in C. +#define TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 120.0 ///< Temperature sensors maximum allowed temperature in C. +#define NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 80.0 ///< Non fluid temperature sensors path maximum allowed temperature in C. +#define TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ( 5 * MS_PER_SECOND ) ///< Temperature sensor out of range persistent period in milliseconds. +// The count cannot be within 0.1V of the rail on both sides therefore: +// ADC count = ((2^12) - 1 / ref voltage) * voltage +// Max allowed voltage = 3.0 - 0.1 = 2.0V +// Min allowed voltage = 0.1 - 0.0 = 0.1V +// Max count = ((2^12) - 1 / ref voltage) * voltage -> ((4096 - 1)/3.0) * (3.0 - 0.1) +// Min count = ((2^12) - 1 / ref voltage) * voltage -> ((4096 - 1)/3.0) * (0.1 - 0.0) +#define TEMP_SENSORS_MAX_ALLOWED_ADC_COUNT 3959U ///< Temperature sensors max allowed ADC count. +#define TEMP_SESNORS_MIN_ALLOWED_ADC_COUNT 137U ///< Temperature sensors min allowed ADC count. + /// Temperature sensor exec states. typedef enum tempSensors_Exec_States { @@ -105,12 +112,11 @@ S32 adcRunningSum; ///< ADC running sum U32 readCount; ///< Read counts from FPGA OVERRIDE_F32_T temperatureValues; ///< Temperature values with override + F32 maxAllowedTemperature; ///< Maximum allowed temperature of the sensor } TEMP_SENSOR_T; // ********** private data ********** -static SELF_TEST_STATUS_T tempSensorsSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< Self-test result of the TemperatureSensors module. -static TEMPSENSORS_SELF_TEST_STATES_T tempSensorsSelfTestState; ///< TemperatureSensor self-test state. static TEMPSENSORS_EXEC_STATES_T tempSensorsExecState; ///< TemperatureSensor exec state. static TEMP_SENSOR_T tempSensors [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors' data structure. static U32 fpgaRawADCReadInterval = 0; ///< FPGA raw ADC read interval count. @@ -140,16 +146,12 @@ -1.228034E-2, 9.804036E-4, -4.413030E-5, 1.057734E-6, -1.052755E-8 }; ///< Thermocouple inverse coefficient for positive cold junction temperature. -static const U32 TEMP_SENSORS_ADC_MAX_COUNT = ( 1 << TEMP_SENSORS_ADC_BITS ) - 1; ///< ADC 24 bit max count which is (2^24 - 1). static const U32 TEMP_EQUATION_RESISTOR_CALC = 1 << ( TEMP_SENSORS_ADC_BITS - 1 ); ///< Temperature sensors resistor calculation (2^(24 - 1)). static const F32 TEMP_EQUATION_COEFF_A = 3.9083E-3; ///< ADC to temperature conversion coefficient A. static const F32 TEMP_EQUATION_COEFF_B = -5.775E-7; ///< ADC to temperature conversion coefficient B. // ********** private function prototypes ********** -static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestStart( void ); -static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestADCCheck( void ); - static TEMPSENSORS_EXEC_STATES_T handleExecStart( void ); static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ); @@ -161,14 +163,12 @@ static BOOL isADCReadValid( U32 sensorIndex, U32 fpgaError, U32 fpgaCount ); static void processADCRead( U32 sensorIndex, S32 adc ); static void publishTemperatureSensorsData( void ); -static U32 getPublishTemperatureSensorsDataInterval( void ); +static void monitorTemperatureSnsrs( U32 sensorIndex, F32 temperature ); /*********************************************************************//** * @brief * The initTemperatureSensors function initializes the module. - * @details Inputs: tempSensorsSelfTestState, tempSensorsExecState, - * elapsedTime, internalHeatersConversionTimer, dataPublicationTimerCounter, - * tempSensors, fpgaRawADCReadInterval + * @details Inputs: none * @details Outputs: tempSensorsSelfTestState, tempSensorsExecState, * elapsedTime, internalHeatersConversionTimer, dataPublicationTimerCounter, * tempSensors, fpgaRawADCReadInterval @@ -179,13 +179,11 @@ U08 i; // Initialize the variables - tempSensorsSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; - tempSensorsSelfTestState = TEMPSENSORS_SELF_TEST_START; - tempSensorsExecState = TEMPSENSORS_EXEC_STATE_START; - elapsedTime = 0; - internalHeatersConversionTimer = 0; - dataPublicationTimerCounter = 0; - fpgaRawADCReadInterval = 0; + tempSensorsExecState = TEMPSENSORS_EXEC_STATE_START; + elapsedTime = 0; + internalHeatersConversionTimer = 0; + dataPublicationTimerCounter = 0; + fpgaRawADCReadInterval = 0; /* NOTE: The temperature sensors do not have conversion coefficient. * The conversion coefficients are used for the heaters internal temperature sensors and @@ -204,28 +202,34 @@ tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].gain = PRIMARY_HEATER_EXT_TEMP_SENSORS_GAIN; tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].refResistance = PRIMARY_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].zeroDegreeResistance = PRIMARY_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; + tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].gain = PRIMARY_HEATER_EXT_TEMP_SENSORS_GAIN; tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].refResistance = PRIMARY_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].zeroDegreeResistance = PRIMARY_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; + tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // Initialize TD1 and TD2 constants tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ].gain = COND_SENSORS_TEMP_SENSOR_GAIN; tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ].refResistance = COND_SENSORS_TEMP_SENSOR_REF_RESISTANCE; tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ].zeroDegreeResistance = COND_SENSORS_TEMP_SENSOR_0_DEGREE_RESISTANCE; + tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ].gain = COND_SENSORS_TEMP_SENSOR_GAIN; tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ].refResistance = COND_SENSORS_TEMP_SENSOR_REF_RESISTANCE; tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ].zeroDegreeResistance = COND_SENSORS_TEMP_SENSOR_0_DEGREE_RESISTANCE; + tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // Initialize TRo and TDi constants tempSensors[ TEMPSENSORS_OUTLET_REDUNDANT ].gain = TRIMMER_HEATER_EXT_TEMP_SENSORS_GAIN; tempSensors[ TEMPSENSORS_OUTLET_REDUNDANT ].refResistance = TRIMMER_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ TEMPSENSORS_OUTLET_REDUNDANT ].zeroDegreeResistance = TRIMMER_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; + tempSensors[ TEMPSENSORS_OUTLET_REDUNDANT ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ TEMPSENSORS_INLET_DIALYSATE ].gain = TRIMMER_HEATER_EXT_TEMP_SENSORS_GAIN; tempSensors[ TEMPSENSORS_INLET_DIALYSATE ].refResistance = TRIMMER_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ TEMPSENSORS_INLET_DIALYSATE ].zeroDegreeResistance = TRIMMER_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; + tempSensors[ TEMPSENSORS_INLET_DIALYSATE ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // Initialize the heaters internal thermocouples constants tempSensors[ TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ].conversionCoeff = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; @@ -237,62 +241,75 @@ // FPGA board temperature conversion coefficient tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].conversionCoeff = 503.975 / (F32)TWELVE_BIT_RESOLUTION; + tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].maxAllowedTemperature = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; F32 const conversionCoeff = 1.0 / 13584.0; - // Board temperature sensors conversion coefficient - tempSensors[ TEMPSENSORS_LOAD_CELL_A1_B1 ].conversionCoeff = conversionCoeff; - tempSensors[ TEMPSENSORS_LOAD_CELL_A2_B2 ].conversionCoeff = conversionCoeff; - tempSensors[ TEMPSENSORS_INTERNAL_THDO_RTD ].conversionCoeff = conversionCoeff; - tempSensors[ TEMPSENSORS_INTERNAL_TDI_RTD ].conversionCoeff = conversionCoeff; - tempSensors[ TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR ].conversionCoeff = conversionCoeff; + tempSensors[ TEMPSENSORS_LOAD_CELL_A1_B1 ].conversionCoeff = conversionCoeff; + tempSensors[ TEMPSENSORS_LOAD_CELL_A1_B1 ].maxAllowedTemperature = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; + tempSensors[ TEMPSENSORS_LOAD_CELL_A2_B2 ].conversionCoeff = conversionCoeff; + tempSensors[ TEMPSENSORS_LOAD_CELL_A2_B2 ].maxAllowedTemperature = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; + + tempSensors[ TEMPSENSORS_INTERNAL_THDO_RTD ].conversionCoeff = conversionCoeff; + tempSensors[ TEMPSENSORS_INTERNAL_THDO_RTD ].maxAllowedTemperature = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; + + tempSensors[ TEMPSENSORS_INTERNAL_TDI_RTD ].conversionCoeff = conversionCoeff; + tempSensors[ TEMPSENSORS_INTERNAL_TDI_RTD ].maxAllowedTemperature = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; + + tempSensors[ TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR ].conversionCoeff = conversionCoeff; + tempSensors[ TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR ].maxAllowedTemperature = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; + // Persistent alarms for inlet water high/low temperature - initPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_TEMPERATURE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_INLET_WATER_LOW_TEMPERATURE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_TEMPERATURE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, + INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); - // Persistent alarm for temperature sensors internal error + initPersistentAlarm( ALARM_ID_INLET_WATER_LOW_TEMPERATURE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, + INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + + // Persistent alarm for the temperature sensors range check + initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE, TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS, + TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ); + + // Persistent alarm for the temperature sensors range check + initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ADC_OUT_OF_RANGE, TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS, + TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ); + + // Persistent alarm for the temperature sensors error bit fault check + initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS, + TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ); + + // Persistent alarm for temperature sensors ADC error // When the FPGA read count does not increment for a period of time, it is considered as an internal error of the temperature sensors // driver. This is internal because FPGA does not error out if the FPGA read count does not increment. - initPersistentAlarm( ALARM_ID_TEMPERATURE_SENSORS_FAULT, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD, + TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); } /*********************************************************************//** * @brief * The execTemperatureSensorsSelfTest function runs the TemperatureSensors * POST during the self-test. - * @details Inputs: tempSensorsSelfTestState - * @details Outputs: tempSensorsSelfTestState + * @details Inputs: none + * @details Outputs: none * @return tempSensorsSelfTestState which is the status of the self test *************************************************************************/ SELF_TEST_STATUS_T execTemperatureSensorsSelfTest( void ) { - switch ( tempSensorsSelfTestState ) - { - case TEMPSENSORS_SELF_TEST_START: - tempSensorsSelfTestState = handleSelfTestStart(); - break; + SELF_TEST_STATUS_T status = SELF_TEST_STATUS_IN_PROGRESS; - case TEMPSENSORS_SELF_TEST_ADC_CHECK: - tempSensorsSelfTestState = handleSelfTestADCCheck(); - break; + // TODO implement the calibration processing function. + // It returns a pass for now - case TEMPSENSORS_SELF_TEST_COMPLETE: - // Done with self-test, do nothing - break; + status = SELF_TEST_STATUS_PASSED; - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSORS_INVALID_SELF_TEST_STATE, tempSensorsSelfTestState ); - tempSensorsSelfTestState = TEMPSENSORS_SELF_TEST_COMPLETE; - break; - } - - return tempSensorsSelfTestResult; + return status; } /*********************************************************************//** * @brief - * The execTemperatureSensors function executes the temperature sensors' state machine. + * The execTemperatureSensors function executes the temperature sensors' + * state machine. * @details Inputs: tempSensorsExecState * @details Outputs: tempSensorsExecState * @return none @@ -302,7 +319,7 @@ // Read the sensors all the time switch ( tempSensorsExecState ) { - case TEMPSENSORS_SELF_TEST_START: + case TEMPSENSORS_EXEC_STATE_START: tempSensorsExecState = handleExecStart(); break; @@ -361,7 +378,20 @@ } else { +#ifdef THD_USING_TRO_CONNECTOR + // In V3 THd is connected to TRo + // In V3 TDi represents TRo since they are very close to each other + if ( TEMPSENSORS_HEAT_DISINFECT == sensorIndex ) + { + temperature = tempSensors[ TEMPSENSORS_OUTLET_REDUNDANT ].temperatureValues.data; + } + else + { + temperature = tempSensors[ sensorIndex ].temperatureValues.data; + } +#else temperature = tempSensors[ sensorIndex ].temperatureValues.data; +#endif } } else @@ -492,8 +522,49 @@ { S32 convertedADC = (S32)( adc & MASK_OFF_U32_MSB ); - if ( TRUE == isADCReadValid( sensorIndex, fpgaError, fpgaCount ) ) + // All the sensors have ADC read and count values that have to be checked + BOOL isADCValid = isADCReadValid( sensorIndex, fpgaError, fpgaCount ); + + // Some of the temperature sensors have an MSB bit that is used as an + // error flag. This flag will be a TRUE by default. + BOOL isTemperatureNotValid = FALSE; + + switch( sensorIndex ) { + case TEMPSENSORS_LOAD_CELL_A1_B1: // 267 + case TEMPSENSORS_LOAD_CELL_A2_B2: // 279 + case TEMPSENSORS_CONDUCTIVITY_SENSOR_1: // 283 + case TEMPSENSORS_CONDUCTIVITY_SENSOR_2: // 287 + case TEMPSENSORS_OUTLET_PRIMARY_HEATER: // 291 + case TEMPSENSORS_INLET_PRIMARY_HEATER: // 295 + case TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR: // 299 + case TEMPSENSORS_OUTLET_REDUNDANT: // 303 + case TEMPSENSORS_INTERNAL_THDO_RTD: // 307 + case TEMPSENSORS_INLET_DIALYSATE: // 311 + case TEMPSENSORS_INTERNAL_TDI_RTD: // 315 + { + // The MSB bit of the last byte is the error flag, so that MSB + // is shifted 31 bits to the first bit of the U32 variable. + // If that bit is a 1, there is either CRC error or Status error + // that are ored on top of each other + U32 errorBit = adc >> 31; + isTemperatureNotValid = errorBit > 0; + checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, isTemperatureNotValid, sensorIndex, + TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ); + } + break; + + default: + // Do nothing. FPGA board temperature sensor does not have error flag bit + // If a wrong temperature sensor name is picked, the function that converts + // ADC counts to temperature raises an alarm. + break; + } + + // To update the moving average of a temperature sensor, both ADC and internal + // error flags must be valid + if ( ( TRUE == isADCValid ) && ( FALSE == isTemperatureNotValid ) ) + { processADCRead( sensorIndex, convertedADC ); } } @@ -556,9 +627,9 @@ } } - BOOL isThereAnError = !isFPGACountChanging || !isFPGAErrorZero; + BOOL isThereAnError = ( FALSE == isFPGACountChanging ) || ( FALSE == isFPGAErrorZero ); - checkPersistentAlarm( ALARM_ID_TEMPERATURE_SENSORS_FAULT, isThereAnError, sensorIndex, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); + checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, isThereAnError, sensorIndex, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); return isADCValid; } @@ -588,6 +659,13 @@ // Calculate the average F32 const avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_2_FOR_AVERAGING; + // Check if the ADC value of the sensor is not out of range + if ( ( (U32)avgADCReads < TEMP_SESNORS_MIN_ALLOWED_ADC_COUNT ) || ( (U32)avgADCReads > TEMP_SENSORS_MAX_ALLOWED_ADC_COUNT ) ) + { + // TODO investigate why the new count check is out of range + //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ADC_OUT_OF_RANGE, TRUE, sensorIndex, avgADCReads ); + } + // Different sensors have different ADC to temperature conversion methods switch( sensorIndex ) { @@ -632,51 +710,13 @@ // Update the temperature tempSensors[ sensorIndex ].temperatureValues.data = temperature; -} -/*********************************************************************//** - * @brief - * The handleSelfTestStart function transitions the self-test state to - * check ADC. - * @details Inputs: tempSensorsSelfTestResult - * @details Outputs: none - * @return the next state of state machine - *************************************************************************/ -static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestStart( void ) -{ - tempSensorsSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; - return TEMPSENSORS_SELF_TEST_ADC_CHECK; + // Monitor the temperature value + monitorTemperatureSnsrs( sensorIndex, temperature ); } /*********************************************************************//** * @brief - * The handleSelfTestADCCheck function checks whether the ADC reads. If the - * reads are above the maximum 24bit ADC count, it will throw an alarm and - * switches to the next state. - * @details Inputs: tempSensorsSelfTestResult - * @details Outputs: tempSensorsSelfTestResult - * @return the next state of the state machine - *************************************************************************/ -static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestADCCheck( void ) -{ - tempSensorsSelfTestResult = SELF_TEST_STATUS_PASSED; - - S32 const tpiADC = (S32)getFPGATPiTemp(); - - BOOL const isLessThanZero = tpiADC <= 0; - BOOL const isGreaterThanFullScale = tpiADC >= TEMP_SENSORS_ADC_MAX_COUNT; - - if ( ( TRUE == isLessThanZero ) || ( TRUE == isGreaterThanFullScale ) ) - { - tempSensorsSelfTestResult = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TEMPERATURE_SENSORS_FAULT, TEMPSENSORS_SELF_TEST_ADC_CHECK ); - } - - return TEMPSENSORS_SELF_TEST_COMPLETE; -} - -/*********************************************************************//** - * @brief * The handleExecStart function waits for a period of time and switches to * the state that reads the ADC values from FPGA. * @details Inputs: elapsedTime @@ -687,7 +727,7 @@ { TEMPSENSORS_EXEC_STATES_T state = TEMPSENSORS_EXEC_STATE_START; - if ( elapsedTime == 0 ) + if ( 0 == elapsedTime ) { elapsedTime = getMSTimerCount(); } @@ -712,37 +752,62 @@ *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ) { + U32 rawADC = 0; + U32 errorCount = 0; + U32 readCount = 0; + // Look at the error counter and the specific error flag to make sure the error is a temperature sensor // Add a byte array to have bits for each sensor to find out exactly what sensor failed if ( ++fpgaRawADCReadInterval >= FPGA_RAW_ADC_READ_INTERVAL_COUNT ) { - processTempSnsrsADCRead( TEMPSENSORS_INLET_PRIMARY_HEATER, getFPGATPiTemp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_OUTLET_PRIMARY_HEATER, getFPGATPoTemp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_1, getFPGACD1Temp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2, getFPGACD2Temp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_OUTLET_REDUNDANT, getFPGATHDoTemp(), getFPGATHDoErrorCount(), getFPGATHDoReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_INLET_DIALYSATE, getFPGATDiTemp(), getFPGATDiErrorCount(), getFPGATDiReadCount() ); + rawADC = getFPGATPiTemp(); + errorCount = (U32)getFPGARTDErrorCount(); + readCount = (U32)getFPGARTDReadCount(); + processTempSnsrsADCRead( TEMPSENSORS_INLET_PRIMARY_HEATER, rawADC, errorCount, readCount ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, getFPGAPrimaryHeaterTemp(), getFPGAPrimaryHeaterFlags(), - getFPGAPrimaryHeaterReadCount() ); + rawADC = getFPGATPoTemp(); + processTempSnsrsADCRead( TEMPSENSORS_OUTLET_PRIMARY_HEATER, rawADC, errorCount, readCount ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, getFPGATrimmerHeaterTemp(), getFPGATrimmerHeaterFlags(), - getFPGATrimmerHeaterReadCount() ); + rawADC = getFPGACD1Temp(); + processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_1, rawADC, errorCount, readCount ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION, getFPGAPrimaryColdJunctionTemp(), getFPGATrimmerHeaterFlags(), - getFPGAPrimaryHeaterReadCount() ); + rawADC = getFPGACD2Temp(); + processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2, rawADC, errorCount, readCount ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION, getFPGATrimmerColdJunctionTemp(), getFPGATrimmerHeaterFlags(), - getFPGATrimmerHeaterReadCount() ); + rawADC = getFPGATRoTemp(); + errorCount = (U32)getFPGATRoErrorCount(); + readCount = (U32)getFPGATRoReadCount(); + processTempSnsrsADCRead( TEMPSENSORS_OUTLET_REDUNDANT, rawADC, errorCount, readCount ); + rawADC = getFPGATDiTemp(); + errorCount = (U32)getFPGATDiErrorCount(); + readCount = (U32)getFPGATDiReadCount(); + processTempSnsrsADCRead( TEMPSENSORS_INLET_DIALYSATE, rawADC, errorCount, readCount ); + + rawADC = getFPGAPrimaryHeaterTemp(); + errorCount = (U32)getFPGAPrimaryHeaterFlags(); + readCount = (U32)getFPGAPrimaryHeaterReadCount(); + processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, rawADC, errorCount, readCount ); + + rawADC = getFPGAPrimaryColdJunctionTemp(); + processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION, rawADC, errorCount, readCount ); + + rawADC = getFPGATrimmerHeaterTemp(); + errorCount = (U32)getFPGATrimmerHeaterFlags(); + readCount = (U32)getFPGATrimmerHeaterReadCount(); + processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, rawADC, errorCount, readCount ); + + rawADC = getFPGATrimmerColdJunctionTemp(); + processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION, rawADC, errorCount, readCount ); + // NOTE: FPGA board temperature sensor is different from the rest of the sensors. This sensor does not have FPGA count and error // coming from FPGA. It is kept here to do moving average on the values. The supporting functions need to see the FPGA read count // incrementing internally so there will not be any errors. U32 simulatedCounter = tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].readCount; processTempSnsrsADCRead( TEMPSENSORS_FPGA_BOARD_SENSOR, getFPGABoardTemp(), 0, ++simulatedCounter ); processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A1_B1, getFPGALoadCellsA1B1Temp(), getFPGAADC1ErrorCount(), getFPGAADC1ReadCount() ); processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A2_B2, getFPGALoadCellsA2B2Temp(), getFPGAADC2ErrorCount(), getFPGAADC2ReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THDO_RTD, getFPGATHDoInternalTemp(), getFPGATHDoErrorCount(), getFPGATHDoReadCount() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THDO_RTD, getFPGATRoInternalTemp(), getFPGATRoErrorCount(), getFPGATRoReadCount() ); processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_TDI_RTD, getFPGATDiInternalTemp(), getFPGATDiErrorCount(), getFPGATDiReadCount() ); processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); @@ -762,26 +827,6 @@ /*********************************************************************//** * @brief - * The getPublishTemperatureSensorsDataInterval function returns the data - * publication interval either from the data or from the override. - * @details Inputs: tempSensorsPublishInterval - * @details Outputs: none - * @return data publish interval - *************************************************************************/ -static U32 getPublishTemperatureSensorsDataInterval( void ) -{ - U32 result = tempSensorsPublishInterval.data; - - if ( tempSensorsPublishInterval.override == OVERRIDE_KEY ) - { - result = tempSensorsPublishInterval.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief * The publishTemperatureSensorsData function broadcasts the temperature * sensors data at the publication interval. * @details Inputs: dataPublicationTimerCounter, tempValuesForPublication @@ -790,32 +835,32 @@ *************************************************************************/ static void publishTemperatureSensorsData( void ) { - if ( ++dataPublicationTimerCounter >= getPublishTemperatureSensorsDataInterval() ) + if ( ++dataPublicationTimerCounter >= getU32OverrideValue( &tempSensorsPublishInterval ) ) { TEMPERATURE_SENSORS_DATA_T data; - data.inletPrimaryHeater = getTemperatureValue ( TEMPSENSORS_INLET_PRIMARY_HEATER ); - data.outletPrimaryHeater = getTemperatureValue ( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - data.conductivitySensor1 = getTemperatureValue ( TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ); - data.conductivitySensor2 = getTemperatureValue ( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); - data.outletRedundant = getTemperatureValue ( TEMPSENSORS_OUTLET_REDUNDANT ); - data.inletDialysate = getTemperatureValue ( TEMPSENSORS_INLET_DIALYSATE ); - data.primaryHeaterThermocouple = getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ); - data.trimmerHeaterThermocouple = getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ); - data.priamyHeaterColdjunction = getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ); - data.trimmerHeaterColdjunction = getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ); - data.primaryHeaterInternal = getTemperatureValue ( TEMPSENSORS_PRIMARY_HEATER_INTERNAL ); - data.trimmerHeaterInternal = getTemperatureValue ( TEMPSENSORS_TRIMMER_HEATER_INTERNAL ); - data.fpgaBoard = getTemperatureValue ( TEMPSENSORS_FPGA_BOARD_SENSOR ); - data.loadCellA1B1 = getTemperatureValue ( TEMPSENSORS_LOAD_CELL_A1_B1 ); - data.loadCellA2B2 = getTemperatureValue ( TEMPSENSORS_LOAD_CELL_A2_B2 ); - data.internalTHDORTD = getTemperatureValue ( TEMPSENSORS_INTERNAL_THDO_RTD ); - data.internalTDIRTD = getTemperatureValue ( TEMPSENSORS_INTERNAL_TDI_RTD ); - data.internalCondSnsrTemp = getTemperatureValue ( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR ); - data.primaryThermoCoupleRaw = tempSensors[ TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; - data.primaryColdjuncRaw = tempSensors[ TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; - data.trimmerThermoCoupleRaw = tempSensors[ TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; - data.trimmerColdjuncRaw = tempSensors[ TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; + data.inletPrimaryHeater = getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ); + data.outletPrimaryHeater = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + data.conductivitySensor1 = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ); + data.conductivitySensor2 = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); + data.outletRedundant = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); + data.inletDialysate = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); + data.primaryHeaterThermocouple = getTemperatureValue( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ); + data.trimmerHeaterThermocouple = getTemperatureValue( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ); + data.priamyHeaterColdjunction = getTemperatureValue( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ); + data.trimmerHeaterColdjunction = getTemperatureValue( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ); + data.primaryHeaterInternal = getTemperatureValue( TEMPSENSORS_PRIMARY_HEATER_INTERNAL ); + data.trimmerHeaterInternal = getTemperatureValue( TEMPSENSORS_TRIMMER_HEATER_INTERNAL ); + data.fpgaBoard = getTemperatureValue( TEMPSENSORS_FPGA_BOARD_SENSOR ); + data.loadCellA1B1 = getTemperatureValue( TEMPSENSORS_LOAD_CELL_A1_B1 ); + data.loadCellA2B2 = getTemperatureValue( TEMPSENSORS_LOAD_CELL_A2_B2 ); + data.internalTHDORTD = getTemperatureValue( TEMPSENSORS_INTERNAL_THDO_RTD ); + data.internalTDIRTD = getTemperatureValue( TEMPSENSORS_INTERNAL_TDI_RTD ); + data.internalCondSnsrTemp = getTemperatureValue( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR ); + data.primaryThermoCoupleRaw = getFPGAPrimaryHeaterTemp(); + data.primaryColdjuncRaw = getFPGAPrimaryColdJunctionTemp(); + data.trimmerThermoCoupleRaw = getFPGATrimmerHeaterTemp(); + data.trimmerColdjuncRaw = getFPGATrimmerColdJunctionTemp(); data.cond1Raw = tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; data.cond2Raw = tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; @@ -825,7 +870,32 @@ } } +/*********************************************************************//** + * @brief + * The monitorTemperatureSnsrs function monitors the temperature sensors' + * temperature value and raises an alarm if any of them are out of range + * for more than the specified time. + * @details Inputs: tempSensors + * @details Outputs: tempSensors + * @param sensorIndex the index of the temperature sensor + * @param temperature the temperature value to be checked + * @return none + *************************************************************************/ +static void monitorTemperatureSnsrs( U32 sensorIndex, F32 temperature ) +{ + // The maximum allowed temperature is different for the sensors that are in the fluid path + // with the ones that are not in the fluid path + F32 maxLimit = tempSensors[ sensorIndex ].maxAllowedTemperature; + // Check both temperature and to be in range + if ( ( temperature < TEMP_SENSORS_MIN_ALLOWED_DEGREE_C ) || ( temperature > maxLimit ) ) + { + // TODO investigate + //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE, TRUE, sensorIndex, temperature ); + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -860,8 +930,8 @@ /*********************************************************************//** * @brief - * The testSetMeasuredTemperatureOverride function resets the override value - * of a specified temperature sensor. + * The testSetMeasuredTemperatureOverride function resets the override + * value of a specified temperature sensor. * @details Inputs: tempSensors * @details Outputs: tempSensors * @param sensorIndex temperature sensor index