/************************************************************************** * * Copyright (c) 2019-2021 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) Peman Montazemi * @date (last) 18-Mar-2021 * * @author (original) Peman Montazemi * @date (original) 18-Mar-2021 * ***************************************************************************/ #include "AlarmMgmt.h" #include "BloodLeak.h" #include "FPGA.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskPriority.h" #include "Timers.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. // ********** private data ********** static OVERRIDE_U32_T bloodLeakState; ///< Current state of blood leak state machine. static OVERRIDE_U32_T bloodLeakStatus; ///< Detected blood leak status for blood leak detector. static U32 bloodLeakZeroTimerCount = 0; ///< Timer counter for blood leak zeroing. static U32 bloodLeakSelfTestTimerCount = 0; ///< Timer counter for blood leak self-test. /// Interval (in ms) at which to publish blood leak data to CAN bus. static OVERRIDE_U32_T bloodLeakStatusPublishInterval = { BLOOD_LEAK_PUB_INTERVAL, BLOOD_LEAK_PUB_INTERVAL, 0, 0 }; static OVERRIDE_U32_T bloodLeakStatePublishInterval = { BLOOD_LEAK_PUB_INTERVAL, BLOOD_LEAK_PUB_INTERVAL, 0, 0 }; static U32 bloodLeakStatusPublicationTimerCounter = 0; ///< Timer counter used to schedule blood leak status publication to CAN bus. static U32 bloodLeakStatePublicationTimerCounter = 0; ///< Timer counter used to schedule blood leak state publication to CAN bus. // ********** private function prototypes ********** static void publishBloodLeakStatus( void ); static void publishBloodLeakState( void ); static U32 getPublishBloodLeakStatusInterval( void ); static U32 getPublishBloodLeakStateInterval( void ); /*********************************************************************//** * @brief * The initBloodLeak function initializes the Blood Leak module. * @details Inputs: none * @details Outputs: Blood Leak module initialized. * @return none *************************************************************************/ void initBloodLeak( void ) { bloodLeakState.data = BLOOD_LEAK_INIT_STATE; bloodLeakStatus.data = BLOOD_LEAK_NOT_DETECTED; } /*********************************************************************//** * @brief * The zeroBloodLeak function puts the Blood Leak module into zeroing state. * @details Inputs: none * @details Outputs: Blood Leak module zeroing. * @return none *************************************************************************/ void zeroBloodLeak( void ) { bloodLeakState.data = BLOOD_LEAK_ZERO_STATE; //setBloodLeakZero(); TODO } /*********************************************************************//** * @brief * The selfTestBloodLeak function puts the Blood Leak module into self-test state. * @details Inputs: none * @details Outputs: Blood Leak module self test. * @return none *************************************************************************/ BOOL selfTestBloodLeak( void ) { bloodLeakState.data = BLOOD_LEAK_SELF_TEST_STATE; //setBloodLeakSelfTest(); TODO return TRUE; } /*********************************************************************//** * @brief * The execBloodLeak function executes the blood leak monitor. * @details Inputs: FPGA blood leak status GPIO pin state * @details Outputs: bloodLeakStatus * @return none *************************************************************************/ void execBloodLeak( void ) { BOOL noBloodLeakDetected = noFPGABloodLeakDetected(); if ( getCurrentOperationMode() != MODE_INIT ) { // Get latest status reading if ( TRUE == noBloodLeakDetected ) { bloodLeakStatus.data = BLOOD_LEAK_NOT_DETECTED; } else { bloodLeakStatus.data = BLOOD_LEAK_DETECTED; } if ( bloodLeakState.data == BLOOD_LEAK_SELF_TEST_STATE ) { if ( FALSE == selfTestBloodLeak() ) { activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTOR_FAULT ); } } else // Blood Leak Detector is not in self-test state (normal state) { // Check status reading and act upon if ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) { if ( getCurrentOperationMode() == HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE ) // TODO: Any other mode/sub-mode to be added here? { activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); } else { activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTOR_FAULT ); } } else // BLOOD_LEAK_NOT_DETECTED == getBloodLeakStatus() { clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); } } } // Publish blood leak status if due publishBloodLeakStatus(); // Publish blood leak state if due publishBloodLeakState(); } /*********************************************************************//** * @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 getPublishBloodLeakStatusInterval function gets the blood leak status * publication interval. * @details Inputs: bloodLeakStatusPublishInterval * @details Outputs: none * @return the current blood leak status publication interval (in task intervals). *************************************************************************/ static U32 getPublishBloodLeakStatusInterval( void ) { U32 result = bloodLeakStatusPublishInterval.data; if ( OVERRIDE_KEY == bloodLeakStatusPublishInterval.override ) { result = bloodLeakStatusPublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The publishBloodLeakStatus function publishes blood leak status at the set interval. * @details Inputs: bloodLeakStatus * @details Outputs: if broadcast is due, send blood leak status * @return none *************************************************************************/ static void publishBloodLeakStatus( void ) { // Publish blood leak status on interval if ( ++bloodLeakStatusPublicationTimerCounter >= getPublishBloodLeakStatusInterval() ) { BLOOD_LEAK_STATUS_T status = getBloodLeakStatus(); broadcastBloodLeakStatus( status ); bloodLeakStatusPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The getBloodLeakState function gets the current state of the blood * leak detector state machine. * @details Inputs: bloodLeakState * @details Outputs: none * @return the current blood leak state. *************************************************************************/ BLOOD_LEAK_STATES_T getBloodLeakState( void ) { BLOOD_LEAK_STATES_T result = (BLOOD_LEAK_STATES_T)bloodLeakState.data; if ( OVERRIDE_KEY == bloodLeakState.override ) { result = (BLOOD_LEAK_STATES_T)bloodLeakState.ovData; } return result; } /*********************************************************************//** * @brief * The getPublishBloodLeakStateInterval function gets the blood leak state * publication interval. * @details Inputs: bloodLeakStatePublishInterval * @details Outputs: none * @return the current blood leak state publication interval (in task intervals). *************************************************************************/ static U32 getPublishBloodLeakStateInterval( void ) { U32 result = bloodLeakStatePublishInterval.data; if ( OVERRIDE_KEY == bloodLeakStatePublishInterval.override ) { result = bloodLeakStatePublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The publishBloodLeakState function publishes blood leak state at the set interval. * @details Inputs: bloodLeakState * @details Outputs: if broadcast is due, send blood leak state * @return none *************************************************************************/ static void publishBloodLeakState( void ) { // Publish blood leak state on interval if ( ++bloodLeakStatePublicationTimerCounter >= getPublishBloodLeakStateInterval() ) { BLOOD_LEAK_STATES_T state = getBloodLeakState(); broadcastBloodLeakState( state ); bloodLeakStatePublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetBloodLeakStatusPublishIntervalOverride function overrides the * blood leak status publish interval. * @details Inputs: none * @details Outputs: bloodLeakStatusPublishInterval * @param value override blood leak status publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetBloodLeakStatusPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; result = TRUE; bloodLeakStatusPublishInterval.ovData = intvl; bloodLeakStatusPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetBloodLeakStatusPublishIntervalOverride function resets the override * of the blood leak status publish interval. * @details Inputs: none * @details Outputs: bloodLeakStatusPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetBloodLeakStatusPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; bloodLeakStatusPublishInterval.override = OVERRIDE_RESET; bloodLeakStatusPublishInterval.ovData = bloodLeakStatusPublishInterval.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. * @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 testSetBloodLeakStatePublishIntervalOverride function overrides the * blood leak state publish interval. * @details Inputs: none * @details Outputs: bloodLeakStatePublishInterval * @param value override blood leak state publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetBloodLeakStatePublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; result = TRUE; bloodLeakStatePublishInterval.ovData = intvl; bloodLeakStatePublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetBloodLeakStatePublishIntervalOverride function resets the override * of the blood leak state publish interval. * @details Inputs: none * @details Outputs: bloodLeakStatePublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetBloodLeakStatePublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; bloodLeakStatePublishInterval.override = OVERRIDE_RESET; bloodLeakStatePublishInterval.ovData = bloodLeakStatePublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetBloodLeakStateOverride function overrides the state * of the blood leak detector state machine. * @details Inputs: none * @details Outputs: bloodLeakState * @param none * @param state override blood leak detector with this * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetBloodLeakStateOverride( BLOOD_LEAK_STATES_T state ) { BOOL result = FALSE; if ( ( state < NUM_OF_BLOOD_LEAK_STATES ) ) { if ( TRUE == isTestingActivated() ) { result = TRUE; bloodLeakState.ovData = (U32)state; bloodLeakState.override = OVERRIDE_KEY; } } return result; } /*********************************************************************//** * @brief * The testResetBloodLeakStateOverride function resets the override of the * blood leak detector state machine. * @details Inputs: none * @details Outputs: bloodLeakState * @param none * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetBloodLeakStateOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; bloodLeakState.override = OVERRIDE_RESET; bloodLeakState.ovData = bloodLeakState.ovInitData; } return result; } /**@}*/