Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r41c7186ac17200977b632102c9c6e3a07b3eb211 -r2e4afce5a9fd0392b330461ed38322ecadd59aa1 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 41c7186ac17200977b632102c9c6e3a07b3eb211) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 2e4afce5a9fd0392b330461ed38322ecadd59aa1) @@ -45,18 +45,13 @@ #define TRIMMER_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE 100U ///< Trimmer heater external temperature sensors zero degree resistance. #define TEMP_SENSORS_ADC_BITS 24U ///< External temperature sensors ADC bits. -#define TEMP_SENSORS_ADC_MAX_COUNT ( pow(2,TEMP_SENSORS_ADC_BITS) - 1 ) ///< Temperature sensors max ADC count. -#define TEMP_EQUATION_COEFF_A ( 3.9083 * pow( 10, -3 ) ) ///< ADC to temperature conversion coefficient A. -#define TEMP_EQUATION_COEFF_B ( -5.775 * pow( 10, -7 ) ) ///< ADC to temperature conversion coefficient B. - #define ADC_FPGA_READ_DELAY 30U ///< Delay in ms before reading the ADC values from FPGA. -#define MAX_NUM_OF_RAW_ADC_SAMPLES 32U ///< Number of ADC reads for moving average calculations. +#define MAX_NUM_OF_RAW_ADC_SAMPLES 4U ///< Number of ADC reads for moving average calculations. #define MAX_ALLOWED_TEMP_DELTA_BETWEEN_SENSORS 2U ///< Maximum allowed temperature delta between sensors. -#define MAX_ALLOWED_UNCHANGED_ADC_READS 4U ///< Maximum number of times that the read of a sensor cannot change. -#define SHIFT_BITS_BY_2 2U ///< Shift bits by 2. -#define SHIFT_BITS_BY_5_FOR_AVERAGING 5U ///< Shift the ADCs of the temperature sensors by 5 to average them. -#define INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for temperature sensors out of range error. +#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 MIN_WATER_INPUT_TEMPERATURE 10U ///< Minimum water input temperature. #define MAX_WATER_INPUT_TEMPERATURE 35U ///< Maximum water input temperature. @@ -68,19 +63,25 @@ #define K_THERMOCOUPLE_TEMP_2_MILLI_VOLT_CONVERSION_COEFF 0.041276 ///< K thermocouple temperature to millivolt conversion coefficient. #define SIZE_OF_THERMOCOUPLE_COEFFICIENTS 10U ///< Size of the thermocouple coefficients. +#define CELSIUS_TO_KELVIN_CONVERSION 273.15 ///< Celsius to Kelvin temperature conversion. +#define ADC_BOARD_TEMP_SENSORS_CONVERSION_CONST 272.5 ///< ADC board temperature sensors conversion constant. +#define TWELVE_BIT_RESOLUTION 4096U ///< 12 bit resolution conversion. +#define ADC_BOARD_TEMP_SENSORS_CONST 0x800000 ///< ADC board temperature sensors constant. + #define EXTERNAL_TEMP_SENSORS_ERROR_VALUE 0x80 ///< External temperature sensors error value. #define HEATERS_INTERNAL_TEMP_SENSOR_FAULT 0x01 ///< Heaters internal temperature sensor fault. #define TEMP_SENSORS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Temperature sensors publish data time interval. -#define MAX_TEMPERATURE_SENSOR_FAILURES 10 ///< Maximum number of temperature sensor errors within window period before alarm. -#define MAX_TEMPERATURE_SENSOR_FAILURE_WINDOW_MS ( 10 * MS_PER_SECOND ) ///< Temperature sensor error window. +#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. + /// 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_CONSISTENCY_CHECK, ///< Temperature sensors self-test consistency 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; @@ -98,60 +99,66 @@ { F32 gain; ///< ADC gain F32 refResistance; ///< ADC reference resistance - F32 conversionCoef; ///< ADC conversion coefficient + F32 conversionCoeff; ///< ADC conversion coefficient F32 zeroDegreeResistance; ///< ADC zero degree resistance - S32 rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES ]; ///< Raw ADC reads array S32 adcNextIndex; ///< Next ADC read index S32 adcRunningSum; ///< ADC running sum - U32 readCount; ///< Read counts from FPGA - U32 internalErrorCount; ///< Internal error counts - OVERRIDE_F32_T temperatureValues; ///< Temperature values with override } TEMP_SENSOR_T; // ********** private data ********** -static SELF_TEST_STATUS_T tempSensorsSelfTestResult; ///< Self-test result of the TemperatureSensors module. +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. +static U32 elapsedTime = 0; ///< Elapsed time variable. +static U32 internalHeatersConversionTimer = 0; ///< Conversion timer variable to calculate the heaters internal temperature. -static U32 elapsedTime; ///< Elapsed time variable. -static U32 internalHeatersConversionTimer; ///< Conversion timer variable to calculate the heaters internal temperature. - static F32 tempValuesForPublication [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors data publication array. static U32 dataPublicationTimerCounter; ///< Temperature sensors data publish timer counter. static OVERRIDE_U32_T tempSensorsPublishInterval = { TEMP_SENSORS_DATA_PUBLISH_INTERVAL, TEMP_SENSORS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Temperature sensors publish time interval override. -static const F32 positiveTCExpA0 = 0.118597600000E0; ///< K TC positive temperature exponent coefficient A0. -static const F32 positiveTCExpA1 = -0.118343200000E-3; ///< K TC positive temperature exponent coefficient A1. -static const F32 positiveTCExpA2 = 0.126968600000E3; ///< K TC positive temperature exponent coefficient A2. +static const F32 POSITIVE_TC_EXP_A0 = 0.118597600000E0; ///< K TC positive temperature exponent coefficient A0. +static const F32 POSITIVE_TC_EXP_A1 = -0.118343200000E-3; ///< K TC positive temperature exponent coefficient A1. +static const F32 POSITIVE_TC_EXP_A2 = 0.126968600000E3; ///< K TC positive temperature exponent coefficient A2. -///< Thermocouple correction coefficients for positive cold junction temperature. -static const F32 positiveTCCoeffs [ SIZE_OF_THERMOCOUPLE_COEFFICIENTS ] = +static const F32 POSITIVE_TC_COEFFS [ SIZE_OF_THERMOCOUPLE_COEFFICIENTS ] = { -0.176004136860E-1, 0.389212049750E-1, 0.185587700320E-4, -0.994575928740E-7, 0.318409457190E-9, -0.560728448890E-12, 0.560750590590E-15,-0.320207200030E-18, 0.971511471520E-22,-0.121047212750E-25 -}; +}; ///< Thermocouple correction coefficients for positive cold junction temperature. -///< Thermcouple inverse coefficient for positive cold junction temperature. -static const F32 positiveTCInverserCoeffs [ SIZE_OF_THERMOCOUPLE_COEFFICIENTS ] = +static const F32 POSITIVE_TC_INVERSER_COEFFS [ SIZE_OF_THERMOCOUPLE_COEFFICIENTS ] = { 0.0, 2.508355E1, 7.860106E-2, -2.503131E-1, 8.315270E-2, -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. + +/// Max FPGA error count limit. +static const F32 MAX_FPGA_ERROR_COUNT_LIMIT = TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD / + ( FPGA_RAW_ADC_READ_INTERVAL_COUNT * TASK_PRIORITY_INTERVAL ); + +/// Max internal error count limit. +static const F32 MAX_INTERNAL_ERROR_COUNT_LIMIT = TEMPERATURE_SENSORS_INTERNAL_ERROR_PERSISTENT_PERIOD / + ( FPGA_RAW_ADC_READ_INTERVAL_COUNT * TASK_PRIORITY_INTERVAL ); + // ********** private function prototypes ********** static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestStart( void ); static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestADCCheck( void ); -static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestConsistencyCheck( void ); static TEMPSENSORS_EXEC_STATES_T handleExecStart( void ); static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ); @@ -168,19 +175,27 @@ /*********************************************************************//** * @brief - * The initTemperatureSensors function initializes the module - * @details Inputs: none - * @details Outputs: TemperatureSensors module initialized + * The initTemperatureSensors function initializes the module. + * @details Inputs: tempSensorsSelfTestState, tempSensorsExecState, + * elapsedTime, internalHeatersConversionTimer, dataPublicationTimerCounter, + * tempSensors, fpgaRawADCReadInterval + * @details Outputs: tempSensorsSelfTestState, tempSensorsExecState, + * elapsedTime, internalHeatersConversionTimer, dataPublicationTimerCounter, + * tempSensors, fpgaRawADCReadInterval * @return none *************************************************************************/ void initTemperatureSensors( void ) { 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; /* NOTE: The temperature sensors do not have conversion coefficient. * The conversion coefficients are used for the heaters internal temperature sensors and @@ -196,50 +211,68 @@ } // Initialize TPi and TPo constants - 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 ].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_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 ].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; // 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 ].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_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 ].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; // Initialize TRo and TDi constants - tempSensors[ TEMPSENSORS_OUTLET_REDUNDANCY ].gain = TRIMMER_HEATER_EXT_TEMP_SENSORS_GAIN; - tempSensors[ TEMPSENSORS_OUTLET_REDUNDANCY ].refResistance = TRIMMER_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; - tempSensors[ TEMPSENSORS_OUTLET_REDUNDANCY ].zeroDegreeResistance = TRIMMER_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; + 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_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 ].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; // Initialize the heaters internal thermocouples constants - tempSensors[ TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ].conversionCoef = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; - tempSensors[ TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ].conversionCoef = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ].conversionCoeff = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ].conversionCoeff = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; // Initialize the heaters cold junction constants - tempSensors[ TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ].conversionCoef = HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF; - tempSensors[ TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ].conversionCoef = HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ].conversionCoeff = HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ].conversionCoeff = HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF; - // Initialize the heaters calculated internal temperature sensors. The constants are zero since they will not be used for conversion + // FPGA board temperature conversion coefficient + tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].conversionCoeff = 503.975 / (F32)TWELVE_BIT_RESOLUTION; - // Windowed time count for FPGA temperature sensor error - initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_TEMPERATURE_SENSOR_ERROR, MAX_TEMPERATURE_SENSOR_FAILURES, MAX_TEMPERATURE_SENSOR_FAILURE_WINDOW_MS ); + 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; + // Persistent alarms for inlet water high/low temperature initPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_HIGH_TEMPERATURE, ALARM_ID_INLET_WATER_HIGH_TEMPERATURE, - FALSE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + TRUE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); initPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_LOW_TEMPERATURE, ALARM_ID_INLET_WATER_LOW_TEMPERATURE, - FALSE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + TRUE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + + // Persistent alarm for temperature sensors internal 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( PERSISTENT_ALARM_TEMP_SENSORS_INTERNAL_ERROR, ALARM_ID_TEMPERATURE_SENSORS_FAULT, + TRUE, TEMPERATURE_SENSORS_INTERNAL_ERROR_PERSISTENT_PERIOD, TEMPERATURE_SENSORS_INTERNAL_ERROR_PERSISTENT_PERIOD ); + + // Persistent alarm for temperature sensors FPGA error + // This is FPGA error which is read from FPGA and it should be 0. If it is not 0 for a period of time, an alarm is raised. + initPersistentAlarm( PERSISTENT_ALARM_TEMP_SENSORS_FPGA_ERROR, ALARM_ID_TEMPERATURE_SENSORS_FAULT, TRUE, + TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); } /*********************************************************************//** @@ -248,7 +281,7 @@ * POST during the self-test. * @details Inputs: tempSensorsSelfTestState * @details Outputs: tempSensorsSelfTestState - * @return tempSensorsSelfTestState + * @return tempSensorsSelfTestState which is the status of the self test *************************************************************************/ SELF_TEST_STATUS_T execTemperatureSensorsSelfTest( void ) { @@ -262,16 +295,13 @@ tempSensorsSelfTestState = handleSelfTestADCCheck(); break; - case TEMPSENSORS_SELF_TEST_CONSISTENCY_CHECK: - tempSensorsSelfTestState = handleSelfTestConsistencyCheck(); - break; - case TEMPSENSORS_SELF_TEST_COMPLETE: // Done with self-test, do nothing break; default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSORS_INVALID_SELF_TEST_STATE, tempSensorsSelfTestState ); + 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; } @@ -304,14 +334,17 @@ tempSensorsExecState = TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; break; } + + // Publish the data + publishTemperatureSensorsData(); } /*********************************************************************//** * @brief * The checkInletWaterTemperature checks inlet water temperature value * and triggers an alarm when temperature value is out of allowed range. - * @details Inputs: Inlet water temperature value - * @details Outputs: Trigger alarms when temperature is out of allowed range + * @details Inputs: none + * @details Outputs: none * @return none *************************************************************************/ void checkInletWaterTemperature( void ) @@ -320,17 +353,18 @@ BOOL const isWaterTempTooHigh = temperature > MAX_WATER_INPUT_TEMPERATURE; BOOL const isWaterTempTooLow = temperature < MIN_WATER_INPUT_TEMPERATURE; - checkPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_HIGH_TEMPERATURE, isWaterTempTooHigh, temperature ); - checkPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_LOW_TEMPERATURE, isWaterTempTooLow, temperature ); + checkPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_HIGH_TEMPERATURE, isWaterTempTooHigh, temperature, MAX_WATER_INPUT_TEMPERATURE ); + checkPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_LOW_TEMPERATURE, isWaterTempTooLow, temperature, MIN_WATER_INPUT_TEMPERATURE ); } /*********************************************************************//** * @brief - * The getTemperatureValue function gets the temperature of the requested sensor. - * @details Inputs: none + * The getTemperatureValue function gets the temperature of the requested + * sensor. + * @details Inputs: tempSensors * @details Outputs: none - * @param sensor temperature sensor index - * @return temperature + * @param sensorIndex which is the temperature sensor index + * @return temperature of the requested sensor *************************************************************************/ F32 getTemperatureValue( U32 sensorIndex ) { @@ -347,30 +381,36 @@ temperature = tempSensors[ sensorIndex ].temperatureValues.data; } } + else + { + // Wrong sensor was called, raise an alarm + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_TEMPERATURE_SENSOR_SELECTED, sensorIndex ); + } return temperature; } /*********************************************************************//** * @brief - * The getADC2TempConversion function calculates the temperature from ADC read from FPGA. - * @details Inputs: none + * The getADC2TempConversion function calculates the temperature from the + * moving average ADC samples. + * @details Inputs: tempEquationCoeffA, tempEquationCoeffB * @details Outputs: none - * @param avgADC Running average ADC + * @param avgADC moving average ADC * @param gain ADC gain * @param refResistance ADC reference resistance * @param zeroDegResistance ADC zero degree resistance * @param adcConversionCoeff ADC conversion coefficient - * @return temperature + * @return calculated temperature *************************************************************************/ static F32 getADC2TempConversion( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance, F32 adcConversionCoeff ) { - F32 temperature; + F32 temperature = 0.0; - if ( fabs( adcConversionCoeff ) < NEARLY_ZERO ) + if ( fabs( adcConversionCoeff ) <= NEARLY_ZERO ) { - // R(RTD) = R(ref) * ( adc – 2^N - 1 ) / ( G * 2^N - 1 ); - F32 resistance = ( refResistance * ( avgADC - pow( 2,(TEMP_SENSORS_ADC_BITS - 1 ) ) ) ) / ( gain * pow( 2, ( TEMP_SENSORS_ADC_BITS - 1 ) ) ); + // R(RTD) = R(ref) * ( adc – 2^(N - 1) ) / ( G * 2^(N - 1) ); + F32 resistance = ( refResistance * ( avgADC - TEMP_EQUATION_RESISTOR_CALC ) ) / ( gain * TEMP_EQUATION_RESISTOR_CALC ); // T = (-A + √( A^2 - 4B * ( 1 - R_T / R_0 ) ) ) / 2B F32 secondSqrtPart = 4 * TEMP_EQUATION_COEFF_B * (1 - ( resistance / zeroDegResistance ) ); temperature = ( -TEMP_EQUATION_COEFF_A + sqrt( pow( TEMP_EQUATION_COEFF_A, 2 ) - secondSqrtPart ) ) / ( 2 * TEMP_EQUATION_COEFF_B ); @@ -385,15 +425,28 @@ /*********************************************************************//** * @brief - * The getHeaterInternalTemp function calculates the heaters' internal temperature. - * @details Inputs: temperatureValues - * @details Outputs: temperatureValues + * The getHeaterInternalTemp function calculates the heaters' internal + * temperature. + * @details Inputs: tempSensors + * @details Outputs: tempSensors * @param TCIndex thermocouple index * @param CJIndex cold junction index * @return none *************************************************************************/ static void getHeaterInternalTemp( U32 TCIndex, U32 CJIndex ) { + /* voltage = 0.041276 * ( cold junction temp - thermo-couple temp ) + * E = Ci * T^i + a0 * exp( a1 * ( T - a2 ) ^ 2 ) + * i is the positive thermo-couple coefficients + * a0 is the positive thermo-couple coefficient + * a1 is the positive thermo-couple coefficient + * a2 is the positive thermo-couple coefficient + * E = voltage + E (E is the corrected voltage) + * Temperature = di * E^i + * d is positive inverse thermo-couple coefficient + * E is corrected voltage + */ + F32 temperature = 0.0; F32 equiVoltage = 0.0; F32 correctedVoltage = 0.0; @@ -409,24 +462,25 @@ { for ( i = 0; i < SIZE_OF_THERMOCOUPLE_COEFFICIENTS; i++ ) { - equiVoltage = equiVoltage + ( positiveTCCoeffs[ i ] * pow( CJTemp, i ) ); + equiVoltage = equiVoltage + ( POSITIVE_TC_COEFFS[ i ] * pow( CJTemp, i ) ); } - equiVoltage = equiVoltage + ( positiveTCExpA0 * ( exp( positiveTCExpA1 * pow( ( CJTemp - positiveTCExpA2 ), 2 ) ) ) ); + equiVoltage = equiVoltage + ( POSITIVE_TC_EXP_A0 * ( exp( POSITIVE_TC_EXP_A1 * pow( ( CJTemp - POSITIVE_TC_EXP_A2 ), 2 ) ) ) ); correctedVoltage = rawVoltage + equiVoltage; for ( i = 0; i < SIZE_OF_THERMOCOUPLE_COEFFICIENTS; i++ ) { - temperature = temperature + ( positiveTCInverserCoeffs[ i ] * pow( correctedVoltage, i ) ); + temperature = temperature + ( POSITIVE_TC_INVERSER_COEFFS[ i ] * pow( correctedVoltage, i ) ); } } else { - // TODO Alarm temperature = -1.0; + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_HEATERS_NEGATIVE_COLD_JUNCTION_TEMPERATURE, CJTemp ) } + // Check which heater's internal temperature is being calculated if ( TCIndex == TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ) { tempSensors[ TEMPSENSORS_PRIMARY_HEATER_INTERNAL ].temperatureValues.data = temperature; @@ -444,7 +498,7 @@ * to check if the read ADC is valid or not and if it is, it calls another * function to process the ADC value and covert it to temperature. * @details Inputs: none - * @details Outputs: Processed valid ADC reading + * @details Outputs: none * @param sensorIndex ID of temperature sensor to process * @param adc ADC value for the temperature sensor * @param fpgaError reported FPGA error status @@ -469,7 +523,7 @@ * check if the read ADC is valid and if it is, the function calls another function * process the ADC and convert it to temperature. * @details Inputs: none - * @details Outputs: Processed heater ADC reading + * @detailsOutputs: none * @param sensorIndex ID of temperature sensor to process * @param adc reported ADC value for temperature sensor * @param fpgaError reported error status by FPGA @@ -478,29 +532,29 @@ *************************************************************************/ static void processHtrsTempSnsrsADCRead( U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount ) { - U16 adcConv; - S16 convertedADC; + U16 adcConv = 0; + S16 convertedADC = 0; if ( ( sensorIndex == TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ) || ( sensorIndex == TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ) ) { - // Cast the adc from U32 to U16 and shit it to left by 2 + // Cast the adc from U32 to U16 and shift it to left by 2 adcConv = ( (U16)adc ) << SHIFT_BITS_BY_2; // Cast from U16 to S16 and shift the bits to right by 2 // so if the sign bit is 1, the sign bit is extended - convertedADC = ( (S16)adcConv ) >> SHIFT_BITS_BY_2; + convertedADC = ( (S32)adcConv ) >> SHIFT_BITS_BY_2; } - else if ( ( sensorIndex == TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ) || (sensorIndex == TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ) ) + else if ( ( sensorIndex == TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ) || ( sensorIndex == TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ) ) { // Cast the adc from U32 to U16 and shift it by 4 adcConv = ( (U16)adc ) << SHIFT_BITS_BY_4; // Cast from U16 to S16 and shift the bits to right by 4 // so if the sign bit is 1, the sign bit is extended - convertedADC = ( (S16)adcConv ) >> SHIFT_BITS_BY_4; + convertedADC = ( (S32)adcConv ) >> SHIFT_BITS_BY_4; } if ( isADCReadValid( sensorIndex, fpgaError, fpgaCount ) ) { - processADCRead( sensorIndex, convertedADC ); + processADCRead( sensorIndex, (S32)convertedADC ); } } @@ -510,47 +564,37 @@ * count. If there is any FPGA, it raises an alarm. If the count has changed * and the ADC value is not the same as the previous ADC read, it returns a * TRUE, signaling that the ADC is valid to be processed. - * @details Inputs: readCount - * @details Outputs: readCount, internalErrorCount + * @details Inputs: tempSensors + * @details Outputs: tempSensors * @param sensorIndex Temperature sensor index * @param fpgaError FPGA error count * @param fpgaCount FPGA read count - * @return isADCValid (BOOL) + * @return returns TRUE if ADC was valid otherwise FALSE *************************************************************************/ static BOOL isADCReadValid( U32 sensorIndex, U32 fpgaError, U32 fpgaCount ) { BOOL isADCValid = FALSE; #ifndef _VECTORCAST_ - // TODO remove these two lines. Temporary set to true until FPGA error count is fixed - isADCValid = TRUE; - fpgaError = 0; + isADCValid = TRUE; // TODO remove this line. Temporary set to true until FPGA error count is fixed + //THIS ISSUE HAS BEEN FIXED. TRY IT. #endif - if ( fpgaError == 0 ) + + // Check the status of FPGA error and FPGA count + BOOL isFPGAErrorZero = fpgaError == 0; + BOOL isFPGACountChanging = tempSensors[ sensorIndex ].readCount != fpgaCount; + + if ( isFPGAErrorZero ) { - if ( tempSensors[ sensorIndex ].readCount != fpgaCount ) + if ( isFPGACountChanging ) { - tempSensors[ sensorIndex ].readCount = fpgaCount; - tempSensors[ sensorIndex ].internalErrorCount = 0; + tempSensors[ sensorIndex ].readCount = fpgaCount; isADCValid = TRUE; } - else - { - ++tempSensors[ sensorIndex ].internalErrorCount; - if ( tempSensors[ sensorIndex ].internalErrorCount > MAX_ALLOWED_UNCHANGED_ADC_READS ) - { - // TODO: Add back alarm when temperature sensor read count is stable - // SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TEMPERATURE_SENSORS_FAULT, sensorIndex ); - } - } } - else - { - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_TEMPERATURE_SENSOR_ERROR ) ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TEMPERATURE_SENSORS_FAULT, sensorIndex ); - } - } + checkPersistentAlarm( PERSISTENT_ALARM_TEMP_SENSORS_INTERNAL_ERROR, !isFPGACountChanging, sensorIndex, MAX_INTERNAL_ERROR_COUNT_LIMIT ); + checkPersistentAlarm( PERSISTENT_ALARM_TEMP_SENSORS_FPGA_ERROR, !isFPGAErrorZero, sensorIndex, MAX_FPGA_ERROR_COUNT_LIMIT ); + return isADCValid; } @@ -559,39 +603,79 @@ * The processADCRead function receives the ADC value and the sensor * index and calculates the running sum and the moving average of the ADCs * The temperatureSensorsADCRead and tempSensorsAvgADCValues are updated. - * @details Inputs: adcNextIndex, rawADCReads, adcRunningSum - * @details Outputs: adcNextIndex, rawADCReads, adcRunningSum, temperatureValues + * @details Inputs: tempSensors + * @details Outputs: tempSensors * @param sensorIndex Temperature sensor index - * @param adc adc reading from fpga + * @param adc adc reading from FPGA * @return none *************************************************************************/ static void processADCRead( U32 sensorIndex, S32 adc ) { + F32 temperature; + U32 const index = tempSensors[ sensorIndex ].adcNextIndex; S32 const indexValue = tempSensors[ sensorIndex ].rawADCReads [ index ]; tempSensors[ sensorIndex ].rawADCReads[ index ] = adc; - tempSensors[ sensorIndex ].adcNextIndex = INC_WRAP( index, 0, MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ); - tempSensors[ sensorIndex ].adcRunningSum = tempSensors[ sensorIndex ].adcRunningSum - indexValue + adc; + tempSensors[ sensorIndex ].adcNextIndex = INC_WRAP( index, 0, MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ); + tempSensors[ sensorIndex ].adcRunningSum = tempSensors[ sensorIndex ].adcRunningSum - indexValue + adc; // Calculate the average - F32 const avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_5_FOR_AVERAGING; + F32 const avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_2_FOR_AVERAGING; - F32 const temperature = getADC2TempConversion( avgADCReads, - (U32)tempSensors [ sensorIndex ].gain, - (U32)tempSensors [ sensorIndex ].refResistance, - (U32)tempSensors [ sensorIndex ].zeroDegreeResistance, - tempSensors [ sensorIndex ].conversionCoef ); + // Different sensors have different ADC to temperature conversion methods + switch( sensorIndex ) + { + case TEMPSENSORS_INLET_PRIMARY_HEATER: + case TEMPSENSORS_OUTLET_PRIMARY_HEATER: + case TEMPSENSORS_CONDUCTIVITY_SENSOR_1: + case TEMPSENSORS_CONDUCTIVITY_SENSOR_2: + case TEMPSENSORS_OUTLET_REDUNDANT: + case TEMPSENSORS_INLET_DIALYSATE: + case TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE: + case TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE: + case TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION: + case TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION: + temperature = getADC2TempConversion( avgADCReads, (U32)tempSensors [ sensorIndex ].gain,(U32)tempSensors [ sensorIndex ].refResistance, + (U32)tempSensors [ sensorIndex ].zeroDegreeResistance, tempSensors [ sensorIndex ].conversionCoeff ); + break; + case TEMPSENSORS_FPGA_BOARD_SENSOR: + // Temperature(C) = ((ADC x 503.975) / 4096) - 273.15 + // The value of 503.975/4096 has been calculated and stored in the conversion coefficient variable of the structure + temperature = ( avgADCReads * tempSensors[ sensorIndex ].conversionCoeff ) - CELSIUS_TO_KELVIN_CONVERSION; + break; + + case TEMPSENSORS_LOAD_CELL_A1_B1: + case TEMPSENSORS_LOAD_CELL_A2_B2: + case TEMPSENSORS_INTERNAL_THDO_RTD: + case TEMPSENSORS_INTERNAL_TDI_RTD: + case TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR: + // Temperature(C) = ((ADC - 0x800000)/13584) - 272.5 + // The value 1/13584 has been calculated and stored in the conversion coefficient variable of the structure + temperature = ( ( avgADCReads - ADC_BOARD_TEMP_SENSORS_CONST ) * tempSensors[ sensorIndex ].conversionCoeff ) - + ADC_BOARD_TEMP_SENSORS_CONVERSION_CONST; + break; + + default: + // Wrong sensor was called, raise an alarm + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_TEMPERATURE_SENSOR_SELECTED, sensorIndex ); + // Wrong sensor, return temperature to be -1 + temperature = -1.0; + break; + } + + // Update the temperature tempSensors[ sensorIndex ].temperatureValues.data = temperature; } /*********************************************************************//** * @brief - * The handleSelfTestStart function transitions the self-test state to check ADC. + * The handleSelfTestStart function transitions the self-test state to + * check ADC. * @details Inputs: tempSensorsSelfTestResult * @details Outputs: none - * @return state (TEMPSENSORS_SELF_TEST_STATES_T) + * @return the next state of state machine *************************************************************************/ static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestStart( void ) { @@ -604,70 +688,35 @@ * 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: TPi ADC reading from FPGA - * @details Outputs: none - * @return TEMPSENSORS_SELF_TEST_CONSISTENCY_CHECK (TEMPSENSORS_SELF_TEST_STATES_T) + * @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 ( isLessThanZero || 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_CONSISTENCY_CHECK; -} - -/*********************************************************************//** - * @brief - * The handleSelfTestConsistencyCheck function checks the values of the - * sensors to make sure they are within the allowed range from each other. - * @details Inputs: TPi and TPo ADC reading from FPGA - * @details Outputs: none - * @return TEMPSENSORS_SELF_TEST_COMPLETE (TEMPSENSORS_SELF_TEST_STATES_T) - *************************************************************************/ -static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestConsistencyCheck( void ) -{ - S32 const tpiConvertedADC = ( (S32)getFPGATPiTemp() & MASK_OFF_U32_MSB ); - F32 const tpiTemperature = getADC2TempConversion( tpiConvertedADC, - (U32) tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].gain, - (U32) tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].refResistance, - (U32) tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].zeroDegreeResistance, - tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].conversionCoef ); - - S32 const tpoConvertedADC = ( (S32)getFPGATPoTemp() & MASK_OFF_U32_MSB ); - F32 const tpoTemperature = getADC2TempConversion( tpoConvertedADC, - (U32) tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].gain, - (U32) tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].refResistance, - (U32) tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].zeroDegreeResistance, - tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].conversionCoef ); - - F32 const tempDiff = fabs( tpiTemperature - tpoTemperature ); - if ( tempDiff > MAX_ALLOWED_TEMP_DELTA_BETWEEN_SENSORS ) - { - tempSensorsSelfTestResult = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TEMPERATURE_SENSORS_INCONSISTENT, TEMPSENSORS_SELF_TEST_CONSISTENCY_CHECK ); - } - else - { - tempSensorsSelfTestResult = SELF_TEST_STATUS_PASSED; - } - 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: none + * @details Inputs: elapsedTime * @details Outputs: elapsedTime - * @return state (TEMPSENSORS_EXEC_STATES_T) + * @return the next state of the state machine *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecStart( void ) { @@ -677,6 +726,7 @@ { elapsedTime = getMSTimerCount(); } + // A delay to let FPGA to boot up else if ( didTimeout( elapsedTime, ADC_FPGA_READ_DELAY ) ) { elapsedTime = 0; @@ -691,36 +741,57 @@ * The handleExecGetADCValues function reads the ADC values from FPGA and * at the specified time intervals and calls other functions to calculate * the internal temperature of the heaters. - * @details Inputs: none - * @details Outputs: internalHeatersConversionTimer, elapsedTime, temperatureValues - * @return state (TEMPSENSORS_EXEC_STATES_T) + * @details Inputs: internalHeatersConversionTimer + * @details Outputs: internalHeatersConversionTimer + * @return the next state of the state machine *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ) { - // Look at the error counter and the specific error flag to make sure the error is a temp sensor + // 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 - 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_REDUNDANCY, getFPGATHDoTemp(), getFPGATHDoErrorCount(), getFPGATHDoReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_INLET_DIALYSATE, getFPGATDiTemp(), getFPGATDiErrorCount(), getFPGATDiReadCount() ); + 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() ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, getFPGAPrimaryHeaterTemp(), getFPGAPrimaryHeaterFlags(), getFPGAPrimaryHeaterReadCount() ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, getFPGATrimmerHeaterTemp(), getFPGATrimmerHeaterFlags(), getFPGATrimmerHeaterReadCount() ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION, getFPGAPrimaryColdJunctionTemp(), getFPGATrimmerHeaterFlags(), getFPGAPrimaryHeaterReadCount() ); - processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION, getFPGATrimmerColdJunctionTemp(), getFPGATrimmerHeaterFlags(), getFPGATrimmerHeaterReadCount() ); + processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, getFPGAPrimaryHeaterTemp(), getFPGAPrimaryHeaterFlags(), + getFPGAPrimaryHeaterReadCount() ); - // Check if time has elapsed to calculate the internal temperature of the heaters - if ( ++internalHeatersConversionTimer >= HEATERS_INTERNAL_TEMPERTURE_CALCULATION_INTERVAL ) - { - getHeaterInternalTemp( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ); - getHeaterInternalTemp( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ); - internalHeatersConversionTimer = 0; - } + processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, getFPGATrimmerHeaterTemp(), getFPGATrimmerHeaterFlags(), + getFPGATrimmerHeaterReadCount() ); - publishTemperatureSensorsData(); + processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION, getFPGAPrimaryColdJunctionTemp(), getFPGATrimmerHeaterFlags(), + getFPGAPrimaryHeaterReadCount() ); + processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION, getFPGATrimmerColdJunctionTemp(), getFPGATrimmerHeaterFlags(), + getFPGATrimmerHeaterReadCount() ); + + // 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_TDI_RTD, getFPGATDiInternalTemp(), getFPGATDiErrorCount(), getFPGATDiReadCount() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); + + // Check if time has elapsed to calculate the internal temperature of the heaters + if ( ++internalHeatersConversionTimer >= HEATERS_INTERNAL_TEMPERTURE_CALCULATION_INTERVAL ) + { + getHeaterInternalTemp( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ); + getHeaterInternalTemp( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ); + internalHeatersConversionTimer = 0; + } + + fpgaRawADCReadInterval = 0; + } + return TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; } @@ -730,7 +801,7 @@ * publication interval either from the data or from the override. * @details Inputs: tempSensorsPublishInterval * @details Outputs: none - * @return result + * @return data publish interval *************************************************************************/ static U32 getPublishTemperatureSensorsDataInterval( void ) { @@ -747,8 +818,8 @@ /*********************************************************************//** * @brief * The publishTemperatureSensorsData function broadcasts the temperature - * sensors data at the publication interval - * @details Inputs: dataPublicationTimerCounter, tempValuesForPublication + * sensors data at the publication interval. + * @detailsInputs: dataPublicationTimerCounter, tempValuesForPublication * @details Outputs: dataPublicationTimerCounter, tempValuesForPublication * @return none *************************************************************************/ @@ -758,10 +829,12 @@ { U32 i; + // Populate all the temperature values for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) { tempValuesForPublication[ i ] = getTemperatureValue ( i ); } + broadcastTemperatureSensorsData( (U08*)(&tempValuesForPublication), NUM_OF_TEMPERATURE_SENSORS * sizeof(F32) ); dataPublicationTimerCounter = 0; } @@ -777,11 +850,11 @@ * @brief * The testSetMeasuredTemperatureOverride function sets the override value * for a specific temperature sensor. - * @details Inputs: temperatureValues - * @details Outputs: temperatureValues + * @details Inputs: tempSensors + * @details Outputs: tempSensors * @param sensorIndex temperature sensor index - * @param temperature temperature value to override if testing activated - * @return result + * @param temperature temperature value to override if testing is activated + * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetMeasuredTemperatureOverride( U32 sensorIndex, F32 temperature ) { @@ -804,10 +877,10 @@ * @brief * The testSetMeasuredTemperatureOverride function resets the override value * of a specified temperature sensor. - * @details Inputs: temperatureValues - * @details Outputs: temperatureValues + * @details Inputs: tempSensors + * @details Outputs: tempSensors * @param sensorIndex temperature sensor index - * @return result + * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetMeasuredTemperatureOverride( U32 sensorIndex ) { @@ -832,8 +905,8 @@ * the temperature sensors publish data interval. * @details Inputs: tempSensorsPublishInterval * @details Outputs: tempSensorsPublishInterval - * @param value temperature sensor data broadcast interval (in ms) to override to - * @return result + * @param value sensors data broadcast interval (in ms) to override + * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetTemperatureSensorsPublishIntervalOverride( U32 value ) { @@ -857,7 +930,7 @@ * the override value of temperature sensors publish data interval. * @details Inputs: tempSensorsPublishInterval * @details Outputs: tempSensorsPublishInterval - * @return result + * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetTemperatureSensorsPublishIntervalOverride( void ) {