Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r1017bbc5760a50e20357da1e4f705b3e6157375e -r2112e3143003eaf9584d4be068f7ca89b33c941a --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 1017bbc5760a50e20357da1e4f705b3e6157375e) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 2112e3143003eaf9584d4be068f7ca89b33c941a) @@ -14,7 +14,7 @@ * **************************************************************************/ -#include "AlarmMgmt.h" +#include "DialInFlow.h" #include "ModeTreatment.h" #include "OperationModes.h" #include "SystemCommMessages.h" @@ -27,55 +27,62 @@ // ********** private definitions ********** -#define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. -#define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. +#define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. +#define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. -#define DRAIN_RESERVOIR_TO_VOLUME_ML 100 ///< Drain reservoir to this volume (in mL) during treatment. -#define FILL_RESERVOIR_TO_VOLUME_ML 1500 ///< Fill reservoir to this volume (in mL) during treatment. +#define DRAIN_RESERVOIR_TO_VOLUME_ML 200 //100 ///< Drain reservoir to this volume (in mL) during treatment. +#define FILL_RESERVOIR_TO_VOLUME_ML 1500 ///< Fill reservoir to this volume (in mL) during treatment. +#define RESERVOIR_SETTLE_TIME_MS 3000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). + /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States { - TREATMENT_RESERVOIR_MGMT_START_STATE = 0, ///< If DG not already in re-circ mode, try to get it there. - TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE, ///< In DG re-circ, wait for lines to flush - then start draining inactive reservoir. - TREATMENT_RESERVOIR_MGMT_DRAIN_RESERVOIR_STATE, ///< Wait for drain to complete. - TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE, ///< Wait to fill inactive reservoir (if appropriate) - then start filling inactive reservoir. - TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE, ///< Wait for fill to complete. - TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE, ///< Wait for active reservoir to be consumed and switch cmd given - then back to flush DG lines state. - NUM_OF_TREATMENT_RESERVOIR_MGMT_STATES ///< Number of treatment reservoir mgmt. states. + TREATMENT_RESERVOIR_MGMT_START_STATE = 0, ///< If DG not already in re-circ mode, try to get it there. + TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE, ///< In DG re-circ, wait for lines to flush - then start draining inactive reservoir. + TREATMENT_RESERVOIR_MGMT_DRAIN_RESERVOIR_STATE, ///< Wait for drain to complete. + TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE, ///< Wait to fill inactive reservoir (if appropriate) - then start filling inactive reservoir. + TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE, ///< Wait for fill to complete. + TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE, ///< Wait a bit for filled reservoir to settle before getting baseline weight (volume). + TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE, ///< Wait for active reservoir to be consumed and switch cmd given - then back to flush DG lines state. + TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE, ///< Wait for inactive reservoir to settle before getting final weight (volume) before starting to drain. + NUM_OF_TREATMENT_RESERVOIR_MGMT_STATES ///< Number of treatment reservoir mgmt. states. } TREATMENT_RESERVOIR_MGMT_STATE_T; // ********** private data ********** // DG status -static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; ///< Current DG operation mode. -static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. -static BOOL dgStarted = FALSE; ///< Flag indicates whether we've commanded the DG to start or stop. -static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we've commanded the DG to start or stop the trimmer heater. -static BOOL dgWaterSampled = FALSE; ///< Flag indicates whether we've commanded the DG to sample water. +static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; ///< Current DG operation mode. +static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. +static BOOL dgStarted = FALSE; ///< Flag indicates whether we've commanded the DG to start or stop. +static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we've commanded the DG to start or stop the trimmer heater. +static BOOL dgWaterSampled = FALSE; ///< Flag indicates whether we've commanded the DG to sample water. // state machine states static TREATMENT_RESERVOIR_MGMT_STATE_T currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; ///< Current state of treatment mode reservoir management. +static U32 resMgmtTimer = 0; ///< used for keeping state time. // DG sensor data -static F32 dgPressures[ NUM_OF_DG_PRESSURE_SENSORS ]; ///< Latest pressures reported by the DG. -static F32 dgPrimaryTempSet = 0.0; ///< Primary heater target temperature commanded. -static F32 dgPrimaryTemp = 0.0; ///< Latest RO water temperature reported by the DG. -static F32 dgTrimmerTempSet = 0.0; ///< Trimmer heater target temperature commanded. -static F32 dgTrimmerTemp = 0.0; ///< Latest dialysate temperature reported by the DG. +static F32 dgPressures[ NUM_OF_DG_PRESSURE_SENSORS ]; ///< Latest pressures reported by the DG. +static F32 dgPrimaryTempSet = 0.0; ///< Primary heater target temperature commanded. +static F32 dgPrimaryTemp = 0.0; ///< Latest RO water temperature reported by the DG. +static F32 dgTrimmerTempSet = 0.0; ///< Trimmer heater target temperature commanded. +static F32 dgTrimmerTemp = 0.0; ///< Latest dialysate temperature reported by the DG. // DG pumps data -static F32 dgROPumpFlowRateMlMin = 0.0; ///< Latest RO water flow rate reported by the DG. -static U32 dgROPumpPressureSetPtPSI = 0; ///< Latest RO pump target pressure reported by the DG. -static U32 dgDrainPumpSpeedSetPtRPM = 0; ///< Latest Drain pump target speed reported by the DG. +static F32 dgROPumpFlowRateMlMin = 0.0; ///< Latest RO water flow rate reported by the DG. +static U32 dgROPumpPressureSetPtPSI = 0; ///< Latest RO pump target pressure reported by the DG. +static U32 dgDrainPumpSpeedSetPtRPM = 0; ///< Latest Drain pump target speed reported by the DG. // reservoir data static DG_RESERVOIR_ID_T dgActiveReservoir = DG_RESERVOIR_2; ///< Latest active reservoir reported by the DG. static DG_RESERVOIR_ID_T dgActiveReservoirSet = DG_RESERVOIR_2; ///< Active reservoir commanded. -static U32 dgReservoirFillVolumeTarget = 0; ///< Latest fill-to volume reported by the DG. -static U32 dgReservoirFillVolumeTargetSet = 0; ///< Fill-to volume commanded. -static U32 dgReservoirDrainVolumeTarget = 0; ///< Latest drain-to volume reported by the DG. -static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. +static U32 dgReservoirFillVolumeTarget = 0; ///< Latest fill-to volume reported by the DG. +static U32 dgReservoirFillVolumeTargetSet = 0; ///< Fill-to volume commanded. +static U32 dgReservoirDrainVolumeTarget = 0; ///< Latest drain-to volume reported by the DG. +static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. +static U32 resUseTimer = 0; ///< used to track time pumping from active reservoir (for volume used calculation). +static F32 resUseVolumeMl = 0.0; ///< Accumulated volume used from active reservoir. // ********** private function prototypes ********** @@ -104,13 +111,20 @@ *************************************************************************/ void execTreatmentReservoirMgmt( void ) { - DG_OP_MODE_T dgOpMode = getDGOpMode(); // TODO - the DG mode & sub-mode come as a pair at interval - they MUST be kept together. + DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); + U32 msSinceLastVolumeCalc = calcTimeSince( resUseTimer ); + F32 flowRateMlPerMs = getMeasuredDialInFlowRate() / (F32)( MS_PER_SECOND * SEC_PER_MIN ); + // calculate volume used from active reservoir + resUseVolumeMl += ( flowRateMlPerMs * msSinceLastVolumeCalc ); // TODO - should this calc be done and kept by Dialysis sub-mode? + // treatment reservoir mgmt. state machine switch ( currentTrtResMgmtState ) { case TREATMENT_RESERVOIR_MGMT_START_STATE: + resUseTimer = getMSTimerCount(); + resUseVolumeMl = 0.0; currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE; break; @@ -164,16 +178,49 @@ case TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE: if ( DG_MODE_CIRC == dgOpMode ) { + resMgmtTimer = getMSTimerCount(); + currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE; + } + break; + + case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_FILL_SETTLE_STATE: + if ( TRUE == didTimeout( resMgmtTimer, RESERVOIR_SETTLE_TIME_MS ) ) + { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE; } break; case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE: // reservoir switch during treatment should only occur in this state (i.e. when DG is ready). - // state will reset to start when next reservoir switch is commanded. - // TODO - should this state machine determine when to give reservoir switch command? Or leave to treatment mode? + // switch reservoirs when active reservoir is spent (i.e. we've pumped fill volume through dialyzer) and DG ready + if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) && + ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) ) + { + DG_RESERVOIR_ID_T activeRes = dgActiveReservoirSet; + DG_RESERVOIR_ID_T inactiveRes = ( activeRes == DG_RESERVOIR_1 ? DG_RESERVOIR_2 : DG_RESERVOIR_1 ); + + // signal dialysis sub-mode to capture baseline volume for next reservoir. + setStartReservoirVolume(); + // command DG to switch reservoirs + cmdSetDGActiveReservoir( inactiveRes ); + // signal dialysis sub-mode to switch reservoirs + signalReservoirsSwitched(); + // wait for used reservoir to settle + resMgmtTimer = getMSTimerCount(); + currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE; + } break; + case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_SWITCH_SETTLE_STATE: + if ( TRUE == didTimeout( resMgmtTimer, RESERVOIR_SETTLE_TIME_MS ) ) + { + // signal dialysis sub-mode to capture final volume of prior reservoir after settling. + setFinalReservoirVolume(); + // reset to start state to restart drain, fill, switch process. + currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; + } + break; + default: // TODO - s/w fault currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; @@ -451,12 +498,30 @@ sendDGStartStopCommand( STOP_DG_CMD ); } +/*********************************************************************//** + * @brief + * The cmdStartDGTrimmerHeater function sends a start trimmer heater command \n + * to the DG. + * @details + * Inputs : none + * Outputs : start DG trimmer heater command sent + * @return none + *************************************************************************/ void cmdStartDGTrimmerHeater( void ) { dgTrimmerHeaterOn = TRUE; sendDGStartStopTrimmerHeaterCommand( START_DG_CMD ); } +/*********************************************************************//** + * @brief + * The cmdStopDGTrimmerHeater function sends a stop trimmer heater command \n + * to the DG. + * @details + * Inputs : none + * Outputs : stop DG trimmer heater command sent + * @return none + *************************************************************************/ void cmdStopDGTrimmerHeater( void ) { dgTrimmerHeaterOn = FALSE;