/************************************************************************** * * Copyright (c) 2024-2024 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 * @date (last) 03-Oct-2024 * * @author (original) Sean * @date (original) 03-Oct-2024 * ***************************************************************************/ #include "AirPump.h" #include "AirTrap.h" #include "AlarmMgmtTD.h" #include "BloodFlow.h" #include "LevelSensors.h" #include "Messaging.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "Pressures.h" #include "TaskGeneral.h" #include "Timers.h" #include "Utilities.h" #include "Valve3Way.h" /** * @addtogroup AirTrap * @{ */ // ********** private definitions ********** #define AIR_TRAP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the air trap data is published on the CAN bus. #define AIR_TRAP_FILL_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Air trap fill timeout period (in ms). #define AIR_PUMP_ON_DELAY_TIME_MS ( 10 * MS_PER_SECOND ) ///< Delay between air pump On (in ms). #define AIR_PUMP_LOWER_OP_TIME_MIN_MS 200 ///< Air trap lower operation minimum time (in ms). #define AIR_PUMP_ON_ERROR_MAX_CNT 6 ///< Maximum number of air pump on events within time window before alarm triggered. Do not exceed MAX_TIME_WINDOWED_COUNT. #define AIR_PUMP_ON_ERROR_TIME_WIN_MS ( 60 * MS_PER_SECOND ) ///< Time window for Air Pump on count error. #define AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Air trap illegal values timeout (in ms) #define VENOUS_LINE_VOLUME_ML ( 200.0F ) ///< Volume (in mL) of venous portion of blood circuit line. TODO - get actual volume from Systems. #define DATA_PUBLISH_COUNTER_START_COUNT 7 ///< Data publish counter start count. /// Air pump on delay after fill adjustment static const U32 AIR_PUMP_ON_DELAY_ADJUST_AFTER_FILL = ( AIR_PUMP_ON_DELAY_TIME_MS - ( 1 * MS_PER_SECOND ) ); #define AIR_PUMP_MOTOR_FILL_PWM 60 ///< Power level setting (PWM) for H12 air pump to fill (raise level) the air trap. #define AIR_PUMP_MOTOR_LOWER_PWM 250 ///< Power level setting (PWM) for H12 air pump to lower the level of the air trap. /// 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_CLOSED_STATE, ///< Closed state - level between lower and upper sensors. AIR_TRAP_RAISE_LEVEL_STATE, ///< Raise level state. AIR_TRAP_LOWER_LEVEL_STATE, ///< Lower level state. NUM_OF_AIR_TRAP_STATES ///< Number of air trap controller states. } AIR_TRAP_STATE_T; // ********** private data ********** static AIR_TRAP_STATE_T airTrapControllerState; ///< Current state of air trap controller state machine. static U32 airTrapDataPublicationTimerCounter; ///< Used to schedule air trap data publication to CAN bus. static OVERRIDE_U32_T airTrapDataPublishInterval; ///< Interval (in ms) at which to publish air trap data to CAN bus. static OVERRIDE_U32_T airTrapAirPumpRaisePowerLevel; ///< Air pump power level to use when raising the air trap blood level. static OVERRIDE_U32_T airTrapAirPumpLowerPowerLevel; ///< Air pump power level to use when lowering the air trap blood level. static BOOL pendingStartAirTrapController; ///< Flag indicates an air trap controller start request is pending. static BOOL pendingStopAirTrapController; ///< Flag indicates an air trap controller stop request is pending. static U32 airTrapFillStartTime; ///< Air trap fill (raise level) operation start time. static U32 airTrapLowerStartTime; ///< Air trap lower level operation start time. static U32 airTrapLowerDelayStartTime; ///< Air trap lower level operation delay start time. static BOOL airTrapWasFilledAtStartOfTreatement; ///< To ensure the fluid level high during start of treatment, we need to do a fill operation. static BOOL airTrapHasDetectedFaultMode; ///< Flag indicates air trap unit has handled transition to fault mode. // ********** private function prototypes ********** static AIR_TRAP_STATE_T handleAirTrapManualControlState( void ); static AIR_TRAP_STATE_T handleAirTrapClosedState( void ); static AIR_TRAP_STATE_T handleAirTrapRaiseLevelState( void ); static AIR_TRAP_STATE_T handleAirTrapLowerlevelState( void ); static U08 getAirPumpRaisePowerLevel( void ); static U08 getAirPumpLowerPowerLevel( void ); static void publishAirTrapData( void ); /*********************************************************************//** * @brief * The initAirTrap function initializes the air trap controller unit. * @details \b Inputs: none * @details \b Outputs: Air trap controller unit initialized * @return none *************************************************************************/ void initAirTrap(void) { // Initialize level sensors and valve drivers initLevelSensors(); init3WayValves(); // Initialize controller variables resetAirTrap(); airTrapDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; airTrapDataPublishInterval.data = AIR_TRAP_DATA_PUB_INTERVAL; airTrapDataPublishInterval.ovData = AIR_TRAP_DATA_PUB_INTERVAL; airTrapDataPublishInterval.ovInitData = AIR_TRAP_DATA_PUB_INTERVAL; airTrapDataPublishInterval.override = OVERRIDE_RESET; airTrapAirPumpRaisePowerLevel.data = AIR_PUMP_MOTOR_FILL_PWM; airTrapAirPumpRaisePowerLevel.ovData = AIR_PUMP_MOTOR_FILL_PWM; airTrapAirPumpRaisePowerLevel.ovInitData = AIR_PUMP_MOTOR_FILL_PWM; airTrapAirPumpRaisePowerLevel.override = OVERRIDE_RESET; airTrapAirPumpLowerPowerLevel.data = AIR_PUMP_MOTOR_LOWER_PWM; airTrapAirPumpLowerPowerLevel.ovData = AIR_PUMP_MOTOR_LOWER_PWM; airTrapAirPumpLowerPowerLevel.ovInitData = AIR_PUMP_MOTOR_LOWER_PWM; airTrapAirPumpLowerPowerLevel.override = OVERRIDE_RESET; airTrapFillStartTime = 0; airTrapLowerDelayStartTime = 0; airTrapLowerStartTime = 0; airTrapHasDetectedFaultMode = FALSE; } /*********************************************************************//** * @brief * The resetAirTrap function resets certain parts of the air trap module * between treatments. * @details \b Inputs: none * @details \b Outputs: Air Trap controller reset. * @return none *************************************************************************/ void resetAirTrap( void ) { airTrapControllerState = AIR_TRAP_INIT_STATE; airTrapWasFilledAtStartOfTreatement = FALSE; pendingStartAirTrapController = FALSE; pendingStopAirTrapController = FALSE; } /*********************************************************************//** * @brief * The startAirTrapControl function requests a start to air trap control. * @details \b Inputs: airTrapControllerState * @details \b Outputs: pendingStartAirTrapController * @return none *************************************************************************/ void startAirTrapControl( void ) { if ( FALSE == isAirTrapControlling() ) { pendingStartAirTrapController = TRUE; } } /*********************************************************************//** * @brief * The endAirTrapControl function requests a stop to air trap control. * @details \b Inputs: airTrapControllerState * @details \b Outputs: pendingStopAirTrapController * @return none *************************************************************************/ void endAirTrapControl( void ) { if ( TRUE == isAirTrapControlling() ) { pendingStopAirTrapController = TRUE; signalLowVenousPressureCheck(); // Venous pressure check should continue even after ending auto air trap control } } /*********************************************************************//** * @brief * The isAirTrapControlling function determines whether the air trap is * currently controlling. * @details \b Inputs: airTrapControllerState * @details \b Outputs: none * @return TRUE if air trap is currently controlling, FALSE if not. *************************************************************************/ BOOL isAirTrapControlling( void ) { BOOL result = FALSE; if ( airTrapControllerState >= AIR_TRAP_CLOSED_STATE ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The execAirTrapMonitor function executes the air trap monitor. * @details \b Alarm: ALARM_ID_TD_AIR_TRAP_ILLEGAL_LEVELS if upper level * sensor detects liquid while the lower level sensor detects air. * @details \b Inputs: air trap level sensor readings * @details \b Outputs: none * @return none *************************************************************************/ void execAirTrapMonitor( void ) { BOOL isAirTrapLevelsValid = FALSE; // Update air trap level sensors from FPGA readAirTrapLevelSensors(); // Check for illegal levels alarm if ( TRUE ) // TODO - need a way to determine whether a blood set is installed - if not installed, we would not trigger illegal levels alarm { // If the pump track on open, zero the persistent counter to not check the air trap illegal level alarm checkPersistentAlarm( ALARM_ID_TD_AIR_TRAP_ILLEGAL_LEVELS, FALSE, 0.0, 0.0 ); } else { AIR_TRAP_LEVELS_T lowerAirTrap = getLevelSensorState( H17_LEVL ); AIR_TRAP_LEVELS_T upperAirTrap = getLevelSensorState( H16_LEVL ); isAirTrapLevelsValid = ( ( ( AIR_TRAP_LEVEL_AIR == lowerAirTrap ) && ( AIR_TRAP_LEVEL_FLUID == upperAirTrap ) ) ? TRUE : FALSE ); #ifndef _RELEASE_ // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ILLEGAL_AIR_TRAP_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif { checkPersistentAlarm( ALARM_ID_TD_AIR_TRAP_ILLEGAL_LEVELS, isAirTrapLevelsValid, lowerAirTrap, upperAirTrap ); } } } /*********************************************************************//** * @brief * The execAirTrapMonitorTreatment function executes the air trap monitor * for treatment mode. * @details \b Alarm: ALARM_ID_TD_AIR_TRAP_FILL_DURING_TREATMENT if air trap * fill exceeds maximum allowed time to complete. * @details \b Inputs: airTrapControllerState, fillStartTime * @details \b Outputs: none * @return none *************************************************************************/ void execAirTrapMonitorTreatment( void ) { // Check air trap fill timeout during treatment if ( AIR_TRAP_RAISE_LEVEL_STATE == airTrapControllerState ) { if ( TRUE == didTimeout( airTrapFillStartTime, AIR_TRAP_FILL_TIMEOUT_MS ) ) { #ifndef _RELEASE_ // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_TRAP_LEVELING_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif { #ifndef TEST_UI_ONLY activateAlarmNoData( ALARM_ID_TD_AIR_TRAP_FILL_DURING_TREATMENT ); #endif } } } } /*********************************************************************//** * @brief * The execAirTrapController function executes the air trap control state machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if current air trap control * state is invalid. * @details \b Message \b Sent: MSG_ID_TD_EVENT if air trap valve closed due to fault. * @details \b Inputs: airTrapControllerState * @details \b Outputs: airTrapControllerState * @return none *************************************************************************/ void execAirTrapController( void ) { // If we have faulted, close valve and go to manual control if ( ( MODE_FAUL == getCurrentOperationMode() ) && ( airTrapHasDetectedFaultMode != TRUE ) ) { endAirTrapControl(); airTrapHasDetectedFaultMode = TRUE; } // Execute air trap state machine switch( airTrapControllerState ) { case AIR_TRAP_INIT_STATE: airTrapControllerState = AIR_TRAP_MANUAL_CONTROL_STATE; break; case AIR_TRAP_MANUAL_CONTROL_STATE: airTrapControllerState = handleAirTrapManualControlState(); break; case AIR_TRAP_CLOSED_STATE: airTrapControllerState = handleAirTrapClosedState(); break; case AIR_TRAP_RAISE_LEVEL_STATE: airTrapControllerState = handleAirTrapRaiseLevelState(); break; case AIR_TRAP_LOWER_LEVEL_STATE: airTrapControllerState = handleAirTrapLowerlevelState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, (U32)SW_FAULT_ID_AIR_TRAP_INVALID_STATE, (U32)airTrapControllerState ) airTrapControllerState = AIR_TRAP_INIT_STATE; break; } // Publish air trap data if due publishAirTrapData(); } /*********************************************************************//** * @brief * The handleAirTrapManualControlState function handles the manual control * state of the air trap. * @details \b Inputs: pendingStartAirTrapController * @details \b Outputs: none * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapManualControlState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_MANUAL_CONTROL_STATE; // Transition to valve control states when requested if ( TRUE == pendingStartAirTrapController ) { pendingStartAirTrapController = FALSE; setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); result = AIR_TRAP_CLOSED_STATE; } return result; } /*********************************************************************//** * @brief * The handleAirTrapClosedState function handles the closed state of the * air trap. * @details \b Message \b Sent: MSG_ID_TD_EVENT if starting a level change. * @details \b Inputs: pendingStopAirTrapController * @details \b Outputs: none * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapClosedState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_CLOSED_STATE; // Transition to manual control state when requested if ( TRUE == pendingStopAirTrapController ) { pendingStopAirTrapController = FALSE; result = AIR_TRAP_MANUAL_CONTROL_STATE; } // Lower air trap level if fluid reaches upper level. else if ( AIR_TRAP_LEVEL_FLUID == getLevelSensorState( H16_LEVL ) ) { if ( ( AIR_PUMP_STATE_OFF == getAirPumpState() ) && ( TRUE == didTimeout( airTrapLowerDelayStartTime, AIR_PUMP_ON_DELAY_TIME_MS ) ) ) { set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); // open valve H13 to allow air to be pumped into air trap from atmosphere setAirPumpState( AIR_PUMP_STATE_ON, getAirPumpLowerPowerLevel() ); airTrapLowerStartTime = getMSTimerCount(); signalInitiatePressureStabilization( USE_SHORT_STABILIZATION_PERIOD ); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_AIR_TRAP_LOWER, ON, 0 ); result = AIR_TRAP_LOWER_LEVEL_STATE; } } // Raise air trap level once at start of treatment (blood priming) or when air detected at lower level else if ( ( airTrapWasFilledAtStartOfTreatement != TRUE ) || ( AIR_TRAP_LEVEL_AIR == getLevelSensorState( H17_LEVL ) ) ) { setAirPumpState( AIR_PUMP_STATE_ON, getAirPumpRaisePowerLevel() ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); // open valve H20 to allow air to be pumped out of air trap to atmosphere airTrapFillStartTime = getMSTimerCount(); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_AIR_TRAP_FILL, ON, 0 ); result = AIR_TRAP_RAISE_LEVEL_STATE; } return result; } /*********************************************************************//** * @brief * The handleAirTrapRaiseLevelState function handles the raise level state * of the air trap. * @details \b Message \b Sent: MSG_ID_TD_EVENT if raising level completed * @details \b Inputs: pendingStopAirTrapController * @details \b Outputs: none * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapRaiseLevelState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_RAISE_LEVEL_STATE; // Transition to manual valve control state when requested if ( TRUE == pendingStopAirTrapController ) { pendingStopAirTrapController = FALSE; setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); result = AIR_TRAP_MANUAL_CONTROL_STATE; } // Transition back to lower level state when air trap fill completed else if ( AIR_TRAP_LEVEL_FLUID == getRawLevelSensorState( H16_LEVL ) ) { airTrapWasFilledAtStartOfTreatement = TRUE; set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); // open valve H13 to allow air to be pumped into air trap from atmosphere setAirPumpState( AIR_PUMP_STATE_ON, getAirPumpLowerPowerLevel() ); airTrapLowerStartTime = getMSTimerCount(); signalInitiatePressureStabilization( USE_SHORT_STABILIZATION_PERIOD ); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_AIR_TRAP_LOWER, ON, 0 ); result = AIR_TRAP_LOWER_LEVEL_STATE; } return result; } /*********************************************************************//** * @brief * The handleAirTrapLowerlevelState function handles the lower level state * of the air trap. * @details \b Message \b Sent: MSG_ID_TD_EVENT if lowering air trap level completed. * @details \b Inputs: none * @details \b Outputs: none * @return next state *************************************************************************/ static AIR_TRAP_STATE_T handleAirTrapLowerlevelState( void ) { AIR_TRAP_STATE_T result = AIR_TRAP_LOWER_LEVEL_STATE; // Air pump stop time based on the blood flow rate S32 qB = 500; // TODO abs( getTargetBloodFlowRate() ); U32 qBx = ( 0 == qB ? MIN_SET_BLOOD_FLOW_RATE : (U32)qB ); U32 airPumpStopTime = AIR_PUMP_LOWER_OP_TIME_MIN_MS + ( ( qBx - MIN_SET_BLOOD_FLOW_RATE ) / 2 ); // Transition to manual valve control state when requested if ( TRUE == pendingStopAirTrapController ) { pendingStopAirTrapController = FALSE; setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); result = AIR_TRAP_MANUAL_CONTROL_STATE; } // Transition back to closed state when air trap lower level operation completed when air detected at upper level else if ( ( TRUE == didTimeout( airTrapLowerStartTime, airPumpStopTime ) ) || ( AIR_TRAP_LEVEL_AIR == getRawLevelSensorState( H16_LEVL ) ) ) { setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); airTrapLowerDelayStartTime = getMSTimerCount(); signalLowVenousPressureCheck(); SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_AIR_TRAP_LOWER, OFF, 0 ); // if lower level operation times out, alarm if ( TRUE == didTimeout( airTrapLowerStartTime, airPumpStopTime ) ) { // TODO - alarm??? } result = AIR_TRAP_CLOSED_STATE; } return result; } /*********************************************************************//** * @brief * The getAirPumpRaisePowerLevel function gets the air pump power level to * use for raising the blood level in the air trap. * @details \b Inputs: airTrapAirPumpRaisePowerLevel * @details \b Outputs: none * @return air pump power level for raising air trap blood level *************************************************************************/ static U08 getAirPumpRaisePowerLevel( void ) { U08 result = getU08OverrideValue( &airTrapAirPumpRaisePowerLevel ); return result; } /*********************************************************************//** * @brief * The getAirPumpLowerPowerLevel function gets the air pump power level to * use for lowering the blood level in the air trap. * @details \b Inputs: airTrapAirPumpLowerPowerLevel * @details \b Outputs: none * @return air pump power level for lowering air trap blood level *************************************************************************/ static U08 getAirPumpLowerPowerLevel( void ) { U08 result = getU08OverrideValue( &airTrapAirPumpLowerPowerLevel ); return result; } /*********************************************************************//** * @brief * The publishAirTrapData function constructs and sends the air trap data * broadcast message. * @details \b Message \b Sent: MSG_ID_TD_AIR_TRAP_DATA to publish air trap data * @details \b Inputs: airTrapDataPublicationTimerCounter, airTrapControllerState, TODO valvestate * @details \b Outputs: airTrapDataPublicationTimerCounter * @return none *************************************************************************/ static void publishAirTrapData( void ) { // Publish air trap data on interval if ( ++airTrapDataPublicationTimerCounter >= getU32OverrideValue( &airTrapDataPublishInterval ) ) { AIR_TRAP_PAYLOAD_T data; data.h17State = getLevelSensorState( H17_LEVL ); data.h16State = getLevelSensorState( H16_LEVL ); data.h17RawState = getRawLevelSensorState( H17_LEVL ); data.h16RawState = getRawLevelSensorState( H16_LEVL ); data.h13State = get3WayValveState( H13_VALV ); data.h20State = get3WayValveState( H20_VALV ); data.isAutoControlling = isAirTrapControlling(); broadcastData( MSG_ID_TD_AIR_TRAP_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( AIR_TRAP_PAYLOAD_T ) ); airTrapDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testAirTrapDataPublishIntervalOverride function overrides the interval * at which the TD air trap data is published. * @details \b Inputs: none * @details \b Outputs: airTrapDataPublishInterval * @param message Override message from Dialin which includes the interval * (in ms) to override the air trap broadcast interval to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testAirTrapDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &airTrapDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testSetAirTrapControl function sets the air trap to start or end * auto level control. * @details \b Inputs: none * @details \b Outputs: airTrapDataPublishInterval * @param message Override message from Dialin which includes the interval * (in ms) to override the air trap broadcast interval to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testSetAirTrapControl( MESSAGE_T *message ) { BOOL result = FALSE; BOOL startControl = FALSE; if ( ( TRUE == isTestingActivated() ) && ( sizeof( BOOL ) == message->hdr.payloadLen ) ) { result = TRUE; memcpy( &startControl, message->payload, sizeof( BOOL ) ); if ( TRUE == startControl ) { startAirTrapControl(); } else { endAirTrapControl(); } } return result; } /*********************************************************************//** * @brief * The testAirPumpPowerRaiseOverride function overrides the air pump power * level used to raise the air trap level. * @details \b Inputs: none * @details \b Outputs: airTrapAirPumpRaisePowerLevel * @param message Override message from Dialin which includes the power level * to override the air pump to when raising air trap level. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testAirPumpPowerRaiseOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &airTrapAirPumpRaisePowerLevel, AIR_PUMP_MOTOR_OFF, AIR_PUMP_MOTOR_MAX_PWM ); return result; } /*********************************************************************//** * @brief * The testAirPumpPowerLowerOverride function overrides the air pump power * level used to lower the air trap level. * @details \b Inputs: none * @details \b Outputs: airTrapAirPumpLowerPowerLevel * @param message Override message from Dialin which includes the power level * to override the air pump to when lowering air trap level. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testAirPumpPowerLowerOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &airTrapAirPumpLowerPowerLevel, AIR_PUMP_MOTOR_OFF, AIR_PUMP_MOTOR_MAX_PWM ); return result; } /**@}*/