Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r3325bb3ddb5961167139a9db37b7098083b7b83d -r7acc14a8f6eeaf6b26757fc2b5d2f6fc7edbdcec --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 3325bb3ddb5961167139a9db37b7098083b7b83d) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 7acc14a8f6eeaf6b26757fc2b5d2f6fc7edbdcec) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2025 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 ModeFill.c * * @author (last) Dara Navaei -* @date (last) 26-Apr-2023 +* @date (last) 27-Feb-2025 * * @author (original) Leonardo Baloa * @date (original) 19-Nov-2019 @@ -52,33 +52,36 @@ #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define RO_PUMP_400_ML_PER_MIN 400.0F ///< RO pump speed of 400.0 mL/minute. #define RO_PUMP_800_ML_PER_MIN 800.0F ///< RO pump speed of 800.0 mL/minute. -#define TARGET_RO_FLOW_RATE_IN_PAUSE_L 0.3F ///< Target flow rate for RO pump during pause in liters. +#define TARGET_RO_FLOW_RATE_IN_PAUSE_L 0.8F ///< Target flow rate for RO pump during pause in liters. #define MILLILITERS_PER_LITER 1000.0F ///< One liter is 1000 milliliters -#define ACID_PUMP_20_ML_PER_MIN 20.0F ///< Acid pump speed of 20.0 mL/minute. +#define ACID_PUMP_23_ML_PER_MIN 23.0F ///< Acid pump speed of 23.0 mL/minute. #define BICARB_PUMP_40_ML_PER_MIN 40.0F ///< Bicarb pump speed of 40.0 mL/minute. #define CONCENTRATE_PUMP_40_ML_PER_MIN 40.0F ///< Concentrate pump speed of 40.0 mL/minute. #define FILL_MODE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the fill mode data is published on the CAN bus. #define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. -#define CONCENTRATE_PUMP_PRIME_INTERVAL ( 10 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Persistent time interval for concentrate pumps prime. - +#define CONC_PUMPS_PRIME_AT_MAX_SPEED_TIME_OUT_MS ( 10 * MS_PER_SECOND ) ///< Concentrate pumps prime at maximum speed timeout in milliseconds. +#define CONC_PUMPS_PRIME_CHECK_COND_SNSRS_TIME_OUT_MS ( 13 * MS_PER_SECOND ) ///< Concentrate pumps prime check conductivity sensors timeout in milliseconds. +#define CONC_PUMPS_PRIME_MAX_ALLOWED_PRIME_TIME_OUT_MS ( 45 * MS_PER_SECOND ) ///< Concentrate pumps prime maximum allowed timeout in prime in milliseconds. +#define HUNDRED_PERCENT_FACTOR 1.00F ///< Hundred percent of expected conductivity when first time reaches it. #define FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE 0.1F ///< Flow integrated volume has 10% tolerance compare to load cell reading. #define FIVE_PERCENT_FACTOR 0.05F ///< 5.0 / 100.0 used to calculate conductivity within range of -/+ 5%. +#define BICARB_CHECK_TOL_FACTOR 0.2F ///< Bicarb check tolerance factor. +#define ACID_CHECK_TOL_FACTOR 0.1F ///< Acid check tolerance factor. #define RO_PUMP_LOOKUP_TABLE_SIZE 4 ///< Size of array used as RO pump speed lookup table. #define CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN 5.0F ///< Concentrate pump additional speed during priming in mL/min. #define CONCENTRATE_TEST_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Concentrate test time out period in ms. #define DELAY_FMP_CHECK_START_BY_MS ( 10 * MS_PER_SECOND ) ///< Delay start of FMP check during dialysate deliver state by this amount of time (in ms). #define CONCENTRATE_TEST_COND_COLLECTION_DELAY_MS ( 5 * MS_PER_SECOND ) ///< Concentrate test conductivity data collection delay in milliseconds. -#define MAX_RO_REJECTION_RATIO_ALLOW 0.10F ///< Maximum RO rejection ratio. #define MAX_CPO_CONDUCTIVITY_ALLOW 100.0F ///< Maximum CPo sensor conductivity value. #define MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML 550 ///< Minimum fill target to check the RO and CPo alarms in milliliters. // 2m long tubing to cap = 19.5 mL (acid line) + 7.92 mL/m * 2 m (tubing to cap) + 20.82 mL (straw) = 56.15 mL // Prime time in seconds = ( 56.15 mL / 48 mL/min ) x 60 second/min + 25 seconds margin time = 95 seconds. -#define PRIME_CONCENTRATE_LINES_TIME_OUT_MS ( 60 * MS_PER_SECOND ) ///< Time required to prime the concentrate lines. +#define PRIME_CONCENTRATE_LINES_TIME_OUT_MS ( 95 * MS_PER_SECOND ) ///< Time required to prime the concentrate lines. #define FLUSH_BUBBLES_PUMP_TIME_OUT_MS ( 2 * MS_PER_SECOND ) ///< RO pump on during flush bubble interval in ms. #define DIALYSATE_TEMPERATURE_TOLERANCE_C 2.0F ///< Dialysate temperature tolerance in degree C. #define DATA_PUBLISH_COUNTER_START_COUNT 63 ///< Data publish counter start count. @@ -93,6 +96,16 @@ // ********** private data ********** +/// Fill for calibration check enumeration from dialin +typedef enum dialin_fill_for_cal +{ + DIALIN_FILL_FOR_CAL_PRIME = 0, ///< Dialin fill for calibration prime. + DIALIN_FILL_FOR_CAL_BICARB_CHECK, ///< Dialin fill for calibration bicarb check. + DIALIN_FILL_FOR_CAL_ACID_CHECK, ///< Dialin fill for calibration acid check. + DIALIN_FILL_FOR_CAL_NONE, ///< Dialin fill for calibration none. + NUM_OF_DIALIN_FILL_FOR_CAL ///< Number of dialin fill for calibration. +} DIALIN_FILL_FOR_CAL_CHECK_T; + /// Fill conditions status typedef struct { @@ -114,14 +127,17 @@ static U32 dataPublishCounter; ///< Used to schedule dialysate fill data publication to CAN bus. static DG_FILL_MODE_STATE_T fillState; ///< Currently active fill state. -static U32 dialysateFillStartTime; ///< Current time when starting to fill dialysate. static F32 reservoirBaseWeight; ///< Fill reservoir base weight. static FILL_CONDITION_STATUS_T fillStatus; ///< Fill condition status. +static BOOL didFillRecoverFromPause; ///< Flag to indicate whether the previous state was pause or not. +static U32 dialysateFillStartTimeMS; ///< Current time when starting to fill dialysate in milliseconds. +static U32 dialysatePauseStartTimeMS; ///< Current time when starting a pause during fill dialysate in milliseconds. +static U32 dialysatePauseElapsedTimeMS; ///< Elapsed time in pause during fill dialysate in milliseconds. static U32 concentrateTestStartTime; ///< Starting time for concentrate test. static U32 concentratePrimingStartTime; ///< Starting time for concentrate priming. static U32 flushBubblesStartTime; ///< Starting time for flush bubbles. -static U32 concentratePumpPrimeCount; ///< Interval count for concentrate pump prime. +static U32 concPumpPrimeStartTimeMS; ///< Concentrate pump prime start time in milliseconds. static BOOL didFMPCheckStart; ///< Flag indicates whether FMP flow vs. LC volume check has begun. static F32 acidConductivityTotal; ///< Total of acid conductivity during fill. @@ -143,14 +159,19 @@ static U32 fillCPoConductivitySampleCnt; ///< Number of samples in sum of CPo and Rej. Ratio conductivity readings for fill. static U32 pumpSpeedIndex; ///< Index used to access the desired pump speed in roPumpFlushBubblesSpeed table. -static BOOL havePauseActuatorsBeenSet; ///< Flag to indicate the actuators have been set to pause for the first time. static FILL_ACID_BICARB_TYPES_T chemicalsTypes; ///< Chemicals Types (acid and bicarb). +static DG_CHEMICALS_FILL_COND_CAL_RECORD_T chemicalsCond; ///< Chemicals fill conductivity records. +static F32 acidMixRatio; ///< Acid conductivity mix ratio. +static F32 bicarbMixRatio; ///< Bicarb conductivity mix ratio. // NOTE: This variable should be initialized here because the init function is called every time and then this variable is set to FALSE even if the settings from the // UI wants the RO only mode. static BOOL hasROOnlyModeBeenEnabled = FALSE; ///< Flag to indicate the RO only mode has been set or not. -static OVERRIDE_F32_T usedAcidVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated acid concentration volume has been used in mL. -static OVERRIDE_F32_T usedBicarbVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated bicarb concentration volume has been used in mL. +// NOTE: This variable should be initialized here because the init function is called every time and then it cannot be initialized there. This variable is +// set via Dialin for calibration check purposes only +static DIALIN_FILL_FOR_CAL_CHECK_T dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; ///< Dialin fill for calibration check. +// NOTE: this variable should be initialized here because the init function is called every time and then this variable is set to 0.0. +static F32 maxRORejectionRatioFromHD = 0.0F; ///< Max RO rejection ratio from HD. static OVERRIDE_U32_T fillModeDataPublishInterval = { FILL_MODE_DATA_PUB_INTERVAL, FILL_MODE_DATA_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish fill mode data to CAN bus. static OVERRIDE_F32_T integratedVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< Total RO flow rate over period of time. @@ -166,10 +187,10 @@ static DG_FILL_MODE_STATE_T handleDeliverDialysateState( void ); static DG_FILL_MODE_STATE_T handlePausedState( void ); +static void setModeFillStateTransition( DG_FILL_MODE_STATE_T state ); static BOOL areInletWaterConditionsAlarmsActive( void ); static BOOL areConductivityAlarmsActive( void ); static void handleDialysateMixing( F32 measuredROFlowRate_mL_min, F32 acidMixingRatio, F32 bicarbMixingRatio ); -static void setFillInfoToRTCRAM( void ); static BOOL isValueWithinPercentRange( F32 testValue, F32 baseValue, F32 percentFactor ); static void publishFillModeData( void ); @@ -182,29 +203,41 @@ *************************************************************************/ void initFillMode( void ) { - fillState = DG_FILL_MODE_STATE_START; - dialysateFillStartTime = 0; - dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; - reservoirBaseWeight = 0.0F; - integratedVolumeML.data = 0.0F; - didFMPCheckStart = FALSE; - concentrateTestStartTime = 0; + DG_ACID_CONCENTRATES_RECORD_T acid; + DG_BICARB_CONCENTRATES_RECORD_T bicarb; + + getAcidConcentrateCalRecord( &acid ); + getBicarbConcentrateCalRecord( &bicarb ); + + acidConductivitySampleCount = 0; acidConductivityTotal = 0.0F; + acidMixRatio = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; + averageAcidConductivity = 0.0F; + averageBicarbConductivity = 0.0F; + bicarbConductivitySampleCount = 0; bicarbConductivityTotal = 0.0F; + bicarbMixRatio = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + concentrateTestStartTime = 0; + concPumpPrimeStartTimeMS = getMSTimerCount(); conductivitySampleCount = 0; - concentratePumpPrimeCount = 0; - pumpSpeedIndex = 0; - averageBicarbConductivity = 0.0F; - averageAcidConductivity = 0.0F; + dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + // This timer is set to 0 to be checked whether we were in pause but this is still 0 so so we the start time regardless + // If we were filling and then went to pause we do not reset this anymore + dialysateFillStartTimeMS = 0; + dialysatePauseElapsedTimeMS = 0; + dialysatePauseStartTimeMS = 0; + didFillRecoverFromPause = FALSE; + didFMPCheckStart = FALSE; + fillCPoConductivitySampleCnt = 0; + fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; + integratedVolumeML.data = 0.0F; pctDiffInConductivity = 0.0F; - bicarbConductivitySampleCount = 0; - acidConductivitySampleCount = 0; - totalBicarbConductivity = 0.0F; - totalAcidConductivity = 0.0F; - havePauseActuatorsBeenSet = FALSE; + pumpSpeedIndex = 0; + reservoirBaseWeight = 0.0F; sumFillCPoConductivity = 0.0F; sumFillRejRatio = 0.0F; - fillCPoConductivitySampleCnt = 0; + totalAcidConductivity = 0.0F; + totalBicarbConductivity = 0.0F; } /*********************************************************************//** @@ -216,19 +249,90 @@ *************************************************************************/ U32 transitionToFillMode( void ) { - initFillMode(); + F32 targetFlowLPM = getTargetFillFlowRateLPM(); + initFillMode(); + setCurrentSubState( NO_SUB_STATE ); // Set initial actuator states setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); +#if !defined(DEBUG_ENABLED) && !defined (_RELEASE_) && !defined (_VECTORCAST_) + // Compile this part of code only if it is not debug, release, or VectorCAST. This is to make sure this part of code is not compiled + // and instrumented in VectorCAST + // Reset the state machine + // Note: the substate timers, and operation flags need to be reset on recovery, consider + // reinitializing the state variables, the resetting the state, by calling setModeFillStateTransition() + if ( ( TRUE == getTestConfigStatus( TEST_CONFIG_RECOVER_TREATMENT ) ) && ( DG_MODE_FAUL == getPreviousOperationMode() ) ) + { // Restore the prior fillstate to a valid, running fill state, with timer state reset. + fillState = restoreFillState; + + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + + switch( fillState ) + { + case DG_FILL_MODE_STATE_TEST_INLET_WATER: + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + break; + + case DG_FILL_MODE_STATE_PRIME_CONCENTRATE_LINES: + targetFlowLPM = RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER; + concentratePrimingStartTime = getMSTimerCount(); + + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONCENTRATE_PUMP_MAX_SPEED ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + break; + + case DG_FILL_MODE_STATE_FLUSH_BUBBLES: + case DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY: + case DG_FILL_MODE_STATE_TEST_ACID_CONDUCTIVITY: + // For the above states, transition back to flush bubbles state + pumpSpeedIndex = 0; + targetFlowLPM = RO_PUMP_FLUSH_BUBBLES_FLOWS[ pumpSpeedIndex ] / MILLILITERS_PER_LITER; + flushBubblesStartTime = getMSTimerCount(); + fillState = DG_FILL_MODE_STATE_FLUSH_BUBBLES; + break; + + case DG_FILL_MODE_STATE_PRODUCE_DIALYSATE: + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + + // Do the necessary setup here before transition to Produce Dialysate State + fillStatus.isThisFirstFill = FALSE; + concPumpPrimeStartTimeMS = getMSTimerCount(); + break; + + case DG_FILL_MODE_STATE_DELIVER_DIALYSATE: + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + dialysateFillStartTimeMS = getMSTimerCount(); + fillStatus.isThisFirstFill = FALSE; + break; + + case DG_FILL_MODE_STATE_PAUSED: + targetFlowLPM = TARGET_RO_FLOW_RATE_IN_PAUSE_L; + dialysatePauseStartTimeMS = getMSTimerCount(); + break; + } + } +#endif + + getFillChemicalCondRecord( &chemicalsCond ); turnOnUVReactor( INLET_UV_REACTOR ); turnOnUVReactor( OUTLET_UV_REACTOR ); // NOTE: The target flow rate should be set prior to setting the start primary heater // because the initial guess in the heaters driver needs the target flow to calculate // the new PWMs for the main and small primary heaters - setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); + setROPumpTargetFlowRateLPM( targetFlowLPM, TARGET_RO_PRESSURE_PSI ); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); startHeater( DG_PRIMARY_HEATER ); setCPLDCleanLEDColor( CPLD_CLEAN_LED_OFF ); @@ -248,18 +352,18 @@ checkDialysateTemperatureSensors(); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); - if ( ( TRUE == areInletWaterConditionsAlarmsActive() ) || ( TRUE == areConductivityAlarmsActive() ) ) + if ( fillState != DG_FILL_MODE_STATE_PAUSED ) { - fillState = DG_FILL_MODE_STATE_PAUSED; + if ( ( TRUE == areInletWaterConditionsAlarmsActive() ) || ( TRUE == areConductivityAlarmsActive() ) ) + { + setModeFillStateTransition( DG_FILL_MODE_STATE_PAUSED ); + fillState = DG_FILL_MODE_STATE_PAUSED; + } } // Execute current Fill state switch ( fillState ) { - case DG_FILL_MODE_STATE_START: - fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; - break; - case DG_FILL_MODE_STATE_TEST_INLET_WATER: fillState = handleTestInletWaterState(); break; @@ -294,10 +398,9 @@ default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_FILL_MODE_INVALID_EXEC_STATE, fillState ) - fillState = DG_FILL_MODE_STATE_START; + fillState = DG_FILL_MODE_STATE_TEST_INLET_WATER; break; } - publishFillModeData(); return fillState; @@ -351,8 +454,8 @@ *************************************************************************/ F32 getIntegratedVolumeML( void ) { + F32 integratedVolume = getF32OverrideValue( &integratedVolumeML ); - F32 integratedVolume = getF32OverrideValue(&integratedVolumeML); return integratedVolume; } @@ -391,68 +494,14 @@ /*********************************************************************//** * @brief - * The getChemicalUsedVolumeML function returns the consumed volume of the called - * chemical bottle in milliliters. - * @details Inputs: none - * @details Outputs: none - * @param bottle which the type of bottle (acid or bicarb) can be specified - * @return used chemical volume in millilters - *************************************************************************/ -F32 getChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ) -{ - F32 volume; - - if ( ACID == bottle ) - { - volume = getF32OverrideValue( &usedAcidVolumeML ); - } - else if ( BICARB == bottle ) - { - volume = getF32OverrideValue( &usedBicarbVolumeML ); - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CHEMICAL_BOTTLE_SELECTED, bottle ) - } - - return volume; -} - -/*********************************************************************//** - * @brief - * The resetChemicalUsedVolumeML function resets the used volume of a chemical - * bottle. - * @details Inputs: none - * @details Outputs: none - * @param bottle which the type of bottle (acid or bicarb) can be specified - * @return none - *************************************************************************/ -void resetChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ) -{ - if ( ACID == bottle ) - { - usedAcidVolumeML.data = 0.0F; - } - else if ( BICARB == bottle ) - { - usedBicarbVolumeML.data = 0.0F; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CHEMICAL_BOTTLE_SELECTED, bottle ) - } -} - -/*********************************************************************//** - * @brief * The setThisFisrtFillFlag function sets the boolean flag that indicates * the acid and bicarb bottle need priming. * @details Inputs: none * @details Outputs: none * @param flag to TRUE if prime is needed otherwise FALSE * @return none *************************************************************************/ -void setThisFisrtFillFlag( BOOL flag ) +void setThisFirstFillFlag( BOOL flag ) { fillStatus.isThisFirstFill = flag; } @@ -502,50 +551,73 @@ /*********************************************************************//** * @brief + * The setMaxRORejectionRatio function sets the RO rejection ratio that has + * been received from the HD institutional record. + * @details Inputs: none + * @details Outputs: roRejectionRatioFromHD + * @param RO rejection ratio + * @return none + *************************************************************************/ +void setMaxRORejectionRatio( F32 roRejectionRatio ) +{ + maxRORejectionRatioFromHD = roRejectionRatio; + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_RO_REJECTION_RATIO_FROM_HD_INSTIT_RECORD, maxRORejectionRatioFromHD, 0.0F ) +} + +/*********************************************************************//** + * @brief * The handleTestInletWaterState function tests for inlet water quality * and if this is the first fill of a treatment, prime the acid and bicarb * lines before jumping to dialysate production state. - * @details Inputs: Temperature, pressure, and conductivity alarms - * @details Outputs: request acid and bicarb pumps on + * @details Inputs: none + * @details Outputs: none * @return the next state *************************************************************************/ static DG_FILL_MODE_STATE_T handleTestInletWaterState( void ) { DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_TEST_INLET_WATER; - // If this is the first fill of a treatment, prime acid and bicarb lines, otherwise transition - // to dialysate production directly - if ( TRUE == isThisTheFirstFill() ) + if ( ( isConcPumpParkInProgress( CONCENTRATEPUMPS_CP1_ACID ) != TRUE ) && ( isConcPumpParkInProgress( CONCENTRATEPUMPS_CP2_BICARB ) ) != TRUE ) { - // Prepare the acid and bicarb pumps to prime the concentrate lines - setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); + // If this is the first fill of a treatment, prime acid and bicarb lines, otherwise transition + // to dialysate production directly + if ( TRUE == isThisTheFirstFill() ) + { + result = DG_FILL_MODE_STATE_PRIME_CONCENTRATE_LINES; - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONCENTRATE_PUMP_MAX_SPEED ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + if ( TRUE == getTestConfigStatus( TEST_CONFIG_EXPEDITE_PRE_TREATMENT ) ) + { + // If expedite pre-treatment flag is enabled, do not do the initial fill + result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; + } + } + else + { + result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; + } - concentratePrimingStartTime = getMSTimerCount(); - result = DG_FILL_MODE_STATE_PRIME_CONCENTRATE_LINES; - } - else - { - DG_ACID_CONCENTRATES_RECORD_T acid; - F32 acidMix; - DG_BICARB_CONCENTRATES_RECORD_T bicarb; - F32 bicarbMix; + if ( TRUE == isTestingActivated() ) + { + switch ( dialinFillForCalCheck ) + { + case DIALIN_FILL_FOR_CAL_PRIME: + result = DG_FILL_MODE_STATE_PRIME_CONCENTRATE_LINES; + break; - getAcidConcentrateCalRecord( &acid ); - getBicarbConcentrateCalRecord( &bicarb ); + case DIALIN_FILL_FOR_CAL_BICARB_CHECK: + result = DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY; + break; - acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; - bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + case DIALIN_FILL_FOR_CAL_ACID_CHECK: + result = DG_FILL_MODE_STATE_TEST_ACID_CONDUCTIVITY; + break; - setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); - handleDialysateMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, acidMix, bicarbMix ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; + default: + // Do nothing. This means there is not a request for the fill calibration check so proceed with the normal operations. + break; + } + } + setModeFillStateTransition( result ); } return result; @@ -555,7 +627,7 @@ * @brief * The handlePrimeConcentrateLinesState function primes the acid and bicarb * lines. - * @details Inputs: None + * @details Inputs: concentratePrimingStartTime * @details Outputs: None * @return the next state *************************************************************************/ @@ -565,15 +637,8 @@ if ( TRUE == didTimeout( concentratePrimingStartTime, PRIME_CONCENTRATE_LINES_TIME_OUT_MS ) ) { - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); - - // Set the RO pump flow rate in according to the roPumpFlushBubblesSpeed table to flush bubbles - pumpSpeedIndex = 0; - setROPumpTargetFlowRateLPM( RO_PUMP_FLUSH_BUBBLES_FLOWS[ pumpSpeedIndex ] / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); - - flushBubblesStartTime = getMSTimerCount(); - result = DG_FILL_MODE_STATE_FLUSH_BUBBLES; + result = DG_FILL_MODE_STATE_FLUSH_BUBBLES; + setModeFillStateTransition( result ); } return result; @@ -603,20 +668,8 @@ } else { - // Initialization - totalBicarbConductivity = 0.0F; - averageBicarbConductivity = 0.0F; - bicarbConductivitySampleCount = 0; - - // Set pumps flow rate to prepare for bicarb conductivity testing - setROPumpTargetFlowRateLPM( RO_PUMP_400_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); - - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_40_ML_PER_MIN ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - - // State transition - concentrateTestStartTime = getMSTimerCount(); - result = DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY; + result = DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY; + setModeFillStateTransition( result ); } } @@ -644,50 +697,28 @@ if ( TRUE == didTimeout( concentrateTestStartTime, CONCENTRATE_TEST_TIME_OUT_MS ) ) { - DG_CHEMICALS_FILL_COND_CAL_RECORD_T chemicalsCond; - F32 bicarbCondUSPerCM = 0.0F; + // In the bicarb test, the acid value is 0, so it is not queried + F32 bicarbCondUSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_BICARB_TEST ].bicarbConduSPerCM; BOOL isConductivityInRange = FALSE; - getFillChemicalCondRecord( &chemicalsCond ); - - // In the bicarb test, the acid value is 0, so it is not queried - bicarbCondUSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_BICARB_TEST ].bicarbConduSPerCM; - averageBicarbConductivity = totalBicarbConductivity / bicarbConductivitySampleCount; - if ( TRUE == isValueWithinPercentRange( averageBicarbConductivity, bicarbCondUSPerCM, FIVE_PERCENT_FACTOR ) ) - { - isConductivityInRange = TRUE; - } + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_BICARB_CHECK_RESULT, averageBicarbConductivity, bicarbCondUSPerCM ) -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_BICARB_CONDUCTIVITY_TEST ) ) + if ( TRUE == isValueWithinPercentRange( averageBicarbConductivity, bicarbCondUSPerCM, BICARB_CHECK_TOL_FACTOR ) ) { isConductivityInRange = TRUE; } -#endif - if ( ( TRUE == isConductivityInRange ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_MIXING_WITH_WATER ) ) ) + if ( ( TRUE == isConductivityInRange ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) ) ) { - // Initialization - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); - totalBicarbConductivity = 0.0F; - totalAcidConductivity = 0.0F; - bicarbConductivitySampleCount = 0; - acidConductivitySampleCount = 0; - - // Set pumps flow rate to prepare for acid conductivity testing - setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_20_ML_PER_MIN ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - // State transition - concentrateTestStartTime = getMSTimerCount(); - result = DG_FILL_MODE_STATE_TEST_ACID_CONDUCTIVITY; + result = DG_FILL_MODE_STATE_TEST_ACID_CONDUCTIVITY; + setModeFillStateTransition( result ); } else { // Bicarb test failed, go to fault - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_BICARB_CONDUCTIVITY_OUT_OF_RANGE, averageBicarbConductivity ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_BICARB_CONDUCTIVITY_OUT_OF_RANGE, averageBicarbConductivity, bicarbCondUSPerCM ) } } @@ -721,70 +752,32 @@ if ( TRUE == didTimeout( concentrateTestStartTime, CONCENTRATE_TEST_TIME_OUT_MS ) ) { - DG_CHEMICALS_FILL_COND_CAL_RECORD_T chemicalsCond; - F32 acidCondUSPerCM = 0.0F; + F32 acidCondUSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_ACID_TEST ].bicarbConduSPerCM; BOOL hasAcidTestPassed = FALSE; - BOOL hasCD1CD2TestPassed = FALSE; - getFillChemicalCondRecord( &chemicalsCond ); - - acidCondUSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_ACID_TEST ].acidConduSPerCM; averageBicarbConductivity = totalBicarbConductivity / bicarbConductivitySampleCount; averageAcidConductivity = totalAcidConductivity / acidConductivitySampleCount; pctDiffInConductivity = fabs( 2.0F * ( averageAcidConductivity - averageBicarbConductivity ) / ( averageAcidConductivity + averageBicarbConductivity ) ); + // NOTE: CD2 or bicarb conductivity sensor is used for acid check since it is a more accurate sensor. + // CD2 is the downstream of the acid concentrate pump so the acid sensed there. + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_ACID_CHECK_RESULT, averageBicarbConductivity, acidCondUSPerCM ) + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_COND1_VS_COND2_DIFF_RESULT, pctDiffInConductivity, 0.0F ) -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ACID_CONDUCTIVITY_TEST ) != SW_CONFIG_ENABLE_VALUE ) -#endif + if ( ( TRUE == isValueWithinPercentRange( averageBicarbConductivity, acidCondUSPerCM, ACID_CHECK_TOL_FACTOR ) ) || + ( TRUE == getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) ) ) { - if ( ( TRUE == isValueWithinPercentRange( averageAcidConductivity, acidCondUSPerCM, FIVE_PERCENT_FACTOR ) ) || - ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_MIXING_WITH_WATER ) ) ) - { - hasAcidTestPassed = TRUE; - } - else - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_ACID_CONDUCTIVITY_OUT_OF_RANGE, averageAcidConductivity ) - } - - if ( ( pctDiffInConductivity < FIVE_PERCENT_FACTOR ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_MIXING_WITH_WATER ) ) ) - { - hasCD1CD2TestPassed = TRUE; - } - else - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_CD1_CD2_CHECK_FAULT, pctDiffInConductivity ) - } + hasAcidTestPassed = TRUE; } -#ifndef _RELEASE_ else { - hasAcidTestPassed = TRUE; - hasCD1CD2TestPassed = TRUE; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_ACID_CONDUCTIVITY_OUT_OF_RANGE, averageBicarbConductivity, acidCondUSPerCM ) } -#endif - if ( ( TRUE == hasAcidTestPassed ) && ( TRUE == hasCD1CD2TestPassed ) ) + if ( TRUE == hasAcidTestPassed ) { - DG_ACID_CONCENTRATES_RECORD_T acid; - F32 acidMix; - DG_BICARB_CONCENTRATES_RECORD_T bicarb; - F32 bicarbMix; - - getAcidConcentrateCalRecord( &acid ); - getBicarbConcentrateCalRecord( &bicarb ); - - acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; - bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; - - setROPumpTargetFlowRateLPM( getTargetFillFlowRateLPM(), TARGET_RO_PRESSURE_PSI ); - handleDialysateMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, acidMix, bicarbMix ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - - // Do the necessary setup here before transition to Produce Dialysate State - fillStatus.isThisFirstFill = FALSE; - result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; + result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; + setModeFillStateTransition( result ); } } @@ -795,34 +788,49 @@ * @brief * The handleProduceDialysateState function executes the dialysate production * state of the fill mode state machine. - * @details Inputs: inlet water quality and dialysate temperature + * @details Inputs: chemicalsCond, concPumpPrimeStartTimeMS * @details Outputs: none * @return the next state *************************************************************************/ static DG_FILL_MODE_STATE_T handleProduceDialysateState( void ) { DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; - DG_ACID_CONCENTRATES_RECORD_T acid; - F32 acidMix; - DG_BICARB_CONCENTRATES_RECORD_T bicarb; - F32 bicarbMix; - getAcidConcentrateCalRecord( &acid ); - getBicarbConcentrateCalRecord( &bicarb ); + if ( TRUE == didTimeout( concPumpPrimeStartTimeMS, CONC_PUMPS_PRIME_AT_MAX_SPEED_TIME_OUT_MS ) ) + { + // Once the time for running the concentrate pumps at full speed has been elapsed, start running the pumps and the target mix ratio + handleDialysateMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, acidMixRatio, bicarbMixRatio ); - acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; - bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; + if ( TRUE == didTimeout( concPumpPrimeStartTimeMS, CONC_PUMPS_PRIME_CHECK_COND_SNSRS_TIME_OUT_MS ) ) + { + /* Once the time for priming the concentrate lines has elapsed, check the mixing conductivity of the sensors + * If the bicarb conductivity values are at about 100% of the target concentrate during fill, transition to the next state + * If the bicarb conductivity values are not at 100% but the maximum prime time has elapsed, transition to the next state + */ + F32 bicarbConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + F32 bicarbFillConduSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_NORMAL_OP ].bicarbConduSPerCM; - // Prime mixing before deliver result to reservoir - handleDialysateMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, acidMix, bicarbMix ); + /* we are insisting conductivity reach 100% of expected level since signal is very noisy and peak noise will reach 100% when average is about 93%. + * if sensor noise is reduced, this level should also be reduced accordingly. + */ + if ( bicarbConduSPerCM >= ( bicarbFillConduSPerCM * HUNDRED_PERCENT_FACTOR ) ) + { + result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + setModeFillStateTransition( result ); + } + else if ( TRUE == didTimeout( concPumpPrimeStartTimeMS, CONC_PUMPS_PRIME_MAX_ALLOWED_PRIME_TIME_OUT_MS ) ) + { + result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + setModeFillStateTransition( result ); + } - if ( concentratePumpPrimeCount++ > CONCENTRATE_PUMP_PRIME_INTERVAL ) - { - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - - dialysateFillStartTime = getMSTimerCount(); - fillStatus.isThisFirstFill = FALSE; - result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + if ( TRUE == getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) ) + { + // If mix with water is enabled do not wait for the conductivity values or timeout, transition to the next state + result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; + setModeFillStateTransition( result ); + } + } } return result; @@ -838,17 +846,13 @@ *************************************************************************/ static DG_FILL_MODE_STATE_T handleDeliverDialysateState( void ) { - DG_ACID_CONCENTRATES_RECORD_T acid; - DG_BICARB_CONCENTRATES_RECORD_T bicarb; - F32 acidMix = 0.0F; - F32 bicarbMix = 0.0F; DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; DG_RESERVOIR_ID_T inactiveRsrvr = getInactiveReservoir(); - F32 acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); - F32 bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - F32 inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); - F32 cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - F32 cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + F32 acidConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); + F32 bicarbConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + F32 inletTemperature = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); + F32 cpiConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + F32 cpoConduSPerCM = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); F32 rejRatio = RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE; // default 1:1 before calculation in case can't divide by zero. #ifndef _RELEASE_ @@ -859,40 +863,31 @@ } #endif - getAcidConcentrateCalRecord( &acid ); - getBicarbConcentrateCalRecord( &bicarb ); - - acidMix = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidConcMixRatio; - bicarbMix = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio; - // Set concentrate pumps speed based on the RO pump flow rate - handleDialysateMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, acidMix, bicarbMix ); + handleDialysateMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, acidMixRatio, bicarbMixRatio ); // Sum conductivity readings for CPo and RR checks - if ( fabs(cpi) >= NEARLY_ZERO ) + if ( fabs(cpiConduSPerCM) >= NEARLY_ZERO ) { - rejRatio = cpo / cpi; + rejRatio = cpoConduSPerCM / cpiConduSPerCM; } - sumFillCPoConductivity += cpo; + sumFillCPoConductivity += cpoConduSPerCM; sumFillRejRatio += rejRatio; fillCPoConductivitySampleCnt++; // Delay start of FMP check, then begin integrating flow to a volume - if ( TRUE == didTimeout( dialysateFillStartTime, DELAY_FMP_CHECK_START_BY_MS ) ) + if ( TRUE == didTimeout( dialysateFillStartTimeMS, DELAY_FMP_CHECK_START_BY_MS ) ) { if ( FALSE == didFMPCheckStart ) { // When FMP check starts, set baseline weight of reservoir we are filling didFMPCheckStart = TRUE; reservoirBaseWeight = getReservoirWeight( getInactiveReservoir() ); } - integratedVolumeML.data += getMeasuredROFlowRateWithConcPumpsLPM() * ML_PER_LITER * FLOW_INTEGRATOR; } - usedAcidVolumeML.data += getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ) * FLOW_INTEGRATOR; - usedBicarbVolumeML.data += getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2_BICARB ) * FLOW_INTEGRATOR; - acidConductivityTotal += acidConductivity; - bicarbConductivityTotal += bicarbConductivity; + acidConductivityTotal += acidConduSPerCM; + bicarbConductivityTotal += bicarbConduSPerCM; conductivitySampleCount++; // DG is delivering dialysate keep collecting the sample counter and the measured flow @@ -901,88 +896,66 @@ fillStatus.fillTemperatureRunningSum += inletTemperature; // TODO: Check for open straw door status and alarm if closed - // Check if run out of time to fill the reservoir - if ( TRUE == didTimeout( dialysateFillStartTime, DIALYSATE_FILL_TIME_OUT ) ) + // Check if run out of time to fill the reservoir, disregarding time paused, + // because pause time isn't the reservoir's, or loadcell's fault + // the 5 minutes DIALYSATE_FILL_TIME_OUT is a mystery number. + if ( TRUE == didTimeout( dialysateFillStartTimeMS, DIALYSATE_FILL_TIME_OUT + dialysatePauseElapsedTimeMS ) ) { activateAlarmNoData( ALARM_ID_DG_DIALYSATE_FILL_OUT_OF_TIME ); } // If we've reached our target fill to volume (by weight), we're done filling - go back to generation idle mode // SRSDG 398 if ( TRUE == hasTargetFillVolumeBeenReached( inactiveRsrvr ) ) { - DG_CHEMICALS_FILL_COND_CAL_RECORD_T chemicalsCond; - - getFillChemicalCondRecord( &chemicalsCond ); - F32 filledVolumeML = getReservoirWeight( inactiveRsrvr ) - reservoirBaseWeight; F32 integratedVolumeToLoadCellReadingPercent = fabs( 1.0F - ( getIntegratedVolumeML() / filledVolumeML ) ); // Filled volume more accurate and stable than the integrated volume from the flowmeter - F32 avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; - F32 avgBicarbConductivity = bicarbConductivityTotal / conductivitySampleCount; - F32 acidNormalConductivity = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_NORMAL_OP ].acidConduSPerCM; - F32 bicarbNormalConductivity = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_NORMAL_OP ].bicarbConduSPerCM; + F32 avgAcidConduSPerCM = acidConductivityTotal / conductivitySampleCount; + F32 avgBicarbConduSPerCM = bicarbConductivityTotal / conductivitySampleCount; + F32 bicarbNormalConduSPerCM = chemicalsCond.fillCondValues[ chemicalsTypes.acidType ][ FILL_COND_NORMAL_OP ].bicarbConduSPerCM; - SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_AVG_DIALYSATE_FILL_COND_VALUES, avgAcidConductivity, avgBicarbConductivity ) + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_AVG_DIALYSATE_FILL_COND_VALUES, avgAcidConduSPerCM, avgBicarbConduSPerCM ) SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_RESERVOIR_FILL_VALUES, reservoirBaseWeight, filledVolumeML ) - // Check RO filter -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_RO_RATIO_CHECK ) != SW_CONFIG_ENABLE_VALUE ) -#endif + if ( getTargetFillVolumeML() > MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML ) { - if ( getTargetFillVolumeML() > MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML ) - { - F32 avgCPo = sumFillCPoConductivity / (F32)fillCPoConductivitySampleCnt; // sample count incremented above w/o condition so no need for divide by zero checks - F32 avgRR = sumFillRejRatio / (F32)fillCPoConductivitySampleCnt; + F32 avgCPo = sumFillCPoConductivity / (F32)fillCPoConductivitySampleCnt; // sample count incremented above w/o condition so no need for divide by zero checks + F32 avgRR = sumFillRejRatio / (F32)fillCPoConductivitySampleCnt; - if ( ( avgCPo > MAX_CPO_CONDUCTIVITY_ALLOW ) && ( getTestConfigStatus( TEST_CONFIG_ENABLE_MIXING_WITH_WATER ) != FALSE ) ) - { - // Fault alarm per PRS 483 - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, avgCPo, MAX_CPO_CONDUCTIVITY_ALLOW ); - } - if ( ( avgRR > MAX_RO_REJECTION_RATIO_ALLOW ) && ( isROOnlyModeEnabled() != TRUE ) ) - { - // Fault alarm per PRS 483 - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, MAX_RO_REJECTION_RATIO_ALLOW ); - } + if ( ( avgCPo > MAX_CPO_CONDUCTIVITY_ALLOW ) && ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) + { + // Fault alarm per PRS 483 + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, avgCPo, MAX_CPO_CONDUCTIVITY_ALLOW ); } + if ( ( avgRR > maxRORejectionRatioFromHD ) && ( isROOnlyModeEnabled() != TRUE ) ) + { + // Fault alarm per PRS 483 + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, maxRORejectionRatioFromHD ); + } } // Check FMP vs. LC #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_FLOW_VS_LOAD_CELL_CHECK_IN_FILL ) != SW_CONFIG_ENABLE_VALUE ) #endif { - if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) // SRSDG 240 + if ( getTargetFillVolumeML() > MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FLOW_METER_CHECK_FAILURE, filledVolumeML, getIntegratedVolumeML() ); + if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) // SRSDG 240 + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FLOW_METER_CHECK_FAILURE, filledVolumeML, getIntegratedVolumeML() ); + } } } - // Check mixing via avg. conductivities -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MIXING_IN_FILL ) != SW_CONFIG_ENABLE_VALUE ) -#endif + // SRSDG 400 + if ( ( FALSE == isValueWithinPercentRange( avgBicarbConduSPerCM, bicarbNormalConduSPerCM, FIVE_PERCENT_FACTOR ) ) && + ( getTargetFillVolumeML() > MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML ) && ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) { - // SRSDG 400 - if ( ( FALSE == isValueWithinPercentRange( avgBicarbConductivity, bicarbNormalConductivity, FIVE_PERCENT_FACTOR ) ) && - ( getTestConfigStatus( TEST_CONFIG_ENABLE_MIXING_WITH_WATER ) != TRUE ) ) - { - setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected - setThisFisrtFillFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConductivity, bicarbNormalConductivity ); // trigger replace bottles alarm #1 - clearAlarm( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); // clear this alarm before triggering in case previous fill was bad and still active from before - activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); - } - - if ( ( FALSE == isValueWithinPercentRange( avgAcidConductivity, acidNormalConductivity, FIVE_PERCENT_FACTOR ) ) && - ( getTestConfigStatus( TEST_CONFIG_ENABLE_MIXING_WITH_WATER ) != TRUE ) ) - { - setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected - setThisFisrtFillFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgAcidConductivity, acidNormalConductivity ); // trigger replace bottles alarm #1 then - clearAlarm( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); // clear this alarm before triggering in case previous fill was bad and still active from before - activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); - } + setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected + setThisFirstFillFlag( TRUE ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConduSPerCM, bicarbNormalConduSPerCM ); // trigger replace bottles alarm #1 + clearAlarm( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); // clear this alarm before triggering in case previous fill was bad and still active from before + activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); } // Done with this fill. Calculate the average fill flow rate and average temperature @@ -1006,30 +979,163 @@ * @brief * The handlePausedState function executes the paused state of the fill * mode state machine. - * @details Inputs: havePauseActuatorsBeenSet - * @details Outputs: havePauseActuatorsBeenSet + * @details Inputs: Inlet water conditions and conductivity + * @details Outputs: didFillRecoverFromPause * @return the next state *************************************************************************/ static DG_FILL_MODE_STATE_T handlePausedState( void ) { DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_PAUSED; - if ( FALSE == havePauseActuatorsBeenSet ) + if ( ( FALSE == areInletWaterConditionsAlarmsActive() ) && ( FALSE == areConductivityAlarmsActive() ) ) { - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_IN_PAUSE_L, TARGET_RO_PRESSURE_PSI ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); - havePauseActuatorsBeenSet = TRUE; + didFillRecoverFromPause = TRUE; + result = DG_FILL_MODE_STATE_TEST_INLET_WATER; + setModeFillStateTransition( result ); } - if ( ( FALSE == areInletWaterConditionsAlarmsActive() ) && ( FALSE == areConductivityAlarmsActive() ) ) + return result; +} + +/*********************************************************************//** + * @brief + * The setModeFillStateTransition function sets the actuators and variables + * for the state transition in mode fill. + * @details Inputs: pumpSpeedIndex, dialysatePauseStartTimeMS + * didFillRecoverFromPause + * @details Outputs: concPumpPrimeStartTimeMS, fillStatus, pumpSpeedIndex, + * concentratePrimingStartTime, totalBicarbConductivity, averageBicarbConductivity, + * bicarbConductivitySampleCount, concentrateTestStartTime, fillStatus, + * flushBubblesStartTime, didFillRecoverFromPause + * dialysatePauseElapsedTimeMS, dialysatePauseStartTimeMS + * @param state mode fill state enum + * @return none + *************************************************************************/ +static void setModeFillStateTransition( DG_FILL_MODE_STATE_T state ) +{ + // Execute cleanup on exiting pause + if ( state != fillState ) { - havePauseActuatorsBeenSet = FALSE; - result = DG_FILL_MODE_STATE_START; + if ( DG_FILL_MODE_STATE_PAUSED == fillState ) + { // accumulate pause + dialysatePauseElapsedTimeMS += calcTimeSince( dialysatePauseStartTimeMS ); + } } - return result; + // Execute on running state + switch( state ) + { + case DG_FILL_MODE_STATE_TEST_INLET_WATER: + // Do nothing + break; + + case DG_FILL_MODE_STATE_PRIME_CONCENTRATE_LINES: + // Prepare the acid and bicarb pumps to prime the concentrate lines + setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONCENTRATE_PUMP_MAX_SPEED ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + concentratePrimingStartTime = getMSTimerCount(); + break; + + case DG_FILL_MODE_STATE_FLUSH_BUBBLES: + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); + + // Set the RO pump flow rate in according to the roPumpFlushBubblesSpeed table to flush bubbles + pumpSpeedIndex = 0; + setROPumpTargetFlowRateLPM( RO_PUMP_FLUSH_BUBBLES_FLOWS[ pumpSpeedIndex ] / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); + flushBubblesStartTime = getMSTimerCount(); + if ( ( DIALIN_FILL_FOR_CAL_PRIME == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) + { + // After prime, the state transitions to flush bubbles. If the cal for check prime was set, transition to Gen Idle and + // set the fill for cal check to none. This is done upon the transition of the next state so then we can transition to Gen Idle. + dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; + requestNewOperationMode( DG_MODE_GENE ); + } + break; + + case DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY: + // Set pumps flow rate to prepare for bicarb conductivity testing + setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_40_ML_PER_MIN ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + + // Prior to collecting data for bicarb test, change the CD2 calibration table + setCondcutivitySensorCalTable( CONDUCTIVITYSENSORS_CD2_SENSOR, CAL_DATA_CD2_COND_SENSOR_FILL_BICARB_TEST ); + totalBicarbConductivity = 0.0F; + averageBicarbConductivity = 0.0F; + bicarbConductivitySampleCount = 0; + concentrateTestStartTime = getMSTimerCount(); + break; + + case DG_FILL_MODE_STATE_TEST_ACID_CONDUCTIVITY: + // Initialization + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); + // Set pumps flow rate to prepare for acid conductivity testing + setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_23_ML_PER_MIN ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + + // Set back the conductivity of CD2 calibration table to the normal calibration table + setCondcutivitySensorCalTable( CONDUCTIVITYSENSORS_CD2_SENSOR, CAL_DATA_CD2_COND_SENSOR ); + totalBicarbConductivity = 0.0F; + totalAcidConductivity = 0.0F; + bicarbConductivitySampleCount = 0; + acidConductivitySampleCount = 0; + concentrateTestStartTime = getMSTimerCount(); + if ( ( DIALIN_FILL_FOR_CAL_BICARB_CHECK == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) + { + // After bicarb test, the state transitions to acid test. If the cal for check prime was set, transition to Gen Idle and + // set the fill for cal check to none. This is done upon the transition of the next state so then we can transition to Gen Idle. + // NOTE: If the bicarb test fails, it transitions to fault mode so it automatically exits mode fill so this is only for the situation + // that bicarb test was successful + dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; + requestNewOperationMode( DG_MODE_GENE ); + } + break; + + case DG_FILL_MODE_STATE_PRODUCE_DIALYSATE: + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONCENTRATE_PUMP_MAX_SPEED ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + concPumpPrimeStartTimeMS = getMSTimerCount(); + fillStatus.isThisFirstFill = FALSE; + if ( ( DIALIN_FILL_FOR_CAL_ACID_CHECK == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) + { + // After acid test, the state transitions to acid test. If the cal for check prime was set, transition to Gen Idle and + // set the fill for cal check to none. This is done upon the transition of the next state so then we can transition to Gen Idle. + // NOTE: If the acid test fails, it transitions to fault mode so it automatically exits mode fill so this is only for the situation + // that bicarb test was successful + dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; + requestNewOperationMode( DG_MODE_GENE ); + } + break; + + case DG_FILL_MODE_STATE_DELIVER_DIALYSATE: + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + if ( ( didFillRecoverFromPause != TRUE ) || ( 0 == dialysateFillStartTimeMS ) ) + { + dialysateFillStartTimeMS = getMSTimerCount(); + } + didFillRecoverFromPause = FALSE; + fillStatus.isThisFirstFill = FALSE; + break; + + case DG_FILL_MODE_STATE_PAUSED: + dialysatePauseStartTimeMS = getMSTimerCount(); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_IN_PAUSE_L, TARGET_RO_PRESSURE_PSI ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_FILL_MODE_INVALID_EXEC_STATE, state ) + break; + } } /*********************************************************************//** @@ -1092,7 +1198,9 @@ * percentFactor. * @details Inputs: None * @details Outputs: None - * @param: testValue, baseValue, percentFactor + * @param testValue value to check range for + * @param baseValue value associated with 100% + * @param percentFactor percentage range (100% +/- this value) * @return TRUE if testValue is within range. Otherwise, return FALSE *************************************************************************/ static BOOL isValueWithinPercentRange( F32 testValue, F32 baseValue, F32 percentFactor ) @@ -1139,33 +1247,16 @@ /*********************************************************************//** * @brief - * The setFillInfoToRTCRAM function writes the fill information to the RTC - * RAM at the end of each fill. This information is used for dialysate temperature - * control. - * @details Inputs: fillStatus.fillFlowRateAverage - * @details Outputs: none - * @return none - *************************************************************************/ -static void setFillInfoToRTCRAM( void ) -{ - DG_HEATERS_RECORD_T record; - - record.averageFillFlow = fillStatus.fillFlowRateAverageLPM; - - setHeatersInfoRecord( (U08*)&record, sizeof( DG_HEATERS_RECORD_T ) ); -} - -/*********************************************************************//** - * @brief * The publishFillModeData function publishes fill mode data * at the set interval. - * @details Inputs: fillModeDataPublicationTimerCounter, fillModeDataPublishInterval + * @details Inputs: fillModeDataPublicationTimerCounter, fillModeDataPublishInterval, + * dataPublishCounter * @details Outputs: fillModeData * @return none *************************************************************************/ static void publishFillModeData( void ) { - // publish Drain pump data on interval + // publish Fill mode data on interval if ( ++dataPublishCounter >= getU32OverrideValue( &fillModeDataPublishInterval ) ) { DG_FILL_MODE_DATA_T fillModeData; @@ -1175,10 +1266,12 @@ fillModeData.averageBicarbConductivity = averageBicarbConductivity; fillModeData.isThisTheFirstFill = isThisTheFirstFill(); fillModeData.pctDiffInConductivity = pctDiffInConductivity; - fillModeData.usedAcidVolumeML = getChemicalUsedVolumeML( ACID ); - fillModeData.usedBicarbVolumeML = getChemicalUsedVolumeML( BICARB ); + fillModeData.usedAcidVolumeML = 0.0F; + fillModeData.usedBicarbVolumeML = 0.0F; fillModeData.integratedVolumeML = getIntegratedVolumeML(); fillModeData.roOnlyModeStatus = (U32)isROOnlyModeEnabled(); + fillModeData.badFillSignal = getCurrentBadFillSignal(); + fillModeData.badFillState = getCurrentGenIdleBadFillState(); broadcastData( MSG_ID_DG_FILL_MODE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&fillModeData, sizeof( DG_FILL_MODE_DATA_T ) ); @@ -1191,110 +1284,13 @@ * TEST SUPPORT FUNCTIONS *************************************************************************/ - /*********************************************************************//** * @brief - * The testSetUsedAcidVolumeMLOverride function overrides the - * acid volume. - * @details Inputs: used acid volume - * @details Outputs: used acid volume - * @param: value : override used acid volume in mL - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetUsedAcidVolumeMLOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedAcidVolumeML.ovInitData = usedAcidVolumeML.data; - usedAcidVolumeML.ovData = value; - usedAcidVolumeML.override = OVERRIDE_KEY; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetUsedAcidVolumeMLOverride function resets the override - * of the used acid volume. - * @details Inputs: used acid volume - * @details Outputs: used acid volume - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testResetUsedAcidVolumeMLOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedAcidVolumeML.data = usedAcidVolumeML.ovInitData; - usedAcidVolumeML.override = OVERRIDE_RESET; - usedAcidVolumeML.ovInitData = 0.0F; - usedAcidVolumeML.ovData = 0.0F; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetUsedBicarbVolumeMLOverride function overrides the - * bicarb volume. - * @details Inputs: used bicarb volume - * @details Outputs: used bicarb volume - * @param: value : override used bicarb volume in mL - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetUsedBicarbVolumeMLOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedBicarbVolumeML.ovInitData = usedBicarbVolumeML.data; - usedBicarbVolumeML.ovData = value; - usedBicarbVolumeML.override = OVERRIDE_KEY; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetUsedBicarbVolumeMLOverride function resets the override - * of the used bicarb volume. - * @details Inputs: used bicarb volume - * @details Outputs: used bicarb volume - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testResetUsedBicarbVolumeMLOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedBicarbVolumeML.data = usedBicarbVolumeML.ovInitData; - usedBicarbVolumeML.override = OVERRIDE_RESET; - usedBicarbVolumeML.ovInitData = 0.0F; - usedBicarbVolumeML.ovData = 0.0F; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief * The testSetFillModeDataPublishIntervalOverride function overrides the * fill mode data publish interval. * @details Inputs: FillModeDataPublishInterval * @details Outputs: FillModeDataPublishInterval - * @param: value override fill mode data publish interval with (in ms) + * @param value override fill mode data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetFillModeDataPublishIntervalOverride( U32 value ) @@ -1340,7 +1336,7 @@ * integrated volume. * @details Inputs: value * @details Outputs: integratedVolumeML - * @param: value integrated volume in mL + * @param value integrated volume in mL * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetIntegratedVolumeOverride( F32 value ) @@ -1379,4 +1375,28 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetModeFillForCal function sets the variable to run mode fill only + * for calibration check + * @details Inputs: none + * @details Outputs: fillForCalCheck + * @param calForCheck the mode that is requested (0 = prime, 1 = bicarb check, + * 2 = acid check) + * @return TRUE if the request is in the range otherwise, FALSE + *************************************************************************/ +BOOL testSetModeFillForCal( U32 calForCheck ) +{ + BOOL result = FALSE; + + if ( ( calForCheck < NUM_OF_DIALIN_FILL_FOR_CAL ) && ( TRUE == isTestingActivated() ) ) + { + dialinFillForCalCheck = (DIALIN_FILL_FOR_CAL_CHECK_T)calForCheck; + result = TRUE; + requestNewOperationMode( DG_MODE_FILL ); + } + + return result; +} + /**@}*/