Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r1949c8bc59aab6710c6ead6876598eb929d698d5 -rf6ebc5a71ac62d586ce741235fe33fcccf7ddbde --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 1949c8bc59aab6710c6ead6876598eb929d698d5) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision f6ebc5a71ac62d586ce741235fe33fcccf7ddbde) @@ -7,17 +7,17 @@ * * @file BloodLeak.c * -* @author (last) Bill Bracken -* @date (last) 13-Jun-2023 +* @author (last) Michael Garthwaite +* @date (last) 09-Aug-2023 * * @author (original) Peman Montazemi * @date (original) 18-Mar-2021 * ***************************************************************************/ -#include // For sprintf and strlen -#include -#include // For sprintf +#include // For pow function +#include // For memset and strlen +#include // For sprintf #include "AlarmMgmt.h" #include "BloodLeak.h" @@ -59,6 +59,7 @@ #define BLOOD_LEAK_SELF_TEST_CMD_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak self test command timeout in milliseconds. #define BLOOD_LEAK_BETWEEN_ZERO_ST_WAIT_MS 250 ///< Blood leak wait time in between zero and self test commands in milliseconds. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. +#define BLOOD_LEAK_DETECT_RECOVERY_MIN_TIME_MS ( 2 * MS_PER_SECOND ) ///< Blood leak blood detect recovery minimum time in milliseconds. // Embedded mode defines #define BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH 6 ///< Blood leak embedded mode command sequence length. @@ -92,9 +93,6 @@ #define BLOOD_LEAK_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak embedded mode FPGA error timeout in milliseconds. #define BLOOD_LEAK_RXFIFO_COUNT_MASK 0x03FF ///< Mask high order bits of blood leak sensor rx count -#define MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Blood Leak comm failures window -#define MAX_BLOOD_LEAK_COMM_FAILURES 3 ///< Blood Leak maximum comm failures per MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS - /// Defined states for the blood leak detector state machine. typedef enum BloodLeakStates { @@ -103,6 +101,7 @@ BLOOD_LEAK_INIT_STATE, ///< Init state. BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE, ///< Blood leak check for zero and self test commands state. BLOOD_LEAK_NORMAL_STATE, ///< Normal state. + BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE, ///< Blood leak recover blood detect state. NUM_OF_BLOOD_LEAK_STATES ///< Number of blood leak detector states. } BLOOD_LEAK_STATE_T; @@ -140,7 +139,7 @@ U32 length; ///< Blood leak sensor expected response length in bytes. U32 timeoutMS; ///< Blood leak sensor receive timeout in milliseconds. U32 commandResp; ///< Blood leak sensor command response back. - U08 commandRetryCount; ///< Blood leak sensor command retry count. + U08 commandRqstCount; ///< Blood leak sensor command request count. BOOL isCmdRespRdy; ///< Blood leak sensor is command response ready flag. } EMB_MODE_CMD_T; @@ -159,6 +158,7 @@ static U08 bloodLeakSetPointSequence[ BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH ][ 2 ]; ///< Blood leak set point sequence array. static HD_BLOOD_LEAK_SENSOR_CAL_RECORD_T bloodLeakCalRecord; ///< Blood leak calibration record structure. static BOOL bloodLeakExitNormalRequested; ///< Blood leak exit normal state requested. +static U32 bloodLeakRecoveryStartTimeMS; ///< Blood leak recovery start time in milliseconds. // Embedded mode variables static BOOL bloodLeakSignalEmbModeReq; ///< Blood leak signal embedded mode has been requested. @@ -188,6 +188,7 @@ static BLOOD_LEAK_STATE_T handleBloodLeakInitState( void ); static BLOOD_LEAK_STATE_T handleBloodLeakCheckZeroAndSelfTestState( void ); static BLOOD_LEAK_STATE_T handleBloodLeakNormalState( void ); +static BLOOD_LEAK_STATE_T handleBloodLeakRecoverBloodDetectState( void ); static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeWaitForCommandState( void ); static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeSendCommandState( void ); @@ -204,6 +205,9 @@ static U32 getAvailableEmbModeQueueCount( void ); static void enqueueInfoEmbModeCmds( void ); static U16 getBloodLeakRxBytesAvailable( void ); +static void resetEmbModeCmdRqstCount( U08 cmd ); +static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ); +static BOOL isDialysateLineInBypass( void ); /*********************************************************************//** * @brief @@ -218,7 +222,7 @@ * bloodLeakEmbModeRespBuffer, bloodLeakEmbModeRespIndex, * bloodLeakExitNormalRequested, bloodLeakEmbModeCmdSeqLength, * bloodLeakEmbModeHasRxRqstBeenSent, bloodLeakEmbModeInfoCmdEnqLastTimeStamp, - * bloodLeakEmbModeInfoCmdCounter + * bloodLeakEmbModeInfoCmdCounter, bloodLeakRecoveryStartTimeMS, * @return none *************************************************************************/ void initBloodLeak( void ) @@ -251,6 +255,7 @@ bloodLeakEmbModeCmdEnqueueCount = 0; bloodLeakEmbModeInfoCmdEnqLastTimeStamp = getMSTimerCount(); bloodLeakEmbModeInfoCmdCounter = 0; + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); // Set the blood leak embedded mode command queue to zero memset( bloodLeakEmbModeCmdQ, 0x0, BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE ); @@ -267,10 +272,6 @@ // Enqueue the commands to set the embedded mode and request the set point of the blood leak sensor enqueueEmbModeCmd( CS_EMB_MODE_CMD ); enqueueEmbModeCmd( D_EMB_MODE_CMD ); - - // initialize FPGA comm failures windowed timer count - initTimeWindowedCount( TIME_WINDOWED_COUNT_BLOOD_LEAK_COMM_ERROR, MAX_BLOOD_LEAK_COMM_FAILURES, MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS); - } /*********************************************************************//** @@ -311,6 +312,10 @@ bloodLeakState = handleBloodLeakNormalState(); break; + case BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE: + bloodLeakState = handleBloodLeakRecoverBloodDetectState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BLOOD_LEAK_STATE, bloodLeakState ) bloodLeakState = BLOOD_LEAK_INIT_STATE; @@ -360,7 +365,7 @@ * zeroed. * @details Inputs: bloodLeakEmbModeCmdEnqueueCount * @details Outputs: bloodLeakEmbModeHasZeroBeenRqustd, - * bloodLeakEmbModeCmdEnqueueCount + * bloodLeakEmbModeCmdEnqueueCount, bloodLeakSelfTestStatus * @return TRUE if the zero commands were successfully queued otherwise, FALSE *************************************************************************/ BOOL zeroBloodLeak( void ) @@ -371,16 +376,16 @@ { status = TRUE; bloodLeakEmbModeHasZeroBeenRqustd = TRUE; + // Since the zero commands have been queued, reset the counter + bloodLeakEmbModeCmdEnqueueCount = 0; + bloodLeakSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; // Enqueue the zero and self test sequence (Z->G->Z->Q->T) enqueueEmbModeCmd( Z_EMB_MODE_CMD ); enqueueEmbModeCmd( G_EMB_MODE_CMD ); enqueueEmbModeCmd( Z_EMB_MODE_CMD ); enqueueEmbModeCmd( Q_EMB_MODE_CMD ); enqueueEmbModeCmd( T_EMB_MODE_CMD ); - - // Since the zero commands have been queued, reset the counter - bloodLeakEmbModeCmdEnqueueCount = 0; } else if ( ++bloodLeakEmbModeCmdEnqueueCount > BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) { @@ -392,6 +397,24 @@ /*********************************************************************//** * @brief + * The hasBloodLeakZeroSequenceFailed function returns TURE if the number + * of times the zero sequence has failed. + * @details Inputs: bloodLeakEmbModeCmd + * @details Outputs: none + * @return TRUE if zero sequence failed otherwise, FALSE + *************************************************************************/ +BOOL hasBloodLeakZeroSequenceFailed( void ) +{ + // The zero sequence contains Z->G->Z->Q->T and each of the commands has a request counter but for checking whether the + // zero sequence has failed only the Z command is checked. When the zero sequence is enqueued, all of the them enqueued so they are + // at the same request count number. + BOOL status = ( bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].commandRqstCount > BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ? TRUE : FALSE ); + + return status; +} + +/*********************************************************************//** + * @brief * The exitBloodLeakNormalState requests that the blood leak sensor to exit * its normal state. * @details Inputs: bloodLeakState @@ -453,7 +476,7 @@ } else if ( ( TRUE == bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].isCmdRespRdy ) && ( BLOOD_LEAK_EMB_MODE_FAIL_ASCII == cmdResp ) ) { - if ( ++bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].commandRetryCount < BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) + if ( bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].commandRqstCount < BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) { // Enqueue the commands to set the embedded mode and request the set point of the blood leak sensor // Since set point was requested in the init function as well, both are requested here because we have to be @@ -474,8 +497,8 @@ if ( ( getCurrentOperationMode() != MODE_INIT ) && ( TRUE == isEmbModeReady ) ) { - bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].commandRetryCount = 0; - state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + resetEmbModeCmdRqstCount( CS_EMB_MODE_CMD ); + state = BLOOD_LEAK_CHECK_SET_POINT_STATE; } return state; @@ -497,7 +520,7 @@ if ( ( bloodLeakSetPoint != bloodLeakCalRecord.setPoint ) && ( TRUE == isCommandRespReady ) ) { - if ( ++bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandRetryCount < BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) + if ( bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandRqstCount < BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) { enqueueEmbModeCmd( D_EMB_MODE_CMD ); } @@ -513,8 +536,8 @@ } else if ( TRUE == isCommandRespReady ) { - bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandRetryCount = 0; - state = BLOOD_LEAK_INIT_STATE; + resetEmbModeCmdRqstCount( D_EMB_MODE_CMD ); + state = BLOOD_LEAK_INIT_STATE; } return state; @@ -535,7 +558,8 @@ // Check if the zero command has been requested if ( TRUE == bloodLeakEmbModeHasZeroBeenRqustd ) { - state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; + bloodLeakEmbModeHasZeroBeenRqustd = FALSE; + state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; } return state; @@ -581,7 +605,6 @@ // Enqueue the zero and self test sequence (Z->G->Z->Q->T) BOOL hasCmdSqncFailed = FALSE; BOOL hasCurrCmdFailed = FALSE; - U08 failedCmd; for ( i = 0; i < NUM_OF_EMB_CMDS; i++ ) { @@ -593,14 +616,12 @@ // Check to see if any of the command responses failed hasCurrCmdFailed = ( BLOOD_LEAK_EMB_MODE_PASS_ASCII == bloodLeakEmbModeCmd[ i ].commandResp ? FALSE : TRUE ); hasCmdSqncFailed |= hasCurrCmdFailed; - failedCmd = ( TRUE == hasCurrCmdFailed ? i : NU_EMB_MODE_CMD ); break; case G_EMB_MODE_CMD: // G command will return a value that has to be greater than 0 hasCurrCmdFailed = ( bloodLeakEmbModeCmd[ i ].commandResp > 0 ? FALSE : TRUE ); hasCmdSqncFailed |= hasCurrCmdFailed; - failedCmd = ( TRUE == hasCurrCmdFailed ? i : NU_EMB_MODE_CMD ); break; default: @@ -613,35 +634,20 @@ if ( FALSE == hasCmdSqncFailed ) { // Done with zero sequence, transition to other states - bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].commandRetryCount = 0; - bloodLeakEmbModeHasZeroBeenRqustd = FALSE; - bloodLeakSelfTestStatus = SELF_TEST_STATUS_PASSED; - state = BLOOD_LEAK_NORMAL_STATE; + resetEmbModeCmdRqstCount( Z_EMB_MODE_CMD ); + resetEmbModeCmdRqstCount( G_EMB_MODE_CMD ); + resetEmbModeCmdRqstCount( Q_EMB_MODE_CMD ); + resetEmbModeCmdRqstCount( T_EMB_MODE_CMD ); + bloodLeakSelfTestStatus = SELF_TEST_STATUS_PASSED; + state = BLOOD_LEAK_NORMAL_STATE; } // If not successful, retry if we've not run out - else if ( bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].commandRetryCount < BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) - { - if ( TRUE == zeroBloodLeak() ) - { - // Check if the zero sequence has been successfully enqueued - // If the command retry of one of the commands in the zero sequence failed, it means all of them have failed - // So in this condition only the Z command is checked - bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].commandRetryCount++; - } - } - // If out of retries, fault else { -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) -#endif - { - bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; - state = BLOOD_LEAK_INIT_STATE; - - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BLOOD_LEAK_SENSOR_ZERO_SEQUENCE_FAILED, failedCmd ); - } + bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; + state = BLOOD_LEAK_INIT_STATE; } + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BLOOD_LEAK_SELF_TEST_RESULT, bloodLeakSelfTestStatus, state ); } return state; @@ -654,68 +660,60 @@ * @details Inputs: bloodLeakStatus, bloodLeakPersistenceCtr, * bloodLeakExitNormalRequested * @details Outputs: bloodLeakStatus, bloodLeakPersistenceCtr, - * bloodLeakExitNormalRequested, bloodLeakEmbModeHasZeroBeenRqustd + * bloodLeakExitNormalRequested, bloodLeakEmbModeHasZeroBeenRqustd, + * bloodLeakRecoveryStartTimeMS * @return next state *************************************************************************/ static BLOOD_LEAK_STATE_T handleBloodLeakNormalState( void ) { BLOOD_LEAK_STATE_T state = BLOOD_LEAK_NORMAL_STATE; - // If the blood leak status bit is low (0) it means blood has not been detected, otherwise, blood has been detected - bloodLeakStatus.data = ( BLOOD_LEAK_STATUS_BIT_LOW == getFPGABloodLeakStatus() ? BLOOD_LEAK_NOT_DETECTED : BLOOD_LEAK_DETECTED ); + bloodLeakStatus.data = getFPGABloodDetectProcessedStatus(); -#ifdef DIALYZER_REPRIME_ENABLED -// exempt blood leak alarm while performing a dialyzer de-prime as air will be pushed past sensor and appear to be blood -if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( DIALYSIS_DIALYZER_REPRIME_STATE == getDialysisState() ) ) -{ - bloodLeakPersistenceCtr = 0; -} -else -{ -#endif - if ( STATE_OPEN == getSwitchStatus( PUMP_TRACK_SWITCH ) ) { // If the pump track on open, zero the persistent counter to not check the blood leak alarm bloodLeakPersistenceCtr = 0; } - // Check status reading and act upon - if ( ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) && ( MODE_TREA == getCurrentOperationMode() ) ) + switch ( getCurrentOperationMode() ) { - if ( ++bloodLeakPersistenceCtr > BLOOD_LEAK_PERSISTENCE ) - { - bloodLeakPersistenceCtr = BLOOD_LEAK_PERSISTENCE; -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) -#endif + case MODE_TREA: + case MODE_SERV: + if ( FALSE == isDialysateLineInBypass() ) { - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); - exitBloodLeakNormalState(); // so we don't keep triggering after user clears it (rinseback or end tx). - } - } - } - else // Blood leak not detected - { - if ( bloodLeakPersistenceCtr > 0 ) - { - bloodLeakPersistenceCtr--; - } - else - { + if ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) + { + if ( ++bloodLeakPersistenceCtr > BLOOD_LEAK_PERSISTENCE ) + { + bloodLeakPersistenceCtr = BLOOD_LEAK_PERSISTENCE; #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif - { - clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); + state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + } + } + } + else if ( bloodLeakPersistenceCtr > 0 ) + { + bloodLeakPersistenceCtr--; + } + else + { + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + } } - } + + default: + // Do nothing. Do not check for blood in other modes. + break; } -#ifdef DIALYZER_REPRIME_ENABLED -} -#endif - if ( TRUE == bloodLeakExitNormalRequested ) { bloodLeakExitNormalRequested = FALSE; @@ -724,14 +722,62 @@ else if ( TRUE == bloodLeakEmbModeHasZeroBeenRqustd ) { // Check whether zeroing the sensor has been requested or not if yes, transition to zero command state otherwise, stay in this state - state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; + bloodLeakEmbModeHasZeroBeenRqustd = FALSE; + state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; } return state; } /*********************************************************************//** * @brief + * The handleBloodLeakRecoverBloodDetectState function handles the blood + * leak recover blood detect state. + * @details Inputs: bloodLeakStatus, bloodLeakRecoveryStartTimeMS, + * bloodLeakEmbModeHasZeroBeenRqustd, bloodLeakExitNormalRequested + * @details Outputs: bloodLeakStatus, bloodLeakRecoveryStartTimeMS, + * bloodLeakPersistenceCtr, bloodLeakEmbModeHasZeroBeenRqustd, + * bloodLeakExitNormalRequested + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakRecoverBloodDetectState( void ) +{ + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + + bloodLeakStatus.data = getFPGABloodDetectProcessedStatus(); + + if ( BLOOD_LEAK_NOT_DETECTED == getBloodLeakStatus() ) + { + if ( TRUE == didTimeout( bloodLeakRecoveryStartTimeMS, BLOOD_LEAK_DETECT_RECOVERY_MIN_TIME_MS ) ) + { + // Blood has not been detected for the specified period of time so clear the alarm condition + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + } + } + else + { + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); + } + + if ( isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ) != TRUE ) + { + // Once the user hit resume, transition back to normal state to continue detecting for blood + // Reset the blood detect counter prior to transitioning back + bloodLeakPersistenceCtr = 0; + state = BLOOD_LEAK_NORMAL_STATE; + } + else if ( TRUE == bloodLeakEmbModeHasZeroBeenRqustd ) + { + // Check whether zeroing the sensor has been requested or not if yes, transition to zero command state otherwise, stay in this state + bloodLeakEmbModeHasZeroBeenRqustd = FALSE; + state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief * The getBloodLeakStatus function gets the current reading for the blood * leak detector. * @details Inputs: bloodLeakStatus @@ -787,8 +833,10 @@ if ( FALSE == isEmbModeCmdQueueEmpty() ) { + U08 commandASCII = 0; + bloodLeakEmbModeRqstedCmd = dequeueEmbModeCmd(); - U08 commandASCII = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].commandASCII; + commandASCII = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].commandASCII; switch( bloodLeakEmbModeRqstedCmd ) { @@ -1052,16 +1100,10 @@ bloodLeakEmbModeRespBuffer[ 0 ] = BLOOD_LEAK_EMB_MODE_FAIL_ASCII; convertString2Integer( bloodLeakEmbModeRqstedCmd, length ); - sendBloodLeakEmbeddedModeCommandResponse( bloodLeakEmbModeRqstedCmd, length, bloodLeakEmbModeRespBuffer ); bloodLeakEmbModeRqstedCmd = NU_EMB_MODE_CMD; state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE; - - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_BLOOD_LEAK_COMM_ERROR ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_BLOOD_LEAK_FPGA_FAULT, MAX_BLOOD_LEAK_COMM_FAILURES, (U32)MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS ) - } } return state; @@ -1263,7 +1305,8 @@ * @brief * The publishBloodLeakData function publishes blood leak data at the set interval. * @details Inputs: bloodLeakDataPublicationTimerCounter - * @details Outputs: bloodLeakDataPublicatimerCouonTinter + * @details Outputs: bloodLeakDataPublicatimerCouonTinter, bloodLeakPersistenceCtr, + * bloodLeakState * @return none *************************************************************************/ static void publishBloodLeakData( void ) @@ -1275,7 +1318,8 @@ data.bloodLeakStatus = (U32)getBloodLeakStatus(); data.bloodLeakState = (U32)bloodLeakState; - data.bloodLeakPersitentCounter = bloodLeakPersistenceCtr; + data.bloodLeakPersistentCounter = bloodLeakPersistenceCtr; + data.bloodLeakSerialCommState = bloodLeakEmbModeSubstate; bloodLeakDataPublicationCounter = 0; broadcastData( MSG_ID_HD_BLOOD_LEAK_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( BLOOD_LEAK_DATA_T ) ); @@ -1398,6 +1442,7 @@ * @details Inputs: none * @details Outputs: bloodLeakEmbModeCmdQRearIndex, bloodLeakEmbModeCmdQCount * bloodLeakEmbModeCmdQ, bloodLeakEmbModeCmd + * @param cmd the command to enqueue * @return none *************************************************************************/ static void enqueueEmbModeCmd( U08 cmd ) @@ -1407,11 +1452,26 @@ bloodLeakEmbModeCmdQ[ bloodLeakEmbModeCmdQRearIndex ] = cmd; bloodLeakEmbModeCmdQRearIndex = INC_WRAP( bloodLeakEmbModeCmdQRearIndex, 0, BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE - 1 ); bloodLeakEmbModeCmd[ cmd ].isCmdRespRdy = FALSE; + bloodLeakEmbModeCmd[ cmd ].commandRqstCount++; bloodLeakEmbModeCmdQCount++; } /*********************************************************************//** * @brief + * The resetEmbModeCmdRqstCount function resets embedded mode command request + * count. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeCmd + * @param cmd the command to reset its request count + * @return none + *************************************************************************/ +static void resetEmbModeCmdRqstCount( U08 cmd ) +{ + bloodLeakEmbModeCmd[ cmd ].commandRqstCount = 0; +} + +/*********************************************************************//** + * @brief * The dequeueEmbModeCmd function dequeues the embedded mode command. * @details Inputs: none * @details Outputs: bloodLeakEmbModeCmdQFrontIndex, bloodLeakEmbModeCmdQCount @@ -1482,10 +1542,10 @@ static void enqueueInfoEmbModeCmds( void ) { if ( ( TRUE == didTimeout( bloodLeakEmbModeInfoCmdEnqLastTimeStamp, BLOOD_LEAK_EMB_MODE_INFO_CMD_TIMOUE_MS ) ) && - ( bloodLeakState >= BLOOD_LEAK_INIT_STATE ) ) + ( bloodLeakState >= BLOOD_LEAK_INIT_STATE ) && ( bloodLeakState != BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE ) ) { - // Enqueue the next command. Make sure the blood leak state is greater than init state since in the post state and - // check for set point, other commands are being enqueued for checking + // Enqueue the next command. Make sure the blood leak state is greater than init state and it is not the zero and self test state + // to make sure setting the embedded mode and getting the set point and zero sequence should go undisturbed. if ( 0 == bloodLeakEmbModeInfoCmdCounter ) { enqueueEmbModeCmd( I_EMB_MODE_CMD ); @@ -1519,7 +1579,41 @@ return getFPGABloodLeakRxFIFOCount() & BLOOD_LEAK_RXFIFO_COUNT_MASK; } +/*********************************************************************//** + * @brief + * The getFPGABloodDetectProcessedStatus function returns the status of the + * blood detect from FPGA meaning the status that is read from the sensor. + * @details Inputs: none + * @details Outputs: none + * @return BLOOD_LEAK_NOT_DETECTED if blood has not been detected otherwise, + * BLOOD_LEAK_DETECTED + *************************************************************************/ +static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ) +{ + // If the blood leak status bit is low (0) it means blood has not been detected, otherwise, blood has been detected + return ( BLOOD_LEAK_STATUS_BIT_LOW == getFPGABloodLeakStatus() ? BLOOD_LEAK_NOT_DETECTED : BLOOD_LEAK_DETECTED ); +} +/*********************************************************************//** + * @brief + * The isDialysateLineInBypass function checks and returns whether the + * dialysate line is in bypass mode or not. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if the dialysate line is in bypass otherwise, FALSE + *************************************************************************/ +static BOOL isDialysateLineInBypass( void ) +{ + BOOL status = TRUE; + + status &= ( VALVE_POSITION_C_CLOSE == getValvePosition( VDI ) ? TRUE : FALSE ); + status &= ( VALVE_POSITION_C_CLOSE == getValvePosition( VDO ) ? TRUE : FALSE ); + status &= ( getMeasuredDialInPumpSpeed() <= NEARLY_ZERO ? TRUE : FALSE ); + + return status; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/