Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -rbbd8081a9bd6fe63174f571bd60036145074e155 -r1a4fca64a161a9965f563f44f72e3251d1f7a929 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision bbd8081a9bd6fe63174f571bd60036145074e155) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 1a4fca64a161a9965f563f44f72e3251d1f7a929) @@ -88,8 +88,15 @@ // ********** private function prototypes ********** +static DIALYSIS_STATE_T handleDialysisUltrafiltrationState( void ); static DIALYSIS_STATE_T handleDialysisSalineBolusState( void ); +static UF_STATE_T handleUFStartState( DIALYSIS_STATE_T *dialysisState ); +static UF_STATE_T handleUFPausedState( DIALYSIS_STATE_T *dialysisState ); +static UF_STATE_T handleUFRunningState( DIALYSIS_STATE_T *dialysisState ); +static UF_STATE_T handleUFOffState( DIALYSIS_STATE_T *dialysisState ); +static UF_STATE_T handleUFCompletedState( DIALYSIS_STATE_T *dialysisState ); + static SALINE_BOLUS_STATE_T handleSalineBolusIdleState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusWait4Pumps2Stop( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusInProgressState( DIALYSIS_STATE_T *dialysisState ); @@ -517,6 +524,10 @@ currentDialysisState = DIALYSIS_UF_STATE; break; + case DIALYSIS_UF_STATE: + currentDialysisState = handleDialysisUltrafiltrationState(); + break; + case DIALYSIS_SALINE_BOLUS_STATE: currentDialysisState = handleDialysisSalineBolusState(); break; @@ -532,6 +543,49 @@ /*********************************************************************//** * @brief + * The handleDialysisUltrafiltrationState function handles the ultrafiltration + * state of the Dialysis state machine. + * @details Inputs: currentUFState + * @details Outputs: currentUFState + * @return next Dialysis state. + *************************************************************************/ +static DIALYSIS_STATE_T handleDialysisUltrafiltrationState( void ) +{ + DIALYSIS_STATE_T result = DIALYSIS_UF_STATE; + + switch ( currentUFState ) + { + case UF_START_STATE: + currentUFState = handleUFStartState( &result ); + break; + + case UF_PAUSED_STATE: + currentUFState = handleUFPausedState( &result ); + break; + + case UF_RUNNING_STATE: + currentUFState = handleUFRunningState( &result ); + break; + + case UF_OFF_STATE: + currentUFState = handleUFOffState( &result ); + break; + + case UF_COMPLETED_STATE: + currentUFState = handleUFCompletedState( &result ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSIS_INVALID_UF_STATE, currentUFState ) + currentUFState = UF_COMPLETED_STATE; + break; + } + + return result; +} + +/*********************************************************************//** + * @brief * The handleDialysisSolutionInfusionState function handles the solution * infustion state of the Dialysis state machine. * @details Inputs: currentSalineBolusState @@ -571,6 +625,199 @@ /*********************************************************************//** * @brief + * The handleUFStartState function handles the Start state of the + * ultrafiltration state machine. + * @details Inputs: maxUFVolumeML + * @details Outputs: if ultrafiltration prescribed, ultrafiltration time is + * initialized. + * @param dialysisState next dialysis state + * @return next ultrafiltration state. + *************************************************************************/ +static UF_STATE_T handleUFStartState( DIALYSIS_STATE_T *dialysisState ) +{ + UF_STATE_T result; + + if ( maxUFVolumeML < NEARLY_ZERO ) + { + result = UF_OFF_STATE; + } + else + { + lastUFTimeStamp = getMSTimerCount(); + uFTimeMS = 0; + result = UF_RUNNING_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleUFPausedState function handles the Paused state of the + * ultrafiltration state machine. + * @details Inputs: none + * @details Outputs: if ultrafiltration resumption requested, UF time is set to resume. + * @param dialysisState next dialysis state + * @return next ultrafiltration state. + *************************************************************************/ +static UF_STATE_T handleUFPausedState( DIALYSIS_STATE_T *dialysisState ) +{ + UF_STATE_T result = UF_PAUSED_STATE; + + // Calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // Handle saline bolus start request from user + if ( TRUE == salineBolusStartRequested ) + { + salineBolusAutoResumeUF = FALSE; + // Go to saline bolus state if we can + if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) + { + *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; + } + else + { + salineBolusStartRequested = FALSE; + } + } + // Handle auto-resume after saline bolus + else if ( TRUE == salineBolusAutoResumeUF ) + { + salineBolusAutoResumeUF = FALSE; + // Set outlet pump to dialysate rate + set UF rate + setDialOutPumpTargetRate( setDialysateFlowRate + FLOAT_TO_INT_WITH_ROUND( setUFRate ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + // Restart UF time accumulation for reference volume calculation + lastUFTimeStamp = getMSTimerCount(); + // Resume UF + result = UF_RUNNING_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleUFRunningState function handles the Running state of the + * ultrafiltration state machine. + * @details Inputs: ms timer, lastUFTimeStamp + * @details Outputs: UF timer incremented, UF volumes updated and provided to DPo + * pump controller. + * @param dialysisState next dialysis state + * @return next ultrafiltration state. + *************************************************************************/ +static UF_STATE_T handleUFRunningState( DIALYSIS_STATE_T *dialysisState ) +{ + UF_STATE_T result = UF_RUNNING_STATE; + U32 newTime = getMSTimerCount(); + U32 msSinceLast = calcTimeBetween( lastUFTimeStamp, newTime ); + + // Update UF time + uFTimeMS += msSinceLast; + lastUFTimeStamp = newTime; + + // Update UF ref volume in UF running state only + refUFVolume += ( ( (F32)msSinceLast / MS_PER_SECOND ) / SEC_PER_MIN ) * setUFRate; + + // Calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // If we have reached target UF volume, UF is complete + if ( refUFVolume >= maxUFVolumeML ) + { + result = UF_COMPLETED_STATE; + } + // Handle saline bolus start request from user + else if ( TRUE == salineBolusStartRequested ) + { + if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) + { + // Since we were doing UF prior to saline bolus, we want to auto-resume when done + salineBolusAutoResumeUF = TRUE; + // Go to UF paused state + result = UF_PAUSED_STATE; + // Go to saline bolus state + *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; + } + else + { + salineBolusStartRequested = FALSE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleUFCompletedOrOffState function handles the UF Off state + * of the ultrafiltration state machine. + * @details Inputs: none + * @details Outputs: UF volumes updated and provided to DPo pump controller. + * @param dialysisState next dialysis state + * @return next ultrafiltration state + *************************************************************************/ +static UF_STATE_T handleUFOffState( DIALYSIS_STATE_T *dialysisState ) +{ + UF_STATE_T result = UF_OFF_STATE; + + // Calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // Handle saline bolus start request from user + if ( TRUE == salineBolusStartRequested ) + { + salineBolusAutoResumeUF = FALSE; + // Go to saline bolus state + if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) + { + *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; + } + else + { + salineBolusStartRequested = FALSE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleUFCompletedState function handles the UF Completed + * state of the ultrafiltration state machine. This is a terminal state. + * @details Inputs: none + * @details Outputs: UF volumes updated and provided to DPo pump controller. + * @param dialysisState next dialysis state + * @return next ultrafiltration state + *************************************************************************/ +static UF_STATE_T handleUFCompletedState( DIALYSIS_STATE_T *dialysisState ) +{ + UF_STATE_T result = UF_COMPLETED_STATE; + + // Calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // Handle saline bolus start request from user + if ( TRUE == salineBolusStartRequested ) + { + salineBolusAutoResumeUF = FALSE; + // Go to saline bolus state + if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) + { + *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; + } + else + { + salineBolusStartRequested = FALSE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief * The handleSalineBolusIdleState function handles the idle state of the * saline bolus state machine. * @details Inputs: none