/************************************************************************** * * 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 AlarmMgmt.c * * @author (last) Quang Nguyen * @date (last) 26-Aug-2020 * * @author (original) Sean * @date (original) 04-Feb-2020 * ***************************************************************************/ #include "AlarmMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" /** * @addtogroup AlarmManagement * @{ */ // ********** private definitions ********** const ALARM_DATA_T blankAlarmData = { ALARM_DATA_TYPE_NONE, 0 }; ///< A blank alarm data record for alarms that do not include alarm data when triggered. // ********** private data ********** static OVERRIDE_U32_T alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of current state of each alarm static BOOL alarmConditionIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of flag indicates if an alarm condition is active // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); /*********************************************************************//** * @brief * The initAlarmMgmt function initializes the AlarmMgmt module. * @details Inputs: none * @details Outputs: AlarmMgmt module initialized. * @return none *************************************************************************/ void initAlarmMgmt( void ) { ALARM_ID_T alrm; // initialize alarm states and start time stamps for ( alrm = ALARM_ID_NO_ALARM; alrm < NUM_OF_ALARM_IDS; alrm++ ) { alarmIsActive[ alrm ].data = FALSE; alarmIsActive[ alrm ].ovData = FALSE; alarmIsActive[ alrm ].ovInitData = TRUE; alarmIsActive[ alrm ].override = OVERRIDE_RESET; alarmConditionIsActive[ alrm ] = FALSE; } } /*********************************************************************//** * @brief * The execAlarmMgmt function executes the alarm management module. * @details Inputs: none * @details Outputs: none * @return none *************************************************************************/ void execAlarmMgmt( void ) { // TODO - any alarm audio or LED/lamp management for DG? } /*********************************************************************//** * @brief * The activateAlarm function activates a given alarm. * @details Inputs: none * @details Outputs: alarmIsActive[] * @param alarm ID of alarm to activate * @return none *************************************************************************/ static void activateAlarm( ALARM_ID_T alarm ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { // no need to do anything if alarm is already active if ( FALSE == isAlarmActive( alarm ) ) { // activate alarm alarmIsActive[ alarm ].data = TRUE; alarmConditionIsActive[ alarm ] = TRUE; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) } } /*********************************************************************//** * @brief * The activateAlarmNoData function activates a given alarm. An alarm message * is broadcast to the rest of the system. * @details Inputs: none * @details Outputs: alarm triggered message sent, alarm activated * @param alarm ID of alarm to activate * @return none *************************************************************************/ void activateAlarmNoData( ALARM_ID_T alarm ) { // broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ].data ) { broadcastAlarmTriggered( alarm, blankAlarmData, blankAlarmData ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM trig:%5d \n", alarm ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } activateAlarm( alarm ); } /*********************************************************************//** * @brief * The activateAlarm1Data function activates a given alarm. An alarm message * is broadcast to the rest of the system. This function will include given * data in the broadcast message for logging. * @details Inputs: none * @details Outputs: alarm triggered message sent, alarm activated * @param alarm ID of alarm to activate * @param alarmData supporting data to include in alarm message * @return none *************************************************************************/ void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) { // broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ].data ) { broadcastAlarmTriggered( alarm, alarmData, blankAlarmData ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM trig:%5d %8X \n", alarm, alarmData.data.uInt.data ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } activateAlarm( alarm ); } /*********************************************************************//** * @brief * The activateAlarm2Data function activates a given alarm. An alarm message * is broadcast to the rest of the system. This function will include * two given data in the broadcast message for logging. * @details Inputs: none * @details Outputs: alarm triggered message sent, alarm activated * @param alarm ID of alarm to activate * @param alarmData1 supporting data to include in alarm message * @param alarmData2 supporting data to include in alarm message * @return none *************************************************************************/ void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ) { // broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ].data ) { broadcastAlarmTriggered( alarm, alarmData1, alarmData2 ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM trig:%5d %8X %8X \n", alarm, alarmData1.data.uInt.data, alarmData2.data.uInt.data ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } activateAlarm( alarm ); } /*********************************************************************//** * @brief * The clearAlarm function clears a given alarm if it is recoverable. * An alarm message is broadcast to the rest of the system. * @details Inputs: none * @details Outputs: AlarmStatusTable[] * @param alarm ID of alarm to clear * @return none *************************************************************************/ void clearAlarm( ALARM_ID_T alarm ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { // clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmIsActive[ alarm ].data ) { broadcastAlarmCleared( alarm ); alarmIsActive[ alarm ].data = FALSE; clearAlarmCondition( alarm ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM cleared:%5d \n", alarm ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, alarm ) } } /*********************************************************************//** * @brief * The clearAlarmCondition function clears a given alarm's condition detected * flag. Also an alarm message is broadcast to the rest of the system. * @details Inputs: none * @details Outputs: alarmConditionIsActive[] * @param alarm ID of alarm to clear condition for * @return none *************************************************************************/ void clearAlarmCondition( ALARM_ID_T alarm ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { // clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmConditionIsActive[ alarm ] ) { broadcastAlarmConditionCleared( alarm ); alarmConditionIsActive[ alarm ] = FALSE; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_ID, alarm ) } } /*********************************************************************//** * @brief * The isAlarmActive function determines whether a given alarm is currently active. * @details Inputs: alarmIsActive[] * @details Outputs: none * @param alarm ID of alarm to check * @return TRUE if given alarm is active, FALSE if not *************************************************************************/ BOOL isAlarmActive( ALARM_ID_T alarm ) { BOOL result = TRUE; if ( alarm < NUM_OF_ALARM_IDS ) { if ( OVERRIDE_KEY == alarmIsActive[ alarm ].override ) { result = (BOOL)alarmIsActive[ alarm ].ovData; } else { result = (BOOL)alarmIsActive[ alarm ].data; } } else { activateAlarmNoData( ALARM_ID_DG_SOFTWARE_FAULT ); } return result; } /*********************************************************************//** * @brief * The checkPersistentAlarm function triggers/clears an alarm if an alarm condition * has persisted/cleared over given time limit. * @details Inputs: none * @details Outputs: checks whether an alarm is triggered or an alarm condition is cleared * @param alarmID ID of alarm to check * @param isErrorOccured Flag indicates alarm condition is active or not * @param data alarm data * @param limit alarm condition limit * @return TRUE if given alarm is active, FALSE if not *************************************************************************/ void checkPersistentAlarm( ALARM_ID_T alarm, BOOL const isErrorOccured, F32 const data, F32 const limit ) { if ( TRUE == isPersistentAlarmTriggered( alarm, isErrorOccured ) ) { SET_ALARM_WITH_2_F32_DATA( alarm, data, limit ); } if ( TRUE == isPersistentAlarmConditionCleared( alarm, isErrorOccured ) ) { clearAlarmCondition( alarm ); } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetAlarmStateOverride function overrides the state of the alarm active * state for a given alarm with the alarm management with a given active state. * @details Inputs: none * @details Outputs: alarm activated or cleared * @param alarmID ID of alarm to activate or clear * @param value override state for the given alarm ID (1=activate, 0=clear) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetAlarmStateOverride( U32 alarmID, U32 state ) { BOOL result = FALSE; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( TRUE == isTestingActivated() ) { if ( TRUE == (BOOL)state ) { activateAlarmNoData( (ALARM_ID_T)alarmID ); } else { clearAlarm( (ALARM_ID_T)alarmID ); } result = TRUE; } } return result; } /*********************************************************************//** * @brief * The testResetAlarmStateOverride function resets the override of the * state of the active state for a given alarm with the alarm management. * @details Inputs: none * @details Outputs: alarm cleared * @param alarmID ID of alarm to clear * @return TRUE if alarm clear successful, FALSE if not *************************************************************************/ BOOL testResetAlarmStateOverride( U32 alarmID ) { BOOL result = FALSE; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; clearAlarm( (ALARM_ID_T)alarmID ); } } return result; } /**@}*/