Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r981de1f5228152ec6877aceae3d66ebf5efc7101 -r78cee9347b3766ac7c14d413ed848be758c7e9cd --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 981de1f5228152ec6877aceae3d66ebf5efc7101) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 78cee9347b3766ac7c14d413ed848be758c7e9cd) @@ -16,13 +16,15 @@ ***************************************************************************/ #include "DialInFlow.h" +#include "Dialysis.h" #include "DGDefs.h" +#include "DGInterface.h" #include "ModeInitPOST.h" -#include "ModeTreatment.h" +#include "ModeTreatment.h" +#include "ModeTreatmentParams.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "Timers.h" -#include "DGInterface.h" /** * @addtogroup DGInterface @@ -36,7 +38,8 @@ #define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). -#define SIZE_OF_SMALL_LOAD_CELL_AVG 8 ///< Small load cell moving average has 8 samples. +#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. + #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. /// States of the treatment reservoir management state machine. @@ -49,18 +52,18 @@ TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE, ///< Wait for fill to complete. TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE, ///< Wait a bit for filled reservoir to settle before getting baseline weight (volume). TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE, ///< Wait for active reservoir to be consumed and switch cmd given - then back to flush DG lines state. - TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE, ///< Wait for inactive reservoir to settle before getting final weight (volume) before starting to drain. + TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE, ///< Wait for inactive reservoir to settle before getting final weight (volume) before starting to drain. NUM_OF_TREATMENT_RESERVOIR_MGMT_STATES ///< Number of treatment reservoir mgmt. states. } TREATMENT_RESERVOIR_MGMT_STATE_T; // ********** private data ********** // 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 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 BOOL dgWaterSampled = FALSE; ///< Flag indicates whether we have commanded the DG to sample water. // State machine states /// Current state of treatment mode reservoir management. @@ -78,16 +81,10 @@ /// Measured weight from load cells. static OVERRIDE_F32_T loadCellWeightInGrams[ NUM_OF_LOAD_CELLS ]; -/// Filtered (8 sample) weight of reservoirs. -static F32 smFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; /// Filtered (32 sample) weight of reservoirs. static F32 lgFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; // Load cell filtering data -/// Holds load cell samples for small load cell moving average. -static F32 smLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_SMALL_LOAD_CELL_AVG ]; -static U32 smLoadCellReadingsIdx = 0; ///< Index for next sample in small load cell rolling average sample array. -static F32 smLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc small load cell moving average. /// Holds load cell samples for large load cell moving average. static F32 lgLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; static U32 lgLoadCellReadingsIdx = 0; ///< Index for next sample in large load cell rolling average sample array. @@ -107,13 +104,15 @@ static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. static U32 resUseTimer = 0; ///< Used to track time pumping from active reservoir (for volume used calculation). static F32 resUseVolumeMl = 0.0; ///< Accumulated volume used from active reservoir. +static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. // 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 ); - /*********************************************************************//** * @brief * The initDGInterface function initializes the DGInterface module. @@ -127,7 +126,6 @@ dgStarted = FALSE; dgTrimmerHeaterOn = FALSE; - dgWaterSampled = FALSE; dgPrimaryTempSet = 0.0; dgTrimmerTempSet = 0.0; dgActiveReservoirSet = DG_RESERVOIR_2; @@ -145,12 +143,7 @@ // initialize reservoirs weights for ( i = 0; i < NUM_OF_DG_RESERVOIRS; i++ ) { - smFilteredReservoirWeightInGrams[ i ] = 0.0; lgFilteredReservoirWeightInGrams[ i ] = 0.0; - for ( j = 0; j < SIZE_OF_SMALL_LOAD_CELL_AVG; j++ ) - { - smLoadCellReadings[ i ][ j ] = 0.0; - } for ( j = 0; j < SIZE_OF_LARGE_LOAD_CELL_AVG; j++ ) { lgLoadCellReadings[ i ][ j ] = 0.0; @@ -165,9 +158,6 @@ dgCmdResp[ i ].rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; } - smLoadCellReadingsIdx = 0; - smLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; - smLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; lgLoadCellReadingsIdx = 0; lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; @@ -184,6 +174,9 @@ void execDGInterfaceMonitor( void ) { // TODO - make sure DG sensor/state data is coming in timely manner (e.g. load cells s/b every 100 ms) + + // Check to see if DG has restarted + checkDGRestart(); } @@ -201,6 +194,19 @@ resMgmtTimer = 0; resUseTimer = getMSTimerCount(); resUseVolumeMl = 0.0; +} + +/*********************************************************************//** + * @brief + * The dialysisResumed function initializes the reservoir re-use timer + * when dialysis is started/resumed so that dialysate usage can be tracked. + * @details Inputs: none + * @details Outputs: resUseTimer + * @return none + *************************************************************************/ +void dialysisResumed( void ) +{ + resUseTimer = getMSTimerCount(); } /*********************************************************************//** @@ -217,22 +223,35 @@ U32 dgSubMode = getDGSubMode(); U32 msSinceLastVolumeCalc = calcTimeSince( resUseTimer ); F32 flowRateMlPerMs = (F32)getTargetDialInFlowRate() / (F32)( MS_PER_SECOND * SEC_PER_MIN ); - + // Calculate volume used from active reservoir - do not accumulate if saline bolus in progress if ( SALINE_BOLUS_STATE_IN_PROGRESS != getSalineBolusState() ) { - resUseVolumeMl += ( flowRateMlPerMs * msSinceLastVolumeCalc ); // TODO - should this calc be done and kept by Dialysis sub-mode? + resUseVolumeMl += ( flowRateMlPerMs * msSinceLastVolumeCalc ); } - resUseTimer = getMSTimerCount(); - + resUseTimer = getMSTimerCount(); + + // Alarm if active reservoir is full and inactive reservoir is not yet ready + if ( getReservoirWeight( getDGActiveReservoir() ) > MAX_RESERVOIR_VOLUME_ML ) + { + if ( currentTrtResMgmtState < TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_RESERVOIR_FULL_AND_DG_NOT_READY_TO_SWITCH, getReservoirWeight( getDGActiveReservoir() ), (F32)currentTrtResMgmtState ) + } + else + { + clearAlarmCondition( ALARM_ID_HD_RESERVOIR_FULL_AND_DG_NOT_READY_TO_SWITCH ); + } + } + // Treatment reservoir mgmt. state machine switch ( currentTrtResMgmtState ) { case TREATMENT_RESERVOIR_MGMT_START_STATE: currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE; break; - case TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE: + case TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE: if ( DG_MODE_CIRC == dgOpMode ) { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) @@ -253,7 +272,7 @@ case TREATMENT_RESERVOIR_MGMT_DRAIN_RESERVOIR_STATE: if ( DG_MODE_CIRC == dgOpMode ) { - currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE; + currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE; } break; @@ -264,8 +283,14 @@ if ( DG_MODE_CIRC == dgOpMode ) { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) - { - cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML ); + { + U32 fillToVolume = FILL_RESERVOIR_TO_VOLUME_ML; + + if ( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) <= SLOW_DIALYSATE_FLOW_ML_MIN ) + { + fillToVolume = FILL_RESERVOIR_TO_VOLUME_LOW_FLOW_ML; + } + cmdStartDGFill( fillToVolume ); } } else @@ -276,7 +301,7 @@ if ( DG_MODE_FILL == dgOpMode ) { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE; - } + } break; case TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE: @@ -296,9 +321,8 @@ case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE: // Reservoir switch during treatment should only occur in this state (i.e. when DG is ready). - // Switch reservoirs when active reservoir is spent (i.e. we have pumped fill volume through dialyzer) and DG ready - if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) && - ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) ) + // Switch reservoirs when active reservoir is spent or full (i.e. we have pumped fill volume through dialyzer) and DG ready + if ( ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) || ( getReservoirWeight( getDGActiveReservoir() ) > MAX_RESERVOIR_VOLUME_ML ) ) { DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); @@ -323,8 +347,8 @@ // Reset to start state to restart drain, fill, switch process. currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; } - break; - + break; + default: // TODO - s/w fault currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; @@ -381,6 +405,19 @@ return inactiveRes; } + +/*********************************************************************//** + * @brief + * The hasDGCompletedReservoirSwitch function checks if DG has completed a + * switch reservoir command. + * @details Inputs: dgActiveReservoir, dgActiveReservoirSet + * @details Outputs: none + * @return TRUE if reported active reservoir is the same as set id, otherwise FALSE + *************************************************************************/ +BOOL hasDGCompletedReservoirSwitch( void ) +{ + return ( dgActiveReservoir == dgActiveReservoirSet ); +} /*********************************************************************//** * @brief @@ -454,13 +491,13 @@ /*********************************************************************//** * @brief - * The getLoadCellWeightInGrams function gets the load cell weight. + * The getLoadCellWeight function gets the current load cell weight. * @details Inputs: loadCellWeightInGrams * @details Outputs: none * @param loadCellID ID of load cell to get * @return the current load cell weight in grams *************************************************************************/ -F32 getLoadCellWeightInGrams( LOAD_CELL_ID_T loadCellID ) +F32 getLoadCellWeight( LOAD_CELL_ID_T loadCellID ) { F32 result = 0.0; @@ -477,52 +514,59 @@ } else { - activateAlarmNoData( ALARM_ID_HD_SOFTWARE_FAULT ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_LOAD_CELL_ID, loadCellID ); } return result; } /*********************************************************************//** * @brief - * The getReservoirWeightSmallFilter function gets the load cell weight - * of the given reservoir after small (8 sample) filter applied. + * The getReservoirWeightLargeFilter function gets the load cell weight + * of the given reservoir after large (32 sample) filter applied. * @details Inputs: lgFilteredReservoirWeightInGrams[] * @details Outputs: none * @param resID ID of reservoir to get filtered weight for * @return the current filtered weight of the given reservoir in grams *************************************************************************/ -F32 getReservoirWeightSmallFilter( DG_RESERVOIR_ID_T resID ) +F32 getReservoirWeightLargeFilter( DG_RESERVOIR_ID_T resID ) { F32 result = 0.0; if ( resID < NUM_OF_DG_RESERVOIRS ) { - result = smFilteredReservoirWeightInGrams[ resID ]; + result = lgFilteredReservoirWeightInGrams[ resID ]; } return result; } /*********************************************************************//** * @brief - * The getReservoirWeightLargeFilter function gets the load cell weight - * of the given reservoir after large (32 sample) filter applied. - * @details Inputs: lgFilteredReservoirWeightInGrams[] + * The getDGDisinfectsStates function returns the DG disinfects readings. + * @details Inputs: none + * @details Outputs: disinfectsStatus + * @return the current DG disinfects readings + *************************************************************************/ +DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) +{ + return disinfectsStatus; +} + +/*********************************************************************//** + * The getReservoirWeight function gets the load cell weight of a given + * reservoir. + * @details Inputs: loadCellWeightInGrams[] * @details Outputs: none - * @param resID ID of reservoir to get filtered weight for - * @return the current filtered weight of the given reservoir in grams + * @param resID ID of reservoir to get weight for + * @return the current weight of the given reservoir in grams *************************************************************************/ -F32 getReservoirWeightLargeFilter( DG_RESERVOIR_ID_T resID ) +F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ) { - F32 result = 0.0; + LOAD_CELL_ID_T lc = ( DG_RESERVOIR_1 == resID ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); + F32 wt = getLoadCellWeight( lc ); - if ( resID < NUM_OF_DG_RESERVOIRS ) - { - result = lgFilteredReservoirWeightInGrams[ resID ]; - } - - return result; + return wt; } /*********************************************************************//** @@ -544,7 +588,7 @@ } else { - // TODO + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_OPERATING_MODE, opMode ); } } @@ -600,8 +644,8 @@ dgReservoirDrainVolumeTarget = drainVol; } else - { - // TODO + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, resID ); } } @@ -677,23 +721,35 @@ loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_PRIMARY ].data = res2Primary; loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_BACKUP ].data = res2Backup; - // feed new weight samples into filters and update moving averages + // Feed new weight samples into filters and update moving averages for ( res = DG_RESERVOIR_1; res < NUM_OF_DG_RESERVOIRS; res++ ) { F32 wt = ( res == DG_RESERVOIR_1 ? res1Primary : res2Primary ); - smLoadCellReadingsTotal[ res ] -= smLoadCellReadings[ res ][ smLoadCellReadingsIdx ]; lgLoadCellReadingsTotal[ res ] -= lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ]; - smLoadCellReadings[ res ][ smLoadCellReadingsIdx ] = wt; lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ] = wt; - smLoadCellReadingsTotal[ res ] += wt; lgLoadCellReadingsTotal[ res ] += wt; - smFilteredReservoirWeightInGrams[ res ] = smLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_SMALL_LOAD_CELL_AVG; lgFilteredReservoirWeightInGrams[ res ] = lgLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; } - smLoadCellReadingsIdx = INC_WRAP( smLoadCellReadingsIdx, 0, SIZE_OF_SMALL_LOAD_CELL_AVG - 1 ); lgLoadCellReadingsIdx = INC_WRAP( lgLoadCellReadingsIdx, 0, SIZE_OF_LARGE_LOAD_CELL_AVG - 1 ); + + // Update Dialysis sub-mode with new reservoir volumes + updateReservoirVolumes( res1Primary, res2Primary ); } +/*********************************************************************//** + * @brief + * The setDGDisinfectsStates function sets the latest disinfects states + * from DG. + * @details Inputs: none + * @details Outputs: disinfectsStatus + * @param states latest DG disinfects state readings + * @return none + *************************************************************************/ +void setDGDisinfectsStates( DG_DISINFECT_UI_STATES_T states ) +{ + memcpy( &disinfectsStatus, &states, sizeof(DG_DISINFECT_UI_STATES_T) ); +} + /*********************************************************************//** * @brief * The cmdSetDGDialysateTargetTemps function sends a target dialysate @@ -721,7 +777,8 @@ *************************************************************************/ void cmdStartDG( void ) { - dgStarted = TRUE; + dgStartCommandSent = TRUE; + sendDGStartStopCommand( START_DG_CMD ); } @@ -735,7 +792,8 @@ *************************************************************************/ void cmdStopDG( void ) { - dgStarted = FALSE; + dgStarted = FALSE; + sendDGStartStopCommand( STOP_DG_CMD ); } @@ -750,7 +808,8 @@ void cmdStartDGTrimmerHeater( void ) { dgTrimmerHeaterOn = TRUE; - dgCmdResp[ DG_CMD_START_TRIMMER_HEATER ].commandID = DG_CMD_NONE; + dgCmdResp[ DG_CMD_START_TRIMMER_HEATER ].commandID = DG_CMD_NONE; + sendDGStartStopTrimmerHeaterCommand( START_DG_CMD, dgTrimmerTempSet ); } @@ -766,6 +825,7 @@ { dgTrimmerHeaterOn = FALSE; dgCmdResp[ DG_CMD_STOP_TRIMMER_HEATER ].commandID = DG_CMD_NONE; + sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD, 0 ); } @@ -783,7 +843,8 @@ if ( resID < NUM_OF_DG_RESERVOIRS ) { dgActiveReservoirSet = resID; - dgCmdResp[ DG_CMD_SWITCH_RESERVOIR ].commandID = DG_CMD_NONE; + dgCmdResp[ DG_CMD_SWITCH_RESERVOIR ].commandID = DG_CMD_NONE; + sendDGSwitchReservoirCommand( (U32)resID ); } else @@ -806,6 +867,7 @@ if ( valveSettingID < NUM_OF_DG_VALVE_SETTTINGS ) { dgCmdResp[ DG_CMD_VALVE_SETTING ].commandID = DG_CMD_NONE; + sendDGChangeValveSettingCommand( (U32)valveSettingID ); } else @@ -825,9 +887,25 @@ void cmdStartDGFill( U32 fillToVolMl ) { dgCmdResp[ DG_CMD_START_FILL ].commandID = DG_CMD_NONE; - dgReservoirFillVolumeTargetSet = fillToVolMl; - sendDGFillCommand( fillToVolMl ); + dgReservoirFillVolumeTargetSet = fillToVolMl; + + sendDGFillCommand( DG_CMD_START, fillToVolMl ); } + +/*********************************************************************//** + * @brief + * The cmdStopDGFill function sends a fill command with stop parameter message to the DG. + * @details Inputs: none + * @details Outputs: fill command with stop parameter sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGFill( void ) +{ + dgCmdResp[ DG_CMD_STOP_FILL ].commandID = DG_CMD_NONE; + dgReservoirFillVolumeTargetSet = 0; + + sendDGFillCommand( DG_CMD_STOP, 0 ); +} /*********************************************************************//** * @brief @@ -845,7 +923,8 @@ dgCmdResp[ DG_CMD_START_DRAIN ].commandID = DG_CMD_NONE; payload.drainToVolumeML = drainToVolMl; payload.tareLoadCells = tareLoadCell; - dgReservoirDrainVolumeTargetSet = drainToVolMl; + dgReservoirDrainVolumeTargetSet = drainToVolMl; + sendDGDrainCommand( &payload ); } @@ -856,14 +935,109 @@ * @details Outputs: sample water command sent to DG. * @return none *************************************************************************/ -void cmdDGSampleWater( void ) +void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ) { - dgWaterSampled = TRUE; - sendDGSampleWaterCommand(); + sendDGSampleWaterCommand( cmd ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGFlush function sends a start flush command message to + * the DG. + * @details Inputs: none + * @details Outputs: start flush mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGFlush( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_FLUSH ].commandID = DG_CMD_NONE; + + sendDGStartFlushModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGFlush function sends a stop flush command message to + * the DG. + * @details Inputs: none + * @details Outputs: stop flush mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGFlush( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_FLUSH ].commandID = DG_CMD_NONE; + + sendDGStartFlushModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGHeatDisinfect function sends a start heat disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: start heat disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGHeatDisinfect( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_HEAT_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartHeatDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGHeatDisinfect function sends a stop heat disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: stop heat disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGHeatDisinfect( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_HEAT_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartHeatDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGChemicalDisinfect function sends a start chemical disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: start chemical disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGChemicalDisinfect( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_CHEM_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartChemicalDisinfectModeCommand( start ); } /*********************************************************************//** * @brief + * The cmdStopDGChemicalDisinfect function sends a stop chemical disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: stop chemical disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGChemicalDisinfect( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_CHEM_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartChemicalDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief * The handleDGCommandResponse function processes the latest DG command response. * @details Inputs: none * @details Outputs: process command response from DG @@ -925,7 +1099,33 @@ return hasCommandResp; } +/*********************************************************************//** + * @brief + * The checkDGRestart function checks to see if DG has restarted after started + * by HD and triggers appropriate alarm. + * @details Inputs: dgStarted + * @details Outputs: triggers a fault alarm if DG restarted + * @return none + *************************************************************************/ +static void checkDGRestart( void ) +{ + if ( ( dgStartCommandSent == TRUE ) && ( DG_MODE_CIRC == dgCurrentOpMode ) ) + { + dgStartCommandSent = FALSE; + dgStarted = TRUE; + } + if ( TRUE == dgStarted ) + { + if ( ( DG_MODE_FAUL != dgCurrentOpMode ) && ( DG_MODE_CIRC != dgCurrentOpMode ) && + ( DG_MODE_FILL != dgCurrentOpMode ) && ( DG_MODE_DRAI != dgCurrentOpMode ) ) + { + activateAlarmNoData( ALARM_ID_DG_RESTARTED_FAULT ); + } + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/