Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -rc12bff518c0b58065eede15469ad8a2a6f6e317b -re7f256098e5c23cc621af73b17160a247d40559c --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision c12bff518c0b58065eede15469ad8a2a6f6e317b) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision e7f256098e5c23cc621af73b17160a247d40559c) @@ -36,8 +36,7 @@ #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 PRIMARY_HEATER_INTERNAL_TEMP_SENSOR_CONVERSION_COEFF 0.25 ///< Primary heater internal temperature sensor conversion coefficient -#define TRIMMER_HEATER_INTERNAL_TEMP_SENSOR_CONVERSION_COEFF 0.25 ///< Trimmer heater internal temperature sensor conversion coefficient +#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 @@ -56,13 +55,23 @@ #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_READS 4U ///< Maximum number of times that the read of a sensor cannot change +#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 { @@ -94,7 +103,7 @@ 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; +} 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 @@ -106,8 +115,9 @@ [ 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 ]; ///< Temperature sensors averaged ADC values -static FPGA_READ_AND_ERROR_COUNTS_T FPGAReadAndErrorCounts; +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 @@ -119,7 +129,7 @@ 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 ); +static void processADCRead ( U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount ); // Public functions @@ -267,60 +277,42 @@ { case TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR: - temperature = getADC2TempConversion ( avgADCReads [ TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ], - tempSensorsConstants [ TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ], - tempSensorsConstants [ TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ], - tempSensorsConstants [ TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] ); + temperature = temperatureValues [ TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR ]; break; case TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR: - temperature = getADC2TempConversion ( avgADCReads [ TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ], - tempSensorsConstants [ TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ], - tempSensorsConstants [ TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ], - tempSensorsConstants [ TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] ); + temperature = temperatureValues [ TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR ]; break; case TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR: - temperature = getADC2TempConversion ( avgADCReads [ TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ], - tempSensorsConstants [ TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ], - tempSensorsConstants [ TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ], - tempSensorsConstants [ TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] ); + temperature = temperatureValues [ TEMPSENSORS_CONDUCTIVITY_SENSOR_1_TEMP_SENSOR ]; break; case TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR: - temperature = getADC2TempConversion ( avgADCReads [ TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ], - 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 ] ); + temperature = temperatureValues [ TEMPSENSORS_CONDUCTIVITY_SENSOR_2_TEMP_SENSOR ]; break; case TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR: - temperature = getADC2TempConversion ( avgADCReads [ TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ], - tempSensorsConstants [ TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ], - tempSensorsConstants [ TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ], - tempSensorsConstants [ TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] ); + temperature = temperatureValues [ TEMPSENSORS_OUTLET_REDUNDANCY_TEMP_SENSOR ]; break; case TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR: - temperature = getADC2TempConversion ( avgADCReads [ TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ], - tempSensorsConstants [ TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ] [ ADC_READ_GAIN_INDEX ], - tempSensorsConstants [ TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ] [ ADC_READ_REF_RESISTANCE_INDEX ], - tempSensorsConstants [ TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ] [ ADC_READ_0_DEG_RESISTANCE_INDEX ] ); + temperature = temperatureValues [ TEMPSENSORS_INLET_DIALYSATE_TEMP_SENSOR ]; break; case TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR: - temperature = avgADCReads [ TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR ] * PRIMARY_HEATER_INTERNAL_TEMP_SENSOR_CONVERSION_COEFF; + temperature = temperatureValues [ TEMPSENSORS_PRIMARY_HEATER_INTERNAL_TEMP_SENSOR ]; break; case TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR: - temperature = avgADCReads [ TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ] * TRIMMER_HEATER_INTERNAL_TEMP_SENSOR_CONVERSION_COEFF; + temperature = temperatureValues [ TEMPSENSORS_TRIMMER_HEATER_INTERNAL_TEMP_SESNOR ]; break; default: @@ -347,8 +339,6 @@ { //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))); - // TODO For testing in a separate workspace, loop through and do the equation, disable Irq and dont disable Fiq and enable Irq and get the mstimer() - // comment you initiProcessor in main. //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); @@ -366,32 +356,137 @@ * @param none * @return none *************************************************************************/ -static void processADCRead ( U32 sensorIndex, U32 adc ) +static void processADCRead (U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount ) { - // 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; + U32 error; + U32 heatersInternalTemperature; + BOOL isADCValid = FALSE; + F32 temperature; - 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 ) + // 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 ) { - sampleCount++; + 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 { - sampleCount = MAX_NUM_OF_RAW_ADC_SAMPLES; + // 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; } - // Calculate average - avgADCReads [ sensorIndex ] = runningSum / sampleCount; + + 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 @@ -515,14 +610,14 @@ // 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() );*/ + //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 /*U32 i; @@ -540,7 +635,7 @@ adc = adc + 150; } U32 elapsedTime = calcTimeSince( testTimer ); - _enable_IRQ();*/ + _enable_IRQ(); U08 dara; @@ -558,7 +653,7 @@ for ( dara = 0; dara<20; dara++) { processADCRead(0, test2[dara]); - } + }*/ // TODO REMOVE THE ABOVE CODE return state;