Index: firmware/App/Modes/ModeFault.c =================================================================== diff -u -r8b73263b38f449dacc0795c67a7cf6240cb79026 -rf9a866abfc44db38c01cb795fea894cce1042eec --- firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision 8b73263b38f449dacc0795c67a7cf6240cb79026) +++ firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision f9a866abfc44db38c01cb795fea894cce1042eec) @@ -7,8 +7,8 @@ * * @file ModeFault.c * -* @author (last) Sean Nash -* @date (last) 13-Jul-2022 +* @author (last) Dara Navaei +* @date (last) 01-Sep-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -27,6 +27,7 @@ #include "SyringePump.h" #include "SystemCommMessages.h" #include "Valves.h" +#include "Utilities.h" /** * @addtogroup HDFaultMode @@ -35,11 +36,14 @@ // ********** private data ********** -// TODO expand this later -static HD_FAULT_STATE_T faultState = HD_FAULT_STATE_START; ///< Currently active fault state. +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. @@ -49,21 +53,23 @@ *************************************************************************/ void initFaultMode( void ) { - // Nothing to do here + 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: - * @return initial state + * @details Outputs: none + * @return initial state of the fault mode state machine *************************************************************************/ U32 transitionToFaultMode( void ) { - HD_OP_MODE_T previousOpMode = getPreviousOperationMode(); + HD_OP_MODE_T previousOpMode = getPreviousOperationMode(); DG_OP_MODE_T dgOperationMode = getDGOpMode(); + initFaultMode(); doorClosedRequired( FALSE, FALSE ); syringeDetectionRequired( FALSE ); @@ -90,22 +96,26 @@ 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: - * @return current state (sub-mode) + * @details Outputs: none + * @return current state of the fault mode *************************************************************************/ U32 execFaultMode( void ) { - BOOL stop = isStopButtonPressed(); + BOOL stop = isStopButtonPressed(); DG_OP_MODE_T dgOperationMode = getDGOpMode(); -#ifndef EMC_TEST_BUILD // Ensure all pumps are stopped signalBloodPumpHardStop(); signalDialInPumpHardStop(); @@ -124,58 +134,27 @@ { cmdStopDG(); } -#else - // TODO - EMC test code - remove later - static U32 toggle = 0; - static BOOL button_state = FALSE; - if ( TRUE == stop ) + switch( faultState ) { - if ( stop != button_state ) - { - toggle = INC_WRAP( toggle, 0, 2 ); - switch ( toggle ) - { - case 0: // Pumps and valves off - setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); - break; + case HD_FAULT_STATE_START: + faultState = handleFaultStartState(); + break; - case 1: // Pumps off, valves in pos A - setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); - setValvePosition( VDO, VALVE_POSITION_A_INSERT_EJECT ); - setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); - setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); - break; + case HD_FAULT_STATE_RUN_NV_POSTS: + faultState = handleFaultRunNVPOSTsState(); + break; - case 2: // Pumps on, valves in pos A - setBloodPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialOutPumpTargetRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - break; + case HD_FAULT_STATE_COMPLETE: + // Do nothing. Done with the NV operations + break; - default: // Should not get here, reset if we do - toggle = 0; - setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); - break; - } - } + default: + faultState = HD_FAULT_STATE_COMPLETE; + break; } - button_state = stop; -#endif - return faultState; // TODO expand the states later + return faultState; } /*********************************************************************//** @@ -192,4 +171,55 @@ // 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; +} + /**@}*/