Index: firmware/App/Modes/StateTxPaused.c =================================================================== diff -u -r79c2105d7ec35f3caeb977f6e2cc1b494853d211 -r289696b3b5e15120cfecbe447ff45ef093959056 --- firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision 79c2105d7ec35f3caeb977f6e2cc1b494853d211) +++ firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision 289696b3b5e15120cfecbe447ff45ef093959056) @@ -18,14 +18,19 @@ #include "AirTrap.h" #include "BloodFlow.h" #include "Buttons.h" +#include "Common.h" #include "DDInterface.h" #include "Messaging.h" +#include "ModeTreatment.h" //#include "NVDataMgmt.h" #include "OperationModes.h" +#include "RotaryValve.h" #include "StateTxPaused.h" -//#include "Switches.h" +#include "Switches.h" #include "TaskGeneral.h" +#include "TxParams.h" #include "Valves.h" +#include "Valve3Way.h" /** * @addtogroup StateTxPaused @@ -41,12 +46,21 @@ static TREATMENT_PAUSED_STATE_T currentTxPausedState; ///< Current treatment paused state. static U32 bloodSittingTimerCtr; ///< Timer counter tracks time in this mode while blood is sitting. -static U32 pausedPublishTimerCtr; ///< Timer counter (in GP task intervals) counts time to next treatment paused status broadcast. - +static U32 treatmentPausedPublishTimerCtr; ///< Timer counter (in GP task intervals) counts time to next treatment paused status broadcast. static OVERRIDE_U32_T treatmentPausedPublishInterval; ///< Interval (in task intervals) at which to publish treatment paused state data to CAN bus. // ********** private function prototypes ********** +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedRecircState( void ); +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedDialysateRecircState( void ); +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedBloodRecircState( void ); +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedNoRecircState( void ); +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedRecoverBloodDetectState( void ); +static void handleTreatmentPausedBloodSittingTimer( void ); +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedAlarmsAndSignals( TREATMENT_PAUSED_STATE_T state ); +static void transitionToTxPausedState( TREATMENT_PAUSED_STATE_T newState ); +static void publishTreatmentPausedData( void ); + /*********************************************************************//** * @brief * The initTreatmentPaused function initializes the Treatment Paused State unit. @@ -56,9 +70,9 @@ *************************************************************************/ void initTreatmentPaused( void ) { - currentTxPausedState = TREATMENT_PAUSED_RECIRC_STATE; // Assume blood and dialysate will recirculate initially - will stop pump(s) as appropriate in state machine - bloodSittingTimerCtr = 0; - pausedPublishTimerCtr = TREATMENT_PAUSED_DATA_PUBLISH_INTERVAL; + currentTxPausedState = TREATMENT_PAUSED_RECIRC_STATE; // Assume blood and dialysate will recirculate initially - will stop pump(s) as appropriate in state machine + bloodSittingTimerCtr = 0; + treatmentPausedPublishTimerCtr = TREATMENT_PAUSED_DATA_PUBLISH_INTERVAL; treatmentPausedPublishInterval.data = TREATMENT_PAUSED_DATA_PUBLISH_INTERVAL; treatmentPausedPublishInterval.ovData = TREATMENT_PAUSED_DATA_PUBLISH_INTERVAL; @@ -83,7 +97,8 @@ // Set user alarm recovery actions allowed in this sub-mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); if ( FALSE ) // TODO ( TRUE == getRinsebackCompleted() ) - { // block rinseback action if already done + { + // block rinseback action if already done setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); } else @@ -92,16 +107,9 @@ } setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); -// setupForBloodRecirculationState(); -// setupForDialysateRecirculationState(); - // temporary actuator setup until setup functions implemented TODO - signalBloodPumpHardStop(); - setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); - setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); - cmdBypassDialyzer( TRUE ); - cmdChangeQuf( 0.0F ); - startAirTrapControl(); + transitionToTxPausedState( currentTxPausedState ); + // TODO figure out the code // signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); // Reset saline bolus state in case alarm interrupted one @@ -139,40 +147,40 @@ { TREATMENT_PAUSED_STATE_T priorSubState = currentTxPausedState; -// switch ( currentTxPausedState ) -// { -// case TREATMENT_PAUSED_RECIRC_STATE: -// currentTxPausedState = handleTreatmentStopRecircState(); -// break; -// -// case TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE: -// currentTxPausedState = handleTreatmentStopDialysateRecircState(); -// break; -// -// case TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE: -// currentTxPausedState = handleTreatmentStopBloodRecircState(); -// break; -// -// case TREATMENT_PAUSED_NO_RECIRC_STATE: -// currentTxPausedState = handleTreatmentStopNoRecircState(); -// break; -// -// case TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE: -// currentTxPausedState = handleTreatmentStopRecoverBloodDetectState(); -// break; -// -// default: -// SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_STOP_INVALID_STATE, currentTxStopState ); -// break; -// } + switch ( currentTxPausedState ) + { + case TREATMENT_PAUSED_RECIRC_STATE: + currentTxPausedState = handleTreatmentPausedRecircState(); + break; + case TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE: + currentTxPausedState = handleTreatmentPausedDialysateRecircState(); + break; + + case TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE: + currentTxPausedState = handleTreatmentPausedBloodRecircState(); + break; + + case TREATMENT_PAUSED_NO_RECIRC_STATE: + currentTxPausedState = handleTreatmentPausedNoRecircState(); + break; + + case TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE: + currentTxPausedState = handleTreatmentPausedRecoverBloodDetectState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_STOP_INVALID_STATE, currentTxPausedState ); + break; + } + if ( priorSubState != currentTxPausedState ) { setCurrentSubState( (U32)currentTxPausedState ); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, priorSubState, currentTxPausedState ); } - // Broadcast treatment stop status -// publishTreatmentStopData(); + // Broadcast treatment paused status + publishTreatmentPausedData(); } /*********************************************************************//** @@ -188,4 +196,310 @@ return currentTxPausedState; } +/*********************************************************************//** + * @brief + * The handleTreatmentPausedRecircState function handles the re-circ dialysate + * and blood state operations. + * @details Inputs: active alarms + * @details Outputs: dialysate re-circulation stopped if active alarm blocks + * @return next treatment paused state + *************************************************************************/ +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedRecircState( void ) +{ + TREATMENT_PAUSED_STATE_T result = TREATMENT_PAUSED_RECIRC_STATE; + + result = handleTreatmentPausedAlarmsAndSignals( result ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentPausedDialysateRecircState function handles the Dialysate only + * re-circulating state operations. + * @details Inputs: flags + * @details Outputs: flags handled + * @return next treatment paused state + *************************************************************************/ +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedDialysateRecircState( void ) +{ + TREATMENT_PAUSED_STATE_T result = TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE; + + handleTreatmentPausedBloodSittingTimer(); + result = handleTreatmentPausedAlarmsAndSignals( result ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentPausedBloodRecircState function handles the Blood only + * re-circulating state operations. + * @details Inputs: flags + * @details Outputs: flags handled + * @return next treatment paused state + *************************************************************************/ +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedBloodRecircState( void ) +{ + TREATMENT_PAUSED_STATE_T result = TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE; + + result = handleTreatmentPausedAlarmsAndSignals( result ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentStopNoRecircState function handles the no re-circ dialysate + * state operations. + * @details Inputs: none + * @details Outputs: none + * @return next treatment paused state + *************************************************************************/ +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedNoRecircState( void ) +{ + TREATMENT_PAUSED_STATE_T result = TREATMENT_PAUSED_NO_RECIRC_STATE; + + handleTreatmentPausedBloodSittingTimer(); + result = handleTreatmentPausedAlarmsAndSignals( result ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentPausedRecoverBloodDetectState function handles the recovering + * for blood detect state in treatment paused. + * @details Inputs: none + * @details Outputs: none + * @return next treatment paused state + *************************************************************************/ +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedRecoverBloodDetectState( void ) +{ + TREATMENT_PAUSED_STATE_T result = TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE; + + // TODO uncomment + //execBloodLeakZeroing(); + + //// Keep reseting the blood sitting timer + handleTreatmentPausedBloodSittingTimer(); + result = handleTreatmentPausedAlarmsAndSignals( result ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentPausedBloodSittingTimer function handles the no re-circ + * blood timer. It should only be called when Blood is NOT circulating. + * Increments and checks for warning and alarm timeouts. + * @details Inputs: bloodSittingTimerCtr + * @details Outputs: bloodSittingTimerCtr + * @return next treatment paused state + *************************************************************************/ +static void handleTreatmentPausedBloodSittingTimer( void ) +{ + // Ensure we do not sit in stopped state for too long (if blood in line) + //if ( getRinsebackCompleted() != TRUE ) // TODO rinseback + if ( TRUE ) + { + bloodSittingTimerCtr++; + if ( FALSE == doesAlarmStatusIndicateEndTxOnly() ) // Alarms appropriate only if we are not already at an alarm stop, end Tx only + { + 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 ); + } + } + } + else + { + bloodSittingTimerCtr = 0; + } +} + +/*********************************************************************//** + * @brief + * The handleTreatmentPausedAlarmsAndSignals function handles the Alarms and User Signals + * operations to set new states. + * @details Inputs: state, flags + * @details Outputs: flags handled + * @param state the treatment paused state + * @return next treatment re-circulation state + *************************************************************************/ +static TREATMENT_PAUSED_STATE_T handleTreatmentPausedAlarmsAndSignals( TREATMENT_PAUSED_STATE_T state ) +{ + TREATMENT_PAUSED_STATE_T result = state; + BOOL bloodRecircBlocked = isBloodRecircBlocked(); + BOOL dialysateRecircBlocked = isDialysateRecircBlocked(); + BOOL bldAlarmsStatus = FALSE; //( ( TRUE == isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ) ) && + // ( FALSE == isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_DETECTED ) ? TRUE : FALSE ) ); // TODO un-comment when BLD is coming up + + if ( TRUE == bldAlarmsStatus ) + { + if ( ( TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE != state ) && ( dialysateRecircBlocked != TRUE ) ) + { + result = TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE; + transitionToTxPausedState( result ); + } + } + else + { + // Both unblocked and not in recirculate both state + if ( ( TREATMENT_PAUSED_NO_RECIRC_STATE != state ) && ( FALSE == dialysateRecircBlocked ) && ( FALSE == bloodRecircBlocked ) ) + { + result = TREATMENT_PAUSED_RECIRC_STATE; + transitionToTxPausedState( result ); + } + // Both blocked and not in stopped state + else if ( ( TREATMENT_PAUSED_NO_RECIRC_STATE != state ) && ( TRUE == dialysateRecircBlocked ) && ( TRUE == bloodRecircBlocked ) ) + { + result = TREATMENT_PAUSED_NO_RECIRC_STATE; + transitionToTxPausedState( result ); + } + // Dialysate recirculation blocked and not in blood recirc state + else if ( ( TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE != state ) && ( TRUE == dialysateRecircBlocked ) && + ( FALSE == bloodRecircBlocked ) ) + { + result = TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE; + transitionToTxPausedState( result ); + } + // Blood recirculation blocked and not in dialysate recirc state + else if ( ( TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE != state ) && ( TRUE == bloodRecircBlocked ) && + ( FALSE == dialysateRecircBlocked ) ) + { + result = TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE; + transitionToTxPausedState( result ); + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The transitionToTxPausedState function handles the transition to treatment + * paused state by setting the actuators. + * @details Inputs: none + * @details Outputs: none + * @param newState the targeted state that the transition is going to go + * @return none + *************************************************************************/ +static void transitionToTxPausedState( TREATMENT_PAUSED_STATE_T newState ) +{ + switch ( newState ) + { + case TREATMENT_PAUSED_RECIRC_STATE: + { + U32 targetBloodFlowMLPM = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + setBloodPumpTargetFlowRate( targetBloodFlowMLPM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + startAirTrapControl(); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + doorClosedRequired( TRUE ); + } + break; + + case TREATMENT_PAUSED_RECIRC_DIALYSATE_ONLY_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + endAirTrapControl(); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + doorClosedRequired( FALSE ); + } + break; + + case TREATMENT_PAUSED_RECIRC_BLOOD_ONLY_STATE: + { + U32 targetBloodFlowMLPM = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); + + setBloodPumpTargetFlowRate( targetBloodFlowMLPM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); + startAirTrapControl(); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( 0.0F ); + cmdChangeQuf( 0.0F ); + doorClosedRequired( TRUE ); + } + break; + + case TREATMENT_PAUSED_NO_RECIRC_STATE: + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + endAirTrapControl(); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( 0.0F ); + cmdChangeQuf( 0.0F ); + doorClosedRequired( FALSE ); + break; + + case TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE: + // TODO fill up later + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_STOP_INVALID_STATE, (U32)newState ) + break; + } +} + +/*********************************************************************//** + * @brief + * The publishTreatmentPausedData function publishes treatment paused progress. + * @details Inputs: stopPublishTimerCtr, bloodSittingTimerCtr + * @details Outputs: treatment stop data published + * @return none + *************************************************************************/ +static void publishTreatmentPausedData( void ) +{ + if ( ++treatmentPausedPublishTimerCtr >= getU32OverrideValue( &treatmentPausedPublishInterval ) ) + { + TREATMENT_PAUSED_PAYLOAD_T data; + + // Set to zero so UI will not update unless needed below + data.timeout = 0; + data.countdown = 0; + + // TODO figure out the alarms + //if ( ( getRinsebackCompleted() != TRUE ) && + // ( isAlarmActive( ALARM_ID_HD_TREATMENT_RINSEBACK_TIMEOUT_ALARM ) != TRUE ) && + // ( isAlarmActive( ALARM_ID_HD_TREATMENT_STOPPED_NO_RINSEBACK ) != TRUE ) ) + { + if ( bloodSittingTimerCtr > 0 ) + { + data.timeout = MAX_TIME_BLOOD_SITTING / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); + data.countdown = ( bloodSittingTimerCtr >= MAX_TIME_BLOOD_SITTING ? 0 : ( MAX_TIME_BLOOD_SITTING - bloodSittingTimerCtr ) / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); + } + } + treatmentPausedPublishTimerCtr = 0; + broadcastData( MSG_ID_TD_TREATMENT_PAUSED_TIMER_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( TREATMENT_PAUSED_PAYLOAD_T ) ); + } +} + /**@}*/