Index: firmware/App/Modes/StateTxRinseback.c =================================================================== diff -u -r1275f9e92eb1ab0cd1b321c0c8eb940524e22117 -r909d4064e98d5684ee139534f0ac6cbc5f8774d5 --- firmware/App/Modes/StateTxRinseback.c (.../StateTxRinseback.c) (revision 1275f9e92eb1ab0cd1b321c0c8eb940524e22117) +++ firmware/App/Modes/StateTxRinseback.c (.../StateTxRinseback.c) (revision 909d4064e98d5684ee139534f0ac6cbc5f8774d5) @@ -46,8 +46,6 @@ /// Interval at which rinseback progress is to be published to UI. #define RINSEBACK_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) -/// Maximum time allowed for rinseback operation until full volume is delivered. Timer is reset whenever BP is running. -#define MAX_RINSEBACK_TIME ( 5 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ) /// Maximum time allowed for each additional rinseback volume delivery. #define MAX_RINSEBACK_ADDITIONAL_TIME ( 25 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. @@ -57,7 +55,7 @@ static RINSEBACK_STATE_T currentRinsebackState; ///< Current state of the rinseback sub-mode. static FLUID_TYPE_T fluidType; ///< Fluid Type to rinseback -static U32 rinsebackTimerCtr; ///< Timer counter for time spent in rinseback sub-mode. +static U32 bloodSittingTimerCtr; ///< Timer counter for time spent in rinseback sub-mode. static U32 rinsebackAdditionalTimerCtr; ///< Timer counter for duration of an additional rinseback delivery. static U32 rinsebackPublishTimerCtr; ///< Timer counter for determining interval for rinseback status to be published. static U32 rinsebackTargetVolume_mL; ///< Calculated target rinseback volume (based on selected dialyzer and fixed tubing volume). @@ -98,13 +96,14 @@ static BOOL handleRecircUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); static void publishRinsebackData( void ); +static void handleRinsebackBloodSittingTimer( void ); static U32 getPublishRinsebackInterval( void ); /*********************************************************************//** * @brief * The initRinseback function initializes the Rinseback sub-mode module. - * @details Inputs: none - * @details Outputs: Rinseback sub-mode module initialized. + * @details \b Inputs: none + * @details \b Outputs: Rinseback sub-mode module initialized. * @return none *************************************************************************/ void initRinseback( void ) @@ -114,7 +113,7 @@ setSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE, (U32)DEFAULT_RINSEBACK_FLOW_RATE_ML_MIN ); // Set to default rate before rinseback start rinsebackTargetVolume_mL = getTreatmentParameterU32( TREATMENT_PARAM_PRIME_RINSEBACK_VOLUME ); targetRinsebackVolumePlusAdditional_mL = rinsebackTargetVolume_mL; - rinsebackTimerCtr = 0; + bloodSittingTimerCtr = 0; cummulativeRinsebackVolume_mL.data = 0.0F; additionalRinsebackVolume_mL = 0.0F; rinsebackAdditionalTimerCtr = 0; @@ -125,8 +124,8 @@ /*********************************************************************//** * @brief * The resetRinsebackFlags function resets the Rinseback request flags. - * @details Inputs: none - * @details Outputs: Rinseback request flags reset to FALSE. + * @details \b Inputs: none + * @details \b Outputs: Rinseback request flags reset to FALSE. * @return none *************************************************************************/ static void resetRinsebackFlags( void ) @@ -144,8 +143,8 @@ * @brief * The transitionToRinseback function prepares for transition to Rinseback * sub-mode. - * @details Inputs: none - * @details Outputs: Rinseback sub-mode setup to begin + * @details \b Inputs: none + * @details \b Outputs: Rinseback sub-mode setup to begin * @return none *************************************************************************/ void transitionToRinseback( void ) @@ -173,8 +172,8 @@ * @brief * The setupForRinsebackDelivery function sets actuators appropriately * for rinseback states where delivery is in progress. - * @details Inputs: none - * @details Outputs: none + * @details \b Inputs: none + * @details \b Outputs: none * @param rate rinseback rate to use for blood pump and HDF pump * @return none *************************************************************************/ @@ -201,8 +200,8 @@ * @brief * The setupForRinsebackStopOrPause function sets actuators appropriately * for rinseback states where delivery is paused or stopped. - * @details Inputs: none - * @details Outputs: none + * @details \b Inputs: none + * @details \b Outputs: none * @return none *************************************************************************/ static void setupForRinsebackStopOrPause( void ) @@ -221,8 +220,8 @@ * @brief * The getDeliveredRinsebackVolume function gets the calculated rinseback volume * delivered. - * @details Inputs: cumulativeRinsebackVolume_mL - * @details Outputs: none + * @details \b Inputs: cumulativeRinsebackVolume_mL + * @details \b Outputs: none * @return the current rinseback volume delivered (in mL). *************************************************************************/ F32 getDeliveredRinsebackVolume( void ) @@ -241,8 +240,8 @@ * @brief * The getCurrentRinsebackState function returns the current state of the * rinseback sub-mode. - * @details Inputs: currentRinsebackState - * @details Outputs: none + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: none * @return currentRinsebackState *************************************************************************/ RINSEBACK_STATE_T getCurrentRinsebackState( void ) @@ -252,16 +251,37 @@ /*********************************************************************//** * @brief + * The handleRinsebackBloodSittingTimer function handles the no re-circ + * blood timer. + * @details Inputs: bloodSittingTimerCtr + * @details Outputs: none + * @return none + *************************************************************************/ +static void handleRinsebackBloodSittingTimer( void ) +{ + if ( bloodSittingTimerCtr > WARN_TIME_BLOOD_SITTING ) + { + activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_WARNING ); + } + if ( bloodSittingTimerCtr > MAX_TIME_BLOOD_SITTING ) + { + // Activate the alarm + activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_TOO_LONG ); + } +} + +/*********************************************************************//** + * @brief * The execRinseback function executes the Rinseback sub-mode state machine. - * @details Inputs: currentRinsebackState - * @details Outputs: currentRinsebackState, rinsebackTimerCtr + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: currentRinsebackState, bloodSittingTimerCtr * @return none *************************************************************************/ void execRinseback( void ) { RINSEBACK_STATE_T priorSubState = currentRinsebackState; - rinsebackTimerCtr++; + bloodSittingTimerCtr++; switch ( currentRinsebackState ) { @@ -301,38 +321,30 @@ // Publish rinseback progress while in rinseback sub-mode publishRinsebackData(); + + // Call blood sitting timer counter + handleRinsebackBloodSittingTimer(); } /*********************************************************************//** * @brief * The handleRinsebackStopInitState function handles the stopped initial * rinseback state operations. - * @details \b Alarms: ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM if rinseback - * timeout - * @details Inputs: startRinsebackRequested - * @details Outputs: none + * @details \b Inputs: startRinsebackRequested + * @details \b Outputs: none * @return next rinseback state *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackStopInitState( void ) { RINSEBACK_STATE_T state = RINSEBACK_STOP_INIT_STATE; - // Have we been in this state for too long? - if ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM, (U32)rinsebackTimerCtr, (U32)MAX_RINSEBACK_TIME ); - } // User requested rinseback start - else if ( TRUE == startRinsebackRequested ) + if ( TRUE == startRinsebackRequested ) { setBloodIsPrimed( FALSE ); setupForRinsebackDelivery(); state = RINSEBACK_RUN_STATE; } - else - { - // No action required. - } return state; } @@ -344,9 +356,9 @@ * @details \b Alarms: ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM if rinseback * timeout, ALARM_ID_TD_EMPTY_SALINE_BAG if saline bag is empty or * saline line is clamped - * @details Inputs: rinsebackTargetVolume_mL, pauseRinsebackRequestd, + * @details \b Inputs: rinsebackTargetVolume_mL, pauseRinsebackRequestd, * incrRinsebackFlowRateRequested, decrRinsebackFlowRateRequested - * @details Outputs: rinsebackTimerCtr, cumulativeRinsebackVolume_mL, + * @details \b Outputs: bloodSittingTimerCtr, cumulativeRinsebackVolume_mL, * rinsebackRate_mL_min, incrRinsebackFlowRateRequested, decrRinsebackFlowRateRequested * @return next rinseback state *************************************************************************/ @@ -355,15 +367,15 @@ RINSEBACK_STATE_T state = RINSEBACK_RUN_STATE; // Reset rinseback timeout - rinsebackTimerCtr = 0; + bloodSittingTimerCtr = 0; // Update rinseback volume delivered so far cummulativeRinsebackVolume_mL.data += ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) * RINSEBACK_FLOW_INTEGRATOR ); // Check for empty saline bag if we are using saline to rinseback. if ( ( FLUID_TYPE_SALINE == fluidType ) && ( TRUE == isSalineBagEmpty() ) ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_EMPTY_SALINE_BAG, getFilteredArterialPressure() ); + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_SALINE_BAG_VOLUME_LOW_ALARM, getFilteredArterialPressure() ); setupForRinsebackStopOrPause(); state = RINSEBACK_PAUSED_STATE; } @@ -418,29 +430,20 @@ * state operations. * @details \b Alarms: ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM if rinseback * timeout - * @details Inputs: rinsebackTimerCtr, resumeRinsebackRequested - * @details Outputs: targetRinsebackVolumePlusAdditional_mL + * @details \b Inputs: bloodSittingTimerCtr, resumeRinsebackRequested + * @details \b Outputs: targetRinsebackVolumePlusAdditional_mL * @return next rinseback state *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackPausedState( void ) { RINSEBACK_STATE_T state = RINSEBACK_PAUSED_STATE; - // Have we been in this state for too long? - if ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM, (U32)rinsebackTimerCtr, (U32)MAX_RINSEBACK_TIME ); - } // User requested to resume - else if ( TRUE == resumeRinsebackRequested ) + if ( TRUE == resumeRinsebackRequested ) { setupForRinsebackDelivery(); state = RINSEBACK_RUN_STATE; } - else - { - // No action required - } return state; } @@ -451,23 +454,18 @@ * state operations. * @details \b Alarms: ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM if rinseback * timeout - * @details Inputs: rinsebackTimerCtr, rinsebackTargetVolume_mL, recircRequested, + * @details \b Inputs: bloodSittingTimerCtr, rinsebackTargetVolume_mL, recircRequested, * additionalRinsebackRequested - * @details Outputs: additionalRinsebackRequested, + * @details \b Outputs: additionalRinsebackRequested, * rinsebackAdditionalTimerCtr, additionalRinsebackVolume_mL * @return next rinseback state *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackStoppedState( void ) { RINSEBACK_STATE_T state = 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 ) && ( getDeliveredRinsebackVolume() < rinsebackTargetVolume_mL ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM, (U32)rinsebackTimerCtr, (U32)MAX_RINSEBACK_TIME ); - } // User requested to recirculate - else if ( TRUE == recircRequested ) + if ( TRUE == recircRequested ) { if ( TRUE == isRecircAllowed() ) { @@ -478,10 +476,10 @@ { additionalRinsebackRequested = FALSE; - if ( ( rinsebackTimerCtr < MAX_RINSEBACK_TIME ) || ( getDeliveredRinsebackVolume() >= rinsebackTargetVolume_mL ) ) + if ( ( bloodSittingTimerCtr < MAX_TIME_BLOOD_SITTING ) || ( getDeliveredRinsebackVolume() >= rinsebackTargetVolume_mL ) ) { rinsebackAdditionalTimerCtr = 0; - additionalRinsebackVolume_mL = 0.0F; + additionalRinsebackVolume_mL = getDeliveredRinsebackVolume(); targetRinsebackVolumePlusAdditional_mL += TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML; setSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE, DEFAULT_RINSEBACK_FLOW_RATE_ML_MIN ); setupForRinsebackDelivery(); @@ -502,8 +500,8 @@ * state operations. * @details \b Alarms: ALARM_ID_TD_EMPTY_SALINE_BAG if saline bag is empty or * saline line is clamped. - * @details Inputs: additionalRinsebackVolume_mL, rinsebackAdditionalTimerCtr - * @details Outputs: rinsebackTimerCtr, additionalRinsebackVolume_mL, cumulativeRinsebackVolume_mL, + * @details \b Inputs: additionalRinsebackVolume_mL, rinsebackAdditionalTimerCtr + * @details \b Outputs: bloodSittingTimerCtr, additionalRinsebackVolume_mL, cumulativeRinsebackVolume_mL, * rinsebackAdditionalTimerCtr, targetRinsebackVolumePlusAdditional_mL * @return next rinseback state *************************************************************************/ @@ -513,25 +511,25 @@ F32 rinsebackVolumeSinceLast = ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) * RINSEBACK_FLOW_INTEGRATOR ); // Reset rinseback t/o - rinsebackTimerCtr = 0; + bloodSittingTimerCtr = 0; // update additional rinseback volume delivered so far - additionalRinsebackVolume_mL += rinsebackVolumeSinceLast; cummulativeRinsebackVolume_mL.data += rinsebackVolumeSinceLast; rinsebackAdditionalTimerCtr++; // Check for empty saline bag if we are using saline to rinseback. if ( ( FLUID_TYPE_SALINE == fluidType ) && ( TRUE == isSalineBagEmpty() ) ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_EMPTY_SALINE_BAG, getFilteredArterialPressure() ); + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_SALINE_BAG_VOLUME_LOW_ALARM, getFilteredArterialPressure() ); setupForRinsebackStopOrPause(); targetRinsebackVolumePlusAdditional_mL = getDeliveredRinsebackVolume(); state = RINSEBACK_STOP_STATE; } // Has additional volume been delivered? - else if ( additionalRinsebackVolume_mL >= TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) + else if ( getDeliveredRinsebackVolume() >= ( additionalRinsebackVolume_mL + TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) ) { setupForRinsebackStopOrPause(); + additionalRinsebackVolume_mL += rinsebackVolumeSinceLast; state = RINSEBACK_STOP_STATE; } // Has alarm requested stop or timed out? @@ -553,8 +551,8 @@ * @brief * The signalRinsebackAlarmResumeUserAction function signals the rinseback * sub-mode to resume per user alarm action. - * @details Inputs: currentRinsebackState - * @details Outputs: resumeRinsebackRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: resumeRinsebackRequested * @return none *************************************************************************/ void signalRinsebackAlarmResumeUserAction( void ) @@ -569,8 +567,8 @@ * @brief * The signalRinsebackUserAction function signals a rinseback user action * has been requested. - * @details Inputs: none - * @details Outputs: action handled, request responded to + * @details \b Inputs: none + * @details \b Outputs: action handled, request responded to * @param message UI message which has requested user action * @return TRUE if request is accepted, FALSE if rejected. *************************************************************************/ @@ -581,7 +579,6 @@ REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; UI_RESPONSE_PAYLOAD_T response; - if ( sizeof(U32) == message->hdr.payloadLen ) { memcpy( &cmd, message->payload, sizeof(U32) ); @@ -653,8 +650,8 @@ * The handleStartRinsebackUserAction function handles a start rinseback * user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs: startRinsebackRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: startRinsebackRequested * @param rejReason code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -680,8 +677,8 @@ * The handleIncrRinsebackUserAction function handles an increase rinseback * flow rate user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs: incrRinsebackFlowRateRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: incrRinsebackFlowRateRequested * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -715,8 +712,8 @@ * The handleDecrRinsebackUserAction function handles a decrease rinseback * flow rte user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs: decrRinsebackFlowRateRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: decrRinsebackFlowRateRequested * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -750,8 +747,8 @@ * The handlePauseRinsebackUserAction function handles a pause rinseback * user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs: pauseRinsebackRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: pauseRinsebackRequested * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -777,8 +774,8 @@ * The handleResumeRinsebackUserAction function handles a resume rinseback * user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs: resumeRinsebackRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: resumeRinsebackRequested * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -804,8 +801,8 @@ * The handleAdditionalRinsebackUserAction function handles an additional rinseback * user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs: additionalRinsebackRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs: additionalRinsebackRequested * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -831,8 +828,8 @@ * The handleToRecircUserAction function handles a go to re-circulate * user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. - * @details Inputs: currentRinsebackState - * @details Outputs:recircRequested + * @details \b Inputs: currentRinsebackState + * @details \b Outputs:recircRequested * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ @@ -865,9 +862,9 @@ * @brief * The publishRinsebackData function publishes rinseback progress to UI * at 1 Hz interval. - * @details Inputs: rinsebackPublishTimerCtr, rinsebackTimerCtr, targetRinsebackVolumePlusAdditional_mL + * @details \b Inputs: rinsebackPublishTimerCtr, bloodSittingTimerCtr, targetRinsebackVolumePlusAdditional_mL * rinsebackRate_mL_min - * @details Outputs: none + * @details \b Outputs: none * @return none *************************************************************************/ static void publishRinsebackData( void ) @@ -886,16 +883,16 @@ data.isRecircAllowed = isRecircAllowed(); // Report blood-sitting timeout countdown only while rinseback not completed and blood pump is stopped - if ( ( TRUE == rinsebackComplete ) || ( 0 == rinsebackTimerCtr ) ) + if ( ( TRUE == rinsebackComplete ) || ( 0 == bloodSittingTimerCtr ) ) { data.timeout = 0; data.countdown = 0; } else { - U32 countdown = ( rinsebackTimerCtr <= MAX_RINSEBACK_TIME ) ? ( MAX_RINSEBACK_TIME - rinsebackTimerCtr ) : 0; + U32 countdown = ( bloodSittingTimerCtr <= MAX_TIME_BLOOD_SITTING ) ? ( MAX_TIME_BLOOD_SITTING - bloodSittingTimerCtr ) : 0; - data.timeout = MAX_RINSEBACK_TIME / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); + data.timeout = MAX_TIME_BLOOD_SITTING / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); data.countdown = countdown / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); } @@ -907,8 +904,8 @@ * @brief * The getPublishRinsebackInterval function gets the rinseback data * publication interval. - * @details Inputs: rinsebackPublishInterval - * @details Outputs: none + * @details \b Inputs: rinsebackPublishInterval + * @details \b Outputs: none * @return the current rinseback publication interval (in task intervals). *************************************************************************/ static U32 getPublishRinsebackInterval( void ) @@ -928,6 +925,7 @@ * TEST SUPPORT FUNCTIONS *************************************************************************/ + /*********************************************************************//** * @brief * The testRinsebackVolumeOverride function overrides or resets the cumulative