Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r736cc5b56cc9c784ab1d8fc8687a73d190c35759 -r7e590c10900e46008d6fd4f1c98d85b368ae0fa7 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 736cc5b56cc9c784ab1d8fc8687a73d190c35759) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 7e590c10900e46008d6fd4f1c98d85b368ae0fa7) @@ -88,11 +88,21 @@ #define BLOOD_LEAK_EMB_MODE_ZERO_CMD_RQRD_Q 5 ///< Blood leak embedded mode zero command required queue count. #define BLOOD_LEAK_EMB_MODE_NUM_OF_RETRIES 3 ///< Blood leak embedded mode number of retries to enqueue. #define BLOOD_LEAK_EMB_MODE_INFO_CMD_TIMOUE_MS ( 2 * MS_PER_SECOND ) ///< Blood leak embedded mode informative command timeout in milliseconds. -#define BLOOD_LEAK_EMB_MODE_NUM_OF_INFO_CMDS 3 ///< Blood leak embedded mode number of informative commands. +#define BLOOD_LEAK_EMB_MODE_NUM_OF_INFO_CMDS 2 ///< Blood leak embedded mode number of informative commands. #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 BLOOD_LEAK_RXFIFO_COUNT_MASK 0x03FF ///< Mask high order bits of blood leak sensor rx count. +// ***************** zeroing status *************** // + +#define BLD_NOMINAL_INTENSITY 930 ///< Blood leak nominal intensity. +#define BLD_MAX_INTENSITY_OUT_OF_RANGE 0.35F ///< Blood leak maximum allowed intensity. +#define BLD_MIN_INTENSITY_OUT_OF_RANGE 0.40F ///< Blood leak minimum allowed intensity. +#define BLD_SHIFT_BITS_BY_4_FOR_AVERAGING 4U ///< Blood leak shift values by 4 to average them. +#define BLD_ZERO_INTERVAL_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Blood leak zeroing interval in milliseconds. +#define BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES 16 ///< Blood leak number of moving average samples. +#define BLD_ZERO_IN_RANGE_DRIFT_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak zero value drift in range timeout in milliseconds. + /// Defined states for the blood leak detector state machine. typedef enum BloodLeakStates { @@ -143,6 +153,18 @@ BOOL isCmdRespRdy; ///< Blood leak sensor is command response ready flag. } EMB_MODE_CMD_T; +/// Blood leak zeroing status data structure +typedef struct +{ + U32 lastZeroingStartTimeMS; ///< Blood leak last zero sequence start time in milliseconds. + U32 driftInRangeStartTimeMS; + BOOL hasDriftTimerBeenSet; + U32 rawIntensity[ BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES ]; + U32 intensityRunningSum; + U32 rawIntensityNextIndex; + U32 intensityMovingAverage; +} BLOOD_LEAK_ZEROING_STATUS_T; + // ********** private data ********** static BLOOD_LEAK_STATE_T bloodLeakState; ///< Current state of blood leak state machine. @@ -159,6 +181,7 @@ 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. +static BLOOD_LEAK_ZEROING_STATUS_T bloodLeakZeroingStatus; ///< Blood leak zeroing status. // Embedded mode variables static BOOL bloodLeakSignalEmbModeReq; ///< Blood leak signal embedded mode has been requested. @@ -208,6 +231,8 @@ static void resetEmbModeCmdRqstCount( U08 cmd ); static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ); static BOOL isDialysateLineInBypass( void ); +static void processBloodLeakIntensityData( void ); +static void checkBloodLeakDrift( void ); /*********************************************************************//** * @brief @@ -223,6 +248,7 @@ * bloodLeakExitNormalRequested, bloodLeakEmbModeCmdSeqLength, * bloodLeakEmbModeHasRxRqstBeenSent, bloodLeakEmbModeInfoCmdEnqLastTimeStamp, * bloodLeakEmbModeInfoCmdCounter, bloodLeakRecoveryStartTimeMS, + * bloodLeakZeroingStatus * @return none *************************************************************************/ void initBloodLeak( void ) @@ -269,6 +295,9 @@ // Initialize the blood leak embedded mode command sequence memset( bloodLeakEmbModeCmdSeq, 0x0, BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH ); + // Initialize the blood leak zeroing sequence status structure + memset( &bloodLeakZeroingStatus, 0x0, sizeof( BLOOD_LEAK_ZEROING_STATUS_T ) ); + // 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 ); @@ -290,6 +319,8 @@ getNVRecord2Driver( GET_CAL_BLOOD_LEAK_SENSOR, (U08*)&bloodLeakCalRecord, length, 0, ALARM_ID_HD_BLOOD_LEAK_INVALID_CAL_RECORD ); } + processBloodLeakIntensityData(); // TODO is this the right place? + switch( bloodLeakState ) { case BLOOD_LEAK_WAIT_FOR_POST_STATE: @@ -692,6 +723,8 @@ bloodLeakPersistenceCtr = 0; } + checkBloodLeakDrift(); + switch ( getCurrentOperationMode() ) { case MODE_TREA: @@ -1329,10 +1362,14 @@ { BLOOD_LEAK_DATA_T data; - data.bloodLeakStatus = (U32)getBloodLeakStatus(); - data.bloodLeakState = (U32)bloodLeakState; - data.bloodLeakPersistentCounter = bloodLeakPersistenceCtr; - data.bloodLeakSerialCommState = bloodLeakEmbModeSubstate; + data.bloodLeakStatus = (U32)getBloodLeakStatus(); + data.bloodLeakState = (U32)bloodLeakState; + data.bloodLeakPersistentCounter = bloodLeakPersistenceCtr; + data.bloodLeakSerialCommState = bloodLeakEmbModeSubstate; + data.bloodLeakIntensity = bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].commandResp; + data.bloodLeakDetect = bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].commandResp; + data.bloodLeakIntensityMovingAvg = bloodLeakZeroingStatus.intensityMovingAverage; + bloodLeakDataPublicationCounter = 0; broadcastData( MSG_ID_HD_BLOOD_LEAK_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( BLOOD_LEAK_DATA_T ) ); @@ -1567,10 +1604,10 @@ { enqueueEmbModeCmd( V_EMB_MODE_CMD ); } - else if ( 2 == bloodLeakEmbModeInfoCmdCounter ) - { - enqueueEmbModeCmd( D_EMB_MODE_CMD ); - } + //else if ( 2 == bloodLeakEmbModeInfoCmdCounter ) + //{ + // enqueueEmbModeCmd( D_EMB_MODE_CMD ); + //} // Set the timer for the next time out to enqueue // Reset the counter. The counter starts from 0 @@ -1626,7 +1663,75 @@ return status; } +/*********************************************************************//** + * @brief + * The processBloodLeakIntensityData function calculates the moving average + * of blood leak intensity data. + * @details Inputs: none + * @details Outputs: bloodLeakZeroingStatus + * @return none + *************************************************************************/ +static void processBloodLeakIntensityData( void ) +{ + if ( TRUE == bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].isCmdRespRdy ) + { + U32 index = bloodLeakZeroingStatus.rawIntensityNextIndex; + U32 indexValue = bloodLeakZeroingStatus.rawIntensity[ index ]; + U32 newIntensity = bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].commandResp; + bloodLeakZeroingStatus.rawIntensity[ index ] = newIntensity; + bloodLeakZeroingStatus.intensityRunningSum = bloodLeakZeroingStatus.intensityRunningSum - indexValue + newIntensity; + bloodLeakZeroingStatus.intensityMovingAverage = bloodLeakZeroingStatus.intensityRunningSum >> BLD_SHIFT_BITS_BY_4_FOR_AVERAGING; + bloodLeakZeroingStatus.rawIntensityNextIndex = INC_WRAP( index, 0, BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES - 1 ); + } +} + +/*********************************************************************//** + * @brief + * The checkBloodLeakDrift function checks for blood leak drift and if the + * conditions are met, it proceeds with requesting the zero sequence again. + * @details Inputs: bloodLeakZeroingStatus + * @details Outputs: bloodLeakZeroingStatus + * @return none + *************************************************************************/ +static void checkBloodLeakDrift( void ) +{ + BOOL isDriftInRange = TRUE; + U32 setPoint = bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].commandResp; + F32 driftUpper = setPoint * BLD_MAX_INTENSITY_OUT_OF_RANGE; + F32 driftLower = setPoint * BLD_MIN_INTENSITY_OUT_OF_RANGE; + F32 intensityDrift = BLD_NOMINAL_INTENSITY - bloodLeakZeroingStatus.intensityMovingAverage; + BOOL isZeroingAllowed = didTimeout( bloodLeakZeroingStatus.lastZeroingStartTimeMS, BLD_ZERO_INTERVAL_MS ); + + isDriftInRange &= ( intensityDrift <= driftUpper ? TRUE : FALSE ); + isDriftInRange &= ( intensityDrift >= driftLower ? TRUE : FALSE ); + + if ( TRUE == isDriftInRange ) + { + if ( FALSE == bloodLeakZeroingStatus.hasDriftTimerBeenSet ) + { + bloodLeakZeroingStatus.driftInRangeStartTimeMS = getMSTimerCount(); + bloodLeakZeroingStatus.hasDriftTimerBeenSet = TRUE; + } + } + else + { + bloodLeakZeroingStatus.driftInRangeStartTimeMS = getMSTimerCount(); + bloodLeakZeroingStatus.hasDriftTimerBeenSet = FALSE; + } + + if ( ( TRUE == isZeroingAllowed ) && ( TRUE == didTimeout( bloodLeakZeroingStatus.driftInRangeStartTimeMS, BLD_ZERO_IN_RANGE_DRIFT_TIMEOUT_MS ) ) ) + { + BOOL status = zeroBloodLeak(); + + if ( TRUE == status ) + { + bloodLeakZeroingStatus.lastZeroingStartTimeMS = getMSTimerCount(); + } + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/BloodLeak.h =================================================================== diff -u -r20d0c02f453b6dae1884fb1b5ba542053852ffc1 -r7e590c10900e46008d6fd4f1c98d85b368ae0fa7 --- firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision 20d0c02f453b6dae1884fb1b5ba542053852ffc1) +++ firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision 7e590c10900e46008d6fd4f1c98d85b368ae0fa7) @@ -48,6 +48,9 @@ U32 bloodLeakState; ///< Blood leak detector state. U32 bloodLeakPersistentCounter; ///< Blood leak detector persistent counter. U32 bloodLeakSerialCommState; ///< Blood leak detector serial communication state. + U32 bloodLeakIntensity; ///< Blood leak detector intensity. + U32 bloodLeakDetect; ///< Blood leak detector detect. + U32 bloodLeakIntensityMovingAvg; ///< Blood leak detector intensity moving average. } BLOOD_LEAK_DATA_T; // ********** public function prototypes **********