/**********************************************************************//** * * 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 TemperatureSensors.c * * @date 7-Apr-2020 * @author Dara Navaei * * @brief DG temperature sensors controller * **************************************************************************/ #include // For temperature calculation #include "TemperatureSensors.h" #include "FPGA.h" // TODO: For testing only REMOVE #include "Timers.h" // TODO: For testing only REMOVE // Private variables #define PRIMARY_HEATER_EXT_TEMP_SENSORS_GAIN 16U ///< Primary heater external temperature sensors gain #define PRIMARY_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE 19600U ///< Primary heater external temperature sensors reference resistance #define PRIMARY_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE 1000U ///< Primary heater external temperature sensors zero degree resistance #define COND_SENSORS_TEMP_SENSOR_GAIN 16U ///< Conductivity sensor gain #define COND_SENSORS_TEMP_SENSOR_REF_RESISTANCE 19600U ///< Conductivity sensor reference resistance #define COND_SENSORS_TEMP_SENSOR_0_DEGREE_RESISTANCE 1000U ///< Conductivity sensor zero degree resistance #define TRIMMER_HEATER_EXT_TEMP_SENSORS_GAIN 32U ///< Trimmer heater external temperature sensors gain #define TRIMMER_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE 5110U ///< Trimmer heater external temperature sensors reference resistance #define TRIMMER_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE 100U ///< Trimmer heater external temperature sensors zero degree resistance #define HEATERS_INTERNAL_ADC_TO_TEMP_CONVERSION_COEFF 0.0625 ///< Heaters internal temperature sensors ADC to temperature conversion coefficient #define TEMP_SENSORS_ADC_BITS 24U ///< External temperature sensors ADC bits #define TEMP_SENSORS_ADC_MAX_COUNT (pow(2,TEMP_SENSORS_ADC_BITS)) ///< 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 MAX_NUM_OF_RAW_ADC_SAMPLES 20U ///< Number of ADC reads for moving average calculations #define ADC_READ_FIRST_READ_INDEX 0U ///< ADC array first ADC read index #define ADC_READ_NEXT_INDEX_INDEX 0U ///< ADC array next insertion index #define ADC_READ_RUNNING_SUM_INDEX 1U ///< ADC array running sum index #define ADC_READ_GAIN_INDEX 0U ///< ADC array gain index #define ADC_READ_REF_RESISTANCE_INDEX 1U ///< ADC array reference resistances index #define ADC_READ_0_DEG_RESISTANCE_INDEX 2U ///< ADC array zero degree resistance index #define READ_AND_ERROR_PREV_FPGA_COUNT_INDEX 0U #define READ_AND_ERROR_INTERNAL_READ_COUNT_INDEX 1U #define READ_AND_ERROR_INTERNAL_ERROR_COUNT_INDEX 2U #define READ_AND_ERROR_PREV_FPGA_ERROR_INDEX 3U #define NUM_OF_READ_AND_ERROR_ARRAY_COLUMNS 4U #define MAX_ALLOWED_TEMP_DELTA_BETWEEN_SENSORS 2U ///< Maximum allowed temperature delta between sensors #define NUM_OF_RUNNING_SUM_AND_INDEX_ARRAY_COLUMNS 2U ///< Number of columns in running sum and index array #define NUM_OF_TEMP_SENSORS_CONSTANTS_ARRAY_COLUMNS 3U ///< Number of columns in temperature sensors constants #define MAX_ALLOWED_UNCHANGED_ADC_READS 4U ///< Maximum number of times that the read of a sensor cannot change #define EXTERNAL_TEMP_SENSORS_ERROR_VALUE 0x80 #define HEATERS_INTERNAL_TEMP_SENSOR_FAULT 0x01 #define MASK_OFF_U32_MSB 0x00FFFFFF /// 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; /// Temperature sensor exec states typedef enum tempSensors_Exec_States { TEMPSENSORS_EXEC_STATE_START = 0, ///< Temperature sensors exec start TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES, ///< Temperature sensors exec get ADC values NUM_OF_TEMPSENSORS_EXEC_STATES, ///< Total number of exec states } TEMPSENSORS_EXEC_STATES_T; /// FPGA error and read counts typedef struct { U08 RTDErrorCount; ///< RTD error count (include all 4 conductivity and temperature sensors) U08 RTDReadCount; ///< RTD read count (include all 4 conductivity and temperature sensors) U08 TRoErrorCount; ///< THDo (outlet redundant temperature sensor) error count U08 TRoReadCount; ///< THDo (outlet redundant temperature sensor) read count U08 TDiErrorCount; ///< TDi (inlet dialysate) temperature sensor error count U08 TDiReadCount; ///< TDi (inlet dialysate) temperature sensor read count U08 primaryHeaterFlags; ///< Primary heater internal temperature sensor error flags U08 primaryHeaterReadCount; ///< Primary heater internal temperature sensor read count U08 trimmerHeaterFlags; ///< Trimmer heater internal temperature sensor error flags U08 trimmerHeaterReadCount; ///< Trimmer heater internal temperature sensor read count } FPGA_READ_AND_ERROR_COUNTS_T; // TODO REmove static SELF_TEST_STATUS_T tempSensorsSelfTestResult; ///< 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 U32 sampleCount; ///< Initial ADC read index until the array if filled up for the first time static U32 rawADCReads [ NUM_OF_TEMPERATURE_SENSORS ] ///< Raw ADC reads array [ MAX_NUM_OF_RAW_ADC_SAMPLES ]; static U32 runningSumAndIndex [ NUM_OF_TEMPERATURE_SENSORS ] ///< Running sum and next ADC index array [ NUM_OF_RUNNING_SUM_AND_INDEX_ARRAY_COLUMNS ]; static U32 tempSensorsConstants [ NUM_OF_TEMPERATURE_SENSORS ] ///< Temperature sensors constants [ NUM_OF_TEMP_SENSORS_CONSTANTS_ARRAY_COLUMNS ]; static F32 avgADCReads [ NUM_OF_TEMPERATURE_SENSORS ]; //TODO remove ///< Temperature sensors averaged ADC values static F32 temperatureValues [ NUM_OF_TEMPERATURE_SENSORS ]; static U32 readAndErrorCounts [ NUM_OF_TEMPERATURE_SENSORS ] [ NUM_OF_READ_AND_ERROR_ARRAY_COLUMNS ]; // Private functions 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 ); static F32 getADC2TempConversion ( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance ); static void processADCRead ( U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount ); // Public functions /************************************************************************* * @brief initTemperatureSensors * The initTemperatureSensors function initializes the module * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ void initTemperatureSensors ( void ) { U08 i; tempSensorsSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; tempSensorsSelfTestState = TEMPSENSORS_SELF_TEST_START; tempSensorsExecState = TEMPSENSORS_EXEC_STATE_START; sampleCount = 0; // Initialize TPi and TPo constants for ( i = TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR; i < TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR; i++ ) { tempSensorsConstants [ i ] [ ADC_READ_GAIN_INDEX ] = PRIMARY_HEATER_EXT_TEMP_SENSORS_GAIN; tempSensorsConstants [ i ] [ ADC_READ_REF_RESISTANCE_INDEX ] = PRIMARY_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; tempSensorsConstants [ i ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] = PRIMARY_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; } // Initialize TD1 and TD2 constants for ( i = TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR; i < TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR; i++ ) { tempSensorsConstants [ i ] [ ADC_READ_GAIN_INDEX ] = COND_SENSORS_TEMP_SENSOR_GAIN; tempSensorsConstants [ i ] [ ADC_READ_REF_RESISTANCE_INDEX ] = COND_SENSORS_TEMP_SENSOR_REF_RESISTANCE; tempSensorsConstants [ i ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] = COND_SENSORS_TEMP_SENSOR_0_DEGREE_RESISTANCE; } // Initialize TRo and TDi constants for ( i = TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR; i < TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR; i++ ) { tempSensorsConstants [ i ] [ ADC_READ_GAIN_INDEX ] = TRIMMER_HEATER_EXT_TEMP_SENSORS_GAIN; tempSensorsConstants [ i ] [ ADC_READ_REF_RESISTANCE_INDEX ] = TRIMMER_HEATER_EXT_TEMP_SENSORS_REF_RESISTANCE; tempSensorsConstants [ i ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] = TRIMMER_HEATER_EXT_TEMP_SENSORS_0_DEGREE_RESISTANCE; } // Initialize primary heater internal temperature sensor // The heaters do not need gain, reference resistance, and zero degree resistance tempSensorsConstants [ TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ] = 0; tempSensorsConstants [ TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ] = 0; tempSensorsConstants [ TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] = 0; // Initialize trimmer heater internal temperature sensor tempSensorsConstants [ TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ] [ ADC_READ_GAIN_INDEX ] = 0; tempSensorsConstants [ TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ] [ ADC_READ_REF_RESISTANCE_INDEX ] = 0; tempSensorsConstants [ TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] = 0; } /************************************************************************* * @brief execTemperatureSensorsSelfTest * The execTemperatureSensorsSelfTest function runs the TemperatureSensors * POST during the self test * @details * Inputs : none * Outputs : SELF_TEST_STATUS_T * @param none * @return SELF_TEST_STATUS_T *************************************************************************/ SELF_TEST_STATUS_T execTemperatureSensorsSelfTest ( void ) { switch ( tempSensorsSelfTestState ) { case TEMPSENSORS_SELF_TEST_START: tempSensorsSelfTestState = handleSelfTestStart(); break; case TEMPSENSORS_SELF_TEST_ADC_CHECK: 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_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSORS_INVALID_SELF_TEST_STATE, tempSensorsSelfTestState ); tempSensorsSelfTestState = TEMPSENSORS_SELF_TEST_COMPLETE; break; } return tempSensorsSelfTestResult; } /************************************************************************* * @brief execTemperatureSensors * The execTemperatureSensors function runs the TemperatureSensors main * tasks * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ void execTemperatureSensors ( void ) { // read the sensors all the time switch ( tempSensorsExecState ) { case TEMPSENSORS_SELF_TEST_START: tempSensorsExecState = handleExecStart(); break; case TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES: tempSensorsExecState = handleExecGetADCValues(); break; default: SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE, tempSensorsExecState ); tempSensorsExecState = TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; break; } } /************************************************************************* * @brief getTemperatureValue * The getTemperatureValue function gets the enum of the requested * temperature sensor, converts the ADC of it to temperature in degree C * and returns the temperature * @details * Inputs : TEMPERATURE_SENSORS_T (sensor) * Outputs : F32 (temperature in deg C) * @param none * @return F32 (temperature in deg C) *************************************************************************/ F32 getTemperatureValue ( TEMPERATURE_SENSORS_T sensor ) { F32 temperature; switch ( sensor ) { case TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ]; break; case TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ]; break; case TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ]; break; case TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ]; break; case TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ]; break; case TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ]; break; case TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR: temperature = temperatureValues [ TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR ]; break; case TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR: temperature = temperatureValues [ TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ]; break; default: // ToDo: Warning? break; } return temperature; } // Private functions /************************************************************************* * @brief getADC2TempConversion * The getADC2TempConversion function calculates the temperature from * ADC read from FPGA * @details * Inputs : U32 (adc, gain, refResistance) * Outputs : F32 (temperature in deg C) * @param none * @return F32 (temperature in deg C) *************************************************************************/ static F32 getADC2TempConversion ( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance ) { //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))); //T=(-A+√(A^2-4B(1-R_T/R_0 )))/2B F32 secondSqrtPart = 4 * TEMP_EQUATION_COEFF_B * (1 - (resistance / zeroDegResistance)); F32 temperature = (-TEMP_EQUATION_COEFF_A + sqrt(pow(TEMP_EQUATION_COEFF_A, 2) - secondSqrtPart)) / (2 * TEMP_EQUATION_COEFF_B); return temperature; } /************************************************************************* * @brief processADCRead * 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 : U32 (sensorIndex, adc) * Outputs : none * @param none * @return none *************************************************************************/ static void processADCRead (U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount ) { U32 error; U32 heatersInternalTemperature; BOOL isADCValid = FALSE; F32 temperature; // TODO For testing only. REMOVE /*temperature = getADC2TempConversion ( adc, tempSensorsConstants [ TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ], tempSensorsConstants [ TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ], tempSensorsConstants [ TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] );*/ // TODO for testing only. REMOVE /* * check if the index is not the heaters * Mask the values accordingly * if error is 0x80 for the external sensors, increment * if count has not changed, update the previous count, increment the internal error count * if the internal error count is above the threshold, set alarm, set the bool avGCalc to false * if count is greater than previous, update the previous and reset the internal count * set the avgCalc to true * if the avgCalc in true, calculate all the steps and immediately convert to temperature */ if ( sensorIndex != TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR || sensorIndex != TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ) { error = adc & MASK_OFF_U32_MSB; /* * what if the fpga channel error is not zero? * what if the fpga channel error is zero but the individual is not? */ if ( fpgaError != 0 ) { if ( error == EXTERNAL_TEMP_SENSORS_ERROR_VALUE ) { // TODO: alarm? } isADCValid = FALSE; } if ( error == EXTERNAL_TEMP_SENSORS_ERROR_VALUE ) { //tODO: FILL UP isADCValid = FALSE; } } else { // Fault state is the 17th bit U32 fault = adc & MASK_OFF_LSW; fault = fault & 0x0001; if ( fault == HEATERS_INTERNAL_TEMP_SENSOR_FAULT ) { // Fault alarm? or have a threshold? // If the fault is 1, should we check the individuals? } // Mask off the thermocouple section heatersInternalTemperature = adc & MASK_OFF_MSW; heatersInternalTemperature = heatersInternalTemperature & MASK_OFF_NIBBLE_LSB; } U32 previousReadCount = readAndErrorCounts [ sensorIndex ] [ READ_AND_ERROR_PREV_FPGA_COUNT_INDEX ]; if ( fpgaCount == previousReadCount ) { U32 internalErrorCount = readAndErrorCounts [ sensorIndex ] [ READ_AND_ERROR_INTERNAL_ERROR_COUNT_INDEX ]; if ( internalErrorCount > MAX_ALLOWED_UNCHANGED_ADC_READS ) { // TODO alarm } else { readAndErrorCounts [ sensorIndex ] [ READ_AND_ERROR_PREV_FPGA_COUNT_INDEX ] = fpgaCount; readAndErrorCounts [ sensorIndex ] [ READ_AND_ERROR_INTERNAL_ERROR_COUNT_INDEX ] = internalErrorCount++; } isADCValid = FALSE; } else if ( fpgaCount > previousReadCount ) { readAndErrorCounts [ sensorIndex ] [ READ_AND_ERROR_PREV_FPGA_COUNT_INDEX ] = fpgaCount; readAndErrorCounts [ sensorIndex ] [ READ_AND_ERROR_INTERNAL_ERROR_COUNT_INDEX ] = 0; isADCValid = TRUE; } if ( isADCValid ) { // Update the values in the folders U32 index = runningSumAndIndex [ sensorIndex ] [ ADC_READ_NEXT_INDEX_INDEX ]; U32 runningSum = runningSumAndIndex [ sensorIndex ] [ ADC_READ_RUNNING_SUM_INDEX ]; U32 indexValue = rawADCReads [ sensorIndex ] [ index ]; U32 nextIndex = INC_WRAP( index, ADC_READ_FIRST_READ_INDEX, MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ); runningSum = runningSum - indexValue + adc; rawADCReads [ sensorIndex ] [ index ] = adc; runningSumAndIndex [ sensorIndex ] [ ADC_READ_NEXT_INDEX_INDEX ] = nextIndex; runningSumAndIndex [ sensorIndex ] [ ADC_READ_RUNNING_SUM_INDEX ] = runningSum; // If the buffer array is being filled for the first time, the number of samples // are changing. When the array is filled up completely, max number of samples are used if ( sampleCount < MAX_NUM_OF_RAW_ADC_SAMPLES ) { sampleCount++; } else { sampleCount = MAX_NUM_OF_RAW_ADC_SAMPLES; } // Calculate average F32 avgADCReads = runningSum / sampleCount; // The external temperature sensors have gain and other parameters for temperature // calculations. The heaters internal temperature sensors do not have any parameters // this is used to decide whether to call the quadratic equation or not if ( tempSensorsConstants [ sensorIndex ] [ ADC_READ_GAIN_INDEX ] != 0 ) { temperature = getADC2TempConversion ( avgADCReads, tempSensorsConstants [ sensorIndex ] [ ADC_READ_GAIN_INDEX ], tempSensorsConstants [ sensorIndex ] [ ADC_READ_REF_RESISTANCE_INDEX ], tempSensorsConstants [ sensorIndex ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] ); } else { temperature = avgADCReads * HEATERS_INTERNAL_ADC_TO_TEMP_CONVERSION_COEFF; } temperatureValues [ sensorIndex ] = temperature; } } /************************************************************************* * @brief handleSelfTestStart * The handleSelfTestStart function waits for the ADC read array to be * filled up for the first time. It then sets the state to next state * @details * Inputs : none * Outputs : state (TEMPSENSORS_SELF_TEST_STATES_T) * @param none * @return state (TEMPSENSORS_SELF_TEST_STATES_T) *************************************************************************/ static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestStart ( void ) { return TEMPSENSORS_SELF_TEST_ADC_CHECK; } /************************************************************************* * @brief handleSelfTestADCCheck * 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 : none * Outputs : state (TEMPSENSORS_SELF_TEST_STATES_T) * @param none * @return state (TEMPSENSORS_SELF_TEST_STATES_T) *************************************************************************/ static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestADCCheck ( void ) { TEMPSENSORS_SELF_TEST_STATES_T state = TEMPSENSORS_SELF_TEST_CONSISTENCY_CHECK; U08 i; for ( i = 0; i < sizeof(avgADCReads); i++ ) { U32 avgADC = avgADCReads [ i ]; if ( avgADC > TEMP_SENSORS_ADC_MAX_COUNT ) { SET_ALARM_WITH_1_U32_DATA ( ALARM_ID_TEMPERATURE_SENSORS_OUT_OF_RANGE, TEMPSENSORS_SELF_TEST_ADC_CHECK ); } } return state; } /************************************************************************* * @brief handleSelfTestConsistencyCheck * The handleSelfTestConsistencyCheck function checks the values of the * sensors to make sure they are within the allowed range from each other * @details * Inputs : none * Outputs : state (TEMPSENSORS_SELF_TEST_STATES_T) * @param none * @return state (TEMPSENSORS_SELF_TEST_STATES_T) *************************************************************************/ static TEMPSENSORS_SELF_TEST_STATES_T handleSelfTestConsistencyCheck ( void ) { //TODO Consider edge cases for the consistency check TEMPSENSORS_SELF_TEST_STATES_T state = TEMPSENSORS_SELF_TEST_COMPLETE; U32 largestDelta; U08 i, j; // Check if all the sensors are within a certain degree c // from each other for ( i = 0; i < sizeof(temperatureValues); i++ ) { for ( j = 0; j < sizeof(temperatureValues); j++ ) { if ( i != j ) { largestDelta = MAX( largestDelta, fabs(temperatureValues [ i ] - temperatureValues [ j ]) ); } if ( largestDelta > MAX_ALLOWED_TEMP_DELTA_BETWEEN_SENSORS ) { SET_ALARM_WITH_1_U32_DATA ( ALARM_ID_TEMPERATURE_SENSORS_INCONSISTENT, TEMPSENSORS_SELF_TEST_CONSISTENCY_CHECK ); } } } return state; } /************************************************************************* * @brief handleExecStart * The handleExecStart function switches the state to read * @details * Inputs : none * Outputs : state (TEMPSENSORS_EXEC_STATES_T) * @param none * @return state (TEMPSENSORS_EXEC_STATES_T) *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecStart ( void ) { return TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; } /************************************************************************* * @brief handleExecGetADCValues * The handleExecGetADCValues function reads the ADC values from FPGA * @details * Inputs : none * Outputs : state (TEMPSENSORS_EXEC_STATES_T) * @param none * @return state (TEMPSENSORS_EXEC_STATES_T) *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues ( void ) { TEMPSENSORS_EXEC_STATES_T state = TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; // Check the read count for a change before inserting // Need to remember the fpga counter and if it has not changed increment another counter and // zero it if it changed. if it is above a certain number throw fault // error counter from fpga same as above remember, if it is incremented: // Look at the error counter and the specific error flag to make sure the error is a temp sensor // Add a byte array to have bits for each sensor to find out exactly what sensor failed //processADCRead( TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR, getFPGATPiTemp() ); //processADCRead( TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR, getFPGATPoTemp() ); //processADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR, getFPGACD1Temp() ); //processADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR, getFPGACD2Temp() ); //processADCRead( TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR, getFPGATHDoTemp() ); //processADCRead( TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR, getFPGATDiTemp() ); //processADCRead( TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR, getFPGAPrimaryHeaterTemp() ); //processADCRead( TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR, getFPGATrimmerHeaterTemp() ); // TODO REMOVE THIS CODE. FOR TESTING ONLY /*U08 dara; U32 test [20] = {16327313, 16330313, 16333313, 16336313, 16339313, 16342313, 16345313, 16348313, 16351313, 16354313, 16357313, 16360313, 16363313, 16366313, 16369313, 16372313, 16375313, 16378313, 16381313, 16384313}; U32 test2 [20] = {16348313, 16358313, 16368313, 16378313, 16388313, 16398313, 16408313, 16418313, 16428313, 16438313, 16448313, 16458313, 16468313, 16478313, 16488313, 16498313, 16508313, 16518313, 16528313, 16538313}; for ( dara = 0; dara<20; dara++) { processADCRead(0, test[dara]); } dara = 0; for ( dara = 0; dara<20; dara++) { processADCRead(0, test2[dara]); }*/ // TODO REMOVE THE ABOVE CODE return state; }