Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -ra6737c3bcc8286c153b778c2c395f465e76aaafb -r60e6185c2c5df195ccb6b603f30548779b4f05c4 --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision a6737c3bcc8286c153b778c2c395f465e76aaafb) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision 60e6185c2c5df195ccb6b603f30548779b4f05c4) @@ -94,18 +94,21 @@ static BOOL delayBypassStateFlag; ///< To indicate change in treatment parameters static F32 dialysateToDialyzerFlowRate; ///< Current dialysate to dialyzer flow rate (ml/min) static U32 d48PumpSpeed; ///< Initial D48 pump speed based on the Qd. +static DD_GEND_ISO_UF_SUB_STATE_T isolatedUFSubState; ///< Isolated UF run/pause sub-state. // ********** private function prototypes ********** static void setModeGenDStateTransition( DD_GEND_MODE_STATE_T state ); static DD_GEND_MODE_STATE_T handleGenDDialysateBypassState( void ); static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryState( void ); static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryPauseState( void ); -static DD_GEND_MODE_STATE_T handleGenDSpentChamberFillState(void); +static DD_GEND_MODE_STATE_T handleGenDSpentChamberFillState( void ); static DD_GEND_MODE_STATE_T handleGenDBicarbChamberFillState( void ); -static DD_GEND_MODE_STATE_T handleGenDIsolatedUFState( void ); +static DD_GEND_MODE_STATE_T handleGenDDialysateIsolatedUFState( void ); static F32 getGenDialysateTargetTemperature( void ); static void updateDialysateToDialyzerFlowRate( void ); +static DD_GEND_MODE_STATE_T applyTDRequestedGenDialysateState( DD_GEND_MODE_STATE_T state ); +static DD_GEND_ISO_UF_SUB_STATE_T getIsolatedUFSubStateForUFRate( void ); static void checkDialysateTemperature( void ); static void monitorChamberLevelStatus( void ); static void publishGenDialysateModeData( void ); @@ -148,6 +151,7 @@ bypassStateDelayStartTimeMS = 0; delayBypassStateFlag = TRUE; dialysateToDialyzerFlowRate = 0.0F; + isolatedUFSubState = DD_GEND_ISO_UF_PAUSE_STATE; //Initialize balancing chamber module initBalanceChamber(); @@ -478,9 +482,61 @@ break; case DD_GEND_ISOLATED_UF_STATE: - // Deactivate Balancing Chamber Switching - requestBalChamberSwitching( FALSE ); - //TODO : define actuators states + isolatedUFSubState = getIsolatedUFSubStateForUFRate(); + resetUFVolumeDelivered(); + + transitionToBalChamberFill(); + // Activate Balancing Chamber Switching + requestBalChamberSwitching( TRUE ); + + setValveState( D8_VALV, VALVE_STATE_CLOSED ); + setValveState( D14_VALV, VALVE_STATE_OPEN ); + setValveState( D31_VALV, VALVE_STATE_CLOSED ); + setValveState( D34_VALV, VALVE_STATE_CLOSED ); + setValveState( D91_VALV, VALVE_STATE_OPEN ); + setValveState( D35_VALV, VALVE_STATE_CLOSED ); + setValveState( D40_VALV, VALVE_STATE_OPEN ); + setValveState( D47_VALV, VALVE_STATE_CLOSED ); + setValveState( D52_VALV, VALVE_STATE_CLOSED ); + setValveState( D54_VALV, VALVE_STATE_CLOSED ); + setValveState( D100_VALV, VALVE_STATE_CLOSED ); + setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve (same as bypass/delivery during gen dialysate) + setValveState( D81_VALV, VALVE_STATE_CLOSED ); + setValveState( D85_VALV, VALVE_STATE_CLOSED ); + + if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_DRY_BICARB ) == FALSE ) + { + setValveState( D80_VALV, VALVE_STATE_OPEN ); + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + } + + calculateTargetDialysateTemp(); + setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); + setD28TempFeedbackControl( TRUE ); + startHeater( D5_HEAT ); + + if ( getTestConfigStatus( TEST_CONFIG_DD_FP_ENABLE_BETA_1_0_HW ) == TRUE ) + { + setHeaterTargetTemperature( D45_HEAT, getFilteredTemperatureValue( D4_TEMP ) ); + } + else + { + setHeaterTargetTemperature( D45_HEAT, getFilteredTemperatureValue( D99_TEMP ) ); + } + startHeater( D45_HEAT ); + + setDialysatePumpTargetRPM( D12_PUMP, getFreshDialPumpInitialRpm(), TRUE ); + + if ( getTDDialysateFlowrate() > ZERO_DIAL_FLOW_RATE ) + { + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); + } + else + { + signalDialysatePumpHardStop( D48_PUMP ); + } + + setRinsePumpState( RINSE_PUMP_STATE_ON ); break; default: @@ -556,7 +612,7 @@ break; case DD_GEND_ISOLATED_UF_STATE: - genDialysateState = handleGenDIsolatedUFState(); + genDialysateState = handleGenDDialysateIsolatedUFState(); break; default: @@ -718,18 +774,118 @@ /*********************************************************************//** * @brief + * The applyTDRequestedGenDialysateState function transitions the gen dialysate + * sub-state to match the latest TD request when allowed. + * @details \b Inputs: getTDRequestedGenDState, getDialGoodToDeliverStatus + * @details \b Outputs: isDialDeliveryInProgress + * @param state Current gen dialysate sub-state. + * @return Updated gen dialysate sub-state (unchanged if TD request not applied). + *************************************************************************/ +static DD_GEND_MODE_STATE_T applyTDRequestedGenDialysateState( DD_GEND_MODE_STATE_T state ) +{ + DD_GEND_MODE_STATE_T requested = (DD_GEND_MODE_STATE_T)getTDRequestedGenDState(); + + if ( state != requested ) + { + switch ( requested ) + { + case DD_GEND_DIALYSATE_BYPASS_STATE: + setModeGenDStateTransition( DD_GEND_DIALYSATE_BYPASS_STATE ); + isDialDeliveryInProgress.data = FALSE; + state = DD_GEND_DIALYSATE_BYPASS_STATE; + break; + + case DD_GEND_DIALYSATE_DELIVERY_STATE: + if ( TRUE == getDialGoodToDeliverStatus() ) + { + setModeGenDStateTransition( DD_GEND_DIALYSATE_DELIVERY_STATE ); + isDialDeliveryInProgress.data = TRUE; + state = DD_GEND_DIALYSATE_DELIVERY_STATE; + } + break; + + case DD_GEND_ISOLATED_UF_STATE: + setModeGenDStateTransition( DD_GEND_ISOLATED_UF_STATE ); + isDialDeliveryInProgress.data = FALSE; + state = DD_GEND_ISOLATED_UF_STATE; + break; + + default: + break; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The getIsolatedUFSubStateForUFRate function maps the latest TD UF rate to + * the required isolated UF run/pause sub-state. + * @details \b Inputs: getTDUFRate + * @details \b Outputs: none + * @return isolated UF run sub-state when Quf > 0, pause otherwise. + *************************************************************************/ +static DD_GEND_ISO_UF_SUB_STATE_T getIsolatedUFSubStateForUFRate( void ) +{ + DD_GEND_ISO_UF_SUB_STATE_T subState = DD_GEND_ISO_UF_PAUSE_STATE; + + if ( getTDUFRate() > ZERO_DIAL_FLOW_RATE ) + { + subState = DD_GEND_ISO_UF_RUN_STATE; + } + + return subState; +} + +/*********************************************************************//** + * @brief * The handleGenDDialysateIsolatedUFState function performs the - * Isolated ultrafiltration operations. - * @details \b Inputs: none. + * isolated ultrafiltration operations. + * @details \b Inputs: none * @details \b Outputs: none * @return the current state of gen dialysate mode *************************************************************************/ -static DD_GEND_MODE_STATE_T handleGenDIsolatedUFState( void ) +static DD_GEND_MODE_STATE_T handleGenDDialysateIsolatedUFState( void ) { - DD_GEND_MODE_STATE_T state = DD_GEND_ISOLATED_UF_STATE; + DD_GEND_MODE_STATE_T state = DD_GEND_ISOLATED_UF_STATE; + BOOL balancingChambFillInProgress = getBalancingChamberFillinProgressStatus(); - //TODO: define isoalted ultrafiltration. + if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_ENABLE_SPENT_CHAMBER_H_FILL ) ) + { + if ( ( TRUE == pendingSpentChamberFill ) && ( FALSE == balancingChambFillInProgress ) ) + { + setModeGenDStateTransition( DD_GEND_SPENT_CHAMBER_FILL_STATE ); + pendingSpentChamberFill = FALSE; + isDialDeliveryInProgress.data = FALSE; + state = DD_GEND_SPENT_CHAMBER_FILL_STATE; + } + } +#ifdef __BICARB_CHAMBER_FILL__ + if ( ( TRUE == pendingBicarbChamberFill ) && ( FALSE == balancingChambFillInProgress ) ) + { + setModeGenDStateTransition( DD_GEND_BICARB_CHAMBER_FILL_STATE ); + pendingBicarbChamberFill = FALSE; + isDialDeliveryInProgress.data = FALSE; + state = DD_GEND_BICARB_CHAMBER_FILL_STATE; + } +#endif + // If TD requests bypass, delivery, or another allowed sub-state, transition out of iso UF + state = applyTDRequestedGenDialysateState( state ); + + if ( DD_GEND_ISOLATED_UF_STATE == state ) + { + DD_GEND_ISO_UF_SUB_STATE_T desiredSubState = getIsolatedUFSubStateForUFRate(); + + if ( desiredSubState != isolatedUFSubState ) + { + isolatedUFSubState = desiredSubState; + } + + execUFControl(); + } + return state; } @@ -780,12 +936,7 @@ #endif //if the produced dialysate is good and TD asks for dialysate delivery //move to next state - if ( ( TRUE == getDialGoodToDeliverStatus() ) && ( FALSE == getTDDialyzerBypass() ) ) - { - setModeGenDStateTransition( DD_GEND_DIALYSATE_DELIVERY_STATE ); - isDialDeliveryInProgress.data = TRUE; - state = DD_GEND_DIALYSATE_DELIVERY_STATE; - } + state = applyTDRequestedGenDialysateState( state ); return state; } @@ -805,14 +956,18 @@ LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); BOOL balancingChambFillInProgress = getBalancingChamberFillinProgressStatus(); - // if TD asks for bypass or dialysate is not good to deliver - //transition to bypass dialystate state - if ( ( FALSE == getDialGoodToDeliverStatus() ) || ( TRUE == getTDDialyzerBypass() ) ) + // if TD asks for a different sub-state or dialysate is not good to deliver, + // transition out of delivery + if ( FALSE == getDialGoodToDeliverStatus() ) { setModeGenDStateTransition( DD_GEND_DIALYSATE_BYPASS_STATE ); isDialDeliveryInProgress.data = FALSE; state = DD_GEND_DIALYSATE_BYPASS_STATE; } + else if ( DD_GEND_DIALYSATE_DELIVERY_STATE != getTDRequestedGenDState() ) + { + state = applyTDRequestedGenDialysateState( state ); + } else if ( getTestConfigStatus( TEST_CONFIG_DD_ENABLE_SPENT_CHAMBER_H_FILL ) == TRUE ) { if ( ( TRUE == pendingSpentChamberFill ) && ( FALSE == balancingChambFillInProgress ) ) @@ -975,6 +1130,19 @@ /*********************************************************************//** * @brief + * The getCurrentIsolatedUFSubState function returns the current isolated UF + * run/pause sub-state. + * @details \b Inputs: isolatedUFSubState + * @details \b Outputs: none + * @return current isolated UF sub-state. + *************************************************************************/ +DD_GEND_ISO_UF_SUB_STATE_T getCurrentIsolatedUFSubState( void ) +{ + return isolatedUFSubState; +} + +/*********************************************************************//** + * @brief * The setTreatmentParamUpdate function sets the flag to indicate one or more * treatement parameters updated. * gen dialysate mode. @@ -1036,6 +1204,18 @@ setD48PumpSpeedForBCFill( initialPumpSpeed ); setDialysatePumpTargetRPM( D48_PUMP, (U32)initialPumpSpeed, TRUE ); + if ( DD_GEND_ISOLATED_UF_STATE == genDialysateState ) + { + if ( getTDDialysateFlowrate() > ZERO_DIAL_FLOW_RATE ) + { + setDialysatePumpTargetRPM( D48_PUMP, d48PumpSpeed, TRUE ); + } + else + { + signalDialysatePumpHardStop( D48_PUMP ); + } + } + //reset the flag isTreatmentParamUpdated = FALSE; } @@ -1345,11 +1525,10 @@ case DD_GEND_STATE_START: case DD_GEND_DIALYSATE_BYPASS_STATE: case DD_GEND_DIALYSATE_DELIVERY_STATE: + case DD_GEND_ISOLATED_UF_STATE: case DD_GEND_SPENT_CHAMBER_FILL_STATE: result = TRUE; break; - - case DD_GEND_ISOLATED_UF_STATE: case DD_GEND_BICARB_CHAMBER_FILL_STATE: case DD_GEND_DIALYSATE_DELIVERY_PAUSE: default: @@ -1388,13 +1567,16 @@ isDialDeliveryInProgress.data = TRUE; break; + case DD_GEND_ISOLATED_UF_STATE: + isDialDeliveryInProgress.data = FALSE; + break; + case DD_GEND_SPENT_CHAMBER_FILL_STATE: pendingSpentChamberFill = FALSE; isDialDeliveryInProgress.data = FALSE; break; case DD_GEND_STATE_START: - case DD_GEND_ISOLATED_UF_STATE: case DD_GEND_BICARB_CHAMBER_FILL_STATE: case DD_GEND_DIALYSATE_DELIVERY_PAUSE: default: