/************************************************************************** * * Copyright (c) 2019-2023 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModeFault.c * * @author (last) Sean Nash * @date (last) 01-Nov-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 * ***************************************************************************/ #include "AlarmLamp.h" #include "BloodFlow.h" #include "Buttons.h" #include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" #include "ModeFault.h" #include "ModePostTreat.h" #include "OperationModes.h" #include "SyringePump.h" #include "SystemCommMessages.h" #include "Valves.h" #include "Utilities.h" /** * @addtogroup HDFaultMode * @{ */ // ********** private data ********** static HD_FAULT_STATE_T faultState; ///< Currently active fault state. static SELF_TEST_STATUS_T faultPOSTSelfTestResult; ///< Fault POST self test result. // ********** private function prototypes ********** static HD_FAULT_STATE_T handleFaultStartState( void ); static HD_FAULT_STATE_T handleFaultRunNVPOSTsState( void ); /*********************************************************************//** * @brief * The initFaultMode function initializes the Fault Mode module. * @details Inputs: none * @details Outputs: Fault Mode module initialized. * @return none *************************************************************************/ void initFaultMode( void ) { faultState = HD_FAULT_STATE_START; faultPOSTSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; } /*********************************************************************//** * @brief * The transitionToFaultMode function prepares for transition to fault mode. * @details Inputs: none * @details Outputs: none * @return initial state of the fault mode state machine *************************************************************************/ U32 transitionToFaultMode( void ) { HD_OP_MODE_T previousOpMode = getPreviousOperationMode(); DG_OP_MODE_T dgOperationMode = getDGOpMode(); initFaultMode(); doorClosedRequired( FALSE, FALSE ); syringeDetectionRequired( FALSE ); // Set user alarm recovery actions allowed in this mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); // Stop trimmer heater cmdStopDGTrimmerHeater(); // Stop syringe pump stopSyringePump(); // If DG filling, abort it if ( DG_MODE_FILL == dgOperationMode ) { cmdStopDGFill(); } // Publish POST failure status to UI if fault triggered in Init/POST mode if ( MODE_INIT == previousOpMode ) { sendPOSTFinalResult( FALSE ); } if ( ( MODE_PRET == previousOpMode ) || ( MODE_TREA == previousOpMode ) ) { collectTreatmentLogData(); sendTreatmentLogDataToUI(); } // Release RTC in case the RTC semaphore was not released prior to transitioning to fault mode. // In fault mode, the non-volatile data mgmt POST might be run again so the RTC has to be available. Also, // the RTC time is read every second which requires the semaphore. releaseSemaphore( SEMAPHORE_RTC ); return faultState; } /*********************************************************************//** * @brief * The execFaultMode function executes the Fault Mode state machine. * @details Inputs: none * @details Outputs: none * @return current state of the fault mode *************************************************************************/ U32 execFaultMode( void ) { BOOL stop = isStopButtonPressed(); DG_OP_MODE_T dgOperationMode = getDGOpMode(); // Ensure all pumps are stopped signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); // TODO - turn off air pump // Ensure all valves are in safe position setValveAirTrap( STATE_CLOSED ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); // If DG not stopped, stop it if ( DG_MODE_GENE == dgOperationMode ) { cmdStopDG(); } switch( faultState ) { case HD_FAULT_STATE_START: faultState = handleFaultStartState(); break; case HD_FAULT_STATE_RUN_NV_POSTS: faultState = handleFaultRunNVPOSTsState(); break; case HD_FAULT_STATE_COMPLETE: // Do nothing. Done with the NV operations break; default: faultState = HD_FAULT_STATE_COMPLETE; break; } return faultState; } /*********************************************************************//** * @brief * The signalAlarmActionToFaultMode function executes the given alarm action * as appropriate while in Fault Mode. * @details Inputs: none * @details Outputs: given alarm action executed * @param action ID of alarm action to execute * @return none *************************************************************************/ void signalAlarmActionToFaultMode( ALARM_ACTION_T action ) { // Fault mode is terminal and already in safe state - no alarm actions handled in this mode. } /*********************************************************************//** * @brief * The handleFaultStartState function handles the start state of the fault mode. * @details Inputs: none * @details Outputs: none * @return next state *************************************************************************/ static HD_FAULT_STATE_T handleFaultStartState( void ) { HD_FAULT_STATE_T state = HD_FAULT_STATE_START; NVDATAMGMT_RECORDS_READ_STATUS_T status = getNVRecordsReadStatus(); switch ( status ) { // If the records are queued or already read, go directly to NV POST to process // their CRCs. case NVDATAMGMT_RECORDS_QUEUED: case NVDATAMGMT_RECORDS_READ: state = HD_FAULT_STATE_RUN_NV_POSTS; break; // If the NV post was completed prior to transitioning to fault mode, do nothing case NVDATAMGMT_RECORDS_CRC_CHECKED: state = HD_FAULT_STATE_COMPLETE; break; } return state; } /*********************************************************************//** * @brief * The handleFaultRunNVPOSTsState function handles running non-volatile POSTs. * @details Inputs: faultPOSTSelfTestResult * @details Outputs: faultPOSTSelfTestResult * @return next state *************************************************************************/ static HD_FAULT_STATE_T handleFaultRunNVPOSTsState( void ) { HD_FAULT_STATE_T state = HD_FAULT_STATE_RUN_NV_POSTS; faultPOSTSelfTestResult = execNVDataMgmtSelfTest(); // Regardless of the status of the NV POST transition to the complete state. if ( ( SELF_TEST_STATUS_PASSED == faultPOSTSelfTestResult ) || ( SELF_TEST_STATUS_FAILED == faultPOSTSelfTestResult ) ) { state = HD_FAULT_STATE_COMPLETE; } return state; } /**@}*/