Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -rb03a3ed91ebe15cfb419e34018f8fe600e744b4b -r7499a42cc0f906f9a4a947c82c5b4615217ce7e5 --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision b03a3ed91ebe15cfb419e34018f8fe600e744b4b) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 7499a42cc0f906f9a4a947c82c5b4615217ce7e5) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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 Rinseback.c * -* @author (last) Sean Nash -* @date (last) 12-Nov-2021 +* @author (last) Dara Navaei +* @date (last) 13-Jul-2022 * * @author (original) Sean Nash * @date (original) 20-Jan-2021 @@ -37,10 +37,11 @@ // ********** private definitions ********** -#define TUBING_RINSEBACK_VOLUME_ML 80.0 ///< Target rinseback volume to deliver back to the patient (in mL). -#define MAX_TOTAL_ADDITIONAL_RINSEBACK_VOLUME_ML 300.0 ///< Maximum total additional rinseback volume allowed : all additionals (in mL). -#define MAX_RINSEBACK_VOLUME_ERROR_ML 60.0 ///< Maximum error in total additional rinseback volume (20% of total). -#define TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML 10.0 ///< Target rinseback volume for an additional volume request (in mL). +#define TUBING_RINSEBACK_VOLUME_ML 80.0F ///< Target rinseback volume to deliver back to the patient (in mL). +#define DEFAULT_RINSEBACK_VOLUME_ML 300.0F ///< Default rinseback volume (in mL). +#define MAX_TOTAL_ADDITIONAL_RINSEBACK_VOLUME_ML 300.0F ///< Maximum total additional rinseback volume allowed : all additionals (in mL). +#define MAX_RINSEBACK_VOLUME_ERROR_ML 60.0F ///< Maximum error in total additional rinseback volume (20% of total). +#define TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML 10.0F ///< Target rinseback volume for an additional volume request (in mL). #define RINSEBACK_FLOW_RATE_ADJ_ML_MIN 25 ///< Adjustment amount (in mL/min) to apply when user requests increase/decrease in flow rate. #define MIN_RINSEBACK_FLOW_RATE_ML_MIN 50 ///< Minimum rinseback flow rate (in mL/min). #define MAX_RINSEBACK_FLOW_RATE_ML_MIN 150 ///< Maximum rinseback flow rate (in mL/min). @@ -56,15 +57,15 @@ /// Maximum time allowed for each additional rinseback volume delivery. static const U32 MAX_RINSEBACK_ADDITIONAL_TIME = ( 20 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ); /// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. -static const F32 RINSEBACK_FLOW_INTEGRATOR = 1.0 / (F32)( SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); +static const F32 RINSEBACK_FLOW_INTEGRATOR = 1.0F / (F32)( SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); // ********** private data ********** static RINSEBACK_STATE_T rinsebackState; ///< Current state of the rinseback sub-mode. static U32 rinsebackRate_mL_min; ///< Rinseback rate to use/adjust for this current rinseback only. static U32 rinsebackTimerCtr; ///< Timer counter for time spent in rinseback sub-mode. -static F32 rinsebackTargetVolume_mL = 300.0; ///< Calculated target rinseback volume (based on selected dialyzer and fixed tubing volume). +static F32 rinsebackTargetVolume_mL; ///< Calculated target rinseback volume (based on selected dialyzer and fixed tubing volume). static OVERRIDE_F32_T cumulativeRinsebackVolume_mL = { 0.0, 0.0, 0.0, 0 }; ///< Total cumulative rinseback volume (in mL) from measured blood flow rate. static F32 expectedRinsebackVolume_mL = 0.0; ///< Total cumulative rinseback volume (in mL) expected based on target blood flow rate. static F32 targetRinsebackVolumePlusAdditional_mL; ///< Target rinseback volume w/ additional volume(s) added (in mL). @@ -135,6 +136,7 @@ totalAdditionalRinsebackVolume_mL = 0.0; rinsebackAdditionalTimerCtr = 0; rinsebackPublishTimerCtr = 0; + rinsebackTargetVolume_mL = DEFAULT_RINSEBACK_VOLUME_ML; resetRinsebackFlags(); } @@ -327,11 +329,14 @@ // Has user requested rinseback start? if ( TRUE == startRinsebackRequested ) { + if ( isTreatmentCompleted() != TRUE ) + { + sendTreatmentLogEventData( MID_TREATMENT_RINSE_BACK_EVENT, 0.0, rinsebackRate_mL_min ); + } setupForRinsebackDelivery( rinsebackRate_mL_min ); // From moment we start rinseback, we consider blood side of dialyzer no longer fully primed setBloodIsPrimed( FALSE ); result = RINSEBACK_RUN_STATE; - sendTreatmentLogEventData( MID_TREATMENT_RINSE_BACK_EVENT, 0.0, 0.0 ); } // Has user requested to return to treatment? else if ( TRUE == backToTreatmentRequested ) @@ -400,16 +405,19 @@ setupForRinsebackStopOrPause(); result = RINSEBACK_PAUSED_STATE; } -#ifndef DISABLE_PUMP_FLOW_CHECKS // Is rinseback taking too long? else if ( fabs( expectedRinsebackVolume_mL - getRinsebackVolume() ) > MAX_RINSEBACK_VOLUME_ERROR_ML ) { - setRinsebackIsCompleted( TRUE ); - setupForRinsebackStopOrPause(); - activateAlarmNoData( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE ); - result = RINSEBACK_STOP_STATE; - } +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_FLOW_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + setRinsebackIsCompleted( TRUE ); + setupForRinsebackStopOrPause(); + activateAlarmNoData( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE ); + result = RINSEBACK_STOP_STATE; + } + } // Otherwise, continue rinseback else { // Has user requested rate change? @@ -483,14 +491,8 @@ { RINSEBACK_STATE_T result = RINSEBACK_STOP_STATE; - // Have we been in this stopped state for too long w/o having delivered full blood volume back to patient? - if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < rinsebackTargetVolume_mL ) ) - { - signalGoToTreatmentStopped(); - activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); - } // Have we been in this stopped state for too long despite having delivered full blood volume back to patient? - else if ( ( rinsebackTimerCtr > MAX_RINSEBACK_DONE_TIME ) && ( getRinsebackVolume() >= rinsebackTargetVolume_mL ) ) + if ( ( rinsebackTimerCtr > MAX_RINSEBACK_DONE_TIME ) && ( getRinsebackVolume() >= rinsebackTargetVolume_mL ) ) { signalGoToTreatmentStopped(); activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); @@ -501,6 +503,12 @@ { activateAlarmNoData( ALARM_ID_HD_TREATMENT_RINSEBACK_TIMEOUT_WARNING ); } + // Have we been in this stopped state for too long w/o having delivered full blood volume back to patient? + else if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < rinsebackTargetVolume_mL ) ) + { + signalGoToTreatmentStopped(); + activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); + } else if ( TRUE == recircRequested ) { signalRinsebackToRecirc(); @@ -994,7 +1002,7 @@ } // Scale to seconds countdown /= ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); - + data.isCompleted = FALSE; data.targetRinsebackVolumeMl = rinsebackTargetVolume_mL; rinsebackPublishTimerCtr = 0; // If we have completed rinseback, timeout is no longer in force - indicate by zeroing timeout. Also include any additionals to target. @@ -1011,7 +1019,10 @@ } data.timeout = timeout; data.countdown = countdown; - data.unused = 0.0; // TODO - remove when UI no longer looks for this field + if ( data.deliveredRinsebackVolumeMl >= rinsebackTargetVolume_mL ) + { + data.isCompleted = TRUE; + } broadcastData( MSG_ID_HD_RINSEBACK_PROGRESS, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( RINSEBACK_DATA_PAYLOAD_T ) ); } }