Index: firmware/App/Controllers/BalancingChamber.c =================================================================== diff -u -r79906a34c1e88c2b02c7453079a6dffe09f9dfb4 -r25371dc5442fafdc0b138b4afe034b2f31ca3d1e --- firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 79906a34c1e88c2b02c7453079a6dffe09f9dfb4) +++ firmware/App/Controllers/BalancingChamber.c (.../BalancingChamber.c) (revision 25371dc5442fafdc0b138b4afe034b2f31ca3d1e) @@ -7,8 +7,8 @@ * * @file BalancingChamber.c * -* @author (last) Dara Navaei -* @date (last) 18-Mar-2026 +* @author (last) Vinayakam Mani +* @date (last) 06-Apr-2026 * * @author (original) Vinayakam Mani * @date (original) 28-Jan-2025 @@ -19,7 +19,7 @@ #include "Conductivity.h" #include "ConcentratePumps.h" #include "DialysatePumps.h" -#include "DryBiCart.h" // For request setBicarbChamberFillRequested +#include "DryBiCart.h" #include "FpgaDD.h" #include "Heaters.h" #include "ModeGenDialysate.h" @@ -47,12 +47,19 @@ #define SPENT_FILL_COMPLETE_PRES_QD_LOW_PSIG 3.5F ///< Spent fill complete pressure (PSI) when Diener 1000 and Qd <= 200. #define SPENT_FILL_COMPLETE_PRES_QD_MID_PSIG 15.0F ///< Spent fill complete pressure (PSI) when Diener 1000 and 200 < Qd <= 400. #define SPENT_FILL_COMPLETE_PRES_QD_HIGH_PSIG 20.0F ///< Spent fill complete pressure (PSI) when Diener 1000 and Qd > 400. +#define SPENT_FILL_COMPLETE_QD_SLOPE_MAX_MLPM 300.0F ///< For Qd <= 300 mL/min, spent fill completion uses pressure-rise slope detection. +#define SPENT_FILL_COMPLETE_QD_TWO_HIT_MAX_MLPM 150.0F ///< For Qd <= 150 mL/min, require two rise detections; above this and <=300, one rise detection is enough. +#define SPENT_FILL_COMPLETE_DP_RISE_PSIG 0.5F ///< Minimum 100 ms spent pressure rise (current minus n-2) to count as a rise hit at low Qd. +#define SPENT_FILL_SLOPE_SPENT_PRESSURE_HIGH_PSIG 2.0F ///< Above this absolute spent pressure, only one rise hit is required. +#define SPENT_FILL_SLOPE_SPENT_PRESSURE_LOW_PSIG 0.5F ///< Below this absolute spent pressure, use Qd-based required rise hit count. +#define SPENT_FILL_SLOPE_MAX_RISE_HITS 2 ///< Rise hits required when Qd <= 150 in the low spent-pressure band. +#define SPENT_FILL_DETECT_COUNT_TOL_PCT 0.20F ///< Allowed detection timing tolerance as a fraction of expected BC switching count. #define QD_THRESHOLD_LOW_MLPM 200.0F ///< Qd threshold (mL/min) below which low pressure limit applies. #define QD_THRESHOLD_HIGH_MLPM 400.0F ///< Qd threshold (mL/min) below which mid pressure limit applies. #define SPENT_DIFF_COUNT_ZERO 0 ///< Zero count difference for spent side fill comparing 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) -#define BICARB_CHAMBER_PERIODIC_FILL_TIME ( 1 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ) ///< Periodic bicarb chamber fill request 60 sec x 20 = 1200 +#define BICARB_CHAMBER_PERIODIC_FILL_TIME ( 1 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ) ///< Periodic bicarb chamber fill request 60 sec x 20 = 1200 #define BAL_CHAMBER_FILL_TIMEOUT_FACTOR 1.5 ///< Balancing Chamber fill timeout factor (150% of observed fill count) /// Payload record structure for balancing chamber switch only request @@ -75,7 +82,9 @@ static U32 balChamberDataPublicationTimerCounter; ///< Used to schedule balancing chamber data publication to CAN bus. static U32 balChamberFillPressureDropCounter; ///< Counter to check balancing chamber valves opened and there by pressure drop is seen. static OVERRIDE_U32_T balChamberDataPublishInterval; ///< Balancing chamber data publish interval. -static BOOL balanceChamberSwitchingOnly; ///< Balancing chamber switching without any pressure check and dosing delivery. +static BOOL balanceChamberSwitchingOnly; ///< Balancing chamber switching without any pressure check and dosing delivery +static BOOL balanceChamberSwitchingOnlyOnRequested; ///< Flag indicating that a request was made to activate balancing chamber switching only +static BOOL balanceChamberSwitchingOnlyOffRequested; ///< Flag indicating that a request was made to deactivate balancing chamber switching only static BOOL isPressureDroppedDuringFill; ///< Flag indicating that the pressure is dropped due to BC fill (state 1 or state 2) in progress condition. static BOOL isFirstCycleBCSwitchingCompleted; ///< Flag indicating that first time balancing chamber swithcing is done to trigger alarms from next cycle onwards. static U32 balChamberFillCompleteStablePressureCounter; ///< Counter to check balancing chamber fill complete and stable pressure is met. @@ -88,8 +97,15 @@ static U32 balChamberFillTimeoutCount; ///< Timeout count (in task interval) to detect BC fill timeout. static S32 diffSpentFillCompleteCount; ///< Difference between spent target fill to actual fill count static BOOL isSpentFillComplete; ///< Flag indicating spent side fill complete. +static BOOL isBalChamberSwitchingActive; ///< Flag indicating balancing chamber switching is active or not. +static BOOL isBalChamberSwitchingOnRequested; ///< Flag indicating that a request was made to activate balancing chamber switching. +static BOOL isBalChamberSwitchingOffRequested; ///< Flag indicating that a request was made to deactivate balancing chamber switching. +static F32 lastPrevSpentDialPressure; ///< Low-Qd slope: spent pressure last sample of dosing (tick before VALVES_CLOSE); then n-2 in VC. +static F32 prevSpentDialPressure; ///< Spent pressure previous sample (n-1) during VALVES_CLOSE for low-Qd slope detection. +static U32 spentFillRiseHitCount; ///< Low-Qd slope: counted rise hits (only incremented when in timing window). +static U32 spentFillRiseMissCounter; ///< Missed samples after a rise hit before resetting hit count. //TODO: remove later once level sensor working -static U32 bicarbChamberPeriodicFillCounter; +static U32 bicarbChamberPeriodicFillCounter; // ********** private function prototypes ********** @@ -100,9 +116,11 @@ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillStart( void ); static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2ValvesClose( void ); static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillEnd(void); +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberStateIdle( void ); static void publishBalChamberData( void ); static U32 getBalChamberDataPublishInterval( void ); static void checkSpentFillComplete( F32 spentDialPressure ); +static BOOL isSpentFillCompleteByPressure( F32 spentDialPressure, F32 qdMlpm, F32 spentFillCompletePresPsig ); /*********************************************************************//** * @brief @@ -113,7 +131,7 @@ *************************************************************************/ void initBalanceChamber( void ) { - balChamberExecState = BAL_CHAMBER_STATE_START; + balChamberExecState = BAL_CHAMBER_STATE_IDLE; balChamberSWState = BAL_CHAMBER_SW_STATE1; balChamberSwitchingFreq.data = 0.0F; balChamberSwitchingFreq.ovData = 0.0F; @@ -132,10 +150,11 @@ bicarbDoseVolume.ovInitData = 0.0F; bicarbDoseVolume.override = OVERRIDE_RESET; balanceChamberSwitchingOnly = FALSE; + balanceChamberSwitchingOnlyOnRequested = FALSE; + balanceChamberSwitchingOnlyOffRequested = FALSE; balChamberSwitchingPeriod = 0; balChamberValveClosePeriod = 0; isBalChamberFillInProgress = FALSE; - currentBalChamberSwitchingCounter = 0; isPressureStabilizedDuringFill = FALSE; lastTdDialysateFlowrate = 0.0F; balChamberDataPublicationTimerCounter = 0; @@ -145,10 +164,18 @@ isPressureDroppedDuringFill = FALSE; freshDialPressure = 0.0F; spentDialPressure = 0.0F; - currentBalChamberFillCounter = 0; balChamberFillTimeoutCount = 0; diffSpentFillCompleteCount = 0; + lastPrevSpentDialPressure = 0.0F; + prevSpentDialPressure = 0.0F; + currentBalChamberSwitchingCounter = 0; + currentBalChamberFillCounter = 0; + spentFillRiseHitCount = 0; + spentFillRiseMissCounter = 0; isSpentFillComplete = FALSE; + isBalChamberSwitchingActive = FALSE; + isBalChamberSwitchingOnRequested = FALSE; + isBalChamberSwitchingOffRequested = FALSE; //TODO:remove once level sensor working bicarbChamberPeriodicFillCounter = 0; } @@ -205,6 +232,15 @@ //Testing balChamberValveClosePeriod = balChamberSwitchingPeriod; balChamberValveClosePeriod -= 1; // Close valves prior 50 msecond for testing + + currentBalChamberFillCounter = 0; + currentBalChamberSwitchingCounter = 0; + spentFillRiseHitCount = 0; + spentFillRiseMissCounter = 0; + isSpentFillComplete = FALSE; + spentDialPressure = getFilteredPressure( D51_PRES ); + lastPrevSpentDialPressure = spentDialPressure; + prevSpentDialPressure = spentDialPressure; } } @@ -218,11 +254,13 @@ *************************************************************************/ U32 execBalancingChamberControl( void ) { + updateBalChamberSwitchingPeriod(); + // Increment counter indicating fill is in progress. currentBalChamberSwitchingCounter += 1; currentBalChamberFillCounter += 1; - if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == TRUE ) + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == TRUE && balChamberExecState > BAL_CHAMBER_STATE_IDLE) { // Increment counter for dry bicarb chamber fill bicarbChamberPeriodicFillCounter += 1; @@ -241,8 +279,8 @@ switch ( balChamberExecState ) { - case BAL_CHAMBER_STATE_START: - balChamberExecState = BAL_CHAMBER_STATE1_FILL_START; + case BAL_CHAMBER_STATE_IDLE: + balChamberExecState = handleBalChamberStateIdle(); break; case BAL_CHAMBER_STATE1_FILL_START: @@ -279,7 +317,7 @@ default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BAL_CHAMBER_INVALID_EXEC_STATE, balChamberExecState ) - balChamberExecState = BAL_CHAMBER_STATE_START; + balChamberExecState = BAL_CHAMBER_STATE_IDLE; break; } @@ -291,6 +329,26 @@ /*********************************************************************//** * @brief + * The requestBalChamberSwitching function activates or deactivates balancing chamber switching. + * @details \b Inputs: none + * @details \b Outputs: isBalChamberSwitchingOnRequested, isBalChamberSwitchingOffRequested + * @param activate - TRUE to activate and FALSE to deactivate. + * @return none. + *************************************************************************/ +void requestBalChamberSwitching( BOOL activate ) +{ + if ( TRUE == activate ) + { + isBalChamberSwitchingOnRequested = TRUE; + } + else + { + isBalChamberSwitchingOffRequested = TRUE; + } +} + +/*********************************************************************//** + * @brief * The valveControlForBCState1FillStart function actuates the valve combination * for state 1 fill/drain process. * @details \b Inputs: none @@ -450,21 +508,38 @@ *************************************************************************/ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState1FillStart( void ) { + F32 acidVolume; + F32 bicarbVolume; BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE1_FILL_START; - currentBalChamberSwitchingCounter = 0; balChamberSWState = BAL_CHAMBER_SW_STATE1; - currentBalChamberFillCounter = 0; balChamberFillTimeoutCount = 0; isBalChamberFillInProgress = FALSE; isPressureStabilizedDuringFill = FALSE; isPressureDroppedDuringFill = FALSE; + lastPrevSpentDialPressure = 0.0F; + prevSpentDialPressure = 0.0F; + currentBalChamberSwitchingCounter = 0; + currentBalChamberFillCounter = 0; + spentFillRiseHitCount = 0; + spentFillRiseMissCounter = 0; isSpentFillComplete = FALSE; - F32 acidVolume = getF32OverrideValue( &acidDoseVolume ); - F32 bicarbVolume = getF32OverrideValue( &bicarbDoseVolume ); - freshDialPressure = getFilteredPressure( D18_PRES ); - spentDialPressure = getFilteredPressure( D51_PRES ); + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == TRUE ) + { + bicarbVolume = getBicarbDoseVol(); + acidVolume = getAcidDoseVol(); + } + else + { + acidVolume = getF32OverrideValue( &acidDoseVolume ); + bicarbVolume = getF32OverrideValue( &bicarbDoseVolume ); + } + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + lastPrevSpentDialPressure = spentDialPressure; + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) ) { //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp @@ -490,8 +565,8 @@ 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 ); + setConcentratePumpTargetSpeed( D11_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, bicarbVolume ); requestConcentratePumpOn( D11_PUMP ); requestConcentratePumpOn( D10_PUMP ); } @@ -504,6 +579,9 @@ { //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 ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } } @@ -550,11 +628,14 @@ if ( BAL_CHAMBER_SW_STATE1 == balChamberSWState ) { - state = BAL_CHAMBER_STATE1_VALVES_CLOSE; + // Low-Qd spent slope: baseline = spent pressure on last dosing tick (this task period) before VALVES_CLOSE. + prevSpentDialPressure = spentDialPressure; + state = BAL_CHAMBER_STATE1_VALVES_CLOSE; } else { - state = BAL_CHAMBER_STATE2_VALVES_CLOSE; + prevSpentDialPressure = spentDialPressure; + state = BAL_CHAMBER_STATE2_VALVES_CLOSE; } } @@ -582,6 +663,9 @@ if ( ( balChamberFillTimeoutCount > 0 ) && ( currentBalChamberFillCounter > balChamberFillTimeoutCount ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_BC_FILL_TIMEOUT_FAULT, currentBalChamberFillCounter, balChamberFillTimeoutCount ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } // Check fresh dialysate pressure back in range to indicate fresh fill complete. @@ -600,18 +684,19 @@ // Check both spent and fresh side fill is complete isBothFillsComplete = ( TRUE == isSpentFillComplete ) && ( TRUE == isPressureStabilizedDuringFill ); isFirstCycleNotDone = ( FALSE == isFirstCycleBCSwitchingCompleted ); - isFillCompleteOrFirstCycle = isBothFillsComplete || isFirstCycleNotDone; - if ( TRUE == isFillCompleteOrFirstCycle ) + if ( FALSE == getBalChamberSwitchingOnlyStatus() ) { + isFillCompleteOrFirstCycle = isBothFillsComplete || isFirstCycleNotDone; + } + + if ( ( TRUE == isFillCompleteOrFirstCycle ) || + ( ( currentBalChamberSwitchingCounter >= balChamberValveClosePeriod ) && ( TRUE == getBalChamberSwitchingOnlyStatus() ) ) ) + { // close the state 1 opened valves valveControlForBCState1FillEnd(); isBalChamberFillInProgress = FALSE; - //setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); - if ( TRUE == isFirstCycleBCSwitchingCompleted ) - { - setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); - } + setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); // Transition to next state state = BAL_CHAMBER_STATE1_FILL_END; @@ -624,8 +709,11 @@ * @brief * The handleBalChamberState1FillEnd function check for the balancing chamber * switching period and transition to next state switching. - * @details \b Inputs: currentBalChamberSwitchingCounter, balChamberSwitchingPeriod + * @details \b Inputs: currentBalChamberSwitchingCounter, balChamberSwitchingPeriod, + * isBalChamberSwitchingOffRequested, balanceChamberSwitchingOnlyOffRequested * @details \b Outputs: balChamberFillPressureDropCounter,balChamberFillCompleteStablePressureCounter + * isBalChamberSwitchingOnRequested, isBalChamberSwitchingOffRequested, isBalChamberSwitchingActive, + * balanceChamberSwitchingOnlyOffRequested * @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 @@ -647,11 +735,18 @@ { // 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 ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } else if ( TRUE != isPressureStabilizedDuringFill ) { // 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 ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } else { @@ -666,10 +761,42 @@ } } else + { // For Balancing Chamber Switch Only command, change state as per the switching period + if ( currentBalChamberSwitchingCounter >= balChamberSwitchingPeriod ) + { + state = BAL_CHAMBER_STATE2_FILL_START; + } + } + + // Clear the switching only on request flag. + balanceChamberSwitchingOnlyOnRequested = FALSE; + + // Check if switching only off was requested + if ( TRUE == balanceChamberSwitchingOnlyOffRequested ) { - state = BAL_CHAMBER_STATE2_FILL_START; + // Clear the Switch only off request flag + balanceChamberSwitchingOnlyOffRequested = FALSE; + + //Clear the switch only flag + setBalChamberSwitchingOnlyStatus( FALSE ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } + // Keep Clearing the On request flag in case an On request was made while the switching is active + isBalChamberSwitchingOnRequested = FALSE; + + // Check if a request made was to deactivate the balancing chamber switching. + if ( TRUE == isBalChamberSwitchingOffRequested ) + { + //Clear the request flag to indicate that the request was processed. + isBalChamberSwitchingOffRequested = FALSE; + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } + return state; } @@ -685,21 +812,38 @@ *************************************************************************/ static BAL_CHAMBER_EXEC_STATE_T handleBalChamberState2FillStart( void ) { + F32 acidVolume; + F32 bicarbVolume; BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE2_FILL_START; - currentBalChamberSwitchingCounter = 0; isBalChamberFillInProgress = FALSE; isPressureStabilizedDuringFill = FALSE; isPressureDroppedDuringFill = FALSE; balChamberSWState = BAL_CHAMBER_SW_STATE2; - currentBalChamberFillCounter = 0; balChamberFillTimeoutCount = 0; + lastPrevSpentDialPressure = 0.0F; + prevSpentDialPressure = 0.0F; + currentBalChamberSwitchingCounter = 0; + currentBalChamberFillCounter = 0; + spentFillRiseHitCount = 0; + spentFillRiseMissCounter = 0; isSpentFillComplete = FALSE; - F32 acidVolume = getF32OverrideValue( &acidDoseVolume ); - F32 bicarbVolume = getF32OverrideValue( &bicarbDoseVolume ); - freshDialPressure = getFilteredPressure( D18_PRES ); - spentDialPressure = getFilteredPressure( D51_PRES ); + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == TRUE ) + { + bicarbVolume = getBicarbDoseVol(); + acidVolume = getAcidDoseVol(); + } + else + { + acidVolume = getF32OverrideValue( &acidDoseVolume ); + bicarbVolume = getF32OverrideValue( &bicarbDoseVolume ); + } + freshDialPressure = getFilteredPressure( D18_PRES ); + spentDialPressure = getFilteredPressure( D51_PRES ); + + lastPrevSpentDialPressure = spentDialPressure; + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) ) { //Set Trimmer heater Target temp every BC cycle to catch up fresh dialysate temp @@ -725,8 +869,8 @@ 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 ); + setConcentratePumpTargetSpeed( D11_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, acidVolume ); + setConcentratePumpTargetSpeed( D10_PUMP, DOSING_CONCENTRATE_PUMP_SPEED, bicarbVolume ); requestConcentratePumpOn( D11_PUMP ); requestConcentratePumpOn( D10_PUMP ); } @@ -739,6 +883,9 @@ { //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 ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } } @@ -776,6 +923,10 @@ if ( ( balChamberFillTimeoutCount > 0 ) && ( currentBalChamberFillCounter > balChamberFillTimeoutCount ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_BC_FILL_TIMEOUT_FAULT, currentBalChamberFillCounter, balChamberFillTimeoutCount ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } // Spent side of balancing chamber fill is complete or not @@ -784,18 +935,19 @@ // Check switching cycle time or pressure check for valve closure isBothFillsComplete = ( TRUE == isSpentFillComplete ) && ( TRUE == isPressureStabilizedDuringFill ); isFirstCycleNotDone = ( FALSE == isFirstCycleBCSwitchingCompleted ); - isFillCompleteOrFirstCycle = isBothFillsComplete || isFirstCycleNotDone; - if ( TRUE == isFillCompleteOrFirstCycle ) + if ( FALSE == getBalChamberSwitchingOnlyStatus() ) { + isFillCompleteOrFirstCycle = isBothFillsComplete || isFirstCycleNotDone; + } + + if ( ( TRUE == isFillCompleteOrFirstCycle ) || + ( ( currentBalChamberSwitchingCounter >= balChamberValveClosePeriod ) && ( TRUE == getBalChamberSwitchingOnlyStatus() ) ) ) + { // close the valves valveControlForBCState2FillEnd(); isBalChamberFillInProgress = FALSE; - //setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); - if ( TRUE == isFirstCycleBCSwitchingCompleted ) - { - setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); - } + setDialysatePumpTargetRPM( D48_PUMP, getD48PumpSpeedForBCFill(), TRUE ); //Transition to next state state = BAL_CHAMBER_STATE2_FILL_END; @@ -808,8 +960,11 @@ * @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 Inputs: currentBalChamberSwitchingCounter, balChamberSwitchingPeriod, + * isBalChamberSwitchingOffRequested, balanceChamberSwitchingOnlyOffRequested + * @details \b Outputs: isPressureStabilizedDuringFill,isBalChamberFillInProgress, + * isBalChamberSwitchingOnRequested, isBalChamberSwitchingOffRequested, isBalChamberSwitchingActive, + * balanceChamberSwitchingOnlyOffRequested * @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 @@ -832,11 +987,17 @@ { // 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 ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } else if ( TRUE != isPressureStabilizedDuringFill ) { // 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 ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; } else { @@ -852,7 +1013,11 @@ } else { - state = BAL_CHAMBER_STATE1_FILL_START; + // For Balancing Chamber Switch Only command, change state as per the switching period + if ( currentBalChamberSwitchingCounter >= balChamberSwitchingPeriod ) + { + state = BAL_CHAMBER_STATE1_FILL_START; + } } // Trigger pressure drop alarm after first cycle of balancing chamber switching complete @@ -861,11 +1026,170 @@ isFirstCycleBCSwitchingCompleted = TRUE; } + // Clear the switching only on request flag. + balanceChamberSwitchingOnlyOnRequested = FALSE; + + // Check if switching only off was requested + if ( TRUE == balanceChamberSwitchingOnlyOffRequested ) + { + // Clear the Switch only off request flag + balanceChamberSwitchingOnlyOffRequested = FALSE; + + //Clear the switch only flag + setBalChamberSwitchingOnlyStatus( FALSE ); + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } + + // Keep Clearing the On request flag in case an On request was made while the switching is active + isBalChamberSwitchingOnRequested = FALSE; + + // Check if a request made was to deactivate the balancing chamber switching. + if ( TRUE == isBalChamberSwitchingOffRequested ) + { + // Clear the request flag to indicate that the request was processed. + isBalChamberSwitchingOffRequested = FALSE; + + // Move to the idle state + state = BAL_CHAMBER_STATE_IDLE; + } + return state; } /*********************************************************************//** * @brief + * The handleBalChamberStateIdle function handles balancing chamber idle state. + * @details \b Inputs: isBalChamberSwitchingOnRequested + * @details \b Outputs: isBalChamberSwitchingOnRequested, isBalChamberSwitchingOffRequested, + * isBalChamberSwitchingActive + * @return next balancing chamber state. + *************************************************************************/ +static BAL_CHAMBER_EXEC_STATE_T handleBalChamberStateIdle( void ) +{ + BAL_CHAMBER_EXEC_STATE_T state = BAL_CHAMBER_STATE_IDLE; + + // Clear the switching only off request flag. + balanceChamberSwitchingOnlyOffRequested = FALSE; + + // Check if the switching only on was requested + if ( TRUE == balanceChamberSwitchingOnlyOnRequested ) + { + // Clear the switching only on request flag. + balanceChamberSwitchingOnlyOnRequested = FALSE; + + // then set BC switching only flag to ignore pressure check and dosing. + setBalChamberSwitchingOnlyStatus( TRUE ); + + // Set flag to indicate that balancing chamber switching is active + isBalChamberSwitchingActive = TRUE; + + // Move to the start state1 + state = BAL_CHAMBER_STATE1_FILL_START; + } + + // Keep Clearing the off request flag in case an off request was made while we were already in the idle state + isBalChamberSwitchingOffRequested = FALSE; + + // Clear flag to indicate that balancing chamber switching is inactive + isBalChamberSwitchingActive = FALSE; + + // Check if a request made was to activate the balancing chamber switching. + if ( TRUE == isBalChamberSwitchingOnRequested ) + { + //Clear the request flag to indicate that the request was processed. + isBalChamberSwitchingOnRequested = FALSE; + + // Set flag to indicate that balancing chamber switching is active + isBalChamberSwitchingActive = TRUE; + + // Move to the start state1 + state = BAL_CHAMBER_STATE1_FILL_START; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The isSpentFillCompleteByPressure function evaluates whether the spent side of the + * balancing chamber fill is complete from D51 pressure. + * @details \b Inputs: spentDialPressure, qdMlpm, spentFillCompletePresPsig, valve-close period, + * fill counter, Diener pump test config, and D51 slope history for low-Qd slope mode. + * @details \b Outputs: spentFillRiseHitCount, spentFillRiseMissCounter, + * lastPrevSpentDialPressure, prevSpentDialPressure (updated only in slope mode). + * @param spentDialPressure filtered spent dialysate pressure (PSIG). + * @param qdMlpm dialysate flow rate (mL/min). + * @param spentFillCompletePresPsig spent fill complete pressure threshold for current Qd and pump. + * @return TRUE if spent fill is detected this task period; FALSE otherwise. + *************************************************************************/ +static BOOL isSpentFillCompleteByPressure( F32 spentDialPressure, F32 qdMlpm, F32 spentFillCompletePresPsig ) +{ + BOOL useSlopeDetector = ( ( TRUE != getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) && + ( qdMlpm <= SPENT_FILL_COMPLETE_QD_SLOPE_MAX_MLPM ) ); + BOOL state; + + if ( TRUE == useSlopeDetector ) + { + U32 detectTolCount = (U32)( (F32)balChamberValveClosePeriod * SPENT_FILL_DETECT_COUNT_TOL_PCT ); + U32 maxDetectCount = balChamberValveClosePeriod + detectTolCount; + U32 minDetectCount = balChamberValveClosePeriod - detectTolCount; + BOOL isDetectionInCountWindow = ( ( currentBalChamberFillCounter >= minDetectCount ) && + ( currentBalChamberFillCounter <= maxDetectCount ) ); + F32 riseDeltaPsi = spentDialPressure - lastPrevSpentDialPressure; + BOOL riseHit = ( riseDeltaPsi > SPENT_FILL_COMPLETE_DP_RISE_PSIG ); + U32 requiredRiseCount; + + if ( riseDeltaPsi > SPENT_FILL_SLOPE_SPENT_PRESSURE_HIGH_PSIG ) + { + requiredRiseCount = 1U; + } + else if ( riseDeltaPsi < SPENT_FILL_SLOPE_SPENT_PRESSURE_LOW_PSIG ) + { + requiredRiseCount = ( qdMlpm <= SPENT_FILL_COMPLETE_QD_TWO_HIT_MAX_MLPM ) ? SPENT_FILL_SLOPE_MAX_RISE_HITS : 1U; + } + else + { + requiredRiseCount = 1U; + } + + if ( ( TRUE == riseHit ) && ( TRUE == isDetectionInCountWindow ) ) + { + spentFillRiseHitCount += 1; + spentFillRiseMissCounter = 0; + } + else if ( spentFillRiseHitCount > 0 ) + { + if ( ( FALSE == riseHit ) && ( TRUE == isDetectionInCountWindow ) ) + { + spentFillRiseMissCounter += 1; + + if ( spentFillRiseMissCounter >= 2 ) + { + spentFillRiseHitCount = 0; + spentFillRiseMissCounter = 0; + } + } + } + + lastPrevSpentDialPressure = prevSpentDialPressure; + prevSpentDialPressure = spentDialPressure; + + state = ( ( spentFillRiseHitCount >= requiredRiseCount ) || + ( ( currentBalChamberFillCounter >= balChamberValveClosePeriod ) && + ( spentDialPressure >= spentFillCompletePresPsig ) ) ); + } + else + { + state = ( spentDialPressure >= spentFillCompletePresPsig ); + + } + return state; +} + +/*********************************************************************//** + * @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. @@ -886,6 +1210,7 @@ F32 qdMlpm = getTDDialysateFlowrate(); BOOL result = FALSE; F32 spentFillCompletePresPsig; + BOOL isSpentFillCompleteDetected = FALSE; // Diener 2000 pump: spent fill complete pressure use legacy 25 PSI. Other pump: depends on Qd. if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DIENER_2000_PUMP ) ) @@ -908,33 +1233,42 @@ } } - if ( ( spentDialPressure >= spentFillCompletePresPsig ) && ( isSpentFillComplete != TRUE ) ) + isSpentFillCompleteDetected = isSpentFillCompleteByPressure( spentDialPressure, qdMlpm, spentFillCompletePresPsig ); + + if ( ( TRUE == isSpentFillCompleteDetected ) && ( 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; - - result = ( ( diffSpentFillCompleteCount <= 0 ) && ( diffSpentFillCompleteCount >= -2 ) ) ? TRUE : FALSE; - //Not adjust the D48 pump speed if the fill counter is just 50ms difference from the closing period (considering only positive DEADBAND as negative deadband might indicate under fill of BC). - if ( FALSE == result ) + if ( balChamberValveClosePeriod > 0 ) { - if ( diffSpentFillCompleteCount < SPENT_DIFF_COUNT_ZERO ) + diffSpentFillCompleteCount = balChamberValveClosePeriod - currentBalChamberFillCounter; + absDiffSpentFillCount = abs(diffSpentFillCompleteCount); + adjustedSpeed = ( ( (F32)absDiffSpentFillCount / (F32)balChamberValveClosePeriod ) * spentDialPumpSpeed ) * D48_SPEED_ADJUST_FACTOR; + + result = ( ( diffSpentFillCompleteCount <= 0 ) && ( diffSpentFillCompleteCount >= -2 ) ) ? TRUE : FALSE; + //Not adjust the D48 pump speed if the fill counter is just 50ms difference from the closing period (considering only positive DEADBAND as negative deadband might indicate under fill of BC). + if ( FALSE == result ) { - // Increase the D48 pump speed - spentDialPumpSpeed += adjustedSpeed; - } - else - { - //Decrease the D48 pump speed - spentDialPumpSpeed -= adjustedSpeed; - } + 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 ); + d48SpeedPostRangeCheck = RANGE( spentDialPumpSpeed, minD48Speed, maxD48Speed ); - // Update the D48 pump speed - setD48PumpSpeedForBCFill( d48SpeedPostRangeCheck ); + // Do not turn on the pump if the switching only is enabled in the standby mode. + if ( FALSE == getBalChamberSwitchingOnlyStatus() ) + { + // Update the D48 pump speed + setD48PumpSpeedForBCFill( d48SpeedPostRangeCheck ); + } } + } //Update spent fill is complete isSpentFillComplete = TRUE; @@ -1072,6 +1406,7 @@ data.currentBalChamberSwitchingCounter = currentBalChamberFillCounter; data.isPressureStabilizedDuringFill = isPressureStabilizedDuringFill; data.balChamberSWOnlyState = balanceChamberSwitchingOnly; + data.isBalChamberSwitchingActive = isBalChamberSwitchingActive; broadcastData( MSG_ID_DD_BAL_CHAMBER_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( BAL_CHAMBER_DATA_T ) ); @@ -1159,7 +1494,6 @@ * chamber switching only without dosing delivery and pressure check condition. * @details \b Inputs: tester logged in * @details \b Outputs: tdDialysateFlowrate,balanceChamberSwitchingOnly - * pendingBalanceChamberSwOnlyRequest * @param message set message from Dialin which includes the balancing chamber * to start/stop switching and update switching rate based on the flow rate. * @return TRUE if set request is successful, FALSE if not @@ -1186,17 +1520,18 @@ setTDDialysateFlowrate( payload.flowrate ); // update switching rate transitionToBalChamberFill(); - // then set BC switching only flag to ignore pressure check and dosing. - setBalChamberSwitchingOnlyStatus( TRUE ); + // Set the flag to indicate that a request was made to start the switching only + balanceChamberSwitchingOnlyOnRequested = TRUE; // Now, if the current operating mode is standby mode idle state, execute the balancing chamber switching only control result = requestBCSwitchingOnlyStart(); } //Handle stop command if ( FALSE == payload.startStop ) { - //Reset the flag - setBalChamberSwitchingOnlyStatus( FALSE ); + // Set the flag to indicate that a request was made to stop the switching only + balanceChamberSwitchingOnlyOffRequested = TRUE; + //Stop the BC switching execution only control requestBCSwitchingOnlyStop(); result = TRUE; Index: firmware/App/Controllers/Ultrafiltration.c =================================================================== diff -u -r79906a34c1e88c2b02c7453079a6dffe09f9dfb4 -r25371dc5442fafdc0b138b4afe034b2f31ca3d1e --- firmware/App/Controllers/Ultrafiltration.c (.../Ultrafiltration.c) (revision 79906a34c1e88c2b02c7453079a6dffe09f9dfb4) +++ firmware/App/Controllers/Ultrafiltration.c (.../Ultrafiltration.c) (revision 25371dc5442fafdc0b138b4afe034b2f31ca3d1e) @@ -8,7 +8,7 @@ * @file Ultrafiltration.c * * @author (last) Vinayakam Mani -* @date (last) 09-Feb-2026 +* @date (last) 19-Feb-2026 * * @author (original) Vinayakam Mani * @date (original) 28-Jul-2025 Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -r79906a34c1e88c2b02c7453079a6dffe09f9dfb4 -r25371dc5442fafdc0b138b4afe034b2f31ca3d1e --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 79906a34c1e88c2b02c7453079a6dffe09f9dfb4) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 25371dc5442fafdc0b138b4afe034b2f31ca3d1e) @@ -7,8 +7,8 @@ * * @file ModeGenDialysate.c * -* @author (last) Dara Navaei -* @date (last) 18-Mar-2026 +* @author (last) Vinayakam Mani +* @date (last) 06-Apr-2026 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 @@ -56,19 +56,14 @@ #define DIALYSATE_TEMP_UPPER_SAFETY_LIMIT_C 42.0F ///< Dialysate upper bound safety temperature limit in C. #define DIALYSATE_TEMP_LOWER_SAFETY_LIMIT_C 33.0F ///< Dialysate lower bound safety temperature limit in C. #define DIALYSATE_TEMP_CLEAR_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature clear persistence timeout. -#define QUAD_FIRST_COEFFICIENT 0.0006F ///< First coefficient used in adjusted dialysate temperature quadratic calculation for low Qds -#define QUAD_SECOND_COEFFICIENT -0.1743F ///< Second coefficient used in adjusted dialysate temperature quadratic calculation for low Qds -#define QUAD_THIRD_COEFFICIENT 17.3F ///< Third coefficient used in adjusted dialysate temperature quadratic calculation for low Qds -#define LINEAR_SLOPE_FACTOR -0.0029F ///< Slope factor used in adjusted dialysate temperature linear calculation for high Qds -#define LINEAR_INTERCEPT_FACTOR 3.47F ///< Intercept factor used in adjusted dialysate temperature linear calculation for high Qds -#define LOW_DIAL_FLOW_RATE 150.0F ///< Dialysate flow rate lesser than 150 considered to be low Qds. #define ZERO_DIAL_FLOW_RATE 0.0F ///< Zero dialysate flow rate #define SPENT_CHAMBER_FILL_MAX_COUNT 10 ///< Total number of spent chamber fill allowed. #define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. #define PUMP_SPEED_SLOPE_FACTOR_DIENER_2000 1.24F ///< D48 Diener 2000 pump speed slope (y = 1.24x + 30). #define PUMP_SPEED_INTERCEPT_FACTOR_DIENER_2000 30.0F ///< D48 Diener 2000 pump speed intercept. #define PUMP_SPEED_SLOPE_FACTOR_DIENER_1000 2.869F ///< D48 Diener 1000 pump speed slope (y = 2.869x + 25.956). #define PUMP_SPEED_INTERCEPT_FACTOR_DIENER_1000 25.956F ///< D48 Diener 1000 pump speed intercept. + #define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. //Testing @@ -108,7 +103,6 @@ static DD_GEND_MODE_STATE_T handleGenDBicarbChamberFillState( void ); static DD_GEND_MODE_STATE_T handleGenDIsolatedUFState( void ); static F32 getGenDialysateTargetTemperature( void ); -static void calculateTargetDialysateTemp( void ); static void updateDialysateToDialyzerFlowRate( void ); static void checkDialysateTemperature( void ); static void monitorChamberLevelStatus( void ); @@ -175,6 +169,8 @@ initGenDialysateMode(); setCurrentSubState( NO_SUB_STATE ); + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); //calculateD48PumpSpeedForBCFill(); initialD48PumpSpeed = getCalculatedD48PumpSpeedForBCFill(); setD48PumpSpeedForBCFill( initialD48PumpSpeed ); @@ -243,7 +239,8 @@ switch( state ) { case DD_GEND_STATE_START: - // Do nothing + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); break; case DD_GEND_DIALYSATE_BYPASS_STATE: @@ -292,13 +289,18 @@ setRinsePumpState( RINSE_PUMP_STATE_ON ); transitionToBalChamberFill(); + // Activate Balancing Chamber Switching + requestBalChamberSwitching( TRUE ); //Testing bypassStateDelayStartTimeMS = getMSTimerCount(); delayBypassStateFlag = TRUE; break; case DD_GEND_DIALYSATE_DELIVERY_STATE: + // Activate Balancing Chamber Switching + requestBalChamberSwitching( TRUE ); + //Previous state setValveState( D47_VALV, VALVE_STATE_CLOSED ); // spent chamber purge valve setValveState( D8_VALV, VALVE_STATE_CLOSED ); @@ -347,6 +349,9 @@ break; case DD_GEND_SPENT_CHAMBER_FILL_STATE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); + //Set valves and actuators setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO @@ -390,6 +395,9 @@ break; case DD_GEND_BICARB_CHAMBER_FILL_STATE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); + requestConcentratePumpOff( D11_PUMP, FALSE ); requestConcentratePumpOff( D10_PUMP, FALSE ); requestConcentratePumpOff( D76_PUMP, FALSE ); @@ -426,6 +434,8 @@ break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); signalDialysatePumpHardStop( D48_PUMP ); requestConcentratePumpOff( D11_PUMP, FALSE ); @@ -467,6 +477,8 @@ break; case DD_GEND_ISOLATED_UF_STATE: + // Deactivate Balancing Chamber Switching + requestBalChamberSwitching( FALSE ); //TODO : define actuators states break; @@ -643,37 +655,6 @@ /*********************************************************************//** * @brief - * The calculateTargetDialysateTemp function calculate the delta temperature - * required for dialysate temperature to meet the set temperature at dialyzer. - * @details \b Inputs: Qd and target temperature. - * @details \b Outputs: Adjusted Target temperature - * @return none. - *************************************************************************/ -static void calculateTargetDialysateTemp( void ) -{ - // Get the dialysate flow rate from TD - F32 dialFlowrate = getTDDialysateFlowrate(); - F32 deltaTemp = 0.0F; - - if ( dialFlowrate >= LOW_DIAL_FLOW_RATE ) - { - // linear relationship seen against high dialysate flowrate Vs DeltaTemp - // deltaTemp = (-0.0029 * Qd) + 3.47 - deltaTemp = ( LINEAR_SLOPE_FACTOR * dialFlowrate ) + LINEAR_INTERCEPT_FACTOR; - } - else - { - // deltaTemp = (0.0006 * Qd * Qd)-(0.1743*Qd) + 17.3 - deltaTemp = ( QUAD_FIRST_COEFFICIENT * dialFlowrate * dialFlowrate ) + - ( QUAD_SECOND_COEFFICIENT * dialFlowrate ) + QUAD_THIRD_COEFFICIENT; - } - - // Adjust the D4 target temperature - targetHydChamberFluidTemp.data = getTDTargetDialysateTemperature() + deltaTemp; -} - -/*********************************************************************//** - * @brief * The getCalculatedD48PumpSpeedForBCFill function returns the D48 pump speed * calculated from dialysate flow rate (Qd) for continuous delivery. * @details \b Inputs: Qd from TD, test config TEST_CONFIG_DD_ENABLE_DIENER_1000_PUMP. @@ -755,11 +736,6 @@ delayBypassStateFlag = FALSE; } } - else - { - //Execute balancing chamber - execBalancingChamberControl(); - } if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_SPENT_CHAMBER_H_FILL ) == TRUE ) { @@ -836,9 +812,6 @@ #endif else { - //Execute balancing chamber - execBalancingChamberControl(); - //Execute ultrafiltration execUFControl(); } @@ -994,6 +967,20 @@ /*********************************************************************//** * @brief + * The setTargetHydChamberTemp function updates the target hydraulics temperature + * for D5 heater control + * @details \b Inputs: none + * @details \b Outputs: targetHydChamberFluidTemp + * @param temperature The target temperature for D5 heater control + * @return none + *************************************************************************/ +void setTargetHydChamberTemp( F32 temperature ) +{ + targetHydChamberFluidTemp.data = temperature; +} + +/*********************************************************************//** + * @brief * The updateTreatmentSettings function updates the switching rate post the * treatement parameters updated during treatement. * @details \b Inputs: isTreatmentParamUpdated @@ -1026,6 +1013,7 @@ //calculateD48PumpSpeedForBCFill(); initialPumpSpeed = getCalculatedD48PumpSpeedForBCFill(); setD48PumpSpeedForBCFill( initialPumpSpeed ); + setDialysatePumpTargetRPM( D48_PUMP, (U32)initialPumpSpeed, TRUE ); //reset the flag isTreatmentParamUpdated = FALSE; @@ -1227,8 +1215,8 @@ * @brief * The testDialDeliveryInProgressOverride function sets the override value * of the dialysate delivery In progress flag. - * @details Inputs: isDialDeliveryInProgress - * @details Outputs: isDialDeliveryInProgress + * @details \b Inputs: isDialDeliveryInProgress + * @details \b Outputs: isDialDeliveryInProgress * @param message Override message from Dialin which includes the override * value to override the dialysate delivery in progress flag. * @return TRUE if override successful, FALSE if not @@ -1244,8 +1232,8 @@ * @brief * The testDialGoodToDeliverStatusOverride function sets the override value * of the dialysate good to deliver status flag. - * @details Inputs: isDialysateGoodtoDeliver - * @details Outputs: isDialysateGoodtoDeliver + * @details \b Inputs: isDialysateGoodtoDeliver + * @details \b Outputs: isDialysateGoodtoDeliver * @param message Override message from Dialin which includes the override * value to override the dialysate delivery in progress flag. * @return TRUE if override successful, FALSE if not