Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r58e7f4184d79fe6dbef4db3d256ad2b56ba7a0aa -rc137d3c7cb17b0364d745e10ff6dbd1901eb1baa --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 58e7f4184d79fe6dbef4db3d256ad2b56ba7a0aa) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision c137d3c7cb17b0364d745e10ff6dbd1901eb1baa) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * -* @file ModeTreatment.c +* @file ModeTreatment.c * -* @author (last) Sean Nash -* @date (last) 12-Oct-2020 +* @author (last) Quang Nguyen +* @date (last) 27-Aug-2021 * -* @author (original) Dara Navaei -* @date (original) 05-Nov-2019 +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 * ***************************************************************************/ @@ -80,9 +80,7 @@ static BOOL rinsebackDone; ///< Flag indicates whether a rinseback has been completed. Set FALSE at start of blood prime. Set TRUE at init and end of rinseback. static BOOL treatmentCompleted; ///< Flag indicates whether the treatment has completed. -static U32 presTreatmentTimeSecs; ///< Prescribed treatment time (in minutes). -static U32 presBloodFlowRate; ///< Prescribed blood flow rate (in mL/min). -static U32 presDialysateFlowRate; ///< Prescribed dialysate flow rate (in mL/min). +static U32 presTreatmentTimeSecs; ///< Prescribed treatment time (in seconds). static F32 presMaxUFVolumeML; ///< Prescribed ultrafiltration volume (in mL). static F32 presUFRate; ///< Prescribed ultrafiltration rate (in mL/min). @@ -166,8 +164,6 @@ treatmentParamsRangesBroadcastTimerCtr = TREATMENT_SETTINGS_RANGES_PUB_INTERVAL; // So we send ranges immediately when we begin treatment mode presTreatmentTimeSecs = 0; - presBloodFlowRate = 0; - presDialysateFlowRate = 0; presMaxUFVolumeML = 0.0; presUFRate = 0.0; @@ -232,9 +228,9 @@ * The transitionToTreatmentMode function prepares for transition to treatment mode. * @details Inputs: none * @details Outputs: - * @return none + * @return initial state *************************************************************************/ -void transitionToTreatmentMode( void ) +U32 transitionToTreatmentMode( void ) { // Initialize treatment mode each time we transition to it initTreatmentMode(); @@ -246,6 +242,8 @@ initRinseback(); initTreatmentRecirc(); initTreatmentEnd(); + + return currentTreatmentState; } /*********************************************************************//** @@ -610,6 +608,11 @@ activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); } + if ( currentTreatmentState != TREATMENT_END_STATE ) + { + checkDialysateTemperature(); + } + // Treatment mode state machine switch ( currentTreatmentState ) { @@ -680,8 +683,6 @@ lastTreatmentTimeStamp = getMSTimerCount(); presTreatmentTimeSecs = SEC_PER_MIN * getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); - presBloodFlowRate = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); - presDialysateFlowRate = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); presMaxUFVolumeML = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ) * (F32)ML_PER_LITER; presUFRate = presMaxUFVolumeML / (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); @@ -719,7 +720,8 @@ { lastTreatmentTimeStamp = getMSTimerCount(); // Kick dialysis sub-mode off - setDialysisParams( presBloodFlowRate, presDialysateFlowRate, presMaxUFVolumeML, presUFRate ); + setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + presMaxUFVolumeML, presUFRate ); transitionToDialysis(); result = TREATMENT_DIALYSIS_STATE; } @@ -841,10 +843,10 @@ { TREATMENT_STATE_T result = TREATMENT_RINSEBACK_STATE; - // Execute treatment re-circ sub-mode + // Execute treatment rinseback sub-mode execRinseback(); - // Handle signals from treatment end sub-mode + // Handle signals from rinseback sub-mode if ( TRUE == rinsebackToRecircRequest ) { transitionToTreatmentRecirc(); @@ -878,7 +880,7 @@ // Execute treatment re-circ sub-mode execTreatmentRecirc(); - // Handle signals from treatment end sub-mode + // Handle signals from treatment re-circ sub-mode if ( TRUE == rinsebackToStoppedRequest ) { transitionToTreatmentStop(); @@ -914,6 +916,11 @@ { signalTreatmentEndAlarmEndTxUserAction(); } + // Handle alarm response from user to resume slow blood flow while waiting for rinseback request + else if ( TRUE == resumeTreatmentAlarmResponseRequest ) + { + signalTreatmentEndAlarmResumeUserAction(); + } // Execute treatment end sub-mode execTreatmentEnd(); @@ -953,7 +960,7 @@ ( CALC_ELAPSED_TREAT_TIME_IN_MIN() < treatmentTime ) && ( treatmentTime >= MIN_TREATMENT_TIME_MINUTES ) ) { F32 uFVolume; - U32 dialVolume = presDialysateFlowRate * treatmentTime; // In mL + U32 dialVolume = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) * treatmentTime; // In mL // Always adjust UF volume to accommodate treatment time change (not UF rate) uFVolume = ( (F32)( treatmentTime - CALC_ELAPSED_TREAT_TIME_IN_MIN() ) * presUFRate ) + getUltrafiltrationReferenceVolume(); @@ -965,7 +972,7 @@ sendTreatmentLogEventData( TREATMENT_DURATION_CHANGE_EVENT, ( presTreatmentTimeSecs / SEC_PER_MIN ), treatmentTime ); presMaxUFVolumeML = uFVolume; presTreatmentTimeSecs = treatmentTime * SEC_PER_MIN; - setDialysisParams( presBloodFlowRate, presDialysateFlowRate, presMaxUFVolumeML, presUFRate ); + setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); } else { @@ -1043,9 +1050,9 @@ { DIALYSIS_STATE_T currDialysisState = getDialysisState(); UF_STATE_T currUFState = getUltrafiltrationState(); - F32 uFRate = uFVolume / ((F32)presTreatmentTimeSecs / (F32)SEC_PER_MIN); // What UF rate would be if user selected to adjust it - U32 trtTime = (S32)( uFVolume / presUFRate ) + 1; // What the treatment duration would be if user selected to adjust it - U32 dialVolume = presDialysateFlowRate * trtTime; // What dialysate volume would be if user selected to adjust time + F32 uFRate = uFVolume / ((F32)presTreatmentTimeSecs / (F32)SEC_PER_MIN); // What UF rate would be if user selected to adjust it + U32 trtTime = (S32)( uFVolume / presUFRate ) + 1; // What the treatment duration would be if user selected to adjust it + U32 dialVolume = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) * trtTime; // What dialysate volume would be if user selected to adjust time // UF should already be paused but let's make sure. if ( ( TREATMENT_DIALYSIS_STATE == currentTreatmentState ) && @@ -1093,7 +1100,7 @@ { if ( MODE_TREA != currMode ) { - rejectReason = REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE; + rejectReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; } else if ( ( currentTreatmentState <= TREATMENT_START_STATE ) || ( currentTreatmentState >= TREATMENT_END_STATE ) ) @@ -1150,7 +1157,8 @@ { presUFRate = pendingUFRateChange; } - setDialysisParams( presBloodFlowRate, presDialysateFlowRate, presMaxUFVolumeML, presUFRate ); + setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + presMaxUFVolumeML, presUFRate ); // If UF paused, resume with new settings if ( ( TREATMENT_DIALYSIS_STATE == currentTreatmentState ) && @@ -1208,12 +1216,13 @@ ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) ) { result = TRUE; - sendTreatmentLogEventData( BLOOD_FLOW_RATE_CHANGE_EVENT, presBloodFlowRate, bloodRate ); - sendTreatmentLogEventData( DIALYSATE_FLOW_RATE_CHANGE_EVENT, presDialysateFlowRate, dialRate ); + sendTreatmentLogEventData( BLOOD_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), bloodRate ); + sendTreatmentLogEventData( DIALYSATE_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), dialRate ); // Set to new rates - presBloodFlowRate = bloodRate; - presDialysateFlowRate = dialRate; - setDialysisParams( presBloodFlowRate, presDialysateFlowRate, presMaxUFVolumeML, presUFRate ); + setTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW, bloodRate ); + setTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW, dialRate ); + setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + presMaxUFVolumeML, presUFRate ); } else { @@ -1235,7 +1244,8 @@ { rejectReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; } - sendChangeBloodDialysateRateChangeResponse( result, (U32)rejectReason, presBloodFlowRate, presDialysateFlowRate ); + sendChangeBloodDialysateRateChangeResponse( result, (U32)rejectReason, getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), + getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) ); // Send new ranges for settings broadcastTreatmentSettingsRanges(); @@ -1369,16 +1379,15 @@ // Broadcast treatment time data at interval if ( ++treatmentTimeBroadcastTimerCtr >= getU32OverrideValue( &treatmentTimePublishInterval ) ) { + TREATMENT_TIME_DATA_T data = { 0, 0, 0 }; + if ( isTreatmentCompleted() != TRUE ) { - U32 timeRemaining = presTreatmentTimeSecs - elapsedTreatmentTimeInSecs; - - broadcastTreatmentTime( presTreatmentTimeSecs, elapsedTreatmentTimeInSecs, timeRemaining ); + data.treatmentTimePrescribedinSec = presTreatmentTimeSecs; + data.treatmentTimeElapsedinSec = elapsedTreatmentTimeInSecs; + data.treatmentTimeRemaininginSec = presTreatmentTimeSecs - elapsedTreatmentTimeInSecs; } - else // If treatment is completed, send zeroes to UI - { - broadcastTreatmentTime( 0, 0, 0 ); - } + broadcastData( MSG_ID_TREATMENT_TIME, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( TREATMENT_TIME_DATA_T ) ); treatmentTimeBroadcastTimerCtr = 0; } // Broadcast treatment state data at interval @@ -1397,7 +1406,7 @@ payload.heparinState = getHeparinState(); payload.dialysisState = getDialysisState(); - broadcastTreatmentState( payload ); + broadcastData( MSG_ID_TREATMENT_STATE, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( TREATMENT_STATE_DATA_T ) ); treatmentStateBroadcastTimerCtr = 0; } } @@ -1423,7 +1432,7 @@ // Compute maximum treatment duration (from both UF and dialysate volume perspectives) U32 maxTimeRem = ( MAX_UF_VOLUME_ML - (U32)getUltrafiltrationReferenceVolume() ) / ( presUFRate > 0.0 ? (U32)presUFRate : 1 ); U32 maxTime1 = minTime + maxTimeRem; - U32 maxTime2 = MAX_DIALYSATE_VOLUME_ML / presDialysateFlowRate; + U32 maxTime2 = MAX_DIALYSATE_VOLUME_ML / getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); U32 maxTime = MAX( maxTime1, maxTime2 ); // Compute minimum UF volume F32 minUFVol = getUltrafiltrationReferenceVolume() + presUFRate; @@ -1461,8 +1470,8 @@ if ( timeElapsedSinceLastCollect_ms >= TREATMENT_PERIODIC_DATA_LOG_INTERVAL ) { - F32 const arterialPres = getMeasuredArterialPressure(); - F32 const venousPres = getMeasuredArterialPressure(); + F32 const arterialPres = getFilteredArterialPressure(); + F32 const venousPres = getFilteredVenousPressure(); lastTreatmentPeriodicDataCollectTimeStamp = treatmentTimeMS; bloodFlowRateSum_mL_min += getMeasuredBloodFlowRate();