/************************************************************************** * * 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 ModePreTreat.c * * @author (last) Dara Navaei * @date (last) 11-Aug-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 * ***************************************************************************/ #include "AlarmMgmt.h" #include "Buttons.h" #include "ConsumableSelfTest.h" #include "FPGA.h" #include "ModePreTreat.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "PresOccl.h" #include "PreTreatmentRecirc.h" #include "Prime.h" #include "Reservoirs.h" #include "SelfTests.h" #include "SampleWater.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" /** * @addtogroup HDPreTreatmentMode * @{ */ // ********** private definitions ********** /// Interval (ms/task time) at which the pre-treatment state data is published on the CAN bus. #define PRE_TREATMENT_DATA_PUB_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) /// Wait time for ui to transition on completion of a sub-mode (ms/task time). #define SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) #define DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN 250 ///< Patient connection sub-mode dialysate inlet pump flow rate in mL/min. #define PRE_TREATMENT_HEATING_DIA_FLOW_ML_PER_MIN 600 ///< Pre treatment heating parameters dialysate flow in mL/min. #define PRE_TREATMENT_FLUSH_FILL_TARGET_TEMP_C 45.0F ///< Pre treatment flush fill target temperature in C. #define PRE_TREATMENT_NORMAL_FILL_TARGET_TEMP_C ( 37.0F + 2.0F ) ///< Pre treatment normal fill target temperature in C. #define PRE_TREATMENT_MIN_FILL_RESERVOIR_VOLUME_ML 500 ///< Fill reservoir to this volume minimum to prep volume during development. #define PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML 300 ///< Fill reservoir to this volume (in mL) to flush filter and lines. #define PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML 1300 ///< Fill reservoir one to this volume (in mL) during pre-treatment mode. #define PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML 600 ///< Fill reservoir two to this volume (in mL) during pre-treatment mode. #define PRE_TREATMENT_FULL_RESERVOIR_VOLUME_ML 1500 ///< Fill reservoir to this volume minimum to prep volume during development. #define PRE_TREATMENT_FLUSH_COUNT 2 ///< Number of flush cycles for each reservoir. #define PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML 1400 ///< Pre-treatment test configuration minimum reservoir volume in milliliters. #define PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML 1575 ///< Pre-treatment test configuration maximum reservoir volume in milliliters. typedef struct { BOOL initialDrain; ///< Flags indicate whether a reservoir has been requested to initially drain. BOOL startFlushFill; ///< Flags "GO" for a flush reservoir fill, to synchronize with self-test requirements BOOL startNormalFill; ///< Flags "GO" for a normal reservoir fill, to synchronize with self-test requirements BOOL flushComplete; ///< Flag indicates a reservoir has been flushed. BOOL fillComplete; ///< Flag indicates a reservoir has been filled. U32 flushCount; ///< Flag indicates the number of reservoir flush cycles required. } PRE_TREATMENT_RESERVOIR_VAR_T; /// States of the pre-treatment reservoir management state machine. typedef enum PreTreatmentReservoirMgmt_States { PRE_TREATMENT_RESERVOIR_MGMT_START_STATE = 0, ///< Wait for signal to start drain and fill reservoirs PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE, ///< Command DG to start draining reservoir PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE, ///< After sending drain command, process DG drain command response PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE, ///< Command DG to start filling reservoir PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE, ///< After sending fill command, process DG fill command response PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE, ///< Reservoir fill has completed PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE, ///< Command DG to switch (toggle) reservoirs PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE, ///< After sending switch command, process DG fill command response PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE, ///< Pre-treatment reservoir management complete state NUM_OF_PRE_TREATMENT_RESERVOIR_MGMT_STATES ///< Number of pre-treatments reservoir mgmt. states } PRE_TREATMENT_RESERVOIR_MGMT_STATE_T; // ********** private data ********** static BOOL confirmInstallRequested; ///< Flag indicates user confirms disposable installation. static BOOL continueToTreatmentRequested; ///< Flag indicates user requests to continue to treatment from re-circ. static BOOL setUFVolStatus; ///< Flag indicates user has set UF volume parameter. static BOOL doorOpened; ///< Flag indicates user has opened door (to invert dialyzer). static BOOL patientConnectionConfirm; ///< Flag indicates user has confirmed patient connection complete. static BOOL treatmentStartRequested; ///< Flag indicates user requests treatment begin. static BOOL signalTestConfigRsrvrMgmtUse; ///< Flag indicates to use test configuration reservoir management. static BOOL alarmActionResumeReceived; ///< Flag indicates alarm action resume received. static HD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current state of pre-treatment mode state machine. static HD_PRE_TREATMENT_PAT_CONN_STATE_T currentPreTxPatConnState; ///< Current state of pre-treatment patient connect sub-mode state machine. static BOOL fillReservoirOneStartRequested; ///< Flag indicates fill reservoir one has been requested. static U32 preTreatmentPublishTimerCounter; ///< Pre-treatment data broadcast timer counter used to schedule when to transmit data. /// Interval (in task intervals) at which to publish pre-treatment mode data to CAN bus. static OVERRIDE_U32_T preTreatmentModePublishInterval = { PRE_TREATMENT_DATA_PUB_INTERVAL, PRE_TREATMENT_DATA_PUB_INTERVAL, PRE_TREATMENT_DATA_PUB_INTERVAL, 0 }; static U32 submodeCompleteTransitionTimeCounter; ///< Sub-mode completed transition wait time counter. static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current pre-treatment reservoir management state. static PRE_TREATMENT_RESERVOIR_VAR_T reservoirStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Detailed state of each reservoir. #ifndef _RELEASE_ const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPrimingDisabled = {FALSE,FALSE,FALSE,TRUE,FALSE,(0)}; #endif const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPretreatmentInit = {FALSE,FALSE,FALSE,FALSE,FALSE,PRE_TREATMENT_FLUSH_COUNT}; // ********** private function prototypes ********** static void publishPreTreatmentState( void ); static void resetSignalFlags( void ); static void transitionToCartridgeInstallation( void ); static void transitionToPatientConnection( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4UFVolState( void ); static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4DialyzerInvertState( void ); static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4UserConfirmState( void ); static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4TreatmentStartState( void ); static void execPreTreatmentReservoirMgmt( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtStartState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdRespState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdRespState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCompleteState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtRequestReservoirSwitchState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtWaitReservoirSwitchState( void ); static void handleDGParkConcentratePumpsCmdRespState( void ); static U32 getPreTreatmentFillVolume( DG_RESERVOIR_ID_T inactiveRes ); static void setPreTreatmentHeatingParams( F32 targetTempC, U32 targetVolML, F32 targetFillFlowLPM, U32 dialysateFlowMLPM ); // Test configuration test function and final drain correction at patient connect static void execPreTreatmentTestConfigReservoirMgmt( void ); /*********************************************************************//** * @brief * The initPreTreatmentMode function initializes the Pre-Treatment Mode module. * @details Inputs: none * @details Outputs: Pre-Treatment Mode module initialized. * @return none *************************************************************************/ void initPreTreatmentMode( void ) { U32 reservoirIndex = 0; currentPreTreatmentState = HD_PRE_TREATMENT_WATER_SAMPLE_STATE; currentPreTxPatConnState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_UF_VOL_STATE; currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; alarmActionResumeReceived = FALSE; fillReservoirOneStartRequested = FALSE; confirmInstallRequested = FALSE; continueToTreatmentRequested = FALSE; setUFVolStatus = FALSE; doorOpened = FALSE; patientConnectionConfirm = FALSE; treatmentStartRequested = FALSE; signalTestConfigRsrvrMgmtUse = FALSE; submodeCompleteTransitionTimeCounter = 0; #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) { for ( reservoirIndex = 0; reservoirIndex < NUM_OF_DG_RESERVOIRS; reservoirIndex++ ) { reservoirStatus[reservoirIndex] = reservoirPrimingDisabled; } } else #endif { for ( reservoirIndex = 0; reservoirIndex < NUM_OF_DG_RESERVOIRS; reservoirIndex++ ) { reservoirStatus[reservoirIndex] = reservoirPretreatmentInit; } } initSampleWater(); initConsumableSelfTest(); initPrime(); initSelfTests(); // Reservoirs state machine is not used in Pre-treatment but the // init function is called here to initialize all the variables in // the reservoirs driver since an API from the reservoirs is used // to setup the DG heaters. initReservoirs(); resetSignalFlags(); } /*********************************************************************//** * @brief * The transitionToPreTreatmentMode function prepares for transition to * pre-treatment mode. * @details Inputs: none * @details Outputs: none * @return initial state *************************************************************************/ U32 transitionToPreTreatmentMode( void ) { F32 trimmerHeaterTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); initPreTreatmentMode(); // Set the heating parameters to start the heaters setPreTreatmentHeatingParams( PRE_TREATMENT_FLUSH_FILL_TARGET_TEMP_C, PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML, DEFAULT_TARGET_FILL_FLOW_RATE_LPM, PRE_TREATMENT_HEATING_DIA_FLOW_ML_PER_MIN ); cmdStopDGTrimmerHeater(); // Pumps should be off signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); stopSyringePump(); // Set valves to default positions setValveAirTrap( STATE_CLOSED ); setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VDO, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); // Set user alarm recovery actions allowed in this mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); doorClosedRequired( FALSE, FALSE ); if ( getTestConfigStatus( TEST_CONFIG_EXPEDITE_PRE_TREATMENT ) != TRUE ) { // Start pre-treatment mode in sample water state transitionToSampleWater(); } else { cmdStartDG(); transitionToPatientConnection(); currentPreTreatmentState = HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } return currentPreTreatmentState; } /*********************************************************************//** * @brief * The execPreTreatmentMode function executes the Pre-Treatment Mode state machine. * @details Inputs: currentPreTreatmentState, signalTestConfigRsrvrMgmtUse * @details Outputs: currentPreTreatmentState * @return current state (sub-mode) *************************************************************************/ U32 execPreTreatmentMode( void ) { BOOL stop = isStopButtonPressed(); if ( TRUE == stop ) { activateAlarmNoData( ALARM_ID_HD_TREATMENT_STOPPED_BY_USER ); } // execute mode state machine switch ( currentPreTreatmentState ) { case HD_PRE_TREATMENT_WATER_SAMPLE_STATE: currentPreTreatmentState = handleWaterSampleState(); break; case HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE: currentPreTreatmentState = handleSelfTestConsumableState(); break; case HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE: currentPreTreatmentState = handleSelfTestNoCartState(); break; case HD_PRE_TREATMENT_CART_INSTALL_STATE: currentPreTreatmentState = handleInstallState(); break; case HD_PRE_TREATMENT_SELF_TEST_DRY_STATE: currentPreTreatmentState = handleSelfTestDryState(); break; case HD_PRE_TREATMENT_PRIME_STATE: currentPreTreatmentState = handlePrimeState(); break; case HD_PRE_TREATMENT_RECIRCULATE_STATE: currentPreTreatmentState = handleRecirculateState(); break; case HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: currentPreTreatmentState = handlePatientConnectionState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, (U32)currentPreTreatmentState ); break; } if ( ( getTestConfigStatus( TEST_CONFIG_EXPEDITE_PRE_TREATMENT ) != TRUE ) && ( signalTestConfigRsrvrMgmtUse != TRUE ) ) { // Execute reservoir management for pre-treatment mode execPreTreatmentReservoirMgmt(); } else { // If the expedite pre-treatment test configuration is set, the reservoir management is executed differently execPreTreatmentTestConfigReservoirMgmt(); } // Alarm response request flags should be handled at this point, reset in case not handled in current state resetSignalFlags(); // Broadcast pre-treatment data publishPreTreatmentState(); return (U32)currentPreTreatmentState; } /*********************************************************************//** * @brief * The signalUserConfirmInstallation function handles user confirmation of * disposable installation. * @details Inputs: none * @details Outputs: confirmInstallRequested * @return none *************************************************************************/ void signalUserConfirmInstallation( void ) { BOOL accepted = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; confirmInstallRequested = FALSE; F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); F32 hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); // Accept installation confirmation if we are in install state of pre-treatment mode and // Door closed, Cartridge installed, syringe is detected or Heparin not being used in this treatment. if ( ( MODE_PRET == getCurrentOperationMode() ) && ( HD_PRE_TREATMENT_CART_INSTALL_STATE == currentPreTreatmentState ) ) { OPN_CLS_STATE_T frontDoor = getSwitchStatus( FRONT_DOOR ); OPN_CLS_STATE_T pumpTrack = getSwitchStatus( PUMP_TRACK_SWITCH ); if ( STATE_CLOSED == pumpTrack ) { if ( STATE_CLOSED == frontDoor ) { if ( ( TRUE == isSyringeDetected() ) || ( ( bolusVol < NEARLY_ZERO ) && ( hepRate < NEARLY_ZERO ) ) ) { // Everything is properly installed accepted = TRUE; confirmInstallRequested = TRUE; if ( ( bolusVol > NEARLY_ZERO ) || ( hepRate > NEARLY_ZERO ) ) { syringeDetectionRequired( TRUE ); } } else { rejReason = REQUEST_REJECT_REASON_SYRINGE_NOT_PRESENT; } } else { rejReason = REQUEST_REJECT_REASON_DOOR_NOT_CLOSED; } } else { rejReason = REQUEST_REJECT_REASON_PUMP_TRACK_NOT_CLOSED; } } else { rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; } sendConsumableInstallCmdResponse( accepted, (U32) rejReason ); } /*********************************************************************//** * @brief * The signalUserContinueToTreatment function handles user request to continue * to treatment. * @details Inputs: none * @details Outputs: handled and send response to continue to treatment request * @return none *************************************************************************/ void signalUserContinueToTreatment( void ) { BOOL accepted = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; if ( HD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) { continueToTreatmentRequested = TRUE; accepted = TRUE; rejReason = REQUEST_REJECT_REASON_NONE; } sendContinueToTreatmentCmdResponse( accepted, rejReason ); } /*********************************************************************//** * @brief * The setUserSetUFVolumeStatus function sets the status of whether user * has set UF volume. * @details Inputs: none * @details Outputs: setUFVolStatus * @param status TRUE if ultrafiltration volume set, FALSE if not * @return none *************************************************************************/ void setUserSetUFVolumeStatus( BOOL status ) { setUFVolStatus = status; } /*********************************************************************//** * @brief * The signalUserConfirmPatientConnection function handles user confirms * patient connection message. * @details Inputs: none * @details Outputs: handled and send response to patient connection confirmation * @return none *************************************************************************/ void signalUserConfirmPatientConnection( void ) { BOOL accepted = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; if ( HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == currentPreTreatmentState ) { if ( currentPreTxPatConnState >= PRE_TREATMENT_PAT_CONN_WAIT_FOR_USER_CONFIRM_STATE ) { patientConnectionConfirm = TRUE; accepted = TRUE; rejReason = REQUEST_REJECT_REASON_NONE; } else { rejReason = REQUEST_REJECT_REASON_DIALYZER_NOT_INVERTED; } } sendPatientConnectionConfirmCmdResponse( accepted, rejReason ); } /*********************************************************************//** * @brief * The signalUserStartTreatment function handles user requests to start treatment. * @details Inputs: patientConnectionConfirm, currentPreTreatmentState * @details Outputs: handled and send response to treatment start request * @return none *************************************************************************/ void signalUserStartTreatment( void ) { BOOL accepted = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NO_PATIENT_CONNECTION_CONFIRM; #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { patientConnectionConfirm = TRUE; } #endif if ( TRUE == patientConnectionConfirm ) { if ( ( MODE_PRET == getCurrentOperationMode() ) && ( HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == currentPreTreatmentState ) ) { treatmentStartRequested = TRUE; accepted = TRUE; rejReason = REQUEST_REJECT_REASON_NONE; } else { rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } } sendStartTreatmentResponse( accepted, rejReason ); } /*********************************************************************//** * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in PreTreatment Mode. * @details Inputs: none * @details Outputs: given alarm action executed * @param action ID of alarm action to execute * @return none *************************************************************************/ void signalAlarmActionToPreTreatmentMode( ALARM_ACTION_T action ) { switch( action ) { case ALARM_ACTION_STOP: // Stop signal actively polled by mode/sub-mode/state break; case ALARM_ACTION_RESUME: alarmActionResumeReceived = TRUE; break; case ALARM_ACTION_END_TREATMENT: if ( currentPreTreatmentState > HD_PRE_TREATMENT_WATER_SAMPLE_STATE ) { signalNoDisinfectRequired(); // no blood introduced in pre-tx, so no need to disinfect after post-tx. requestNewOperationMode( MODE_POST ); } else { requestNewOperationMode( MODE_STAN ); cmdStopDG(); } break; case ALARM_ACTION_ACK: // Nothing to be done here break; default: // Ignore break; } } /*********************************************************************//** * @brief * The signalAllowDGFlushFills function sets the reservoir flush flags * to allow reservoir flush fills to proceed when ready. * @details Inputs: none * @details Outputs: reservoirStatus[] * @return none *************************************************************************/ void signalAllowDGFlushFills( void ) { reservoirStatus[ DG_RESERVOIR_1 ].startFlushFill = TRUE; reservoirStatus[ DG_RESERVOIR_2 ].startFlushFill = TRUE; } /*********************************************************************//** * @brief * The signalAllowDGFillRes1 function sets the reservoir 1 fill flag * to allow reservoir 1 fill to proceed when ready. * @details Inputs: none * @details Outputs: reservoirStatus[] * @return none *************************************************************************/ void signalAllowDGFillRes1( void ) { reservoirStatus[ DG_RESERVOIR_1 ].startNormalFill = TRUE; } /*********************************************************************//** * @brief * The signalAllowDGFillRes2 function sets the reservoir 2 fill flag * to allow reservoir 2 fill to proceed when ready. * @details Inputs: none * @details Outputs: reservoirStatus[] * @return none *************************************************************************/ void signalAllowDGFillRes2( void ) { reservoirStatus[ DG_RESERVOIR_2 ].startNormalFill = TRUE; } /*********************************************************************//** * @brief * The getReservoirFillStatus function returns the fill complete status for * given reservoir. * @details Inputs: reservoirStatus[] * @details Outputs: none * @return TRUE if reservoir has been filled, otherwise FALSE *************************************************************************/ BOOL getReservoirFillStatus( DG_RESERVOIR_ID_T reservoirID ) { return reservoirStatus[ reservoirID ].fillComplete; } /*********************************************************************//** * @brief * The getPreTreatmentSubState function gets the current * pre-treatment mode state. * @details Inputs: currentPreTreatmentState * @details Outputs: none * @return currentPreTreatmentState *************************************************************************/ HD_PRE_TREATMENT_MODE_STATE_T getPreTreatmentSubState( void ) { return currentPreTreatmentState; } /*********************************************************************//** * @brief * The publishPreTreatmentState function broadcasts pre-treatment sub-mode * and current sub-mode state. * @details Inputs: pre-treatment sub-mode, state * @details Outputs: pre-treatment sub-mode, state messages sent on interval * @return none *************************************************************************/ static void publishPreTreatmentState( void ) { // Broadcast treatment time and state data at interval if ( ++preTreatmentPublishTimerCounter >= getU32OverrideValue( &preTreatmentModePublishInterval ) ) { PRE_TREATMENT_STATE_DATA_T preTreatmentData; preTreatmentData.preTreatmentSubMode = currentPreTreatmentState; preTreatmentData.sampleWaterState = getSampleWaterState(); preTreatmentData.consumableSelfTestsState = getConsumableSelfTestState(); preTreatmentData.noCartSelfTestsState = getNoCartSelfTestsState(); preTreatmentData.installState = 0; preTreatmentData.drySelfTestsState = getDrySelfTestsState(); preTreatmentData.primeState = getPrimeState(); preTreatmentData.recircState = getPreTreatmentRecircState(); preTreatmentData.patientConnectionState = (U32)currentPreTxPatConnState; preTreatmentData.wetSelfTestsState = getWetSelfTestState(); preTreatmentData.preTreatmentRsrvrState = currentReservoirMgmtState; broadcastData( MSG_ID_PRE_TREATMENT_STATE_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&preTreatmentData, sizeof( PRE_TREATMENT_STATE_DATA_T ) ); preTreatmentPublishTimerCounter = 0; } } /*********************************************************************//** * @brief * The resetSignalFlags function resets all signal flags. * @details Inputs: none * @details Outputs: signal flags set to FALSE * @return none *************************************************************************/ static void resetSignalFlags( void ) { treatmentStartRequested = FALSE; confirmInstallRequested = FALSE; continueToTreatmentRequested = FALSE; alarmActionResumeReceived = FALSE; } /*********************************************************************//** * @brief * The transitionToCartridgeInstallation function prepares actuators before * transition to pre-treatment install state. * @details Inputs: none * @details Outputs: valves are in insert position * @return none *************************************************************************/ static void transitionToCartridgeInstallation( void ) { VALVE_T valve; doorClosedRequired( FALSE, FALSE ); // Set valves for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) { setValvePosition( valve, VALVE_POSITION_A_INSERT_EJECT ); } setValveAirTrap( STATE_CLOSED ); // Pumps should be off signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); stopSyringePump(); } /*********************************************************************//** * @brief * The transitionToPatientConnection function prepares actuators before * transition to pre-treatment patient connection state. * @details Inputs: none * @details Outputs: setUFVolStatus, doorOpened, patientConnectionConfirm, * treatmentStartRequested, signalTestConfigRsrvrMgmtUse, * currentReservoirMgmtState * @return none *************************************************************************/ static void transitionToPatientConnection( void ) { VALVE_T valve; setUFVolStatus = FALSE; doorOpened = FALSE; patientConnectionConfirm = FALSE; treatmentStartRequested = FALSE; // Signal the reservoir management to use the test configuration reservoir management to drain the reservoirs // to target volume in case the inactive reservoir was filled to more than the target volume // Set the reservoir management state machine to be start again. The reservoir management was set to // complete at the end of the prime signalTestConfigRsrvrMgmtUse = TRUE; currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; doorClosedRequired( FALSE, TRUE ); for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) { setValvePosition( valve, VALVE_POSITION_C_CLOSE ); } signalBloodPumpHardStop(); signalDialOutPumpHardStop(); setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); cmdStartDGTrimmerHeater(); if ( TRUE == getTestConfigStatus( TEST_CONFIG_EXPEDITE_PRE_TREATMENT ) ) { setOcclusionInstallLevel(); } } /*********************************************************************//** * @brief * The handleWaterSampleState function handles sample water state during * pre-treatment mode. * @details Inputs: none * @details Outputs: executed sample water state machine * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_WATER_SAMPLE_STATE; DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); execSampleWater(); if ( SAMPLE_WATER_COMPLETE_STATE == getSampleWaterState() ) { cmdDGSampleWater( SAMPLE_WATER_CMD_END ); if ( SELF_TEST_STATUS_PASSED == getSampleWaterResult() ) { if ( ( DG_MODE_STAN == dgOpMode ) && ( DG_STANDBY_MODE_STATE_IDLE == dgSubMode ) ) { state = HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; cmdStartDG(); transitionToConsumableSelfTest(); } else { cmdStopDG(); } } else { requestNewOperationMode( MODE_STAN ); } } return state; } /*********************************************************************//** * @brief * The handleSelfTestConsumableState function handles consumable self-test state * during pre-treatment mode. * @details Inputs: submodeCompleteTransitionTimeCounter * @details Outputs: execute consumable self-test state machine * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; execConsumableSelfTest(); if ( CONSUMABLE_SELF_TESTS_COMPLETE_STATE == getConsumableSelfTestState() ) { if ( submodeCompleteTransitionTimeCounter++ >= SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ) { submodeCompleteTransitionTimeCounter = 0; state = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; fillReservoirOneStartRequested = TRUE; transitionToNoCartSelfTests(); } signalAllowDGFlushFills(); } return state; } /*********************************************************************//** * @brief * The handleSelfTestNoCartState function handles self-test with no cartridge. * @details Inputs: none * @details Outputs: home blood pump and dialysate pumps * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; signalResumeSelfTests(); } execNoCartSelfTests(); if ( NO_CART_SELF_TESTS_COMPLETE_STATE == getNoCartSelfTestsState() ) { if ( submodeCompleteTransitionTimeCounter++ >= SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ) { submodeCompleteTransitionTimeCounter = 0; state = HD_PRE_TREATMENT_CART_INSTALL_STATE; doorOpened = FALSE; setCurrentSubState( NO_SUB_STATE ); transitionToCartridgeInstallation(); } } return state; } /*********************************************************************//** * @brief * The handleInstallState function handles disposable installation. * @details Inputs: confirmInstallRequested * @details Outputs: transition to prime sub-mode when blood pump finished * homing * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_CART_INSTALL_STATE; #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { confirmInstallRequested = TRUE; } #endif handleDoorCloseAfterCartridgeInsertion(); // want to pinch off saline once door closed after cartridge install if ( TRUE == confirmInstallRequested ) { confirmInstallRequested = FALSE; state = HD_PRE_TREATMENT_SELF_TEST_DRY_STATE; transitionToDrySelfTests(); } return state; } /*********************************************************************//** * @brief * The handleSelfTestDryState function performs dry self-test. * @details Inputs: none * @details Outputs: transition to prime state on user request * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_SELF_TEST_DRY_STATE; if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; signalResumeSelfTests(); } execDrySelfTests(); if ( DRY_SELF_TESTS_COMPLETE_STATE == getDrySelfTestsState() ) { if ( submodeCompleteTransitionTimeCounter++ >= SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ) { submodeCompleteTransitionTimeCounter = 0; state = HD_PRE_TREATMENT_PRIME_STATE; transitionToPrime(); } } return state; } /*********************************************************************//** * @brief * The handlePrimeState function handles priming the blood and dialysate * circuits. * @details Inputs: none * @details Outputs: transition to self test wet state after priming passed * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_PRIME_STATE; if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; signalResumePrime(); } execPrime(); if ( HD_PRIME_COMPLETE == getPrimeState() ) { if ( submodeCompleteTransitionTimeCounter++ >= SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ) { submodeCompleteTransitionTimeCounter = 0; state = HD_PRE_TREATMENT_RECIRCULATE_STATE; activateAlarmNoData( ALARM_ID_HD_PRIME_COMPLETED_LOW_PRIORITY ); transitionToPreTreatmentRecirc(); } } return state; } /*********************************************************************//** * @brief * The handleRecirculateState function handles blood and dialysate circuits * recirculation state during pre-treatment mode. * @details Inputs: none * @details Outputs: controlled valves and pumps * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ) { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_RECIRCULATE_STATE; if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; signalResumePreTreatmentRecirc(); } execPreTreatmentRecirc(); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { continueToTreatmentRequested = TRUE; } #endif if ( TRUE == continueToTreatmentRequested ) { continueToTreatmentRequested = FALSE; state = HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; transitionToPatientConnection(); } return state; } /*********************************************************************//** * @brief * The handlePatientConnectionState function handles patient connection state * during pre-treatment mode. * @details Inputs: currentPreTxPatConnState, alarmActionResumeReceived * @details Outputs: currentPreTxPatConnState * @return current state (sub-mode) *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ) { HD_PRE_TREATMENT_PAT_CONN_STATE_T priorSubState = currentPreTxPatConnState; switch ( currentPreTxPatConnState ) { case PRE_TREATMENT_PAT_CONN_WAIT_FOR_UF_VOL_STATE: currentPreTxPatConnState = handlePatientConnectionWait4UFVolState(); break; case PRE_TREATMENT_PAT_CONN_WAIT_FOR_DLZR_INVERT_STATE: currentPreTxPatConnState = handlePatientConnectionWait4DialyzerInvertState(); break; case PRE_TREATMENT_PAT_CONN_WAIT_FOR_USER_CONFIRM_STATE: currentPreTxPatConnState = handlePatientConnectionWait4UserConfirmState(); break; case PRE_TREATMENT_PAT_CONN_WAIT_FOR_TREATMENT_START_STATE: currentPreTxPatConnState = handlePatientConnectionWait4TreatmentStartState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_PRE_TREATMENT_PAT_CONN_STATE, currentPreTxPatConnState ); break; } if ( priorSubState != currentPreTxPatConnState ) { setCurrentSubState( (U32)currentPreTxPatConnState ); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentPreTxPatConnState ); } // handle alarms w/ stop property if ( TRUE == doesAlarmStatusIndicateStop() ) { signalDialInPumpHardStop(); if ( TRUE == getTrimmerHeaterCommandedOn() ) { cmdStopDGTrimmerHeater(); } } if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); cmdStartDGTrimmerHeater(); } return HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } /*********************************************************************//** * @brief * The handlePatientConnectionDoorOpened function handles the check * for door opened in pre-treatment patient connection * sub-mode. * @details Inputs: none * @details Outputs: doorOpened * @return none *************************************************************************/ static void handlePatientConnectionDoorOpened( void ) { // Look for cartridge door to open (indicating user inverting dialyzer) if ( STATE_OPEN == getSwitchStatus( FRONT_DOOR ) ) { doorOpened = TRUE; cmdStopDGTrimmerHeater(); signalDialInPumpHardStop(); } else { setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); cmdStartDGTrimmerHeater(); } } /*********************************************************************//** * @brief * The handlePatientConnectionWait4UFVolState function handles the wait * for ultrafiltration volume setting state of pre-treatment patient connection * sub-mode. * @details Inputs: setUFVolStatus * @details Outputs: setUFVolStatus * @return next patient connection state *************************************************************************/ static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4UFVolState( void ) { HD_PRE_TREATMENT_PAT_CONN_STATE_T nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_UF_VOL_STATE; // Look for cartridge door to open and then close (indicating user inverted dialyzer) handlePatientConnectionDoorOpened(); // If UF volume set by user, move on to next state if ( TRUE == setUFVolStatus ) { setUFVolStatus = FALSE; nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_DLZR_INVERT_STATE; } return nextState; } /*********************************************************************//** * @brief * The handlePatientConnectionWait4DialyzerInvertState function handles the wait * for dialyzer invert confirmation state of pre-treatment patient connection * sub-mode. * @details Inputs: doorOpened * @details Outputs: none * @return next patient connection state *************************************************************************/ static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4DialyzerInvertState( void ) { HD_PRE_TREATMENT_PAT_CONN_STATE_T nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_DLZR_INVERT_STATE; // Look for cartridge door to open and then close (indicating user inverted dialyzer) handlePatientConnectionDoorOpened(); if ( ( TRUE == doorOpened ) && ( STATE_CLOSED == getSwitchStatus( FRONT_DOOR ) ) ) { doorClosedRequired( TRUE, TRUE ); nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_USER_CONFIRM_STATE; } return nextState; } /*********************************************************************//** * @brief * The handlePatientConnectionWait4UserConfirmState function handles the wait * for dialyzer invert confirmation state of pre-treatment patient connection * sub-mode. * @details Inputs: patientConnectionConfirm * @details Outputs: none * @return next patient connection state *************************************************************************/ static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4UserConfirmState( void ) { HD_PRE_TREATMENT_PAT_CONN_STATE_T nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_USER_CONFIRM_STATE; if ( TRUE == patientConnectionConfirm ) { nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_TREATMENT_START_STATE; } return nextState; } /*********************************************************************//** * @brief * The handlePatientConnectionWait4TreatmentStartState function handles the wait * for treatment start state of pre-treatment patient connection sub-mode. * @details Inputs: treatmentStartRequested, currentReservoirMgmtState, * doorOpened * @details Outputs: none * @return next patient connection state *************************************************************************/ static HD_PRE_TREATMENT_PAT_CONN_STATE_T handlePatientConnectionWait4TreatmentStartState( void ) { HD_PRE_TREATMENT_PAT_CONN_STATE_T nextState = PRE_TREATMENT_PAT_CONN_WAIT_FOR_TREATMENT_START_STATE; BOOL startTreatment = TRUE; if ( ( TRUE == getTestConfigStatus( TEST_CONFIG_EXPEDITE_PRE_TREATMENT ) ) && ( currentReservoirMgmtState != PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE ) ) { startTreatment = FALSE; } if ( ( TRUE == treatmentStartRequested ) && ( TRUE == startTreatment ) ) { DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); patientConnectionConfirm = FALSE; doorOpened = FALSE; setStartReservoirVolume( activeRes ); requestNewOperationMode( MODE_TREA ); } return nextState; } /*********************************************************************//** * @brief * The execPreTreatmentReservoirMgmt function executes the state machine for * reservoir management during pre-treatment mode. * @details Inputs: currentReservoirMgmtState * @details Outputs: DG reservoirs' fills managed. * @return none *************************************************************************/ static void execPreTreatmentReservoirMgmt( void ) { // treatment reservoir mgmt. state machine switch ( currentReservoirMgmtState ) { case PRE_TREATMENT_RESERVOIR_MGMT_START_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtStartState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtDrainCmdState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtDrainCmdRespState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtFillCmdState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtFillCmdRespState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtFillCompleteState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtRequestReservoirSwitchState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE: currentReservoirMgmtState = handlePreTreatmentReservoirMgmtWaitReservoirSwitchState(); break; case PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE: // retry the DG park concentrate pump request command if previous request was failed. handleDGParkConcentratePumpsCmdRespState(); break; default: currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_RESERVOIR_MGMT_INVALID_STATE, currentReservoirMgmtState ); break; } } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtStartState function handles reservoir * management start state for pre-treatment mode. * @details Inputs: fillReservoirOneStartRequested * @details Outputs: fillReservoirOneStartRequested * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtStartState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; if ( TRUE == fillReservoirOneStartRequested ) { DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; rsrvrCmd.useLastTrimmerHeaterDC = FALSE; fillReservoirOneStartRequested = FALSE; state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; cmdSetDGActiveReservoir( &rsrvrCmd ); } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtDrainCmdState function sends drain * command to DG when DG is in re-circulate mode. * @details Inputs: none * @details Outputs: processed fill reservoir one request * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); // If DG has not started yet, start DG if ( DG_MODE_STAN == dgOpMode ) { cmdStartDG(); } // Ensure any pending reservoir switches are completed before sending drain command if ( TRUE == hasDGCompletedReservoirSwitch() ) { if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE, FALSE, TRUE ); } } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtDrainCmdRespState function waits * and processes DG drain command response. * @details Inputs: DG drain command response * @details Outputs: processed DG drain command response * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdRespState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; DG_CMD_RESPONSE_T dgCmdResp; DG_OP_MODE_T dgOpMode = getDGOpMode(); // Check DG response to drain command if ( TRUE == getDGCommandResponse( DG_CMD_START_DRAIN, &dgCmdResp ) ) { if ( DG_CMD_REQUEST_REJECT_REASON_NONE == dgCmdResp.rejectCode ) { if ( DG_MODE_DRAI == dgOpMode ) { state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; } } else { state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; } } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtFillCmdState function sends fill * command to DG when DG is in re-circulate mode. * @details Inputs: DG operation mode, DG operation sub-mode, * reservoirStatus.flushedStatus, reservoirStatus * @details Outputs: sent fill command to DG * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); U32 dialysateFlowMLPM = ( HD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ? DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN : PRE_TREATMENT_HEATING_DIA_FLOW_ML_PER_MIN ); if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { U32 volume = 0; // Drain both reservoirs and return to active res 2 before initial fills if ( reservoirStatus[ inactiveReservoir ].initialDrain != TRUE ) { reservoirStatus[ inactiveReservoir ].initialDrain = TRUE; state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; } // Determine target fill volume for next fill volume = getPreTreatmentFillVolume( inactiveReservoir ); // Determine whether we can start next fill yet if ( ( FALSE == reservoirStatus[ inactiveReservoir ].flushComplete ) && ( TRUE == reservoirStatus[ inactiveReservoir ].startFlushFill ) ) { cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); setPreTreatmentHeatingParams( PRE_TREATMENT_FLUSH_FILL_TARGET_TEMP_C, volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM, dialysateFlowMLPM ); state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; } else if ( ( TRUE == reservoirStatus[ inactiveReservoir ].flushComplete ) && ( TRUE == reservoirStatus[ inactiveReservoir ].startNormalFill ) ) { cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); setPreTreatmentHeatingParams( PRE_TREATMENT_NORMAL_FILL_TARGET_TEMP_C, volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM, dialysateFlowMLPM ); state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; } } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtFillCmdRespState function waits * and processes DG fill command response. * @details Inputs: DG fill command response * @details Outputs: processed DG fill command response * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdRespState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; DG_CMD_RESPONSE_T dgCmdResp; DG_OP_MODE_T dgOpMode = getDGOpMode(); // handle fill command response from DG if ( TRUE == getDGCommandResponse( DG_CMD_START_FILL, &dgCmdResp ) ) { if ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejectCode ) { state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; } else if ( dgCmdResp.rejectCode != DG_CMD_REQUEST_REJECT_REASON_NONE ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DG_INVALID_FILL_COMMAND_REJECTED, dgCmdResp.rejectCode ) } } // wait for DG to begin filling before moving on to next state if ( DG_MODE_FILL == dgOpMode ) { state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE; } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtFillCompleteState function switches * reservoir after the first one fill is complete and restart reservoir management * state machine. * @details Inputs: DG operation mode, reservoirStatus[] * @details Outputs: switch active reservoir and signal prime fill complete status, * reservoirStatus[] * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCompleteState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE; DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); DG_RESERVOIR_ID_T activeReservoir = getDGActiveReservoir(); if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; if ( ( TRUE == reservoirStatus[ DG_RESERVOIR_1 ].flushComplete ) && ( TRUE == reservoirStatus[ DG_RESERVOIR_2 ].flushComplete ) ) { reservoirStatus[ inactiveReservoir ].fillComplete = TRUE; } else { // Start tracking flush cycles, flushComplete => don't drain again, this completes the final fill. if ( FALSE == reservoirStatus[ inactiveReservoir ].flushComplete ) { reservoirStatus[ inactiveReservoir ].flushCount--; if ( 0 == reservoirStatus[ inactiveReservoir ].flushCount ) { reservoirStatus[ inactiveReservoir ].flushComplete = TRUE; } } } } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtRequestReservoirSwitchState function waits * until prime operation switches the active reservoir before filling up next reservoir. * @details Inputs: DG inactive reservoir * @details Outputs: start filling next reservoir * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtRequestReservoirSwitchState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); BOOL waitBeforeSwitch = TRUE; //wait after drain or fill if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { // We do not want to switch over to res 2 final fill until prime is ready for it. #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) { waitBeforeSwitch = FALSE; } #endif if ( TRUE == reservoirStatus[ DG_RESERVOIR_2 ].fillComplete ) { if ( ( getPreTreatmentSubState() > HD_PRE_TREATMENT_PRIME_STATE ) || ( ( HD_PRE_TREATMENT_PRIME_STATE == getPreTreatmentSubState() ) && ( getPrimeState() >= HD_PRIME_RESERVOIR_TWO_FILL_COMPLETE_STATE ) && ( getPrimeState() < HD_PRIME_PAUSE ) ) ) { waitBeforeSwitch = FALSE; } } else { waitBeforeSwitch = FALSE; } if ( waitBeforeSwitch != TRUE ) { DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; rsrvrCmd.reservoirID = (U32)inactiveReservoir; rsrvrCmd.useLastTrimmerHeaterDC = TRUE; state = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; cmdSetDGActiveReservoir( &rsrvrCmd ); } } return state; } /*********************************************************************//** * @brief * The handlePreTreatmentReservoirMgmtWaitReservoirSwitchState function waits * until prime operation switches the active reservoir before filling up next reservoir. * @details Inputs: DG inactive reservoir * @details Outputs: start filling next reservoir * @return current state of pre-treatment reservoir management *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtWaitReservoirSwitchState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; DG_CMD_RESPONSE_T dgCmdResp; // handle fill command response from DG if ( TRUE == getDGCommandResponse( DG_CMD_SWITCH_RESERVOIR, &dgCmdResp ) ) { if ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejectCode ) { state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; } else if ( dgCmdResp.rejectCode != DG_CMD_REQUEST_REJECT_REASON_NONE ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DG_INVALID_FILL_COMMAND_REJECTED, dgCmdResp.rejectCode ) } else { if ( ( TRUE == reservoirStatus[ DG_RESERVOIR_1 ].fillComplete ) && ( TRUE == reservoirStatus[ DG_RESERVOIR_2 ].fillComplete ) ) { F32 targetTempC = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); U32 dialysateFlowMLPM = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); // Set the heating parameters setPreTreatmentHeatingParams( targetTempC, FILL_RESERVOIR_TO_VOLUME_ML, DEFAULT_TARGET_FILL_FLOW_RATE_LPM, dialysateFlowMLPM ); // after reservoir fill at end of the pre-treatment, do park the concentrate pumps to maintain conductivity // when treatment begins cmdDGParkConcentratePumps(); state = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; } else { state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; } } } return state; } /*********************************************************************//** * @brief * The handleDGParkConcentratePumpsCmdRespState function checks * Park DG concentrate pump command request sent was successfully handled or not. * on failure, retry the DG Concentrate pumps park command request. * @details Inputs: DG park concentrate pump request command response * @details Outputs: retry park command on failure * @return none *************************************************************************/ static void handleDGParkConcentratePumpsCmdRespState( void ) { DG_CMD_RESPONSE_T dgCmdResp; // Check DG response to park concentrate pumps command if ( TRUE == getDGCommandResponse( DG_CMD_PARK_CONCENTRATE_PUMPS, &dgCmdResp ) ) { if ( DG_CMD_REQUEST_REJECT_REASON_NONE != dgCmdResp.rejectCode ) { // retry park concentrate pumps command request to DG cmdDGParkConcentratePumps(); } } } /*********************************************************************//** * @brief * The getPreTreatmentFillVolume function determines which volume to fill * the inactive reservoir. * @details Inputs: reservoirStatus[] * @details Outputs: none * @param DG inactive Reservoir * @return volume to fill *************************************************************************/ static U32 getPreTreatmentFillVolume( DG_RESERVOIR_ID_T inactiveRes ) { U32 volume = 0; // Fill volumes after flushing if ( TRUE == reservoirStatus[ inactiveRes ].flushComplete ) { #ifndef _RELEASE_ if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) || ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_WET_SELF_TEST ) ) ) { if ( DG_RESERVOIR_1 == inactiveRes ) { volume = PRE_TREATMENT_FULL_RESERVOIR_VOLUME_ML; } // Reservoir 2 else { volume = PRE_TREATMENT_MIN_FILL_RESERVOIR_VOLUME_ML; } } else #endif { if ( DG_RESERVOIR_1 == inactiveRes ) { volume = PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML; } // Reservoir 2 else { volume = PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML; } } } // Flush fill volumes else { volume = PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML; } return volume; } /*********************************************************************//** * @brief * The setPreTreatmentHeatingParams function calculates and set the heating * parameters to be sent to DG. * @details Inputs: none * @details Outputs: none * @param targetTempC target temperature in C * @param targetVolML target fill volume in milliliters * @param targetFillFlowLPM target fill flow rate in L/min * @param dialysateFlowMLPM dialysate flow in mL/min * @return none *************************************************************************/ static void setPreTreatmentHeatingParams( F32 targetTempC, U32 targetVolML, F32 targetFillFlowLPM, U32 dialysateFlowMLPM ) { DG_CMD_DIALYSATE_HEATING_PARAMS_T params; F32 fillTimeMS = ( (F32)targetVolML / ( targetFillFlowLPM * ML_PER_LITER ) ) * SEC_PER_MIN * MS_PER_SECOND; params.trimmerTargetTemperature = targetTempC; params.timeReservoirWait2SwitchMS = 0; params.timeReservoirFillMS = fillTimeMS; params.timeReservoirCycleMS = (U32)fillTimeMS; params.dialysateFlowLPM = ( (F32)dialysateFlowMLPM ) / ML_PER_LITER; params.usePriTargetTempEquation = FALSE; cmdSetDGDialysateHeatingParams( params ); } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The execPreTreatmentTestConfigReservoirMgmt function executes the state * machine for reservoir management during pre-treatment mode when a test * configuration (expedite pre-treatment test config for now) is enabled. * @details Inputs: currentReservoirMgmtState * @details Outputs: currentReservoirMgmtState * @return none *************************************************************************/ static void execPreTreatmentTestConfigReservoirMgmt( void ) { DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; DG_CMD_RESPONSE_T dgCmdResp; F32 reservoir1Level = getReservoirWeight( DG_RESERVOIR_1 ); F32 reservoir2Level = getReservoirWeight( DG_RESERVOIR_2 ); DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); // If DG has not started yet, start DG if ( DG_MODE_STAN == dgOpMode ) { cmdStartDG(); } switch( currentReservoirMgmtState ) { case PRE_TREATMENT_RESERVOIR_MGMT_START_STATE: if ( DG_MODE_GENE == dgOpMode ) { rsrvrCmd.useLastTrimmerHeaterDC = FALSE; if ( ( reservoir1Level >= PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML ) && ( reservoir1Level < PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) ) { // Assume a reservoir switch is not needed and transition to the complete state because we are done currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; if ( DG_RESERVOIR_2 == getDGActiveReservoir() ) { // Reservoir 1 has the right volume, set it to active reservoir and wait for it to be done rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; cmdSetDGActiveReservoir( &rsrvrCmd ); } } else if ( reservoir1Level >= PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) { // Reservoir 1 needs a partial drain so set it to be inactive so DG can drain it if ( DG_RESERVOIR_1 == getDGActiveReservoir() ) { rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; cmdSetDGActiveReservoir( &rsrvrCmd ); } currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; } else if ( ( reservoir2Level >= PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML ) && ( reservoir2Level < PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) ) { // Reservoir 2 is in the right level, just make sure it is the active reservoir // Assume a reservoir switch is not needed and transition to the complete state because we are done currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; if ( DG_RESERVOIR_1 == getDGActiveReservoir() ) { rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; cmdSetDGActiveReservoir( &rsrvrCmd ); } } else if ( reservoir2Level >= PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) { if ( DG_RESERVOIR_2 == getDGActiveReservoir() ) { rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; cmdSetDGActiveReservoir( &rsrvrCmd ); } currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; } } break; case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE: // Ensure any pending reservoir switches are completed before sending drain command if ( TRUE == hasDGCompletedReservoirSwitch() ) { if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; cmdStartDGDrain( PRE_TREATMENT_FULL_RESERVOIR_VOLUME_ML, FALSE, FALSE, TRUE ); } } break; case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE: // Check DG response to drain command if ( TRUE == getDGCommandResponse( DG_CMD_START_DRAIN, &dgCmdResp ) ) { if ( DG_CMD_REQUEST_REJECT_REASON_NONE == dgCmdResp.rejectCode ) { if ( DG_MODE_DRAI == dgOpMode ) { currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; } } else { currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; } } break; case PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE: if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); rsrvrCmd.reservoirID = ( DG_RESERVOIR_1 == inactiveReservoir ? (U32)DG_RESERVOIR_1 : (U32)DG_RESERVOIR_2 ); rsrvrCmd.useLastTrimmerHeaterDC = FALSE; cmdSetDGActiveReservoir( &rsrvrCmd ); currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; } break; case PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE: if ( TRUE == hasDGCompletedReservoirSwitch() ) { currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; } break; case PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE: // Done with test configuration reservoir management. Do nothing. break; } } /*********************************************************************//** * @brief * The testSetPreTreatmentModePublishIntervalOverride function sets the override of the * pre-treatment mode data publication interval. * @details Inputs: none * @details Outputs: preTreatmentModePublishInterval * @param ms milliseconds between pre-treatment mode broadcasts * @return TRUE if override set successful, FALSE if not *************************************************************************/ BOOL testSetPreTreatmentModePublishIntervalOverride( U32 ms ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = ms / TASK_GENERAL_INTERVAL; result = TRUE; preTreatmentModePublishInterval.ovData = intvl; preTreatmentModePublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetPreTreatmentModePublishIntervalOverride function resets the override of the * pre-treatment mode data publication interval. * @details Inputs: none * @details Outputs: preTreatmentModePublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetPreTreatmentModePublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; preTreatmentModePublishInterval.override = OVERRIDE_RESET; preTreatmentModePublishInterval.ovData = preTreatmentModePublishInterval.ovInitData; } return result; } /**@}*/