Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -r493b74788dde91fc09303df6185bd9fa90de52d0 -r517905db003e860a4c4a21e9d0ac84e38be2d9ad --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 493b74788dde91fc09303df6185bd9fa90de52d0) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 517905db003e860a4c4a21e9d0ac84e38be2d9ad) @@ -38,9 +38,11 @@ #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_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_DELAY_TIME_MS ( 10 * MS_PER_SECOND ) ///< Delay between air pump On (in ms). +#define AIR_PUMP_UPPER_LEVEL_PERSISTENCE ( 100 / TASK_GENERAL_INTERVAL ) ///< Persistence time for air pump operation after air trap upper level reads air. #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 /// Persistence period for illegal level sensors fault. #define AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Air trap illegal values timeout (in ms) @@ -66,11 +68,16 @@ /// Interval (in ms) at which to publish air trap data to CAN bus. static OVERRIDE_U32_T airTrapDataPublishInterval = { AIR_TRAP_DATA_PUB_INTERVAL, AIR_TRAP_DATA_PUB_INTERVAL, AIR_TRAP_DATA_PUB_INTERVAL, 0 }; static OVERRIDE_U32_T airTrapLevels[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Detected air trap level for each level sensor. +static OVERRIDE_U32_T rawAirTrapLevels[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Raw air trap level before debouncing time +static U32 airTrapLevelsDebounceStartTime[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Debounce start time for airtrap level sensor. 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. +static U32 airPumpUpperLevelCtr = 0; ///< Timer count for air pump persistence. + static U32 fillStartTime = 0; ///< Time stamp for start of air trap fill. +static U32 airPumpOnDelayStartTime = 0; ///< Air pump On start time. static BOOL airTrapValveOpenAtStablePressureState = FALSE; ///< Periodic AirTrap fill during pressure stable state, to clear any accumulated bubbles @@ -95,13 +102,20 @@ resetAirTrap(); airTrapDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; airTrapValveOpenAtStablePressureState = TRUE; + airPumpUpperLevelCtr = 0; + airPumpOnDelayStartTime = getMSTimerCount(); for ( i = 0; i < NUM_OF_AIR_TRAP_LEVEL_SENSORS; i++ ) { - airTrapLevels[i].data = 0; - airTrapLevels[i].ovData = 0; - airTrapLevels[i].ovInitData = 0; - airTrapLevels[i].override = OVERRIDE_RESET; + airTrapLevels[i].data = 0; + airTrapLevels[i].ovData = 0; + airTrapLevels[i].ovInitData = 0; + airTrapLevels[i].override = OVERRIDE_RESET; + rawAirTrapLevels[i].data = 0; + rawAirTrapLevels[i].ovData = 0; + rawAirTrapLevels[i].ovInitData = 0; + rawAirTrapLevels[i].override = OVERRIDE_RESET; + airTrapLevelsDebounceStartTime[i] = 0; } initPersistentAlarm( ALARM_ID_HD_AIR_TRAP_ILLEGAL_LEVELS, AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS, AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS ); @@ -199,12 +213,39 @@ BOOL lower, upper; BOOL isAirTrapLevelsValid = FALSE; AIR_TRAP_LEVELS_T lowerAirTrap, upperAirTrap; + AIR_TRAP_LEVEL_SENSORS_T airTrapLevelSensor; - // Get latest level readings + // Get latest raw level readings getFPGAAirTrapLevels( &lower, &upper ); - airTrapLevels[ AIR_TRAP_LEVEL_SENSOR_LOWER ].data = (U32)( TRUE == lower ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); - airTrapLevels[ AIR_TRAP_LEVEL_SENSOR_UPPER ].data = (U32)( TRUE == upper ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); + 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 ); + // Read the level after expiry of debouncing time + for( airTrapLevelSensor = AIR_TRAP_LEVEL_SENSOR_LOWER; airTrapLevelSensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS; airTrapLevelSensor++ ) + { + // Check if the raw level sensor status is not the same as the recorded data + if ( getRawAirTrapLevel( airTrapLevelSensor ) != (AIR_TRAP_LEVELS_T)airTrapLevels[ airTrapLevelSensor ].data ) + { + // If the debounce time is 0, start the timer + if ( 0 == airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] ) + { + airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] = getMSTimerCount(); + } + // If the debounce time has been elapsed, update the level sensor status to the new status + else if ( TRUE == didTimeout( airTrapLevelsDebounceStartTime[ airTrapLevelSensor ], AIR_TRAP_LEVEL_DEBOUNCE_TIME_MS ) ) + { + // reset the debounce time + airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] = 0; + // update recent level status + airTrapLevels[ airTrapLevelSensor ].data = (U32)getRawAirTrapLevel( airTrapLevelSensor ); + } + } + else + { + airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] = 0; + } + } + if ( STATE_OPEN == getSwitchStatus( PUMP_TRACK_SWITCH ) ) { // If the pump track on open, zero the persistent counter to not check the air trap illegal level alarm @@ -340,6 +381,7 @@ if ( AIR_PUMP_STATE_ON == getAirPumpState() ) { setAirPumpState( AIR_PUMP_STATE_OFF ); + airPumpUpperLevelCtr = 0; } } @@ -361,9 +403,11 @@ //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() ) + if ( ( AIR_PUMP_STATE_OFF == getAirPumpState() ) && + ( TRUE == didTimeout( airPumpOnDelayStartTime, AIR_PUMP_ON_DELAY_TIME_MS ) ) ) { setAirPumpState( AIR_PUMP_STATE_ON ); + airPumpUpperLevelCtr = 0; signalInitiatePressureStabilization( USE_SHORT_STABILIZATION_PERIOD ); } } @@ -373,14 +417,19 @@ { if ( AIR_PUMP_STATE_ON == getAirPumpState() ) { - // Turn air pump off once we detect air at upper level - setAirPumpState( AIR_PUMP_STATE_OFF ); + 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() ) { @@ -451,8 +500,34 @@ /*********************************************************************//** * @brief + * The getRawAirTrapLevel function gets the raw level reading for the given + * level sensor. + * @details Inputs: rawAirTrapLevels[] + * @details Outputs: none + * @param sensor ID of level sensor to get reading for + * @return the raw level sensor reading for the given sensor (air or fluid). + *************************************************************************/ +AIR_TRAP_LEVELS_T getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSORS_T sensor ) +{ + 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; + } + + return result; +} + +/*********************************************************************//** + * @brief * The publishAirTrapData function publishes air trap data at the set interval. - * @details Inputs: airTrapLevels[] + * @details Inputs: airTrapLevels[], rawAirTrapLevels[] * @details Outputs: if broadcast is due, send air trap data * @return none *************************************************************************/ @@ -463,8 +538,10 @@ { AIR_TRAP_PAYLOAD_T data; - data.lowerLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); - data.upperLevel = getAirTrapLevel( 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; @@ -594,4 +671,57 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetRawAirTrapLevelOverride function overrides the measured raw level + * for a given level sensor. + * @details Inputs: none + * @details Outputs: rawAirTrapLevels[] + * @param sensor ID of level sensor to override + * @param level override level sensor with this + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor, AIR_TRAP_LEVELS_T level ) +{ + 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; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetRawAirTrapLevelOverride function resets the override of the + * level sensor. + * @details Inputs: none + * @details Outputs: rawAirTrapLevels[] + * @param sensor ID of level sensor to reset override + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ) +{ + 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; + } + } + + return result; +} + /**@}*/ Index: firmware/App/Controllers/AirTrap.h =================================================================== diff -u -r493b74788dde91fc09303df6185bd9fa90de52d0 -r517905db003e860a4c4a21e9d0ac84e38be2d9ad --- firmware/App/Controllers/AirTrap.h (.../AirTrap.h) (revision 493b74788dde91fc09303df6185bd9fa90de52d0) +++ firmware/App/Controllers/AirTrap.h (.../AirTrap.h) (revision 517905db003e860a4c4a21e9d0ac84e38be2d9ad) @@ -53,6 +53,8 @@ { U32 lowerLevel; ///< Lower air trap level sensor state U32 upperLevel; ///< Upper air trap level sensor state + U32 rawLowerLevel; ///< Raw Lower air trap level sensor state + U32 rawUpperLevel; ///< Raw Upper air trap level sensor state } AIR_TRAP_PAYLOAD_T; // ********** public function prototypes ********** @@ -69,11 +71,14 @@ void signalAirTrapPeriodicFill( void ); AIR_TRAP_LEVELS_T getAirTrapLevel( AIR_TRAP_LEVEL_SENSORS_T sensor ); +AIR_TRAP_LEVELS_T getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSORS_T sensor ); BOOL testSetAirTrapDataPublishIntervalOverride( U32 value ); BOOL testResetAirTrapDataPublishIntervalOverride( void ); BOOL testSetAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor, AIR_TRAP_LEVELS_T level ); -BOOL testResetAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ); +BOOL testResetAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ); +BOOL testSetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor, AIR_TRAP_LEVELS_T level ); +BOOL testResetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ); /**@}*/ Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r134d96d197007eeafb2e8e41de941742f348f9db -r517905db003e860a4c4a21e9d0ac84e38be2d9ad --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 134d96d197007eeafb2e8e41de941742f348f9db) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 517905db003e860a4c4a21e9d0ac84e38be2d9ad) @@ -677,6 +677,8 @@ stabilizationStartTimeMs = getMSTimerCount(); useShortStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; + // Fill air trap to clear any accumulated bubbles + signalAirTrapPeriodicFill(); } break;