Index: firmware/App/Monitors/BloodLeak.c =================================================================== diff -u --- firmware/App/Monitors/BloodLeak.c (revision 0) +++ firmware/App/Monitors/BloodLeak.c (revision bc4537c14a446c8fe1720f574200399b180a6ff9) @@ -0,0 +1,2254 @@ + + +#include // For pow function +#include // For memset and strlen +#include // For sprintf + +#include "AlarmMgmtDD.h" +#include "BloodLeak.h" +#include "FpgaDD.h" +#include "Messaging.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "TaskPriority.h" +#include "Timers.h" +#include "Utilities.h" + +/** + * @addtogroup BloodLeak + * @{ + */ + +// ********** private definitions ********** + +#define BLOOD_LEAK_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the blood leak data is published on the CAN bus. +#define BLOOD_LEAK_PERSISTENCE ( 10 * MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Persistence for blood leak detected alarm. +#define BLOOD_LEAK_RESET_TX_FIFO 2 ///< Blood leak reset transmit FIFO command. +#define BLOOD_LEAK_UART_COMM_ACTIVE_LOW 0 ///< Blood leak UART communication active low command. +#define BLOOD_LEAK_UART_COMM_ACTIVE_HIGH 1 ///< Blood leak UART communication active high command. + +#define BLOOD_LEAK_SET_POINT_MAX_CHAR_LENGTH 11 ///< Blood leak set point maximum character length. +#define BLOOD_LEAK_SET_POINT_START_CHAR_ASCII 83 ///< Blood leak set point sequence start character in ASCII (letter S). +#define BLOOD_LEAK_STOP_WRITE_FIFO_COMMAND 0 ///< Blood leak set point stop writing to FIFO command. +#define BLOOD_LEAK_SET_POINT_START_CHAR_INDEX 0 ///< Blood leak set point sequence start character index number. +#define BLOOD_LEAK_CARRIAGE_RETURN_ASCII 13 ///< Blood leak set point sequence carriage return character in ASCII. +#define BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH 17 ///< Blood leak set point sequence maximum length. + +#define BLOOD_LEAK_ZERO_CMD_STATUS_READY 0x80 ///< Blood leak zero command status ready value. +#define BLOOD_LEAK_SELF_TEST_CMD_STATUS_READY 0x80 ///< Blood leak self test command status ready value. +#define BLOOD_LEAK_STATUS_BIT_HIGH 1 ///< Blood leak status bit high. +#define BLOOD_LEAK_STATUS_BIT_LOW 0 ///< Blood leak status bit low. +#define BLOOD_LEAK_ZERO_CMD_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak zero command timeout in milliseconds. +#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. +#define BLOOD_LEAK_EMB_MODE_RQST_RX_LENGTH 2 ///< Blood leak embedded mode request new Rx data length. +#define BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_HIGH 5 ///< Blood leak embedded mode communication active high command. +#define BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_LOW 4 ///< Blood leak embedded mode communication active low command. +#define BLOOD_LEAK_EMB_MODE_COMM_RESET 6 ///< Blood leak embedded mode communication reset. +#define BLOOD_LEAK_EMB_MODE_COMM_READ_REQST 12 ///< Blood leak embedded mode communication read Rx byte request. +#define BLOOD_LEAK_EMB_MODE_RX_BUFFER_EMPTY 0x80 ///< Blood leak embedded mode buffer empty value. +#define BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN 5 ///< Blood leak embedded mode number of commands. +#define BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES 3 ///< Blood leak embedded mode max number of command tries. +#define BLOOD_LEAK_EMB_MODE_0_NUM_ASCII 48 ///< Blood leak embedded mode character 0 in ASCII. +#define BLOOD_LEAK_EMB_MODE_9_NUM_ASCII 57 ///< Blood leak embedded mode character 9 in ASCII. +#define BLOOD_LEAK_EMB_MODE_SET_PNT_RESP_LEN 4 ///< Blood leak embedded mode set point response length. +#define BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX 0 ///< Blood leak embedded mode command (UART/Transmit) column index number. +#define BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX 1 ///< Blood leak embedded mode is command type UART or transmit flag. +#define BLOOD_LEAK_EMB_MODE_PASS_ASCII 80 ///< Blood leak embedded mode P (pass) in ASCII. +#define BLOOD_LEAK_EMB_MODE_FAIL_ASCII 70 ///< Blood leak embedded mode F (fail) in ASCII. + +#define BLOOD_LEAK_EMB_MODE_RESET_INDEX 0 ///< Blood leak embedded mode reset FIFO command index. +#define BLOOD_LEAK_EMB_MODE_CMD_INDEX 2 ///< Blood leak embedded mode command index. +#define BLOOD_LEAK_EMB_MODE_STOP_WRITE_INDEX 3 ///< Blood leak embedded mode stop write to FIFO index. +#define BLOOD_LEAK_EMB_MODE_ACTIVE_HIGH_INDEX 4 ///< Blood leak embedded mode active high command index. +#define BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX 0 ///< Blood leak embedded mode request Rx to read index. +#define BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE 12 ///< Blood leak embedded mode command queue maximum size. +#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_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Blood leak embedded mode informative command timeout in milliseconds. +#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. + +// ***************** zeroing status *************** // + +#define BLD_NOMINAL_INTENSITY 930 ///< Blood leak nominal intensity. +#define BLD_MAX_INTENSITY_DRFT_AFTER_ZEROING 10 ///< Blood leak max intensity drift after zeroing. +#define BLD_MAX_INTENSITY_OUT_OF_RANGE 0.40F ///< Blood leak maximum allowed intensity. +#define BLD_MIN_INTENSITY_OUT_OF_RANGE 0.35F ///< Blood leak minimum allowed intensity. +#define BLD_ZERO_MIN_INTERVAL_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Blood leak zeroing minimum 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 ( 10 * MS_PER_SECOND ) ///< Blood leak zero value drift in range timeout in milliseconds. +#define BLD_MAX_UPPER_INTENSITY_DRIFT ( BLD_NOMINAL_INTENSITY + 20 ) ///< Blood leak maximum upper range intensity drift. +#define BLD_START_OF_TX_MIN_INTENSITY_DRIFT 915 ///< Blood leak start of treatment minimum intensity. +#define BLD_UPPER_INTENSITY_INTERVAL_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Blood leak upper drift interval in milliseconds. +#define BLD_ZERO_UPPER_RANGE_DRIFT_TIMEOUT_MS ( 60 * MS_PER_SECOND ) ///< Blood leak zero upper range drift timeout in milliseconds. + +/// Defined states for the blood leak detector state machine. +typedef enum BloodLeakStates +{ + BLOOD_LEAK_WAIT_FOR_POST_STATE = 0, ///< Blood leak wait for post state. + BLOOD_LEAK_CHECK_SET_POINT_STATE, ///< Blood leak check set point state. + BLOOD_LEAK_INIT_STATE, ///< Blood leak init state. + BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE, ///< Blood leak check for zero and self test commands state. + BLOOD_LEAK_VERIFY_INTENSITY_AFTER_ZEROING_STATE, ///< Blood leak verify intensity after zeroing state. + BLOOD_LEAK_NORMAL_STATE, ///< Blood leak 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; + +/// Defined embedded states +typedef enum EmbStates +{ + BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE = 0, ///< Blood leak embedded mode state wait for command state. + BLOOD_LEAK_EMB_MODE_SEND_COMMAND_STATE, ///< Blood leak embedded mode state send command state. + BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMMAND_RESPONSE_STATE, ///< Blood leak embedded mode state wait for command response state. + NUM_OF_BLOOD_LEAK_EMB_MODE_STATES ///< Number of blood leak embedded mode states. +} BLOOD_LEAK_EMB_MODE_STATE_T; + +/// Blood leak detector embedded mode commands +typedef enum EmbCommands +{ + NU_EMB_MODE_CMD = 0, ///< Null command. + CS_EMB_MODE_CMD, ///< Control S command to switch to embedded mode. + SP_EMB_MODE_CMD, ///< Set point command to set the set point. + T_EMB_MODE_CMD, ///< Self test command. + G_EMB_MODE_CMD, ///< Get self test command. + I_EMB_MODE_CMD, ///< Intensity command. + V_EMB_MODE_CMD, ///< Blood detection level command. + Z_EMB_MODE_CMD, ///< Zero sensor command. + Q_EMB_MODE_CMD, ///< Zero sensor confirm command. + D_EMB_MODE_CMD, ///< Display blood detection command. + C_EMB_MODE_CMD, ///< Calibration sensor command. + NUM_OF_EMB_CMDS, ///< Number of embedded mode commands. +} BLOOD_LEAK_EMB_MODE_CMD_T; + +/// Embedded mode commands specifications +typedef struct +{ + U08 commandASCII; ///< Blood leak sensor command ID number in ASCII. + U08 expChar1; ///< Blood leak sensor expected response in character. + U08 expChar2; ///< Blood leak sensor expected response in character. + 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 commandRqstCount; ///< Blood leak sensor command request count. + 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 driftInRangeDebounceTimeMS; ///< Blood leak drift is in range debounce start time in milliseconds. + U32 rawIntensity[ BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES ]; ///< Blood leak raw intensity array. + U32 intensityRunningSum; ///< Blood leak intensity running sum for moving average. + U32 rawIntensityNextIndex; ///< Blood leak raw intensity next index for moving average. + OVERRIDE_F32_T intensityMovingAverage; ///< Blood leak intensity moving average. + OVERRIDE_U32_T zeroingDriftIntervalTimeMS; ///< Blood leak zeroing interval time in milliseconds. + OVERRIDE_U32_T zeroingUpperRangeIntervalTimeMS; ///< BLood leak zeroing upper range interval time in milliseconds. + U32 driftUpperRangeDebounceTimeMS; ///< Blood leak drift in upper range debounce time in milliseconds. + U32 driftInRangeStatus; + U32 driftUpperRangeStatus; +} BLOOD_LEAK_ZEROING_STATUS_T; + +// ********** private data ********** + +static BLOOD_LEAK_STATE_T bloodLeakState; ///< Current state of blood leak state machine. +static OVERRIDE_U32_T bloodLeakStatus; ///< Detected blood leak status for blood leak detector. +static SELF_TEST_STATUS_T bloodLeakSelfTestStatus; ///< Current status of blood leak self-test. +static U32 bloodLeakPersistenceCtr; ///< Blood leak alarm persistence timer counter. +static OVERRIDE_U32_T bloodLeakDataPublishInterval = { BLOOD_LEAK_PUB_INTERVAL, + BLOOD_LEAK_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish blood leak data to CAN bus. +static U32 bloodLeakDataPublicationCounter; ///< Timer counter used to schedule blood leak data publication to CAN bus. +static U32 bloodLeakUARTCmdIndex; ///< Blood leak UART command index. +static U32 bloodLeakSetPointSeqLength; ///< Blood leak set point sequence actual length. +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. // TODO uncomment +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. +static U08 bloodLeakEmbModeRqstedCmd; ///< Blood leak signal embedded mode requested command. +static U08 bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH ][ 2 ]; ///< Blood leak embedded mode command sequence. +static BLOOD_LEAK_EMB_MODE_STATE_T bloodLeakEmbModeSubstate; ///< Blood leak embedded mode state. +static U32 bloodLeakEmbModeOpsStartTime; ///< Blood leak embedded mode operations start time. +static U16 bloodLeakEmbModeSetPoint; ///< Blood leak embedded mode set point command. +static EMB_MODE_CMD_T bloodLeakEmbModeCmd[ NUM_OF_EMB_CMDS ]; ///< Blood leak embedded mode commands. +static U08 bloodLeakEmbModeRespBuffer[ BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ]; ///< Blood leak embedded mode response buffer. +static U32 bloodLeakEmbModeRespIndex; ///< Blood leak embedded mode response buffer index. +static U32 bloodLeakEmbModeCmdSeqLength; ///< Blood leak embedded mode command sequence length. +static BOOL bloodLeakEmbModeHasRxRqstBeenSent; ///< Blood leak embedded mode Rx request has been sent signal. +static U08 bloodLeakEmbModeCmdQ[ BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE ]; ///< Blood leak embedded mode command queue. +static U08 bloodLeakEmbModeCmdQRearIndex; ///< Blood leak embedded mode command queue rear index. +static U08 bloodLeakEmbModeCmdQFrontIndex; ///< Blood leak embedded mode command queue front index. +static U08 bloodLeakEmbModeCmdQCount; ///< Blood leak embedded mode command queue count. +static BOOL bloodLeakEmbModeHasZeroBeenRqustd; ///< Blood leak embedded mode flag to indicate zero has been requested. +static U32 bloodLeakEmbModeCmdEnqueueCount; ///< Blood leak embedded mode command enqueue count. +static U32 bloodLeakEmbModeInfoCmdEnqLastTimeStamp; ///< Blood leak embedded mode informative command (i.e. I, V, D) timer. +static U32 bloodLeakEmbModeInfoCmdCounter; ///< Blood leak embedded mode informative command counter. +static OVERRIDE_U32_T bloodLeakEmbModeIntensityOverride; ///< Blood leak embedded mode intensity override. +static OVERRIDE_U32_T bloodLeakEmbModeDetectOverride; ///< Blood leak embedded mode blood detect override. + +// ********** private function prototypes ********** + +static BLOOD_LEAK_STATE_T handleBloodLeakWaitForPostState( void ); +static BLOOD_LEAK_STATE_T handleBloodLeakCheckSetPointState( void ); +static BLOOD_LEAK_STATE_T handleBloodLeakInitState( void ); +static BLOOD_LEAK_STATE_T handleBloodLeakCheckZeroAndSelfTestState( void ); +static BLOOD_LEAK_STATE_T handleBloodLeakVerifyIntensityAfterZeroingState( 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 ); +static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeWaitForCommandResponseState( void ); + +static void processReceivedEmbModeChar( U08 data ); +static void convertString2Integer( U08 cmd, U32 respLength ); +static void prepareSetPointSeq( U16 setPoint ); +static void publishBloodLeakData( void ); +static void initEmbModeSpecs( void ); +static void enqueueEmbModeCmd( U08 cmd ); +static U08 dequeueEmbModeCmd( void ); +static BOOL isEmbModeCmdQueueEmpty( void ); +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 ); +static void processBloodLeakIntensityData( void ); +static void resetEmbModeCmdRespConsumedFlag( U08 cmd ); +static U32 getEmbModeInfoValue( U08 cmd ); +static BOOL isLowerRangeIntensityDriftZeroingNeeded( void ); +static BOOL isUpperIntensityZeroingNeeded( void ); + +/*********************************************************************//** + * @brief + * The initBloodLeak function initializes the Blood Leak module. + * @details Inputs: none + * @details Outputs: bloodLeakState, bloodLeakStatus, bloodLeakSelfTestStatus, + * bloodLeakUARTCmdIndex, bloodLeakSetPointSequence + * bloodLeakDataPublicationTimerCounter, bloodLeakEmbModeHasZeroBeenRqustd + * bloodLeakEmbModeSubstate, bloodLeakEmbModeCmdEnqueueCount + * bloodLeakPersistenceCtr, bloodLeakSignalEmbModeReq, + * bloodLeakEmbModeRqstedCmd, bloodLeakEmbModeOpsStartTime, + * bloodLeakEmbModeRespBuffer, bloodLeakEmbModeRespIndex, + * bloodLeakExitNormalRequested, bloodLeakEmbModeCmdSeqLength, + * bloodLeakEmbModeHasRxRqstBeenSent, bloodLeakEmbModeInfoCmdEnqLastTimeStamp, + * bloodLeakEmbModeInfoCmdCounter, bloodLeakRecoveryStartTimeMS, + * bloodLeakZeroingStatus + * @return none + *************************************************************************/ +void initBloodLeak( void ) +{ + // Initialize the embedded mode specifications + initEmbModeSpecs(); + + bloodLeakDataPublicationCounter = DATA_PUBLISH_COUNTER_START_COUNT; + bloodLeakState = BLOOD_LEAK_WAIT_FOR_POST_STATE; + bloodLeakStatus.data = BLOOD_LEAK_NOT_DETECTED; + bloodLeakStatus.ovInitData = BLOOD_LEAK_NOT_DETECTED; + bloodLeakStatus.ovData = BLOOD_LEAK_NOT_DETECTED; + bloodLeakStatus.override = OVERRIDE_RESET; + bloodLeakSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + bloodLeakUARTCmdIndex = 0; + bloodLeakSetPointSeqLength = 0; + bloodLeakPersistenceCtr = 0; + bloodLeakSignalEmbModeReq = FALSE; + bloodLeakEmbModeRqstedCmd = NU_EMB_MODE_CMD; + bloodLeakEmbModeSubstate = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE; + bloodLeakEmbModeOpsStartTime = 0; + bloodLeakEmbModeRespIndex = 0; + bloodLeakExitNormalRequested = FALSE; + bloodLeakEmbModeCmdSeqLength = 0; + bloodLeakEmbModeHasRxRqstBeenSent = FALSE; + bloodLeakEmbModeCmdQFrontIndex = 0; + bloodLeakEmbModeCmdQRearIndex = 0; + bloodLeakEmbModeCmdQCount = 0; + bloodLeakEmbModeHasZeroBeenRqustd = FALSE; + 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 ); + + // Set the blood leak set pint sequence to 0 to be initialized + memset( bloodLeakSetPointSequence, 0x0, BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH ); + + // Initialize the blood leak embedded mode response buffer + memset( bloodLeakEmbModeRespBuffer, 0x0, BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ); + + // 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 ) ); + + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.data = BLD_ZERO_MIN_INTERVAL_MS; + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.ovInitData = BLD_ZERO_MIN_INTERVAL_MS; + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.ovData = 0; + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.override = 0; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.data = BLD_UPPER_INTENSITY_INTERVAL_MS; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.ovInitData = BLD_UPPER_INTENSITY_INTERVAL_MS; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.ovData = 0; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.override = 0; + + // 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 ); +} + +/*********************************************************************//** + * @brief + * The execBloodLeak function executes the blood leak detector driver. + * @details Inputs: bloodLeakState + * @details Outputs: bloodLeakCalRecord, bloodLeakState + * @return none + *************************************************************************/ +void execBloodLeak( void ) +{ + //if ( TRUE == isNewCalibrationRecordAvailable() ) + //{ + // U32 length = sizeof( HD_BLOOD_LEAK_SENSOR_CAL_RECORD_T ); + // + // getNVRecord2Driver( GET_CAL_BLOOD_LEAK_SENSOR, (U08*)&bloodLeakCalRecord, length, 0, ALARM_ID_HD_BLOOD_LEAK_INVALID_CAL_RECORD ); + //} + + processBloodLeakIntensityData(); + + switch( bloodLeakState ) + { + case BLOOD_LEAK_WAIT_FOR_POST_STATE: + bloodLeakState = handleBloodLeakWaitForPostState(); + break; + + case BLOOD_LEAK_CHECK_SET_POINT_STATE: + bloodLeakState = handleBloodLeakCheckSetPointState(); + break; + + case BLOOD_LEAK_INIT_STATE: + bloodLeakState = handleBloodLeakInitState(); + break; + + case BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE: + bloodLeakState = handleBloodLeakCheckZeroAndSelfTestState(); + break; + + case BLOOD_LEAK_VERIFY_INTENSITY_AFTER_ZEROING_STATE: + bloodLeakState = handleBloodLeakVerifyIntensityAfterZeroingState(); + break; + + case BLOOD_LEAK_NORMAL_STATE: + bloodLeakState = handleBloodLeakNormalState(); + break; + + case BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE: + bloodLeakState = handleBloodLeakRecoverBloodDetectState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_BLOOD_LEAK_STATE, bloodLeakState ) + bloodLeakState = BLOOD_LEAK_INIT_STATE; + break; + } + + enqueueInfoEmbModeCmds(); + + // Publish blood leak data if due + publishBloodLeakData(); +} + +/*********************************************************************//** + * @brief + * The execBloodLeakEmbModeCommand function executes the blood leak embedded + * mode command. + * @details Inputs: bloodLeakEmbModeSubstate + * @details Outputs: bloodLeakEmbModeSubstate + * @return none + *************************************************************************/ +void execBloodLeakEmbModeCommand( void ) +{ + switch ( bloodLeakEmbModeSubstate ) + { + case BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE: + bloodLeakEmbModeSubstate = handleBloodLeakEmbModeWaitForCommandState(); + break; + + case BLOOD_LEAK_EMB_MODE_SEND_COMMAND_STATE: + bloodLeakEmbModeSubstate = handleBloodLeakEmbModeSendCommandState(); + break; + + case BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMMAND_RESPONSE_STATE: + bloodLeakEmbModeSubstate = handleBloodLeakEmbModeWaitForCommandResponseState(); + break; + + default: + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_LEAK_EMBEDDED_MODE_INVALID_STATE ) + bloodLeakEmbModeSubstate = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE; + break; + } +} + +/*********************************************************************//** + * @brief + * The zeroBloodLeak function requests that the Blood Leak Detector be + * zeroed. + * @details Inputs: bloodLeakEmbModeCmdEnqueueCount + * @details Outputs: bloodLeakEmbModeHasZeroBeenRqustd, + * bloodLeakEmbModeCmdEnqueueCount, bloodLeakSelfTestStatus + * @return TRUE if the zero commands were successfully queued otherwise, FALSE + *************************************************************************/ +BOOL zeroBloodLeak( void ) +{ + BOOL status = FALSE; + + if ( getAvailableEmbModeQueueCount() >= BLOOD_LEAK_EMB_MODE_ZERO_CMD_RQRD_Q ) + { + 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 ); + + SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_BLOOD_LEAK_ZEROING_REQUEST, 0, 0 ) + } + else if ( ++bloodLeakEmbModeCmdEnqueueCount > BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_LEAK_ENQUEUE_FAILURE ) + } + + return status; +} + +/*********************************************************************//** + * @brief + * The zeroBloodLeakReset function resets the commandRqstCount for all the + * zero blood leak commands. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +void zeroBloodLeakReset( void ) +{ + resetEmbModeCmdRqstCount( Z_EMB_MODE_CMD ); + resetEmbModeCmdRqstCount( G_EMB_MODE_CMD ); + resetEmbModeCmdRqstCount( Q_EMB_MODE_CMD ); + resetEmbModeCmdRqstCount( T_EMB_MODE_CMD ); +} + +/*********************************************************************//** + * @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 getBloodLeakStatus function gets the current reading for the blood + * leak detector. + * @details Inputs: bloodLeakStatus + * @details Outputs: none + * @return the current blood leak status. + *************************************************************************/ +BLOOD_LEAK_STATUS_T getBloodLeakStatus( void ) +{ + BLOOD_LEAK_STATUS_T result = (BLOOD_LEAK_STATUS_T)bloodLeakStatus.data; + + if ( OVERRIDE_KEY == bloodLeakStatus.override ) + { + result = (BLOOD_LEAK_STATUS_T)bloodLeakStatus.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getBloodLeakSelfTestStatus function gets the status for the blood + * leak detector self-test. + * @details Inputs: bloodLeakSelfTestStatus + * @details Outputs: none + * @return status of blood leak detector self-test. + *************************************************************************/ +SELF_TEST_STATUS_T getBloodLeakSelfTestStatus( void ) +{ +#ifndef _RELEASE_ + //if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_SELF_TEST ) ) + { + bloodLeakSelfTestStatus = SELF_TEST_STATUS_PASSED; + } +#endif + + return bloodLeakSelfTestStatus; +} + +/*********************************************************************//** + * @brief + * The isBloodLeakZeroingNeeded function checks whether blood leak zeroing + * is needed in terms of drift. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if blood leak zeroing is needed otherwise, FALSE + *************************************************************************/ +BOOL isBloodLeakZeroingNeeded( void ) +{ + BOOL status = FALSE; + DD_OP_MODE_T opMode = getCurrentOperationMode(); + + if ( MODE_PRET == opMode ) + { + U32 intensity = getEmbModeInfoValue( I_EMB_MODE_CMD ); + + if ( ( intensity <= BLD_START_OF_TX_MIN_INTENSITY_DRIFT ) || ( intensity >= BLD_MAX_UPPER_INTENSITY_DRIFT ) ) + { + SEND_EVENT_WITH_2_F32_DATA( DD_EVENT_BLOOD_LEAK_ZEROING_REQUIRED, intensity, opMode ) + status = TRUE; + } + } + else if ( MODE_TREA == opMode ) + { + status |= isLowerRangeIntensityDriftZeroingNeeded(); + status |= isUpperIntensityZeroingNeeded(); + } + + return status; +} + +/*********************************************************************//** + * @brief + * The exitBloodLeakNormalState requests that the blood leak sensor to exit + * its normal state. + * @details Inputs: bloodLeakState + * @details Outputs: bloodLeakExitNormalRequested + * @return none + *************************************************************************/ +void exitBloodLeakNormalState( void ) +{ + if ( BLOOD_LEAK_NORMAL_STATE == bloodLeakState ) + { + bloodLeakExitNormalRequested = TRUE; + } +} + +/*********************************************************************//** + * @brief + * The execBloodLeakSelfTest function executes the blood leak self-test. + * @details Inputs: none + * @details Outputs: none + * @return blood leak self test results (SELF_TEST_STATUS_T) + *************************************************************************/ +SELF_TEST_STATUS_T execBloodLeakSelfTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + //U32 length = sizeof( HD_BLOOD_LEAK_SENSOR_CAL_RECORD_T ); + ALARM_ID_T alarm = ALARM_ID_DD_BLOOD_LEAK_INVALID_CAL_RECORD; + BOOL calStatus = TRUE; //getNVRecord2Driver( GET_CAL_BLOOD_LEAK_SENSOR, (U08*)&bloodLeakCalRecord, length, 0, alarm ); // TODO uncomment + + if ( TRUE == calStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakWaitForPostState function handles the wait for POST + * state of the of blood leak state machine. + * @details Inputs: bloodLeakEmbModeCmd + * @details Outputs: bloodLeakEmbModeCmd + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakWaitForPostState( void ) +{ + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_WAIT_FOR_POST_STATE; + BOOL isEmbModeReady = FALSE; + U32 cmdResp = bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].commandResp; + + if ( BLOOD_LEAK_EMB_MODE_PASS_ASCII == cmdResp ) + { + isEmbModeReady = TRUE; + } + else if ( ( TRUE == bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].isCmdRespRdy ) && ( BLOOD_LEAK_EMB_MODE_FAIL_ASCII == cmdResp ) ) + { + 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 + // in the embedded mode first + enqueueEmbModeCmd( CS_EMB_MODE_CMD ); + enqueueEmbModeCmd( D_EMB_MODE_CMD ); + } + else + { +#ifndef _RELEASE_ + // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + activateAlarmNoData( ALARM_ID_DD_BLOOD_LEAK_SENSOR_EMBEDDED_MODE_FAILURE ); + } + } + } + + if ( ( getCurrentOperationMode() != MODE_INIT ) && ( TRUE == isEmbModeReady ) ) + { + resetEmbModeCmdRqstCount( CS_EMB_MODE_CMD ); + state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakCheckSetPointState function handles the check set point + * state to ensure the set point is set correctly. + * @details Inputs: bloodLeakCalRecord + * @details Outputs: bloodLeakCalRecord + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakCheckSetPointState( void ) +{ + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + U16 bloodLeakSetPoint = bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandResp; + BOOL isCommandRespReady = bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].isCmdRespRdy; + U08 commandDRqstCount = bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandRqstCount; + + SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_BLOOD_LEAK_NUM_OF_SET_POINT_CHECK_FAILURES, (U32)commandDRqstCount, state ) + + if ( FALSE ) // TODO bring back the blood leak set point once the calibration system is ready + //if ( ( bloodLeakSetPoint != bloodLeakCalRecord.setPoint ) && ( TRUE == isCommandRespReady ) ) + { + if ( commandDRqstCount < BLOOD_LEAK_EMB_MODE_MAX_NUM_CMD_TRIES ) + { + enqueueEmbModeCmd( D_EMB_MODE_CMD ); + } + else + { +#ifndef _RELEASE_ + // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + activateAlarmNoData( ALARM_ID_DD_BLOOD_LEAK_SENSOR_SET_POINT_SET_FAILURE ); + } + } + } + else if ( TRUE == isCommandRespReady ) + { + resetEmbModeCmdRqstCount( D_EMB_MODE_CMD ); + state = BLOOD_LEAK_INIT_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakInitState function handles the Blood Leak module in init + * state. + * @details Inputs: bloodLeakEmbModeHasZeroBeenRqustd + * @details Outputs: none + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakInitState( void ) +{ + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_INIT_STATE; + + // Check if the zero command has been requested + if ( TRUE == bloodLeakEmbModeHasZeroBeenRqustd ) + { + bloodLeakEmbModeHasZeroBeenRqustd = FALSE; + state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakCheckZeroAndSelfTestState function handles the blood + * leak check zero and self test state. + * @details Inputs: bloodLeakEmbModeCmd + * @details Outputs: bloodLeakEmbModeCmd, bloodLeakEmbModeHasZeroBeenRqustd, + * bloodLeakSelfTestStatus + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakCheckZeroAndSelfTestState( void ) +{ + U08 i; + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_CHECK_ZERO_AND_SELF_TEST_STATE; + BOOL areCommandsReady = TRUE; + + // Check to see if all commands in sequence have been responded to + for ( i = 0; i < NUM_OF_EMB_CMDS; i++ ) + { + switch( i ) + { + case Z_EMB_MODE_CMD: + case G_EMB_MODE_CMD: + case Q_EMB_MODE_CMD: + case T_EMB_MODE_CMD: + // All the commands shall be processed and have data prior to checking the results + areCommandsReady &= bloodLeakEmbModeCmd[ i ].isCmdRespRdy; + break; + + default: + // Do nothing with the rest of the commands + break; + } + } + + // When all commands in sequence have been responded to, determine whether anything went wrong + if ( TRUE == areCommandsReady ) + { + // Enqueue the zero and self test sequence (Z->G->Z->Q->T) + BOOL hasCmdSqncFailed = FALSE; + BOOL hasCurrCmdFailed = FALSE; + + for ( i = 0; i < NUM_OF_EMB_CMDS; i++ ) + { + switch( i ) + { + case Z_EMB_MODE_CMD: + case Q_EMB_MODE_CMD: + case T_EMB_MODE_CMD: + // Check to see if any of the command responses failed + hasCurrCmdFailed = ( BLOOD_LEAK_EMB_MODE_PASS_ASCII == bloodLeakEmbModeCmd[ i ].commandResp ? FALSE : TRUE ); + hasCmdSqncFailed |= hasCurrCmdFailed; + 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; + break; + + default: + // Do nothing with the rest of the commands + break; + } + } + + // Pass self-test if entire sequence was successful + if ( FALSE == hasCmdSqncFailed ) + { + // Done with the commands, request a fresh intensity read to check its range + enqueueEmbModeCmd( I_EMB_MODE_CMD ); + state = BLOOD_LEAK_VERIFY_INTENSITY_AFTER_ZEROING_STATE; + } + // If not successful, retry if we've not run out + else + { + bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; + state = BLOOD_LEAK_INIT_STATE; + SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_BLOOD_LEAK_SELF_TEST_RESULT, bloodLeakSelfTestStatus, state ) + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakVerifyIntensityAfterZeroingState function checks the + * blood leak sensor's intensity after zeroing the sensor. + * @details Inputs: bloodLeakEmbModeCmd + * @details Outputs: bloodLeakSelfTestStatus + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakVerifyIntensityAfterZeroingState( void ) +{ + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_VERIFY_INTENSITY_AFTER_ZEROING_STATE; + + if ( TRUE == bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].isCmdRespRdy ) + { + U32 intensity = getEmbModeInfoValue( I_EMB_MODE_CMD ); + + state = BLOOD_LEAK_INIT_STATE; + bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; + + if ( abs( BLD_NOMINAL_INTENSITY - intensity ) <= BLD_MAX_INTENSITY_DRFT_AFTER_ZEROING ) + { + // Done with zero sequence, transition to other states + zeroBloodLeakReset(); + bloodLeakZeroingStatus.lastZeroingStartTimeMS = getMSTimerCount(); + bloodLeakSelfTestStatus = SELF_TEST_STATUS_PASSED; + state = BLOOD_LEAK_NORMAL_STATE; + + if ( TRUE == isAlarmActive( ALARM_ID_DD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ) ) + { + state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + } + } + SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_BLOOD_LEAK_SELF_TEST_RESULT, bloodLeakSelfTestStatus, state ) + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakNormalState function handles the Blood Leak module + * in normal state. + * @details Inputs: bloodLeakStatus, bloodLeakPersistenceCtr, + * bloodLeakExitNormalRequested + * @details Outputs: bloodLeakStatus, bloodLeakPersistenceCtr, + * bloodLeakExitNormalRequested, bloodLeakEmbModeHasZeroBeenRqustd, + * bloodLeakRecoveryStartTimeMS + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATE_T handleBloodLeakNormalState( void ) +{ + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_NORMAL_STATE; + + bloodLeakStatus.data = getFPGABloodDetectProcessedStatus(); + + switch ( getCurrentOperationMode() ) + { + case MODE_TREA: + case MODE_SERV: + if ( ( FALSE == isDialysateLineInBypass() ) && ( getTreatmentState() != TREATMENT_RECIRC_STATE ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) + { + if ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) + { + if ( ++bloodLeakPersistenceCtr > BLOOD_LEAK_PERSISTENCE ) + { + bloodLeakPersistenceCtr = BLOOD_LEAK_PERSISTENCE; + //if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != TRUE ) // TODO enable when test config is caught up + { + activateAlarmNoData( ALARM_ID_DD_BLOOD_LEAK_DETECTED ); + activateAlarmNoData( ALARM_ID_DD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); + state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + } + } + } + else if ( bloodLeakPersistenceCtr > 0 ) + { + bloodLeakPersistenceCtr--; + } + else + { + clearAlarmCondition( ALARM_ID_DD_BLOOD_LEAK_DETECTED ); + clearAlarmCondition( ALARM_ID_DD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + } + } + + default: + // Do nothing. Do not check for blood in other modes. + break; + } + + if ( TRUE == bloodLeakExitNormalRequested ) + { + bloodLeakExitNormalRequested = FALSE; + state = BLOOD_LEAK_INIT_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 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(); + + // Check if the blood is not detected but at the same time the Dialin pump should be running to make sure we are in the + // blood recovery state of the treatment stop so the blood detection recovery is not done on the stagnant fluid + // NOTE: should we check of the measured flow is about 600 mL/min? + if ( ( BLOOD_LEAK_NOT_DETECTED == getBloodLeakStatus() ) && ( TRUE == isDialInPumpRunning() ) ) + { + 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_DD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + } + } + else + { + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); + } + + if ( isAlarmActive( ALARM_ID_DD_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 handleBloodLeakEmbModeWaitForCommandState function handles the wait for + * command state. The state prepares the message to be sent to the blood leak + * sensor. + * @details Inputs: bloodLeakEmbModeRqstedCmd, bloodLeakEmbModeCmd + * @details Outputs: bloodLeakEmbModeRqstedCmd, bloodLeakEmbModeCmdSeq, + * bloodLeakUARTCmdIndex, bloodLeakEmbModeRespIndex, bloodLeakEmbModeCmdSeqLength, + * bloodLeakEmbModeOpsStartTime, bloodLeakEmbModeSetPoint, bloodLeakEmbModeRespBuffer + * @return next state + *************************************************************************/ +static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeWaitForCommandState( void ) +{ + BLOOD_LEAK_EMB_MODE_STATE_T state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE; + + if ( FALSE == isEmbModeCmdQueueEmpty() ) + { + U08 commandASCII = 0; + + bloodLeakEmbModeRqstedCmd = dequeueEmbModeCmd(); + commandASCII = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].commandASCII; + + switch( bloodLeakEmbModeRqstedCmd ) + { + case NU_EMB_MODE_CMD: + // Null command do nothing + break; + + case CS_EMB_MODE_CMD: + case T_EMB_MODE_CMD: + case G_EMB_MODE_CMD: + case I_EMB_MODE_CMD: + case V_EMB_MODE_CMD: + case Z_EMB_MODE_CMD: + case Q_EMB_MODE_CMD: + case D_EMB_MODE_CMD: + case C_EMB_MODE_CMD: + // First clear the buffer from the older data + memset( bloodLeakEmbModeCmdSeq, 0x0, 2 * BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH ); + + // Set the command sequence + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_RESET_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_EMB_MODE_COMM_RESET; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_RESET_INDEX ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_RESET_INDEX + 1 ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_LOW; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_RESET_INDEX + 1 ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_CMD_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = commandASCII; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_CMD_INDEX ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = FALSE; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_STOP_WRITE_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_STOP_WRITE_FIFO_COMMAND; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_STOP_WRITE_INDEX ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = FALSE; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_ACTIVE_HIGH_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_HIGH; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_ACTIVE_HIGH_INDEX ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_ACTIVE_HIGH_INDEX + 1 ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_LOW; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_ACTIVE_HIGH_INDEX + 1 ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + + // Set the variables for the next state + bloodLeakUARTCmdIndex = 0; + bloodLeakEmbModeRespIndex = 0; + bloodLeakEmbModeCmdSeqLength = BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH; + bloodLeakEmbModeOpsStartTime = getMSTimerCount(); + state = BLOOD_LEAK_EMB_MODE_SEND_COMMAND_STATE; + + // Clear the response buffer to able to receive fresh data + memset( bloodLeakEmbModeRespBuffer, 0x0, BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ); + break; + + case SP_EMB_MODE_CMD: + prepareSetPointSeq( bloodLeakEmbModeSetPoint ); + bloodLeakEmbModeRespIndex = 0; + bloodLeakEmbModeOpsStartTime = getMSTimerCount(); + state = BLOOD_LEAK_EMB_MODE_SEND_COMMAND_STATE; + // Clear the command sequence buffer in case it is needed to send byte read request. The byte + // read requests are sent using this buffer while the set point is set using the set point buffer + memset( bloodLeakEmbModeCmdSeq, 0x0, 2 * BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH ); + // Clear the response buffer to able to receive fresh data + memset( bloodLeakEmbModeRespBuffer, 0x0, BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_LEAK_INVALID_EMB_MODE_CMD_SELECTED, bloodLeakEmbModeRqstedCmd ) + break; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakEmbModeSendCommandState function handles the send command + * state. The state sends the command sequence to the blood leak sensor one by one. + * @details Inputs: bloodLeakEmbModeRqstedCmd, bloodLeakCalCharacter, bloodLeakUARTCmdIndex + * bloodLeakEmbModeCmdSeqLength + * @details Outputs: bloodLeakEmbModeRqstedCmd, bloodLeakCalCommandSquence, + * bloodLeakUARTCmdIndex, bloodLeakEmbModeCmdSeqLength, bloodLeakEmbModeCmdSeqLength, + * bloodLeakSetPointSequence + * @return next state + *************************************************************************/ +static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeSendCommandState( void ) +{ + U08 command; + BLOOD_LEAK_EMB_MODE_STATE_T state = BLOOD_LEAK_EMB_MODE_SEND_COMMAND_STATE; + BOOL isUARTCtrlCmd = FALSE; + BOOL isUARTCtrlDone = TRUE; + + switch ( bloodLeakEmbModeRqstedCmd ) + { + case CS_EMB_MODE_CMD: + case T_EMB_MODE_CMD: + case G_EMB_MODE_CMD: + case I_EMB_MODE_CMD: + case V_EMB_MODE_CMD: + case Z_EMB_MODE_CMD: + case Q_EMB_MODE_CMD: + case D_EMB_MODE_CMD: + case C_EMB_MODE_CMD: + command = bloodLeakEmbModeCmdSeq[ bloodLeakUARTCmdIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ]; + isUARTCtrlCmd = bloodLeakEmbModeCmdSeq[ bloodLeakUARTCmdIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ]; + isUARTCtrlDone = ( bloodLeakUARTCmdIndex > ( bloodLeakEmbModeCmdSeqLength - 1 ) ? TRUE : FALSE ); + bloodLeakUARTCmdIndex++; + break; + + case SP_EMB_MODE_CMD: + // Check if the first element in the command sequence buffer is the read request. If it is, the set point command sequence has already been sent + // and we are requesting the buffer to read and get its response back so use this buffer to send data to the sensor + // Otherwise, send the set point command sequence to the sensor since the set point is sent prior to reading the response back from the sensor + if ( BLOOD_LEAK_EMB_MODE_COMM_READ_REQST == bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] ) + { + command = bloodLeakEmbModeCmdSeq[ bloodLeakUARTCmdIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ]; + isUARTCtrlCmd = bloodLeakEmbModeCmdSeq[ bloodLeakUARTCmdIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ]; + isUARTCtrlDone = ( bloodLeakUARTCmdIndex > ( bloodLeakEmbModeCmdSeqLength - 1 ) ? TRUE : FALSE ); + } + else + { + command = bloodLeakSetPointSequence[ bloodLeakUARTCmdIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ]; + isUARTCtrlCmd = bloodLeakSetPointSequence[ bloodLeakUARTCmdIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ]; + isUARTCtrlDone = ( bloodLeakUARTCmdIndex > ( bloodLeakSetPointSeqLength - 1 ) ? TRUE : FALSE ); + } + bloodLeakUARTCmdIndex++; + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_LEAK_INVALID_EMB_MODE_CMD_SELECTED, bloodLeakEmbModeRqstedCmd ) + break; + } + + if ( ( bloodLeakEmbModeRqstedCmd != CS_EMB_MODE_CMD ) && ( bloodLeakUARTCmdIndex - 1 > BLOOD_LEAK_EMB_MODE_RESET_INDEX ) && + ( bloodLeakUARTCmdIndex - 1 <= BLOOD_LEAK_EMB_MODE_RESET_INDEX + 1 ) ) + { + if ( 0 == getBloodLeakRxBytesAvailable() ) + { + // TODO do nothing right now. I case it was decided to use the terminal mode again, make sure the reset went through prior to sending the + // reset of the command sequence + } + } + + // Check if the current index towards the end of the buffer which are FIFO set and FIFO reset + if ( FALSE == isUARTCtrlDone ) + { + if ( FALSE == isUARTCtrlCmd ) + { + setFPGABloodLeakUARTTransmit( command ); + } + else + { + setFPGABloodLeakUARTControl( command ); + } + } + else + { + // If the element in the first index of the command sequence buffer is the read a byte request, set the variable to TRUE so the + // wait for data to receive state knows that the request has been sent and it can read the byte. + U08 commandInIndex0 = bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ]; + + bloodLeakEmbModeHasRxRqstBeenSent = ( BLOOD_LEAK_EMB_MODE_COMM_READ_REQST == commandInIndex0 ? TRUE : FALSE ); + bloodLeakUARTCmdIndex = 0; + bloodLeakEmbModeCmdSeqLength = 0; + state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMMAND_RESPONSE_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakEmbModeWaitForCommandResponseState function handles the + * wait for command responses state. The state receives data in the buffer. + * @details Inputs: bloodLeakEmbModeHasRxRqstBeenSent, bloodLeakEmbModeRespBuffer, + * bloodLeakEmbModeRespIndex, bloodLeakEmbModeRqstedCmd, bloodLeakEmbModeOpsStartTime + * @details Outputs: bloodLeakEmbModeCmd, bloodLeakEmbModeRqstedCmd, + * bloodLeakEmbModeCmdSeq, bloodLeakEmbModeRespBuffer + * @return next state + *************************************************************************/ +static BLOOD_LEAK_EMB_MODE_STATE_T handleBloodLeakEmbModeWaitForCommandResponseState( void ) +{ + BLOOD_LEAK_EMB_MODE_STATE_T state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMMAND_RESPONSE_STATE; + U16 rxFIFOCount = getBloodLeakRxBytesAvailable(); + BOOL hasCharBeenReceived = FALSE; + U32 commandTimeoutMS = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].timeoutMS; + U32 length = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].length; + + if ( TRUE == bloodLeakEmbModeHasRxRqstBeenSent ) + { + // If the read request sequence has been sent already, read the next byte in the buffer and process it + U08 data = getFPGABloodLeakRxFIFODataOut(); + hasCharBeenReceived = TRUE; + bloodLeakEmbModeHasRxRqstBeenSent = FALSE; + processReceivedEmbModeChar( data ); + } + else if ( ( rxFIFOCount > 0 ) && ( FALSE == bloodLeakEmbModeHasRxRqstBeenSent ) ) + { + // If there is still more data in the buffer and a read sequence has not been sent, create the sequence and send it + // First clear the buffer from the older data. Set to 2 times the length because the array is 2D + memset( bloodLeakEmbModeCmdSeq, 0x0, 2 * BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH ); + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_EMB_MODE_COMM_READ_REQST; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX + 1 ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_LOW; + bloodLeakEmbModeCmdSeq[ BLOOD_LEAK_EMB_MODE_REQUEST_RX_INDEX + 1 ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + + // Set the variables for the next state + bloodLeakUARTCmdIndex = 0; + bloodLeakEmbModeCmdSeqLength = BLOOD_LEAK_EMB_MODE_RQST_RX_LENGTH; + state = BLOOD_LEAK_EMB_MODE_SEND_COMMAND_STATE; + } + + // If wait for the receive FIFO has timed out or all there is no buffer left in the Rx FIFO transition back to wait for command state for the next command + if ( ( TRUE == hasCharBeenReceived ) && ( bloodLeakEmbModeRespIndex >= length ) ) + { + U08 i; + BOOL isNull = FALSE; + + for ( i = 0; i < length; i++ ) + { + // Loop through the elements of the buffer and make sure none of the elements are not NULL. + // The elements are checked until the specified length that is expected for a command + isNull |= ( bloodLeakEmbModeRespBuffer[ i ] != NU_EMB_MODE_CMD ? FALSE : TRUE ); + } + + // Check if the failed command is Control S which is switch to embedded mode and if + // it failed set the embedded mode request to false so the other commands cannot be sent again + bloodLeakSignalEmbModeReq = ( ( CS_EMB_MODE_CMD == bloodLeakEmbModeRqstedCmd ) && ( NU_EMB_MODE_CMD == bloodLeakEmbModeRespBuffer[ 0 ] ) ? FALSE : TRUE ); + + if ( TRUE == isNull ) + { + // There is null in the characters that were supposed to be received and not be null but null was found + // Clear the response buffer and write the ASCII fail in the first element of the response buffer + // Set the length to be 1 because there is only 1 character (fail) is in the buffer + memset( bloodLeakEmbModeRespBuffer, 0x0, BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ); + + length = 1; + bloodLeakEmbModeRespBuffer[ 0 ] = BLOOD_LEAK_EMB_MODE_FAIL_ASCII; + } + else if ( CS_EMB_MODE_CMD == bloodLeakEmbModeRqstedCmd ) + { + memset( bloodLeakEmbModeRespBuffer, 0x0, BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ); + + length = 1; + bloodLeakEmbModeRespBuffer[ 0 ] = BLOOD_LEAK_EMB_MODE_PASS_ASCII; + } + else if ( 1 == length ) + { + U08 passChar = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].expChar1; + U08 data = bloodLeakEmbModeRespBuffer[ 0 ]; + bloodLeakEmbModeRespBuffer[ 0 ] = ( passChar == data ? BLOOD_LEAK_EMB_MODE_PASS_ASCII : BLOOD_LEAK_EMB_MODE_FAIL_ASCII ); + } + + convertString2Integer( bloodLeakEmbModeRqstedCmd, length ); + + sendBloodLeakEmbeddedModeCommandResponse( bloodLeakEmbModeRqstedCmd, length, bloodLeakEmbModeRespBuffer ); + + // Done with receiving the data + bloodLeakEmbModeRqstedCmd = NU_EMB_MODE_CMD; + state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE; + } + + if ( TRUE == didTimeout( bloodLeakEmbModeOpsStartTime, commandTimeoutMS ) ) + { + // Command timed out. Clear the receive buffer from any data and put a Fail in there to be sent up + memset( bloodLeakEmbModeRespBuffer, 0x0, BLOOD_LEAK_EMB_MODE_RESP_BUFFER_LEN ); + + // Only F (fail) will be sent so the length of the buffer is 1 + length = 1; + 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; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The processReceivedEmbModeChar function processes the character that + * has been received. + * @details Inputs: bloodLeakEmbModeCmd, bloodLeakEmbModeRespIndex + * @details Outputs: bloodLeakEmbModeRespBuffer, bloodLeakEmbModeRespIndex + * @param data which is the data that has been received from the BLD + * @return none + *************************************************************************/ +static void processReceivedEmbModeChar( U08 data ) +{ + /* + * There are 3 types of data that can be received from the the sensor: + * 1. It could be a start character and the length (i.e. VXXXX) + * 2. It could be two discrete characters (i.e. P, F) + * 3. It could be none of the two characters (i.e. XXXX) + */ + U08 length = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].length; + U08 expChar1 = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].expChar1; + U08 expChar2 = bloodLeakEmbModeCmd[ bloodLeakEmbModeRqstedCmd ].expChar2; + + if ( expChar1 != NU_EMB_MODE_CMD ) + { + // This is the case that there is a start character. If current character buffer index is less than the + // length of the expected response of the command. + if ( bloodLeakEmbModeRespIndex < length ) + { + if ( NU_EMB_MODE_CMD == expChar2 ) + { + // Check if the expected char is received and the response buffer is empty because the index is 0, + // insert the buffer data + if ( ( expChar1 == data ) && ( 0 == bloodLeakEmbModeRespIndex ) ) + { + bloodLeakEmbModeRespBuffer[ bloodLeakEmbModeRespIndex ] = data; + bloodLeakEmbModeRespIndex++; + } + // Check if the buffer index is cd ve> 0 so the first char has been inserted and the rest is data but it is not the echo of the command + // For instance, V has been inserted and XXXX is inserted that is followed by V. So V123 and not VVV12. + else if ( ( bloodLeakEmbModeRespIndex > 0 ) && ( data != expChar1 ) ) + { + bloodLeakEmbModeRespBuffer[ bloodLeakEmbModeRespIndex ] = data; + bloodLeakEmbModeRespIndex++; + } + } + else + { + // Check if either of the expected chars are received and if they are insert it into the response buffer + if ( ( expChar1 == data ) || ( expChar2 == data ) ) + { + bloodLeakEmbModeRespBuffer[ bloodLeakEmbModeRespIndex ] = data; + bloodLeakEmbModeRespIndex++; + } + } + } + } + else + { + // This is the case that there are no expected characters and the received value are numbers + if ( bloodLeakEmbModeRespIndex < length ) + { + // If the received character is in the range of numbers chars (0 to 9), then insert them into the response buffer + if ( ( data >= BLOOD_LEAK_EMB_MODE_0_NUM_ASCII ) && ( data <= BLOOD_LEAK_EMB_MODE_9_NUM_ASCII ) ) + { + bloodLeakEmbModeRespBuffer[ bloodLeakEmbModeRespIndex ] = data; + bloodLeakEmbModeRespIndex++; + } + } + } +} + +/*********************************************************************//** + * @brief + * The convertString2Integer function converts the buffer of the answers in + * string (ASCII) to integer. + * @details Inputs: bloodLeakEmbModeCmd + * @details Outputs: bloodLeakEmbModeRespBuffer, bloodLeakEmbModeCmd + * @param cmd which is the embedded mode command + * @param respLength the length of the received response from the sensor + * @return none + *************************************************************************/ +static void convertString2Integer( U08 cmd, U32 respLength ) +{ + if ( 1 == respLength ) + { + bloodLeakEmbModeCmd[ cmd ].commandResp = bloodLeakEmbModeRespBuffer[ 0 ]; + } + else + { + U08 i; + U32 bufferValue; + U32 respExpectedLength = bloodLeakEmbModeCmd[ cmd ].length; + // Reset the command response + bloodLeakEmbModeCmd[ cmd ].commandResp = 0; + + for ( i = 0; i < respExpectedLength; i++ ) + { + // The last value is inserted into the response buffer (i.e. S030) + // So the buffer array is used from the last element of the array + bufferValue = bloodLeakEmbModeRespBuffer[ respExpectedLength - 1 - i ]; + + if ( ( bufferValue >= BLOOD_LEAK_EMB_MODE_0_NUM_ASCII ) && ( bufferValue <= BLOOD_LEAK_EMB_MODE_9_NUM_ASCII ) ) + { + // If the value in the response buffer is within the ASCII values of 0 (ASCII 48) to 9 (ASCII 57) then it is a number and needs to be converted to integer + // Subtract the buffer value from ASCII 48 to get the offset (i.e. buffer = 50 - 48 = 2) + // Add the offset value to the command response in the right order (i.e. if i = 1, then it is 2 x 10 ^1 = 20) + bufferValue -= BLOOD_LEAK_EMB_MODE_0_NUM_ASCII; + bloodLeakEmbModeCmd[ cmd ].commandResp += ( bufferValue * pow( 10, i ) ); + } + } + } + + // Set the command response ready + bloodLeakEmbModeCmd[ cmd ].isCmdRespRdy = TRUE; +} + +/*********************************************************************//** + * @brief + * The prepareSetPointSeq function prepares the set point sequence to be + * written to the blood leak sensor. + * @details Inputs: none + * @details Outputs: bloodLeakSetPointSequence, bloodLeakSetPointSeqLength + * @param setPoint the set point that has to be prepared to be sent to the sensor + * @return none + *************************************************************************/ +static void prepareSetPointSeq( U16 setPoint ) +{ + U08 i; + U32 digitCount; + char tempCharBuffer[ BLOOD_LEAK_SET_POINT_MAX_CHAR_LENGTH ]; + U08 command; + U32 bufferIndex = BLOOD_LEAK_SET_POINT_START_CHAR_INDEX; + + memset( tempCharBuffer, 0x0, BLOOD_LEAK_SET_POINT_MAX_CHAR_LENGTH ); + + // Convert the set point number to the equivalent ASCII number with the unsigned integer data type + sprintf( tempCharBuffer, "%u", (U32)setPoint ); + + // Calculate the length of the character buffer. strlen does not count the null character. + digitCount = strlen( tempCharBuffer ); + + command = ( TRUE == bloodLeakSignalEmbModeReq ? BLOOD_LEAK_EMB_MODE_COMM_RESET : BLOOD_LEAK_RESET_TX_FIFO ); + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = command; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bufferIndex++; + + command = ( TRUE == bloodLeakSignalEmbModeReq ? BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_LOW : BLOOD_LEAK_UART_COMM_ACTIVE_LOW ); + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = command; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bufferIndex++; + + // Set the first item to the ASCII character of S. The format to set the set point is + // SXXXCR10. It starts with S followed by the characters up to 3 digits, carriage return and a 1 and a 0 to write to the buffer. + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_SET_POINT_START_CHAR_ASCII; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = FALSE; + bufferIndex++; + + // Loop through the number of digits and get each ASCII value + for ( i = 0; i < digitCount; i++ ) + { + // Write the characters + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = tempCharBuffer[ i ]; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = FALSE; + bufferIndex++; + } + + // After the characters, insert the carriage return into the buffer + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_CARRIAGE_RETURN_ASCII; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = FALSE; + bufferIndex++; + + // After the characters, insert the stop write to FIFO character which is number 0 + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = BLOOD_LEAK_STOP_WRITE_FIFO_COMMAND; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = FALSE; + bufferIndex++; + + // Set active high into the buffer. + // If the mode is embedded mode, the active high (and active low) values are different than in the Ctrl U mode since the bit values are different + command = ( TRUE == bloodLeakSignalEmbModeReq ? BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_HIGH : BLOOD_LEAK_UART_COMM_ACTIVE_HIGH ); + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = command; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + bufferIndex++; + + command = ( TRUE == bloodLeakSignalEmbModeReq ? BLOOD_LEAK_EMB_MODE_COMM_ACTIVE_LOW : BLOOD_LEAK_UART_COMM_ACTIVE_LOW ); + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_CMD_COL_INDEX ] = command; + bloodLeakSetPointSequence[ bufferIndex ][ BLOOD_LEAK_EMB_MODE_IS_UART_COL_INDEX ] = TRUE; + + // Update the sequence length for writing to the sensor + bloodLeakSetPointSeqLength = bufferIndex + 1; + bloodLeakUARTCmdIndex = 0; +} + +/*********************************************************************//** + * @brief + * The publishBloodLeakData function publishes blood leak data at the set interval. + * @details Inputs: bloodLeakDataPublicationTimerCounter + * @details Outputs: bloodLeakDataPublicationTimerCounter, bloodLeakPersistenceCtr, + * bloodLeakState, bloodLeakZeroingStatus + * @return none + *************************************************************************/ +static void publishBloodLeakData( void ) +{ + // Publish blood leak data on interval + if ( ++bloodLeakDataPublicationCounter >= getU32OverrideValue( &bloodLeakDataPublishInterval ) ) + { + BLOOD_LEAK_DATA_T data; + + data.bloodLeakStatus = (U32)getBloodLeakStatus(); + data.bloodLeakState = (U32)bloodLeakState; + data.bloodLeakPersistentCounter = bloodLeakPersistenceCtr; + data.bloodLeakSerialCommState = bloodLeakEmbModeSubstate; + data.bloodLeakIntensity = getEmbModeInfoValue( I_EMB_MODE_CMD ); + data.bloodLeakDetect = getEmbModeInfoValue( V_EMB_MODE_CMD ); + data.bloodLeakIntensityMovingAvg = getF32OverrideValue( &bloodLeakZeroingStatus.intensityMovingAverage ); + data.bloodLeakTimeSinceZeroMS = calcTimeSince( bloodLeakZeroingStatus.lastZeroingStartTimeMS ); + data.driftInRangeStatus = bloodLeakZeroingStatus.driftInRangeStatus; + data.driftUpperRangeStatus = bloodLeakZeroingStatus.driftUpperRangeStatus; + + bloodLeakDataPublicationCounter = 0; + + broadcastData( MSG_ID_DD_BLOOD_LEAK_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( BLOOD_LEAK_DATA_T ) ); + } +} + +/*********************************************************************//** + * @brief + * The initEmbModeSpecs function initializes the embedded mode specifications + * structure. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeCmd + * @return none + *************************************************************************/ +static void initEmbModeSpecs( void ) +{ + // Null command + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].commandASCII = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].expChar1 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].length = 0; + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].timeoutMS = 0; + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ NU_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Control S command + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].commandASCII = 19; // ASCII for Control S + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].expChar1 = 69; // ASCII for E (Embedded ...) + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].length = 5; + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ CS_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Set point command + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].commandASCII = 83; // ASCII for S + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].expChar1 = 32; // For space (Set point is returned by a space at the beginning of returning the set point value) + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].length = 5; + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].timeoutMS = 10 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Self test command + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].commandASCII = 84; // ASCII for T + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].expChar1 = 80; // ASCII for P + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].expChar2 = 70; // ASCII for F + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].length = 1; + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ T_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Get self test command + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].commandASCII = 71; // ASCII for G + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].expChar1 = 71; + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].length = 5; + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].timeoutMS = 10 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ G_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Intensity command + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].commandASCII = 73; // ASCII for I + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].expChar1 = 73; + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].length = 5; + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Blood detection command + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].commandASCII = 86; // ASCII for V + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].expChar1 = 86; + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].length = 5; + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ V_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Zero sensor command + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].commandASCII = 90; // ASCII for Z + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].expChar1 = 89; // ASCII for Y + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].length = 1; + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].timeoutMS = 10 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ Z_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Zero confirm command + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].commandASCII = 81; // ASCII for Q + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].expChar1 = 80; // ASCII for P + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].expChar2 = 70; // ASCII for F + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].length = 1; + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ Q_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Display blood detection command + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandASCII = 68; + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].expChar1 = 68; // ASCII for D + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].length = 5; + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].isCmdRespRdy = FALSE; + + // Calibrate command + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].commandASCII = 67; + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].expChar1 = 67; // ASCII for C + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].expChar2 = NU_EMB_MODE_CMD; + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].length = 4; + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].timeoutMS = 5 * MS_PER_SECOND; + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].commandResp = 0; + bloodLeakEmbModeCmd[ C_EMB_MODE_CMD ].isCmdRespRdy = FALSE; +} + +/*********************************************************************//** + * @brief + * The enqueueEmbModeCmd function enqueues an embedded mode command. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeCmdQRearIndex, bloodLeakEmbModeCmdQCount + * bloodLeakEmbModeCmdQ, bloodLeakEmbModeCmd + * @param cmd the command to enqueue + * @return none + *************************************************************************/ +static void enqueueEmbModeCmd( U08 cmd ) +{ + // Enqueue the command and increment the rear embedded mode index + // Set the command response to be false so the command was just queued to be read + 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 + * @return command that is dequeued + *************************************************************************/ +static U08 dequeueEmbModeCmd( void ) +{ + U08 command = 0; + U08 tempIndex; + + _disable_IRQ(); + tempIndex = bloodLeakEmbModeCmdQFrontIndex; + + if ( FALSE == isEmbModeCmdQueueEmpty() ) + { + bloodLeakEmbModeCmdQFrontIndex = INC_WRAP( bloodLeakEmbModeCmdQFrontIndex, 0, BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE - 1 ); + command = bloodLeakEmbModeCmdQ[ tempIndex ]; + bloodLeakEmbModeCmdQCount--; + } + _enable_IRQ(); + + return command; +} + +/*********************************************************************//** + * @brief + * The isEmbModeCmdQueueEmpty function checks whether the embedded mode command + * queue is empty or not. + * @details Inputs: bloodLeakEmbModeCmdQCount + * @details Outputs: none + * @return TRUE if the queue is empty otherwise, FALSE + *************************************************************************/ +static BOOL isEmbModeCmdQueueEmpty( void ) +{ + BOOL isEmpty = TRUE; + + if ( bloodLeakEmbModeCmdQCount > 0 ) + { + isEmpty = FALSE; + } + + return isEmpty; +} + +/*********************************************************************//** + * @brief + * The getAvailableEmbModeQueueCount function returns the available embedded + * mode queue count. + * @details Inputs: bloodLeakEmbModeCmdQCount + * @details Outputs: none + * @return Current available embedded mode queue count + *************************************************************************/ +static U32 getAvailableEmbModeQueueCount( void ) +{ + return BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE - bloodLeakEmbModeCmdQCount; +} + +/*********************************************************************//** + * @brief + * The enqueueInfoEmbModeCmds function enqueues the informative embedded + * mode commands. + * @details Inputs: bloodLeakEmbModeInfoCmdEnqueueLastTimeStamp, bloodLeakState, + * bloodLeakEmbModeInfoCmdCounter + * @details Outputs: bloodLeakEmbModeInfoCmdEnqueueLastTimeStamp, bloodLeakState, + * bloodLeakEmbModeInfoCmdCounter + * @return none + *************************************************************************/ +static void enqueueInfoEmbModeCmds( void ) +{ + if ( TRUE == didTimeout( bloodLeakEmbModeInfoCmdEnqLastTimeStamp, BLOOD_LEAK_EMB_MODE_INFO_CMD_TIMEOUT_MS ) ) + { + switch ( bloodLeakState ) + { + case BLOOD_LEAK_INIT_STATE: + case BLOOD_LEAK_NORMAL_STATE: + case BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE: + // 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 ); + } + else if ( 1 == bloodLeakEmbModeInfoCmdCounter ) + { + enqueueEmbModeCmd( V_EMB_MODE_CMD ); + } + + // Set the timer for the next time out to enqueue + // Reset the counter. The counter starts from 0 + bloodLeakEmbModeInfoCmdEnqLastTimeStamp = getMSTimerCount(); + bloodLeakEmbModeInfoCmdCounter = INC_WRAP( bloodLeakEmbModeInfoCmdCounter, 0, BLOOD_LEAK_EMB_MODE_NUM_OF_INFO_CMDS - 1 ); + break; + + default: + // Do nothing as the other commands are ignored + break; + } + } +} + +/*********************************************************************//** + * @brief + * The getBloodLeakRxBytesAvailable function returns the number of received + * bytes available from FPGA. + * @details Inputs: none + * @details Outputs: none + * @return Number of received bytes available + *************************************************************************/ +static U16 getBloodLeakRxBytesAvailable( void ) +{ + 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 ); + + 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 ) && ( bloodLeakState != BLOOD_LEAK_VERIFY_INTENSITY_AFTER_ZEROING_STATE ) ) + { + U32 index = bloodLeakZeroingStatus.rawIntensityNextIndex; + U32 indexValue = bloodLeakZeroingStatus.rawIntensity[ index ]; + U32 newIntensity = getEmbModeInfoValue( I_EMB_MODE_CMD ); + + bloodLeakZeroingStatus.rawIntensity[ index ] = newIntensity; + bloodLeakZeroingStatus.intensityRunningSum = bloodLeakZeroingStatus.intensityRunningSum - indexValue + newIntensity; + bloodLeakZeroingStatus.intensityMovingAverage.data = (F32)bloodLeakZeroingStatus.intensityRunningSum / (F32)BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES; + bloodLeakZeroingStatus.rawIntensityNextIndex = INC_WRAP( index, 0, BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES - 1 ); + + resetEmbModeCmdRespConsumedFlag( I_EMB_MODE_CMD ); + } +} +/*********************************************************************//** + * @brief + * The resetEmbModeCmdRespConsumedFlag function sets the cmd response ready flag + * to false its flag that fresh data is ready. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeCmd + * @param cmd the command to signal its data has been consumed + * @return none + *************************************************************************/ +static void resetEmbModeCmdRespConsumedFlag( U08 cmd ) +{ + bloodLeakEmbModeCmd[ cmd ].isCmdRespRdy = FALSE; +} + +/*********************************************************************//** + * @brief + * The getEmbModeInfoValue function gets the data of the embedded info cmds. + * This is only for the info values (I, V). + * @details Inputs: bloodLeakEmbModeIntensityOverride, + * bloodLeakEmbModeDetectOverride + * @details Outputs: bloodLeakEmbModeCmd + * @param cmd the command to get the read data + * @return the value of the read command + *************************************************************************/ +static U32 getEmbModeInfoValue( U08 cmd ) +{ + U32 value = bloodLeakEmbModeCmd[ cmd ].commandResp; + + switch( cmd ) + { + case I_EMB_MODE_CMD: + if ( OVERRIDE_KEY == bloodLeakEmbModeIntensityOverride.override ) + { + value = bloodLeakEmbModeIntensityOverride.ovData; + } + break; + + case V_EMB_MODE_CMD: + if ( OVERRIDE_KEY == bloodLeakEmbModeDetectOverride.override ) + { + value = bloodLeakEmbModeDetectOverride.ovData; + } + break; + + default: + // Do nothing with the rest of the commands + break; + } + + return value; +} + +/*********************************************************************//** + * @brief + * The isLowerRangeIntensityDriftZeroingNeeded function checks whether blood + * leak zeroing is needed in terms of drift in range drift (35-40%). + * @details Inputs: bloodLeakZeroingStatus + * @details Outputs: bloodLeakZeroingStatus + * @return TRUE if blood leak zeroing is needed otherwise, FALSE + *************************************************************************/ +static BOOL isLowerRangeIntensityDriftZeroingNeeded( void ) +{ + /* + * Nominal intensity = 930 + * Set point is queried from the blood leak detector + * Min drift from top = 930 - (setpoint * 40%) + * Max drift from top = 930 - (setpoint * 35%) + * If Min drift from top ≤ moving average intensity ≤ Max drift from top then the debounce timer is set + * If the debounce time has been elapsed the signal to zero the BLD is set + */ + BOOL status = FALSE; + BOOL isZeroingNeeded = TRUE; + U32 setPoint = bloodLeakEmbModeCmd[ D_EMB_MODE_CMD ].commandResp; + F32 driftMinFromTop = BLD_NOMINAL_INTENSITY - ( setPoint * BLD_MAX_INTENSITY_OUT_OF_RANGE ); + F32 driftMaxFromTop = BLD_NOMINAL_INTENSITY - ( setPoint * BLD_MIN_INTENSITY_OUT_OF_RANGE ); + U32 zeroingIntervalMS = getU32OverrideValue( &bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS ); + BOOL isZeroingAllowed = didTimeout( bloodLeakZeroingStatus.lastZeroingStartTimeMS, zeroingIntervalMS ); + F32 intensityMvgAvg = getF32OverrideValue( &bloodLeakZeroingStatus.intensityMovingAverage ); + + isZeroingNeeded &= ( intensityMvgAvg >= driftMinFromTop ? TRUE : FALSE ); + isZeroingNeeded &= ( intensityMvgAvg <= driftMaxFromTop ? TRUE : FALSE ); + + if ( FALSE == isZeroingNeeded ) + { + // Intensity drift is not in range so reset the debounce timer + bloodLeakZeroingStatus.driftInRangeDebounceTimeMS = getMSTimerCount(); + } + + if ( ( TRUE == isZeroingAllowed ) && ( TRUE == didTimeout( bloodLeakZeroingStatus.driftInRangeDebounceTimeMS, BLD_ZERO_IN_RANGE_DRIFT_TIMEOUT_MS ) ) ) + { + // If the moving average intensity is set and then the debounce time has elapsed the signal to zero is set to true. + status = TRUE; + } + + bloodLeakZeroingStatus.driftInRangeStatus = status; + + return status; +} + +/*********************************************************************//** + * @brief + * The isUpperIntensityZeroingNeeded function checks whether blood + * leak zeroing is needed in terms of drift upper range intensity (>= 950). + * @details Inputs: bloodLeakZeroingStatus + * @details Outputs: bloodLeakZeroingStatus + * @return TRUE if blood leak zeroing is needed otherwise, FALSE + *************************************************************************/ +static BOOL isUpperIntensityZeroingNeeded( void ) +{ + BOOL status = FALSE; + U32 zeroingUpperIntervalMS = getU32OverrideValue( &bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS ); + BOOL isZeroingAllowed = didTimeout( bloodLeakZeroingStatus.lastZeroingStartTimeMS, zeroingUpperIntervalMS ); + F32 intensityMvgAvg = getF32OverrideValue( &bloodLeakZeroingStatus.intensityMovingAverage ); + BOOL isUpperZeroingNeeded = ( intensityMvgAvg >= BLD_MAX_UPPER_INTENSITY_DRIFT ? TRUE : FALSE ); + + if ( FALSE == isUpperZeroingNeeded ) + { + bloodLeakZeroingStatus.driftUpperRangeDebounceTimeMS = getMSTimerCount(); + } + + if ( ( TRUE == isZeroingAllowed ) && ( TRUE == didTimeout( bloodLeakZeroingStatus.driftUpperRangeDebounceTimeMS, BLD_ZERO_UPPER_RANGE_DRIFT_TIMEOUT_MS ) ) ) + { + status = TRUE; + } + + bloodLeakZeroingStatus.driftUpperRangeStatus = status; + + return status; +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetBloodLeakDataPublishIntervalOverride function overrides the + * blood leak data publish interval. + * @details Inputs: none + * @details Outputs: bloodLeakDataPublishInterval + * @param value override blood leak data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodLeakDataPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_PRIORITY_INTERVAL; + result = TRUE; + bloodLeakDataPublishInterval.ovData = intvl; + bloodLeakDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBloodLeakDataPublishIntervalOverride function resets the override + * of the blood leak data publish interval. + * @details Inputs: none + * @details Outputs: bloodLeakDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetBloodLeakDataPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodLeakDataPublishInterval.override = OVERRIDE_RESET; + bloodLeakDataPublishInterval.ovData = bloodLeakDataPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBloodLeakStatusOverride function overrides the status + * of the blood leak detector. + * @details Inputs: none + * @details Outputs: bloodLeakStatus + * @param none + * @param status override blood leak detector with this + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodLeakStatusOverride( BLOOD_LEAK_STATUS_T status ) +{ + BOOL result = FALSE; + + if ( status < NUM_OF_BLOOD_LEAK_STATUS ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodLeakStatus.ovData = (U32)status; + bloodLeakStatus.override = OVERRIDE_KEY; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBloodLeakStatusOverride function resets the override of the + * blood leak detector status. + * @details Inputs: none + * @details Outputs: bloodLeakStatus + * @param none + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetBloodLeakStatusOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodLeakStatus.override = OVERRIDE_RESET; + bloodLeakStatus.ovData = bloodLeakStatus.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBloodLeak2EmbeddedMode function sets the blood leak driver to the + * embedded more for calibration. + * @details Inputs: none + * @details Outputs: bloodLeakSignalEmbeddedModeReq + * @return TRUE if switching to embedded mode was accepted otherwise, FALSE + *************************************************************************/ +BOOL testSetBloodLeak2EmbeddedMode( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + DD_OP_MODE_T mode = getCurrentOperationMode(); + + // Check if the mode is fault, service or standby before accepting a transition to + // the embedded mode + if ( ( MODE_FAUL == mode ) || ( MODE_SERV == mode ) || ( MODE_STAN == mode ) ) + { + bloodLeakSignalEmbModeReq = TRUE; + bloodLeakEmbModeRqstedCmd = CS_EMB_MODE_CMD; + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBloodLeakEmbeddedModeCommand function sets the blood leak + * calibration command. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeSetPoint + * @param command the command ID to be sent to blood leak in embedded mode + * @param setpointPayload the set point value that is sent with the set point + * command. This value is 0 with other commands since they do not have a payload + * @return TRUE if the command is accepted otherwise, FALSE + *************************************************************************/ +BOOL testSetBloodLeakEmbeddedModeCommand( U08 command, U16 setPointPayload ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( command < NUM_OF_EMB_CMDS ) ) + { + enqueueEmbModeCmd( command ); + + bloodLeakEmbModeSetPoint = setPointPayload; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBloodLeakEmbeddedModeInfoOverride function overrides the + * blood leak embedded mode info values. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeIntensityOverride, + * bloodLeakEmbModeDetectOverride + * @param command the command to override its value + * @param value the value that the command is overridden to + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodLeakEmbeddedModeInfoOverride( U08 command, U32 value ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( command < NUM_OF_EMB_CMDS ) ) + { + switch( command ) + { + case I_EMB_MODE_CMD: + result = TRUE; + bloodLeakEmbModeIntensityOverride.ovData = value; + bloodLeakEmbModeIntensityOverride.override = OVERRIDE_KEY; + break; + + case V_EMB_MODE_CMD: + result = TRUE; + bloodLeakEmbModeDetectOverride.ovData = value; + bloodLeakEmbModeDetectOverride.override = OVERRIDE_KEY; + break; + + default: + // Do nothing with the rest of the commands. They cannot be overridden. + break; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBloodLeakEmbeddedModeInfoOverride function reset the overrides + * of the blood leak embedded mode info values. + * @details Inputs: none + * @details Outputs: bloodLeakEmbModeIntensityOverride, + * bloodLeakEmbModeDetectOverride + * @param command the command to reset its override value + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetBloodLeakEmbeddedModeInfoOverride( U08 command ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( command < NUM_OF_EMB_CMDS ) ) + { + switch( command ) + { + case I_EMB_MODE_CMD: + result = TRUE; + bloodLeakEmbModeIntensityOverride.ovData = 0; + bloodLeakEmbModeIntensityOverride.override = OVERRIDE_RESET; + break; + + case V_EMB_MODE_CMD: + result = TRUE; + bloodLeakEmbModeDetectOverride.ovData = 0; + bloodLeakEmbModeDetectOverride.override = OVERRIDE_RESET; + break; + + default: + // Do nothing with the rest of the commands. They cannot be overridden. + break; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBloodLeakIntensityMovingAverageOverride function overrides the + * blood leak intensity moving average. + * @details Inputs: none + * @details Outputs: bloodLeakZeroingStatus + * @param value intensity moving average + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodLeakIntensityMovingAverageOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodLeakZeroingStatus.intensityMovingAverage.ovData = value; + bloodLeakZeroingStatus.intensityMovingAverage.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBloodLeakIntensityMovingAverageOverride function resets the + * override of the blood leak intensity moving average. + * @details Inputs: none + * @details Outputs: bloodLeakZeroingStatus + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetBloodLeakIntensityMovingAverageOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + bloodLeakZeroingStatus.intensityMovingAverage.ovData = bloodLeakZeroingStatus.intensityMovingAverage.ovInitData; + bloodLeakZeroingStatus.intensityMovingAverage.override = OVERRIDE_RESET; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBloodLeakZeroingIntervalInMinsOverride function overrides the + * blood leak zeroing interval in minutes. + * @details Inputs: none + * @details Outputs: bloodLeakZeroingStatus + * @param drift check interval or upper range intensity boolean flag + * @param value zeroing interval in minutes + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodLeakZeroingIntervalInMinsOverride( BOOL upperRangeInterval, U32 valueMins ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + if ( FALSE == upperRangeInterval ) + { + result = TRUE; + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.ovData = ( valueMins * SEC_PER_MIN * MS_PER_SECOND ); + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.override = OVERRIDE_KEY; + } + else + { + result = TRUE; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.ovData = ( valueMins * SEC_PER_MIN * MS_PER_SECOND ); + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.override = OVERRIDE_KEY; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBloodLeakZeroingIntervalInMinsOverride function resets the + * override of the blood leak zeroing interval + * @details Inputs: none + * @details Outputs: bloodLeakZeroingStatus + * @param boolean flag to indicate to reset upper range interval or the drift + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetBloodLeakZeroingIntervalInMinsOverride( BOOL upperRangeInterval ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + if ( FALSE == upperRangeInterval ) + { + result = TRUE; + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.ovData = bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.ovInitData; + bloodLeakZeroingStatus.zeroingDriftIntervalTimeMS.override = OVERRIDE_RESET; + } + else + { + result = TRUE; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.ovData = bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.ovInitData; + bloodLeakZeroingStatus.zeroingUpperRangeIntervalTimeMS.override = OVERRIDE_RESET; + } + } + + return result; +} + +/**@}*/ + + Index: firmware/App/Monitors/BloodLeak.h =================================================================== diff -u --- firmware/App/Monitors/BloodLeak.h (revision 0) +++ firmware/App/Monitors/BloodLeak.h (revision bc4537c14a446c8fe1720f574200399b180a6ff9) @@ -0,0 +1,82 @@ + + +#ifndef __BLOODLEAK_H__ +#define __BLOODLEAK_H__ + + +#include "DDCommon.h" + +/** + * @defgroup BloodLeak BloodLeak + * @brief Blood Leak detector monitor module. Monitors the + * blood leak detector. + * + * INTROTEK - Blood Component Detector Part No. 105-0002 + * + * @addtogroup BloodLeak + * @{ + */ + +// ********** public definitions ********** + +/// Enumeration of blood leak detector status. +typedef enum BloodLeakDetectorStatus +{ + BLOOD_LEAK_DETECTED = 0, ///< Blood leak detector senses blood. + BLOOD_LEAK_NOT_DETECTED, ///< Blood leak detector does not sense any blood. + NUM_OF_BLOOD_LEAK_STATUS ///< Number of blood leak detector status. +} BLOOD_LEAK_STATUS_T; + +/// Blood leak detector data publish +typedef struct +{ + U32 bloodLeakStatus; ///< Blood leak detector status. + 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. + F32 bloodLeakIntensityMovingAvg; ///< Blood leak detector intensity moving average. + U32 bloodLeakTimeSinceZeroMS; ///< Blood leak detector time since last zero in milliseconds. + U32 driftInRangeStatus; ///< Blood leak detector drift in range status. + U32 driftUpperRangeStatus; ///< Blood leak detector drift upper range status. +} BLOOD_LEAK_DATA_T; + +// ********** public function prototypes ********** + +void initBloodLeak( void ); +void execBloodLeak( void ); +void execBloodLeakEmbModeCommand( void ); +BOOL zeroBloodLeak( void ); +void zeroBloodLeakReset( void ); +BOOL hasBloodLeakZeroSequenceFailed( void ); +BOOL isBloodLeakZeroingNeeded( void ); + +void exitBloodLeakNormalState( void ); + +SELF_TEST_STATUS_T execBloodLeakSelfTest( void ); + +BLOOD_LEAK_STATUS_T getBloodLeakStatus( void ); +SELF_TEST_STATUS_T getBloodLeakSelfTestStatus( void ); + +BOOL testSetBloodLeakDataPublishIntervalOverride( U32 value ); +BOOL testResetBloodLeakDataPublishIntervalOverride( void ); + +BOOL testSetBloodLeakStatusOverride( BLOOD_LEAK_STATUS_T status ); +BOOL testResetBloodLeakStatusOverride( void ); + +BOOL testSetBloodLeak2EmbeddedMode( void ); +BOOL testSetBloodLeakEmbeddedModeCommand( U08 command, U16 setPointPayload ); + +BOOL testSetBloodLeakEmbeddedModeInfoOverride( U08 command, U32 value ); +BOOL testResetBloodLeakEmbeddedModeInfoOverride( U08 command ); + +BOOL testSetBloodLeakIntensityMovingAverageOverride( F32 value ); +BOOL testResetBloodLeakIntensityMovingAverageOverride( void ); + +BOOL testSetBloodLeakZeroingIntervalInMinsOverride( BOOL upperRangeInterval, U32 valueMins ); +BOOL testResetBloodLeakZeroingIntervalInMinsOverride( BOOL upperRangeInterval ); + +/**@}*/ + +#endif Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rafb05eebd86337012af4f6a9d21cb9a1e7f5f16a -rbc4537c14a446c8fe1720f574200399b180a6ff9 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision afb05eebd86337012af4f6a9d21cb9a1e7f5f16a) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision bc4537c14a446c8fe1720f574200399b180a6ff9) @@ -138,6 +138,10 @@ SW_FAULT_ID_PRE_GEND_WET_SELF_TEST_INVALID_EXEC_STATE = 107, SW_FAULT_ID_PRE_GEND_WET_SELF_TEST_INVALID_EXEC_STATE1 = 108, SW_FAULT_ID_UF_INVALID_EXEC_STATE = 109, + SW_FAULT_ID_TD_INVALID_BLOOD_LEAK_STATE = 110, + SW_FAULT_ID_BLOOD_LEAK_EMBEDDED_MODE_INVALID_STATE = 111, + SW_FAULT_ID_BLOOD_LEAK_ENQUEUE_FAILURE = 112, + SW_FAULT_ID_BLOOD_LEAK_INVALID_EMB_MODE_CMD_SELECTED = 113, #ifdef __PUMPTEST__ // Assigning high value to separate from actual fault id from test fault ids. SW_FAULT_ID_PISTON_PUMP_EXEC_INVALID_STATE = 9000,