Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r50086215a9c8977c977f836dcd4c454dd4d7d712 -r6e23d627c3f5a1ef3f7cca5d4e48eb478b0eef4c --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 50086215a9c8977c977f836dcd4c454dd4d7d712) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 6e23d627c3f5a1ef3f7cca5d4e48eb478b0eef4c) @@ -7,8 +7,8 @@ * * @file ModeStandby.c * -* @author (last) Sean Nash -* @date (last) 05-Feb-2023 +* @author (last) Dara Navaei +* @date (last) 20-Mar-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -48,22 +48,24 @@ // ********** private definitions ********** #define DISINFECTS_DATA_PUB_INTERVAL ( 1 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Disinfects data publish interval in counts. -#define DISINFECTS_TIME_INTERVAL_S ( 2 * SECONDS_IN_A_DAY ) ///< HD/DG 2-day service interval in seconds. +#define DISINFECTS_TIME_INTERVAL_S ( 3 * SECONDS_IN_A_DAY ) ///< HD/DG 3-day service interval in seconds. #define FLUSH_TIME_INTERVAL_S ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Flush time interval in seconds. #define MAX_ALLOWED_RO_FILTER_TEMP_FOR_TX_C 44.0F ///< Maximum allowed temperature to start a treatment in C. // ********** private data ********** static HD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. - static BOOL treatStartReqReceived; ///< Flag indicates user has requested initiation of a treatment. static BOOL flushStartReqReceived; ///< Flag indicates user has requested initiation of flush mode. static BOOL heatDisinfectStartReqReceived; ///< Flag indicates user has requested initiation of heat disinfect mode. static BOOL chemDisinfectStartReqReceived; ///< Flag indicates user has requested initiation of chemical disinfect mode. -static GENERIC_CONFIRM_ID_T disinfectCancelReqID; ///< ID of requested cancel disinfect mode. +static BOOL chemDisinfectFlushStartReqReceived; ///< Flag indicates user has requested initiation of chemical disinfect flush mode. +static GENERIC_CONFIRM_ID_T disinfectCancelReqID; ///< ID of requested cancel disinfect mode. static DG_DISINFECT_STATE_T dgDisinfectState; ///< DG disinfect state to be boadcast to UI. static U32 dataPublishCounter; ///< Disinfects data publish counter. static BOOL homingInitiated; ///< Boolean flag to indicate homing is initiated. +static BOOL hasChemFlushSampleAlarmBeenTrgrd; ///< Boolean flag to indicate whether chem flush sample alarm has been triggered or not. +static GENERIC_CONFIRM_ID_T chemFlushSampleID; ///< Chemical disinfect flush sample ID. /// 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 }; @@ -91,6 +93,10 @@ static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectStartState( void ); static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ); +static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectFlushCmdResponseState( void ); +static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectFlushStartState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectFlushInProgressState( void ); + static BOOL isDGDisinfectValid( void ); static BOOL haveHDDGServicesBeenExpired( REQUEST_REJECT_REASON_CODE_T* rejReason ); static void publishDisinfectData( void ); @@ -101,21 +107,25 @@ * @details Inputs: none * @details Outputs: currentStandbyState, treatStartReqReceived, * flushStartReqReceived, dataPublishCounter, heatDisinfectStartReqReceived, - * chemDisinfectStartReqReceived, dgDisinfectState, homingInitiated + * chemDisinfectStartReqReceived, dgDisinfectState, homingInitiated, + * chemDisinfectFlushStartReqReceived, hasChemFlushSampleAlarmBeenTrgrd, + * chemFlushSampleID * @return none *************************************************************************/ void initStandbyMode( void ) { - currentStandbyState = STANDBY_START_STATE; - treatStartReqReceived = FALSE; - flushStartReqReceived = FALSE; - dataPublishCounter = 0; - heatDisinfectStartReqReceived = FALSE; - chemDisinfectStartReqReceived = FALSE; - disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; - homingInitiated = FALSE; - dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; - homingInitiated = FALSE; + currentStandbyState = STANDBY_START_STATE; + treatStartReqReceived = FALSE; + flushStartReqReceived = FALSE; + dataPublishCounter = 0; + heatDisinfectStartReqReceived = FALSE; + chemDisinfectStartReqReceived = FALSE; + chemDisinfectFlushStartReqReceived = FALSE; + disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + homingInitiated = FALSE; + hasChemFlushSampleAlarmBeenTrgrd = FALSE; + chemFlushSampleID = GENERIC_CONFIRM_ID_NONE; } /*********************************************************************//** @@ -188,7 +198,6 @@ handleDisinfectCancel( stop ); -#ifndef RUN_WITHOUT_DG // State machine to get DG to prep a reservoir so we can start a treatment switch ( currentStandbyState ) { @@ -240,37 +249,23 @@ 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; + case STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_FLUSH_CMD_RESPONSE_STATE: + currentStandbyState = handleStandbyModeWaitForDGChemDisinfectFlushCmdResponseState(); break; - } -#else - // State machine to get DG to prep a reservoir so we can start a treatment - switch ( currentStandbyState ) - { - case STANDBY_START_STATE: - currentStandbyState = STANDBY_WAIT_FOR_TREATMENT_STATE; - // Temporary test code - TODO - remove later - homeBloodPump(); - homeDialInPump(); - homeDialOutPump(); + + case STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_FLUSH_TO_START_STATE: + currentStandbyState = handleStandbyModeWaitForDGChemDisinfectFlushStartState(); break; - case STANDBY_WAIT_FOR_TREATMENT_STATE: - if ( TRUE == treatStartReqReceived ) - { - requestNewOperationMode( MODE_TPAR ); - treatStartReqReceived = FALSE; - } + case STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGChemDisininfectFlushInProgressState(); 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; } -#endif return currentStandbyState; } @@ -472,6 +467,42 @@ /*********************************************************************//** * @brief + * The signalUserInitiateChemcialDisinfectFlushMode function handles user + * initiation of chemical disinfect flush mode. + * @details Inputs: currentStandbyState + * @details Outputs: chemDisinfectFlushStartReqReceived + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateChemcialDisinfectFlushMode( 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() ) + { + chemDisinfectFlushStartReqReceived = 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 signalInitiateStandbyDisinfectSubmode function handles user * initiation of setting the disinfects submode. * @details Inputs: currentStandbyState @@ -541,7 +572,8 @@ if ( ( STANDBY_DG_FLUSH_IN_PROGRESS_STATE == currentStandbyState ) || ( STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) || - ( STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) ) + ( STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE == currentStandbyState ) || + ( STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE == currentStandbyState ) ) { if ( ( TRUE == stop ) && ( GENERIC_CONFIRM_ID_NONE == disinfectCancelReqID ) ) { @@ -557,6 +589,10 @@ { confirm_id = GENERIC_CONFIRM_ID_DISINFECT_STOP_CHEMICAL; } + else if ( STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE == currentStandbyState ) + { + confirm_id = GENERIC_CONFIRM_ID_DISINFECT_STOP_CHEMICAL_FLUSH; + } // Send message to UI to indicate user request to cancel disinfect disinfectCancelReqID = addConfirmationRequest( confirm_id, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0 ); } @@ -566,7 +602,7 @@ confirm_status = getConfirmationRequestStatus( disinfectCancelReqID ); switch ( confirm_status ) { - case CONFIRMATION_REQUEST_STATUS_ACCEPTED : + case CONFIRMATION_REQUEST_STATUS_ACCEPTED: // Clear request active status disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; @@ -584,21 +620,25 @@ cmdStopDGChemicalDisinfect(); break; + case STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE: + cmdStopDGChemFlushDisinfect(); + break; + default: // UI Confirm already closed. Nothing to do. break; } break; - case CONFIRMATION_REQUEST_STATUS_TIMEOUT : - case CONFIRMATION_REQUEST_STATUS_REJECTED : + case CONFIRMATION_REQUEST_STATUS_TIMEOUT: + case CONFIRMATION_REQUEST_STATUS_REJECTED: // Clear request active status disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; break; case CONFIRMATION_REQUEST_STATUS_PENDING: case CONFIRMATION_REQUEST_STATUS_UNUSED: - default : + default: // Nothing to do break; } @@ -744,6 +784,11 @@ cmdStartDGChemicalDisinfect(); state = STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_CMD_RESPONSE_STATE; } + else if ( TRUE == chemDisinfectFlushStartReqReceived ) + { + cmdStartDGChememicalFlushDisinfect(); + state = STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_FLUSH_CMD_RESPONSE_STATE; + } return state; } @@ -988,6 +1033,128 @@ /*********************************************************************//** * @brief + * The handleStandbyModeWaitForDGChemDisinfectFlushCmdResponseState function handles + * DG chemical disinfect flush wait for command response state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, chemDisinfectFlushStartReqReceived + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectFlushCmdResponseState( void ) +{ + DG_CMD_RESPONSE_T dgCmdResp; + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_FLUSH_CMD_RESPONSE_STATE; + BOOL result = FALSE; + + if ( TRUE == getDGCommandResponse( DG_CMD_START_CHEM_DISINFECT_FLUSH, &dgCmdResp ) ) + { + state = STANDBY_WAIT_FOR_DISINFECT_STATE; + chemDisinfectFlushStartReqReceived = FALSE; + + if ( DG_CMD_REQUEST_REJECT_REASON_NONE == dgCmdResp.rejectCode ) + { + dgDisinfectState = DG_DISINFECT_CHEM_FLUSH_STATE; + state = STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_FLUSH_TO_START_STATE; + result = TRUE; + } + + sendDisinfectConfirmResponse( result, dgCmdResp.rejectCode ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeWaitForDGChemDisinfectFlushStartState function handles + * DG chemical disinfect flush wait for start state. + * @details Inputs: none + * @details Outputs: dgDisinfectState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectFlushStartState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_FLUSH_TO_START_STATE; + + if ( DG_MODE_CHFL == getDGOpMode() ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + state = STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DISINFECT_CHEM_FLUSH, 0 ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGChemDisininfectFlushInProgressState function handles + * DG chemical disinfect flush in progress state. + * @details Inputs: hasChemFlushSampleAlarmBeenTrgrd, chemFlushSampleID + * @details Outputs: dgDisinfectState, hasChemFlushSampleAlarmBeenTrgrd, + * chemFlushSampleID + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectFlushInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE; + + if ( ( FALSE == hasChemFlushSampleAlarmBeenTrgrd ) && ( TRUE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ) ) ) + { + // Check if the flush sample alarm has been raised for the first time in the sample flush state + hasChemFlushSampleAlarmBeenTrgrd = TRUE; + } + else if ( ( TRUE == hasChemFlushSampleAlarmBeenTrgrd ) && ( FALSE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ) ) ) + { + // Sample flush alarm has been triggered and the user has cleared the alarm by pressing Ok. The user is collecting sample. + // Send the notification to the UI to prompt the pass/fail screen so the user can choose whether the sampling after flush passed or failed + hasChemFlushSampleAlarmBeenTrgrd = FALSE; + chemFlushSampleID = addConfirmationRequest( GENERIC_CONFIRM_ID_DISINFECT_CHEM_FLUSH_SAMPLE_PASS_FAIL, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0 ); + } + + if ( chemFlushSampleID != GENERIC_CONFIRM_ID_NONE ) + { + // There is a user confirm + CONFIRMATION_REQUEST_STATUS_T status = getConfirmationRequestStatus( chemFlushSampleID ); + U32 sampleStatus = 0; + + switch( status ) + { + // If the request status is accepted send a 1 to DG + case CONFIRMATION_REQUEST_STATUS_ACCEPTED: + sampleStatus = (U32)CONFIRMATION_REQUEST_STATUS_ACCEPTED; + chemFlushSampleID = GENERIC_CONFIRM_ID_NONE; + handleSendChemFlushPassFailToDG( sampleStatus ); + break; + + // If the request timed out or rejected, it is 0 or failure to DG + case CONFIRMATION_REQUEST_STATUS_TIMEOUT: + case CONFIRMATION_REQUEST_STATUS_REJECTED: + chemFlushSampleID = GENERIC_CONFIRM_ID_NONE; + handleSendChemFlushPassFailToDG( sampleStatus ); + break; + + case CONFIRMATION_REQUEST_STATUS_PENDING: + case CONFIRMATION_REQUEST_STATUS_UNUSED: + default: + // Nothing to do + break; + } + } + + if ( getDGOpMode() != DG_MODE_CHFL ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + state = STANDBY_WAIT_FOR_TREATMENT_STATE; + clearAlarm( ALARM_ID_HD_DISINFECT_CHEM_FLUSH ); + } + + publishDisinfectData(); + + return state; +} + +/*********************************************************************//** + * @brief * The isDGDisinfectValid function checks whether the DG disinfects is * acceptable to start another treatment. * @details Inputs: none @@ -1010,29 +1177,27 @@ U32 lastChemFlushCompleteDate = data.dgUsageInfo.lastChemDisFlushCompleteDateEpoch; U32 lastHeatCompleteDate = data.dgUsageInfo.lastHeatDisCompleteDateEpoch; U32 lastFlushCompleteDate = data.dgUsageInfo.lastBasicFlushCompleteDateEpoch; + U32 lastHeatCoolCompleteDate = data.dgUsageInfo.lastHeatActiveCoolCompleteDateEpoch; U32 lastStartTxTimeDate = usageRecord.txLastStartTimeEpoch; // Last Treatment Start < Last Heat Disinfect Complete or Last Treatment Start < Last Chem Disinfect Complete so it means at least a heat disinfect // or a chemical disinfect has been done since the last treatment BOOL hasDisBeenDone = ( ( ( lastStartTxTimeDate < lastChemCompleteDate ) || ( lastStartTxTimeDate < lastHeatCompleteDate ) ) ? TRUE : FALSE ); - // Last Chem Disinfect Complete < Current Time – Chem Disinfect Interval, so the chemical disinfect that has been done has not been expired - BOOL isChemDisValid = ( lastChemCompleteDate < ( getRTCTimestamp() - DISINFECTS_TIME_INTERVAL_S ) ? TRUE : FALSE ); - // Last Heat Disinfect Complete < Current Time – Heat Disinfect Interval, so the heat disinfect that has been done has not been expired BOOL isHeatDisValid = ( lastHeatCompleteDate < ( getRTCTimestamp() - DISINFECTS_TIME_INTERVAL_S ) ? TRUE : FALSE ); // Last Chem Flush Complete < Last Chem Disinfect Start, so after running a chemical disinfect, a chemical disinfect flush has been done BOOL isChemFlushComplete = ( lastChemFlushCompleteDate > lastChemCompleteDate ? TRUE : FALSE ); // If either of the basic flush, heat disinfect, or chemical disinfect flush have been done within the interval, it means the filters have been flushed - BOOL isBasicFlushValid = ( lastFlushCompleteDate < ( getRTCTimestamp() - FLUSH_TIME_INTERVAL_S ) ? TRUE : TRUE ); - BOOL isHeatDisFlushValid = ( lastHeatCompleteDate < ( getRTCTimestamp() - FLUSH_TIME_INTERVAL_S ) ? TRUE : TRUE ); - BOOL isChemFlushValid = ( lastChemFlushCompleteDate < ( getRTCTimestamp() - FLUSH_TIME_INTERVAL_S ) ? TRUE : TRUE ); - BOOL isFlushValid = ( isBasicFlushValid || isHeatDisFlushValid || isChemFlushValid ); + BOOL isBasicFlushValid = ( lastFlushCompleteDate < ( getRTCTimestamp() - FLUSH_TIME_INTERVAL_S ) ? TRUE : TRUE ); + BOOL isChemFlushValid = ( lastChemFlushCompleteDate < ( getRTCTimestamp() - FLUSH_TIME_INTERVAL_S ) ? TRUE : TRUE ); + BOOL isHeatDisCoolFlushValid = ( lastHeatCoolCompleteDate < ( getRTCTimestamp() - FLUSH_TIME_INTERVAL_S ) ? TRUE : TRUE ); + BOOL isFlushValid = ( isBasicFlushValid || isChemFlushValid || isHeatDisCoolFlushValid ); // If all of the above conditions are true, it means we can start a treatment - if ( ( TRUE == hasDisBeenDone ) && ( TRUE == isChemDisValid ) && ( TRUE == isHeatDisValid ) && ( TRUE == isChemFlushComplete ) && ( TRUE == isFlushValid ) ) + if ( ( TRUE == hasDisBeenDone ) && ( TRUE == isHeatDisValid ) && ( TRUE == isChemFlushComplete ) && ( TRUE == isFlushValid ) ) { status = TRUE; } @@ -1110,6 +1275,10 @@ case STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE: data.disinfectDGChemState = state.chemDisinfectUIState; break; + + case STANDBY_DG_CHEM_DISINFECT_FLUSH_IN_PROGRESS_STATE: + data.disinfectDGChemState = state.chemDisinfectUIState; // TDOD add chem flush + break; } data.disinfectSubModeHDState = (U32)dgDisinfectState;