Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r7a7bf19d0cf16745566956f45cef57f8eb5df445 -r8466e63f95f65a3ffb18c3af85ac99328e41167b --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 7a7bf19d0cf16745566956f45cef57f8eb5df445) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 8466e63f95f65a3ffb18c3af85ac99328e41167b) @@ -17,6 +17,7 @@ #include "AirTrap.h" #include "AlarmLamp.h" +#include "Battery.h" #include "BloodFlow.h" #include "Buttons.h" #include "DGInterface.h" @@ -32,6 +33,7 @@ #include "SystemComm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" +#include "Timers.h" #ifdef EMC_TEST_BUILD // TODO - test code #include "FPGA.h" #endif @@ -47,20 +49,26 @@ // ********** private data ********** -static HD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. +static HD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. -static BOOL treatStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of a treatment +static BOOL treatStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of a treatment. +static BOOL flushStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of flush mode. +static BOOL heatDisinfectStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of heat disinfect mode. +static BOOL chemDisinfectStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of chemical disinfect mode. +static BOOL hasDisinfectCmdBeenSet = FALSE; ///< Flag indicates that a disinfect command has been set. +static DG_DISINFECT_STATE_T dgDisinfectState; ///< DG disinfect state to be boadcast to UI. -static U32 dataPublishCounter = 0; ///< Disinfects data publish counter. +static U32 dataPublishCounter = 0; ///< Disinfects data publish counter. /// Interval (in task intervals) at which to publish standby mode data to CAN bus. static OVERRIDE_U32_T standbyModePublishInterval = { DISINFECTS_DATA_PUB_INTERVAL, DISINFECTS_DATA_PUB_INTERVAL, DISINFECTS_DATA_PUB_INTERVAL, 0 }; // ********** private function prototypes ********** -static HD_STANDBY_STATE_T handleStandbyWait4TreatmentState( void ); -static HD_STANDBY_STATE_T handleStandbyDGFlushState( void ); -static HD_STANDBY_STATE_T handleStandbyDGHeatDisinfectState( void ); -static HD_STANDBY_STATE_T handleStandbyDGChemDisinfectState( void ); +static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ); +static HD_STANDBY_STATE_T handleStandbyModeWaitForDisinfectState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGFlushInProgressState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGHeatDisinfectInProgressState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ); static void publishDisinfectData( void ); @@ -73,8 +81,12 @@ *************************************************************************/ void initStandbyMode( void ) { - currentStandbyState = STANDBY_START_STATE; - treatStartReqReceived = FALSE; + currentStandbyState = STANDBY_START_STATE; + treatStartReqReceived = FALSE; + flushStartReqReceived = FALSE; + dataPublishCounter = 0; + hasDisinfectCmdBeenSet = FALSE; + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; } /*********************************************************************//** @@ -127,20 +139,27 @@ break; case STANDBY_WAIT_FOR_TREATMENT_STATE: - currentStandbyState = handleStandbyWait4TreatmentState(); + currentStandbyState = handleStandbyModeWaitForTreatmentState(); break; + case STANDBY_WAIT_FOR_DISINFECT_STATE: + currentStandbyState = handleStandbyModeWaitForDisinfectState(); + break; + case STANDBY_DG_FLUSH_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGFlushInProgressState(); break; case STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGHeatDisinfectInProgressState(); break; case STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGChemDisininfectInProgressState(); break; default: - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); currentStandbyState = STANDBY_START_STATE; break; } @@ -229,7 +248,7 @@ break; default: - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); currentStandbyState = STANDBY_START_STATE; break; } @@ -240,91 +259,184 @@ /*********************************************************************//** * @brief - * The handleStandbyWait4TreatmentState function handles the wait for - * treatment state for standby mode. - * @details Inputs: treatStartReqReceived - * @details Outputs: treatment may be initiated - * @return next standby state + * The signalUserInitiateTreatment function handles user initiation of a + * treatment. + * @details Inputs: none + * @details Outputs: treatStartReqReceived + * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -static HD_STANDBY_STATE_T handleStandbyWait4TreatmentState( void ) +BOOL signalUserInitiateTreatment( void ) { - HD_STANDBY_STATE_T result = STANDBY_WAIT_FOR_TREATMENT_STATE; + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; - if ( TRUE == treatStartReqReceived ) + if ( TRUE == getNoNewTreatmentStatus() ) { - // Initialize treatment modes before starting a new treatment - initTreatParamsMode(); - initPreTreatmentMode(); - initTreatmentMode(); - initPostTreatmentMode(); - // Start treatment workflow with treatment parameters mode - requestNewOperationMode( MODE_TPAR ); - treatStartReqReceived = FALSE; + rejReason = REQUEST_REJECT_REASON_NO_NEW_TREATMENT_ALARM_TRIGGERED; } + if ( ( MODE_STAN != getCurrentOperationMode() ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE != currentStandbyState ) ) + { + rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + } + + if ( TRUE != isDGCommunicating() ) + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + + if ( ( DG_MODE_STAN != getDGOpMode() ) || ( DG_STANDBY_MODE_STATE_IDLE != getDGSubMode() ) ) + { + rejReason = REQUEST_REJECT_REASON_DG_NOT_IN_STANDBY_IDLE_STATE; + } + + if ( FALSE == isBatteryCharged() ) + { + rejReason = REQUEST_REJECT_REASON_BATTERY_IS_NOT_CHARGED; + } + + if ( REQUEST_REJECT_REASON_NONE == rejReason ) + { + result = TRUE; + treatStartReqReceived = TRUE; + } + + sendInitiateTreatmentResponseMsg( result, rejReason ); + return result; } /*********************************************************************//** * @brief - * The handleStandbyDGFlushState function handles the DG flush state for - * standby mode. - * @details Inputs: - * @details Outputs: - * @return next standby state + * The signalAlarmActionToStandbyMode function executes the given alarm action + * as appropriate while in Standby Mode. + * @details Inputs: none + * @details Outputs: given alarm action executed + * @param action ID of alarm action to execute + * @return none *************************************************************************/ -static HD_STANDBY_STATE_T handleStandbyDGFlushState( void ) +void signalAlarmActionToStandbyMode( ALARM_ACTION_T action ) { - HD_STANDBY_STATE_T result = STANDBY_DG_FLUSH_IN_PROGRESS_STATE; + // Alarm actions not handled in Standby mode +} - // TODO - implement w/ UI +/*********************************************************************//** + * @brief + * The signalUserInitiateFlushMode function handles user initiation of flush + * mode. + * @details Inputs: currentStandbyState + * @details Outputs: flushStartReqReceived + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateFlushMode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + if ( MODE_STAN == getCurrentOperationMode() ) + { + if ( ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + flushStartReqReceived = TRUE; + result = TRUE; + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + return result; } /*********************************************************************//** * @brief - * The handleStandbyDGHeatDisinfectState function handles the wait for - * treatment state for standby mode. - * @details Inputs: - * @details Outputs: - * @return next standby state + * The signalUserInitiateFlushMode function handles user initiation of heat + * disinfect mode. + * @details Inputs: currentStandbyState + * @details Outputs: heatDisinfectStartReqReceived + * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -static HD_STANDBY_STATE_T handleStandbyDGHeatDisinfectState( void ) +BOOL signalUserInitiateHeatDisinfectMode( void ) { - HD_STANDBY_STATE_T result = STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE; + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; - // TODO - implement w/ UI + if ( MODE_STAN == getCurrentOperationMode() ) + { + if ( ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + heatDisinfectStartReqReceived = TRUE; + result = TRUE; + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + } + sendDisinfectConfirmResponse( result, rejReason ); + return result; } /*********************************************************************//** * @brief - * The handleStandbyDGChemDisinfectState function handles the wait for - * treatment state for standby mode. - * @details Inputs: - * @details Outputs: - * @return next standby state + * The signalUserInitiateChemicalDisinfectMode function handles user + * initiation of chemical disinfect mode. + * @details Inputs: currentStandbyState + * @details Outputs: chemDisinfectStartReqReceived + * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -static HD_STANDBY_STATE_T handleStandbyDGChemDisinfectState( void ) +BOOL signalUserInitiateChemicalDisinfectMode( void ) { - HD_STANDBY_STATE_T result = STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE; + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; - // TODO - implement w/ UI + if ( MODE_STAN == getCurrentOperationMode() ) + { + if ( ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + chemDisinfectStartReqReceived = TRUE; + result = TRUE; + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + } + sendDisinfectConfirmResponse( result, rejReason ); + return result; } /*********************************************************************//** * @brief - * The signalUserInitiateTreatment function handles user initiation of a - * treatment. - * @details Inputs: none - * @details Outputs: treatStartReqReceived + * The signalInitiateStandbyDisinfectSubmode function handles user + * initiation of setting the disinfects submode. + * @details Inputs: currentStandbyState + * @details Outputs: currentStandbyState * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -BOOL signalUserInitiateTreatment( void ) +BOOL signalInitiateStandbyDisinfectSubmode( void ) { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; @@ -333,7 +445,7 @@ { if ( TRUE == isDGCommunicating() ) { - treatStartReqReceived = TRUE; + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; result = TRUE; rejReason = REQUEST_REJECT_REASON_NONE; } @@ -343,27 +455,183 @@ } } - sendInitiateTreatmentResponseMsg( result, rejReason ); + sendDisinfectConfirmResponse( result, rejReason ); return result; } +// ********** private functions ********** + /*********************************************************************//** * @brief - * The signalAlarmActionToStandbyMode function executes the given alarm action - * as appropriate while in Standby Mode. + * The handleStandbyModeWaitForTreatmentState function handles wait for + * treatment state. + * @details Inputs: treatStartReqReceived + * @details Outputs: treatStartReqReceived + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; + DG_OP_MODE_T dgOperationMode = getDGOpMode(); + + if ( DG_MODE_FILL == dgOperationMode ) + { + cmdStopDGFill(); + } + + if ( DG_MODE_CIRC == dgOperationMode ) + { + cmdStopDG(); + } + + if ( TRUE == treatStartReqReceived ) + { + // Initialize treatment modes before starting a new treatment + initTreatParamsMode(); + initPreTreatmentMode(); + initTreatmentMode(); + initPostTreatmentMode(); + // Start treatment workflow with treatment parameters mode + requestNewOperationMode( MODE_TPAR ); + treatStartReqReceived = FALSE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeWaitForDisinfectState function handles wait for + * disinfect state. + * @details Inputs: flushStartReqReceived, heatDisinfectStartReqReceived, + * chemDisinfectStartReqReceived, hasDisinfectCmdBeenSet + * @details Outputs: flushStartReqReceived, heatDisinfectStartReqReceived, + * chemDisinfectStartReqReceived, hasDisinfectCmdBeenSet, dgDisinfectState, + * currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeWaitForDisinfectState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DISINFECT_STATE; + + if ( TRUE == flushStartReqReceived ) + { + if ( FALSE == hasDisinfectCmdBeenSet ) + { + cmdStartDGFlush(); + hasDisinfectCmdBeenSet = TRUE; + } + else if ( DG_MODE_FLUS == getDGOpMode() ) + { + hasDisinfectCmdBeenSet = FALSE; + flushStartReqReceived = FALSE; + dgDisinfectState = DG_DISINFECT_FLUSH_STATE; + state = STANDBY_DG_FLUSH_IN_PROGRESS_STATE; + } + } + else if ( TRUE == heatDisinfectStartReqReceived ) + { + if ( FALSE == hasDisinfectCmdBeenSet ) + { + cmdStartDGHeatDisinfect(); + hasDisinfectCmdBeenSet = TRUE; + } + else if ( DG_MODE_HEAT == getDGOpMode() ) + { + hasDisinfectCmdBeenSet = FALSE; + heatDisinfectStartReqReceived = FALSE; + dgDisinfectState = DG_DISINFECT_HEAT_STATE; + state = STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE; + } + } + else if ( TRUE == chemDisinfectStartReqReceived ) + { + if ( FALSE == hasDisinfectCmdBeenSet ) + { + cmdStartDGChemicalDisinfect(); + hasDisinfectCmdBeenSet = TRUE; + } + else if ( DG_MODE_CHEM == getDGOpMode() ) + { + hasDisinfectCmdBeenSet = FALSE; + chemDisinfectStartReqReceived = FALSE; + dgDisinfectState = DG_DISINFECT_CHEM_STATE; + state = STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGFlushInProgressState function handles DG flush + * in progress state. * @details Inputs: none - * @details Outputs: given alarm action executed - * @param action ID of alarm action to execute - * @return none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine *************************************************************************/ -void signalAlarmActionToStandbyMode( ALARM_ACTION_T action ) +static HD_STANDBY_STATE_T handleStandbyModeDGFlushInProgressState( void ) { - // Alarm actions not handled in Standby mode + HD_STANDBY_STATE_T state = STANDBY_DG_FLUSH_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_FLUS ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + state = STANDBY_WAIT_FOR_TREATMENT_STATE; + } + publishDisinfectData(); + + return state; } /*********************************************************************//** * @brief + * The handleStandbyModeDGHeatDisinfectInProgressState function handles DG + * heat disinfect in progress state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGHeatDisinfectInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_HEAT ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + state = STANDBY_WAIT_FOR_TREATMENT_STATE; + } + publishDisinfectData(); + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGChemDisininfectInProgressState function handles + * DG chemical disinfect in progress state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_CHEM ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + state = STANDBY_WAIT_FOR_TREATMENT_STATE; + } + publishDisinfectData(); + + return state; +} + +/*********************************************************************//** + * @brief * The publishDisinfectData function publishes disinfects data at * the set interval. * @details Inputs: dataPublishCounter @@ -372,10 +640,31 @@ *************************************************************************/ static void publishDisinfectData( void ) { - if ( ++dataPublishCounter > getU32OverrideValue( &standbyModePublishInterval ) ) + if ( ++dataPublishCounter > DISINFECTS_DATA_PUB_INTERVAL ) { + DG_DISINFECT_UI_STATES_T state = getDGDisinfectsStates(); + DISINFECTS_DATA_T data; + + switch( currentStandbyState ) + { + case STANDBY_DG_FLUSH_IN_PROGRESS_STATE: + data.disinfectDGFlushState = state.flushUIState; + break; + + case STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE: + data.disinfectDGHeatState = state.heatDisinfectUIState; + break; + + case STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE: + data.disinfectDGChemState = state.chemDisinfectUIState; + break; + } + + data.disinfectSubModeHDState = (U32)dgDisinfectState; + + broadcastDisinfectsData( &data ); + dataPublishCounter = 0; - // TODO - merge function code from Dara's branch } }