Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -146,11 +146,13 @@ static U32 bpControlTimerCounter = 0; ///< determines when to perform control on blood flow -static U32 bpRotorRevStartTime = 0; ///< blood pump rotor rotation start time (in ms) +static U32 bpRotorRevStartTime = 0; ///< blood pump rotor rotation start time (in ms) +static U32 bloodPumpRotorCounter = 0; ///< running counter for blood pump rotor revolutions static BOOL bpStopAtHomePosition = FALSE; ///< stop blood pump at next home position static U32 bpHomeStartTime = 0; ///< when did blood pump home command begin? (in ms) -static U16 bpLastMotorHallSensorCount = 0; ///< last hall sensor count for the blood pump motor +static U16 bpLastMotorHallSensorCount = 0; ///< last hall sensor count for the blood pump motor +static U32 bloodPumpMotorEdgeCount = 0; ///< running counter for blood pump motor revolutions static MOTOR_DIR_T bpMotorDirectionFromHallSensors = MOTOR_DIR_FORWARD; ///< pump direction according to hall sensor count static U32 bpMotorSpeedCalcTimerCtr = 0; ///< counter determines interval for calculating blood pump motor speed from hall sensor count. @@ -313,7 +315,10 @@ void signalBloodPumpRotorHallSensor( void ) { U32 rotTime = getMSTimerCount(); - U32 deltaTime = calcTimeBetween( bpRotorRevStartTime, rotTime ); + U32 deltaTime = calcTimeBetween( bpRotorRevStartTime, rotTime ); + + // increment rotor counter + bloodPumpRotorCounter++; // calculate rotor speed (in RPM) bloodPumpRotorSpeedRPM.data = ( 1.0 / (F32)deltaTime ) * (F32)MS_PER_SECOND * (F32)SEC_PER_MIN; @@ -347,6 +352,45 @@ } return result; +} + +/*********************************************************************//** + * @brief + * The getBloodPumpMotorCount function returns the current count for the + * blood pump motor revolution counter. + * @details Inputs: bloodPumpMotorCount + * @details Outputs: none + * @return bloodPumpMotorCount + *************************************************************************/ +U32 getBloodPumpMotorCount( void ) +{ + return bloodPumpMotorEdgeCount / BP_HALL_EDGE_COUNTS_PER_REV; +} + +/*********************************************************************//** + * @brief + * The getBloodPumpRotorCount function returns the current count for the + * blood pump rotor revolution counter. + * @details Inputs: bloodPumpRotorCounter + * @details Outputs: none + * @return bloodPumpRotorCounter + *************************************************************************/ +U32 getBloodPumpRotorCount( void ) +{ + return bloodPumpRotorCounter; +} + +/*********************************************************************//** + * @brief + * The isBloodPumpRunning function returns whether the blood pump is currently + * running or not. + * @details Inputs: isBloodPumpOn + * @details Outputs: none + * @return isBloodPumpOn + *************************************************************************/ +BOOL isBloodPumpRunning( void ) +{ + return isBloodPumpOn; } /*********************************************************************//** @@ -911,7 +955,8 @@ bpMotorDirectionFromHallSensors = MOTOR_DIR_REVERSE; delta = decDelta; bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; - } + } + bloodPumpMotorEdgeCount += delta; // update last count for next time bpLastMotorHallSensorCount = bpMotorHallSensorCount; Index: firmware/App/Controllers/BloodFlow.h =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -32,7 +32,10 @@ // ********** public definitions ********** #define MAX_BLOOD_FLOW_RATE 500 ///< Maximum blood flow rate (in mL/min). -#define MIN_BLOOD_FLOW_RATE 100 ///< Minimum blood flow rate (in mL/min). +#define MIN_BLOOD_FLOW_RATE 100 ///< Minimum blood flow rate (in mL/min). +#define SALINE_BOLUS_FLOW_RATE 150 ///< Saline bolus flow rate (in mL/min). + +#define VOLUME_PER_BP_MOTOR_REV_ML 0.2 ///< Theoretical volume (mL) of blood/saline volume per motor revolution. // ********** public function prototypes ********** @@ -43,7 +46,10 @@ BOOL setBloodPumpTargetFlowRate( U32 flowRate, MOTOR_DIR_T dir, PUMP_CONTROL_MODE_T mode ); void signalBloodPumpHardStop( void ); void signalBloodPumpRotorHallSensor( void ); -BOOL homeBloodPump( void ); +BOOL homeBloodPump( void ); +U32 getBloodPumpMotorCount( void ); +U32 getBloodPumpRotorCount( void ); +BOOL isBloodPumpRunning( void ); SELF_TEST_STATUS_T execBloodFlowTest( void ); Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -346,6 +346,19 @@ return result; } +/*********************************************************************//** + * @brief + * The isDialInPumpRunning function returns whether the dialysate inlet pump + * is currently running or not. + * @details Inputs: isDialInPumpOn + * @details Outputs: none + * @return isDialInPumpOn + *************************************************************************/ +BOOL isDialInPumpRunning( void ) +{ + return isDialInPumpOn; +} + /*********************************************************************//** * @brief * The execDialInFlowMonitor function executes the dialIn flow monitor. Index: firmware/App/Controllers/DialInFlow.h =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -33,6 +33,7 @@ #define MAX_DIAL_IN_FLOW_RATE 600 ///< Maximum dialysate inlet flow rate (in mL/min). #define MIN_DIAL_IN_FLOW_RATE 100 ///< Minimum dialysate inlet flow rate (in mL/min). +#define DIALYSATE_FLOW_RATE_FOR_RECIRC 100 ///< Dialysate recirculation flow rate (in mL/min). // ********** public function prototypes ********** @@ -44,6 +45,7 @@ void signalDialInPumpHardStop( void ); void signalDialInPumpRotorHallSensor( void ); BOOL homeDialInPump( void ); +BOOL isDialInPumpRunning( void ); SELF_TEST_STATUS_T execDialInFlowTest( void ); Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -380,6 +380,19 @@ /*********************************************************************//** * @brief + * The isDialOutPumpRunning function returns whether the dialysate outlet + * pump is currently running or not. + * @details Inputs: isDialOutPumpOn + * @details Outputs: none + * @return isDialOutPumpOn + *************************************************************************/ +BOOL isDialOutPumpRunning( void ) +{ + return isDialOutPumpOn; +} + +/*********************************************************************//** + * @brief * The setDialOutUFVolumes function sets the ultrafiltration reference and * measured total volumes (in mL). * @details Index: firmware/App/Controllers/DialOutFlow.h =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -68,6 +68,7 @@ void signalDialOutPumpHardStop( void ); void signalDialOutPumpRotorHallSensor( void ); BOOL homeDialOutPump( void ); +BOOL isDialOutPumpRunning( void ); BOOL setNewLoadCellReadings( F32 res1Primary, F32 res1Backup, F32 res2Primary, F32 res2Backup ); Index: firmware/App/HDCommon.h =================================================================== diff -u -r62a09fa67dc30631186f3e4d7a62437c1108c31a -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 62a09fa67dc30631186f3e4d7a62437c1108c31a) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -48,7 +48,7 @@ #define DISABLE_PUMP_DIRECTION_CHECKS 1 // do not error on HD pump direction checks #define DISABLE_PRESSURE_CHECKS 1 // do not error on HD pressure checks #define DISABLE_UF_ALARMS 1 // do not error on HD ultrafiltration checks - #define RUN_PUMPS_OPEN_LOOP 1 // BP and DPi pumps will be run open loop (no flow sensor feedback) +// #define RUN_PUMPS_OPEN_LOOP 1 // BP and DPi pumps will be run open loop (no flow sensor feedback) // #define RAW_FLOW_SENSOR_DATA 1 // test build will not filter flow sensor data // #define READ_FPGA_ASYNC_DATA 1 // test build reads non-priority register page every other time // #define FLOW_DEBUG 1 // test build sends flow, signal strength, and occlusion readings to debug UART Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -ra4f5ed3748870d287a4c2c6fcc003fc4d3b9233f -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision a4f5ed3748870d287a4c2c6fcc003fc4d3b9233f) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -23,12 +23,13 @@ #include "Dialysis.h" #include "DialInFlow.h" #include "DialOutFlow.h" +#include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" -#include "ModeTreatment.h" +#include "Valves.h" /** * @addtogroup Dialysis @@ -41,11 +42,15 @@ #define MAX_UF_RATE_ACCURACY_ERROR_ML_HR 100.0 ///< Maximum ultrafiltration rate accuracy error in mL/hr over each hour of treatment. #define MAX_UF_RATE_ACCURACY_ERROR_PCT 0.05 ///< Minimum ultrafilteration rate accuracy in percentage of set point (5%) over each hour of treatment. #define MAX_UF_ACCURACY_ERROR_ML 250.0 ///< Maximum ultrafiltration accuracy error in mL over the entire treatment. -/// Ultrafiltration rate accuracy check interval count +/// Saline bolus data broadcast interval (ms/task time) count. +#define SALINE_BOLUS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +/// Ultrafiltration rate accuracy check interval count. #define UF_ACCURACY_CHECK_INTERVAL ((1 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL) -#define MAX_SALINE_VOLUME_DELIVERED 800.0 ///< Maximum saline volume delivered for a treatment. +#define MAX_SALINE_VOLUME_DELIVERED 800 ///< Maximum saline volume delivered for a treatment. #define SALINE_BOLUS_RATE_ML_MIN 150 ///< Fixed rate for saline bolus delivery. +#define MIN_SALINE_BOLUS_VOLUME_PCT 0.8 ///< Minimum saline bolus volume measured by independent means (as % of target). +#define MAX_SALINE_BOLUS_VOLUME_PCT 1.2 ///< Maximum saline bolus volume measured by independent means (as % of target). // ********** private data ********** @@ -68,12 +73,16 @@ static F32 setUFRate; ///< Currently set ultrafiltration rate (from prescription). static F32 maxUFRateAccuracyError_Ml_hr; ///< Minimum ultrafiltration rate accuracy over 1 hour duration (5% or 100 mL, whichever is greater). +static U32 salineBolusBroadcastTimerCtr; ///< Saline bolus data broadcast timer counter used to schedule when to transmit data. static BOOL salineBolusStartRequested; ///< Flag indicates a saline bolus start has been requested by user. static BOOL salineBolusAbortRequested; ///< Flag indicates a salien bolus abort has been requested by user. static BOOL salineBolusAutoResumeUF; ///< Flag indicates UF should be auto-resumed after saline bolus completes. static F32 totalSalineVolumeDelivered; ///< Volume (mL) in total of saline delivered so far (cumulative for all boluses including current one). static F32 bolusSalineVolumeDelivered; ///< Volume (mL) of current bolus delivered so far. static F32 bolusSalineVolumeDelivered_Safety; ///< Volume (mL) of current bolus delivered so far according to safety monitor. +static U32 bolusSalineRotorCount; ///< Blood pump rotor count during saline bolus to calculate saline bolus volume independently for safety. +static U32 bolusSalineLastRotorCount; ///< Last blood pump count from last saline bolus volume update. +static U32 bolusSalineLastVolumeTimeStamp; ///< Time stamp for last saline volume update. static U32 uFAccuracyCheckTimerCtr; ///< Timer counter to determine when next to check ultrafiltration accuracy. static F32 lastUFVolumeChecked; ///< Starting ultrafiltration volume for accuracy check. @@ -90,12 +99,15 @@ static UF_STATE_T handleUFCompletedState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusIdleState( DIALYSIS_STATE_T *dialysisState ); +static SALINE_BOLUS_STATE_T handleSalineBolusWait4Pumps2Stop( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusInProgressState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusMaxDeliveredState( DIALYSIS_STATE_T *dialysisState ); static void checkUFAccuracyAndVolume( void ); static void updateUFVolumes( void ); +static void publishSalineBolusData( void ); + /*********************************************************************//** * @brief * The initDialysis function initializes the Dialysis sub-mode module. @@ -114,8 +126,6 @@ refUFVolume = 0.0; measUFVolume = 0.0; -// resStartVolume[ DG_RESERVOIR_1 ] = 0.0; -// resStartVolume[ DG_RESERVOIR_2 ] = 0.0; resFinalVolume[ DG_RESERVOIR_1 ] = 0.0; resFinalVolume[ DG_RESERVOIR_2 ] = 0.0; measUFVolumeFromPriorReservoirs = 0.0; @@ -129,12 +139,19 @@ setUFRate = 0.0; maxUFRateAccuracyError_Ml_hr = MAX_UF_RATE_ACCURACY_ERROR_ML_HR; - salineBolusStartRequested = FALSE; - salineBolusAbortRequested = FALSE; - salineBolusAutoResumeUF = FALSE; + salineBolusBroadcastTimerCtr = 0; + totalSalineVolumeDelivered = 0.0; uFAccuracyCheckTimerCtr = 0; lastUFVolumeChecked = 0.0; + + // initialize saline bolus variables + salineBolusStartRequested = FALSE; + salineBolusAbortRequested = FALSE; + salineBolusAutoResumeUF = FALSE; + bolusSalineVolumeDelivered = 0.0; + bolusSalineVolumeDelivered_Safety = 0.0; + bolusSalineRotorCount = 0; } /*********************************************************************//** @@ -206,6 +223,7 @@ lastUFTimeStamp = getMSTimerCount(); // send dialysate outlet pump latest UF volumes setDialOutUFVolumes( refUFVolume, measUFVolume ); + // restart pumps #ifndef RUN_PUMPS_OPEN_LOOP setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); @@ -271,7 +289,7 @@ { rejReason = REQUEST_REJECT_REASON_SALINE_BOLUS_IN_PROGRESS; } - else if ( totalSalineVolumeDelivered >= MAX_SALINE_VOLUME_DELIVERED ) + else if ( totalSalineVolumeDelivered >= (F32)MAX_SALINE_VOLUME_DELIVERED ) { rejReason = REQUEST_REJECT_REASON_SALINE_MAX_VOLUME_REACHED; } @@ -512,6 +530,9 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSIS_INVALID_STATE, currentDialysisState ) break; } + + // publish saline bolus data at set interval (whether we're delivering one or not) + publishSalineBolusData(); } /*********************************************************************//** @@ -577,6 +598,10 @@ currentSalineBolusState = handleSalineBolusIdleState( &result ); break; + case SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP: + currentSalineBolusState = handleSalineBolusWait4Pumps2Stop( &result ); + break; + case SALINE_BOLUS_STATE_IN_PROGRESS: currentSalineBolusState = handleSalineBolusInProgressState( &result ); break; @@ -809,13 +834,72 @@ if ( TRUE == salineBolusStartRequested ) { salineBolusStartRequested = FALSE; + // cmd all pumps to stop +#ifndef RUN_PUMPS_OPEN_LOOP + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); +#else + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); +#endif + // begin saline bolus + result = SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP; } return result; } /*********************************************************************//** * @brief + * The handleSalineBolusWait4Pumps2Stop function handles the wait for pumps + * to stop state of the saline bolus state machine. + * @details Inputs: none + * @details Outputs: + * @param dialysisState next dialysis state + * @return next saline bolus state + *************************************************************************/ +static SALINE_BOLUS_STATE_T handleSalineBolusWait4Pumps2Stop( DIALYSIS_STATE_T *dialysisState ) +{ + SALINE_BOLUS_STATE_T result = SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP; + + if ( ( FALSE == isBloodPumpRunning() ) && ( FALSE == isDialInPumpRunning() ) && ( FALSE == isDialOutPumpRunning() ) ) + { + // reset bolus data before we start + bolusSalineVolumeDelivered = 0.0; + bolusSalineVolumeDelivered_Safety = 0.0; + bolusSalineRotorCount = 0; + bolusSalineLastRotorCount = getBloodPumpRotorCount(); + bolusSalineLastVolumeTimeStamp = getMSTimerCount(); + // TODO - turn off accumulation of dialysate usage + + // bypass dialyzer + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + // switch to saline bag + setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); + // start blood pump at saline bolus rate +#ifndef RUN_PUMPS_OPEN_LOOP + setBloodPumpTargetFlowRate( SALINE_BOLUS_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); +#else + setBloodPumpTargetFlowRate( SALINE_BOLUS_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); +#endif + // start dialysate inlet pump at re-circ rate +#ifndef RUN_PUMPS_OPEN_LOOP + setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_RECIRC, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); +#else + setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_RECIRC, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); +#endif + // begin saline bolus + result = SALINE_BOLUS_STATE_IN_PROGRESS; + } + + return result; +} + +/*********************************************************************//** + * @brief * The handleSalineBolusInProgressState function handles the in-progress state of the * saline bolus state machine. * @details Inputs: none @@ -826,7 +910,72 @@ static SALINE_BOLUS_STATE_T handleSalineBolusInProgressState( DIALYSIS_STATE_T *dialysisState ) { SALINE_BOLUS_STATE_T result = SALINE_BOLUS_STATE_IN_PROGRESS; + F32 timeSinceLastVolumeUpdateMin = (F32)calcTimeSince( bolusSalineLastVolumeTimeStamp ) / (F32)( MS_PER_SECOND * SEC_PER_MIN ); + F32 bolusTargetVolume = getTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); + F32 bldFlowRate = getMeasuredBloodFlowRate(); // TODO - should I use raw flow instead of filtered here??? + F32 volSinceLastUpdateMl = bldFlowRate * timeSinceLastVolumeUpdateMin; + U32 bldPumpMotorCount = getBloodPumpMotorCount(); + U32 bldPumpMotorDelta = u32DiffWithWrap( bolusSalineLastRotorCount, bldPumpMotorCount ); + // update saline bolus volumes + bolusSalineLastVolumeTimeStamp = getMSTimerCount(); + bolusSalineVolumeDelivered += volSinceLastUpdateMl; + totalSalineVolumeDelivered += volSinceLastUpdateMl; + bolusSalineRotorCount += bldPumpMotorDelta; + bolusSalineLastRotorCount = bldPumpMotorCount; + bolusSalineVolumeDelivered_Safety = ( (F32)bolusSalineRotorCount * VOLUME_PER_BP_MOTOR_REV_ML ); // TODO - include upstream pressure compensation to this calc + + // TODO - check for empty saline bag + + // determine if we've reached maximum saline delivery volume + if ( ( totalSalineVolumeDelivered >= (F32)MAX_SALINE_VOLUME_DELIVERED ) ) + { + result = SALINE_BOLUS_STATE_MAX_DELIVERED; + } + else + { + // determine if bolus is complete + if ( bolusSalineVolumeDelivered >= bolusTargetVolume ) + { + // if safety thinks we've under-delivered the bolus, throw a fault + if ( bolusSalineVolumeDelivered_Safety < ( bolusTargetVolume * MIN_SALINE_BOLUS_VOLUME_PCT ) ) + { + // TODO - fault + } + result = SALINE_BOLUS_STATE_IDLE; + } + // determine if safety thinks we've over-delivered the bolus + else if ( bolusSalineVolumeDelivered_Safety > ( bolusTargetVolume * MAX_SALINE_BOLUS_VOLUME_PCT ) ) + { + // TODO - fault + result = SALINE_BOLUS_STATE_IDLE; + } + } + + // are we stopping the bolus and resuming treatment? + if ( result != SALINE_BOLUS_STATE_IN_PROGRESS ) + { + // hard stop blood and dialysate pumps + signalBloodPumpHardStop(); + signalDialInPumpHardStop(); + // send last saline bolus data + salineBolusBroadcastTimerCtr = SALINE_BOLUS_DATA_PUB_INTERVAL; + publishSalineBolusData(); + // switch back to dialyzer + + // switch back to patient artery + + if ( TRUE == salineBolusAutoResumeUF ) + { + // TODO - resume dialysis + // TODO - resume UF + } + // TODO - resume dialysate usage + + // resume dialysis + startDialysis(); + } + return result; } @@ -843,11 +992,36 @@ { SALINE_BOLUS_STATE_T result = SALINE_BOLUS_STATE_MAX_DELIVERED; + // nothing to be done here - this is a terminal state for a given treatment - no more saline may be delivered to patient + return result; } /*********************************************************************//** * @brief + * The publishSalineBolusData function handles the max saline delivered + * state of the saline bolus state machine. This is a terminal state. + * @details Inputs: none + * @details Outputs: + * @param dialysisState next dialysis state + * @return next saline bolus state + *************************************************************************/ +static void publishSalineBolusData( void ) +{ + if ( ++salineBolusBroadcastTimerCtr >= SALINE_BOLUS_DATA_PUB_INTERVAL ) + { + SALINE_BOLUS_DATA_PAYLOAD_T data; + + data.maxSalineVolumeMl = MAX_SALINE_VOLUME_DELIVERED; + data.cumSalineVolumeMl = totalSalineVolumeDelivered; + data.bolSalineVolumeMl = bolusSalineVolumeDelivered; + broadcastSalineBolusData( data ); + salineBolusBroadcastTimerCtr = 0; + } +} + +/*********************************************************************//** + * @brief * The checkUF function checks ultrafiltration accuracy for the last * hour and checks total UF volume. Triggers an alarm if out of spec. * @details Index: firmware/App/Modes/Dialysis.h =================================================================== diff -u -ra4f5ed3748870d287a4c2c6fcc003fc4d3b9233f -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Modes/Dialysis.h (.../Dialysis.h) (revision a4f5ed3748870d287a4c2c6fcc003fc4d3b9233f) +++ firmware/App/Modes/Dialysis.h (.../Dialysis.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -31,6 +31,18 @@ // ********** public definitions ********** +#pragma pack(push,1) + +/// Payload record structure for a saline bolus data broadcast message. +typedef struct +{ + U32 maxSalineVolumeMl; + F32 cumSalineVolumeMl; + F32 bolSalineVolumeMl; +} SALINE_BOLUS_DATA_PAYLOAD_T; + +#pragma pack(pop) + // ********** private function prototypes ********** void initDialysis( void ); Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rd91a24c730aeb5cd7e3eba9ef4eca78e442911f8 -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision d91a24c730aeb5cd7e3eba9ef4eca78e442911f8) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -455,6 +455,19 @@ BOOL result = alarmIsActive[ alarm ]; return result; +} + +/*********************************************************************//** + * @brief + * The getCurrentAlarmStatePriority function determines the current alarm + * state priority (NONE, LOW, MEDIUM, or HIGH). + * @details Inputs: alarmStatus + * @details Outputs: none + * @return current alarm state priority + *************************************************************************/ +ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ) +{ + return alarmStatus.alarmsState; } /*********************************************************************//** @@ -466,7 +479,7 @@ * @param alarmID ID of alarm to check * @return The start time stamp of given alarm ID *************************************************************************/ -U32 getAlarmStartTime( U32 alarmID ) +U32 getAlarmStartTime( U32 alarmID ) { U32 result = 0; Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -ra4f5ed3748870d287a4c2c6fcc003fc4d3b9233f -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision a4f5ed3748870d287a4c2c6fcc003fc4d3b9233f) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -210,7 +210,8 @@ void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ); void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ); void clearAlarm( ALARM_ID_T alarm ); -BOOL isAlarmActive( ALARM_ID_T alarm ); +BOOL isAlarmActive( ALARM_ID_T alarm ); +ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ); BOOL testSetAlarmStatusPublishIntervalOverride( U32 value ); BOOL testResetAlarmStatusPublishIntervalOverride( void ); Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -ra4f5ed3748870d287a4c2c6fcc003fc4d3b9233f -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a4f5ed3748870d287a4c2c6fcc003fc4d3b9233f) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -23,7 +23,6 @@ #include "Buttons.h" #include "DGInterface.h" #include "DialInFlow.h" -#include "Dialysis.h" #include "FPGA.h" #include "MessagePayloads.h" #include "ModeStandby.h" @@ -1131,7 +1130,7 @@ /***********************************************************************//** * @brief - * The broadcastHDValves function constructs an HD valves msg to \n + * The broadcastHDValves function constructs an HD valves msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none * @details Outputs: HD valves msg constructed and queued @@ -1156,6 +1155,33 @@ return result; } +/***********************************************************************//** + * @brief + * The broadcastSalineBolusData function constructs a saline bolus data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: saline bolus data msg constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastSalineBolusData( SALINE_BOLUS_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_SALINE_BOLUS_DATA; + msg.hdr.payloadLen = sizeof( SALINE_BOLUS_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( SALINE_BOLUS_DATA_PAYLOAD_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + #ifdef EMC_TEST_BUILD BOOL broadcastCANErrorCount( U32 count ) { Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -ra4f5ed3748870d287a4c2c6fcc003fc4d3b9233f -r2acda0ccdd00334bec87bfbe61c4e78e867925de --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a4f5ed3748870d287a4c2c6fcc003fc4d3b9233f) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 2acda0ccdd00334bec87bfbe61c4e78e867925de) @@ -21,7 +21,8 @@ #include "HDCommon.h" #include "MsgQueues.h" #include "DialOutFlow.h" -#include "DGInterface.h" +#include "DGInterface.h" +#include "Dialysis.h" #include "Valves.h" /** @@ -200,6 +201,9 @@ // MSG_ID_HD_VALVES_DATA BOOL broadcastHDValves( HD_VALVE_DATA_T *valveData ); +// MSG_ID_SALINE_BOLUS_DATA +BOOL broadcastSalineBolusData( SALINE_BOLUS_DATA_PAYLOAD_T data ); + #ifdef EMC_TEST_BUILD // MSG_ID_CAN_ERROR_COUNT BOOL broadcastCANErrorCount( U32 count );