#include "AlarmMgmtTD.h" #include "FpgaTD.h" #include "PressureSensor.h" #include "TaskGeneral.h" #include "Temperatures.h" #include "Timers.h" #include "Utilities.h" /** * @addtogroup Temperatures * @{ */ // ********** private definitions ********** #define TEMPERATURE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the pressure/occlusion data is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 7 ///< Data publish counter start count. #define TEMP_MOVING_AVG_NUM_OF_SAMPLES 10 ///< Temperature sensor moving average number of samples. /// Defined states for the temperature monitor state machine. typedef enum Temperature_States { TEMPERATURE_WAIT_FOR_POST_STATE = 0, ///< Wait for POST state. TEMPERATURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. NUM_OF_TEMPERATURE_STATES ///< Number of temperature monitor states. } TEMPERATURE_STATE_T; /// Temperature sensor moving average structure typedef struct { F32 tempRunningSumC; ///< Temperature sensor running sum in C. OVERRIDE_F32_T tempAvgC; ///< Temperature sensor average in C. F32 tempSamplesC[ TEMP_MOVING_AVG_NUM_OF_SAMPLES ]; ///< Temperature sensor samples array in C. U32 tempSamplesNextIndex; ///< Temperature sensor sample next index number. } TEMP_MOVING_AVG_STATUS_T; // ********** private data ********** static TEMPERATURE_STATE_T temperatureState; ///< Current state of pressure temperature state machine. static OVERRIDE_U32_T temperatureDataPublishInterval; ///< Interval (in ms) at which to publish temperature data to CAN bus. static U32 temperatureDataPublicationTimerCounter; ///< Used to schedule temperature data publication to CAN bus. static TEMP_MOVING_AVG_STATUS_T tempMovingAvg[ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature moving average status. // ********** private function prototypes ********** static TEMPERATURE_STATE_T handleTemperatureWaitForPOSTState( void ); static TEMPERATURE_STATE_T handleTemperatureContReadState( void ); static void processTemperatureReadings( TEMPERATURE_SENSORS_T sensor ); static void calculateTemperatureMovingAverage( TEMPERATURE_SENSORS_T sensor, F32 temperatureValueC ); static F32 getCalibrationAppliedTemperature( U08 sensor, F32 temperature ); static void publishTemperatureData( void ); /*********************************************************************//** * @brief * The initTemperature function initializes the Temperature unit. * @details \b Inputs: none * @details \b Outputs: Temperature unit initialized. * @return none *************************************************************************/ void initTemperature( void ) { TEMPERATURE_SENSORS_T i; temperatureState = TEMPERATURE_WAIT_FOR_POST_STATE; temperatureDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; temperatureDataPublishInterval.data = 0; temperatureDataPublishInterval.ovData = 0; temperatureDataPublishInterval.ovInitData = 0; temperatureDataPublishInterval.override = OVERRIDE_RESET; for ( i = H23_TEMP; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) { tempMovingAvg[ i ].tempAvgC.data = 0.0F; tempMovingAvg[ i ].tempAvgC.ovData = 0.0F; tempMovingAvg[ i ].tempAvgC.ovInitData = 0.0F; tempMovingAvg[ i ].tempAvgC.override = OVERRIDE_RESET; tempMovingAvg[ i ].tempRunningSumC = 0.0F; tempMovingAvg[ i ].tempSamplesNextIndex = 0; memset( &tempMovingAvg[ i ].tempSamplesC, 0.0F, TEMP_MOVING_AVG_NUM_OF_SAMPLES ); } } /*********************************************************************//** * @brief * The execTemperature function executes the temperature monitor state machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if temperature state is invalid. * @details \b Inputs: temperatureState * @details \b Outputs: temperatureState * @return none *************************************************************************/ void execTemperature( void ) { switch( temperatureState ) { case TEMPERATURE_WAIT_FOR_POST_STATE: temperatureState = handleTemperatureWaitForPOSTState(); break; case TEMPERATURE_CONTINUOUS_READ_STATE: temperatureState = handleTemperatureContReadState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_INVALID_STATE, temperatureState ) break; } publishTemperatureData(); } /*********************************************************************//** * @brief * The execTemperaturePOSTSelfTest function executes the temperature self-test to * be run during power-on self-test on startup. * @details \b Inputs: none * @details \b Outputs: TODO fill up * @return PASSED if self-test passes, FAILED if not. *************************************************************************/ SELF_TEST_STATUS_T execTemperaturePOSTSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; // TODO fill up return result; } /*********************************************************************//** * @brief * The getTemperatureSensorC function gets the current temperature sensor * in deg C. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given sensor is invalid. * @details \b Inputs: tempMovingAvg * @details \b Outputs: none * @param sensor ID of temperature sensor to get reading for. * @return The current temperature sensor deg C of the given temperature sensor. *************************************************************************/ F32 getTemperatureSensorC( TEMPERATURE_SENSORS_T sensor ) { F32 result = 0.0F; if ( sensor < NUM_OF_TEMPERATURE_SENSORS ) { result = getF32OverrideValue( &tempMovingAvg[ sensor ].tempAvgC ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSOR_INVALID_SENSOR, sensor ) } return result; } /*********************************************************************//** * @brief * The handleTemperatureWaitForPOSTState function handles the wait for POST * state. * @details \b Inputs: TODO fill up if any * @details \b Outputs: none * @return next state *************************************************************************/ static TEMPERATURE_STATE_T handleTemperatureWaitForPOSTState( void ) { TEMPERATURE_STATE_T state = TEMPERATURE_WAIT_FOR_POST_STATE; // TODO are more tests needed? state = TEMPERATURE_CONTINUOUS_READ_STATE; return state; } /*********************************************************************//** * @brief * The handleTemperatureContReadState function handles the continuous read state * of the temperature monitor state machine. * @details \b Inputs: FPGA temperature readings * @details \b Outputs: temperature sensor values updated * @return next state *************************************************************************/ static TEMPERATURE_STATE_T handleTemperatureContReadState( void ) { TEMPERATURE_STATE_T state = TEMPERATURE_CONTINUOUS_READ_STATE; TEMPERATURE_SENSORS_T i; for ( i = H23_TEMP; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) { processTemperatureReadings( i ); } return state; } /*********************************************************************//** * @brief * The processTemperatureReadings function processes the temperature readings. * The function then gets the converted values from other modules and passes them * to another function to calculate the moving average temperature. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if temperature sensor ID is invalid. * @details \b Inputs: none * @details \b Outputs: none * @param sensor the sensor ID to process its temperature * @return none *************************************************************************/ static void processTemperatureReadings( TEMPERATURE_SENSORS_T sensor ) { F32 temperatureValue = 0.0F; switch( sensor ) { case H23_TEMP: temperatureValue = getPressureSensorTemperature( H23_PRES ); calculateTemperatureMovingAverage( sensor, temperatureValue ); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSOR_INVALID_SENSOR, sensor ) break; } } /*********************************************************************//** * @brief * The calculateTemperatureMovingAverage function calculates the moving * average temperature of the provided temperature sensor. * @details \b Inputs: tempMovingAvg * @details \b Outputs: tempMovingAvg * @param sensor the sensor ID to process its temperature * @param temperatureValueC the temperature value to calculate its moving average * @return none *************************************************************************/ static void calculateTemperatureMovingAverage( TEMPERATURE_SENSORS_T sensor, F32 temperatureValueC ) { U32 currentIndex = tempMovingAvg[ sensor ].tempSamplesNextIndex; F32 prevSampleToRemoveC = tempMovingAvg[ sensor ].tempSamplesC[ currentIndex ]; F32 tempBeforeCal = 0.0F; tempMovingAvg[ sensor ].tempSamplesC[ currentIndex ] = temperatureValueC; tempMovingAvg[ sensor ].tempRunningSumC = tempMovingAvg[ sensor ].tempRunningSumC + temperatureValueC - prevSampleToRemoveC; tempMovingAvg[ sensor ].tempSamplesNextIndex = INC_WRAP( currentIndex, 0, TEMP_MOVING_AVG_NUM_OF_SAMPLES - 1 ); tempBeforeCal = tempMovingAvg[ sensor ].tempRunningSumC / TEMP_MOVING_AVG_NUM_OF_SAMPLES; tempMovingAvg[ sensor ].tempAvgC.data = getCalibrationAppliedTemperature( (U08)sensor, tempBeforeCal ); } /*********************************************************************//** * @brief * The getCalibrationAppliedTemperature function applies the calibration values * to the provided temperature and returns the values. * @details Inputs: TODO fill up * @details Outputs: none * @param sensor the ID of the temperature sensor * @param temperature the temperature before applying calibration to it * @return calibration applied temperature *************************************************************************/ static F32 getCalibrationAppliedTemperature( U08 sensor, F32 temperature ) { // TODO placeholder for later //F32 calPressure = pow( pressure, 4 ) * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].fourthOrderCoeff + // pow( pressure, 3 ) * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].thirdOrderCoeff + // pow( pressure, 2 ) * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].secondOrderCoeff + // pressure * pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].gain + // pressuresCalRecord.pressureSensors[ (PRESSURE_SENSORS_T)sensorId ].offset; //return calPressure; return temperature; } /*********************************************************************//** * @brief * The publishTemperatureData function publishes temperature data at the set * interval. * @details \b Message \b Sent: MSG_ID_TD_TEMPERATURE_DATA * @details \b Inputs: temperatureDataPublicationTimerCounter, * temperatureDataPublishInterval * @details \b Outputs: temperature data are published to CAN bus. * @return none *************************************************************************/ static void publishTemperatureData( void ) { // Publish pressure/occlusion data on interval if ( ++temperatureDataPublicationTimerCounter >= getU32OverrideValue( &temperatureDataPublishInterval ) ) { TEMPERATURE_DATA_T data; data.h32TemperatureC = getTemperatureSensorC( H23_TEMP ); broadcastData( MSG_ID_TD_TEMPERATURE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( TEMPERATURE_DATA_T ) ); temperatureDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testTemperatureDataPublishIntervalOverride function overrides the interval * at which the TD temperature data is published. * @details \b \b Inputs: none * @details \b \b Outputs: temperatureDataPublishInterval * @param message Override message from Dialin which includes the interval * (in ms) to override the temperature broadcast interval to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testTemperatureDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &temperatureDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testTemperatureOverride function overrides the temperature. * @details \b \b Inputs: none * @details \b \b Outputs: tempMovingAvg * @param message Override message from Dialin which includes the temperature * to override it to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testTemperatureOverride( MESSAGE_T *message ) { BOOL result = f32ArrayOverride( message, &tempMovingAvg[ 0 ].tempAvgC, NUM_OF_TEMPERATURE_SENSORS - 1 ); return result; }