/************************************************************************** * * Copyright (c) 2019-2020 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 AirTrap.c * * @author (last) Sean Nash * @date (last) 16-Sep-2020 * * @author (original) Sean * @date (original) 16-Sep-2020 * ***************************************************************************/ #include "AirTrap.h" #include "AlarmMgmt.h" #include "FPGA.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" #include "Timers.h" /** * @addtogroup AirTrap * @{ */ // ********** private definitions ********** /// Default publication interval for pressure and occlusion data. #define AIR_TRAP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< interval (ms/task time) at which the air trap data is published on the CAN bus. /// Defined states for the air trap controller state machine. typedef enum AirTrap_States { AIR_TRAP_INIT_STATE = 0, ///< Initialization state AIR_TRAP_MANUAL_CONTROL_STATE, ///< Manually control air trap valve state AIR_TRAP_VALVE_CLOSED_STATE, ///< Valve closed state - until air detected at lower level AIR_TRAP_VALVE_OPEN_STATE, ///< Valve open state - until fluid detected at upper level NUM_OF_AIR_TRAP_STATES ///< Number of air trap controller states } AIR_TRAP_STATE_T; /// Defined states for the air trap self-test state machine. typedef enum AirTrap_Self_Test_States { AIR_TRAP_SELF_TEST_STATE_START = 0, ///< Self test start state AIR_TRAP_TEST_STATE_IN_PROGRESS, ///< Self test in progress state AIR_TRAP_TEST_STATE_COMPLETE, ///< Self test completed state NUM_OF_AIR_TRAP_SELF_TEST_STATES ///< Number of air trap self-test states } AIR_TRAP_SELF_TEST_STATE_T; // ********** private data ********** static AIR_TRAP_STATE_T airTrapControllerState; ///< current state of air trap controller state machine. static U32 airTrapDataPublicationTimerCounter = 0; ///< used to schedule air trap data publication to CAN bus. static OVERRIDE_U32_T airTrapDataPublishInterval = { AIR_TRAP_DATA_PUB_INTERVAL, AIR_TRAP_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish air trap data to CAN bus. static OVERRIDE_U32_T airTrapLevels[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< detected air trap level for each level sensor. static AIR_TRAP_SELF_TEST_STATE_T airTrapSelfTestState; ///< current air trap self-test state. static U32 airTrapSelfTestTimerCount = 0; ///< timer counter for air trap self-test. static BOOL pendingStartAirTrapController = FALSE; ///< flag indicates an air trap controller start request is pending. static BOOL pendingStopAirTrapController = FALSE; ///< flag indicates an air trap controller stop request is pending. // ********** private function prototypes ********** static AIR_TRAP_STATE_T handleAirTrapManualControlState( void ); static AIR_TRAP_STATE_T handleAirTrapValveClosedState( void ); static AIR_TRAP_STATE_T handleAirTrapValveOpenState( void ); static void publishAirTrapData( void ); static U32 getPublishAirTrapDataInterval( void ); /*********************************************************************//** * @brief * The initAirTrap function initializes the Air Trap module. * @details * Inputs : none * Outputs : Air Trap module initialized. * @return none *************************************************************************/ void initAirTrap( void ) { resetAirTrap(); airTrapSelfTestState = AIR_TRAP_SELF_TEST_STATE_START; } /*********************************************************************//** * @brief * The resetAirTrap function resets certain parts of the air trap module * between treatments. * @details * Inputs : none * Outputs : Air Trap module reset. * @return none *************************************************************************/ void resetAirTrap( void ) { airTrapControllerState = AIR_TRAP_INIT_STATE; pendingStartAirTrapController = FALSE; pendingStopAirTrapController = FALSE; } /*********************************************************************//** * @brief * The startAirTrapControl function requests a start to air trap control. * @details * Inputs : airTrapControllerState * Outputs : pendingStartAirTrapController * @return none *************************************************************************/ void startAirTrapControl( void ) { if ( FALSE == isAirTrapControlling() ) { pendingStartAirTrapController = TRUE; } } /*********************************************************************//** * @brief * The endAirTrapControl function requests a stop to air trap control. * @details * Inputs : airTrapControllerState * Outputs : pendingStopAirTrapController * @return none *************************************************************************/ void endAirTrapControl( void ) { if ( TRUE == isAirTrapControlling() ) { pendingStopAirTrapController = TRUE; } } /*********************************************************************//** * @brief * The isAirTrapControlling function determines whether the air trap is * currently controlling. * @details * Inputs : airTrapControllerState * Outputs : none * @return TRUE if air trap is currently controlling, FALSE if not. *************************************************************************/ BOOL isAirTrapControlling( void ) { BOOL result = FALSE; if ( airTrapControllerState >= AIR_TRAP_VALVE_CLOSED_STATE ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The execAirTrapMonitor function executes the air trap monitor. * @details * Inputs : TBD * Outputs : airTrapLevels[] * @return none *************************************************************************/ void execAirTrapMonitor( void ) { // TODO - get latest level readings // TODO - fault if illegal level readings persist } /*********************************************************************//** * @brief * The execAirTrapController function executes the air trap control state machine. * @details * Inputs : airTrapControllerState * Outputs : airTrapControllerState * @return none *************************************************************************/ void execAirTrapController( void ) { // execute state machine switch( airTrapControllerState ) { case AIR_TRAP_INIT_STATE: airTrapControllerState = AIR_TRAP_MANUAL_CONTROL_STATE; break; case AIR_TRAP_MANUAL_CONTROL_STATE: break; case AIR_TRAP_VALVE_CLOSED_STATE: break; case AIR_TRAP_VALVE_OPEN_STATE: break; default: // TODO - s/w fault break; } } /*********************************************************************//** * @brief * The handleAirTrapManualControlState function handles the manual control * state of the air trap. * @details * Inputs : TBD * Outputs : TBD * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapManualControlState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_MANUAL_CONTROL_STATE; return result; } /*********************************************************************//** * @brief * The handleAirTrapValveClosedState function handles the valve closed state * of the air trap. * @details * Inputs : TBD * Outputs : TBD * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapValveClosedState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_VALVE_CLOSED_STATE; return result; } /*********************************************************************//** * @brief * The handleAirTrapValveOpenState function handles the valve open state of * the air trap. * @details * Inputs : TBD * Outputs : TBD * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapValveOpenState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_VALVE_OPEN_STATE; return result; } /*********************************************************************//** * @brief * The publishAirTrapData function publishes air trap data at the set interval. * @details * Inputs : airTrapLevels[] * Outputs : if broadcast is due, send air trap data * @return none *************************************************************************/ static void publishAirTrapData( void ) { // publish pressure/occlusion data on interval if ( ++airTrapDataPublicationTimerCounter >= getPublishAirTrapDataInterval() ) { AIR_TRAP_LEVELS_T lowLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); AIR_TRAP_LEVELS_T highLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); // broadcastAirTrapData( (U32)lowLevel, (U32)highLevel ); airTrapDataPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The execAirTrapTest function executes the state machine for the air trap * self-test. * @details * Inputs : none * Outputs : none * @return the current state of the PresOccl self-test. *************************************************************************/ SELF_TEST_STATUS_T execAirTrapTest( void ) { SELF_TEST_STATUS_T status; return status; } /*********************************************************************//** * @brief * The getAirTrapLevel function gets the current reading for the given * level sensor. * @details * Inputs : airTrapLevels[] * Outputs : none * @param sensor ID of level sensor to get reading for * @return the current level sensor reading for the given sensor (air or fluid). *************************************************************************/ AIR_TRAP_LEVELS_T getAirTrapLevel( AIR_TRAP_LEVEL_SENSORS_T sensor ) { AIR_TRAP_LEVELS_T result; if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) { result = (AIR_TRAP_LEVELS_T)airTrapLevels[ sensor ].data; if ( OVERRIDE_KEY == airTrapLevels[ sensor ].override ) { result = (AIR_TRAP_LEVELS_T)airTrapLevels[ sensor ].ovData; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, 0, (U32)sensor ) // TODO - 1st param s/b a unique enum from AlarmMgmt.h result = AIR_TRAP_LEVEL_AIR; } return result; } /*********************************************************************//** * @brief * The getPublishAirTrapDataInterval function gets the air trap data * publication interval. * @details * Inputs : airTrapDataPublishInterval * Outputs : none * @return the current air trap data publication interval (in task intervals). *************************************************************************/ static U32 getPublishAirTrapDataInterval( void ) { U32 result = airTrapDataPublishInterval.data; if ( OVERRIDE_KEY == airTrapDataPublishInterval.override ) { result = airTrapDataPublishInterval.ovData; } return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetAirTrapDataPublishIntervalOverride function overrides the * air trap data publish interval. * @details * Inputs : none * Outputs : airTrapDataPublishInterval * @param value override pressure and occlusion data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetAirTrapDataPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; airTrapDataPublishInterval.ovData = value; airTrapDataPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetAirTrapDataPublishIntervalOverride function resets the override * of the air trap data publish interval. * @details * Inputs : none * Outputs : airTrapDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetAirTrapDataPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; airTrapDataPublishInterval.override = OVERRIDE_RESET; airTrapDataPublishInterval.ovData = airTrapDataPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetArterialPressureOverride function overrides the measured level * for a given level sensor. * @details * Inputs : none * Outputs : airTrapLevels[] * @param sensor ID of level sensor to override * @param value override level sensor with this * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor, AIR_TRAP_LEVELS_T level ) { BOOL result = FALSE; if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; airTrapLevels[ sensor ].ovData = (U32)level; airTrapLevels[ sensor ].override = OVERRIDE_KEY; } } return result; } /*********************************************************************//** * @brief * The testResetAirTrapLevelOverride function resets the override of the * level sensor. * @details * Inputs : none * Outputs : airTrapLevels[] * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ) { BOOL result = FALSE; if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; airTrapLevels[ sensor ].override = OVERRIDE_RESET; airTrapLevels[ sensor ].ovData = airTrapLevels[ sensor ].ovInitData; } } return result; } /**@}*/