Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -78,10 +78,11 @@ static U32 lastTreatmentTimeStamp; ///< Last time elapsed treatment time was recorded (a timestamp in ms). static U32 treatmentTimeBroadcastTimerCtr; ///< Treatment data broadcast timer counter used to schedule when to transmit data. static U32 treatmentParamsRangesBroadcastTimerCtr; ///< Treatment parameter ranges broadcast timer counter used to schedule when to transmit updated ranges. -// TODO - test code - remove later -static BUTTON_STATE_T lastOffButtonState = BUTTON_STATE_RELEASED; -static BOOL pendingUserEndTreatmentRequest; ///< Flag indicates user has requested treatment end. +static BOOL alarmStopSignalled; ///< Flag indicates an alarm w/ stop property was triggered. +static BOOL resumeTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment resume. +static BOOL initiateRinsebackAlarmResponseRequest; ///< Flag indicates user has requested rinseback. +static BOOL endTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment end. static U32 pendingParamChangesTimer; ///< User required to confirm UF volume change within 1 minute. static F32 pendingUFVolumeChange; ///< An ultrafiltration volume change (mL) is pending user confirmation. @@ -90,10 +91,14 @@ // ********** private function prototypes ********** +static void resetAlarmResponseFlags( void ); static void broadcastTreatmentSettingsRanges( void ); static TREATMENT_STATE_T handleTreatmentStartState( void ); +static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ); static TREATMENT_STATE_T handleTreatmentDialysisState( void ); static TREATMENT_STATE_T handleTreatmentStopState( void ); +static TREATMENT_STATE_T handleTreatmentRinsebackState( void ); +static TREATMENT_STATE_T handleTreatmentRecircState( void ); /*********************************************************************//** * @brief @@ -120,7 +125,7 @@ presMaxUFVolumeML = 0.0; presUFRate = 0.0; - pendingUserEndTreatmentRequest = FALSE; + resetAlarmResponseFlags(); pendingParamChangesTimer = 0; pendingUFVolumeChange = 0.0; @@ -130,6 +135,21 @@ /*********************************************************************//** * @brief + * The resetAlarmResponseFlags function resets the alarm response flags. + * @details Inputs: none + * @details Outputs: flags set to FALSE + * @return none + *************************************************************************/ +static void resetAlarmResponseFlags( void ) +{ + alarmStopSignalled = FALSE; + resumeTreatmentAlarmResponseRequest = FALSE; + initiateRinsebackAlarmResponseRequest = FALSE; + endTreatmentAlarmResponseRequest = FALSE; +} + +/*********************************************************************//** + * @brief * The transitionToTreatmentMode function prepares for transition to treatment mode. * @details Inputs: none * @details Outputs: @@ -197,7 +217,7 @@ * @details Outputs: none * @return bloodIsPrimed *************************************************************************/ -BOOL getBloodIsPrimed( void ) // Determine whether the blood-side circuit of the dialyzer has been primed with blood +BOOL getBloodIsPrimed( void ) { return bloodIsPrimed; } @@ -232,72 +252,19 @@ switch( action ) { case ALARM_ACTION_STOP: - switch ( currentTreatmentState ) - { - case TREATMENT_START_STATE: - case TREATMENT_DIALYSIS_STATE: - stopDialysis(); - transitionToTreatmentStop(); - currentTreatmentState = TREATMENT_STOP_STATE; - break; - - case TREATMENT_RINSEBACK_STATE: - signalStopRinseback(); - break; - - case TREATMENT_RECIRC_STATE: - signalStopTreatmentRecirc(); - break; - - default: - // Ignore - break; - } + alarmStopSignalled = TRUE; break; case ALARM_ACTION_RESUME: - switch ( currentTreatmentState ) - { - case TREATMENT_STOP_STATE: - lastTreatmentTimeStamp = getMSTimerCount(); - startDialysis(); - transitionToDialysis(); - currentTreatmentState = TREATMENT_DIALYSIS_STATE; - break; - - default: - // Ignore - break; - } + resumeTreatmentAlarmResponseRequest = TRUE; break; case ALARM_ACTION_RINSEBACK: - switch ( currentTreatmentState ) - { - case TREATMENT_STOP_STATE: - lastTreatmentTimeStamp = getMSTimerCount(); - startDialysis(); - transitionToDialysis(); - currentTreatmentState = TREATMENT_DIALYSIS_STATE; - break; - - default: - // Ignore - break; - } + initiateRinsebackAlarmResponseRequest = TRUE; break; case ALARM_ACTION_END_TREATMENT: - switch ( currentTreatmentState ) - { - case TREATMENT_STOP_STATE: - pendingUserEndTreatmentRequest = TRUE; - break; - - default: - // Ignore - break; - } + endTreatmentAlarmResponseRequest = TRUE; break; case ALARM_ACTION_ACK: @@ -333,6 +300,10 @@ currentTreatmentState = handleTreatmentStartState(); break; + case TREATMENT_BLOOD_PRIME_STATE: + currentTreatmentState = handleTreatmentBloodPrimeState(); + break; + case TREATMENT_DIALYSIS_STATE: currentTreatmentState = handleTreatmentDialysisState(); break; @@ -342,11 +313,11 @@ break; case TREATMENT_RINSEBACK_STATE: - // TODO - implement + currentTreatmentState = handleTreatmentRinsebackState(); break; case TREATMENT_RECIRC_STATE: - // TODO - implement + currentTreatmentState = handleTreatmentRecircState(); break; case TREATMENT_DIALYSIS_END_STATE: @@ -364,6 +335,10 @@ currentTreatmentState = TREATMENT_END_STATE; break; } + + // Alarm response request flags should be handled at this point, reset in case not handled in current state + resetAlarmResponseFlags(); + // Broadcast treatment data broadcastTreatmentTimeAndState(); broadcastTreatmentSettingsRanges(); @@ -378,22 +353,20 @@ /*********************************************************************//** * @brief * The handleTreatmentStartState function handles the Start state of - * the Treatment Mode state machine. + * the Treatment Mode state machine. Should only pass through this state + * once at very beginning of treatment. * @details Inputs: none * @details Outputs: treatmentTimeMS, lastTreatmentTimeStamp * @return next treatment mode state *************************************************************************/ -static TREATMENT_STATE_T handleTreatmentStartState( void ) // TODO - we need a blood prime state between start and dialysis sub-modes +static TREATMENT_STATE_T handleTreatmentStartState( void ) { - TREATMENT_STATE_T result = TREATMENT_DIALYSIS_STATE; + TREATMENT_STATE_T result = TREATMENT_BLOOD_PRIME_STATE; // Initialize treatment time treatmentTimeMS = 0; lastTreatmentTimeStamp = getMSTimerCount(); - setRinsebackIsCompleted( FALSE ); - //setBloodIsPrimed( TRUE ); TODO - call when blood prime is completed - presTreatmentTimeSecs = SEC_PER_MIN * getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); presBloodFlowRate = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); presDialysateFlowRate = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); @@ -409,6 +382,43 @@ /*********************************************************************//** * @brief + * The handleTreatmentBloodPrimeState function handles the blood prime state of + * the Treatment Mode state machine. + * @details Inputs: none + * @details Outputs: none + * @return next treatment mode state + *************************************************************************/ +static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ) // TODO - need separate module w/ states for this sub-mode (signal functions in treatment mode to be called if sub-mode chaning) +{ + TREATMENT_STATE_T result = TREATMENT_BLOOD_PRIME_STATE; + + setRinsebackIsCompleted( FALSE ); + + if ( TRUE == alarmStopSignalled ) + { + alarmStopSignalled = FALSE; + // TODO - stopBloodPrime(); + transitionToTreatmentStop(); + result = TREATMENT_STOP_STATE; + } + else + { + if ( TRUE ) // TODO - when blood prime done signal + { + setBloodIsPrimed( TRUE ); // TODO - call when blood prime is completed + result = TREATMENT_DIALYSIS_STATE; + } + else + { + //execTreatmentBloodPrime(); // TODO - implement this state + } + } + + return result; +} + +/*********************************************************************//** + * @brief * The handleTreatmentDialysisState function handles the Dialysis state of * the Treatment Mode state machine. * @details Inputs: none @@ -422,39 +432,33 @@ U32 newTime = getMSTimerCount(); U32 msSinceLast = calcTimeBetween( lastTreatmentTimeStamp, newTime ); - // Update treatment time (unless delivering a saline bolus) - if ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) + if ( TRUE == alarmStopSignalled ) { - treatmentTimeMS += msSinceLast; + alarmStopSignalled = FALSE; + stopDialysis(); + transitionToTreatmentStop(); + result = TREATMENT_STOP_STATE; } - lastTreatmentTimeStamp = newTime; - - // End treatment if treatment duration has been reached - if ( CALC_ELAPSED_TREAT_TIME_IN_SECS() >= presTreatmentTimeSecs ) - { - result = TREATMENT_END_STATE; - } - // Otherwise, execute state machine for treatment dialysis sub-mode else { - execDialysis(); - } + // Update treatment time (unless delivering a saline bolus) + if ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) + { + treatmentTimeMS += msSinceLast; + } + lastTreatmentTimeStamp = newTime; - // TODO - test code - remove later - if ( getOffButtonState() == BUTTON_STATE_PRESSED ) - { - if ( lastOffButtonState == BUTTON_STATE_RELEASED ) + // End treatment if treatment duration has been reached + if ( CALC_ELAPSED_TREAT_TIME_IN_SECS() >= presTreatmentTimeSecs ) { - lastOffButtonState = BUTTON_STATE_PRESSED; - stopDialysis(); - transitionToTreatmentStop(); - result = TREATMENT_STOP_STATE; + result = TREATMENT_END_STATE; } + // Otherwise, execute state machine for treatment dialysis sub-mode + else + { + execDialysis(); + } } - else - { - lastOffButtonState = BUTTON_STATE_RELEASED; - } return result; } @@ -471,34 +475,89 @@ { TREATMENT_STATE_T result = TREATMENT_STOP_STATE; + // If user requests resumption of treatment, resume treatment + if ( TRUE == resumeTreatmentAlarmResponseRequest ) + { + resumeTreatmentAlarmResponseRequest = FALSE; + if ( TRUE == getBloodIsPrimed() ) + { + lastTreatmentTimeStamp = getMSTimerCount(); + startDialysis(); + transitionToDialysis(); + result = TREATMENT_DIALYSIS_STATE; + } + else + { + // TODO - transitionToBloodPrime(); + result = TREATMENT_BLOOD_PRIME_STATE; + } + } + // If user requests rinseback, go to rinseback + else if ( TRUE == initiateRinsebackAlarmResponseRequest ) + { + initiateRinsebackAlarmResponseRequest = FALSE; + transitionToRinseback(); + result = TREATMENT_RINSEBACK_STATE; + } // If user requests treatment end, end treatment - if ( TRUE == pendingUserEndTreatmentRequest ) + else if ( TRUE == endTreatmentAlarmResponseRequest ) { + endTreatmentAlarmResponseRequest = FALSE; + // TODO - transition to end state result = TREATMENT_END_STATE; } + // Otherwise execute state machine for treatment stop sub-mode else { - // Execute state machine for treatment stop sub-mode execTreatmentStop(); } - // TODO - test code - remove later - if ( getOffButtonState() == BUTTON_STATE_PRESSED ) + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentRinsebackState function executes the rinseback state of the + * Treatment Mode state machine. + * @details Inputs: none + * @details Outputs: treatment rinseback sub-mode executed. + * @return next treatment mode state + *************************************************************************/ +static TREATMENT_STATE_T handleTreatmentRinsebackState( void ) +{ + TREATMENT_STATE_T result = TREATMENT_RINSEBACK_STATE; + + if ( TRUE == alarmStopSignalled ) { - if ( lastOffButtonState == BUTTON_STATE_RELEASED ) - { - lastOffButtonState = BUTTON_STATE_PRESSED; - lastTreatmentTimeStamp = getMSTimerCount(); - startDialysis(); - transitionToDialysis(); - result = TREATMENT_DIALYSIS_STATE; - } + alarmStopSignalled = FALSE; + signalStopRinseback(); } - else + + execRinseback(); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentRecircState function executes the re-circulate state of the + * Treatment Mode state machine. + * @details Inputs: none + * @details Outputs: treatment re-circulate sub-mode executed. + * @return next treatment mode state + *************************************************************************/ +static TREATMENT_STATE_T handleTreatmentRecircState( void ) +{ + TREATMENT_STATE_T result = TREATMENT_RINSEBACK_STATE; + + if ( TRUE == alarmStopSignalled ) { - lastOffButtonState = BUTTON_STATE_RELEASED; + alarmStopSignalled = FALSE; + signalStopTreatmentRecirc(); } + execTreatmentRecirc(); + return result; } Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -22,27 +22,67 @@ #include "DialInFlow.h" #include "DialOutFlow.h" #include "ModeTreatment.h" +#include "ModeTreatmentParams.h" #include "OperationModes.h" #include "Rinseback.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "TreatmentStop.h" #include "Valves.h" /** * @addtogroup Rinseback * @{ */ +// ********** private definitions ********** + +#define TARGET_RINSEBACK_VOLUME_ML 300.0 ///< Target rinseback volume to deliver back to the patient (in mL). +#define RINSEBACK_FLOW_RATE_ADJ_ML_MIN 25.0 ///< Adjustment amount (in mL/min) to apply when user requests increase/decrease in flow rate. +#define MIN_RINSEBACK_FLOW_RATE_ML_MIN 50.0 ///< Minimum rinseback flow rate (in mL/min). +#define MAX_RINSEBACK_FLOW_RATE_ML_MIN 150.0 ///< Maximum rinseback flow rate (in mL/min). + +static const F32 RINSEBACK_FLOW_INTEGRATOR = 1.0 / (F32)( SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); + // ********** private data ********** static RINSEBACK_STATE_T rinsebackState; ///< Current state of the rinseback sub-mode. +static F32 cumulativeRinsebackVolume_mL; ///< Total cumulative rinseback volume (in mL). + +static BOOL rinsebackStopRequested; ///< Flag indicates alarm requesting to stop rinseback. +static BOOL startRinsebackRequested; ///< Flag indicates user requesting rinseback start (confirming saline bag move to arterial line end). +static BOOL incrRinsebackFlowRateRequested; ///< Flag indicates user requesting rinseback flow rate be increased. +static BOOL decrRinsebackFlowRateRequested; ///< Flag indicates user requesting rinseback flow rate be decreased. +static BOOL pauseRinsebackRequested; ///< Flag indicates user requesting rinseback pause. +static BOOL resumeRinsebackRequested; ///< Flag indicates user requesting rinseback resume. +static BOOL endRinsebackRequested; ///< Flag indicates user requesting to end rinseback operation. +static BOOL additionalRinsebackRequested; ///< Flag indicates user requesting a little more rinseback volume. +static BOOL recircRequested; ///< Flag indicates user requesting to begin re-circulation (confirming disconnection and shunt). +static BOOL backToTreatmentRequested; ///< Flag indicates user requesting to go back to treatment (confirming still connected). +static BOOL endTreatmentRequested; ///< Flag indicates user requesting to end treatment. + // ********** private function prototypes ********** +static void resetRinsebackFlags( void ); + static RINSEBACK_STATE_T handleRinsebackStopInitState( void ); static RINSEBACK_STATE_T handleRinsebackRunState( void ); static RINSEBACK_STATE_T handleRinsebackPausedState( void ); static RINSEBACK_STATE_T handleRinsebackStoppedState( void ); static RINSEBACK_STATE_T handleRinsebackRunAdditionalState( void ); +static BOOL handleStartRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleIncrRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleDecrRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handlePauseRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleResumeRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleEndRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleAdditionalRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleToRecircUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleBackToTreatmentUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleEndTreatmentUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); + /*********************************************************************//** * @brief * The initRinseback function initializes the Rinseback sub-mode module. @@ -53,10 +93,34 @@ void initRinseback( void ) { rinsebackState = RINSEBACK_STOP_INIT_STATE; + cumulativeRinsebackVolume_mL = 0.0; + resetRinsebackFlags(); } /*********************************************************************//** * @brief + * The resetRinsebackFlags function resets the Rinseback request flags. + * @details Inputs: none + * @details Outputs: Rinseback request flags reset to FALSE. + * @return none + *************************************************************************/ +static void resetRinsebackFlags( void ) +{ + rinsebackStopRequested = FALSE; + startRinsebackRequested = FALSE; + incrRinsebackFlowRateRequested = FALSE; + decrRinsebackFlowRateRequested = FALSE; + pauseRinsebackRequested = FALSE; + resumeRinsebackRequested = FALSE; + endRinsebackRequested = FALSE; + additionalRinsebackRequested = FALSE; + recircRequested = FALSE; + backToTreatmentRequested = FALSE; + endTreatmentRequested = FALSE; +} + +/*********************************************************************//** + * @brief * The transitionToRinseback function prepares for transition to Rinseback * sub-mode. * @details Inputs: none @@ -125,36 +189,102 @@ // TODO - s/w fault break; } + + // Rinseback flags should be handled by now - reset in case not handled by current state + resetRinsebackFlags(); } +/*********************************************************************//** + * @brief + * The handleRinsebackStopInitState function handles the stopped initial + * rinseback state operations. + * @details Inputs: none + * @details Outputs: none + * @return next rinseback state + *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackStopInitState( void ) { RINSEBACK_STATE_T result = RINSEBACK_STOP_INIT_STATE; return result; } +/*********************************************************************//** + * @brief + * The handleRinsebackRunState function handles the rinseback run state + * operations. + * @details Inputs: none + * @details Outputs: none + * @return next rinseback state + *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackRunState( void ) { RINSEBACK_STATE_T result = RINSEBACK_RUN_STATE; + // TODO - update rinseback volume + cumulativeRinsebackVolume_mL += ( getMeasuredBloodFlowRate() * RINSEBACK_FLOW_INTEGRATOR ); + + // Has rinseback completed? + if ( cumulativeRinsebackVolume_mL <= TARGET_RINSEBACK_VOLUME_ML ) + { + setRinsebackIsCompleted( TRUE ); + result = RINSEBACK_STOP_STATE; + } + // Has user or alarm requested rinseback pause? + else if ( ( TRUE == rinsebackStopRequested ) || ( TRUE == isAnyAlarmActive() ) ) + { + result = RINSEBACK_PAUSED_STATE; + } + // Otherwise, continue rinseback + else + { // Has user requested rate change? + if ( ( TRUE == incrRinsebackFlowRateRequested ) || ( TRUE == incrRinsebackFlowRateRequested ) ) + { + // TODO - update rate if within limits + } + } + return result; } +/*********************************************************************//** + * @brief + * The handleRinsebackStopInitState function handles the rinseback paused + * state operations. + * @details Inputs: none + * @details Outputs: none + * @return next rinseback state + *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackPausedState( void ) { RINSEBACK_STATE_T result = RINSEBACK_PAUSED_STATE; return result; } +/*********************************************************************//** + * @brief + * The handleRinsebackStoppedState function handles the stopped rinseback + * state operations. + * @details Inputs: none + * @details Outputs: none + * @return next rinseback state + *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackStoppedState( void ) { RINSEBACK_STATE_T result = RINSEBACK_STOP_STATE; return result; } +/*********************************************************************//** + * @brief + * The handleRinsebackRunAdditionalState function handles the rinseback additional + * state operations. + * @details Inputs: none + * @details Outputs: none + * @return next rinseback state + *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackRunAdditionalState( void ) { RINSEBACK_STATE_T result = RINSEBACK_RUN_ADDITIONAL_STATE; @@ -167,16 +297,375 @@ * The signalStopRinseback function signals the rinseback sub-mode * to stop per an active alarm. * @details Inputs: none - * @details Outputs: none + * @details Outputs: rinsebackStopRequested * @return none *************************************************************************/ void signalStopRinseback( void ) { + rinsebackStopRequested = TRUE; +} +/*********************************************************************//** + * @brief + * The signalRinsebackUserAction function signals a rinseback user action + * has been requested. The request is handled and responded to. + * @details Inputs: none + * @details Outputs: none + * @param action User action requested + * @return none + *************************************************************************/ +void signalRinsebackUserAction( REQUESTED_RINSEBACK_USER_ACTIONS_T action ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + + // Reject user action requests if any alarm is currently active. User must clear alarm first. + if ( FALSE == isAnyAlarmActive() ) + { + switch ( action ) + { + case REQUESTED_USER_ACTION_RINSEBACK_CONFIRM_START: + accepted = handleStartRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_INCREASE_RATE: + accepted = handleIncrRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_DECREASE_RATE: + accepted = handleDecrRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_PAUSE: + accepted = handlePauseRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_RESUME: + accepted = handleResumeRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_END: + accepted = handleEndRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_ADDITIONAL: + accepted = handleAdditionalRinsebackUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_CONFIRM_DISCONNECT: + accepted = handleToRecircUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_END_TREATMENT: + accepted = handleBackToTreatmentUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_RINSEBACK_BACK_TO_TREATMENT: + accepted = handleEndTreatmentUserAction( &rejReason ); + break; + + default: + rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; + break; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_ALARM_IS_ACTIVE; + } + + // Respond to user action request + sendRinsebackCmdResponse( accepted, (U32)rejReason ); } /*********************************************************************//** * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleStartRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( RINSEBACK_STOP_INIT_STATE == rinsebackState ) + { + result = TRUE; + startRinsebackRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleIncrRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + F32 rbRate = (F32)getTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ); + + if ( ( rbRate + RINSEBACK_FLOW_RATE_ADJ_ML_MIN ) <= MAX_RINSEBACK_FLOW_RATE_ML_MIN ) + { + if ( RINSEBACK_RUN_STATE == rinsebackState ) + { + result = TRUE; + incrRinsebackFlowRateRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + } + else + { + *rejReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleDecrRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + F32 rbRate = (F32)getTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ); + + if ( ( rbRate + RINSEBACK_FLOW_RATE_ADJ_ML_MIN ) >= MIN_RINSEBACK_FLOW_RATE_ML_MIN ) + { + if ( RINSEBACK_RUN_STATE == rinsebackState ) + { + result = TRUE; + decrRinsebackFlowRateRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + } + else + { + *rejReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handlePauseRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( RINSEBACK_RUN_STATE == rinsebackState ) + { + result = TRUE; + pauseRinsebackRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleResumeRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( RINSEBACK_PAUSED_STATE == rinsebackState ) + { + result = TRUE; + resumeRinsebackRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleEndRinsebackUserAction function handles an end rinseback + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleEndRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( ( RINSEBACK_RUN_STATE == rinsebackState ) || ( RINSEBACK_PAUSED_STATE == rinsebackState ) ) + { + result = TRUE; + endRinsebackRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleAdditionalRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( RINSEBACK_STOP_STATE == rinsebackState ) + { + result = TRUE; + additionalRinsebackRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * 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: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleToRecircUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( RINSEBACK_STOP_STATE == rinsebackState ) + { + result = TRUE; + recircRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleBackToTreatmentUserAction function handles a back to treatment + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleBackToTreatmentUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( ( RINSEBACK_STOP_INIT_STATE == rinsebackState ) || ( RINSEBACK_STOP_STATE == rinsebackState ) ) + { + result = TRUE; + backToTreatmentRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleEndTreatmentUserAction function handles an end treatment + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleEndTreatmentUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( ( RINSEBACK_STOP_INIT_STATE == rinsebackState ) || ( RINSEBACK_STOP_STATE == rinsebackState ) ) + { + result = TRUE; + endTreatmentRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The getCurrentRinsebackState function returns the current state of the * rinseback sub-mode. * @details Inputs: rinsebackState Index: firmware/App/Modes/Rinseback.h =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Modes/Rinseback.h (.../Rinseback.h) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Modes/Rinseback.h (.../Rinseback.h) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -38,7 +38,8 @@ void transitionToRinseback( void ); void execRinseback( void ); -void signalStopRinseback( void ); +void signalStopRinseback( void ); // from alarm +void signalRinsebackUserAction( REQUESTED_RINSEBACK_USER_ACTIONS_T action ); // from user RINSEBACK_STATE_T getCurrentRinsebackState( void ); /**@}*/ Index: firmware/App/Modes/TreatmentRecirc.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Modes/TreatmentRecirc.c (.../TreatmentRecirc.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Modes/TreatmentRecirc.c (.../TreatmentRecirc.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -23,6 +23,8 @@ #include "DialOutFlow.h" #include "ModeTreatment.h" #include "OperationModes.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" #include "TreatmentRecirc.h" #include "Valves.h" @@ -31,15 +33,38 @@ * @{ */ +// ********** private definitions ********** + +/// Alarm if re-circulation is running for this much time. TODO - finalize these times w/ Systems +#define RECIRC_TIMEOUT_MS ( ( 15 * 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) +/// Alarm if re-circulation is stopped for this much time. +#define RECIRC_STOP_TIMEOUT_MS ( ( 15 * 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) + // ********** private data ********** -static TREATMENT_RECIRC_STATE_T treatmentRecircState; ///< Current state of the treatment re-circulate sub-mode. +static TREATMENT_RECIRC_STATE_T treatmentRecircState; ///< Current state of the treatment re-circulate sub-mode. +static U32 recircTimerCtr; ///< Timer counter (in GP task intervals) that re-circulation is running. +static U32 recircStoppedTimerCtr; ///< Timer counter (in GP task intervals) that re-circulation is stopped. + +static BOOL recircStopRequested; ///< Flag indicates alarm requesting to stop rinseback. +static BOOL recircReconnectRequested; ///< Flag indicates user requesting re-circulate stop so they can re-connect. +static BOOL recircBackToTreatmenRequested; ///< Flag indicates user requesting to go back to treatment (confirming re-connected). +static BOOL recircResumeRequested; ///< Flag indicates user requesting resumption of re-circulating. +static BOOL recircEndTreatmentRequested; ///< Flag indicates user requesting end of treatment. + // ********** private function prototypes ********** +static void resetTreatmentRecircFlags( void ); + static TREATMENT_RECIRC_STATE_T handleRecircRecircState( void ); static TREATMENT_RECIRC_STATE_T handleRecircStoppedState( void ); +static BOOL handleRecircReconnectUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleRecicConfirmReconnectUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleRecircResumeUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); +static BOOL handleRecircEndTreatmentUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); + /*********************************************************************//** * @brief * The initTreatmentRecirc function initializes the Treatment Re-circulate sub-mode @@ -51,10 +76,29 @@ void initTreatmentRecirc( void ) { treatmentRecircState = TREATMENT_RECIRC_RECIRC_STATE; + recircTimerCtr = 0; + recircStoppedTimerCtr = 0; + resetTreatmentRecircFlags(); } /*********************************************************************//** * @brief + * The resetRinsebackFlags function resets the Rinseback request flags. + * @details Inputs: none + * @details Outputs: Rinseback request flags reset to FALSE. + * @return none + *************************************************************************/ +static void resetTreatmentRecircFlags( void ) +{ + recircStopRequested = FALSE; + recircReconnectRequested = FALSE; + recircBackToTreatmenRequested = FALSE; + recircResumeRequested = FALSE; + recircEndTreatmentRequested = FALSE; +} + +/*********************************************************************//** + * @brief * The transitionToTreatmentRecirc function prepares for transition to treatment * re-circulate sub-mode. * @details Inputs: none @@ -72,8 +116,8 @@ setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); // Reset saline bolus state in case alarm interrupted one resetSalineBolus(); - // Stop air trap control - endAirTrapControl(); + // Start air trap control + startAirTrapControl(); // Should always have stopped alarm active in treatment stop sub-mode so that user can take action activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); @@ -107,19 +151,84 @@ // TODO - s/w fault break; } + + // Re-circulate flags should be handled by now - reset in case not handled by current state + resetTreatmentRecircFlags(); } +/*********************************************************************//** + * @brief + * The handleRecircRecircState function handles the re-circulating state + * operations. + * @details Inputs: none + * @details Outputs: none + * @return next treatment re-circulation state + *************************************************************************/ static TREATMENT_RECIRC_STATE_T handleRecircRecircState( void ) { TREATMENT_RECIRC_STATE_T result = TREATMENT_RECIRC_RECIRC_STATE; + // TODO - update timer on this state + recircTimerCtr++; + + // is stop or reconnect requested or max re-circ time exceeded? + if ( ( TRUE == recircStopRequested ) || ( TRUE == recircReconnectRequested ) || ( recircTimerCtr > RECIRC_TIMEOUT_MS ) ) + { + // TODO stop BP, close VBA and VBV + result = TREATMENT_RECIRC_STOPPED_STATE; + } + // is end treatment requested? + else if ( TRUE == recircEndTreatmentRequested ) + { + // TODO stop BP, close VBA and VBV + endAirTrapControl(); + // TODO - signal end Tx sub-mode + } + return result; } +/*********************************************************************//** + * @brief + * The handleRecircStoppedState function handles the re-circulation stopped + * state operations. + * @details Inputs: none + * @details Outputs: none + * @return next Treatment re-circulation state + *************************************************************************/ static TREATMENT_RECIRC_STATE_T handleRecircStoppedState( void ) { TREATMENT_RECIRC_STATE_T result = TREATMENT_RECIRC_STOPPED_STATE; + // TODO - update timer on this state + recircStoppedTimerCtr++; + + // is back to treatment requested? + if ( TRUE == recircBackToTreatmenRequested ) + { + // TODO - signal return to treatment stop sub-mode + } + // is end treatment requested? + else if ( TRUE == recircEndTreatmentRequested ) + { + // TODO - signal end Tx sub-mode + } + // is re-circ resume requested? + else if ( TRUE == recircResumeRequested ) + { + // TODO start BP, open VBA and VBV + startAirTrapControl(); + result = TREATMENT_RECIRC_RECIRC_STATE; + } + else + { + // is max re-circ stopped time exceeded? + if ( recircStoppedTimerCtr > RECIRC_STOP_TIMEOUT_MS ) + { + // TODO - alarm + } + } + return result; } @@ -133,11 +242,168 @@ *************************************************************************/ void signalStopTreatmentRecirc( void ) { + recircStopRequested = TRUE; +} +/*********************************************************************//** + * @brief + * The signalTreatmentRecircUserAction function signals a re-circ user action + * has been requested. The request is handled and responded to. + * @details Inputs: none + * @details Outputs: none + * @param action User action requested + * @return none + *************************************************************************/ +void signalTreatmentRecircUserAction( REQUESTED_TREATMENT_RECIRC_USER_ACTIONS_T action ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + + // Reject user action requests if any alarm is currently active. User must clear alarm first. + if ( FALSE == isAnyAlarmActive() ) + { + switch ( action ) + { + case REQUESTED_USER_ACTION_TX_RECIRC_RECONNECT: + accepted = handleRecircReconnectUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_TX_RECIRC_CONFIRM_RECONNECT: + accepted = handleRecicConfirmReconnectUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_TX_RECIRC_RESUME_RC: + accepted = handleRecircResumeUserAction( &rejReason ); + break; + + case REQUESTED_USER_ACTION_TX_RECIRC_END_TREATMENT: + accepted = handleRecircEndTreatmentUserAction( &rejReason ); + break; + + default: + rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; + break; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_ALARM_IS_ACTIVE; + } + + // Respond to user action request + sendRinsebackCmdResponse( accepted, (U32)rejReason ); } /*********************************************************************//** * @brief + * The handleRecircReconnectUserAction function handles a re-circulate re-connect + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleRecircReconnectUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( TREATMENT_RECIRC_RECIRC_STATE == treatmentRecircState ) + { + result = TRUE; + recircReconnectRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleRecicConfirmReconnectUserAction function handles a re-circulate + * back to treatment user action request. It is assumed that the calling + * function will set the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleRecicConfirmReconnectUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( TREATMENT_RECIRC_STOPPED_STATE == treatmentRecircState ) + { + result = TRUE; + recircBackToTreatmenRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleRecircResumeUserAction function handles a re-circulate resume + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleRecircResumeUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( TREATMENT_RECIRC_STOPPED_STATE == treatmentRecircState ) + { + result = TRUE; + recircResumeRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleRecircEndTreatmentUserAction function handles an e reatment + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: none + * @details Outputs: none + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleRecircEndTreatmentUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( ( TREATMENT_RECIRC_RECIRC_STATE == treatmentRecircState ) || ( TREATMENT_RECIRC_STOPPED_STATE == treatmentRecircState ) ) + { + result = TRUE; + recircEndTreatmentRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The getCurrentTreatmentRecircState function returns the current state of the * treatment re-circulate sub-mode. * @details Inputs: treatmentRecircState Index: firmware/App/Modes/TreatmentRecirc.h =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Modes/TreatmentRecirc.h (.../TreatmentRecirc.h) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Modes/TreatmentRecirc.h (.../TreatmentRecirc.h) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -37,7 +37,8 @@ void transitionToTreatmentRecirc( void ); void execTreatmentRecirc( void ); -void signalStopTreatmentRecirc( void ); +void signalStopTreatmentRecirc( void ); // from alarm +void signalTreatmentRecircUserAction( REQUESTED_TREATMENT_RECIRC_USER_ACTIONS_T action ); // from user TREATMENT_RECIRC_STATE_T getCurrentTreatmentRecircState( void ); /**@}*/ Index: firmware/App/Modes/TreatmentStop.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -62,10 +62,18 @@ resetSalineBolus(); // Stop air trap control endAirTrapControl(); - // Should always have stopped alarm active in treatment stop sub-mode so that user can take action - if ( FALSE == isAlarmActive( ALARM_ID_TREATMENT_STOPPED_BY_USER ) ) + // Should always have an alarm active in treatment stop sub-mode so that user can take action + if ( FALSE == isAnyAlarmActive() ) { - activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); + if ( FALSE == getRinsebackCompleted() ) + { + activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_AFTER_RINSEBACK ); + } + else + { + activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); + } + // coming back to stop state via non-alarm path, so no audio - just want alarm for its options signalAlarmSilence( ALARM_SILENCE_CMD_CANCEL ); } Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -192,7 +192,12 @@ { // No need to do anything if alarm is already active if ( FALSE == alarmIsActive[ alarm ] ) - { + { + // If alarm status was that no alarms currently active, set this alarm as top alarm until status formally updated later + if ( ALARM_ID_NO_ALARM == alarmStatus.alarmTop ) + { + alarmStatus.alarmTop = alarm; + } // If alarms silenced, end silence due to new alarm alarmStatus.alarmsSilenced = FALSE; // If alarm is a fault, request transition to fault mode @@ -527,6 +532,21 @@ /*********************************************************************//** * @brief + * The isAnyAlarmActive function determines whether any alarm is currently + * active. + * @details Inputs: alarmStatus + * @details Outputs: none + * @return TRUE if any alarm is active, FALSE if not + *************************************************************************/ +BOOL isAnyAlarmActive( void ) +{ + BOOL result = ( alarmStatus.alarmTop != ALARM_ID_NO_ALARM ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief * The getCurrentAlarmStatePriority function determines the current alarm * state priority (NONE, LOW, MEDIUM, or HIGH). * @details Inputs: alarmStatus Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -255,6 +255,7 @@ void signalAlarmSilence( ALARM_SILENCE_CMD_T cmd ); void signalAlarmUserActionInitiated( ALARM_USER_ACTION_T action ); BOOL isAlarmActive( ALARM_ID_T alarm ); +BOOL isAnyAlarmActive( void ); ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ); BOOL isAlarmRecoverable( ALARM_ID_T alarm ); void setAlarmAudioVolume( U32 volumeLevel ); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -1195,6 +1195,14 @@ handleUFVolumeSetRequest( message ); break; + case MSG_ID_UI_RINSEBACK_CMD: + handlRinsebackCmd( message ); + break; + + case MSG_ID_UI_RECIRC_CMD: + handleTreatmentRecircCmd( message ); + break; + case MSG_ID_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -1998,6 +1998,119 @@ result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); return result; +} + +/*********************************************************************//** + * @brief + * The handlRinsebackCmd function handles a rinseback user action command + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handlRinsebackCmd( MESSAGE_T *message ) +{ + if ( sizeof(U32) == message->hdr.payloadLen ) + { + U32 cmd; + + memcpy( &cmd, &message->payload[0], sizeof(U32) ); + + signalRinsebackUserAction( (REQUESTED_RINSEBACK_USER_ACTIONS_T)cmd ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The sendRinsebackCmdResponse function constructs a rinseback user action + * response to the UI and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Rinseback command response msg constructed and queued. + * @param accepted T/F - was rinseback user action accepted? + * @param rejReason reason why action was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendRinsebackCmdResponse( BOOL accepted, U32 rejReason ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RINSEBACK_CMD_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // 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_2_UI, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentRecircCmd function handles a treatment re-circ user action command + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTreatmentRecircCmd( MESSAGE_T *message ) +{ + if ( sizeof(U32) == message->hdr.payloadLen ) + { + U32 cmd; + + memcpy( &cmd, &message->payload[0], sizeof(U32) ); + + signalTreatmentRecircUserAction( (REQUESTED_TREATMENT_RECIRC_USER_ACTIONS_T)cmd ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The sendTreatmentRecircCmdResponse function constructs a treatment re-circulation + * user action response to the UI and queues the msg for transmit on the appropriate + * CAN channel. + * @details Inputs: none + * @details Outputs: Treatment re-circ command response msg constructed and queued. + * @param accepted T/F - was re-circ user action accepted? + * @param rejReason reason why action was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTreatmentRecircCmdResponse( BOOL accepted, U32 rejReason ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RECIRC_CMD_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // 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_2_UI, ACK_REQUIRED ); + + return result; } /*********************************************************************//** Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rfa356a2bce909141f45c6832659fa1ceea5bfbba -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision fa356a2bce909141f45c6832659fa1ceea5bfbba) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) @@ -156,6 +156,18 @@ // MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE BOOL sendPressureLimitsChangeResponse( PRESSURE_LIMIT_CHANGE_RESPONSE_T *data ); +// MSG_ID_UI_RINSEBACK_CMD +void handlRinsebackCmd( MESSAGE_T *message ); + +// MSG_ID_HD_RINSEBACK_CMD_RESPONSE +BOOL sendRinsebackCmdResponse( BOOL accepted, U32 rejReason ); + +// MSG_ID_UI_RECIRC_CMD +void handleTreatmentRecircCmd( MESSAGE_T *message ); + +// MSG_ID_HD_RECIRC_CMD_RESPONSE +BOOL sendTreatmentRecircCmdResponse( BOOL accepted, U32 rejReason ); + // MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS BOOL sendDialysateTempTargetsToDG( F32 primary, F32 trimmer );