Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r5e3e9943759f429fc2213db848475c07ca6b79a5 -r3f2b9de757500da37e0ed8881e4e906d94f3076c --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 5e3e9943759f429fc2213db848475c07ca6b79a5) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 3f2b9de757500da37e0ed8881e4e906d94f3076c) @@ -32,6 +32,8 @@ #include "OperationModes.h" #include "SystemComm.h" #include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "Timers.h" #ifdef EMC_TEST_BUILD // TODO - test code #include "FPGA.h" #endif @@ -43,19 +45,30 @@ // ********** private definitions ********** +#define DISINFECTS_DATA_PUB_INTERVAL ( 1 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Disinfects data publish interval in counts. + // ********** 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 U32 dataPublishCounter = 0; ///< Disinfects data publish counter. +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. // ********** 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 ); + /*********************************************************************//** * @brief * The initStandbyMode function initializes the Standby Mode module. @@ -65,8 +78,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; } /*********************************************************************//** @@ -124,20 +141,28 @@ 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: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); + currentStandbyState = STANDBY_START_STATE; break; } #else @@ -236,143 +261,402 @@ /*********************************************************************//** * @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_NONE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; - if ( TRUE == getNoNewTreatmentStatus() ) + if ( ( MODE_STAN == getCurrentOperationMode() ) && ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) { - rejReason = REQUEST_REJECT_REASON_NO_NEW_TREATMENT_ALARM_TRIGGERED; + if ( TRUE == isDGCommunicating() ) + { + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + result = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } } - if ( ( MODE_STAN != getCurrentOperationMode() ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE != currentStandbyState ) ) + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +// ********** private functions ********** + +/*********************************************************************//** + * @brief + * 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; + + if ( TRUE == treatStartReqReceived ) { - rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + // Initialize treatment modes before starting a new treatment + initTreatParamsMode(); + initPreTreatmentMode(); + initTreatmentMode(); + initPostTreatmentMode(); + // Start treatment workflow with treatment parameters mode + requestNewOperationMode( MODE_TPAR ); + treatStartReqReceived = FALSE; } - if ( TRUE != isDGCommunicating() ) + 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 ) { - rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + 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; + } } - - if ( ( DG_MODE_STAN != getDGOpMode() ) || ( DG_STANDBY_MODE_STATE_IDLE != getDGSubMode() ) ) + else if ( TRUE == heatDisinfectStartReqReceived ) { - rejReason = REQUEST_REJECT_REASON_DG_NOT_IN_STANDBY_IDLE_STATE; + 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; + } } - - if ( FALSE == isBatteryCharged() ) + else if ( TRUE == chemDisinfectStartReqReceived ) { - rejReason = REQUEST_REJECT_REASON_BATTERY_IS_NOT_CHARGED; + 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; + } } - if ( REQUEST_REJECT_REASON_NONE == rejReason ) + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGFlushInProgressState function handles DG flush + * in progress state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGFlushInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_FLUSH_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_FLUS ) { - result = TRUE; - treatStartReqReceived = TRUE; + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + state = STANDBY_WAIT_FOR_TREATMENT_STATE; } + publishDisinfectData(); - sendInitiateTreatmentResponseMsg( result, rejReason ); + return state; +} - return result; +/*********************************************************************//** + * @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 signalAlarmActionToStandbyMode function executes the given alarm action - * as appropriate while in Standby Mode. + * The handleStandbyModeDGChemDisininfectInProgressState function handles + * DG chemical disinfect 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 handleStandbyModeDGChemDisininfectInProgressState( void ) { - // Alarm actions not handled in Standby mode + 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 + * @details Outputs: dataPublishCounter + * @return: none + *************************************************************************/ +static void publishDisinfectData( void ) +{ + 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; + } +} + /**@}*/