Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r51147222d369a3023a11b2ee675178d058ffaf46 -r8a18b5d1fb4598c6b7facb3e7e233252941eaded --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 51147222d369a3023a11b2ee675178d058ffaf46) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 8a18b5d1fb4598c6b7facb3e7e233252941eaded) @@ -17,10 +17,10 @@ #include "AlarmLamp.h" #include "BloodFlow.h" #include "Buttons.h" +#include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" #include "Dialysis.h" -#include "Buttons.h" #include "TaskGeneral.h" #include "OperationModes.h" #include "SystemCommMessages.h" @@ -33,16 +33,17 @@ #endif /** - * @addtogroup TreatmentMode + * @addtogroup HDTreatmentMode * @{ */ // ********** private definitions ********** #define MAX_TREATMENT_TIME_MINUTES ( 8 * MIN_PER_HOUR ) ///< Maximum treatment time (in minutes). +#define MIN_TREATMENT_TIME_MINUTES ( 1 * MIN_PER_HOUR ) ///< Minimum treatment time (in minutes). #define MAX_UF_RATE_ML_MIN ( (F32)2500 / (F32)MIN_PER_HOUR ) ///< Maximum ultrafiltration rate (in mL/min). #define MAX_UF_VOLUME_ML ( 8 * ML_PER_LITER ) ///< Maximum ultrafiltration volume (in mL). -#define MAX_DIALYSATE_VOLUME_ML ( 180 * ML_PER_LITER ) ///< Maximum dialysate volume (in mL). +#define MAX_DIALYSATE_VOLUME_ML ( 150 * ML_PER_LITER ) ///< Maximum dialysate volume (in mL). #define USER_CONFIRM_CHANGE_TIMEOUT_MS ( 60 * MS_PER_SECOND ) ///< Require user to confirm UF volume change within this time. #define PREVENT_UF_VOL_CHANGE_IF_NEARLY_DONE_SEC ( 10 * SEC_PER_MIN ) ///< Prevent UF volume change if treatment within this much time from end of treatment (in seconds). @@ -127,6 +128,7 @@ { // initialize treatment mode each time we transition to it initTreatmentMode(); + initTreatmentReservoirMgmt(); // initialize treatment sub-modes each time we transition to treatment mode initDialysis(); initTreatmentStop(); @@ -162,9 +164,9 @@ * Inputs : none * Outputs : * @param none - * @return none + * @return current state (sub-mode) *************************************************************************/ -void execTreatmentMode( void ) +U32 execTreatmentMode( void ) { #ifndef UF_TEST_ENABLED BOOL stop = isStopButtonPressed(); @@ -230,6 +232,8 @@ broadcastTreatmentTimeAndState(); broadcastTreatmentSettingsRanges(); + + execTreatmentReservoirMgmt(); #endif #ifdef RM46_EVAL_BOARD_TARGET // TODO - temporary test code for eval board - move to next mode after 5 min @@ -238,6 +242,8 @@ requestNewOperationMode( MODE_POST ); } #endif + + return currentTreatmentState; } /*********************************************************************//** @@ -262,7 +268,7 @@ presTreatmentTimeSecs = 3600; presBloodFlowRate = 300; presDialysateFlowRate = 300; - presMaxUFVolumeML = 300.0; + presMaxUFVolumeML = 600.0; presUFRate = 10.0; // kick dialysis sub-mode off @@ -365,12 +371,12 @@ { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejectReason = REQUEST_REJECT_REASON_NONE; - OP_MODE currMode = getCurrentOperationMode(); + HD_OP_MODE_T currMode = getCurrentOperationMode(); // check if we are in an appropriate treatment state for settings adjustment if ( ( MODE_TREA == currMode ) && ( currentTreatmentState > TREATMENT_START_STATE ) && ( currentTreatmentState < TREATMENT_DIALYSIS_END_STATE ) && - ( CALC_ELAPSED_TREAT_TIME_IN_MIN() < treatmentTime ) ) + ( CALC_ELAPSED_TREAT_TIME_IN_MIN() < treatmentTime ) && ( treatmentTime >= MIN_TREATMENT_TIME_MINUTES ) ) { F32 uFVolume; U32 dialVolume = presDialysateFlowRate * treatmentTime; // in mL @@ -413,13 +419,19 @@ { rejectReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; } + else if ( treatmentTime < MIN_TREATMENT_TIME_MINUTES ) + { + rejectReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_MINIMUM; + } else { rejectReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; } } // send response to request sendChangeTreatmentDurationResponse( result, rejectReason, presTreatmentTimeSecs / SEC_PER_MIN, presMaxUFVolumeML ); + // send new ranges for settings + broadcastTreatmentSettingsRanges(); return result; } @@ -440,7 +452,7 @@ REQUEST_REJECT_REASON_CODE_T rejectReason = REQUEST_REJECT_REASON_NONE; S32 timeDiff = 0; F32 rateDiff = 0.0; - OP_MODE currMode = getCurrentOperationMode(); + HD_OP_MODE_T currMode = getCurrentOperationMode(); // reset pending UF/time settings changes to current values in case request is rejected pendingUFVolumeChange = presMaxUFVolumeML; @@ -470,23 +482,34 @@ // start t/o timer - user must confirm UF changes within 1 minute from now pendingParamChangesTimer = getMSTimerCount(); - // verify UF rate change would be valid (this should be as UI is getting regular UF volume range updates) + // verify UF rate change would be valid (leave zero if not valid - UI will disable option) if ( uFRate <= (F32)MAX_UF_RATE_ML_MIN ) { result = TRUE; pendingUFVolumeChange = uFVolume; pendingUFRateChange = uFRate; rateDiff = ( uFRate - presUFRate ); - - // verify treatment duration change would be valid - if ( ( trtTime <= MAX_TREATMENT_TIME_MINUTES ) && ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) ) - { - pendingTreatmentTimeChange = trtTime; - timeDiff = trtTime - ( (U32)( (F32)presTreatmentTimeSecs / (F32)SEC_PER_MIN ) + 1 ); - } } else { + pendingUFRateChange = 0.0; + } + // verify treatment duration change would be valid (leave zero if not valid - UI will disable option) + if ( ( trtTime <= MAX_TREATMENT_TIME_MINUTES ) && ( trtTime >= MIN_TREATMENT_TIME_MINUTES ) && + ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) ) + { + result = TRUE; + pendingUFVolumeChange = uFVolume; + pendingTreatmentTimeChange = trtTime; + timeDiff = trtTime - ( (U32)( (F32)presTreatmentTimeSecs / (F32)SEC_PER_MIN ) + 1 ); + } + else + { + pendingTreatmentTimeChange = 0; + } + // if neither option works, reject for UF rate + if ( FALSE == result ) + { rejectReason = REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE; } } @@ -511,7 +534,7 @@ } } // respond to UF settings change request - sendChangeUFSettingsResponse( result, rejectReason, pendingUFVolumeChange, pendingTreatmentTimeChange, pendingUFRateChange, timeDiff, rateDiff ); + sendChangeUFSettingsResponse( result, rejectReason, pendingUFVolumeChange, pendingTreatmentTimeChange, pendingUFRateChange, timeDiff, rateDiff, presUFRate ); return result; } @@ -527,11 +550,12 @@ * @param adjustment : The adjustment selected by the user. * @return TRUE if new UF settings accepted, FALSE if not. *************************************************************************/ -BOOL verifyUFSettingsConfirmation( F32 uFVolume, UF_ADJ_T adjustment ) +BOOL verifyUFSettingsConfirmation( F32 uFVolume, U32 adjustment ) { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejectReason = REQUEST_REJECT_REASON_NONE; - OP_MODE currMode = getCurrentOperationMode(); + HD_OP_MODE_T currMode = getCurrentOperationMode(); + F32 oldUFRate = presUFRate; // user confirmed UF settings change(s)? if ( ( MODE_TREA == currMode ) && ( FALSE == didTimeout( pendingParamChangesTimer, USER_CONFIRM_CHANGE_TIMEOUT_MS ) ) ) @@ -573,7 +597,9 @@ } } // respond to UF settings change confirmation - sendChangeUFSettingsResponse( result, rejectReason, presMaxUFVolumeML, presTreatmentTimeSecs / SEC_PER_MIN, presUFRate, 0, 0 ); + sendChangeUFSettingsOptionResponse( result, rejectReason, presMaxUFVolumeML, presTreatmentTimeSecs / SEC_PER_MIN, presUFRate ); + // send new ranges for settings + broadcastTreatmentSettingsRanges(); return result; } @@ -593,7 +619,7 @@ { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejectReason = REQUEST_REJECT_REASON_NONE; - OP_MODE currMode = getCurrentOperationMode(); + HD_OP_MODE_T currMode = getCurrentOperationMode(); // check if we are in treatment mode for settings change if ( MODE_TREA == currMode ) @@ -632,6 +658,8 @@ rejectReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; } sendChangeBloodDialysateRateChangeResponse( result, (U32)rejectReason, presBloodFlowRate, presDialysateFlowRate ); + // send new ranges for settings + broadcastTreatmentSettingsRanges(); return result; } @@ -674,7 +702,9 @@ /*********************************************************************//** * @brief * The broadcastTreatmentSettingsRanges function computes and broadcasts \n - * updated treatment parameter ranges that the user may change during treatment. + * updated treatment parameter ranges that the user may change during treatment. \n + * It is assumed that prescription settings have already been set prior to calling \n + * this function. * @details * Inputs : current operating mode, treatment states and parameters * Outputs : valid ranges message sent on interval @@ -685,26 +715,28 @@ if ( ++treatmentParamsRangesBroadcastTimerCtr >= TREATMENT_SETTINGS_RANGES_PUB_INTERVAL ) { // compute minimum treatment duration - U32 minTime = CALC_ELAPSED_TREAT_TIME_IN_MIN() + 2; // add two minutes to cover rounding and ensure it's valid for next minute + U32 presTime = ( presTreatmentTimeSecs / SEC_PER_MIN ); + U32 elapseTime = CALC_ELAPSED_TREAT_TIME_IN_MIN(); + U32 minTime = MAX( (elapseTime + 2), MIN_TREATMENT_TIME_MINUTES ); // treatment duration cannot be < 1 hour. add two minutes to cover rounding and ensure it's valid for next minute // compute maximum treatment duration (from both UF and dialysate volume perspectives) U32 maxTimeRem = ( MAX_UF_VOLUME_ML - (U32)getUltrafiltrationVolumeCollected() ) / ( presUFRate > 0.0 ? (U32)presUFRate : 1 ); U32 maxTime1 = minTime + maxTimeRem; U32 maxTime2 = MAX_DIALYSATE_VOLUME_ML / presDialysateFlowRate; - U32 maxTime = MIN( maxTime1, maxTime2 ); + U32 maxTime = MAX( maxTime1, maxTime2 ); // compute minimum UF volume - U32 minUFVol = (U32)(getUltrafiltrationVolumeCollected()); - // compute maximum UF volume (considering from adjustment of treatment duration or UF rate perspectives) - U32 maxUFVol1 = minUFVol + ( ( CALC_TREAT_TIME_REMAINING_IN_SECS() / SEC_PER_MIN ) * MAX_UF_RATE_ML_MIN ); - U32 maxUFVol2 = ( presUFRate > 0 ? minUFVol + (U32)( ( MAX_TREATMENT_TIME_MINUTES - CALC_ELAPSED_TREAT_TIME_IN_MIN() - 1 ) * presUFRate ) : MAX_UF_VOLUME_ML ); - U32 maxUFVol = MIN( maxUFVol1, maxUFVol2 ); + F32 minUFVol = getUltrafiltrationVolumeCollected() + presUFRate; + // compute maximum UF volume (considering from adjustment of UF rate and time perspectives) + F32 maxUFVol1 = minUFVol + ( (F32)( presTime - elapseTime ) * MAX_UF_RATE_ML_MIN ); + F32 maxUFVol2 = ( presUFRate > 0.0 ? minUFVol + ( (F32)( MAX_TREATMENT_TIME_MINUTES - elapseTime - 1 ) * presUFRate ) : minUFVol ); + F32 maxUFVol = MAX( maxUFVol1, maxUFVol2 ); // compute minimum dialysate flow rate U32 minDialRate = MIN_DIAL_IN_FLOW_RATE; // compute maximum dialysate flow rate from max dialysate volume perspective - U32 maxDialRate = MAX_DIALYSATE_VOLUME_ML / ( presTreatmentTimeSecs / SEC_PER_MIN ); + U32 maxDialRate = MAX_DIALYSATE_VOLUME_ML / presTime; // now ensure maximums do not exceed the literal maximums maxTime = MIN( maxTime, MAX_TREATMENT_TIME_MINUTES ); - maxUFVol = MIN( maxUFVol, MAX_UF_VOLUME_ML ); + maxUFVol = MIN( maxUFVol, (F32)MAX_UF_VOLUME_ML ); maxDialRate = MIN( maxDialRate, MAX_DIAL_IN_FLOW_RATE ); // send updated treatment parameter ranges to UI sendTreatmentParamsRangesToUI( minTime, maxTime, minUFVol, maxUFVol, minDialRate, maxDialRate );