Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r00b244580f01f3cbd1b7d2d5a14ee61675bf4642 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 00b244580f01f3cbd1b7d2d5a14ee61675bf4642) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -76,7 +76,6 @@ #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. @@ -117,6 +116,7 @@ F32 fillFlowRateAverageLPM; ///< Fill flow average value in L/min. F32 fillLastTemperature; ///< Fill last temperature value. BOOL isThisFirstFill; ///< Fill flag to indicate whether it is the first fill or not. + BOOL isPrimeCondChecksSkipped; ///< Fill flag to indicate whether the acid and bicarb conductivity checks should be skipped after priming. } FILL_CONDITION_STATUS_T; /// Fill acid and bicarb types @@ -171,8 +171,8 @@ // 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. -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 this variable is set to 0. +static U32 minRORejectionRatioPCTFromHD = 0; ///< Min RO rejection ratio in percent 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. @@ -194,7 +194,6 @@ static void handleDialysateMixing( F32 measuredROFlowRate_mL_min, F32 acidMixingRatio, F32 bicarbMixingRatio ); static BOOL isValueWithinPercentRange( F32 testValue, F32 baseValue, F32 percentFactor ); static void publishFillModeData( void ); -static void updateChemicalsUsage( void ); /*********************************************************************//** * @brief @@ -353,7 +352,6 @@ { checkDialysateTemperatureSensors(); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); - updateChemicalsUsage(); if ( fillState != DG_FILL_MODE_STATE_PAUSED ) { @@ -477,9 +475,10 @@ fillStatus.fillTemperatureRunningSum = 0.0F; // At the beginning the last and average temperatures are considered as the trimmer heater target temperature which // is the dialysate temperature - fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); - fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; - fillStatus.isThisFirstFill = TRUE; + fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); + fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; + fillStatus.isThisFirstFill = TRUE; + fillStatus.isPrimeCondChecksSkipped = FALSE; } /*********************************************************************//** @@ -497,60 +496,6 @@ /*********************************************************************//** * @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 @@ -608,6 +553,23 @@ /*********************************************************************//** * @brief + * The setMinRORejectionRatioPCT function sets the RO rejection ratio in + * percent that has been received from the HD institutional record. + * @details Inputs: none + * @details Outputs: roRejectionRatioFromHD + * @param RO rejection ratio + * @return none + *************************************************************************/ +void setMinRORejectionRatioPCT( U32 roRejectionRatio ) +{ + U32 priorMinRORejectionRatio = minRORejectionRatioPCTFromHD; + + minRORejectionRatioPCTFromHD = roRejectionRatio; + SEND_EVENT_WITH_2_U32_DATA( DG_EVENT_MIN_RO_REJECTION_RATIO_PCT_FROM_HD_INSTIT_RECORD, priorMinRORejectionRatio, minRORejectionRatioPCTFromHD ) +} + +/*********************************************************************//** + * @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. @@ -710,7 +672,7 @@ } else { - result = DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY; + result = ( FALSE == fillStatus.isPrimeCondChecksSkipped ? DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY : DG_FILL_MODE_STATE_PRODUCE_DIALYSATE ); setModeFillStateTransition( result ); } } @@ -962,16 +924,21 @@ { 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; + // The rejection ratio = 1 - (institutional RR value in percent) / 100 + // If the instit RR value is 0% the converted RR becomes 1. But If the instit RR value is 0, the RR alarm is not checked + F32 convRR = 1.0F - ( ( (F32)minRORejectionRatioPCTFromHD ) / FRACTION_TO_PERCENT_FACTOR ); + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_CALC_RO_REJECTION_RATIO, convRR, avgRR ) + 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 > MAX_RO_REJECTION_RATIO_ALLOW ) && ( isROOnlyModeEnabled() != TRUE ) ) + if ( ( avgRR > convRR ) && ( isROOnlyModeEnabled() != TRUE ) && ( minRORejectionRatioPCTFromHD > 0 ) ) { // 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 ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, convRR ); } } @@ -995,8 +962,9 @@ { setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected setThisFirstFillFlag( TRUE ); - resetChemicalUsedVolumeML( BICARB ); - resetChemicalUsedVolumeML( ACID ); + // Bad fill conductivity. Set this flag so after priming the concentrate lines, acid and bicarb conductivities are not checked + // again to save time + fillStatus.isPrimeCondChecksSkipped = 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 ); @@ -1145,8 +1113,9 @@ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - concPumpPrimeStartTimeMS = getMSTimerCount(); - fillStatus.isThisFirstFill = FALSE; + concPumpPrimeStartTimeMS = getMSTimerCount(); + fillStatus.isThisFirstFill = FALSE; + fillStatus.isPrimeCondChecksSkipped = 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 @@ -1310,8 +1279,6 @@ fillModeData.averageBicarbConductivity = averageBicarbConductivity; fillModeData.isThisTheFirstFill = isThisTheFirstFill(); fillModeData.pctDiffInConductivity = pctDiffInConductivity; - fillModeData.usedAcidVolumeML = getChemicalUsedVolumeML( ACID ); - fillModeData.usedBicarbVolumeML = getChemicalUsedVolumeML( BICARB ); fillModeData.integratedVolumeML = getIntegratedVolumeML(); fillModeData.roOnlyModeStatus = (U32)isROOnlyModeEnabled(); fillModeData.badFillSignal = getCurrentBadFillSignal(); @@ -1323,123 +1290,13 @@ } } -/*********************************************************************//** - * @brief - * The updateChemicalsUsage function updates the used acid and bicarb volumes. - * @details Inputs: usedAcidVolumeML, usedBicarbVolumeML - * @details Outputs: none - * @return none - *************************************************************************/ -static void updateChemicalsUsage( void ) -{ - usedAcidVolumeML.data += getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP1_ACID ) * FLOW_INTEGRATOR; - usedBicarbVolumeML.data += getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP2_BICARB ) * FLOW_INTEGRATOR; -} - /************************************************************************* * 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 @@ -1531,6 +1388,27 @@ /*********************************************************************//** * @brief + * The testSetEnableTestChemsCondValuesStatus function enables the testing + * of acid and bicarb conductivity values after priming. + * @details Inputs: none + * @details Outputs: fillStatus.isPrimeCondChecksSkipped + * @return TRUE if set successful, FALSE if not + *************************************************************************/ +BOOL testSetEnableTestChemsCondValuesStatus( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + fillStatus.isPrimeCondChecksSkipped = FALSE; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The testSetModeFillForCal function sets the variable to run mode fill only * for calibration check * @details Inputs: none