Index: firmware/App/Controllers/Temperatures.c =================================================================== diff -u -r3f26385e0e67b8596b06c26533353c759f3ee996 -rbef8f02d9c868976c1e9d4f30432a3288db52324 --- firmware/App/Controllers/Temperatures.c (.../Temperatures.c) (revision 3f26385e0e67b8596b06c26533353c759f3ee996) +++ firmware/App/Controllers/Temperatures.c (.../Temperatures.c) (revision bef8f02d9c868976c1e9d4f30432a3288db52324) @@ -27,7 +27,7 @@ #define POWER_SUPPLY_THERMISTOR_BETA_VALUE 3345.0 ///< Power supply beta value. #define CELSIUS_TO_KELVIN_CONVERSION 273.15 ///< Celsius to Kelvin temperature conversion. #define MIN_ALLOWED_TEMPERATURE 0.0 ///< Thermistors/sensors minimum allowed temperature reading. -#define MAX_ALLOWED_TEMPERATURE 80.0 ///< Thermistors/sensors maximum allowed temperature reading. +#define MAX_ALLOWED_TEMPERATURE 120.0 ///< Thermistors/sensors maximum allowed temperature reading. #define MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD ( 5 * MS_PER_SECOND ) ///< Thermistors/sensors maximum allowed temperature out of range period. /// Temperatures exec states @@ -58,14 +58,16 @@ (F32)TWELVE_BIT_RESOLUTION; ///< On board thermistor ADC to voltage conversion coefficient. static const F32 ON_BOARD_THERMISTOR_REF_TEMP_INV = 1 / THERMISTOR_REFERENCE_TEMPERATURE; ///< On board thermistor reference inverse. +static const F32 CONVERSION_COEFF = 1.0 / 13584.0; ///< Conversion coefficient for FPGA board temperature. + // ********** private function prototypes ********** static TEMPERATURES_EXEC_STATES_T handleExecStart( void ); static TEMPERATURES_EXEC_STATES_T handleExecGetADCValues( void ); static void monitorTemperatures( void ); static void convertADC2Temperature( void ); -static F32 calculateTemperature( S32 adcValue ); +static F32 calculateOnBoardThemristorTemperature( S32 adcValue ); static void publishTemperaturesData( void ); static U32 getPublishTemperaturesDataInterval( void ); @@ -88,7 +90,7 @@ memset( &temperaturesStatus[ i ], 0x0, sizeof( TEMPERATURE_SENSORS_T ) ); } - // Initialize a persistent alarm for temperatures temeprature out of range + // Initialize a persistent alarm for temperatures temperature out of range initPersistentAlarm( ALARM_ID_HD_TEMPERATURES_OUT_OF_RANGE, MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD, MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD ); } @@ -139,7 +141,219 @@ } // Publish the data - getPublishTemperaturesDataInterval(); + publishTemperaturesData(); } +/*********************************************************************//** + * @brief + * The getThermistorTemperatureValue function returns the temperature of + * a requested thermistor or temperature sensor. + * @details Inputs: thermistorsStatus + * @details Outputs: none + * @param sensorID index to get its temperature value + * @return temperature of a thermistor or temperature sensor + *************************************************************************/ +F32 getTemperatureValue( TEMPERATURES_T sensorID ) +{ + F32 temperature = 0.0; + + // Check if the temperature sensor is in range + if ( sensorID < NUM_OF_TEMPERATURES ) + { + if ( OVERRIDE_KEY == temperaturesStatus[ sensorID ].temperatureValue.override ) + { + temperature = temperaturesStatus[ sensorID ].temperatureValue.ovData; + } + else + { + temperature = temperaturesStatus[ sensorID ].temperatureValue.data; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_TEMPERATURE_SENSOR_SELECTED, sensorID ); + } + + return temperature; +} + +/*********************************************************************//** + * @brief + * The handleExecStart function handles the start state of the exec state + * machine. + * @details Inputs: adcReadCounter + * @details Outputs: adcReadCounter + * @return next state of the exec state machine + *************************************************************************/ +static TEMPERATURES_EXEC_STATES_T handleExecStart( void ) +{ + TEMPERATURES_EXEC_STATES_T state = TEMPERATURES_EXEC_STATE_START_STATE; + + // Give a short time for FPGA to boot up and start sending the ADC reads + if ( ++adcReadCounter > ADC_FPGA_READ_DELAY_COUNT ) + { + state = TEMPERATURES_EXEC_STATE_GET_ADC_VALUES_STATE; + adcReadCounter = 0; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleExecGetADCValues function handles the get ADC values state + * of the exec state machine. + * @details Inputs: adcReadCounter + * @details Outputs: adcReadCounter, thermistorsStatus + * @return next state of the exec machine + *************************************************************************/ +static TEMPERATURES_EXEC_STATES_T handleExecGetADCValues( void ) +{ + TEMPERATURES_EXEC_STATES_T state = TEMPERATURES_EXEC_STATE_GET_ADC_VALUES_STATE; + + // If time has elapsed to read the ADCs, read them all + if ( ++adcReadCounter >= TEMPERATURES_ADC_READ_INTERVAL ) + { + // Get all the raw readings in ADC + temperaturesStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getIntADCReading( INT_ADC_BOARD_THERMISTOR ); + temperaturesStatus[ THERMISTOR_POWER_SUPPLY_1 ].rawADCRead = getIntADCReading( INT_ADC_PS_THERMISTOR ); + temperaturesStatus[ TEMPSENSOR_FPGA_BOARD_SENSOR ].rawADCRead = getFPGABoardTemperature(); + temperaturesStatus[ TEMPSENSOR_PBA_ADC_SENSOR ].rawADCRead = getFPGAPBAADCTemperature(); + + convertADC2Temperature(); + + // Monitor the values for a gross range check + // Monitor is called in this function because this driver is constantly reading + // the temperatures values. Also the internal ADC values are processed with moving average in the internalADC driver + // So the temperatures drivers just gets the latest ADC value and converts it to temperature + monitorTemperatures(); + + // Zero the counter for the next round of reading + adcReadCounter = 0; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The monitorTemperatures function monitors the temperature sensors for + * gross temperature range check. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +static void monitorTemperatures( void ) +{ + TEMPERATURES_T sensor; + F32 temperature; + + for ( sensor = THERMISTOR_ONBOARD_NTC; sensor < NUM_OF_THERMISTORS; sensor++ ) + { + temperature = getThermistorTemperatureValue( thermistor ); + BOOL isTempOutOfRange = ( temperature > MAX_ALLOWED_TEMPERATURE ) || ( temperature < MIN_ALLOWED_TEMPERATURE ); + + checkPersistentAlarm( ALARM_ID_HD_TEMPERATURES_OUT_OF_RANGE, isTempOutOfRange, temperature, MAX_ALLOWED_TEMPERATURE ); + } +} + +/*********************************************************************//** + * @brief + * The convertADCtoTemperature function converts the ADC values of different + * thermistors and temperature sensors to temperature value. + * @details Inputs: none + * @details Outputs: temperaturesStatus + * @return none + *************************************************************************/ +static void convertADC2Temperature( void ) +{ + TEMPERATURES_T sensor; + F32 temperature; + S32 rawADC; + + // Loop through the list and update the temperatures values + for ( sensor = THERMISTOR_ONBOARD_NTC; sensor < NUM_OF_TEMPERATURES; sensor++ ) + { + rawADC = (S32)temperaturesStatus[ sensor ].rawADCRead; + + switch ( sensor ) + { + case THERMISTOR_ONBOARD_NTC: + temperature = calculateOnBoardThemristorTemperature( rawADC ); + break; + + case THERMISTOR_POWER_SUPPLY_1: + // TODO figure out the temperature conversion + break; + + case TEMPSENSOR_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 = ( rawADC * CONVERSION_COEFF ) - CELSIUS_TO_KELVIN_CONVERSION; + break; + + case TEMPSENSOR_PBA_ADC_SENSOR: + // TODO figure out the temperature conversion + break; + + default: + // Wrong sensor was called, raise an alarm + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_TEMPERATURE_SENSOR_SELECTED, sensor ); + // Wrong sensor, return temperature to be -1 + temperature = -1.0; + break; + } + + temperaturesStatus[ sensor ].temperatureValue.data = temperature; + } +} + +/*********************************************************************//** + * @brief + * The calculateOnBoardThemristorTemperature function converts the ADC value + * of the onboard thermistor into temperature in C. Below are the calculation + * steps: + * voltage = ADC x 3 / 2^12 + * voltage = 3 x 10 / ( 10 + R(T) ) + * R(T) = 10000 x e^(beta x (1/T - 1/298)) + * Solve for T which is temperature in Kelvin + * @details Inputs: onBoardThermistorVoltageConvCoeff, + * onBoardThermistorBetaValueInv + * @details Outputs: none + * @param ADC value to be converted into temperature in C + * @return calculated temperature in C + *************************************************************************/ +static F32 calculateOnBoardThemristorTemperature( S32 adcValue ) +{ + // Voltage = ADC x 3 / 2^12 for 12 bits resolution and a 3V ADC + // The value of 3 / 2^12 has been calculated in a const to prevent the division again + F32 thermistorVoltage = adcValue * THERMISTOR_VOLTAGE_CONV_COEFF; + + // Calculate the thermistor resistor by solving: thermistorVoltage = (3 x 10) / (10 + R(T)) + F32 thermistorResistor = ( ( THERMISTOR_REFERENCE_RESISTOR_AT_25 * THERMISTOR_REFERENCE_VOLTAGE ) - + ( THERMISTOR_REFERENCE_RESISTOR_AT_25 * thermistorVoltage ) ) / thermistorVoltage; + + // 1/T = Ln(thermistorResistor/10000)/3380 + 1/298 + F32 invTemperature = ( logf( thermistorResistor / THERMISTOR_REFERENCE_RESISTOR_AT_25 ) / ONBOARD_THERMISTOR_BETA_VALUE ) + + ON_BOARD_THERMISTOR_REF_TEMP_INV; + + // Inverse the value to get the temperature in Kelvin and then convert it to Celsius + F32 temperature = ( 1 / invTemperature ) - CELSIUS_TO_KELVIN_CONVERSION; + + return temperature; +} + +/*********************************************************************//** + * @brief + * The publishTemperaturesData function publishes the temperatures sensors + * data at the specified time interval. + * @details Inputs: dataPublishCounter + * @details Outputs: dataPublishCounter + * @return none + *************************************************************************/ +static void publishTemperaturesData( void ) +{ + +} + /**@}*/ Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r3f26385e0e67b8596b06c26533353c759f3ee996 -rbef8f02d9c868976c1e9d4f30432a3288db52324 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 3f26385e0e67b8596b06c26533353c759f3ee996) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision bef8f02d9c868976c1e9d4f30432a3288db52324) @@ -156,6 +156,7 @@ SW_FAULT_ID_HD_INVALID_BUBBLE_STATE, // 125 SW_FAULT_ID_HD_INVALID_BUBBLE_ID, SW_FAULT_ID_HD_TEMPERATURES_INALID_EXEC_STATE, + SW_FAULT_ID_HD_INVALID_TEMPERATURE_SENSOR_SELECTED, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T;