Index: firmware/App/Controllers/Bubble.c =================================================================== diff -u --- firmware/App/Controllers/Bubble.c (revision 0) +++ firmware/App/Controllers/Bubble.c (revision f24be7fd135878e6ff28dff56937c31626bd4bc1) @@ -0,0 +1,474 @@ +/************************************************************************** +* +* 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 Bubble.c +* +* @author (last) Peman Montazemi +* @date (last) 30-Apr-2021 +* +* @author (original) Peman Montazemi +* @date (original) 30-Apr-2021 +* +***************************************************************************/ + +#include "AlarmMgmt.h" +#include "Bubble.h" +#include "FPGA.h" +#include "OperationModes.h" +#include "SystemCommMessages.h" +#include "TaskPriority.h" +#include "Timers.h" + +/** + * @addtogroup Bubble + * @{ + */ + +// ********** private definitions ********** + +#define BUBBLE_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the air bubble detector data is published on the CAN bus. +#define BUBBLE_TIMEOUT_MS 500 ///< Air bubble detector timeout for self-test (15 ms extended edge detection) + +/// Defined states for the air bubble detectors state machine. +typedef enum BubbleStates +{ + BUBBLE_INIT_STATE = 0, ///< Initial state + BUBBLE_SELF_TEST_STATE, ///< Self-test state + BUBBLE_NORMAL_STATE, ///< Normal state + NUM_OF_BUBBLE_STATES ///< Number of bubble detector states +} BUBBLE_STATES_T; + +// ********** private data ********** + +static BUBBLE_STATES_T bubblesState[ NUM_OF_BUBBLES ]; ///< Current state of air bubble detectors state machines. +static OVERRIDE_U32_T bubblesStatus[ NUM_OF_BUBBLES ]; ///< Detected air bubble status for air bubble detectors. +static SELF_TEST_STATUS_T bubblesSelfTestStatus[ NUM_OF_BUBBLES ]; ///< Current status of air bubble detectors self-tests. + +static U32 bubblesSelfTestStartTime = [ 0, 0 ]; ///< Air bubble detectors self-test start times. +static BOOL bubblesSelfTestRequested = [ FALSE, FALSE ]; ///< Air bubble detectors self-test requested flags. + +/// Interval (in ms) at which to publish air bubble detectors data on CAN bus. +static OVERRIDE_U32_T bubblesDataPublishInterval = { BUBBLE_PUB_INTERVAL, BUBBLE_PUB_INTERVAL, 0, 0 }; +static U32 bubblesDataPublicationTimerCounter = 0; ///< Timer counter used to schedule air bubble detectors data publication to CAN bus. + +// ********** private function prototypes ********** + +static BUBBLE_STATES_T handleBubbleInitState( BUBBLES_T ); +static BUBBLE_STATES_T handleBubbleSelfTestState( BUBBLES_T ); +static BUBBLE_STATES_T handleBubbleNormalState( BUBBLES_T ); + +static void publishBubblesData( void ); +static U32 getPublishBubblesDataInterval( void ); + +/*********************************************************************//** + * @brief + * The initBubbles function initializes the air bubble detectors module. + * @details Inputs: none + * @details Outputs: Air bubble detectors module initialized. + * @return none + *************************************************************************/ +void initBubbles( void ) +{ + BUBBLES_T bubble; + + for (bubble = ADA; bubble < NUM_OF_BUBBLES; bubble++) + { + bubblesState[ bubble ] = BUBBLE_INIT_STATE; + bubblesStatus[ bubble ].data = BUBBLE_NOT_DETECTED; + bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_IN_PROGRESS; + bubblesSelfTestRequested[ bubble ] = FALSE; + bubblesSelfTestStartTime[ bubble ] = 0; + } +} + +/*********************************************************************//** + * @brief + * The execBubbles function executes the air bubble detectors driver. + * @details Inputs: FPGA air bubble detectors status GPIO pin state + * @details Outputs: bubblesStatus + * @return none + *************************************************************************/ +void execBubble( void ) +{ + BUBBLES_T bubble; + + if ( getCurrentOperationMode() != MODE_INIT ) + { + // Loop through all of the air bubble detectors + for ( bubble = ADA; bubble < NUM_OF_BUBBLES; bubble++ ) + { + // Execute the air bubble detector state machine + switch( bubblesState[ bubble ] ) + { + case BUBBLE_INIT_STATE: + bubblesState[ bubble ] = handleBubbleInitState( bubble ); + break; + + case BUBBLE_SELF_TEST_STATE: + bubblesState[ bubble ] = handleBubbleSelfTestState( bubble ); + break; + + case BUBBLE_NORMAL_STATE: + bubblesState[ bubble ] = handleBubbleNormalState( bubble ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BUBBLE_STATE, bubblesState[ bubble ] ) + bubblesState[ bubble ] = BUBBLE_INIT_STATE; + break; + } + } + } + + // Publish air bubble detectors data if due + publishBubblesData(); +} + +/*********************************************************************//** + * @brief + * The selfTestBubble function requests that a specified air bubble detector + * be self-tested. + * @details Inputs: none + * @details Outputs: Air bubble detector module self-testing + * @return Boolean as success or failure + *************************************************************************/ +void selfTestBubble( BUBBLES_T bubble ) +{ + bubbleSelfTestRequested[ bubble ] = TRUE; +} + +/*********************************************************************//** + * @brief + * The handleBubbleInitState function handles a given air bubble detector + * module in init state. + * @details Inputs: none + * @details Outputs: Air bubble detector module init. + * @return next state + *************************************************************************/ +static BUBBLE_STATES_T handleBubbleInitState( BUBBLES_T bubble ) +{ + BUBBLE_STATES_T state[ bubble ] = BUBBLE_INIT_STATE; + + if ( TRUE == bubblesSelfTestRequested[ bubble ] ) + { + state[ bubble ] = BUBBLE_SELF_TEST_STATE; + bubblesSelfTestRequested[ bubble ] = FALSE; + + setFPGABubbleSelfTest( bubble ); + bubblesSelfTestStartTime[ bubble ] = getMSTimerCount(); + } + + return state[ bubble ]; +} + +/*********************************************************************//** + * @brief + * The handleBubbleSelfTestState function handles a given air bubble detector + * module in self-test state. + * @details Inputs: none + * @details Outputs: Air bubble detector module self-test. + * @return next state + *************************************************************************/ +static BUBBLE_STATES_T handleBubbleSelfTestState( BUBBLES_T bubble ) +{ + BUBBLE_STATES_T state[ bubble ] = BUBBLE_SELF_TEST_STATE; + + if ( TRUE == FPGABubbleSelfTestDetected( bubble ) ) + { + state[ bubble ] = BUBBLE_SELF_TEST_STATE; + bubblesSelfTestStatus[ bubble ] = SELF_TEST_STATUS_IN_PROGRESS; + clearFPGABubbleSelfTest( bubble ); + bubblesSelfTestStartTime[ bubble ] = getMSTimerCount(); + } + else + { + if ( TRUE == didTimeout( bubblesSelfTestStartTime[ bubble ], BUBBLE_TIMEOUT_MS ) ) + { + if ( bubble == ADA ) + { + activateAlarmNoData( ALARM_ID_HD_ARTERIAL_BUBBLE_FAULT ); + } + else if ( bubble == ADV ) + { + activateAlarmNoData( ALARM_ID_HD_VENOUS_BUBBLE_FAULT ); + } + else + { + // TODO: Should never get here, alarm as appropriate + } + } + } + + return state[ bubble ]; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakSelfTestState function handles the Blood Leak module + * in self-test state. + * @details Inputs: none + * @details Outputs: Blood Leak module self test. + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakSelfTestState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_SELF_TEST_STATE; + + if ( SELF_TEST_STATUS_IN_PROGRESS == bloodLeakSelfTestStatus ) + { + if ( FALSE == noFPGABloodLeakDetected() ) // Faked blood leak caused by independent MCU board + { + bloodLeakSelfTestStatus = SELF_TEST_STATUS_PASSED; + clearFPGABloodLeakSelfTest(); + } + else if ( TRUE == didTimeout( bloodLeakSelfTestStartTime, BLOOD_LEAK_TIMEOUT_MS ) ) + { + bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_FAILURE ); + } + } + else + { + // Blood leak self-test finished, wait for self-test faked blood leak clear + if ( TRUE == noFPGABloodLeakDetected() ) + { + state = BLOOD_LEAK_NORMAL_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakNormalState function handles the Blood Leak module + * in normal state. + * @details Inputs: none + * @details Outputs: Blood Leak module normal. + * @return next state + *************************************************************************/ +static BLOOD_LEAK_STATES_T handleBloodLeakNormalState( void ) +{ + BLOOD_LEAK_STATES_T state = BLOOD_LEAK_NORMAL_STATE; + + if ( TRUE == noFPGABloodLeakDetected() ) + { + bloodLeakStatus.data = BLOOD_LEAK_NOT_DETECTED; + } + else + { + bloodLeakStatus.data = BLOOD_LEAK_DETECTED; + } + + // Check status reading and act upon + if ( BLOOD_LEAK_DETECTED == getBloodLeakStatus() ) + { + if ( getCurrentOperationMode() == MODE_TREA ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + } + else + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_FAULT ); + } + } + else // Blood leak not detected + { + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + } + + if ( TRUE == bloodLeakZeroRequested ) + { + state = BLOOD_LEAK_ZERO_STATE; + bloodLeakZeroRequested = FALSE; + + setFPGABloodLeakZero(); + bloodLeakZeroStartTime = getMSTimerCount(); + } + + return state; +} + +/*********************************************************************//** + * @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 ) +{ + return bloodLeakSelfTestStatus; +} + +/*********************************************************************//** + * @brief + * The getPublishBloodLeakDataInterval function gets the blood leak data + * publication interval. + * @details Inputs: bloodLeakDataPublishInterval + * @details Outputs: none + * @return the current blood leak data publication interval (in task intervals). + *************************************************************************/ +static U32 getPublishBloodLeakDataInterval( void ) +{ + U32 result = bloodLeakDataPublishInterval.data; + + if ( OVERRIDE_KEY == bloodLeakDataPublishInterval.override ) + { + result = bloodLeakDataPublishInterval.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The publishBubblesData function publishes air bubble detectors data at + * the set interval. + * @details Inputs: bloodLeakStatus, bloodLeakState + * @details Outputs: if broadcast is due, send air bubble detectors data + * @return none + *************************************************************************/ +static void publishBubblesData( void ) +{ + BUBBLE_T bubble; + + // Publish air bubble detectors data on interval + if ( ++bubblesDataPublicationTimerCounter >= getPublishBubblesDataInterval() ) + { + BUBBLES_STATUS_T status = getBubblesStatus(); + + broadcastBloodLeakData( status, (U32)bloodLeakState ); + bloodLeakDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * 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; +} + +/**@}*/ Index: firmware/App/Controllers/Bubble.h =================================================================== diff -u --- firmware/App/Controllers/Bubble.h (revision 0) +++ firmware/App/Controllers/Bubble.h (revision f24be7fd135878e6ff28dff56937c31626bd4bc1) @@ -0,0 +1,70 @@ +/************************************************************************** +* +* 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 Bubble.h +* +* @author (last) Peman Montazemi +* @date (last) 30-Apr-2021 +* +* @author (original) Peman Montazemi +* @date (original) 30-Apr-2021 +* +***************************************************************************/ + +#ifndef __BUBBLE_H__ +#define __BUBBLE_H__ + +#include "HDCommon.h" + +/** + * @defgroup Bubble Bubble + * @brief Air bubble detectors monitor module. Monitors the + * bubble detector. + * + * SMD - Venous Air Bubble Detector Part No. DIA8413 + * SMD - Arterial Air Bubble Detector Part No. DIA8309 + * + * @addtogroup Bubble + * @{ + */ + +// ********** public definitions ********** + +/// Enumeration of air bubble detectors status. +typedef enum BubblesStatus +{ + BUBBLE_DETECTED = 0, ///< Air bubble detector senses bubble + BUBBLE_NOT_DETECTED, ///< Air bubble detector does not sense any bubble + NUM_OF_BUBBLE_STATUS ///< Number of air bubble detector status +} BUBBLE_STATUS_T; + +/// Air bubble detectors names +typedef enum bubblesNames +{ + ADA = 0, ///< Arterial air bubble detector + ADV, ///< Venous air bubble detector + NUM_OF_BUBBLES ///< Number of air bubble detectors +} BUBBLES_T; + +// ********** public function prototypes ********** + +void initBubbles( void ); +void execBubbles( void ); +void selfTestBubble( BUBBLES_T ); + +BUBBLES_STATUS_T getBubblesStatus( void ); +SELF_TEST_STATUS_T getBubblesSelfTestStatus( void ); + +BOOL testSetBubblesDataPublishIntervalOverride( U32 value ); +BOOL testResetBubblesDataPublishIntervalOverride( void ); + +BOOL testSetBubblesStatusOverride( BUBBLE_STATUS_T status); +BOOL testResetBubblesStatusOverride( void ); + +/**@}*/ + +#endif Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r04f033af4174bf41a7aa0ff9ccaae45b77472e01 -rf24be7fd135878e6ff28dff56937c31626bd4bc1 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 04f033af4174bf41a7aa0ff9ccaae45b77472e01) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision f24be7fd135878e6ff28dff56937c31626bd4bc1) @@ -52,17 +52,6 @@ NUMBER_OF_ALARM_ACTIONS ///< Number of alarm actions } ALARM_ACTION_T; -/// Alarm data types list. -typedef enum Alarm_Data_Types -{ - ALARM_DATA_TYPE_NONE = 0, ///< No data given. - ALARM_DATA_TYPE_U32 = 1, ///< Alarm data is unsigned 32-bit integer type. - ALARM_DATA_TYPE_S32 = 2, ///< Alarm data is signed 32-bit integer type. - ALARM_DATA_TYPE_F32 = 3, ///< Alarm data is 32-bit floating point type. - ALARM_DATA_TYPE_BOOL = 4, ///< Alarm data is 32-bit boolean type. - NUM_OF_ALARM_DATA_TYPES ///< Total number of alarm data types. -} ALARM_DATA_TYPES_T; - #pragma pack(push, 4) /// Record structure for detailing the properties of the current composite alarm status. typedef struct @@ -258,6 +247,7 @@ SW_FAULT_ID_HD_SYRINGE_INVALID_CONT_CMD, SW_FAULT_ID_HD_SYRINGE_INVALID_VREF, SW_FAULT_ID_HD_SYRINGE_INVALID_STATE, + SW_FAULT_ID_HD_INVALID_BUBBLE_STATE, // 115 NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T;