Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r74be223d47ea7bb0ac7d814e74d3627d830a5fac -rb531672fa7e70a0be9e4fa0e9c87bfe3c2628d68 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 74be223d47ea7bb0ac7d814e74d3627d830a5fac) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision b531672fa7e70a0be9e4fa0e9c87bfe3c2628d68) @@ -8,7 +8,7 @@ * @file BloodLeak.c * * @author (last) Sean Nash -* @date (last) 11-Aug-2021 +* @date (last) 12-Nov-2021 * * @author (original) Peman Montazemi * @date (original) 18-Mar-2021 @@ -30,35 +30,70 @@ // ********** 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_TIMEOUT_MS 500 ///< Blood leak detector timeout for zeroing and self-test (15 ms extended edge detection) +#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_TIMEOUT_MS 500 ///< Blood leak detector timeout for zeroing and self-test (15 ms extended edge detection) +#define BLOOD_LEAK_PERSISTENCE ( 5 * 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_START_COMM_CTRL_U_ASCII 21 ///< Blood leak start communication command, ^U (Ctrl-U) in ascii. +#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_STARTUP_SEQUENCE_LENGTH 5 ///< Blood leak start up sequence array length. +#define BLOOD_LEAK_SET_POINT_START_CHAR 'S' +#define BLOOD_LEAK_CARRIAGE_RETURN_ASCII 13 +#define BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH 7 + + /// Defined states for the blood leak detector state machine. typedef enum BloodLeakStates { - BLOOD_LEAK_INIT_STATE = 0, ///< Initial state - BLOOD_LEAK_ZERO_STATE, ///< Zero state - BLOOD_LEAK_SELF_TEST_STATE, ///< Self-test state - BLOOD_LEAK_NORMAL_STATE, ///< Normal state - NUM_OF_BLOOD_LEAK_STATES ///< Number of blood leak detector states + BLOOD_LEAK_START_UP_STATE = 0, ///< Start up state. + BLOOD_LEAK_CHECK_SET_POINT_STATE, ///< Check set point state. + BLOOD_LEAK_SET_SET_POINT_STATE, ///< Set set point state. + BLOOD_LEAK_INIT_STATE, ///< Init state. + BLOOD_LEAK_ZERO_STATE, ///< Zero state. + BLOOD_LEAK_SELF_TEST_STATE, ///< Self-test state. + BLOOD_LEAK_NORMAL_STATE, ///< Normal state. + NUM_OF_BLOOD_LEAK_STATES ///< Number of blood leak detector states. } BLOOD_LEAK_STATES_T; // ********** private data ********** -static BLOOD_LEAK_STATES_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 BLOOD_LEAK_STATES_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 BOOL bloodLeakZeroRequested = FALSE; ///< Blood leak zero requested flag -static U32 bloodLeakZeroStartTime = 0; ///< Blood leak zeroing start time. -static U32 bloodLeakSelfTestStartTime = 0; ///< Blood leak self-test start time. +static BOOL bloodLeakZeroRequested = FALSE; ///< Blood leak zero requested flag +static U32 bloodLeakZeroStartTime = 0; ///< Blood leak zeroing start time. +static U32 bloodLeakSelfTestStartTime = 0; ///< Blood leak self-test start time. -/// Interval (in ms) at which to publish blood leak data to CAN bus. -static OVERRIDE_U32_T bloodLeakDataPublishInterval = { BLOOD_LEAK_PUB_INTERVAL, BLOOD_LEAK_PUB_INTERVAL, 0, 0 }; -static U32 bloodLeakDataPublicationTimerCounter = 0; ///< Timer counter used to schedule blood leak data publication to CAN bus. +static U32 bloodLeakPersistenceCtr = 0; ///< 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 bloodLeakDataPublicationTimerCounter = 0; ///< Timer counter used to schedule blood leak data publication to CAN bus. + +static U32 bloodLeakUARTCmdIndex; ///< Blood leak UART command index. + +static U32 bloodLeakSetPointSequenceActualLength = 0; ///< Blood leak set point sequence actual length. + +static U08 bloodLeakSetPointSequence[ BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH ]; ///< Blood leak set point sequence array. + +/// Blood leak start up sequence array. +static const U08 BLOOD_LEAK_START_UP_SEQUENCE[ BLOOD_LEAK_STARTUP_SEQUENCE_LENGTH ] = { BLOOD_LEAK_RESET_TX_FIFO, + BLOOD_LEAK_UART_COMM_ACTIVE_LOW, + BLOOD_LEAK_START_COMM_CTRL_U_ASCII, + BLOOD_LEAK_UART_COMM_ACTIVE_HIGH, + BLOOD_LEAK_UART_COMM_ACTIVE_LOW }; +static const U32 REMOVE_LATER_SET_POINT = 20; // TODO remove this later +static U32 test = 23; + + // ********** private function prototypes ********** +static BLOOD_LEAK_STATES_T handleBloodLeakStartupState( void ); +static BLOOD_LEAK_STATES_T handleBloodLeakCheckSetPointState( void ); +static BLOOD_LEAK_STATES_T handleBloodLeakSetSetPointState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakInitState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakZeroState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakSelfTestState( void ); @@ -70,20 +105,26 @@ * @brief * The initBloodLeak function initializes the Blood Leak module. * @details Inputs: none - * @details Outputs: Blood Leak module initialized. + * @details Outputs: bloodLeakState, bloodLeakStatus, bloodLeakSelfTestStatus, + * bloodLeakZeroRequested, bloodLeakZeroRequested, bloodLeakSelfTestStartTime, + * bloodLeakUARTCmdIndex, bloodLeakSetPointSequence * @return none *************************************************************************/ void initBloodLeak( void ) { - bloodLeakState = BLOOD_LEAK_INIT_STATE; - bloodLeakStatus.data = BLOOD_LEAK_NOT_DETECTED; + bloodLeakState = BLOOD_LEAK_START_UP_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; - bloodLeakZeroRequested = FALSE; - bloodLeakZeroStartTime = 0; + bloodLeakStatus.ovData = BLOOD_LEAK_NOT_DETECTED; + bloodLeakStatus.override = OVERRIDE_RESET; + bloodLeakSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + bloodLeakZeroRequested = FALSE; + bloodLeakZeroStartTime = 0; bloodLeakSelfTestStartTime = 0; + bloodLeakUARTCmdIndex = 0; + + // Set the blood leak set pint sequence to 0 to be initialized + memset( bloodLeakSetPointSequence, 0x0, BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH); } /*********************************************************************//** @@ -100,6 +141,18 @@ // Execute blood leak state machine switch( bloodLeakState ) { + case BLOOD_LEAK_START_UP_STATE: + bloodLeakState = handleBloodLeakStartupState(); + break; + + case BLOOD_LEAK_CHECK_SET_POINT_STATE: + bloodLeakState = handleBloodLeakCheckSetPointState(); + break; + + case BLOOD_LEAK_SET_SET_POINT_STATE: + bloodLeakState = handleBloodLeakSetSetPointState(); + break; + case BLOOD_LEAK_INIT_STATE: bloodLeakState = handleBloodLeakInitState(); break; @@ -142,10 +195,89 @@ /*********************************************************************//** * @brief + * The handleBloodLeakStartupState function handles the startup state of the + * of blood leak state machine. + * @details Inputs: bloodLeakUARTCmdIndex + * @details Outputs: bloodLeakUARTCmdIndex + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakStartupState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_START_UP_STATE; + + U32 command = BLOOD_LEAK_START_UP_SEQUENCE[ bloodLeakUARTCmdIndex ]; + + if ( BLOOD_LEAK_START_COMM_CTRL_U_ASCII == command ) + { + setFPGABloodLeakUARTTransmit( (U08)command ); + } + else + { + setFPGABloodLeakUARTControl( command ); + } + + if ( bloodLeakUARTCmdIndex > BLOOD_LEAK_STARTUP_SEQUENCE_LENGTH - 1 ) + { + bloodLeakUARTCmdIndex = 0; + state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + } + else + { + bloodLeakUARTCmdIndex++; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakCheckSetPointState function handles the check set point + * state to ensure the set point is set correctly. + * @details Inputs: none + * @details Outputs: none + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakCheckSetPointState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + + U32 bloodLeakSetPoint = (U32)getFPGABloodLeakDetectSetPoint(); + + if ( REMOVE_LATER_SET_POINT == bloodLeakSetPoint ) + { + state = BLOOD_LEAK_SET_SET_POINT_STATE; + } + else + { + state = BLOOD_LEAK_INIT_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakSetSetPointState function handles the set set point state. + * @details Inputs: none + * @details Outputs: TODO fill up + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakSetSetPointState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_SET_SET_POINT_STATE; + + // TODO implement the set set point state + state = BLOOD_LEAK_INIT_STATE; + + return state; +} + +/*********************************************************************//** + * @brief * The handleBloodLeakInitState function handles the Blood Leak module in init * state. * @details Inputs: none - * @details Outputs: Blood Leak module init. + * @details Outputs: none * @return next state *************************************************************************/ static BLOOD_LEAK_STATES_T handleBloodLeakInitState( void ) @@ -188,7 +320,9 @@ { if ( TRUE == didTimeout( bloodLeakZeroStartTime, BLOOD_LEAK_TIMEOUT_MS ) ) { +#ifndef IGNORE_BLOOD_LEAK_ALARM activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_FAULT ); +#endif } } @@ -207,6 +341,7 @@ { BLOOD_LEAK_STATES_T state = BLOOD_LEAK_SELF_TEST_STATE; +#ifndef IGNORE_BLOOD_LEAK_SELF_TEST if ( SELF_TEST_STATUS_IN_PROGRESS == bloodLeakSelfTestStatus ) { if ( FALSE == noFPGABloodLeakDetected() ) // Faked blood leak caused by independent MCU board @@ -217,8 +352,9 @@ else if ( TRUE == didTimeout( bloodLeakSelfTestStartTime, BLOOD_LEAK_TIMEOUT_MS ) ) { bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_FAILURE ); - } + } } else { @@ -228,6 +364,9 @@ state = BLOOD_LEAK_NORMAL_STATE; } } +#else + state = BLOOD_LEAK_NORMAL_STATE; +#endif return state; } @@ -254,21 +393,29 @@ } // Check status reading and act upon - if ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) + if ( ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) && ( getCurrentOperationMode() == MODE_TREA ) ) { - if ( getCurrentOperationMode() == MODE_TREA ) + if ( ++bloodLeakPersistenceCtr > BLOOD_LEAK_PERSISTENCE ) { + bloodLeakPersistenceCtr = BLOOD_LEAK_PERSISTENCE; +#ifndef IGNORE_BLOOD_LEAK_ALARM activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); +#endif } + } + else // Blood leak not detected + { + if ( bloodLeakPersistenceCtr > 0 ) + { + bloodLeakPersistenceCtr--; + } else { - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_FAULT ); +#ifndef IGNORE_BLOOD_LEAK_ALARM + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); +#endif } } - else // Blood leak not detected - { - clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); - } if ( TRUE == bloodLeakZeroRequested ) { @@ -327,11 +474,20 @@ // Publish blood leak data on interval if ( ++bloodLeakDataPublicationTimerCounter >= getU32OverrideValue( &bloodLeakDataPublishInterval ) ) { - BLOOD_LEAK_DATA_T bloodLeakData; + BLOOD_LEAK_DATA_T data; - bloodLeakData.bloodLeakStatus = (U32)getBloodLeakStatus(); - bloodLeakData.bloodLeakState = (U32)bloodLeakState; - broadcastData( MSG_ID_HD_BLOOD_LEAK_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&bloodLeakData, sizeof( BLOOD_LEAK_DATA_T ) ); + data.bloodLeakStatus = (U32)getBloodLeakStatus(); + data.bloodLeakState = (U32)bloodLeakState; + data.bloodLeakZeroStatusCounter = (U32)getFPGABloodLeakZeroStatusCounter(); + data.bloodLeakCounter = (U32)getFPGABloodLeakCounter(); + data.bloodLeakZeroedStatus = (U32)getFPGABloodLeakZeroedStatus(); + data.bloodLeakDetectSetPoint = (U32)getFPGABloodLeakDetectSetPoint(); + data.bloodLeakDetectLevel = (U32)getFPGABloodLeakDetectLevel(); + data.bloodLeakStCount = (U32)getFPGABloodLeakStCount(); + data.bloodLeakLEDIntesity = (U32)getFPGABloodLeakLEDIntensity(); + data.bloodLeakRegisterCounter = (U32)getFPGABloodLeakRegisterCounter(); + + broadcastData( MSG_ID_HD_BLOOD_LEAK_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( BLOOD_LEAK_DATA_T ) ); bloodLeakDataPublicationTimerCounter = 0; } }