Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r830213bc6dcc1a684610caf78c79d55f2cb41e93 -r8e93a6e39b2c7af5f0b47ef1272a2b53446fab0b --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 830213bc6dcc1a684610caf78c79d55f2cb41e93) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 8e93a6e39b2c7af5f0b47ef1272a2b53446fab0b) @@ -7,8 +7,8 @@ * * @file BalancingChamber.c * -* @author (last) Shyam Kumar Mathamala -* @date (last) 03-Sep-2025 +* @author (last) Varshini Nagabooshanam +* @date (last) 26-Jan-2026 * * @author (original) Vinayakam Mani * @date (original) 28-Jan-2025 @@ -22,6 +22,7 @@ #include "FpgaDD.h" #include "Heaters.h" #include "ModeStandby.h" +#include "ModeGenDialysate.h" #include "Messaging.h" #include "OperationModes.h" #include "Pressure.h" @@ -41,6 +42,11 @@ #define BAL_CHAMBER_DATA_PUBLISH_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the balancing chamber data published. #define BAL_CHAMBER_FILL_PRES_DROP_MS ( 200 / TASK_GENERAL_INTERVAL ) ///< Time (ms/tasktime) to confirm the balancing chamber filling started and corrosponding valves opened. #define BAL_CHAMBER_FILL_COMPLETE_MS ( 300 / TASK_GENERAL_INTERVAL ) ///< Time (ms/tasktime) to confirm the balancing chamber fill completed and pressure is within range +#define SPENT_FILL_COMPLETE_PRES 25.0F ///< Spent pressure that indicates fill is complete. +#define SPENT_DIFF_COUNT_ZERO 0 ///< Zero count difference for spent side fill comparing target count +#define SPENT_DIFF_COUNT_DEADBAND 1 ///< Stop changing D48 pump speed when fill difference reaches close to target count +#define D48_SPEED_ADJUST_FACTOR 0.5F ///< D48 speed adjustment factor ( 50% of speed adjustment = 0.5) +#define D48_SPEED_RANGE_LIMIT 0.25F ///< D48 speed adjustment range check limit ( D48 speed can vary +/-25% of initial calculated speed) /// Payload record structure for balancing chamber switch only request typedef struct @@ -71,6 +77,11 @@ static F32 lastTdDialysateFlowrate; ///< Previous TD dialysate flow rate static F32 freshDialPressure; ///< Fresh side dialysate pressure static F32 spentDialPressure; ///< Spent side dialysate pressure +static F32 prevSpentDialPressure; ///< Previous spent side dialysate pressure +static F32 lastPrevSpentDialPressure; ///< Last previous spent side dialysate pressure +static U32 currentBalChamberFillCounter; ///< Counter (in task interval) to monitor the timing spent for the spent side fill operation. +static S32 diffSpentFillCompleteCount; ///< Difference between spent target fill to actual fill count +static BOOL isSpentFillComplete; ///< Flag indicating that spent side fill is complete. // ********** private function prototypes ********** @@ -83,6 +94,7 @@ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillEnd(void); static void publishBalChamberData( void ); static U32 getBalChamberDataPublishInterval( void ); +static void checkSpentFillComplete( F32 spentDialPressure ); /*********************************************************************//** * @brief @@ -125,6 +137,11 @@ isPressureDroppedDuringFill = FALSE; freshDialPressure = 0.0F; spentDialPressure = 0.0F; + prevSpentDialPressure = 0.0F; + lastPrevSpentDialPressure = 0.0F; + currentBalChamberFillCounter = 0; + diffSpentFillCompleteCount = 0; + isSpentFillComplete = FALSE; } /*********************************************************************//** @@ -191,6 +208,7 @@ { // Increment counter indicating fill is in progress. currentBalChamberSwitchingCounter += 1; + currentBalChamberFillCounter += 1; // execute current balancing chamber exec state switch ( balChamberExecState ) @@ -392,6 +410,7 @@ setValveState( D26_VALV, VALVE_STATE_CLOSED ); } +#if 0 /*********************************************************************//** * @brief * The handleBalChamberState1FillStart function handles the balancing chamber @@ -419,7 +438,7 @@ // Check fresh and spent dialysate pressure in range or BC switch only flag set if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) || - ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) ) ) + ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) { //Valve control for state 1 fill valveControlForBCState1FillStart(); @@ -441,7 +460,7 @@ } else { - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) { //Alarm when pressure is not in range SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE1_FILL_START_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); @@ -517,7 +536,7 @@ spentDialPressure = getFilteredPressure( D51_PRES ); // Check fresh and spent dialysate pressure back in range to indicate fill complete. - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) { if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) ) @@ -573,7 +592,7 @@ if ( TRUE != getBalChamberSwitchingOnlyStatus() ) { - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) { if ( ( TRUE != isPressureDroppedDuringFill ) && ( TRUE == isFirstCycleBCSwitchingCompleted ) ) { @@ -633,7 +652,7 @@ // Check fresh and spent dialysate pressure in range if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) || - ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) ) ) + ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) { // Valve control for state 2 fill valveControlForBCState2FillStart(); @@ -655,7 +674,7 @@ } else { - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) { //Alarm when pressure is not in range SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE2_FILL_START_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); @@ -680,7 +699,7 @@ spentDialPressure = getFilteredPressure( D51_PRES ); // Check fresh and spent dialysate pressure back in range to indicate fill complete. - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) { if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) && ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) ) @@ -737,7 +756,7 @@ // Pressure alarm check if ( TRUE != getBalChamberSwitchingOnlyStatus() ) { - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) { if ( ( TRUE != isPressureDroppedDuringFill ) && ( TRUE == isFirstCycleBCSwitchingCompleted ) ) { @@ -775,9 +794,447 @@ return state; } +#else /*********************************************************************//** * @brief + * The handleBalChamberState1FillStart function handles the balancing chamber + * state 1 fill and time to fill chamber counter being updated. + * @details \b Inputs: Pressure + * @details \b Outputs: valve states + * @details \b Alarm: ALARM_ID_DD_BC_STATE1_FILL_START_PRESSURE_OUT_OF_RANGE + * when pressure is not in range during balancing chamber fill start. + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState1FillStart( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE1_FILL_START; + currentBalChamberSwitchingCounter = 0; + balChamberSWState = BAL_CHAMBER_SW_STATE1; + currentBalChamberFillCounter = 0; + isBalChamberFillInProgress = FALSE; + isPressureStalbilizedDuringFill = FALSE; + isPressureDroppedDuringFill = FALSE; + isSpentFillComplete = FALSE; + lastPrevSpentDialPressure = 0.0F; + prevSpentDialPressure = 0.0F; + + F32 acidVolume = getF32OverrideValue( &acidDoseVolume ); + F32 bicarbVolume = getF32OverrideValue( &bicarbDoseVolume ); + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + // Check fresh and spent dialysate pressure in range or BC switch only flag set + if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) || + ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) + { + //Valve control for state 1 fill + valveControlForBCState1FillStart(); + + // Update fill status flag to true + isBalChamberFillInProgress = TRUE; + + // Deliver dosing during generate dialysate mode + if ( TRUE != getBalChamberSwitchingOnlyStatus() ) + { + // start acid and bicarb pump with the expected quantity + setConcentratePumpTargetSpeed( D11_PUMP, CONCENTRATE_PUMP_MAX_SPEED, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, CONCENTRATE_PUMP_MAX_SPEED, bicarbVolume ); + requestConcentratePumpOn( D11_PUMP ); + requestConcentratePumpOn( D10_PUMP ); + } + + state = BAL_CHAMBER_STATE1_BICARB_ACID_DOSING_CNTRL; + } + else + { + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + { + //Alarm when pressure is not in range + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE1_FILL_START_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBalChamberConcentrateControl function handles the Acid and Bicarb + * concentrate dosing and checks the conductivity of the dialysate for the treatment. + * @details \b Inputs: balChamberSWState , Concentrate volume + * @details \b Outputs: isPressureDroppedDuringFill, state + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberConcentrateControl( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state; + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + if ( BAL_CHAMBER_SW_STATE1 == balChamberSWState ) + { + state = BAL_CHAMBER_STATE1_BICARB_ACID_DOSING_CNTRL; + } + else + { + state = BAL_CHAMBER_STATE2_BICARB_ACID_DOSING_CNTRL; + } + + // Pressure drop check during fill process helps to find if there is any issue with valves opening + if ( ( freshDialPressure <= BC_FRESH_FILL_PRESSURE_PSIG ) && ( spentDialPressure <= BC_SPENT_FILL_PRESSURE_PSIG ) ) + { + if ( ++balChamberFillPressureDropCounter >= BAL_CHAMBER_FILL_PRES_DROP_MS ) + { + isPressureDroppedDuringFill = TRUE; + } + } + + // On dosing completion, transition to next state based on the current switching state + if ( ( ( TRUE == isConcentratePumpDosingCompleted( D11_PUMP ) ) && + ( TRUE == isConcentratePumpDosingCompleted( D10_PUMP ) ) ) || + ( TRUE == getBalChamberSwitchingOnlyStatus() ) ) + { + //Collect first sample of spent pressure + lastPrevSpentDialPressure = prevSpentDialPressure; + prevSpentDialPressure = spentDialPressure; + + if ( BAL_CHAMBER_SW_STATE1 == balChamberSWState ) + { + state = BAL_CHAMBER_STATE1_VALVES_CLOSE; + } + else + { + state = BAL_CHAMBER_STATE2_VALVES_CLOSE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBalChamberState1ValvesClose function check for the balancing chamber + * fill complete and close the currently opened valves. + * @details \b Inputs: currentBalChamberSwitchingCounter, spent and fresh dialysate pressure + * @details \b Outputs: isPressureStalbilizedDuringFill,isBalChamberFillInProgress + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState1ValvesClose( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE1_VALVES_CLOSE; + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + // Check fresh dialysate pressure back in range to indicate fresh fill complete. + if ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) + { + if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) + { + // stabilized pressure indicating fresh side fill is complete + isPressureStalbilizedDuringFill = TRUE; + } + } + + // Spent side of balancing chamber fill is complete or not + checkSpentFillComplete( spentDialPressure ); + + // Check both spent and fresh side fill is complete + if ( ( TRUE == isSpentFillComplete ) && ( TRUE == isPressureStalbilizedDuringFill ) || ( FALSE == isFirstCycleBCSwitchingCompleted ) ) + { + // close the state 1 opened valves + valveControlForBCState1FillEnd(); + isBalChamberFillInProgress = FALSE; + setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); + + // Transition to next state + state = BAL_CHAMBER_STATE1_FILL_END; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBalChamberState1FillEnd function check for the balancing chamber + * switching period and transition to next state switching. + * @details \b Inputs: currentBalChamberSwitchingCounter, balChamberSwitchingPeriod + * @details \b Outputs: balChamberFillPressureDropCounter,balChamberFillCompleteStablePressureCounter + * @details \b Alarm: ALARM_ID_DD_BC_STATE1_FILL_PRESSURE_DROP_OUT_OF_RANGE + * when pressure drop is not in range during balancing chamber fill in progress. + * @details \b Alarm: ALARM_ID_DD_BC_STATE1_FILL_END_PRESSURE_OUT_OF_RANGE + * when pressure is not in range during balancing chamber fill complete. + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState1FillEnd( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE1_FILL_END; + + balChamberFillPressureDropCounter = 0; + balChamberFillCompleteStablePressureCounter = 0; + + if ( TRUE != getBalChamberSwitchingOnlyStatus() ) + { + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + { + if ( ( TRUE != isPressureDroppedDuringFill ) && ( TRUE == isFirstCycleBCSwitchingCompleted ) ) + { + // When fill initiated, pressure is not dropped to the expected range, possible valve failures. + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE1_FILL_PRESSURE_DROP_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); + } + else if ( TRUE != isPressureStalbilizedDuringFill ) + { + // Alarm when switching time expired, but still pressure not in range which indicates fill is not yet completed. + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE1_FILL_END_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); + } + else + { + // Move to next state when pressure is in range. + state = BAL_CHAMBER_STATE2_FILL_START; + } + } + else + { + // Allow to proceed next state even though pressure is not stabilized. + state = BAL_CHAMBER_STATE2_FILL_START; + } + } + else + { + state = BAL_CHAMBER_STATE2_FILL_START; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBalChamberState2FillStart function handles the balancing chamber + * state 2 fill and time to fill chamber counter being updated. + * @details \b Inputs: fresh and spent dialysate pressure + * @details \b Outputs: valve states + * @details \b Alarm: ALARM_ID_DD_BC_STATE2_FILL_START_PRESSURE_OUT_OF_RANGE + * when pressure is not in range during balancing chamber state 2 fill start. + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillStart( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE2_FILL_START; + currentBalChamberSwitchingCounter = 0; + isBalChamberFillInProgress = FALSE; + isPressureStalbilizedDuringFill = FALSE; + isPressureDroppedDuringFill = FALSE; + balChamberSWState = BAL_CHAMBER_SW_STATE2; + currentBalChamberFillCounter = 0; + isSpentFillComplete = FALSE; + lastPrevSpentDialPressure = 0.0F; + prevSpentDialPressure = 0.0F; + + F32 acidVolume = getF32OverrideValue( &acidDoseVolume ); + F32 bicarbVolume = getF32OverrideValue( &bicarbDoseVolume ); + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + // Check fresh dialysate pressure in range + if ( ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) || + // ( ( spentDialPressure >= SPENT_DIAL_PRESSURE_MIN_PSIG ) && ( spentDialPressure <= SPENT_DIAL_PRESSURE_MAX_PSIG ) ) || + ( TRUE == getBalChamberSwitchingOnlyStatus() ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) ) ) + { + // Valve control for state 2 fill + valveControlForBCState2FillStart(); + + // Update fill status flag to true + isBalChamberFillInProgress = TRUE; + + // Deliver dosing during generate dialysate mode + if ( TRUE != getBalChamberSwitchingOnlyStatus() ) + { + // start acid and bicarb pump with the expected quantity + setConcentratePumpTargetSpeed( D11_PUMP, CONCENTRATE_PUMP_MAX_SPEED, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, CONCENTRATE_PUMP_MAX_SPEED, bicarbVolume ); + requestConcentratePumpOn( D11_PUMP ); + requestConcentratePumpOn( D10_PUMP ); + } + + state = BAL_CHAMBER_STATE2_BICARB_ACID_DOSING_CNTRL; + } + else + { + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + { + //Alarm when pressure is not in range + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE2_FILL_START_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); + } + } + return state; +} + +/*********************************************************************//** + * @brief + * The handleBalChamberState2ValvesClose function check for the balancing chamber + * fill complete and close the currently opened valves. + * @details \b Inputs: currentBalChamberSwitchingCounter, spent and fresh dialysate pressure + * @details \b Outputs: isPressureStalbilizedDuringFill,isBalChamberFillInProgress + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2ValvesClose( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE2_VALVES_CLOSE; + + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + // Check fresh and spent dialysate pressure back in range to indicate fill complete. + if ( ( freshDialPressure >= FRESH_DIAL_PRESSURE_MIN_PSIG ) && ( freshDialPressure <= FRESH_DIAL_PRESSURE_MAX_PSIG ) ) + { + if ( ++balChamberFillCompleteStablePressureCounter >= BAL_CHAMBER_FILL_COMPLETE_MS ) + { + // stabilized pressure indicating fresh side fill is complete + isPressureStalbilizedDuringFill = TRUE; + } + } + + // Spent side of balancing chamber fill is complete or not + checkSpentFillComplete( spentDialPressure ); + + // Check switching cycle time or pressure check for valve closure + if ( ( TRUE == isSpentFillComplete ) && ( TRUE == isPressureStalbilizedDuringFill ) || ( FALSE == isFirstCycleBCSwitchingCompleted ) ) + { + // close the valves + valveControlForBCState2FillEnd(); + isBalChamberFillInProgress = FALSE; + setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); + + //Transition to next state + state = BAL_CHAMBER_STATE2_FILL_END; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBalChamberState2FillEnd function check for the balancing chamber + * switching period complete and transition to next state. + * @details \b Inputs: currentBalChamberSwitchingCounter, balChamberSwitchingPeriod + * @details \b Outputs: isPressureStalbilizedDuringFill,isBalChamberFillInProgress + * @details \b Alarm: ALARM_ID_DD_BC_STATE2_FILL_PRESSURE_DROP_OUT_OF_RANGE + * when pressure is not in range during balacing chamber state 2 fill in progress. + * @details \b Alarm: ALARM_ID_DD_BC_STATE2_FILL_END_PRESSURE_OUT_OF_RANGE + * when pressure is not in range during balacing chamber state 2 fill complete. + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillEnd( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE2_FILL_END; + + balChamberFillPressureDropCounter = 0; + balChamberFillCompleteStablePressureCounter = 0; + + // Pressure alarm check + if ( TRUE != getBalChamberSwitchingOnlyStatus() ) + { + if ( getTestConfigStatus( TEST_CONFIG_DD_DISABLE_BC_PRESSURE_ALARMS ) != TRUE ) + { + if ( ( TRUE != isPressureDroppedDuringFill ) && ( TRUE == isFirstCycleBCSwitchingCompleted ) ) + { + // When fill initiated, pressure is not dropped to the expected range, possible valve failures. + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE2_FILL_PRESSURE_DROP_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); + } + else if ( TRUE != isPressureStalbilizedDuringFill ) + { + // Alarm when switching time expired, but still pressure not in range which indicates fill is not completed. + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DD_BC_STATE2_FILL_END_PRESSURE_OUT_OF_RANGE, freshDialPressure, spentDialPressure ); + } + else + { + // Move to next state when pressure is in range. + state = BAL_CHAMBER_STATE1_FILL_START; + } + } + else + { + // Allow to proceed next state even though pressure is not stabilized. + state = BAL_CHAMBER_STATE1_FILL_START; + + } + } + else + { + state = BAL_CHAMBER_STATE1_FILL_START; + } + + // Trigger pressure drop alarm after first cycle of balancing chamber switching complete + if ( FALSE == isFirstCycleBCSwitchingCompleted ) + { + isFirstCycleBCSwitchingCompleted = TRUE; + } + + return state; +} + +#endif + +/*********************************************************************//** + * @brief + * The checkSpentFillComplete function checks the pressure difference for + * spent side fill completion and adjusts the D48 pump speed to align the + * fill timing close to the switching period time. + * @details \b Inputs: balChamberExecState + * @details \b Outputs: none + * @return the current state of balancing chamber states. + *************************************************************************/ +static void checkSpentFillComplete( F32 spentDialPressure ) +{ + F32 diffInSpentPressure = 0.0F; + U32 absDiffSpentFillCount = 0; + U32 adjustedSpeed = 0; + U32 spentDialPumpSpeed = getD48PumpSpeedForBCFill(); + U32 initialD48PumpSpeed = calculateD48PumpSpeedForBCFill(); + U32 minD48Speed = initialD48PumpSpeed - ( initialD48PumpSpeed * D48_SPEED_RANGE_LIMIT ); + U32 maxD48Speed = initialD48PumpSpeed + ( initialD48PumpSpeed * D48_SPEED_RANGE_LIMIT ); + U32 d48SpeedPostRangeCheck = 0; + + // Collect the next sample of spent pressure + lastPrevSpentDialPressure = prevSpentDialPressure; + prevSpentDialPressure = spentDialPressure; + // find the pressure difference for pressure spike detection + diffInSpentPressure = fabs(spentDialPressure - lastPrevSpentDialPressure); + + if ( ( spentDialPressure >= SPENT_FILL_COMPLETE_PRES ) && ( isSpentFillComplete != TRUE ) ) + { + // Check spent fill time against the balancing chamber closing period + diffSpentFillCompleteCount = balChamberValveClosePeriod - currentBalChamberFillCounter; + absDiffSpentFillCount = abs(diffSpentFillCompleteCount); + adjustedSpeed = ( ( (F32)absDiffSpentFillCount / (F32)balChamberValveClosePeriod ) * spentDialPumpSpeed ) * D48_SPEED_ADJUST_FACTOR; + + //Not adjust the D48 pump speed if the fill counter is just 50ms difference from the closing period. + if ( absDiffSpentFillCount > SPENT_DIFF_COUNT_DEADBAND ) + { + if ( diffSpentFillCompleteCount < SPENT_DIFF_COUNT_ZERO ) + { + // Increase the D48 pump speed + spentDialPumpSpeed += adjustedSpeed; + } + else + { + //Decrease the D48 pump speed + spentDialPumpSpeed -= adjustedSpeed; + } + + d48SpeedPostRangeCheck = RANGE( spentDialPumpSpeed, minD48Speed, maxD48Speed ); + + // Update the D48 pump speed + setD48PumpSpeedForBCFill( d48SpeedPostRangeCheck ); + } + + //Update spent fill is complete + isSpentFillComplete = TRUE; + } +} + +/*********************************************************************//** + * @brief * The getCurrentBalancingChamberExecState function returns the current state * of the balancing chamber. * @details \b Inputs: balChamberExecState @@ -901,9 +1358,15 @@ data.balChamberExecState = (U32)balChamberExecState; data.balChamberSWState = (U32)balChamberSWState; data.balChamberSWFreq = getBalChamberSwitchingFreq(); +#if 0 data.balChamberSwPeriod = balChamberSwitchingPeriod; data.isBalChamberFillInProgress = isBalChamberFillInProgress; data.currentBalChamberSwitchingCounter = currentBalChamberSwitchingCounter; +#else + data.balChamberSwPeriod = getD48PumpSpeedForBCFill(); + data.isBalChamberFillInProgress = isSpentFillComplete; + data.currentBalChamberSwitchingCounter = currentBalChamberFillCounter; +#endif data.isPressureStalbilizedDuringFill = isPressureStalbilizedDuringFill; data.balChamberSWOnlyState = balanceChamberSwitchingOnly;