Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r514463982373eb976e4b48a27d0f85f56e014920 -r40f46e196349e3dd730048a354df8bbb2e40407d --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 514463982373eb976e4b48a27d0f85f56e014920) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 40f46e196349e3dd730048a354df8bbb2e40407d) @@ -1,19 +1,19 @@ /************************************************************************** -* -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. -* -* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN -* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. -* -* @file BloodLeak.c -* -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 -* -* @author (original) Peman Montazemi -* @date (original) 18-Mar-2021 -* -***************************************************************************/ + * + * Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. + * + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * @file BloodLeak.c + * + * @author (last) Dara Navaei + * @date (last) 04-Jan-2022 + * + * @author (original) Peman Montazemi + * @date (original) 18-Mar-2021 + * + ***************************************************************************/ #include // For sprintf and strlen #include "AlarmMgmt.h" @@ -33,7 +33,7 @@ // ********** 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_TIMEOUT_MS 2000 ///< Blood leak detector timeout for zeroing and self-test (15 ms extended edge detection) #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_START_COMM_CTRL_U_ASCII 21 ///< Blood leak start communication command, ^U (Ctrl-U) in ascii. @@ -52,14 +52,18 @@ #define BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH 15 ///< Blood leak set point sequence maximum length. #define BLOOD_LEAK_WAIT_2_READ_SET_POINT ( 1 * MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Blood leak wait to read set point in counts. +#define BLOOD_LEAK_WAIT_2_READ_CTRL_U ( 1 * MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Blood leak wait to read control U in counts. #define BLOOD_LEAK_MAX_SET_POINT_WRITE_TRIALS 3 ///< Blood leak maximum number of trials to write the set point. +#define BLOOD_LEAK_MAX_CTRL_U_WRITE_TRIALS 3 ///< Blood leak maximum number of trials to write the control U command. #define BLOOD_LEAK_MIN_WAIT_TIME_2_GET_CAL_MS ( 2 * MS_PER_SECOND ) ///< Blood leak minimum wait time to get calibration in milliseconds. /// Defined states for the blood leak detector state machine. typedef enum BloodLeakStates { - BLOOD_LEAK_START_UP_STATE = 0, ///< Start up state. + BLOOD_LEAK_WAIT_FOR_POST_STATE = 0, ///< Wait for post state. + BLOOD_LEAK_START_UP_STATE, ///< Start up state. + BLOOD_LEAK_CHECK_COMM_STATE, ///< Check communication (Control U) 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. @@ -78,6 +82,7 @@ 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 bloodLeakIsPOSTComplete; ///< Blood leak is POST complete flag. static U32 bloodLeakPersistenceCtr = 0; ///< Blood leak alarm persistence timer counter. @@ -87,10 +92,11 @@ static U32 bloodLeakUARTCmdIndex = 0; ///< Blood leak UART command index. static U32 bloodLeakSetPointSeqLength = 0; ///< Blood leak set point sequence actual length. static U08 bloodLeakSetPointSequence[ BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH ]; ///< Blood leak set point sequence array. -static U32 bloodLeakWait2ReadSetPointCounter = 0; ///< Blood leak wait to read delay counter. -static U32 bloodLeakCurrentSetPointWriteTry = 0; ///< Blood leak current set point write try number. +static U32 bloodLeakWait2ReadResponseCounter; ///< Blood leak wait to read response counter. +static U32 bloodLeakCommandWriteTryCount; ///< Blood leak current set point write try number. static HD_BLOOD_LEAK_SENSOR_CAL_RECORD_T bloodLeakCalRecord; ///< Blood leak calibration record structure. -static U32 bloodLeakGetCalStartTime = 0; ///< Blood leak get calibration start time. +static U32 bloodLeakGetCalStartTime; ///< Blood leak get calibration start time. +static U32 bloodLeakPrevFPGARegisterCount; ///< Blood leak previous FPGA communications counter. /// Blood leak start up sequence array. static const U08 BLOOD_LEAK_START_UP_SEQUENCE[ BLOOD_LEAK_STARTUP_SEQ_LENGTH ] = { BLOOD_LEAK_RESET_TX_FIFO, @@ -102,7 +108,9 @@ // ********** private function prototypes ********** +static BLOOD_LEAK_STATES_T handleBloodLeakWaitForPostState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakStartupState( void ); +static BLOOD_LEAK_STATES_T handleBloodLeakCheckCommState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakCheckSetPointState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakSetSetPointState( void ); static BLOOD_LEAK_STATES_T handleBloodLeakInitState( void ); @@ -119,15 +127,16 @@ * @details Inputs: none * @details Outputs: bloodLeakState, bloodLeakStatus, bloodLeakSelfTestStatus, * bloodLeakZeroRequested, bloodLeakZeroRequested, bloodLeakSelfTestStartTime, - * bloodLeakUARTCmdIndex, bloodLeakSetPointSequence, - * bloodLeakWait2ReadSetPointCounter, bloodLeakDataPublicationTimerCounter, - * bloodLeakCurrentSetPointWriteTry, bloodLeakGetCalStartTime + * bloodLeakUARTCmdIndex, bloodLeakSetPointSequence, bloodLeakPrevFPGARegisterCount + * bloodLeakWait2ReadResponseCounter, bloodLeakDataPublicationTimerCounter, + * bloodLeakCommandWriteTryCount, bloodLeakGetCalStartTime, + * bloodLeakIsPOSTComplete * @return none *************************************************************************/ void initBloodLeak( void ) { bloodLeakDataPublicationTimerCounter = 0; - bloodLeakState = BLOOD_LEAK_START_UP_STATE; + 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; @@ -138,9 +147,11 @@ bloodLeakSelfTestStartTime = 0; bloodLeakUARTCmdIndex = 0; bloodLeakSetPointSeqLength = 0; - bloodLeakWait2ReadSetPointCounter = 0; - bloodLeakCurrentSetPointWriteTry = 0; + bloodLeakWait2ReadResponseCounter = 0; + bloodLeakCommandWriteTryCount = 0; bloodLeakGetCalStartTime = getMSTimerCount(); + bloodLeakIsPOSTComplete = FALSE; + bloodLeakPrevFPGARegisterCount = 0; // Set the blood leak set pint sequence to 0 to be initialized memset( bloodLeakSetPointSequence, 0x0, BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH ); @@ -179,10 +190,18 @@ // Execute blood leak state machine switch( bloodLeakState ) { + case BLOOD_LEAK_WAIT_FOR_POST_STATE: + bloodLeakState = handleBloodLeakWaitForPostState(); + break; + case BLOOD_LEAK_START_UP_STATE: bloodLeakState = handleBloodLeakStartupState(); break; + case BLOOD_LEAK_CHECK_COMM_STATE: + bloodLeakState = handleBloodLeakCheckCommState(); + break; + case BLOOD_LEAK_CHECK_SET_POINT_STATE: bloodLeakState = handleBloodLeakCheckSetPointState(); break; @@ -249,7 +268,8 @@ if ( TRUE == calStatus ) { - result = SELF_TEST_STATUS_PASSED; + result = SELF_TEST_STATUS_PASSED; + bloodLeakIsPOSTComplete = TRUE; } else { @@ -261,6 +281,29 @@ /*********************************************************************//** * @brief + * The handleBloodLeakWaitForPostState function handles the wait for POST + * state of the of blood leak state machine. + * @details Inputs: bloodLeakIsPOSTComplete, bloodLeakPrevFPGARegisterCount + * @details Outputs: none + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakWaitForPostState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_WAIT_FOR_POST_STATE; + + if ( TRUE == bloodLeakIsPOSTComplete ) + { + // Read the value that is in the FPGA counter so it can be used to make sure the blood leak is communicating after + // sending Ctrl U + bloodLeakPrevFPGARegisterCount = getFPGABloodLeakRegisterCounter(); + state = BLOOD_LEAK_START_UP_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleBloodLeakStartupState function handles the startup state of the * of blood leak state machine. * @details Inputs: bloodLeakUARTCmdIndex @@ -287,8 +330,12 @@ // Done with writing all the commands, reset the index and transition if ( bloodLeakUARTCmdIndex >= ( BLOOD_LEAK_STARTUP_SEQ_LENGTH - 1 ) ) { - bloodLeakUARTCmdIndex = 0; - state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + // Wait for the sensor to start communication + if ( ++bloodLeakWait2ReadResponseCounter > BLOOD_LEAK_WAIT_2_READ_CTRL_U ) + { + bloodLeakUARTCmdIndex = 0; + state = BLOOD_LEAK_CHECK_COMM_STATE; + } } else { @@ -300,6 +347,46 @@ /*********************************************************************//** * @brief + * The handleBloodLeakCheckCommState function handles the check communication + * state to ensure the sensor is communicating. + * @details Inputs: bloodLeakCommandWriteTryCount, bloodLeakPrevFPGARegisterCount + * @details Outputs: bloodLeakCommandWriteTryCount, bloodLeakPrevFPGARegisterCount + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakCheckCommState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_CHECK_COMM_STATE; + + // Check if the blood leak sensor has started communicating + BOOL isBloodLeakCommunicating = ( bloodLeakPrevFPGARegisterCount != getFPGABloodLeakRegisterCounter() ? TRUE : FALSE ); + + // The sensor is communicating move on + if ( TRUE == isBloodLeakCommunicating ) + { + state = BLOOD_LEAK_CHECK_SET_POINT_STATE; + bloodLeakCommandWriteTryCount = 0; + } + else + { + // If the sensor is not communicating, and the number of writes has not exceeded try again, otherwise alarm + if ( bloodLeakCommandWriteTryCount < BLOOD_LEAK_MAX_CTRL_U_WRITE_TRIALS ) + { + bloodLeakCommandWriteTryCount++; + + bloodLeakPrevFPGARegisterCount = getFPGABloodLeakRegisterCounter(); + state = BLOOD_LEAK_START_UP_STATE; + } + else + { + // TODO alarm. Should we check the BLD communications all the time like in the monitor? + } + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleBloodLeakCheckSetPointState function handles the check set point * state to ensure the set point is set correctly. * @details Inputs: none @@ -313,28 +400,32 @@ U16 bloodLeakSetPoint = getFPGABloodLeakDetectSetPoint(); #ifdef BOARD_WITH_NO_HARDWARE - bloodLeakCalRecord.setPoint = 30; + // In case it is just a bare board, use this value + bloodLeakCalRecord.setPoint = 20; #endif if ( bloodLeakSetPoint != bloodLeakCalRecord.setPoint ) { - if ( bloodLeakCurrentSetPointWriteTry < BLOOD_LEAK_MAX_SET_POINT_WRITE_TRIALS ) + if ( bloodLeakCommandWriteTryCount < BLOOD_LEAK_MAX_SET_POINT_WRITE_TRIALS ) { prepareSetPointSeq(); - bloodLeakCurrentSetPointWriteTry++; + bloodLeakCommandWriteTryCount++; state = BLOOD_LEAK_SET_SET_POINT_STATE; } else { #ifndef IGNORE_BLOOD_LEAK_ALARM - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_SET_POINT_SET_FAILURE ); + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_SET_POINT_SET_FAILURE ); + } #endif } } else { state = BLOOD_LEAK_INIT_STATE; - bloodLeakCurrentSetPointWriteTry = 0; + bloodLeakCommandWriteTryCount = 0; } return state; @@ -373,9 +464,9 @@ } else { - if ( ++bloodLeakWait2ReadSetPointCounter > BLOOD_LEAK_WAIT_2_READ_SET_POINT ) + if ( ++bloodLeakWait2ReadResponseCounter > BLOOD_LEAK_WAIT_2_READ_SET_POINT ) { - bloodLeakWait2ReadSetPointCounter = 0; + bloodLeakWait2ReadResponseCounter = 0; bloodLeakUARTCmdIndex = 0; // Done with writing the set point state = BLOOD_LEAK_CHECK_SET_POINT_STATE; @@ -434,10 +525,13 @@ if ( TRUE == didTimeout( bloodLeakZeroStartTime, BLOOD_LEAK_TIMEOUT_MS ) ) { #ifndef IGNORE_BLOOD_LEAK_ALARM - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_FAULT ); + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_FAULT ); + } #endif } - } + } return state; } @@ -454,7 +548,6 @@ { BLOOD_LEAK_STATES_T state = BLOOD_LEAK_SELF_TEST_STATE; -#ifndef IGNORE_BLOOD_LEAK_ALARM if ( SELF_TEST_STATUS_IN_PROGRESS == bloodLeakSelfTestStatus ) { if ( FALSE == noFPGABloodLeakDetected() ) // Faked blood leak caused by independent MCU board @@ -467,7 +560,7 @@ bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_FAILURE ); - } + } } else { @@ -477,9 +570,6 @@ state = BLOOD_LEAK_NORMAL_STATE; } } -#else - state = BLOOD_LEAK_NORMAL_STATE; -#endif return state; } @@ -512,7 +602,10 @@ { bloodLeakPersistenceCtr = BLOOD_LEAK_PERSISTENCE; #ifndef IGNORE_BLOOD_LEAK_ALARM - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + } #endif } } @@ -525,7 +618,10 @@ else { #ifndef IGNORE_BLOOD_LEAK_ALARM - clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) + { + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + } #endif } } @@ -609,9 +705,9 @@ // Loop through the number of digits and get each ASCII value for ( i = 0; i < digitCount; i++ ) { - // Write the characters - bloodLeakSetPointSequence[ bufferIndex ] = tempCharBuffer[ i ]; - bufferIndex++; + // Write the characters + bloodLeakSetPointSequence[ bufferIndex ] = tempCharBuffer[ i ]; + bufferIndex++; } // After the characters, insert the carriage return into the buffer