Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r94dab74a6432263dc4569e0cf8f9fa0b01bf1917 -r80a6638b362f5f613c0665200023d181f614d1bc --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 94dab74a6432263dc4569e0cf8f9fa0b01bf1917) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 80a6638b362f5f613c0665200023d181f614d1bc) @@ -26,6 +26,7 @@ #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "PersistentAlarm.h" +#include "SystemComm.h" #include "SystemCommMessages.h" #include "Timers.h" @@ -41,30 +42,36 @@ #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. -#define DIALYSATE_TEMP_PERSISTENCE_PERIOD ( 3 * MS_PER_SECOND ) ///< Persistence period for dialysate temperature alarm. +#define DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C 2.0F ///< Dialysate temperature out of target tolerance C. +#define DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ( 300 * MS_PER_SECOND ) ///< Dialysate temperature out of target timeout in milliseconds. +#define DIALYSATE_TEMP_HIGH_SAFETY_LIMIT_C 46.0F ///< Dialysate high safety temperature limit in C. +#define DIALYSATE_TEMP_HIGH_SAFETY_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Dialysate temperature high safety timeout in milliseconds. +#define DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C 42.0F ///< Dialysate low safety temperature limit in C. +#define DIALYSATE_TEMP_LOW_SAFETY_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature low safety timeout in milliseconds. -#define DIALYSATE_TEMP_RECOVERY_TOLERANCE_C 2.0F ///< Dialysate temperature recovery tolerance in degree C. -#define DIALYSATE_TEMP_TOLERANCE_C 4.0F ///< Dialysate temperature tolerance in degree C. -#define DIALYSATE_TEMP_HIGH_LIMIT_C 42.0F ///< Dialysate high temperature limit in degree C. -#define DIALYSATE_TEMP_LOW_LIMIT_C 33.0F ///< Dialysate low temperature limit in degree C. +#define LOAD_CELL_DATA_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Load cell freshness timeout (in ms). // ********** private data ********** +static const U32 DIP_LOAD_CELL_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIP_TEMPERATURE_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIP_RESERVOIRS_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIP_DG_OP_MODE_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); // DG status -static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; ///< Current DG operation mode. -static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. -static BOOL dgStartCommandSent = FALSE; ///< Flag indicates command to start DG has been sent. -static BOOL dgStarted = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop. -static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. +static DG_OP_MODE_T dgCurrentOpMode; ///< Current DG operation mode. +static U32 dgSubMode; ///< Current state (sub-mode) of current DG operation mode. +static BOOL dgStartCommandSent; ///< Flag indicates command to start DG has been sent. +static BOOL dgStarted; ///< Flag indicates whether we have commanded the DG to start or stop. +static BOOL dgTrimmerHeaterOn; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. // State machine states static U32 timeStartMS = 0; // TODO is this needed? // DG sensor data -static F32 dgDialysateTemp = 0.0; ///< Dialysate temperature reported by the DG. +static F32 dgDialysateTemp; ///< Dialysate temperature reported by the DG. static F32 dgRedundantDialysateTemp = 0.0; ///< Redundant dialysate temperature reported by the DG. static F32 dgPrimaryTemp = 0.0; ///< Latest RO water temperature reported by the DG. -static F32 dgTrimmerTempSet = 0.0; ///< Trimmer heater target temperature commanded. +static F32 dgTrimmerTempSet; ///< Trimmer heater target temperature commanded. static F32 dgTrimmerTemp = 0.0; ///< Latest dialysate temperature reported by the DG. /// Measured weight from load cells. @@ -83,10 +90,18 @@ // DG Dialysate flow rate static F32 dgDialysateFlowRateMlMin = 0.0; ///< Latest dialysate flow rate reported by the DG. static BOOL dgDialysateFlowDataFreshFlag = FALSE; ///< Flag to signal the execDialInFlowMonitor() to process fresh flow rate data +static BOOL dgLoadCellDataFreshFlag = FALSE; ///< Flag to signal the handleLoadCellReadingsFromDG() to process fresh load cell data +static BOOL dgDialysateTemperatureDataFreshFlag = FALSE; ///< Flag to signal the handleTemperatureReadingsFromDG() to process fresh temperature data +static BOOL dgReservoirsDataFreshFlag = FALSE; ///< Flag to signal the handleDGReservoirData() to process fresh reservoirs data +static BOOL dgOpModeDataFreshFlag = FALSE; ///< Flag to signal the handleDGOpMode() to process fresh dg op mode data +static U32 loadcellDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh load cell data message is received +static U32 temperatureDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh temperature data message is received +static U32 reservoirsDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh reservoirs data message is received +static U32 dgOpModeDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh dg op mode data message is received // Reservoir data -static DG_RESERVOIR_ID_T dgActiveReservoir = DG_RESERVOIR_2; ///< Latest active reservoir reported by the DG. -static DG_RESERVOIR_ID_T dgActiveReservoirSet = DG_RESERVOIR_2; ///< Active reservoir commanded. +static DG_RESERVOIR_ID_T dgActiveReservoir; ///< Latest active reservoir reported by the DG. +static DG_RESERVOIR_ID_T dgActiveReservoirSet; ///< Active reservoir commanded. // TODO remove below variables static U32 dgReservoirFillVolumeTarget = 0; ///< Latest fill-to volume reported by the DG. @@ -96,13 +111,15 @@ static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. static DG_MIXING_RATIOS_T dgMixingRatios; ///< DG mixing ratios. +static HEATERS_DATA_T dgHeatersData; ///< DG heaters data. // DG command response static DG_CMD_RESPONSE_T dgCmdResp[ NUM_OF_DG_COMMANDS ]; ///< Keep the latest DG command response for each command. // ********** private function prototypes ********** static void checkDGRestart( void ); +static void checkDGTrimmerHeaterStatus( void ); /*********************************************************************//** * @brief @@ -115,29 +132,37 @@ { U32 i, j; - dgStarted = FALSE; - dgTrimmerHeaterOn = FALSE; - dgTrimmerTempSet = 0.0; - dgActiveReservoirSet = DG_RESERVOIR_2; - dgReservoirFillVolumeTargetSet = 0; + dgStarted = FALSE; + dgTrimmerHeaterOn = FALSE; + dgTrimmerTempSet = 0.0F; + dgActiveReservoirSet = DG_RESERVOIR_2; + dgActiveReservoir = DG_RESERVOIR_2; + dgReservoirFillVolumeTargetSet = 0; dgReservoirDrainVolumeTargetSet = 0; + dgDialysateTemp = 0.0F; + dgCurrentOpMode = DG_MODE_INIT; + dgSubMode = 0; + dgStartCommandSent = FALSE; + dgDialysateFlowRateMlMin = 0.0F; + dgDialysateFlowDataFreshFlag = FALSE; // initialize load cell weights for ( i = 0; i < NUM_OF_LOAD_CELLS; i++ ) { - loadCellWeightInGrams[ i ].data = 0.0; - loadCellWeightInGrams[ i ].ovInitData = 0.0; - loadCellWeightInGrams[ i ].ovData = 0.0; - loadCellWeightInGrams[ i ].override = 0; + loadCellWeightInGrams[ i ].data = 0.0F; + loadCellWeightInGrams[ i ].ovInitData = 0.0F; + loadCellWeightInGrams[ i ].ovData = 0.0F; + loadCellWeightInGrams[ i ].override = 0; } // initialize reservoirs weights for ( i = 0; i < NUM_OF_DG_RESERVOIRS; i++ ) { - lgFilteredReservoirWeightInGrams[ i ] = 0.0; + lgFilteredReservoirWeightInGrams[ i ] = 0.0F; + for ( j = 0; j < SIZE_OF_LARGE_LOAD_CELL_AVG; j++ ) { - lgLoadCellReadings[ i ][ j ] = 0.0; - lgLoadCellBackupReadings[ i ][ j ] = 0.0; + lgLoadCellReadings[ i ][ j ] = 0.0F; + lgLoadCellBackupReadings[ i ][ j ] = 0.0F; } } @@ -149,15 +174,53 @@ dgCmdResp[ i ].rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; } - lgLoadCellReadingsIdx = 0; - lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; - lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; - lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; - lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; + lgLoadCellReadingsIdx = 0; + lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0F; + lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0F; + lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_1 ] = 0.0F; + lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_2 ] = 0.0F; - initPersistentAlarm( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, DIALYSATE_TEMP_PERSISTENCE_PERIOD, DIALYSATE_TEMP_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, DIALYSATE_TEMP_PERSISTENCE_PERIOD, DIALYSATE_TEMP_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_HIGH_SAFETY_RANGE, DIALYSATE_TEMP_HIGH_SAFETY_TIMEOUT_MS, DIALYSATE_TEMP_HIGH_SAFETY_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_LOW_SAFETY_RANGE, DIALYSATE_TEMP_LOW_SAFETY_TIMEOUT_MS, DIALYSATE_TEMP_LOW_SAFETY_TIMEOUT_MS ); + + initPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ); + + initPersistentAlarm( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE, LOAD_CELL_DATA_TIMEOUT_MS, LOAD_CELL_DATA_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_NEW_DIALYSATE_TEMPERATURE_DATA_MESSAGE_NOT_RECEIVE, LOAD_CELL_DATA_TIMEOUT_MS, LOAD_CELL_DATA_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_NEW_RESERVOIRS_DATA_MESSAGE_NOT_RECEIVE, LOAD_CELL_DATA_TIMEOUT_MS, LOAD_CELL_DATA_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_NEW_DG_OPERATION_MODE_MESSAGE_NOT_RECEIVE, LOAD_CELL_DATA_TIMEOUT_MS, LOAD_CELL_DATA_TIMEOUT_MS ); } + +/**********************************************************************//** + * @brief + * The checkDGDataFreshness function checks the condition + * for triggering an alarm if the DG fresh data is not received for 2 seconds. + * @details Inputs: none + * @details Outputs: an alarm is triggered or an alarm condition is cleared + * @param alarm ID of alarm to check + * @param flag to signal the fresh data processing + * @return None + *************************************************************************/ +void checkDGDataFreshness( ALARM_ID_T alarmID, BOOL *dgFreshDataFlag ) +{ + if ( TRUE == *dgFreshDataFlag ) + { + *dgFreshDataFlag = FALSE; + checkPersistentAlarm( alarmID, FALSE, 0.0, 0.0 ); + } + else + { // Alarm if not receiving DG fresh data message in timely manner + if ( TRUE == isDGCommunicating() ) + { + checkPersistentAlarm( alarmID, TRUE, 0.0, 0.0 ); + } + else + { + checkPersistentAlarm( alarmID, FALSE, 0.0, 0.0 ); + } + } +} /*********************************************************************//** * @brief @@ -169,10 +232,24 @@ *************************************************************************/ void execDGInterfaceMonitor( void ) { - // TODO - make sure DG sensor/state data is coming in timely manner (e.g. load cells s/b every 100 ms) + // Trigger alarm if not receiving new load cell data message in timely manner + /*checkDGDataFreshness( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE, &dgLoadCellDataFreshFlag ); - // Check to see if DG has restarted + // Trigger alarm if not receiving new dialysate temperature data message in timely manner + checkDGDataFreshness( ALARM_ID_HD_NEW_DIALYSATE_TEMPERATURE_DATA_MESSAGE_NOT_RECEIVE, &dgDialysateTemperatureDataFreshFlag ); + + // Trigger alarm if not receiving new reservoirs data message in timely manner + checkDGDataFreshness( ALARM_ID_HD_NEW_RESERVOIRS_DATA_MESSAGE_NOT_RECEIVE, &dgReservoirsDataFreshFlag ); + + // Trigger alarm if not receiving new reservoirs data message in timely manner + checkDGDataFreshness( ALARM_ID_HD_NEW_DG_OPERATION_MODE_MESSAGE_NOT_RECEIVE, &dgOpModeDataFreshFlag ); + + // Check to see if DG has restarted*/ + checkDGRestart(); + + // Check the status of the trimmer heater + checkDGTrimmerHeaterStatus(); } /*********************************************************************//** @@ -282,6 +359,74 @@ return result; } + +/*********************************************************************//** + * @brief + * The getLoadCellDataFreshFlag function returns a flag to indicate + * if the load cell data message reported by the DG is fresh or stale data. + * @details Inputs: dgLoadCellDataFreshFlag + * @details Outputs: dgLoadCellDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getLoadCellDataFreshFlag( void ) +{ + BOOL result = dgLoadCellDataFreshFlag; + + dgLoadCellDataFreshFlag = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getTemperatureDataFreshFlag function returns a flag to indicate + * if the temperature data message reported by the DG is fresh or stale data. + * @details Inputs: dgDialysateTemperatureDataFreshFlag + * @details Outputs: dgDialysateTemperatureDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getTemperatureDataFreshFlag( void ) // DN-19AUG2022 +{ + BOOL result = dgDialysateTemperatureDataFreshFlag; + + dgDialysateTemperatureDataFreshFlag = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getReservoirsDataFreshFlag function returns a flag to indicate + * if the reservoirs data message reported by the DG is fresh or stale data. + * @details Inputs: dgReservoirsDataFreshFlag + * @details Outputs: dgReservoirsDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getReservoirsDataFreshFlag( void ) // DN-22AUG2022 +{ + BOOL result = dgReservoirsDataFreshFlag; + + dgReservoirsDataFreshFlag = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getDGOpModeDataFreshFlag function returns a flag to indicate + * if the dg op mode data message reported by the DG is fresh or stale data. + * @details Inputs: dgOpModeDataFreshFlag + * @details Outputs: dgOpModeDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getDgOpModeDataFreshFlag( void ) // DN-22AUG2022 +{ + BOOL result = dgOpModeDataFreshFlag; + + dgOpModeDataFreshFlag = FALSE; + + return result; +} /*********************************************************************//** * @brief @@ -358,26 +503,26 @@ /*********************************************************************//** * @brief - * The getDialysateTemperature function gets the latest dialysate temperature. - * @details Inputs: dgDialysateTemp + * The getDGDisinfectsStates function returns the DG disinfects readings. + * @details Inputs: none * @details Outputs: none - * @return the current dialysate temperature + * @return the current DG disinfects readings *************************************************************************/ -F32 getDialysateTemperature( void ) +DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) { - return dgDialysateTemp; + return disinfectsStatus; } /*********************************************************************//** * @brief - * The getDGDisinfectsStates function returns the DG disinfects readings. - * @details Inputs: none + * The getDialysateTemperature function gets the latest dialysate temperature. + * @details Inputs: dgDialysateTemp * @details Outputs: none - * @return the current DG disinfects readings + * @return the current dialysate temperature *************************************************************************/ -DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) +F32 getDialysateTemperature( void ) { - return disinfectsStatus; + return dgDialysateTemp; } /*********************************************************************//** @@ -420,7 +565,7 @@ * @return none *************************************************************************/ void setDGOpMode( U32 opMode, U32 subMode ) -{ +{ if ( opMode < NUM_OF_DG_MODES ) { dgCurrentOpMode = (DG_OP_MODE_T)opMode; @@ -429,7 +574,9 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_OPERATING_MODE, opMode ); - } + } + + dgOpModeDataFreshFlag = TRUE; } /*********************************************************************//** @@ -443,9 +590,11 @@ * @return none *************************************************************************/ void setDialysateTemperatureReadings( F32 temp1, F32 temp2 ) -{ - dgDialysateTemp = temp1; - dgRedundantDialysateTemp = temp2; +{ + dgDialysateTemp = temp1; + dgRedundantDialysateTemp = temp2; + + dgDialysateTemperatureDataFreshFlag = TRUE; } /*********************************************************************//** @@ -460,7 +609,7 @@ * @return none *************************************************************************/ void setDGReservoirsData( DG_RESERVOIR_ID_T resID, U32 fillVol, U32 drainVol ) -{ +{ if ( resID < NUM_OF_DG_RESERVOIRS ) { dgActiveReservoir = resID; @@ -470,7 +619,9 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, resID ); - } + } + + dgReservoirsDataFreshFlag = TRUE; } /*********************************************************************//** @@ -538,6 +689,8 @@ // Update Dialysis sub-mode with new reservoir volumes updateReservoirVolumes( res1Primary, res2Primary ); + + dgLoadCellDataFreshFlag = TRUE; } /*********************************************************************//** @@ -565,9 +718,22 @@ *************************************************************************/ void setDGMixingRatios( DG_MIXING_RATIOS_T ratios ) { - memcpy( &dgMixingRatios, &ratios, sizeof(DG_MIXING_RATIOS_T) ); + memcpy( &dgMixingRatios, &ratios, sizeof( DG_MIXING_RATIOS_T ) ); } +/*********************************************************************//** + * @brief + * The setDGHeatersData function sets heaters data that has been read from DG. + * @details Inputs: none + * @details Outputs: dgHeatersData + * @param data which is a pointer to the received heaters data + * @return none + *************************************************************************/ +void setDGHeatersData( HEATERS_DATA_T *data ) +{ + memcpy( &dgHeatersData, data, sizeof( HEATERS_DATA_T ) ); +} + /*********************************************************************//** * @brief * The cmdSetDGDialysateHeatingParams function sends the dialysate heating @@ -627,7 +793,7 @@ dgTrimmerHeaterOn = TRUE; dgCmdResp[ DG_CMD_START_TRIMMER_HEATER ].commandID = DG_CMD_NONE; - sendDGStartStopTrimmerHeaterCommand( START_DG_CMD, dgTrimmerTempSet ); + sendDGStartStopTrimmerHeaterCommand( START_DG_CMD ); } /*********************************************************************//** @@ -643,7 +809,7 @@ dgTrimmerHeaterOn = FALSE; dgCmdResp[ DG_CMD_STOP_TRIMMER_HEATER ].commandID = DG_CMD_NONE; - sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD, 0 ); + sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD ); } /*********************************************************************//** @@ -950,43 +1116,28 @@ * @brief * The checkDialysateTemperature function checks the dialysate temperature * reported by DG and alarm if temperature is out of range. - * @details Inputs: dgTrimmerTempSet, dgDialysateTemp, dgRedundantDialysateTemp - * @details Outputs: alarm if dialysate temperature is out of accepted range + * @details Inputs: dgTrimmerTempSet, dgDialysateTemp + * @details Outputs: none * @return none *************************************************************************/ void checkDialysateTemperature( void ) { - BOOL const dialysateHighTemp = ( ( ( dgDialysateTemp - dgTrimmerTempSet ) > DIALYSATE_TEMP_TOLERANCE_C ) || - ( dgDialysateTemp > DIALYSATE_TEMP_HIGH_LIMIT_C ) ); + BOOL isTDiTempAboveHighSafety = ( dgDialysateTemp >= DIALYSATE_TEMP_HIGH_SAFETY_LIMIT_C ? TRUE : FALSE ); + BOOL isTDiTempAboveLowSafety = ( dgDialysateTemp >= DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C ? TRUE : FALSE ); + F32 TDiHigh = dgTrimmerTempSet + DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C; + BOOL isTDiTempAboveDialysateTarget = ( TDiHigh >= dgDialysateTemp ? TRUE : FALSE ); + F32 TDiLow = dgTrimmerTempSet - DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C; + BOOL isTDiTempBelowDialysateTarget = ( TDiLow >= dgDialysateTemp ? TRUE : FALSE ); - BOOL const dialysateLowTemp = ( ( ( dgTrimmerTempSet - dgDialysateTemp ) > DIALYSATE_TEMP_TOLERANCE_C ) || - ( dgDialysateTemp < DIALYSATE_TEMP_LOW_LIMIT_C ) ); - - BOOL const dialysateTempRecovered = fabs( dgDialysateTemp - dgTrimmerTempSet ) < DIALYSATE_TEMP_RECOVERY_TOLERANCE_C ? TRUE : FALSE; - #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DIALYSATE_TEMP_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dgTrimmerTempSet, dgDialysateTemp ); - } + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_HIGH_SAFETY_RANGE, isTDiTempAboveHighSafety, dgDialysateTemp, DIALYSATE_TEMP_HIGH_SAFETY_LIMIT_C ); + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_LOW_SAFETY_RANGE, isTDiTempAboveLowSafety, dgDialysateTemp, DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C ); - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateLowTemp ) ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dgTrimmerTempSet, dgDialysateTemp ); - } - - if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) - { - clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH ); - } - - if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateTempRecovered ) ) - { - clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_LOW ); - } + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, isTDiTempAboveDialysateTarget, dgDialysateTemp, TDiHigh ); + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, isTDiTempBelowDialysateTarget, dgDialysateTemp, TDiLow ); } } @@ -1018,7 +1169,29 @@ } } +/*********************************************************************//** + * @brief + * The checkDGTrimmerHeaterStatus function checks to see the status of the + * trimmer heater and set them according to the status of the trimmer heater flag. + * @details Inputs: dgTrimmerHeaterOn + * @details Outputs: none + * @return none + *************************************************************************/ +static void checkDGTrimmerHeaterStatus( void ) +{ + U32 trimmerState = dgHeatersData.trimmerHeaterState; + if ( ( TRUE == dgTrimmerHeaterOn ) && ( HEATER_EXEC_STATE_OFF == trimmerState ) ) + { + cmdStartDGTrimmerHeater(); + } + else if ( ( FALSE == dgTrimmerHeaterOn ) && ( trimmerState != HEATER_EXEC_STATE_OFF ) ) + { + cmdStopDGTrimmerHeater(); + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/