Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -r161503f32e66083ed9c6c16091d6e669d2ba15d9 -rdd18920c6a8890cc3449128b8480aa33eb0955ec --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 161503f32e66083ed9c6c16091d6e669d2ba15d9) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision dd18920c6a8890cc3449128b8480aa33eb0955ec) @@ -7,8 +7,8 @@ * * @file AirTrap.c * -* @author (last) Dara Navaei -* @date (last) 13-Oct-2023 +* @author (last) Vinayakam Mani +* @date (last) 05-Mar-2024 * * @author (original) Sean Nash * @date (original) 16-Sep-2020 @@ -37,9 +37,9 @@ #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 ( 6 * MS_PER_SECOND ) ///< Air trap fill timeout period (in ms). +#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_UPPER_LEVEL_PERSISTENCE ( 300 / TASK_GENERAL_INTERVAL ) ///< Persistence time for air pump operation after air trap upper level reads air. +#define AIR_PUMP_ON_STOP_TIME_MIN_MS 200 ///< Stop air Pump time. #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_LEVEL_DEBOUNCE_TIME_MS ( 400 ) ///< Air trap level sensor debounce time @@ -76,8 +76,11 @@ static U32 fillStartTime = 0; ///< Time stamp for start of air trap fill. static U32 airPumpOnDelayStartTime = 0; ///< Air pump On start time. +static U32 stopAirPumpStartTime = 0; ///< Stop air pump start time. +/// 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 ) ); -static U32 airPumpUpperLevelCtr = 0; ///< Timer count for air pump persistence. +static BOOL airTrapValveOpenAtStartOfTreatement = FALSE; ///< To Keep the fluid level high close to Air trap upper level during start of treatment // ********** private function prototypes ********** @@ -98,9 +101,10 @@ U32 i; resetAirTrap(); - airTrapDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - airPumpUpperLevelCtr = 0; - airPumpOnDelayStartTime = getMSTimerCount(); + airTrapDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + airTrapValveOpenAtStartOfTreatement = TRUE; + airPumpOnDelayStartTime = getMSTimerCount(); + stopAirPumpStartTime = 0; for ( i = 0; i < NUM_OF_AIR_TRAP_LEVEL_SENSORS; i++ ) { @@ -199,7 +203,7 @@ AIR_TRAP_LEVELS_T lowerAirTrap, upperAirTrap; AIR_TRAP_LEVEL_SENSORS_T airTrapLevelSensor; - // Get latest level readings + // Get latest raw level readings getFPGAAirTrapLevels( &lower, &upper ); rawAirTrapLevels[ AIR_TRAP_LEVEL_SENSOR_LOWER ].data = (U32)( TRUE == lower ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); rawAirTrapLevels[ AIR_TRAP_LEVEL_SENSOR_UPPER ].data = (U32)( TRUE == upper ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); @@ -356,6 +360,11 @@ { AIR_TRAP_STATE_T result = AIR_TRAP_VALVE_CLOSED_STATE; + // Air pump stop time based on the blood flow rate + S32 qB = abs( getTargetBloodFlowRate() ); + U32 qBx = ( 0 == qB ? MIN_SET_BLOOD_FLOW_RATE : (U32)qB ); + U32 airPumpStopTime = AIR_PUMP_ON_STOP_TIME_MIN_MS + ( ( qBx - MIN_SET_BLOOD_FLOW_RATE ) / 2 ); + // Transition to manual valve control state when requested if ( TRUE == pendingStopAirTrapController ) { @@ -365,40 +374,50 @@ if ( AIR_PUMP_STATE_ON == getAirPumpState() ) { setAirPumpState( AIR_PUMP_STATE_OFF ); - airPumpUpperLevelCtr = 0; } } + //Open valve once at start of treatment ( blood priming) + else if ( TRUE == airTrapValveOpenAtStartOfTreatement ) + { + airTrapValveOpenAtStartOfTreatement = FALSE; + if ( AIR_PUMP_STATE_ON == getAirPumpState() ) + { + setAirPumpState( AIR_PUMP_STATE_OFF ); + } + + setValveAirTrap( STATE_OPEN ); + fillStartTime = getMSTimerCount(); + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, STATE_OPEN, 0 ); + result = AIR_TRAP_VALVE_OPEN_STATE; + } + + // Turn air pump off after defined time or air detected at upper level + else if ( ( AIR_PUMP_STATE_ON == getAirPumpState() ) && + ( ( TRUE == didTimeout( stopAirPumpStartTime, airPumpStopTime ) ) || + ( ( AIR_TRAP_LEVEL_AIR == getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) && + ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) ) ) + + { + setAirPumpState( AIR_PUMP_STATE_OFF ); + airPumpOnDelayStartTime = getMSTimerCount(); + } + //Turn on air pump if fluid reaches upper level. else if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) { if ( ( AIR_PUMP_STATE_OFF == getAirPumpState() ) && ( TRUE == didTimeout( airPumpOnDelayStartTime, AIR_PUMP_ON_DELAY_TIME_MS ) ) ) { setAirPumpState( AIR_PUMP_STATE_ON ); - airPumpUpperLevelCtr = 0; + stopAirPumpStartTime = getMSTimerCount(); signalInitiatePressureStabilization( USE_SHORT_STABILIZATION_PERIOD ); } } - else if ( ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) && - ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) - { - if ( AIR_PUMP_STATE_ON == getAirPumpState() ) - { - airPumpUpperLevelCtr++; - // Turn air pump off once we detect air at upper level and exceed persistence - if ( airPumpUpperLevelCtr >= AIR_PUMP_UPPER_LEVEL_PERSISTENCE ) - { - setAirPumpState( AIR_PUMP_STATE_OFF ); - airPumpOnDelayStartTime = getMSTimerCount(); - } - } - } - // Transition to open valve state when air detected at lower level else if ( ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) && - ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) + ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) { if ( AIR_PUMP_STATE_ON == getAirPumpState() ) { @@ -407,7 +426,7 @@ setValveAirTrap( STATE_OPEN ); fillStartTime = getMSTimerCount(); - SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, 0, 0 ); + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, STATE_OPEN, 0 ); result = AIR_TRAP_VALVE_OPEN_STATE; } @@ -432,10 +451,13 @@ pendingStopAirTrapController = FALSE; result = AIR_TRAP_MANUAL_CONTROL_STATE; } - // Transition to closed valve state when fluid detected at lower level - else if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) + // Transition to closed valve state when fluid detected at upper level + else if ( AIR_TRAP_LEVEL_FLUID == getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) { setValveAirTrap( STATE_CLOSED ); + airPumpOnDelayStartTime = u32DiffWithWrap( AIR_PUMP_ON_DELAY_ADJUST_AFTER_FILL, getMSTimerCount() ); + signalLowVenousPressureCheck(); + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, STATE_CLOSED, 0 ); result = AIR_TRAP_VALVE_CLOSED_STATE; } return result; @@ -478,19 +500,19 @@ *************************************************************************/ AIR_TRAP_LEVELS_T getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSORS_T sensor ) { - AIR_TRAP_LEVELS_T result; + AIR_TRAP_LEVELS_T result; - if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) - { - result = (AIR_TRAP_LEVELS_T)getU32OverrideValue( &rawAirTrapLevels[ sensor ] ); - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (U32)SW_FAULT_ID_AIR_TRAP_INVALID_LEVEL_SENSOR, (U32)sensor ) - result = AIR_TRAP_LEVEL_AIR; - } + if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) + { + result = (AIR_TRAP_LEVELS_T)getU32OverrideValue( &rawAirTrapLevels[ sensor ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (U32)SW_FAULT_ID_AIR_TRAP_INVALID_LEVEL_SENSOR, (U32)sensor ) + result = AIR_TRAP_LEVEL_AIR; + } - return result; + return result; } /*********************************************************************//** @@ -502,19 +524,19 @@ *************************************************************************/ static void publishAirTrapData( void ) { - // Publish air trap data on interval - if ( ++airTrapDataPublicationTimerCounter >= getU32OverrideValue( &airTrapDataPublishInterval ) ) - { - AIR_TRAP_PAYLOAD_T data; + // Publish air trap data on interval + if ( ++airTrapDataPublicationTimerCounter >= getU32OverrideValue( &airTrapDataPublishInterval ) ) + { + AIR_TRAP_PAYLOAD_T data; - data.lowerLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); - data.upperLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); - data.rawLowerLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); - data.rawUpperLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); + data.lowerLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); + data.upperLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); + data.rawLowerLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); + data.rawUpperLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); - broadcastData( MSG_ID_HD_AIR_TRAP_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( AIR_TRAP_PAYLOAD_T ) ); - airTrapDataPublicationTimerCounter = 0; - } + broadcastData( MSG_ID_HD_AIR_TRAP_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( AIR_TRAP_PAYLOAD_T ) ); + airTrapDataPublicationTimerCounter = 0; + } } /*********************************************************************//** @@ -652,19 +674,19 @@ *************************************************************************/ BOOL testSetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor, AIR_TRAP_LEVELS_T level ) { - BOOL result = FALSE; + BOOL result = FALSE; - if ( ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) && ( level < NUM_OF_AIR_TRAP_LEVELS ) ) - { - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - rawAirTrapLevels[ sensor ].ovData = (U32)level; - rawAirTrapLevels[ sensor ].override = OVERRIDE_KEY; - } - } + if ( ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) && ( level < NUM_OF_AIR_TRAP_LEVELS ) ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + rawAirTrapLevels[ sensor ].ovData = (U32)level; + rawAirTrapLevels[ sensor ].override = OVERRIDE_KEY; + } + } - return result; + return result; } /*********************************************************************//** @@ -678,19 +700,19 @@ *************************************************************************/ BOOL testResetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ) { - BOOL result = FALSE; + BOOL result = FALSE; - if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) - { - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - rawAirTrapLevels[ sensor ].override = OVERRIDE_RESET; - rawAirTrapLevels[ sensor ].ovData = rawAirTrapLevels[ sensor ].ovInitData; - } - } + if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + rawAirTrapLevels[ sensor ].override = OVERRIDE_RESET; + rawAirTrapLevels[ sensor ].ovData = rawAirTrapLevels[ sensor ].ovInitData; + } + } - return result; + return result; } /**@}*/