Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -r4468dcb6d88bb364c60412ac368d1420adb66b27 -r0e65964d36bf2f26486b03b45ac5f55b76e013e8 --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 4468dcb6d88bb364c60412ac368d1420adb66b27) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 0e65964d36bf2f26486b03b45ac5f55b76e013e8) @@ -1,37 +1,41 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2023 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 ModeFlush.c * * @author (last) Dara Navaei -* @date (last) 13-Jun-2022 +* @date (last) 21-Jun-2023 * * @author (original) Leonardo Baloa * @date (original) 20-Dec-2019 * ***************************************************************************/ #include "ConcentratePumps.h" +#include "ConductivitySensors.h" +#include "CPLD.h" #include "DrainPump.h" +#include "FlowSensors.h" #include "Heaters.h" #include "LoadCell.h" #include "MessageSupport.h" #include "ModeFault.h" #include "ModeFlush.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" +#include "RTC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" #include "UVReactors.h" #include "Valves.h" -#include "CPLD.h" /** * @addtogroup DGFlushMode @@ -47,7 +51,7 @@ #define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. // Drain R1 & R2 states defines -#define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. +#define DRAIN_WEIGHT_UNCHANGE_TIMEOUT_MS ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines #define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. @@ -56,20 +60,20 @@ #define FLUSH_DIALYSATE_WAIT_TIME_MS ( 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds. // Flush concentrate straws state defines -#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. todo was 3 minutes +#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. #define ACID_PUMP_SPEED_ML_PER_MIN -30.0F ///< Acid pump speed in mL/min. // The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during flush #define BICARB_PUMP_SPEED_ML_PER_MIN 30.6F ///< Bicarb pump speed in mL/min. // Flush and drain R1 and R2 state defines -#define RSRVRS_FULL_VOL_ML 1800.0F ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 +#define RSRVRS_FULL_VOL_ML 1850.0F ///< Reservoirs 1 & 2 full volume in mL. #define RSRVRS_PARTIAL_FILL_VOL_ML 500.0F ///< Reservoirs 1 & 2 partial volume in mL. #define RSRVRS_FULL_STABLE_TIME_COUNT ( ( 4 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in counts. #define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. #define RSRVRS_PARTIAL_FILL_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. #define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. -#define FINAL_DRAIN_RO_PUMP_FLOW_LPM 0.6F ///< Final drain RO pump flow rate in L/min. This is used to flush the drain line during drain. +#define FINAL_DRAIN_RO_PUMP_FLOW_LPM 0.8F ///< Final drain RO pump flow rate in L/min. This is used to flush the drain line during drain. // Flush drain line state defines #define FLUSH_DRAIN_LINE_VOLUME_L 0.1F ///< Water volume to flush in liters. @@ -97,6 +101,7 @@ static BOOL hasWaterCancellationBeenSet; ///< Water cancellation set/not set boolean flag. static F32 flushLinesVolumeL; ///< Volume of water pumped by RO pump during flush lines state. static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Boolean flag to indicate whether the drain parameters have been reset or not. +static BOOL hasFlushStatusBeenWrittenToNV; ///< Boolean flag to indicate whether the flush status has been written to NV or not. // ********** private function prototypes ********** @@ -120,6 +125,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ); static void publishFlushData( void ); static void monitorModeFlush( void ); +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ); /*********************************************************************//** * @brief @@ -128,7 +134,8 @@ * @details Outputs: flushState, prevFlushState, rsrvrFillStableTimeCounter, * overallFlushElapsedTime, isThisInitialDrain, dataPublishCounter, * rsrvr1Status, rsrvr2Status, hasWaterCancellationBeenSet, - * flushLinesVolumeL, haveDrainParamsBeenInit, stateTimerStart + * flushLinesVolumeL, haveDrainParamsBeenInit, stateTimerStart, + * hasFlushStatusBeenWrittenToNV * @return none *************************************************************************/ void initFlushMode( void ) @@ -138,16 +145,17 @@ prevFlushState = DG_FLUSH_STATE_START; flushUIState = FLUSH_UI_STATE_NOT_RUNNING; rsrvrFillStableTimeCounter = 0; - overallFlushElapsedTimeStart = 0; + overallFlushElapsedTimeStart = getMSTimerCount(); isThisInitialDrain = TRUE; dataPublishCounter = 0; rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; hasWaterCancellationBeenSet = FALSE; - flushLinesVolumeL = 0.0; + flushLinesVolumeL = 0.0F; haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; - stateTimerStart = 0; + stateTimerStart = getMSTimerCount(); + hasFlushStatusBeenWrittenToNV = FALSE; } /*********************************************************************//** @@ -160,10 +168,10 @@ U32 transitionToFlushMode( void ) { // Reset all the actuators - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); initFlushMode(); - + setCurrentSubState( NO_SUB_STATE ); setCPLDCleanLEDColor( CPLD_CLEAN_LED_BLUE ); return flushState; @@ -178,6 +186,16 @@ *************************************************************************/ U32 execFlushMode( void ) { + checkInletWaterPressure(); + + if ( flushState != DG_FLUSH_STATE_FLUSH_DRAIN ) + { + // Do not check on the inlet water temperature and conductivity until the inlet filters have been flushed + // The initial states are drain reservoirs but in those states VPi is closed so these alarms are not checked + checkInletWaterTemperature(); + checkInletWaterConductivity(); + } + monitorModeFlush(); // Execute current flush state @@ -280,7 +298,7 @@ if ( DG_MODE_FLUS == getCurrentOperationMode() ) { // Reset all the actuators - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); // Transition to mode standby requestNewOperationMode( DG_MODE_STAN ); @@ -343,7 +361,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT_MS, RSRVRS_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -368,7 +386,7 @@ } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -389,7 +407,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { - rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT_MS, RSRVRS_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -406,6 +424,7 @@ setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + turnOnUVReactor( INLET_UV_REACTOR ); state = DG_FLUSH_STATE_FLUSH_DRAIN; } @@ -425,14 +444,14 @@ turnOnUVReactor( OUTLET_UV_REACTOR ); flushUIState = FLUSH_UI_STATE_FLUSH_RECIRCULATION_PATH; - state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE; + state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE; } stateTimerStart = getMSTimerCount(); } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -460,8 +479,7 @@ turnOnUVReactor( OUTLET_UV_REACTOR ); stateTimerStart = getMSTimerCount(); - - state = DG_FLUSH_STATE_FLUSH_DIALYSATE; + state = DG_FLUSH_STATE_FLUSH_DIALYSATE; } return state; @@ -480,6 +498,8 @@ { DG_FLUSH_STATE_T state = DG_FLUSH_STATE_FLUSH_DIALYSATE; + writeDisinfectDataToNV( USAGE_INFO_FILTER_FLUSH ); + if ( TRUE == didTimeout( stateTimerStart, FLUSH_DIALYSATE_WAIT_TIME_MS ) ) { // Turn the pumps on in reverse @@ -490,7 +510,10 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - stateTimerStart = getMSTimerCount(); + // Set the timer for the next state + // Set the NV data flag to FALSE since it should be ready for another write while the mode is running + stateTimerStart = getMSTimerCount(); + hasFlushStatusBeenWrittenToNV = FALSE; state = DG_FLUSH_STATE_FLUSH_CONCENTRATE_STRAWS; } @@ -514,8 +537,8 @@ if ( TRUE == didTimeout( stateTimerStart, FLUSH_CONCENTRATE_STRAWS_TIME_MS ) ) { // Done with flushing the concentrate pumps line - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); @@ -621,7 +644,7 @@ // If reservoir 1 is empty, turn off the drain pump if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT_MS, RSRVRS_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -632,7 +655,7 @@ // Reservoir 1 drain time out else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } // First reservoir 2 must be completely full but if reservoir 1 is filled before reservoir 2 is full, alarm @@ -708,16 +731,18 @@ * within the defined time, it transitions to water cancellation state. * @details Inputs: stateTimerStart, flushLinesVolumeL * @details Outputs: stateTimerStart, flushLinesVolumeL, - * alarmDetectedPendingTrigger + * alarmDetectedPendingTrigger, hasFlushStatusBeenWrittenToNV * @return next state of the flush state machine *************************************************************************/ static DG_FLUSH_STATE_T handleFlushModeFlushCirculationDrainLineState( void ) { DG_FLUSH_STATE_T state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE; - F32 waterFlowRate = getMeasuredROFlowRateLPM(); - F32 waterVolume = ( ( waterFlowRate / SEC_PER_MIN ) / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); + writeDisinfectDataToNV( USAGE_INFO_FILTER_FLUSH ); + F32 waterFlowRate = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); + F32 waterVolume = ( ( waterFlowRate / SEC_PER_MIN ) / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); + // Integrate volume of water moved through line flushLinesVolumeL += waterVolume; @@ -731,15 +756,14 @@ setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLOW_RATE_LPM, RO_PUMP_MAX_PRESSURE_PSI ); - stateTimerStart = getMSTimerCount(); - - state = DG_FLUSH_STATE_FLUSH_CIRCULATION; + hasFlushStatusBeenWrittenToNV = FALSE; + stateTimerStart = getMSTimerCount(); + state = DG_FLUSH_STATE_FLUSH_CIRCULATION; } else if ( TRUE == didTimeout( stateTimerStart, FLUSH_DRAIN_LINE_TIMEOUT_MS ) ) { alarmDetectedPendingTrigger = ALARM_ID_DG_DRAIN_CIRCULATION_LINE_TIMEOUT; - // Could not reach to the defined drain line on time - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -765,8 +789,7 @@ setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); stateTimerStart = getMSTimerCount(); - - state = DG_FLUSH_STATE_FLUSH_WITH_FRESH_WATER; + state = DG_FLUSH_STATE_FLUSH_WITH_FRESH_WATER; } return state; @@ -778,7 +801,7 @@ * flush with fresh water state. It runs the circulation state with fresh * water for the defined period of time. * @details Inputs: stateTimerStart - * @details Outputs: none + * @details Outputs: flushUIState * @return next state of the flush state machine *************************************************************************/ static DG_FLUSH_STATE_T handleFlushModeFlushWithFreshWaterState( void ) @@ -787,9 +810,9 @@ if ( TRUE == didTimeout( stateTimerStart, FLUSH_WITH_FRESH_WATER_WAIT_TIME_MS ) ) { - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); flushUIState = FLUSH_UI_STATE_COMPLETE; - state = DG_FLUSH_STATE_COMPLETE; + state = DG_FLUSH_STATE_COMPLETE; } return state; @@ -835,7 +858,7 @@ if ( FALSE == hasWaterCancellationBeenSet ) { // Stop all the actuators first then decide who should run next - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); // Set the actuators setValveState( VPI, VALVE_STATE_CLOSED ); @@ -863,7 +886,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { // If the cancellation water path cannot be done, got to basic cancellation path - rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT_MS, RSRVRS_DRAIN_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -880,7 +903,7 @@ if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) ) { // If the cancellation water path cannot be done, go to basic cancellation path - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT_MS, RSRVRS_DRAIN_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -903,29 +926,38 @@ /*********************************************************************//** * @brief * The handleFlushModeComplete function handles the complete state. - * @details Inputs: none + * @details Inputs: hasFlushStatusBeenWrittenToNV * @details Outputs: none * @return next state of the flush state machine *************************************************************************/ static DG_FLUSH_STATE_T handleFlushModeComplete( void ) { DG_FLUSH_STATE_T state = DG_FLUSH_STATE_COMPLETE; - stopDGFlush(); + writeDisinfectDataToNV( USAGE_INFO_BASIC_FLUSH ); + if ( TRUE == hasFlushStatusBeenWrittenToNV ) + { + stopDGFlush(); + } + return state; } /*********************************************************************//** * @brief * The failFlushMode function sets the alarm that failed the flush mode. - * @details Inputs: alarm, prevHeatDisinfectState + * @details Inputs: alarmDetectedPendingTrigger, prevFlushState * @details Outputs: none * @return none *************************************************************************/ static void failFlushMode( void ) { - SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevFlushState ) + if ( alarmDetectedPendingTrigger != ALARM_ID_NO_ALARM ) + { + SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevFlushState ) + } + requestNewOperationMode( DG_MODE_STAN ); } /*********************************************************************//** @@ -992,8 +1024,8 @@ * The getRsrvrDrainStatus function returns the status of draining a * reservoir. If the drain times out, it set the status to did not reach * target. - * @details Inputs: rsrvrFillStableTimeCounter, alarm, stateTimer - * @details Outputs: rsrvrFillStableTimeCounter, alarm, stateTimer, + * @details Inputs: alarm, stateTimer + * @details Outputs: alarm, stateTimer, * prevFlushState * @param r is DG_RESERVOIR_1 or DG_RESERVOIR_2 * @param drainSteadyStateTimeout which is the time the reservoir's level @@ -1005,6 +1037,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_ABOVE_TARGET; + BOOL isDrainComplete = FALSE; // If the drain parameters of the reservoir is not initialized, initialize them if ( FALSE == haveDrainParamsBeenInit [ r ] ) @@ -1013,7 +1046,9 @@ haveDrainParamsBeenInit[ r ] = TRUE; } - BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); + // NOTE: the drain status should be checked once the reservoirs parameters are initialized. This is to make sure the + // the timers for stable drain time are initialized prior to using them again + isDrainComplete = hasTargetDrainToZeroBeenReached( r, drainSteadyStateTimeout ); if ( TRUE == isDrainComplete ) { @@ -1054,7 +1089,7 @@ *************************************************************************/ static void publishFlushData( void ) { - if ( ++dataPublishCounter > FLUSH_DATA_PUB_INTERVAL ) + if ( ++dataPublishCounter >= FLUSH_DATA_PUB_INTERVAL ) { MODE_FLUSH_DATA_T data; @@ -1089,12 +1124,41 @@ { // Set the variables to fail and go to cancel water path. Set the pending alarm to no alarm so the cancel water path // will not be raising the alarm at end of the cancel water path. The recoverable alarm is raised here in this function - U32 cap = (U32)( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ? CONCENTRATE_CAP : DIALYSATE_CAP ); prevFlushState = flushState; flushState = DG_FLUSH_STATE_CANCEL_WATER_PATH; - alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; + alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_CAP_NOT_IN_PROPER_POSITION; + + if ( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ) + { + alarmDetectedPendingTrigger = ALARM_ID_DG_CONCENTRATE_CAP_NOT_IN_PROPER_POSITION; + } } } + + if ( ( TRUE == isDGFaultAlarmActive() ) || ( TRUE == isAnyCleaningModeInletWaterConditionActive() ) ) + { + if ( flushState != DG_FLUSH_STATE_CANCEL_WATER_PATH ) + { + prevFlushState = flushState; + flushState = DG_FLUSH_STATE_CANCEL_WATER_PATH; + } + } } +/*********************************************************************//** + * @brief + * The writeDisinfectDataToNV function writes the disinfection data to the + * non-volatile memory. + * @details Inputs: hasFlushStatusBeenWrittenToNV + * @details Outputs: hasFlushStatusBeenWrittenToNV + * @return: none + *************************************************************************/ +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ) +{ + if ( FALSE == hasFlushStatusBeenWrittenToNV ) + { + hasFlushStatusBeenWrittenToNV = setLastDisinfectDate( info, getRTCTimestamp() ); + } +} + /**@}*/