Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -ra74a984a7059f75d86ad87d6d9499bd8f94cc976 -r57ee0134869672b53ab5b7146b8988ede8f828d6 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision a74a984a7059f75d86ad87d6d9499bd8f94cc976) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 57ee0134869672b53ab5b7146b8988ede8f828d6) @@ -14,24 +14,66 @@ * **************************************************************************/ +#include "BloodFlow.h" +#include "Buttons.h" #include "Dialysis.h" +#include "DialInFlow.h" +#include "DialOutFlow.h" #include "OperationModes.h" +#include "Timers.h" #include "ModeTreatment.h" -// ********** private data ********** +// ********** private definitions ********** +typedef enum Dialysis_States +{ + DIALYSIS_START_STATE = 0, + DIALYSIS_UF_STATE, + DIALYSIS_SOLUTION_INFUSION_STATE, + NUM_OF_DIALYSIS_STATES +} DIALYSIS_STATE_T; + typedef enum UF_States { - UF_PAUSED_STATE = 0, + UF_START_STATE = 0, + UF_PAUSED_STATE, UF_RUNNING_STATE, UF_COMPLETED_OR_OFF_STATE, NUM_OF_UF_STATES } UF_STATE_T; +// ********** private data ********** + +static DIALYSIS_STATE_T currentDialysisState; +static UF_STATE_T currentUFState; + +static F32 refUFVolume; +static F32 measUFVolume; +static F32 resStartVolume; +static F32 measUFVolumeFromPriorReservoirs; + +static U32 uFTimeMS; +static U32 lastUFTimeStamp; + +static U32 setBloodFlowRate; +static U32 setDialysateFlowRate; +static F32 maxUFVolumeML; +static F32 setUFRate; + // ********** private function prototypes ********** +static DIALYSIS_STATE_T handleDialysisUltrafiltrationState( void ); +static DIALYSIS_STATE_T handleDialysisSolutionInfusionState( void ); + +static UF_STATE_T handleUFStartState( void ); +static UF_STATE_T handleUFPausedState( void ); +static UF_STATE_T handleUFRunningState( void ); +static UF_STATE_T handleUFCompletedOrOffState( void ); + +static void updateUFVolumes( void ); + /************************************************************************* - * @brief initDialysis + * @brief * The initDialysis function initializes the Dialysis module. * @details * Inputs : none @@ -41,10 +83,25 @@ *************************************************************************/ void initDialysis( void ) { + currentDialysisState = DIALYSIS_START_STATE; + currentUFState = UF_START_STATE; + + refUFVolume = 0.0; + measUFVolume = 0.0; + resStartVolume = 0.0; + measUFVolumeFromPriorReservoirs = 0.0; + + uFTimeMS = 0; + lastUFTimeStamp = 0; + + setBloodFlowRate = 0; + setDialysateFlowRate = 0; + maxUFVolumeML = 0.0; + setUFRate = 0.0; } /************************************************************************* - * @brief transitionToDialysis + * @brief * The transitionToDialysis function prepares for transition to dialysis sub-mode. * @details * Inputs : none @@ -54,18 +111,278 @@ *************************************************************************/ void transitionToDialysis( void ) { + // while in treatment mode, we may transition in and out of dialysis sub-mode. + // we'll want to retain our state to facilitate resumption of dialysis. } /************************************************************************* - * @brief execDialysis - * The execDialysis function executes the Dialysis sub-mode state machine. + * @brief + * The setDialysisParams function sets the dialysis treatment parameters. * @details * Inputs : none - * Outputs : + * Outputs : dialysis treatment parameters are set. + * @param bPFlow : target blood pump flow rate (in mL/min). + * @param dPFlow : target dialysate inlet pump flow rate (in mL/min). + * @param maxUFVol : maximum ultrafiltration volume (in mL). + * @param uFRate : target ultrafiltration rate (in mL/min). + * @return none + *************************************************************************/ +void setDialysisParams( U32 bPFlow, U32 dPFlow, F32 maxUFVol, F32 uFRate ) +{ + setBloodFlowRate = bPFlow; + setDialysateFlowRate = dPFlow; + maxUFVolumeML = maxUFVol; + setUFRate = uFRate; +} + +/************************************************************************* + * @brief + * The startDialysis function starts/resumes dialysis. + * @details + * Inputs : none + * Outputs : none + * @return none + *************************************************************************/ +void startDialysis( void ) +{ + lastUFTimeStamp = getMSTimerCount(); + setDialOutUFVolumes( refUFVolume, measUFVolume ); + setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); +} + +/************************************************************************* + * @brief + * The stopDialysis function stops dialysis. This may be due to an alarm \n + * or user pressed the stop button. Dialysis may be resumed later. + * @details + * Inputs : none + * Outputs : none + * @return none + *************************************************************************/ +void stopDialysis( void ) +{ + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); +} + +/************************************************************************* + * @brief + * The execDialysis function executes the Dialysis sub-mode state machine. + * @details + * Inputs : currentDialysisState + * Outputs : currentDialysisState * @param none * @return none *************************************************************************/ void execDialysis( void ) { + switch ( currentDialysisState ) + { + case DIALYSIS_START_STATE: + resStartVolume = getLoadCellWeightInGrams( LOAD_CELL_RESERVOIR_1_PRIMARY ); // always start dialysis w/ reservoir 1 + currentDialysisState = DIALYSIS_UF_STATE; + break; + + case DIALYSIS_UF_STATE: + currentDialysisState = handleDialysisUltrafiltrationState(); + break; + + case DIALYSIS_SOLUTION_INFUSION_STATE: + currentDialysisState = handleDialysisSolutionInfusionState(); + break; + + default: + // TODO - s/w fault + break; + } } +/************************************************************************* + * @brief + * The handleDialysisUltrafiltrationState function handles the ultrafiltration \n + * state of the Dialysis state machine. + * @details + * Inputs : none + * Outputs : none + * @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(); + break; + + case UF_PAUSED_STATE: + currentUFState = handleUFPausedState(); + break; + + case UF_RUNNING_STATE: + currentUFState = handleUFRunningState(); + break; + + case UF_COMPLETED_OR_OFF_STATE: + currentUFState = handleUFCompletedOrOffState(); + break; + + default: + // TODO - s/w fault + break; + } + + return result; +} + +/************************************************************************* + * @brief + * The handleDialysisSolutionInfusionState function handles the solution \n + * infustion state of the Dialysis state machine. + * @details + * Inputs : none + * Outputs : none + * @return next Dialysis state. + *************************************************************************/ +static DIALYSIS_STATE_T handleDialysisSolutionInfusionState( void ) +{ + DIALYSIS_STATE_T result = DIALYSIS_SOLUTION_INFUSION_STATE; + + return result; +} + +/************************************************************************* + * @brief + * The handleUFStartState function handles the Start state of the \n + * ultrafiltration state machine. + * @details + * Inputs : none + * Outputs : none + * @return next ultrafiltration state. + *************************************************************************/ +static UF_STATE_T handleUFStartState( void ) +{ + UF_STATE_T result; + + if ( maxUFVolumeML < NEARLY_ZERO ) + { + result = UF_COMPLETED_OR_OFF_STATE; + } + else + { + lastUFTimeStamp = getMSTimerCount(); + uFTimeMS = 0; + result = UF_RUNNING_STATE; + } + + return result; +} + +/************************************************************************* + * @brief + * The handleUFPausedState function handles the Paused state of the \n + * ultrafiltration state machine. + * @details + * Inputs : none + * Outputs : none + * @return next ultrafiltration state. + *************************************************************************/ +static UF_STATE_T handleUFPausedState( void ) +{ + UF_STATE_T result = UF_PAUSED_STATE; + + // calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // TODO - test code - remove later + if ( TRUE == isStopButtonPressed() ) + { + lastUFTimeStamp = getMSTimerCount(); // restart UF time accumulation + result = UF_RUNNING_STATE; + } + + return result; +} + +/************************************************************************* + * @brief + * The handleUFRunningState function handles the Running state of the \n + * ultrafiltration state machine. + * @details + * Inputs : none + * Outputs : none + * @return next ultrafiltration state. + *************************************************************************/ +static UF_STATE_T handleUFRunningState( void ) +{ + UF_STATE_T result = UF_RUNNING_STATE; + U32 newTime = getMSTimerCount(); + U32 msSinceLast = calcTimeBetween( lastUFTimeStamp, newTime ); + + // update UF time + uFTimeMS += msSinceLast; + lastUFTimeStamp = newTime; + + // calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // TODO - test code - remove later + if ( TRUE == isStopButtonPressed() ) + { + result = UF_PAUSED_STATE; + } + + return result; +} + +/************************************************************************* + * @brief + * The handleUFCompletedOrOffState function handles the UF Completed or Off \n + * state of the ultrafiltration state machine. + * @details + * Inputs : none + * Outputs : none + * @return next ultrafiltration state + *************************************************************************/ +static UF_STATE_T handleUFCompletedOrOffState( void ) +{ + UF_STATE_T result = UF_COMPLETED_OR_OFF_STATE; + + // calculate UF volumes and provide to dialysate outlet pump controller + updateUFVolumes(); + + // TODO - test code - remove later + if ( TRUE == isStopButtonPressed() ) + { + // do nothing + } + + return result; +} + +/************************************************************************* + * @brief + * The updateUFVolumes function updates the ultrafiltration volumes based on \n + * set UF rate, latest UF elapsed time, and the latest load cell weight for the \n + * currently used reservoir. Updated UF volumes are then sent to the dialysate \n + * outlet pump controller. + * @details + * Inputs : setUFRate, uFTimeMS, load cell weight + * Outputs : refUFVolume, measUFVolume + * @return none + *************************************************************************/ +static void updateUFVolumes( void ) +{ + F32 latestResVolume = getLoadCellWeightInGrams( LOAD_CELL_RESERVOIR_1_PRIMARY ); // TODO - just res 1 for now - add reservoir switching, mgmt later. + + // calculate UF volumes and provide to dialysate outlet pump controller + refUFVolume = ( ( (F32)uFTimeMS / MS_PER_SECOND ) / SEC_PER_MIN ) * setUFRate; + measUFVolume = measUFVolumeFromPriorReservoirs + ( latestResVolume - resStartVolume ); + setDialOutUFVolumes( refUFVolume, measUFVolume ); +} + +