Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r78db0ac30c2511d78e1da8b9be3fdbf68d4a9902 -r90d3a2eb18cc8282c0c68a23e39677327448781a --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 78db0ac30c2511d78e1da8b9be3fdbf68d4a9902) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 90d3a2eb18cc8282c0c68a23e39677327448781a) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-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 Prime.c * -* @author (last) Sean Nash -* @date (last) 12-Nov-2021 +* @author (last) Hung Nguyen +* @date (last) 04-Jan-2022 * * @author (original) Quang Nguyen * @date (original) 08-Dec-2020 @@ -36,88 +36,87 @@ // ********** private definitions ********** -#define MAX_PRIME_TIME ( 15 * SEC_PER_MIN ) ///< Maximum prime time (in seconds). -#define PRIME_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the prime data is published on the CAN bus. +#define MAX_PRIME_TIME ( 10 * SEC_PER_MIN ) ///< Maximum prime time (in seconds). +#define PRIME_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the prime data is published on the CAN bus. -#define BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN 300 ///< Blood pump fast flow rate to fill fluid. -#define BLOOD_PUMP_SLOW_FLOW_RATE_PURGE_AIR_ML_MIN 150 ///< Blood pump slow flow rate after fluid reach lower level of air trap sensor. -#define BLOOD_PUMP_SALINE_FLOW_RATE_PURGE_AIR_ML_MIN 200 ///< Blood pump very slow flow rate during prime saline dialyzer state -#define BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump flow rate during prime recirculate blood circuit state. -#define BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN 300 ///< Blood pump flow rate during prime the saline dialyzer dialysate state. +#define BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN 300 ///< Blood pump fast flow rate to fill fluid. +#define BLOOD_PUMP_SLOW_FLOW_RATE_PURGE_AIR_ML_MIN 150 ///< Blood pump slow flow rate after fluid reach lower level of air trap sensor. +#define BLOOD_PUMP_SALINE_FLOW_RATE_PURGE_AIR_ML_MIN 200 ///< Blood pump very slow flow rate during prime saline dialyzer state +#define BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump flow rate during prime recirculate blood circuit state. +#define BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN 300 ///< Blood pump flow rate during prime the saline dialyzer dialysate state. +#define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. -#define DIALYSATE_DIALYZER_TUBE_VOLUME_ML 115 ///< This total tube volume is used to calculate the Dpi & Dpo time out in the dialysate dialyzer state. -#define DIALYSATE_DIALYZER_BYPASS_TUBE_VOLUME_ML 75 ///< This volume is used to calculate the DPi pump time out in the dialyzer bypass state +#define DIALYSATE_DIALYZER_TUBE_VOLUME_ML 115 ///< This total tube volume is used to calculate the Dpi & Dpo time out in the dialysate dialyzer state. +#define DIALYSATE_DIALYZER_BYPASS_TUBE_VOLUME_ML 75 ///< This volume is used to calculate the DPi pump time out in the dialyzer bypass state. +#define DIALYZER_DVI_PATH_VOLUME_ML 17 ///< Path volume from the dialyzer to the VDI valve in mL. +#define DIALYZER_VOLUME_SCALE_FACTOR 0.5 ///< Half of the dialyzer total volume. -#define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. -#define DIALYZER_DVI_PATH_VOLUME_ML 17 ///< Path volume from the dialyzer to the VDI valve in mL. +#define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. +#define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. +#define LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ( 1 * MS_PER_SECOND ) ///< Time load cell reading steady state detection sampling time in seconds. +#define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 15 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. +#define STEADY_VOLUME_COUNT_SEC ( 10000 / LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ) ///< Counter must be greater than 10 seconds before steady volume is true. +#define STEADY_VOLUME_TIME_DEADLINE_MS ( 55 * MS_PER_SECOND ) ///< Time in msec for the steady volume deadline time out. -#define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. -#define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. -#define LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ( 1 * MS_PER_SECOND ) ///< Time load cell reading steady state detection sampling time in seconds. -#define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 15 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. -#define STEADY_VOLUME_COUNT_SEC 10 ///< Counter must be greater than 10 before steady volume is true. -#define STEADY_VOLUME_TIME_DEADLINE_MS ( 55 * MS_PER_SECOND ) ///< Time in msec for the steady volume deadline time out. - /// States of the treatment reservoir management state machine. typedef enum PrimeReservoirMgmt_States { - PRIME_RESERVOIR_MGMT_START_STATE = 0, ///< If DG not already in re-circ mode, try to get it there. - PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE, ///< In DG re-circ, wait for lines to flush - then start draining inactive reservoir. - PRIME_RESERVOIR_MGMT_WAIT_FOR_DRAIN_CMD_RESP, ///< After sending drain command, wait for DG to response back. - PRIME_RESERVOIR_MGMT_DRAIN_STATE, ///< Wait for drain to complete. - PRIME_RESERVOIR_MGMT_START_FILL_STATE, ///< Command DG to start filling reservoir. - PRIME_RESERVOIR_MGMT_WAIT_FOR_FILL_CMD_RESP, ///< After sending fill command, wait for DG to response back. - PRIME_RESERVOIR_MGMT_FILL_STATE, ///< Wait for fill to complete. - PRIME_RESERVOIR_MGMT_FILL_COMPLETE_STATE, ///< Reservoir fill has completed. - PRIME_RESERVOIR_MGMT_WAIT_RESERVOIR_TWO_INACTIVE, ///< Wait for reservoir 2 become inactive. - NUM_OF_PRIME_RESERVOIR_MGMT_STATES ///< Number of prime reservoir mgmt. states. + PRIME_RESERVOIR_MGMT_START_STATE = 0, ///< If DG not already in re-circ mode, try to get it there. + PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE, ///< In DG re-circ, wait for lines to flush - then start draining inactive reservoir. + PRIME_RESERVOIR_MGMT_WAIT_FOR_DRAIN_CMD_RESP, ///< After sending drain command, wait for DG to response back. + PRIME_RESERVOIR_MGMT_DRAIN_STATE, ///< Wait for drain to complete. + PRIME_RESERVOIR_MGMT_START_FILL_STATE, ///< Command DG to start filling reservoir. + PRIME_RESERVOIR_MGMT_WAIT_FOR_FILL_CMD_RESP, ///< After sending fill command, wait for DG to response back. + PRIME_RESERVOIR_MGMT_FILL_STATE, ///< Wait for fill to complete. + PRIME_RESERVOIR_MGMT_FILL_COMPLETE_STATE, ///< Reservoir fill has completed. + PRIME_RESERVOIR_MGMT_WAIT_RESERVOIR_TWO_INACTIVE, ///< Wait for reservoir 2 become inactive. + NUM_OF_PRIME_RESERVOIR_MGMT_STATES ///< Number of prime reservoir mgmt. states. } PRIME_RESERVOIR_MGMT_STATE_T; typedef struct { - U32 bloodVolume; ///< Blood volume of the dialyzer in mL. - U32 dialysateVolume; ///< Dialysate volume of the dialyzer in mL. + U32 bloodVolume; ///< Blood volume of the dialyzer in mL. + U32 dialysateVolume; ///< Dialysate volume of the dialyzer in mL. } DIALYZER_VOLUME_DATA_T; // ********** private data ********** -static DIALYZER_VOLUME_DATA_T dialyzerVolumeTable[ ] = { { 82, 170 }, ///< Dialyzer volume table in mL of five types of dialyzer - { 100, 200 }, - { 120, 257 }, - { 87, 233 }, - { 102, 280 } }; +/// Dialyzer volumes (blood and dialysate) table in mL for each type of dialyzer. +static DIALYZER_VOLUME_DATA_T dialyzerVolumeTable[ ] = + { { 82, 170 }, // DIALYZER_TYPE_BBRAUN_PRO_13H + { 100, 200 }, // DIALYZER_TYPE_BBRAUN_PRO_16H + { 120, 257 }, // DIALYZER_TYPE_BBRAUN_PRO_19H + { 87, 233 }, // DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F160NRE + { 102, 280 } }; // DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F180NRE -static U32 primeDialysateDialyzerTimeLimit; ///< Time limit in msec for priming dialysate dialyzer path. -static U32 primeSalineDialyzerTimeLimit; ///< Time limit in msec for priming saline dialyzer path. +static U32 primeDialysateDialyzerTimeLimit; ///< Time limit in msec for priming dialysate dialyzer path. +static U32 primeSalineDialyzerTimeLimit; ///< Time limit in msec for priming saline dialyzer path. -static HD_PRE_TREATMENT_PRIME_STATE_T currentPrimeState; ///< Current state of the prime sub-mode state machine. -static HD_PRE_TREATMENT_PRIME_STATE_T previousPrimeState; ///< Previous state of the prime sub-mode, to use when resuming from pause. -static PRIME_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current reservoir management state. +static HD_PRE_TREATMENT_PRIME_STATE_T currentPrimeState; ///< Current state of the prime sub-mode state machine. +static HD_PRE_TREATMENT_PRIME_STATE_T previousPrimeState; ///< Previous state of the prime sub-mode, to use when resuming from pause. +static PRIME_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current reservoir management state. -static U32 primeStartTime; ///< Starting time of priming (in ms). -static U32 primePauseStartTime; ///< Priming pause start time (in ms). -static U32 primeStatusBroadcastTimerCounter; ///< Prime status data broadcast timer counter used to schedule when to transmit data. +static U32 primeStartTime; ///< Starting time of priming (in ms). +static U32 primePauseStartTime; ///< Priming pause start time (in ms). +static U32 primeStatusBroadcastTimerCounter; ///< Prime status data broadcast timer counter used to schedule when to transmit data. -static BOOL primeStartRequested; ///< Flag indicates user requesting to start prime. -static BOOL primeResumeRequested; ///< Flag indicates user requesting prime resume. +static BOOL primeStartRequested; ///< Flag indicates user requesting to start prime. +static BOOL primeResumeRequested; ///< Flag indicates user requesting prime resume. -static U32 noAirDetectedStartTime; ///< starting time when detecting no air. -static U32 purgeAirTimeOutStartTime; ///< Starting time for purge air state time out. -static U32 primeSalineDialyzerStartTime; ///< Starting time of priming saline dialyzer circuit. -static U32 primeDialysateDialyzerStartTime; ///< Starting time of priming dialysate dialyzer circuit. -static U32 primeDialysateBypassStartTime; ///< Starting time of priming dialysate bypass circuit. -static U32 steadyVolumeSamplingStartTime; ///< Load cell steady volume sampling interval starting time. -static BOOL runBloodCircuitPrimeAgain; ///< Flag indicates HD should run blood circuit prime once more time. -static F32 minimumReservoirVolume; ///< Minimum reservoir volume in mL. -static U32 steadyVolumeCount; ///< Use to keep track the number of dVolume/dt < Threshold +static U32 noAirDetectedStartTime; ///< starting time when detecting no air. +static U32 purgeAirTimeOutStartTime; ///< Starting time for purge air state time out. +static U32 primeSalineDialyzerStartTime; ///< Starting time of priming saline dialyzer circuit. +static U32 primeDialysateDialyzerStartTime; ///< Starting time of priming dialysate dialyzer circuit. +static U32 primeDialysateBypassStartTime; ///< Starting time of priming dialysate bypass circuit. +static U32 steadyVolumeSamplingStartTime; ///< Load cell steady volume sampling interval starting time. +static F32 minimumReservoirVolume; ///< Minimum reservoir volume in mL. +static U32 steadyVolumeCount; ///< Use to keep track the number of dVolume/dt < Threshold // ********** private function prototypes ********** static void resetPrimeFlags(); static void setupForPrimePause( void ); static void broadcastPrimingStatus( void ); static void purgeAirValvesBloodPumpControl( void ); -static F32 getDialyzerBloodVolume( void ); -static F32 getDialyzerDialysateVolume( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeWaitForUserStartState( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineDialyzerSetupState( void ); @@ -161,7 +160,6 @@ primeStartTime = getMSTimerCount(); primePauseStartTime = 0; primeStatusBroadcastTimerCounter = 0; - runBloodCircuitPrimeAgain = TRUE; setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); @@ -271,9 +269,9 @@ * the selected dialyzer. * @details Inputs: dialyzer volume table * @details Outputs: none - * @return blood volume capacity of the dialyzer in mL + * @return blood volume capacity of the selected dialyzer type in mL *************************************************************************/ -F32 getDialyzerBloodVolume( void ) +U32 getDialyzerBloodVolume( void ) { U32 dialyzerType = getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ); @@ -286,9 +284,9 @@ * of the selected dialyzer. * @details Inputs: dialyzer volume table * @details Outputs: none - * @return dialysate volume capacity of the dialyzer in mL + * @return dialysate volume capacity of the selected dialyzer type in mL *************************************************************************/ -F32 getDialyzerDialysateVolume( void ) +U32 getDialyzerDialysateVolume( void ) { U32 dialyzerType = getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ); @@ -426,7 +424,10 @@ primeStartTime = getMSTimerCount(); #ifdef SKIP_UI_INTERACTION - primeStartRequested = TRUE; + //if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) != SW_CONFIG_ENABLE_VALUE ) + { + primeStartRequested = TRUE; + } #endif if ( TRUE == primeStartRequested ) { @@ -618,19 +619,7 @@ { if ( ++steadyVolumeCount >= STEADY_VOLUME_COUNT_SEC ) { -#ifdef RUN_BLOOD_CIRCUIT_PRIME_AGAIN - if ( TRUE == runBloodCircuitPrimeAgain ) - { - runBloodCircuitPrimeAgain = FALSE; - state = HD_PRIME_SALINE_SETUP_STATE; - } - else - { - state = HD_PRIME_SALINE_DIALYZER_SETUP_STATE; - } -#else state = HD_PRIME_SALINE_DIALYZER_SETUP_STATE; -#endif } } else @@ -684,7 +673,7 @@ signalDialInPumpHardStop(); setBloodPumpTargetFlowRate( BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - primeSalineDialyzerTimeLimit = (U32)( ( ( dialyzerDialysateVolume * 0.5 + DIALYZER_DVI_PATH_VOLUME_ML ) * SEC_PER_MIN * MS_PER_SECOND ) / BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN ); + primeSalineDialyzerTimeLimit = (U32)( ( ( dialyzerDialysateVolume * DIALYZER_VOLUME_SCALE_FACTOR + DIALYZER_DVI_PATH_VOLUME_ML ) * SEC_PER_MIN * MS_PER_SECOND ) / BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN ); primeSalineDialyzerStartTime = getMSTimerCount(); if ( TRUE == doesAlarmStatusIndicateStop() )