/************************************************************************** * * Copyright (c) 2024-2026 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 Temperature.c * * @author (last) Michael Garthwaite * @date (last) 06-Mar-2026 * * @author (original) Vinayakam Mani * @date (original) 25-Sep-2024 * ***************************************************************************/ #include "BalancingChamber.h" #include "Conductivity.h" #include "Flow.h" #include "Messaging.h" #include "MessageSupport.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "Pressure.h" #include "Temperature.h" #include "Timers.h" #include "TaskPriority.h" #include "TDInterface.h" #include "Utilities.h" /** * @addtogroup Temperature * @{ */ // ********** private definitions ********** #define ADC_FPGA_READ_DELAY 30U ///< Delay in ms before reading the ADC values from FPGA. #define TEMP_SENSORS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Temperature sensors publish data time interval. #define TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Temperature sensors FPGA error timeout in milliseconds. #define TEMP_MOVING_AVG_NUM_OF_SAMPLES 50 ///< temperature sensor moving average number of samples. #define DATA_PUBLISH_COUNTER_START_COUNT 30 ///< Data publish counter start count. #define DIAL_TEMP_MOVING_AVG_NUM_OF_SAMPLES 30 ///< Dialysate temperature sensors moving average number of samples. #define D28_D30_DATA_COLLECTION_TIME_MS ( 1 * MS_PER_SECOND ) ///< Dialysate temperature sensors data collection time in milliseconds. #define D28_D30_TEMP_SENSORS_MAX_DEVIATION_C 3.0F ///< Dialysate temperature sensors maximum allowed deviation in C. #define DIALYSATE_TEMP_SNSRS_OUT_OF_RANGE_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature sensors drift timeout in milliseconds. #define D28_D30_TEMP_SENSORS_MAX_DEVIATION_IN_HEAT_DIS_C 5.0F ///< Dialysate temperature sensors maximum allowed deviation in heat disinfect in C. /// Dialysate temperature sensors enums typedef enum dial_Temps_Sensors { DIAL_TEMP_D28 = 0, ///< Dialysate temperature D28. DIAL_TEMP_FIRST = DIAL_TEMP_D28, ///< Dialysate temperature first. DIAL_TEMP_D30, ///< Dialysate temperature D30. NUM_OF_DIAL_TEMPS ///< Number of Dialysate temperature sensors. } DIAL_TEMPERATURE_SENSORS_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; /// Filter temperature readings record. typedef struct { F32 temperatureReadings[ TEMP_MOVING_AVG_NUM_OF_SAMPLES ]; ///< Holds temperature sample rolling average. U32 temperatureReadingsIdx; ///< Index for next sample in rolling average array. F32 temperatureReadingsTotal; ///< Rolling total - used to calc average. U32 temperatureReadingsCount; ///< Number of samples in rolling average buffer } FILTER_TEMPERATURE_READINGS_T; /// Dialysate temperature moving average structure typedef struct { BOOL dialTempColHasTimerBeenSet; ///< Dialysate temperature has data collection timer started boolean flag. U32 dialTempDataColStartTimeMS; ///< Dialysate temperature data collection start time in milliseconds. F32 dialTempRunningSumC; ///< Dialysate temperature running sum in C. F32 dialTempAvgC; ///< Dialysate temperature average in C. F32 dialTempSamplesC[ DIAL_TEMP_MOVING_AVG_NUM_OF_SAMPLES ]; ///< Dialysate temperature samples array in C. U32 dialTempSamplesNextIndex; ///< Dialysate temperature sample next index number. } DIAL_TEMP_MOVING_AVG_DATA_T; // ********** private data ********** static TEMPSENSORS_EXEC_STATES_T tempSensorsExecState; ///< TemperatureSensor exec state. static U32 startTime; ///< start time to read FPGA values. static BOOL tempDriftEventCheck; ///< Temperature sensor drift event boolean. static DIAL_TEMP_MOVING_AVG_DATA_T dialTempMovingAvgData[ NUM_OF_DIAL_TEMPS ]; ///< Dialysate temperature moving average data. static FILTER_TEMPERATURE_READINGS_T filteredTemperatureReadings[NUM_OF_TEMPERATURE_SENSORS]; ///< Filtered temperature reading for temperature sensors. static OVERRIDE_F32_T filteredcurrentTemperatureReadings[ NUM_OF_TEMPERATURE_SENSORS ]; ///< filtered current temperature sensor temperature readings (overrideable). static U32 tempDataCollectionTimeInterval; ///< Temperature data collection time interval in milliseconds. static U32 TempSampleIntervalCounter; ///< temperature sensor sample collection timer counter. static U32 ddTempDataPublicationTimerCounter; ///< DD Temperature sensors data publish timer counter. static U32 fpTempDataPublicationTimerCounter; ///< FP Temperature sensors data publish timer counter. static OVERRIDE_U32_T ddTempSensorsPublishInterval; ///< DD Temperature sensors publish time interval override. static OVERRIDE_U32_T fpTempSensorsPublishInterval; ///< FP Temperature sensors publish time interval override. // ********** private function prototypes ********** static TEMPSENSORS_EXEC_STATES_T handleExecStart( void ); static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ); static void filterTemperatureReadings( void ); static void filterDialTemperatureReadings( void ); static void getTempMovingAverageTimeInterval( void ); static void publishTemperatureSensorsData( void ); /*********************************************************************//** * @brief * The initTemperature function initializes the temperature unit. * @details \b Inputs: none * @details \b Outputs: temperature unit variables initialized. * @return none *************************************************************************/ void initTemperature( void ) { TEMPERATURE_SENSORS_T sensor; startTime = 0; tempSensorsExecState = TEMPSENSORS_EXEC_STATE_START; ddTempDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; fpTempDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; TempSampleIntervalCounter = 0; tempDataCollectionTimeInterval = 0; tempDriftEventCheck = FALSE; // Initialize override structures for each temperature sensor for ( sensor = TEMPSENSORS_FIRST; sensor < NUM_OF_TEMPERATURE_SENSORS; sensor++ ) { filteredcurrentTemperatureReadings[ sensor ].data = 0.0F; filteredcurrentTemperatureReadings[ sensor ].ovData = 0.0F; filteredcurrentTemperatureReadings[ sensor ].ovInitData = 0.0F; filteredcurrentTemperatureReadings[ sensor ].override = OVERRIDE_RESET; filteredTemperatureReadings[ sensor ].temperatureReadingsIdx = 0; filteredTemperatureReadings[ sensor ].temperatureReadingsTotal = 0.0F; filteredTemperatureReadings[ sensor ].temperatureReadingsCount = 0; } dialTempMovingAvgData[ DIAL_TEMP_D28 ].dialTempColHasTimerBeenSet = FALSE; dialTempMovingAvgData[ DIAL_TEMP_D30 ].dialTempColHasTimerBeenSet = FALSE; ddTempSensorsPublishInterval.data = TEMP_SENSORS_DATA_PUBLISH_INTERVAL; ddTempSensorsPublishInterval.ovData = TEMP_SENSORS_DATA_PUBLISH_INTERVAL; ddTempSensorsPublishInterval.ovInitData = 0; ddTempSensorsPublishInterval.override = OVERRIDE_RESET; fpTempSensorsPublishInterval.data = TEMP_SENSORS_DATA_PUBLISH_INTERVAL; fpTempSensorsPublishInterval.ovData = TEMP_SENSORS_DATA_PUBLISH_INTERVAL; fpTempSensorsPublishInterval.ovInitData = 0; fpTempSensorsPublishInterval.override = OVERRIDE_RESET; // Initialize the temperature sensors initTemperatureSensors(); // Persistent alarm for the temperature sensors range check initPersistentAlarm( ALARM_ID_DD_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE, 0, DIALYSATE_TEMP_SNSRS_OUT_OF_RANGE_TIMEOUT_MS ); } /*********************************************************************//** * @brief * The execTemperatureSensorsSelfTest function runs the TemperatureSensors * POST during the self-test. * @details \b Inputs: none * @details \b Outputs: none * @return tempSensorsSelfTestState which is the status of the self test *************************************************************************/ SELF_TEST_STATUS_T execTemperatureSensorsSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; //TODO: Uncomment below once Non volatile record is implemented. //BOOL calStatus = getNVRecord2Driver( GET_CAL_TEMP_SENSORS, (U08*)&tempSensorCalRecord, sizeof( DD_TEMP_SENSORS_CAL_RECORD_T ), // NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_DD_TEMPERATURE_SENSORS_INVALID_CAL_RECORD ); BOOL calStatus = TRUE; if ( TRUE == calStatus ) { result = SELF_TEST_STATUS_PASSED; } else { result = SELF_TEST_STATUS_FAILED; } return result; } /*********************************************************************//** * @brief * The execTemperatureSensors function executes the temperature sensors' * state machine. * @details \b Inputs: tempSensorsExecState * @details \b Outputs: tempSensorsExecState * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid temperature * sensor state is seen. * @return none *************************************************************************/ void execTemperatureSensors( void ) { // Check if a new calibration is available // if ( TRUE == isNewCalibrationRecordAvailable() ) // { // getNVRecord2Driver( GET_CAL_TEMP_SENSORS, (U08*)&tempSensorCalRecord, sizeof( DD_TEMP_SENSORS_CAL_RECORD_T ), // NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_DD_TEMPERATURE_SENSORS_INVALID_CAL_RECORD ); // } // Read the sensors all the time switch ( tempSensorsExecState ) { case TEMPSENSORS_EXEC_STATE_START: tempSensorsExecState = handleExecStart(); break; case TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES: tempSensorsExecState = handleExecGetADCValues(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE, tempSensorsExecState ); tempSensorsExecState = TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; break; } // Monitor the temperature values monitorTemperatureSenors(); //Update the timeinterval getTempMovingAverageTimeInterval(); // Filter D4/D50 temperature readings filterTemperatureReadings(); // Publish the data publishTemperatureSensorsData(); } /*********************************************************************//** * @brief * The handleExecStart function waits for a period of time and switches to * the state that reads the ADC values from FPGA. * @details \b Inputs: startTime * @details \b Outputs: startTime * @return the next state of the state machine *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecStart( void ) { TEMPSENSORS_EXEC_STATES_T state = TEMPSENSORS_EXEC_STATE_START; if ( 0 == startTime ) { startTime = getMSTimerCount(); } // A delay to let FPGA to boot up else if ( TRUE == didTimeout( startTime, ADC_FPGA_READ_DELAY ) ) { startTime = 0; state = TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; } return state; } /*********************************************************************//** * @brief * The handleExecGetADCValues function reads the ADC values from FPGA and * at the specified time intervals and calls required functions to calculate * the actual tempetature from the raw ADC values. * @details \b Inputs: FPGA * @details \b Outputs: temperature value. * @return the next state of the state machine *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ) { // Read temperature sensors readTemperatureSensors(); return TEMPSENSORS_EXEC_STATE_GET_ADC_VALUES; } /*********************************************************************//** * @brief * The filterTemperatureReadings function adds a new temperature sensor * sample to the filters. * @details \b Inputs: D4, D50,D78 and D99 Temperature * @details \b Outputs: d4TempSamplesC[], d4TempSamplesNextIndex, d4TempRunningSumC, * d4TempCount, d4TempAvgC, d50TempSamplesC, d50TempRunningSumC, d50TempSamplesNextIndex, * d50TempCount, d50TempAvgC, d99TempSamplesC, d99TempRunningSumC, d99TempSamplesNextIndex, * d99TempCount, d99TempAvgC, * @return none *************************************************************************/ static void filterTemperatureReadings( void ) { TEMPERATURE_SENSORS_T sensor; F32 rawTemp = 0.0F; if ( ++TempSampleIntervalCounter >= tempDataCollectionTimeInterval ) { for ( sensor = TEMPSENSORS_FIRST; sensor < NUM_OF_TEMPERATURE_SENSORS; sensor++ ) { rawTemp = getTemperatureValue ( sensor ); if ( filteredTemperatureReadings[ sensor ].temperatureReadingsCount >= TEMP_MOVING_AVG_NUM_OF_SAMPLES ) { filteredTemperatureReadings[ sensor ].temperatureReadingsTotal -= filteredTemperatureReadings[ sensor ].temperatureReadings[ filteredTemperatureReadings[ sensor ].temperatureReadingsIdx ]; } filteredTemperatureReadings[ sensor ].temperatureReadings[ filteredTemperatureReadings[ sensor ].temperatureReadingsIdx ] = rawTemp; filteredTemperatureReadings[ sensor ].temperatureReadingsTotal += rawTemp; filteredTemperatureReadings[ sensor ].temperatureReadingsIdx = INC_WRAP( filteredTemperatureReadings[ sensor ].temperatureReadingsIdx, 0, TEMP_MOVING_AVG_NUM_OF_SAMPLES - 1 ); filteredTemperatureReadings[ sensor ].temperatureReadingsCount = INC_CAP( filteredTemperatureReadings[ sensor ].temperatureReadingsCount, TEMP_MOVING_AVG_NUM_OF_SAMPLES ); filteredcurrentTemperatureReadings[ sensor ].data = filteredTemperatureReadings[ sensor ].temperatureReadingsTotal / (F32)filteredTemperatureReadings[ sensor ].temperatureReadingsCount; } TempSampleIntervalCounter = 0; } // dailysate temperature moving average filterDialTemperatureReadings(); } /*********************************************************************//** * @brief * The filterDialTemperatureReadings function adds a new dialysate temperature * sensor sample to the filters. * @details \b Inputs: dialysate temperature * @details \b Outputs: dialTempMovingAvgData[] * @return none *************************************************************************/ static void filterDialTemperatureReadings( void ) { DIAL_TEMPERATURE_SENSORS_T i; F32 temperatureC = 0.0F; U32 currentIndex = 0; F32 prevSampleToRemoveC = 0.0f; for ( i = DIAL_TEMP_FIRST; i < NUM_OF_DIAL_TEMPS; i++ ) { if ( FALSE == dialTempMovingAvgData[ i ].dialTempColHasTimerBeenSet ) { dialTempMovingAvgData[ i ].dialTempDataColStartTimeMS = getMSTimerCount(); dialTempMovingAvgData[ i ].dialTempColHasTimerBeenSet = TRUE; } else if ( TRUE == didTimeout( dialTempMovingAvgData[ i ].dialTempDataColStartTimeMS, D28_D30_DATA_COLLECTION_TIME_MS ) ) { CONDUCTIVITY_SENSORS_T sensor = ( DIAL_TEMP_D28 == i ? D27_COND : D29_COND ); if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) != TRUE ) { temperatureC = getTeensyConductivityTemperatureValue( sensor ); } else { temperatureC = getConductivityTemperature( sensor ); } currentIndex = dialTempMovingAvgData[ i ].dialTempSamplesNextIndex; prevSampleToRemoveC = dialTempMovingAvgData[ i ].dialTempSamplesC[ currentIndex ]; dialTempMovingAvgData[ i ].dialTempDataColStartTimeMS = getMSTimerCount(); dialTempMovingAvgData[ i ].dialTempColHasTimerBeenSet = TRUE; dialTempMovingAvgData[ i ].dialTempSamplesC[ currentIndex ] = temperatureC; dialTempMovingAvgData[ i ].dialTempRunningSumC = dialTempMovingAvgData[ i ].dialTempRunningSumC + temperatureC - prevSampleToRemoveC; dialTempMovingAvgData[ i ].dialTempSamplesNextIndex = INC_WRAP( dialTempMovingAvgData[ i ].dialTempSamplesNextIndex, 0, DIAL_TEMP_MOVING_AVG_NUM_OF_SAMPLES - 1 ); dialTempMovingAvgData[ i ].dialTempAvgC = dialTempMovingAvgData[ i ].dialTempRunningSumC / (F32)DIAL_TEMP_MOVING_AVG_NUM_OF_SAMPLES; } } } /*********************************************************************//** * @brief * The checkDialysateTemperatureSensors function checks whether the * dialysate temperature sensors have drifted. If they are drifted, it raises * an alarm. * @details \b Inputs: dialysate temperature * @details \b Outputs: None * @return none *************************************************************************/ void checkDialysateTemperatureSensors( void ) { DD_OP_MODE_T op = getCurrentOperationMode(); if ( ( DD_MODE_GEND == op ) || ( DD_MODE_HEAT == op ) ) { F32 d28Temp = dialTempMovingAvgData[ DIAL_TEMP_D28 ].dialTempAvgC; F32 d30Temp = dialTempMovingAvgData[ DIAL_TEMP_D30 ].dialTempAvgC; F32 driftC = ( DD_MODE_HEAT == op ? D28_D30_TEMP_SENSORS_MAX_DEVIATION_IN_HEAT_DIS_C : D28_D30_TEMP_SENSORS_MAX_DEVIATION_C ); BOOL isDriftOut = ( fabs( d28Temp - d30Temp ) > driftC ? TRUE : FALSE ); checkPersistentAlarm( ALARM_ID_DD_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE, isDriftOut, fabs( d28Temp - d30Temp ), driftC ); if ( ( FALSE == tempDriftEventCheck ) && ( TRUE == isDriftOut ) ) { // Send event only condition trigger, not continuously. tempDriftEventCheck = TRUE; SEND_EVENT_WITH_2_U32_DATA(DD_EVENT_TEMPERATURE_DRIFT, d28Temp, d30Temp) } if ( ( TRUE == tempDriftEventCheck ) && ( FALSE == isDriftOut ) ) { tempDriftEventCheck = FALSE; } } } /*********************************************************************//** * @brief * The getD4AverageTemperature function returns the average temperature * for D4 temp sensor. * @details \b Inputs: filteredcurrentTemperatureReadings * @details \b Outputs: none * @return the D4 average temperature *************************************************************************/ F32 getD4AverageTemperature( void ) { F32 temperature = getF32OverrideValue( &filteredcurrentTemperatureReadings[ D4_TEMP ] ); return temperature; } /*********************************************************************//** * @brief * The getD50AverageTemperature function returns the average temperature * for D50 temp sensor. * @details \b Inputs: filteredcurrentTemperatureReadings * @details \b Outputs: none * @return the D50 average temperature *************************************************************************/ F32 getD50AverageTemperature( void ) { F32 temperature = getF32OverrideValue( &filteredcurrentTemperatureReadings[ D50_TEMP ] ); return temperature; } /*********************************************************************//** * @brief * The getD99AverageTemperature function returns the average temperature * for D99 temperature sensor. * @details \b Inputs: filteredcurrentTemperatureReadings * @details \b Outputs: none * @return the D99 average temperature *************************************************************************/ F32 getD99AverageTemperature( void ) { F32 temperature = getF32OverrideValue( &filteredcurrentTemperatureReadings[ D99_TEMP ] ); return temperature; } /*********************************************************************//** * @brief * The getD78AverageTemperature function returns the average temperature * for D78 temperature sensor. * @details \b Inputs: filteredcurrentTemperatureReadings * @details \b Outputs: none * @return the D78 average temperature *************************************************************************/ F32 getD78AverageTemperature( void ) { F32 temperature = getF32OverrideValue( &filteredcurrentTemperatureReadings[ D78_TEMP ] ); return temperature; } /*********************************************************************//** * @brief * The getTempMovingAverageTimeInterval function calculates the temperature * interval used for sample collection based on the dialysate flow rate, * to find the average value. * @details \b Inputs: dialysate flow rate * @details \b Outputs: none * @return the temperature interval for sample collection in task interval *************************************************************************/ static void getTempMovingAverageTimeInterval( void ) { F32 period = (F32)SEC_PER_MIN / ( getTDDialysateFlowrate() / BAL_CHAMBER_FILL_VOLUME_ML ) ; U32 sampleInterval = (U32)( ( period / (F32)TEMP_MOVING_AVG_NUM_OF_SAMPLES ) * MS_PER_SECOND ); tempDataCollectionTimeInterval = (U32) ( sampleInterval / TASK_PRIORITY_INTERVAL ); } /*********************************************************************//** * @brief * The publishTemperatureSensorsData function broadcasts the * temperature sensors data at the publication interval. * @details \b Inputs: ddTempDataPublicationTimerCounter * fpTempDataPublicationTimerCounter and publish interval time. * @details \b Outputs: ddTempDataPublicationTimerCounter, fpTempDataPublicationTimerCounter * @details \b Message \b Sent: MSG_ID_DD_TEMPERATURE_DATA, MSG_ID_FP_TEMPERATURE_DATA * publishes the temperature data in a periodic interval. * @return none *************************************************************************/ static void publishTemperatureSensorsData( void ) { // publish DD temperature data on interval if ( ++ddTempDataPublicationTimerCounter >= getU32OverrideValue( &ddTempSensorsPublishInterval ) ) { TEMPERATURE_SENSORS_DD_DATA_T data; data.d1Temp = getTemperatureValue( D1_TEMP ); data.d78Temp = getTemperatureValue( D78_TEMP ); data.d4Temp = getTemperatureValue( D4_TEMP ); data.d50Temp = getTemperatureValue( D50_TEMP ); data.d99Temp = getTemperatureValue( D99_TEMP ); data.boardTemp = getTemperatureValue( BRD_TEMP ); if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_2_0_HW ) != TRUE ) { data.d16CondTemp = getTeensyConductivityTemperatureValue( D17_COND ); data.d28CondTemp = getTeensyConductivityTemperatureValue( D27_COND ); data.d30CondTemp = getTeensyConductivityTemperatureValue( D29_COND ); data.d44CondTemp = getTeensyConductivityTemperatureValue( D43_COND ); data.d75CondTemp = getTeensyConductivityTemperatureValue( D74_COND ); } else { data.d16CondTemp = getConductivityTemperature( D17_COND ); data.d28CondTemp = getConductivityTemperature( D27_COND ); data.d30CondTemp = getConductivityTemperature( D29_COND ); data.d44CondTemp = getConductivityTemperature( D43_COND ); data.d75CondTemp = getConductivityTemperature( D74_COND ); } data.d4AvgTemp = getD4AverageTemperature(); data.d50AvgTemp = getD50AverageTemperature(); data.d99AvgTemp = getD99AverageTemperature(); data.d28AvgTemp = dialTempMovingAvgData[ DIAL_TEMP_D28 ].dialTempAvgC; data.d30AvgTemp = dialTempMovingAvgData[ DIAL_TEMP_D30 ].dialTempAvgC; data.d78AvgTemp = getD78AverageTemperature(); data.d9PresTemp = getFilteredPressureSensorTemperature( D9_PRES ); data.d66PresTemp = getFilteredPressureSensorTemperature( D66_PRES ); data.d51PresTemp = getFilteredPressureSensorTemperature( D51_PRES ); data.d18PresTemp = getFilteredPressureSensorTemperature( D18_PRES ); data.d41PresTemp = getFilteredPressureSensorTemperature( D41_PRES ); data.d87PresTemp = getFilteredPressureSensorTemperature( D87_PRES ); broadcastData( MSG_ID_DD_TEMPERATURE_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( TEMPERATURE_SENSORS_DD_DATA_T ) ); ddTempDataPublicationTimerCounter = 0; } // publish FP temperature data on interval if ( ++fpTempDataPublicationTimerCounter >= getU32OverrideValue( &fpTempSensorsPublishInterval ) ) { TEMPERATURE_SENSORS_FP_DATA_T data; data.m3Temp = getFilteredPressureSensorTemperature( M3_PRES ); data.p8Temp = getFilteredPressureSensorTemperature( P8_PRES ); data.p13Temp = getFilteredPressureSensorTemperature( P13_PRES ); data.p17Temp = getFilteredPressureSensorTemperature( P17_PRES ); data.p46Temp = getFilteredPressureSensorTemperature( P46_PRES ); data.p10Temp = getFilteredConductivitySensorTemperature( P9_COND ); data.p19Temp = getFilteredConductivitySensorTemperature( P18_COND ); data.p7Temp = getFilteredFlowSensorTemperature( P7_FLOW ); data.p16Temp = getFilteredFlowSensorTemperature( P16_FLOW ); data.p7InternalTemp = getFlowInternalTemperature( P7_FLOW ); data.p16InternalTemp = getFlowInternalTemperature( P16_FLOW ); broadcastData( MSG_ID_FP_TEMPERATURE_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( TEMPERATURE_SENSORS_FP_DATA_T ) ); fpTempDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testDDTemperatureSensorsDataPublishIntervalOverride function * overrides the DD temperature sensor data publish interval. * @details \b Inputs: none * @details \b Outputs: ddTempSensorsPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the DD temperature sensor data broadcast interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDDTemperatureSensorsDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &ddTempSensorsPublishInterval, TASK_PRIORITY_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testDDTemperatureSensorFilteredReadingsOverride function overrides the * filtered value of the specified DD temperature sensor with a given value. * @details \b Inputs: none * @details \b Outputs: filteredcurrentTemperatureReadings[] * @param message Override message from Dialin which includes a sensor * ID and override value of the temperature value for that sensor. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDDTemperatureSensorFilteredReadingsOverride( MESSAGE_T *message ) { BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &payload ); if ( payload.index <= NUM_OF_TEMPERATURE_SENSORS ) { result = f32ArrayOverride( message, &filteredcurrentTemperatureReadings[0], NUM_OF_TEMPERATURE_SENSORS - 1 ); } return result; } /*********************************************************************//** * @brief * The testIOFPTemperatureSensorsDataPublishIntervalOverride function * overrides the IOFP temperature sensors data publish interval. * @details \b Inputs: none * @details \b Outputs: fpTempSensorsPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the IOFP temperature sensor data broadcast interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testIOFPTemperatureSensorsDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &fpTempSensorsPublishInterval, TASK_PRIORITY_INTERVAL ); return result; } /**@}*/