Index: firmware/App/Controllers/Bubble.c =================================================================== diff -u -r757fb5decc17b09e50869877d1bb111ba01d67e3 -rfb9a367aedfcff9958bbc7458dbccd6577bd4f9a --- firmware/App/Controllers/Bubble.c (.../Bubble.c) (revision 757fb5decc17b09e50869877d1bb111ba01d67e3) +++ firmware/App/Controllers/Bubble.c (.../Bubble.c) (revision fb9a367aedfcff9958bbc7458dbccd6577bd4f9a) @@ -36,9 +36,8 @@ /// Defined states for the air bubble detectors state machine. typedef enum BubbleStates { - BUBBLE_INIT_STATE = 0, ///< Initial state + BUBBLE_NORMAL_STATE = 0, ///< Normal state BUBBLE_SELF_TEST_STATE, ///< Self-test state - BUBBLE_NORMAL_STATE, ///< Normal state NUM_OF_BUBBLE_STATES ///< Number of bubble detector states } BUBBLE_STATES_T; @@ -57,9 +56,8 @@ // ********** private function prototypes ********** -static BUBBLE_STATES_T handleBubbleInitState( BUBBLES_T ); -static BUBBLE_STATES_T handleBubbleSelfTestState( BUBBLES_T ); static BUBBLE_STATES_T handleBubbleNormalState( BUBBLES_T ); +static BUBBLE_STATES_T handleBubbleSelfTestState( BUBBLES_T ); static void publishBubblesData( void ); static U32 getPublishBubblesDataInterval( void ); @@ -77,7 +75,7 @@ for (bubble = ADA; bubble < NUM_OF_BUBBLES; bubble++) { - bubblesState[ bubble ] = BUBBLE_INIT_STATE; + bubblesState[ bubble ] = BUBBLE_NORMAL_STATE; bubblesStatus[ bubble ].data = BUBBLE_NOT_DETECTED; bubblesStatus[ bubble ].ovInitData = BUBBLE_NOT_DETECTED; bubblesStatus[ bubble ].ovData = BUBBLE_NOT_DETECTED; @@ -107,21 +105,16 @@ // Execute the air bubble detector state machine switch( bubblesState[ bubble ] ) { - case BUBBLE_INIT_STATE: - bubblesState[ bubble ] = handleBubbleInitState( bubble ); + case BUBBLE_NORMAL_STATE: + bubblesState[ bubble ] = handleBubbleNormalState( bubble ); break; case BUBBLE_SELF_TEST_STATE: bubblesState[ bubble ] = handleBubbleSelfTestState( bubble ); break; - case BUBBLE_NORMAL_STATE: - bubblesState[ bubble ] = handleBubbleNormalState( bubble ); - break; - default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BUBBLE_STATE, bubblesState[ bubble ] ) - bubblesState[ bubble ] = BUBBLE_INIT_STATE; break; } } @@ -146,77 +139,35 @@ /*********************************************************************//** * @brief - * The handleBubbleInitState function handles a given air bubble detector - * module in init state. - * @details Inputs: none - * @details Outputs: Air bubble detector module init. - * @return next state + * The getBubbleStatus function gets the current reading for a given air bubble + * detector. + * @details Inputs: bubblesStatus + * @details Outputs: none + * @return the current air bubble status. *************************************************************************/ -static BUBBLE_STATES_T handleBubbleInitState( BUBBLES_T bubble ) +BUBBLE_STATUS_T getBubbleStatus( BUBBLES_T bubble ) { - BUBBLE_STATES_T state = BUBBLE_INIT_STATE; + BUBBLE_STATUS_T result = (BUBBLE_STATUS_T)bubblesStatus[ bubble ].data; - if ( TRUE == bubblesSelfTestRequested[ bubble ] ) + if ( OVERRIDE_KEY == bubblesStatus[ bubble ].override ) { - state = BUBBLE_SELF_TEST_STATE; - bubblesSelfTestRequested[ bubble ] = FALSE; - - setFPGABubbleSelfTest( bubble ); - bubblesSelfTestStartTime[ bubble ] = getMSTimerCount(); + result = (BUBBLE_STATUS_T)bubblesStatus[ bubble ].ovData; } - return state; + return result; } /*********************************************************************//** * @brief - * The handleBubbleSelfTestState function handles a given air bubble detector - * in self-test state. - * @details Inputs: none - * @details Outputs: Air bubble detector module self-test. - * @return next state + * The getBubbleSelfTestStatus function gets the status for a given air bubble + * detector self-test. + * @details Inputs: bubblesSelfTestStatus + * @details Outputs: none + * @return status of air bubble detector self-test. *************************************************************************/ -static BUBBLE_STATES_T handleBubbleSelfTestState( BUBBLES_T bubble ) +SELF_TEST_STATUS_T getBubbleSelfTestStatus( BUBBLES_T bubble ) { - BUBBLE_STATES_T state = BUBBLE_SELF_TEST_STATE; - - if ( ( bubble == ADA ) || ( bubble == ADV) ) - { - if ( SELF_TEST_STATUS_IN_PROGRESS == bubblesSelfTestStatus[ bubble ] ) - { - if ( FALSE == noFPGABubbleDetected( bubble ) ) // Faked air bubble caused - { - bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_PASSED; - clearFPGABubbleSelfTest( bubble ); - } - else if ( TRUE == didTimeout( bubblesSelfTestStartTime[ bubble ], BUBBLE_TIMEOUT_MS ) ) - { - bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_FAILED; - if ( bubble == ADA ) - { - activateAlarmNoData( ALARM_ID_HD_ARTERIAL_BUBBLE_SELF_TEST_FAILURE ); - } - else if ( bubble == ADV ) - { - activateAlarmNoData( ALARM_ID_HD_VENOUS_BUBBLE_SELF_TEST_FAILURE ); - } - } - } - else - { - // Air bubble self-test finished, wait for self-test faked air bubble detector clear - if ( TRUE == noFPGABubbleDetected( bubble ) ) - { - state = BUBBLE_NORMAL_STATE; - } - } - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BUBBLE_ID, bubble ) - } - - return state; + return bubblesSelfTestStatus[ bubble ]; } /*********************************************************************//** @@ -289,6 +240,7 @@ { state = BUBBLE_SELF_TEST_STATE; bubblesSelfTestRequested[ bubble ] = FALSE; + bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_IN_PROGRESS; setFPGABubbleSelfTest( bubble ); bubblesSelfTestStartTime[ bubble ] = getMSTimerCount(); @@ -304,46 +256,73 @@ /*********************************************************************//** * @brief - * The getBubbleStatus function gets the current reading for a given air bubble - * detector. - * @details Inputs: bubblesStatus - * @details Outputs: none - * @return the current air bubble status. + * The handleBubbleSelfTestState function handles a given air bubble detector + * in self-test state. + * @details Inputs: none + * @details Outputs: Air bubble detector module self-test. + * @return next state *************************************************************************/ -BUBBLE_STATUS_T getBubbleStatus( BUBBLES_T bubble ) +static BUBBLE_STATES_T handleBubbleSelfTestState( BUBBLES_T bubble ) { - BUBBLE_STATUS_T result = (BUBBLE_STATUS_T)bubblesStatus[ bubble ].data; + BUBBLE_STATES_T state = BUBBLE_SELF_TEST_STATE; - if ( OVERRIDE_KEY == bubblesStatus[ bubble ].override ) + if ( ( bubble == ADA ) || ( bubble == ADV) ) { - result = (BUBBLE_STATUS_T)bubblesStatus[ bubble ].ovData; + if ( TRUE == noFPGABubbleDetected( bubble ) ) + { + bubblesStatus[ bubble ].data = BUBBLE_NOT_DETECTED; + } + else + { + bubblesStatus[ bubble ].data = BUBBLE_DETECTED; + } + + if ( SELF_TEST_STATUS_IN_PROGRESS == bubblesSelfTestStatus[ bubble ] ) + { + if ( BUBBLE_DETECTED == getBubbleStatus( bubble ) ) // Faked air bubble caused + { + bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_PASSED; + clearFPGABubbleSelfTest( bubble ); + } + else if ( TRUE == didTimeout( bubblesSelfTestStartTime[ bubble ], BUBBLE_TIMEOUT_MS ) ) + { + bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_FAILED; + if ( bubble == ADA ) + { + activateAlarmNoData( ALARM_ID_HD_ARTERIAL_BUBBLE_SELF_TEST_FAILURE ); + } + else if ( bubble == ADV ) + { + activateAlarmNoData( ALARM_ID_HD_VENOUS_BUBBLE_SELF_TEST_FAILURE ); + } + } + } + else + { + // Air bubble self-test finished, wait for self-test faked air bubble detector clear + if ( BUBBLE_NOT_DETECTED == getBubbleStatus( bubble ) ) + { + state = BUBBLE_NORMAL_STATE; + } + } } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BUBBLE_ID, bubble ) + } - return result; + return state; } /*********************************************************************//** * @brief - * The getBubbleSelfTestStatus function gets the status for a given air bubble - * detector self-test. - * @details Inputs: bubblesSelfTestStatus - * @details Outputs: none - * @return status of air bubble detector self-test. - *************************************************************************/ -SELF_TEST_STATUS_T getBubbleSelfTestStatus( BUBBLES_T bubble ) -{ - return bubblesSelfTestStatus[ bubble ]; -} - -/*********************************************************************//** - * @brief * The getPublishBubblesDataInterval function gets the air bubbles data * publication interval. * @details Inputs: bubblesDataPublishInterval * @details Outputs: none * @return the current air bubbles data publication interval (in task intervals). *************************************************************************/ -static U32 getPublishBubblesDataInterval( void ) +static U32 getPublishBubblesDataInterval( void ) { U32 result = bubblesDataPublishInterval.data; @@ -368,11 +347,11 @@ // Publish air bubble detectors data on interval if ( ++bubblesDataPublicationTimerCounter >= getPublishBubblesDataInterval() ) { - BUBBLE_STATUS_T statusADA = getBubbleStatus( ADA ); - BUBBLE_STATUS_T statusADV = getBubbleStatus( ADV ); + BUBBLE_STATUS_T statusADA = getBubbleStatus( ADA ); + BUBBLE_STATUS_T statusADV = getBubbleStatus( ADV ); - broadcastBubblesData( (U32)statusADA, (U32)bubblesState[ ADA ], (U32)statusADV, (U32)bubblesState[ ADV ] ); - bubblesDataPublicationTimerCounter = 0; + broadcastBubblesData( (U32)statusADA, (U32)bubblesState[ ADA ], (U32)statusADV, (U32)bubblesState[ ADV ] ); + bubblesDataPublicationTimerCounter = 0; } } Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r1c311459f0cb0796b265062d0ee36a902f007669 -rfb9a367aedfcff9958bbc7458dbccd6577bd4f9a --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 1c311459f0cb0796b265062d0ee36a902f007669) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision fb9a367aedfcff9958bbc7458dbccd6577bd4f9a) @@ -75,6 +75,7 @@ { WET_SELF_TESTS_START_STATE = 0, ///< Wet self-tests starting state. WET_SELF_TESTS_SETUP_STATE, ///< Setup reservoirs for wet self-tests. + WET_SELF_TESTS_BUBBLES_STATE, ///< Wet self-test air bubble detectors state. WET_SELF_TESTS_PRIME_CHECK_STATE, ///< Prime check wet self-tests state, checks for primed patient lines. WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE, ///< Setup valve and start dialysate pump for first displacement. WET_SELF_TESTS_FIRST_DISPLACEMENT_STATE, ///< Fill reservoir 2 with 100 mL of dialysate from reservoir 1 state. @@ -122,7 +123,6 @@ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestsWaitForClosedDoor( void ); static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestLeakDetectorsState( void ); -static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestBubblesState( void ); static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestHomeValvesState( void ); static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestHomeSyringePumpState( void ); static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestPumpsState( void ); @@ -139,6 +139,7 @@ static WET_SELF_TESTS_STATE_T handleWetSelfTestStartState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestSetupState( void ); +static WET_SELF_TESTS_STATE_T handleWetSelfTestBubblesState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestPrimeCheckState( SELF_TEST_STATUS_T *result ); static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementSetupState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestFirstDisplacementState( void ); @@ -271,10 +272,6 @@ currentNoCartSelfTestsState = handleNoCartSelfTestLeakDetectorsState(); break; - case NO_CART_SELF_TESTS_BUBBLES_STATE: - currentNoCartSelfTestsState = handleNoCartSelfTestBubblesState(); - break; - case NO_CART_SELF_TESTS_BOARD_TEMPERATURE_STATE: // TODO: Implement self tests currentNoCartSelfTestsState = NO_CART_SELF_TESTS_HOME_VALVES_STATE; @@ -510,6 +507,10 @@ currentWetSelfTestsState = handleWetSelfTestSetupState(); break; + case WET_SELF_TESTS_BUBBLES_STATE: + currentWetSelfTestsState = handleWetSelfTestBubblesState(); + break; + case WET_SELF_TESTS_PRIME_CHECK_STATE: currentWetSelfTestsState = handleWetSelfTestPrimeCheckState( &result ); break; @@ -617,33 +618,6 @@ if ( SELF_TEST_STATUS_PASSED == getBloodLeakSelfTestStatus() ) { - selfTestBubble( ADA ); - selfTestBubble( ADV ); - state = NO_CART_SELF_TESTS_BUBBLES_STATE; - } - - if ( TRUE == doesAlarmStatusIndicateStop() ) - { - setupForSelfTestsStop(); - state = NO_CART_SELF_TESTS_STOPPED_STATE; - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleNoCartSelfTestBubblesState function verifies air bubbles status. - * @details Inputs: none - * @details Outputs: none - * @return the next state of no cartridge self-tests state machine - *************************************************************************/ -static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestBubblesState( void ) -{ - NO_CART_SELF_TESTS_STATE_T state = NO_CART_SELF_TESTS_BUBBLES_STATE; - - if ( ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADA ) ) && ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADV ) ) ) - { state = NO_CART_SELF_TESTS_BOARD_TEMPERATURE_STATE; } @@ -846,10 +820,10 @@ { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; - BOOL const isADADetectedFluid = noFPGABubbleDetected( ADA ); - BOOL const isADVDetectedFluid = noFPGABubbleDetected( ADV ); + BUBBLE_STATUS_T const ADABubbleStatus = getBubbleStatus( ADA ); + BUBBLE_STATUS_T const ADVBubbleStatus = getBubbleStatus( ADV ); - if ( ( FALSE == isADADetectedFluid ) && ( FALSE == isADVDetectedFluid ) && + if ( ( BUBBLE_DETECTED == ADABubbleStatus ) && ( BUBBLE_DETECTED == ADVBubbleStatus ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) ) { @@ -1123,6 +1097,34 @@ if ( setupDisplacementVolume <= 0 ) { signalDialInPumpHardStop(); + selfTestBubble( ADA ); + selfTestBubble( ADV ); + state = WET_SELF_TESTS_BUBBLES_STATE; + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = WET_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleWetSelfTestBubblesState function waiting for air bubble detectors + * self-tests to finish. + * @details Inputs: bubbleSelfTestStatus + * @details Outputs: none + * @return the next state of wet self-tests state machine + *************************************************************************/ +static WET_SELF_TESTS_STATE_T handleWetSelfTestBubblesState( void ) +{ + WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLES_STATE; + + if ( ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADA ) ) && ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADV ) ) ) + { state = WET_SELF_TESTS_PRIME_CHECK_STATE; } @@ -1149,11 +1151,11 @@ WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_PRIME_CHECK_STATE; *result = SELF_TEST_STATUS_FAILED; - BOOL const isADADetectedFluid = noFPGABubbleDetected( ADA ); - BOOL const isADVDetectedFluid = noFPGABubbleDetected( ADV ); + BUBBLE_STATUS_T const ADABubbleStatus = getBubbleStatus( ADA ); + BUBBLE_STATUS_T const ADVBubbleStatus = getBubbleStatus( ADV ); #ifndef SKIP_AIR_BUBBLE_CHECK - if ( ( TRUE == isADADetectedFluid ) && ( TRUE == isADVDetectedFluid ) ) + if ( ( BUBBLE_NOT_DETECTED == ADABubbleStatus ) && ( BUBBLE_NOT_DETECTED == ADVBubbleStatus ) ) #endif { settleStartTime = getMSTimerCount();