/************************************************************************** * * 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 LevelSensors.c * * @author (last) Sean * @date (last) 03-Oct-2024 * * @author (original) Sean * @date (original) 03-Oct-2024 * ***************************************************************************/ #include "LevelSensors.h" #include "FpgaTD.h" #include "Messaging.h" #include "TaskPriority.h" #include "Timers.h" /** * @addtogroup LevelSensors * @{ */ // ********** private definitions ********** #define AIR_TRAP_LEVEL_DEBOUNCE_TIME_MS ( 400 / TASK_PRIORITY_INTERVAL ) ///< Air trap level sensor debounce time (in priority task intervals). // ********** private data ********** static OVERRIDE_U32_T rawLevelStates[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Raw air trap level states before debounce (overrideable). static OVERRIDE_U32_T currentLevelStates[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Current raw level sensor states (overrideable). static U32 airTrapLevelsDebounceTimerCtr[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Debounce timer counter for air trap level sensors. // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initLevelSensors function initializes the Level Sensors unit. * @details \b Inputs: none * @details \b Outputs: Level Sensors unit is initialized. * @return none *************************************************************************/ void initLevelSensors( void ) { AIR_TRAP_LEVEL_SENSORS_T airTrapLevelSensor; for( airTrapLevelSensor = AIR_TRAP_LEVEL_FIRST; airTrapLevelSensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS; airTrapLevelSensor++ ) { airTrapLevelsDebounceTimerCtr[ airTrapLevelSensor ] = 0; rawLevelStates[ airTrapLevelSensor ].data = AIR_TRAP_LEVEL_AIR; rawLevelStates[ airTrapLevelSensor ].ovData = AIR_TRAP_LEVEL_AIR; rawLevelStates[ airTrapLevelSensor ].ovInitData = AIR_TRAP_LEVEL_AIR; rawLevelStates[ airTrapLevelSensor ].override = OVERRIDE_RESET; currentLevelStates[ airTrapLevelSensor ].data = AIR_TRAP_LEVEL_AIR; currentLevelStates[ airTrapLevelSensor ].ovData = AIR_TRAP_LEVEL_AIR; currentLevelStates[ airTrapLevelSensor ].ovInitData = AIR_TRAP_LEVEL_AIR; currentLevelStates[ airTrapLevelSensor ].override = OVERRIDE_RESET; } } /*********************************************************************//** * @brief * The readAirTrapLevelSensors function gets the current level sensor state * for a all level sensors from the FPGA. * @note This function should be called periodically to maintain fresh * sensor readings for all level sensors. * @details \b Inputs: FPGA * @details \b Outputs: rawLevelStates[], currentLevelStates[], * airTrapLevelsDebounceStartTime[] * @return none *************************************************************************/ void readAirTrapLevelSensors( void ) { BOOL lowAir, highAir; AIR_TRAP_LEVEL_SENSORS_T airTrapLevelSensor; // Get latest raw level sensor states from FPGA getFPGAAirTrapLevels( &lowAir, &highAir ); rawLevelStates[ H17_LEVL ].data = (U32)( FALSE == lowAir ? AIR_TRAP_LEVEL_FLUID : AIR_TRAP_LEVEL_AIR ); rawLevelStates[ H16_LEVL ].data = (U32)( FALSE == highAir ? AIR_TRAP_LEVEL_FLUID : AIR_TRAP_LEVEL_AIR ); // Debounce raw air trap level sensor readings for( airTrapLevelSensor = AIR_TRAP_LEVEL_FIRST; airTrapLevelSensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS; airTrapLevelSensor++ ) { // Check if the raw level sensor status is not the same as the recorded data if ( getRawLevelSensorState( airTrapLevelSensor ) != (AIR_TRAP_LEVELS_T)currentLevelStates[ airTrapLevelSensor ].data ) { // If the debounce time has elapsed, update the level sensor status to the new status if ( ++airTrapLevelsDebounceTimerCtr[ airTrapLevelSensor ] >= AIR_TRAP_LEVEL_DEBOUNCE_TIME_MS ) { currentLevelStates[ airTrapLevelSensor ].data = (U32)getRawLevelSensorState( airTrapLevelSensor ); airTrapLevelsDebounceTimerCtr[ airTrapLevelSensor ] = 0; } } else { airTrapLevelsDebounceTimerCtr[ airTrapLevelSensor ] = 0; } } } /*********************************************************************//** * @brief * The getLevelSensorState function gets the current debounced sensor state * for a given level sensor. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given sensor is invalid. * @details \b Inputs: currentLevelStates[] * @details \b Outputs: none * @param sensor ID of level sensor to get state for. * @return The current state of the given level sensor. *************************************************************************/ AIR_TRAP_LEVELS_T getLevelSensorState( AIR_TRAP_LEVEL_SENSORS_T sensor ) { AIR_TRAP_LEVELS_T result = AIR_TRAP_LEVEL_AIR; if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) { result = (AIR_TRAP_LEVELS_T)currentLevelStates[ sensor ].data; if ( OVERRIDE_KEY == currentLevelStates[ sensor ].override ) { result = (AIR_TRAP_LEVELS_T)currentLevelStates[ sensor ].ovData; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_LEVEL_SENSOR_INVALID_SENSOR, sensor ) } return result; } /*********************************************************************//** * @brief * The getRawLevelSensorState function gets the current raw sensor state * for a given level sensor. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given sensor is invalid. * @details \b Inputs: rawLevelStates[] * @details \b Outputs: none * @param sensor ID of level sensor to get state for. * @return The current state of the given level sensor. *************************************************************************/ AIR_TRAP_LEVELS_T getRawLevelSensorState( AIR_TRAP_LEVEL_SENSORS_T sensor ) { AIR_TRAP_LEVELS_T result = AIR_TRAP_LEVEL_AIR; if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) { result = (AIR_TRAP_LEVELS_T)rawLevelStates[ sensor ].data; if ( OVERRIDE_KEY == rawLevelStates[ sensor ].override ) { result = (AIR_TRAP_LEVELS_T)rawLevelStates[ sensor ].ovData; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_LEVEL_SENSOR_INVALID_SENSOR, sensor ) } return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testRawLevelSensorOverride function overrides the raw sensor state * for a given level sensor. * @details \b Inputs: none * @details \b Outputs: rawLevelStates[] * @param message Override message from Dialin which includes an ID of * the sensor to override and the state to override the sensor to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testRawLevelSensorOverride( MESSAGE_T *message ) { BOOL result = u32ArrayOverride( message, &rawLevelStates[0], NUM_OF_AIR_TRAP_LEVEL_SENSORS - 1, 0, NUM_OF_AIR_TRAP_LEVELS - 1 ); return result; } /*********************************************************************//** * @brief * The testLevelSensorOverride function overrides the sensor state for a * given level sensor. * @details \b Inputs: none * @details \b Outputs: currentLevelStates[] * @param message Override message from Dialin which includes an ID of * the sensor to override and the state to override the sensor to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testLevelSensorOverride( MESSAGE_T *message ) { BOOL result = u32ArrayOverride( message, ¤tLevelStates[0], NUM_OF_AIR_TRAP_LEVEL_SENSORS - 1, 0, NUM_OF_AIR_TRAP_LEVELS - 1 ); return result; } /**@}*/