Index: firmware/App/Modes/ModePostTreat.c =================================================================== diff -u -re67d12da06d96f7f6a30771ef309fc9db5b92d70 -r07e0fa769e376ae03dd1d7e9d01bdbf092e3af2f --- firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision e67d12da06d96f7f6a30771ef309fc9db5b92d70) +++ firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision 07e0fa769e376ae03dd1d7e9d01bdbf092e3af2f) @@ -35,18 +35,16 @@ // ********** private definitions ********** -#define EMPTY_RESERVOIR_VOLUME_ML 0 ///< Empty reservoir volume in ml. -#define DIP_FLUSH_FLOW_RATE_ML_MIN 150 ///< Dialysate inlet pump flow rate during flush in mL/min. +#define EMPTY_RESERVOIR_VOLUME_ML 0 ///< Empty reservoir volume in ml. +#define DIP_FLUSH_FLOW_RATE_ML_MIN 150 ///< Dialysate inlet pump flow rate during flush in mL/min. -#define LOAD_CELL_VOLUME_NOISE_TOLERANCE 0.05 ///< Allow 5% tolerance on load cell readings. -#define LOAD_CELL_STEADY_VOLUME_TIME ( 10 * MS_PER_SECOND ) ///< Time load cell reading need to remain steady in ms. +#define LOAD_CELL_VOLUME_NOISE_TOLERANCE_GRAMS 5.0 ///< Allowed tolerance on load cell readings when empty in grams. /// Post-Treatmen de-prime state machine. typedef enum De_Prime_States { - DE_PRIME_FIRST_DRAIN_STATE = 0, ///< De-prime drain first reservoir state. - DE_PRIME_FLUSH_BYPASS_STATE, ///< De-prime drain second reservoir while flushing bypass circuit state. - DE_PRIME_DRAIN_BYPASS_STATE, ///< De-prime drain dialysate from bypass circuit state. + DE_PRIME_DRAIN_RESERVOIR_ONE_STATE = 0, ///< De-prime drain reservoir one state. + DE_PRIME_DRAIN_RESERVOIR_TWO_STATE, ///< De-prime drain reservoir two state. DE_PRIME_COMPLETE_STATE, ///< De-prime complete state. NUM_OF_DE_PRIME_STATES ///< Number of de-prime states. } DE_PRIME_STATE_T; @@ -57,8 +55,6 @@ static BOOL disposableRemovalConfirmed = FALSE; ///< Flag indicates user confirms disposable removal. static BOOL isDrainStarted = FALSE; ///< Flag indicates a drain operation has been started. -static U32 previousLoadCellReading; ///< Previous load cell reading. -static U32 loadcellSteadyVolumeStartTime; ///< Load cell steady volume starting time. static HD_POST_TREATMENT_STATE_T currentPostTreatmentState; ///< Current state of post-treatment mode state machine. static DE_PRIME_STATE_T currentDePrimeState; ///< Current de-prime sub-mode state. @@ -67,15 +63,13 @@ static HD_POST_TREATMENT_STATE_T handlePostTreatmentPatientDisconnectionState( void ); static HD_POST_TREATMENT_STATE_T handlePostTreatmentDePrimeState( void ); -static HD_POST_TREATMENT_STATE_T handlePostTreatmentUnloadState( void ); static HD_POST_TREATMENT_STATE_T handlePostTreatmentVerifyState( void ); static void execDePrime( void ); static BOOL switchReservoirCompleted( DG_RESERVOIR_ID_T activeRes ); static BOOL startDrainCompleted( void ); -static DE_PRIME_STATE_T handleDePrimeFirstDrainState( void ); -static DE_PRIME_STATE_T handleDePrimeFlushBypassState( void ); -static DE_PRIME_STATE_T handleDePrimeDrainBypassState( void ); +static DE_PRIME_STATE_T handleDePrimeDrainReservoirOneState( void ); +static DE_PRIME_STATE_T handleDePrimeDrainReservoirTwoState( void ); /*********************************************************************//** * @brief @@ -89,10 +83,8 @@ patientDisconnectionConfirmed = FALSE; disposableRemovalConfirmed = FALSE; isDrainStarted = FALSE; - previousLoadCellReading = 0; - loadcellSteadyVolumeStartTime = 0; currentPostTreatmentState = HD_POST_TREATMENT_PATIENT_DISCONNECTION_STATE; - currentDePrimeState = DE_PRIME_FIRST_DRAIN_STATE; + currentDePrimeState = DE_PRIME_DRAIN_RESERVOIR_ONE_STATE; } /*********************************************************************//** @@ -115,11 +107,19 @@ setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); cmdSetDGActiveReservoir( DG_RESERVOIR_2 ); + cmdStopDGTrimmerHeater(); + + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_CLOSED ); + + signalBloodPumpHardStop(); + signalDialOutPumpHardStop(); + signalDialInPumpHardStop(); + // TODO: Enable when have syringe pump driver // stopSyringePump(); } @@ -145,10 +145,6 @@ currentPostTreatmentState = handlePostTreatmentDePrimeState(); break; - case HD_POST_TREATMENT_UNLOAD_STATE: - currentPostTreatmentState = handlePostTreatmentUnloadState(); - break; - case HD_POST_TREATMENT_VERIFY_STATE: currentPostTreatmentState = handlePostTreatmentVerifyState(); break; @@ -198,11 +194,24 @@ static HD_POST_TREATMENT_STATE_T handlePostTreatmentPatientDisconnectionState( void ) { HD_POST_TREATMENT_STATE_T state = HD_POST_TREATMENT_PATIENT_DISCONNECTION_STATE; + VALVE_T valve; if ( TRUE == patientDisconnectionConfirmed ) { patientDisconnectionConfirmed = FALSE; state = HD_POST_TREATMENT_DE_PRIME_STATE; + + for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) + { + homeValve( valve ); + } + + homeBloodPump(); + homeDialInPump(); + homeDialOutPump(); + + // TODO: Enable when have syringe pump driver +// retractSyringePump(); } return state; @@ -224,46 +233,11 @@ if ( DE_PRIME_COMPLETE_STATE == currentDePrimeState ) { - state = HD_POST_TREATMENT_UNLOAD_STATE; - - 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 ); - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handlePostTreatmentUnloadState function waits for user confirmation - * of disposable removal and doors to be closed. - * @details Inputs: disposableRemovalConfirmed, doors' status - * @details Outputs: transition to verify state - * @return current state (sub-mode) - *************************************************************************/ -static HD_POST_TREATMENT_STATE_T handlePostTreatmentUnloadState( void ) -{ - HD_POST_TREATMENT_STATE_T state = HD_POST_TREATMENT_UNLOAD_STATE; - - if ( ( TRUE == disposableRemovalConfirmed ) && ( STATE_CLOSED == getFPGADoorState() ) ) - { - disposableRemovalConfirmed = FALSE; - - if ( TRUE == isCartridgeUnloaded() ) + if ( TRUE == disposableRemovalConfirmed ) { + disposableRemovalConfirmed = FALSE; state = HD_POST_TREATMENT_VERIFY_STATE; - - setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); - setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); - setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); } - else - { - activateAlarmNoData( ALARM_ID_CARTRIDGE_REMOVAL_FAILURE ); - } } return state; @@ -279,19 +253,29 @@ *************************************************************************/ static HD_POST_TREATMENT_STATE_T handlePostTreatmentVerifyState( void ) { - // TODO: Check DG doors and straws + BOOL const isReservoirOneEmpty = fabs( getReservoirWeightLargeFilter( DG_RESERVOIR_1 ) ) <= LOAD_CELL_VOLUME_NOISE_TOLERANCE_GRAMS; + BOOL const isReservoirTwoEmpty = fabs( getReservoirWeightLargeFilter( DG_RESERVOIR_2 ) ) <= LOAD_CELL_VOLUME_NOISE_TOLERANCE_GRAMS; + if ( STATE_CLOSED == getFPGADoorState() ) { + + if ( FALSE == isCartridgeUnloaded() ) + { + activateAlarmNoData( ALARM_ID_CARTRIDGE_REMOVAL_FAILURE ); + } + // TODO: Enable when have syringe pump driver -// if ( FALSE == isSyringeDetected() ) +// if ( TRUE == isSyringeDetected() ) // { -// retractSyringePump(); +// // TODO: alarm // } -// -// if ( TRUE == isSyringePumpHome() ) -// { + + // TODO: Add checks for syringe removed + if ( ( TRUE == isReservoirOneEmpty ) && ( TRUE == isReservoirTwoEmpty ) && + ( TRUE == isCartridgeUnloaded() ) ) + { requestNewOperationMode( MODE_STAN ); -// } + } } else { @@ -312,18 +296,14 @@ { switch ( currentDePrimeState ) { - case DE_PRIME_FIRST_DRAIN_STATE: - currentDePrimeState = handleDePrimeFirstDrainState(); + case DE_PRIME_DRAIN_RESERVOIR_ONE_STATE: + currentDePrimeState = handleDePrimeDrainReservoirOneState(); break; - case DE_PRIME_FLUSH_BYPASS_STATE: - currentDePrimeState = handleDePrimeFlushBypassState(); + case DE_PRIME_DRAIN_RESERVOIR_TWO_STATE: + currentDePrimeState = handleDePrimeDrainReservoirTwoState(); break; - case DE_PRIME_DRAIN_BYPASS_STATE: - currentDePrimeState = handleDePrimeDrainBypassState(); - break; - case DE_PRIME_COMPLETE_STATE: break; @@ -390,43 +370,15 @@ /*********************************************************************//** * @brief - * The isBypassCircuitFlushed function checks load cell steady reading as an - * indicator for flushed bypass circuit. - * @details Inputs: previousLoadCellReading - * @details Outputs: processed DG drain command response - * @return TRUE if start reservoir drain completed, otherwise FALSE - *************************************************************************/ -static BOOL isBypassCircuitFlushed( void ) -{ - BOOL result = FALSE; - DG_RESERVOIR_ID_T const activeRes = getDGActiveReservoir(); - F32 const loadcellWeight = getReservoirWeightSmallFilter( activeRes ); - F32 const weightChange = fabs( 1.0 - ( previousLoadCellReading / loadcellWeight ) ); - - if ( weightChange < LOAD_CELL_VOLUME_NOISE_TOLERANCE ) - { - result = didTimeout( loadcellSteadyVolumeStartTime, LOAD_CELL_STEADY_VOLUME_TIME ); - } - else - { - previousLoadCellReading = loadcellWeight; - loadcellSteadyVolumeStartTime = getMSTimerCount(); - } - - return result; -} - -/*********************************************************************//** - * @brief - * The handleDePrimeFirstDrainState function sends command to DG to drain - * reservoir one. + * The handleDePrimeDrainReservoirOneState function sends command to DG to + * drain reservoir one. * @details Inputs: none * @details Outputs: drained reservoir one * @return current state (sub-mode) *************************************************************************/ -static DE_PRIME_STATE_T handleDePrimeFirstDrainState( void ) +static DE_PRIME_STATE_T handleDePrimeDrainReservoirOneState( void ) { - DE_PRIME_STATE_T state = DE_PRIME_FIRST_DRAIN_STATE; + DE_PRIME_STATE_T state = DE_PRIME_DRAIN_RESERVOIR_ONE_STATE; if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) ) { @@ -447,23 +399,23 @@ if ( ( TRUE == isDrainStarted ) && ( DG_MODE_CIRC == getDGOpMode() ) ) { isDrainStarted = FALSE; - state = DE_PRIME_FLUSH_BYPASS_STATE; + state = DE_PRIME_DRAIN_RESERVOIR_TWO_STATE; } return state; } /*********************************************************************//** * @brief - * The handleDePrimeFlushBypassState function sends command to DG to drain - * reservoir two while flushing dialysate from bypass circuit to reservoir one. + * The handleDePrimeDrainReservoirTwoState function sends command to DG to drain + * reservoir two. * @details Inputs: none - * @details Outputs: drained reservoir two, flushed dialysate from bypass circuit + * @details Outputs: drained reservoir two * @return current state (sub-mode) *************************************************************************/ -static DE_PRIME_STATE_T handleDePrimeFlushBypassState( void ) +static DE_PRIME_STATE_T handleDePrimeDrainReservoirTwoState( void ) { - DE_PRIME_STATE_T state = DE_PRIME_FLUSH_BYPASS_STATE; + DE_PRIME_STATE_T state = DE_PRIME_DRAIN_RESERVOIR_TWO_STATE; if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) ) { @@ -472,8 +424,6 @@ if ( TRUE == switchReservoirCompleted( DG_RESERVOIR_1 ) ) { - loadcellSteadyVolumeStartTime = getMSTimerCount(); - setDialInPumpTargetFlowRate( DIP_FLUSH_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); cmdStartDGDrain( EMPTY_RESERVOIR_VOLUME_ML, FALSE ); } @@ -483,44 +433,6 @@ } // Drain has started and DG goes to re-circ mode means drain completed - if ( ( TRUE == isBypassCircuitFlushed() ) && ( TRUE == isDrainStarted ) && ( DG_MODE_CIRC == getDGOpMode() ) ) - { - signalDialInPumpHardStop(); - isDrainStarted = FALSE; - state = DE_PRIME_DRAIN_BYPASS_STATE; - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleDePrimeDrainBypassState function sends command to DG to drain - * reservoir one, which contains flushed dialysate from bypass circuit. - * @details Inputs: none - * @details Outputs: drained reservoir one - * @return current state (sub-mode) - *************************************************************************/ -static DE_PRIME_STATE_T handleDePrimeDrainBypassState( void ) -{ - DE_PRIME_STATE_T state = DE_PRIME_DRAIN_BYPASS_STATE; - - if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) ) - { - cmdSetDGActiveReservoir( DG_RESERVOIR_2 ); - } - - if ( TRUE == switchReservoirCompleted( DG_RESERVOIR_2 ) ) - { - cmdStartDGDrain( EMPTY_RESERVOIR_VOLUME_ML, FALSE ); - } - - if ( TRUE == startDrainCompleted() ) - { - isDrainStarted = TRUE; - } - - // Drain has started and DG goes to re-circ mode means drain completed if ( ( TRUE == isDrainStarted ) && ( DG_MODE_CIRC == getDGOpMode() ) ) { isDrainStarted = FALSE; Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r27f3db92495948d4c1192421c1b0c20338c4a034 -r07e0fa769e376ae03dd1d7e9d01bdbf092e3af2f --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 27f3db92495948d4c1192421c1b0c20338c4a034) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 07e0fa769e376ae03dd1d7e9d01bdbf092e3af2f) @@ -118,8 +118,6 @@ static void handleDrySelfTestsStopRequest( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ); -static DRY_SELF_TESTS_STATE_T handleDrySelfTestBubbleDetectorsState( void ); -static DRY_SELF_TESTS_STATE_T handleDrySelfTestAirTrapState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsSetupState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( SELF_TEST_STATUS_T *result ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalState( SELF_TEST_STATUS_T *result ); @@ -284,10 +282,10 @@ case NO_CART_SELF_TESTS_BOARD_TEMPERATURE_STATE: // TODO: Implement self tests - currentNoCartSelfTestsState = NO_CART_SELF_TESTS_DOOR_SWITCH_STATE; + currentNoCartSelfTestsState = NO_CART_SELF_TESTS_START_HOMING_STATE; break; - case NO_CART_SELF_TESTS_DOOR_SWITCH_STATE: + case NO_CART_SELF_TESTS_START_HOMING_STATE: // TODO: Implement self tests currentNoCartSelfTestsState = NO_CART_SELF_TESTS_HOME_VALVES_AND_PUMPS_STATE; break; @@ -386,14 +384,6 @@ currentDrySelfTestsState = handleDrySelfTestWaitForDoorCloseState(); break; - case DRY_SELF_TESTS_BUBBLE_DETECTOR_STATE: - currentDrySelfTestsState = handleDrySelfTestBubbleDetectorsState(); - break; - - case DRY_SELF_TESTS_AIR_TRAP_STATE: - currentDrySelfTestsState = handleDrySelfTestAirTrapState(); - break; - case DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE: if ( SELF_TEST_STATUS_PASSED == execPresOcclDryTest() ) { @@ -740,60 +730,8 @@ if ( STATE_CLOSED == getFPGADoorState() ) { - state = DRY_SELF_TESTS_BUBBLE_DETECTOR_STATE; - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleDrySelfTestBubbleDetectorsState function verify no fluid is detected - * by bubble detectors. - * @details Inputs: none - * @details Outputs: none - * @return the next state of dry self-tests state machine - *************************************************************************/ -static DRY_SELF_TESTS_STATE_T handleDrySelfTestBubbleDetectorsState( void ) -{ - DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_BUBBLE_DETECTOR_STATE; - - BOOL const isADADetectedAir = getFPGAArterialAirBubbleStatus(); - BOOL const isADVDetectedAir = getFPGAVenousAirBubbleStatus(); - - if ( ( TRUE == isADADetectedAir ) && ( TRUE == isADVDetectedAir ) ) - { - state = DRY_SELF_TESTS_AIR_TRAP_STATE; - } - else - { - activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleDrySelfTestAirTrapState function verify no fluid is detected - * by air trap. - * @details Inputs: none - * @details Outputs: none - * @return the next state of dry self-tests state machine - *************************************************************************/ -static DRY_SELF_TESTS_STATE_T handleDrySelfTestAirTrapState( void ) -{ - DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_AIR_TRAP_STATE; - - if ( ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && - ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) ) - { state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; } - else - { - activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); - } return state; }