Index: firmware/App/Modes/StateTxBloodPrime.c =================================================================== diff -u -rfa48af23c2b1cf940c485ad2602fdd186e775a0e -r837f6f8cde5a6902e6033d4097d42a4c34067182 --- firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision fa48af23c2b1cf940c485ad2602fdd186e775a0e) +++ firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision 837f6f8cde5a6902e6033d4097d42a4c34067182) @@ -53,14 +53,15 @@ // ********** private data ********** static BLOOD_PRIME_STATE_T bloodPrimeState; ///< Current state of the blood prime sub-mode. +static REQUESTED_BLOOD_PRIME_USER_ACTIONS_T bloodPrimeRequestedAction = NUM_OF_REQUESTED_BLOOD_PRIME_USER_ACTIONS; ///< Number of requested blood prime user actions static F32 bloodPrimeRampFlowRate_mL_min; ///< Current blood pump ramp flow rate. static F32 bloodPrimeRampStep_mL; ///< Blood pump volume step size for ramping. static F32 bloodPrimeTargetVolume_mL; ///< Calculated target blood prime volume (based on selected dialyzer and fixed tubing volume). +static F32 lastBloodPrimeFlowRate_mL_min; ///< Timer counter for determining for last blood prime status. static U32 bloodPrimeRampControlTimerCtr; ///< Timer counter for determining interval for controlling BP ramp. static U32 bloodPrimePublishTimerCtr; ///< Timer counter for determining interval for blood prime status to be published. -static U32 lastBloodPrimeFlowRate_mL_min; ///< Timer counter for determining for last blood prime status. /// Interval (in task intervals) at which to publish blood prime data to CAN bus. static OVERRIDE_U32_T bloodPrimePublishInterval = { BLOOD_PRIME_DATA_PUBLISH_INTERVAL, BLOOD_PRIME_DATA_PUBLISH_INTERVAL, BLOOD_PRIME_DATA_PUBLISH_INTERVAL, 0 }; @@ -95,8 +96,9 @@ cumulativeBloodPrimeVolume_mL.data = 0.0; resetBloodPrimeFlags(); - bloodPrimeTargetVolume_mL = (F32)getTreatmentParameterU32( TUBING_BLOOD_PRIME_VOLUME_ML ) + getDialyzerBloodVolume( getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ) ); + bloodPrimeTargetVolume_mL = TUBING_BLOOD_PRIME_VOLUME_ML + (F32)( getDialyzerBloodVolume( getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ) ) ); bloodPrimeRampFlowRate_mL_min = (F32)BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN; + bloodPrimeRequestedAction = NUM_OF_REQUESTED_BLOOD_PRIME_USER_ACTIONS; // Calculate BP ramp step size rampRateSpan = (F32)( setBPRate - BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN ); @@ -230,40 +232,48 @@ { BLOOD_PRIME_STATE_T result = BLOOD_PRIME_RAMP_STATE; - // Update blood prime volume delivered so far + //Update blood prime volume delivered so far cumulativeBloodPrimeVolume_mL.data += ( getMeasuredBloodFlowRate() * BLOOD_PRIME_FLOW_INTEGRATOR ); - // Has blood prime completed? - if ( getBloodPrimeVolume() >= bloodPrimeTargetVolume_mL ) + if ( TRUE == getTestConfigStatus( TEST_CONFIG_SKIP_BLOOD_PRIME ) ) { - initBloodPrime(); // Reset blood prime so that we start anew next time we transition to this sub-mode - setBloodIsPrimed( TRUE ); // Signal treatment mode that blood prime is completed - signalBloodPrimeToDialysis(); // Signal treatment mode that it's time to start dialysis + cumulativeBloodPrimeVolume_mL.data = bloodPrimeTargetVolume_mL; } - else if ( getMeasuredBloodFlowRate() >= getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ) + // Volume reached to Dialysis + if ( getBloodPrimeVolume() >= bloodPrimeTargetVolume_mL ) { - result = BLOOD_PRIME_RUN_STATE; + initBloodPrime(); + setBloodIsPrimed( TRUE ); + signalBloodPrimeToDialysis(); } - // User requested pause - else if ( TRUE == isStopButtonPressed() ) + // Soft pause from UI + else if ( bloodPrimeRequestedAction == REQUESTED_USER_ACTION_BLOOD_PRIME_PAUSE ) { + bloodPrimeRequestedAction = NUM_OF_REQUESTED_BLOOD_PRIME_USER_ACTIONS; lastBloodPrimeFlowRate_mL_min = getMeasuredBloodFlowRate(); - setBloodPumpTargetFlowRate(0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - - // Close arterial & venous valves - setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); - setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); result = BLOOD_PRIME_PAUSED_STATE; } - else if ( getMeasuredBloodFlowRate() >= getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ) + else if ( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) != lastBloodPrimeFlowRate_mL_min ) { result = BLOOD_PRIME_RUN_STATE; } - return result; + else + { + // Continue ramping + if ( ++bloodPrimeRampControlTimerCtr >= BLOOD_PRIME_RAMPING_INTERVAL ) + { + U32 setBPRate = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); + setBloodPumpTargetFlowRate( setBPRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + bloodPrimeRampControlTimerCtr = 0; + } + } + + return result; } /*********************************************************************//** @@ -276,32 +286,34 @@ *************************************************************************/ static BLOOD_PRIME_STATE_T handleBloodPrimeRunState( void ) { - BLOOD_PRIME_STATE_T result = BLOOD_PRIME_RUN_STATE; + BLOOD_PRIME_STATE_T result = BLOOD_PRIME_RUN_STATE; - // Update blood prime volume delivered so far - cumulativeBloodPrimeVolume_mL.data += ( getMeasuredBloodFlowRate() * BLOOD_PRIME_FLOW_INTEGRATOR ); + // Update blood prime volume delivered so far + cumulativeBloodPrimeVolume_mL.data += ( getMeasuredBloodFlowRate() * BLOOD_PRIME_FLOW_INTEGRATOR ); - if ( getBloodPrimeVolume() >= bloodPrimeTargetVolume_mL ) - { - initBloodPrime(); // Reset blood prime so that we start anew next time we transition to this sub-mode - setBloodIsPrimed( TRUE ); // Signal treatment mode that blood prime is completed - signalBloodPrimeToDialysis(); // Signal treatment mode that it's time to start dialysis - } + if ( getBloodPrimeVolume() >= bloodPrimeTargetVolume_mL ) + { + initBloodPrime(); + setBloodIsPrimed( TRUE ); + signalBloodPrimeToDialysis(); + } - // User if request stop/pause - else if ( TRUE == isStopButtonPressed() ) - { - lastBloodPrimeFlowRate_mL_min = getMeasuredBloodFlowRate(); - // Turn pump OFF - setBloodPumpTargetFlowRate(0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + // Soft pause + else if ( bloodPrimeRequestedAction == REQUESTED_USER_ACTION_BLOOD_PRIME_PAUSE ) + { + bloodPrimeRequestedAction = NUM_OF_REQUESTED_BLOOD_PRIME_USER_ACTIONS; + lastBloodPrimeFlowRate_mL_min = getMeasuredBloodFlowRate(); + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + result = BLOOD_PRIME_PAUSED_STATE; + } - // Close arterial & venous pinch valves - setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); - setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); - result = BLOOD_PRIME_PAUSED_STATE; - } + else + { + // Run continuously at requested rate + setBloodPumpTargetFlowRate( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } - return result; + return result; } /*********************************************************************//** @@ -316,17 +328,22 @@ { BLOOD_PRIME_STATE_T result = BLOOD_PRIME_PAUSED_STATE; - // Transition back to treatment - if ( getCurrentOperationMode() == MODE_TREA ) + // Hard stop to exit blood prime + if ( TRUE == isStopButtonPressed() ) { - // Re-open arterial & venous valves - setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); - setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); + initBloodPrime(); + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + result = BLOOD_PRIME_RAMP_STATE; + } - // Restart pump at previous flow rate + // Resume from UI + else if ( bloodPrimeRequestedAction == REQUESTED_USER_ACTION_BLOOD_PRIME_RESUME ) + { + bloodPrimeRequestedAction = NUM_OF_REQUESTED_BLOOD_PRIME_USER_ACTIONS; + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); setBloodPumpTargetFlowRate( lastBloodPrimeFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - // Next state if ( getMeasuredBloodFlowRate() < getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ) { result = BLOOD_PRIME_RAMP_STATE; @@ -354,6 +371,34 @@ } /*********************************************************************//** +* @brief +* The bloodPrimeHandleCmdRequest function handles the UI blood prime +* command request. +* @details \b Message \b Sent: MSG_ID_UI_BLOOD_PRIME_CMD_REQUEST +* @details \b Inputs: message containing requested blood prime user action. +* @details \b Outputs: bloodPrimeRequestedAction updated if valid. +* @return TRUE if payload is valid, FALSE otherwise. +*************************************************************************/ +BOOL bloodPrimeHandleCmdRequest( MESSAGE_T *message ) +{ + REQUESTED_BLOOD_PRIME_USER_ACTIONS_T requestedAction; + + if ( sizeof(requestedAction) == message->hdr.payloadLen ) + { + memcpy( &requestedAction, message->payload[0], sizeof( requestedAction ) ); + + if ( requestedAction < NUM_OF_REQUESTED_BLOOD_PRIME_USER_ACTIONS ) + { + bloodPrimeRequestedAction = requestedAction; + } + + return TRUE; + } + + return FALSE; +} + +/*********************************************************************//** * @brief * The publishBloodPrimeData function publishes blood prime data * at interval.